Rock Paper Overkill 在开发者的 Mac 上跑得好好的,一放到网页版、进入实测就崩了几次。制作它的机器与真正游玩它的地方之间的这道缝隙,就是整个案例。frostyshotss 在 2026年10月27日发表于 itch.io 的开发日志里报告:他把卡牌与合成的整个绘制方式都重做了,因为合成越多,内存泄漏就越多。作者说现在已经修好、应该很流畅了,并邀请玩家报告仍存在的问题。本文不会超出这一点:日志没有给出泄漏的内部机制,本文也不点名任何机制;流畅的结果是作者的说法,不是独立测量。
快速信息
来源:frostyshotss 在 itch.io 上发表的 Rock Paper Overkill 开发日志,2026年10月27日。本文关于修复的事实均出自这篇日志,另有说明来自游戏页面的除外。
症状,按报告只出现在网页版:游戏在作者的 Mac 上跑得好好的,但上传到网页版并实测时崩了几次。没有给出崩溃次数、浏览器、操作系统或设备清单,本文也不声称这些。
修复,按作者自己的范围:卡牌与合成的整个绘制方式都被重做,因为以前合成越多,内存泄漏就越多。作者说现在已修好、应该很流畅,并邀请玩家报告任何问题。
引擎,附出处说明:游戏页面说该游戏由 RoomTemperatureGames 用 Godot 制作并带有 Godot 标签,本文据此说明引擎为 Godot。日志本身没有讨论引擎内部机制。
本文不声称的内容:没有点名释放、对象池或其他内部机制,因为日志没有点名;没有报告修复前后的测量数据,因为日志没有给出;下面的清单是给读者自己项目的通用网页版测试做法,不是作者的步骤清单。
最后核实:2026年11月3日。
在开发者的机器上能跑,恰恰就是陷阱
游戏开发里最危险的测试结果,就是只在一台机器上通过的那种,而这篇日志正是为什么危险的一个简洁例子。Rock Paper Overkill 是一款 roguelite 构筑游戏,讲的是把床底下的日常物品合成为连招,而合成在其中不是支线活动。游戏页面描述为“什么都能合成”,有 241 张合成卡可收集,试玩版包含完整的第一幕,大约 90 分钟的游玩时间。一款核心循环就是合成的游戏,会被每一个上手的玩家一次又一次地合成。在作者的 Mac 上,这个循环跑得好好的;上传到网页版并实测时,却崩了几次。日志没有给出崩溃次数,也没有浏览器或设备清单,本文不会把它包装成一个测得的故障率。实测里几次崩溃就已经够重要了,因为崩溃不是一次本来不错的会话上的瑕疵,它会终结这次会话。
作者报告的模式,即使没有内部机制,也已经缩小了搜索范围。以前合成越多,内存泄漏就越多,于是应对办法是把卡牌与合成的整个绘制方式重做。这句话同时做了两件事。第一,它把泄漏与玩家会反复做的动作绑在一起,意味着泄漏应该随游玩而增长,而不是在某个固定时刻出现;而只玩一小会儿的测试可能永远看不到它。第二,它把修复范围限定在卡牌与合成的绘制上,而不是整款游戏——即使细节没有公开,这也是一种有用的纪律:去改泄漏动作所经过的那条路径,而不是同时到处乱找。本文不会去补上缺失的中间环节。日志没有说对象释放不正确、没有说缺少对象池、也没有说某种特定结构在累积,所以这些解释无论对 Godot 开发者听起来多么熟悉,都不会出现在这里。
当泄漏随动作增长时,就跟着动作走
随合成而增长的泄漏有一种可以测试的形态,而这种形态是这个单薄案例里最容易带走的部分。如果泄漏确实随合成累积而增长,那么短会话与长会话看起来应该不同,合成少的会话与合成多的会话看起来也应该不同;而一个只对短会话有帮助的修复,根本没有触及所报告的模式。作者的报告是:重做已经解决了问题,游戏现在应该很流畅,并邀请玩家报告任何问题。这句邀请比看起来更重要:对于一款故障只在上传与实测之后才出现的网页版游戏,下一轮证据将来自作者所没有的机器与浏览器上的玩家,而作者恰恰为这种证据留了门。在这样的报告到来之前,诚实的状态就是作者的状态:已修复、应该流畅,并等待着只有发布才能提供的更广泛的测试。
这个故事里的网页版部分值得单独强调,因为它正是修复之后最容易被遗忘的部分。在开发者的 Mac 上跑得好的游戏,只通过了一个环境,而不是玩家将要使用的环境;而网页版游玩带来了桌面测试从未触及的约束:玩家实际加载的构建、浏览器在长会话里的内存表现,以及只有反复执行核心动作才会产生的累积。这次更新的文件就是一个网页版构建,游戏页面还说玩家进度保存在浏览器里,这让一次会话中途的崩溃不只是烦人:它打断了一次玩家预期会存续的会话。这些都不会把这篇单薄的日志变成一份厚重的技术复盘。它没有数字、没有机制、没有测量,本文也没有编造其中任何一项。它提供的是一种干净而小巧的模式:桌面端正常、网页版崩溃、泄漏随合成增长、绘制被重做、作者报告已流畅、并邀请报告。
能复用的部分
下面的步骤不是 frostyshotss 在已述重做之外做过的事;这份清单是给读者自己项目的通用网页版测试做法,不是作者的步骤,并且始终停留在这个定位里。能复用的思路是:用玩家实际会加载的构建、按玩家实际会玩的时长、按玩家实际会做的频率去做核心动作,来测试。桌面端通过不等于网页版通过,短测试通过不等于长测试通过;而一个修复,也不能靠“在当初就没发现问题的同一段短测试里不再崩溃”来证明。如果问题随重复动作而增长,那么证明修复的测试就必须把这个动作重复到超出旧问题曾经出现的位置,而结案的报告应该说明测试跑了多久、在什么上面跑、跑的时候观察了什么。
周一早上照着做
在你自己的项目里,作为通用的网页版测试做法,要测试网页版构建本身,而不只测桌面版,因为在你的机器上正常的游戏,还没有通过玩家将要加载它的那个地方。
在你自己的项目里,作为通用的网页版测试做法,玩一次多次重复核心动作的长会话,并在动作累积的过程中观察内存,让随游玩而增长的泄漏无法躲在短测试后面。
在你自己的项目里,作为通用的网页版测试做法,把核心动作少的短会话与核心动作多的长会话对比,并把两者之间的差异当作“开销在哪里增长”的线索。
在你自己的项目里,作为通用的网页版测试做法,任何重做之后,都要把核心动作重复到超出旧问题曾经出现的位置,而不是只重跑当初没发现问题的那段短测试。
在你自己的项目里,作为通用的网页版测试做法,记录证明性测试跑了多久、在哪个浏览器与机器上跑、跑的时候观察了什么,让修复报告可以被核查,而不只是被相信。
在你自己的项目里,作为通用的网页版测试做法,在只针对网页版的修复之后,邀请其他机器与浏览器上的玩家报告问题,并一直保持邀请开放,直到这些报告有时间到来。

