← ALL ARTICLES
游戏AI7 MIN READ

决策日志与恢复

全库目录221
本文目录7

进程在命令登记后、接纳前退出,恢复时必须确认原请求是否已发生。本页给出采用统一有序日志、宿主接纳账本和恢复排他边界的一种持久化架构;普通内存内NPC可以采用更轻量的状态保存策略。输入是已提交日志、世界快照和回执账本,输出是恢复后的同一动作身份及待续交请求。命令与实例的区别见决策输入与动作交接,计划安装见决策计划提交。

异步事件与决策重放

计划终态与重规划所述的正常交接依赖完成消息。守卫的移动成功与受伤同时到达时,先消费成功会让实例17正常结束;先消费受伤则开始取消,随后成功只结清取消路径。调度器为每个NPC保存递增消费序号,一轮开始冻结事件批次,按事件优先级、来源ID与来源内序号排序。受伤可发起紧急轮,但仍经这个入口串行消费。每项保存来源运行纪元、请求或动作ID、结果与本轮消费序号,工作线程只投递消息。

有序来源缺号时暂缓其后续事件,并查询回执或请求重传;来源确认不可恢复时写入显式故障事件。取消截止也作为带逻辑Tick的事件进入批次,已提交的批次直接读取日志,恢复后的完成速度不能改变截止前收取的集合。

命令登记与宿主接纳

决策日志的一次提交包含冻结事件、黑板差异、模型配置版本、活动模型状态和待发命令,并同时推进事件消费游标。命令ID取持久NPC实例ID、决策轮号和轮内序号,载荷包含计划代次、目标、前提读取版本与载荷哈希。运行纪元放在投递信封中,恢复时保持原命令ID与载荷。若把纪元放进命令ID,恢复补发就会被宿主当成另一次请求。

每条已登记命令构成持久出站表的一项。发送完成标记只帮助调度,宿主的接纳或拒绝回执才决定它是否已经交付。宿主以命令ID查询接纳账本:已存在且哈希相同就返回原实例及已有回执,哈希不同报身份冲突;不存在时检查目标、读取版本和独占资源,在同一次宿主提交里记录接纳结果与资源所有者,随后才允许动作更新。明确拒绝也写入账本,因此重试不会因场景后来改变而把同一拒绝变成接纳。

守卫的C17可以经历以下三种退出位置。它们恢复后的动作不同:

持久状态恢复采用的记录续行
决策已登记C17,宿主没有接纳记录原C17载荷,宿主给出的确定Absent结果以新信封纪元补发原C17;宿主按此刻实际条件首次接纳或拒绝
宿主已接纳C17为实例17,决策未消费回执宿主接纳记录及资源所有者登记返回的原回执,继续跟踪实例17;不创建第二个移动实例
实例17的终态与世界效果已经提交,决策尚未消费完成原终态回执、效果序号和世界提交位置恢复世界效果一次,再消费原终态,推进原行为树或取消路径

Absent表示宿主持久账本在约定恢复前沿内确定没有这个ID,超时、网络失败与账本尚未加载都属于Unknown。Unknown保持等待并重试对账,不能据此补发另一ID。首次接纳前若门已关闭,C17拒绝并结束该命令;决策消费拒绝后基于新快照产生另一个命令ID。原载荷不能在补发时悄悄改成另一条路线。

世界效果与恢复前沿

为让上表有确定输入,本页采用同一宿主有序提交日志。决策提交、宿主接纳、世界效果及终态、恢复控制记录都取得全局日志序号L。内存世界是这份日志的物化状态:宿主先持久提交效果与回执,再按效果序号应用一次;快照保存已应用位置。恢复世界时从快照位置重放效果,宿主执行器恢复活动阶段,历史决策回放只消费保存的回执,不再次调用射击或领取资源接口。接入独立外部服务时,其接纳账本与效果回执也必须能够恢复并对账后才能开放这些动作。

进程退出后,先关闭命令派发、动作更新与普通决策轮,并在宿主提交入口取得恢复排他锁,阻止旧进程和工作线程继续提交,再取得日志的已提交末端H。该锁保持到新纪元恢复记录提交,避免读取H以后还有旧纪元效果追加到日志。按L顺序恢复到H:决策记录重建活动节点和出站表,接纳记录重建实例归属,效果记录恢复世界,终态记录补齐待消费回执。某条回执已被后续决策消费时,由保存的回执消费游标排除;尚未消费的回执在恢复后进入一次新的冻结批次。旧决策轮的回放不会向宿主发送命令。

随后以更高运行纪元写入恢复记录,包含恢复前沿H、原纪元、新纪元、活动实例的继续或安全退出决定、未完成查询的重新派发参数。该记录的宿主提交同时推进允许纪元,接纳入口和每次世界效果提交都在同一日志串行化边界检查这个纪元。提交新纪元后释放恢复排他锁。旧工作线程即使仍运行,也无法在恢复记录之后提交世界修改。恢复会暂停宿主提交,这是采用统一恢复边界的时间成本。活动实例保留原ID和命令归属,由新纪元接管;旧纪元迟到消息拒绝,所需结果从持久账本读取。恢复决定产生的取消命令同样进入出站表,不能直接释放旧所有者。

例如日志L100登记C17,进程在派发前退出。恢复到H=100后,L101记录纪元7接管为8;宿主确认C17为Absent,新纪元补发原C17,L102接纳为实例17,L103记录到达及位置效果。若在决策消费L103前再次退出,第二次恢复从旧快照按序读L100、L101、L102、L103,先恢复纪元8及原实例归属,再恢复位置和待消费成功。它在L104登记纪元9后只对账,不重建C17,也不再次移动。若首次恢复在L101之后、补发之前退出,第二次恢复仍能从C17出站项发现尚未交付的命令,按相同规则补发。

世界到达H且恢复记录已提交后,先对账活动动作与出站表,再开放发送。每轮先消费冻结的已有回执和紧急事件、登记所需取消,然后发送仍待交付的原命令。宿主对新接纳再次核对前提;取消与启动仍遵守资源释放次序。恢复期间需要安全退出的跳跃等动作完成资源对账以前,相关分支保持等待,其他资源上的安全行为可以继续。未完成的纯查询以新纪元和递增尝试号重新派发,查询原身份与尝试变更也写入恢复记录;已提交的采用结果直接读取。

新快照同时保存L位置、世界已应用位置、出站表、接纳账本、回执消费游标及活动动作阶段。模式持有的保持实例、资源归属、事实代次与恢复截止也属于这一前沿;恢复世界及所有权后先核对保持,再允许依赖站位的交互和Satisfied状态继续。历史移动Success只恢复已完成步骤,不能独自生成一份新的保持所有者。

只有所有受支持的快照都越过终态和消费位置,且不存在待交付或待对账引用时,才清理命令去重记录。模式仍引用的保持或取消记录继续保留。日志恢复到一半再次退出仍按同一序号重放;内存发送标记和当前线程状态都不是恢复依据。

调试记录本轮快照、候选门禁与评分、活动节点、动作ID、资源所有者、取消原因和终态。看到角色仍追旧敌人时,先检查决策是否产生取消,再检查执行器是否完成交接,最后检查新候选是否被接纳。这样可以区分选择错误、取消滞留和资源竞争,而不只观察最后的动画。

逐机制反例

以下为完整框架接入后的验证用例设计,执行状态见“实现与证据”。

  • 确定性回放:固定配置、输入事件序列、种子与世界快照离线重放整局决策,逐帧比对每个 NPC 的当前节点与动作序列;任何分叉都要能定位到具体黑板键的变化。
  • 中止测试集:为每类 Observer 中止构造“打断瞬间”用例,确认被打断动作的退出执行了、外部请求被取消、黑板残留状态被清理。
  • 黑板审计:记录每个键的写入者与时间戳,检查是否有系统绕过受控接口直接改写,短期感知键是否按过期时间清理。
  • Utility 回归:录制典型局势(残血、弹尽、被围),确认期望动作得分第一;每个评分因素的输入、曲线输出与总分写日志,分数异常时可回放归因。
  • GOAP 计划校验:对生成的计划逐步骤检查前提在模拟中成立;动作执行失败时确认执行器上报失败并触发重规划,而不是原地干等。
  • 预算检查:统计单帧决策耗时的 P99;大量 NPC 时确认事件驱动重评估生效,检查持续 Running 任务更新与条件重评估各占多少成本。事件驱动和逐帧 Tick 都可以成立,选择取决于实现语义与预算。

实现与证据

本文为机制设计与状态推演,完整NPC框架、异步动作和持久恢复尚未接入运行。相关机制片段的局部验证见效用评分与目标规划。

相关主题

参考资料

本文的动作账本、版本与提交次序属于示例架构。行为树的引擎来源见状态机与行为树,目标规划原始实践见效用评分与目标规划;它们不直接规定本文持久协议。