我为我的游戏引擎构建了协程,但最后却没有使用它们
我为我的游戏引擎构建了一个生成器协程系统。它只有 122 行代码,并配有 12 个测试。它解决了回调地狱问题,让脚本看起来像是一条直线。
然后,我决定不在游戏逻辑中使用它。相反,我使用了有限状态机 (FSM)。
以下是原因。
大多数教程都忽略了生成器在实时游戏中的两个重大问题:内存和存档。
1. 内存压力
每当你对生成器调用 .next() 时,JavaScript 引擎都会创建一个新对象。该对象包含当前值和状态。
在以 60 FPS 运行的游戏循环中,这会产生持续的垃圾回收 (GC) 压力。我的引擎遵循“零分配”规则以保持性能稳定。而生成器打破了这一规则。它们在每一帧都会产生一系列微小对象。
2. 序列化问题
游戏需要存档和读档。你需要将当前游戏状态转换为数据,并能将其还原。
你无法序列化一个暂停中的生成器。它的状态存在于你无法访问的引擎内部插槽中。如果你尝试保存它,你会得到一个空对象或报错。
有限状态机则不同。状态仅仅是组件上的一个字符串。
- 存档:将字符串写入磁盘。
- 读档:读取字符串并告知 FSM 从该状态开始。
FSM 胜出了,因为它处理了专业游戏中最关键的两件事:性能和持久化。
如何选择:
逻辑是否在主帧循环内?
- 否:使用生成器协程。它们非常适合加载资源或新手引导等一次性流程。
- 是:问下一个问题。
状态是否需要在存档后保留?
- 是:使用有限状态机。
- 否:问下一个问题。
你是否在同时运行许多序列?
- 是:使用有限状态机。
- 否:使用生成器协程。
生成器并不是错误的选择。它们只是不适合用于“热路径 (hot path)”。可以将它们用于异步粘合逻辑,但游戏逻辑请使用 FSM。
Source: https://dev.to/grzott/i-built-generator-coroutines-for-my-game-engine-then-didnt-use-them-o3g
