核心见解是将其视为分布式系统,而不是游戏循环。

全局不可变存储作为真实来源。所有实体状态都存储在不可变快照中——每次写入都会通过原子不可变字典交换产生一个新的快照。没有锁定,没有共享可变状态。任何线程都可以自由读取;只有一个写入路径存在。这是etcd/Kubernetes使用的相同模式。

AI与渲染分离。AI规划器在自己的时间器上运行——完全独立于60fps渲染循环。可视化棋子仅从最后写入的通道中消费移动意图,每帧都进行平滑插值。整个AI层都完全无头(没有GPU,没有显示),这就是我们如何进行蒙特卡罗回归测试——在CI中运行数千个随机种子,根据种子重放时出现问题。

GOAP与每类型范围内的动作集。而不是一个全局动作空间,每个实体类型都注册它可以执行的动作。一个药瘾者有3个动作;一个帮派成员有59个动作。规划器只在该类型的集合中搜索。除了规划器之外,权重计算器还会在规划之前运行,并根据世界状态将大多数目标门限设置为零——因此在实践中,规划器通常每个时钟周期评估2-3个活跃候选目标,而不是33个。

路径寻找不是规划。A*在MovementService中运行,完全独立于GOAP。规划器只发出“追逐实体X,距离Y”的意图。MovementService计算并缓存路径,只在目标移动超过阈值时重新计算路径。规划器永远不会直接接触A*。

结果:对于~50个实体,AI每个时钟周期运行时间小于毫秒。无头压力测试10,000个时钟周期,20个实体耗时约15秒。