一个 1993 年的 Amiga 游戏,凭什么在 2025 年重新活过来?答案不是模拟器,不是重制团队,是一个人在 Claude Code 里让 Claude Fable 5 干了场硬活——34,000 行 C++ 一夜之间迁进 Godot 4,72,758 行连注释都没有的 68000 汇编被重新编译成与当年发售版逐字节一致的二进制。这不是什么“AI 辅助编程”的漂亮话,这是一场不动声色的代码考古。
对象不是新游戏,是三十年前的自己
大多数人对“AI 写代码”的想象还停留在生成 Todo App 的阶段。真正在一线干活的人已经换了一种玩法:把三十年前的老物件挖出来,让 AI 给它续命。
一个很老的项目,一位很新的“同事”
这次移植的对象是开发者自己在 1993 年写的 Amiga 游戏。那个年代的 Amiga 开发者有个共同点:写代码是真往骨头里写的。C++ 只是表层,底层是赤裸裸的 68000 汇编,没有注释,没有中间层,效率压到极限。如今这批代码躺在磁盘镜像里,像一枚时间胶囊。
他不是做模拟器——那等于让老代码活在玻璃罩里。他的目标是让这个游戏变成 Godot 4 原生程序,能编译、能分发、能在现代平台上跑起来。同时他还定了一个近乎苛刻的标准:所有汇编部分必须重建出与发售版二进制逐字节一致的产物。
为什么是“迁移”而不是“重写”
有人可能会问:既然有 AI,为什么不干脆让 LLM 把老逻辑直接翻译成现代语言?现实没那么浪漫。游戏逻辑与硬件时序深度耦合,Amiga 的协处理器、帧缓冲、音频寄存器都在汇编里直接操作。你说“重写”,等于把 1993 年的物理规则改写成 2025 年的理解——那不是移植,是投胎。
所以他的思路很实际:逻辑能搬就搬——C++ 部分直接迁入 Godot;底层必须逐字节对应——汇编部分走重建路线。
C++ 这一层,一夜扫完
34000 行的高效搬运
所有迁移工作被切成三个阶段。第一个阶段是 C++ 代码层的迁移,体量 34,000 行。结果出人意料地顺利。Claude Fable 5 在一个晚上的时间里完成了主要搬运工作:类结构转换、平台 API 替换、资源加载逻辑对接 Godot 的节点体系。效率高到作者自己都在复盘里用了“惊人”这个词。
这里面有时代因素。1993 年的 C++ 相对朴素,大量结构可以用现代模式直接映射,LLM 对这种“旧→新”的翻译极其擅长,因为它不需要推理复杂的运行时刻行为,只需要忠实映射。
通畅背后的隐忧
C++ 层的顺利其实让作者心里打了个问号:真正难啃的骨头根本不在这一层。下一个阶段的材料是 72,758 行 68000 汇编。它更关键的问题是:没有注释。当年写这些代码的人根本没打算给 30 年后的自己留解说词。
那 34000 行代码被扫清的同时,真正的角力也正式拉开。
72758 行无注释汇编,和一套极端的校验主义
到这里,想象力帮不上忙。你需要一套可执行、可验证的方法,把零语义注释的 68000 指令逐条梳理出来,形成逻辑实体并接入新引擎。
一切从 vasm 开始
作者为汇编部分定制的方法是这样的:用跨平台汇编器 vasm 重新汇编原有的程序源码。如果汇编结果和 1993 年发售版的原二进制完全一致,就证明源码层面的转移没有破坏任何底层逻辑。这被称为字节级校验——最严格的标准,没有之一。
这招的聪明之处在于它把“LLM 是否理解正确”翻译成了一个硬件可回答的问题:比较两个二进制文件的每一个字节。这与凭空写单元测试来验证所谓“语义正确性”有本质区别——后者在逻辑等价性面前从来都是可被操纵的,而字节比较零容错。
AI 会的,和 AI 不会的
过程中,Claude 不止一次出过错。作者在复盘里展示了多处真实实例:错误的内联数据宽度、被误判的分支条件、对周期精确代码的过度优化——每一处都可能让游戏在特定帧或特定硬件状态下崩溃。
你不可能仅仅凭一次 prompt 就让 LLM 完美处理这类问题。开发者必须不断把编译失败、字节对比差异信息回喂给模型,让它反复修正,直到那个结果出现:一个完全匹配的二进制。
“懂汇编”不是加分项,是前提
面对这种场景,真正卡脖子的不是 AI 懂不懂汇编,而是你懂不懂。你如果看不出某种指令模式代表音频驱动时序,AI 的任何错误输出在你眼里都会“看起来没问题”。一位资深开发者在这套流程中的价值不在写代码的环节,而在建立验证策略与分辨错误类型的节点上。
把 1993 年的老版塞进新游戏——出于尊敬,也出于科学
整个移植终于收场时,他做了件很有仪式感的事:把原版 1993 年的游戏作为启动项嵌入重新构建的新版本。启动新游戏时,玩家可以选择切换回“原始模式”——一个像素级对齐、指令周期级一致的化石版体验。
这不再是情怀,是工程档案
如果只是情怀,可以直接在游戏菜单埋一个模拟器入口。但他用的是完全不同的方式:原版的编译产物以原生状态嵌入 Godot 4 游戏包,不隔一层模拟层。这意味着现代版和原始版共享同样的底层执行环境,只是走不同的启动路径。
于是这游戏现在是个双生体:一侧是 2025 年的迁移版画面,另一侧是 1993 年的原版字节流。收藏家不会这么做,考古学家才会。作者在这里同时扮演了两种角色,而 Claude Code 成了他的洛阳铲。
验证了一切的老版本
嵌入原版后续发挥的作用超出展示意义。它就是整场移植的唯一“真相源”。任何迁移层出现诡异行为,你切到原始模式跑一遍相似操作——如果老版没有同样问题,那是迁移层出错了;如果老版一样,说明当年代码本来就长这样。
这是软件工程中最昂贵的奢侈品:一个权威参照物。大多数现代重构项目做梦都不敢想有这个。可对于这次移植,它从一开始就安静地躺在那里。
从 Amiga 到 Godot:这次迁移留下的三句话
AI 干得了力气活,想不明白为什么
翻译代码是纯粹的力气活,Token 消耗量才是问题。LLM 干这个绰绰有余。但让它设计验证方法、理解周期精确时序与音效硬件的微妙互动,还远不够可靠。
但把它放到流水线里、赋予它明确的工序和硬性验收标准时,它就突然变成了一个非常能干活的初级工程师——会的很多,犯错误的姿势也千奇百怪,但你把规矩立好,它的产出惊人地稳定。
这次的规矩是:字节不一致就不算数。
老游戏是代码考古的完美试验场
现代项目的接口每天都在变,依赖关系复杂到像城市地下管网。而 1993 年的游戏代码是封闭、确定、有边界的。它不会在你看代码的时候偷偷更新 API。这种封闭性使 LLM 的行为变得可预测、可复盘、可校验——也让人能专注研究 AI 在编码任务上的上限到底在哪里。
那 72,758 行汇编,每一字节都被最终校验,这在某种程度上也获得了反证:AI 推理与人类修复形成了一个高度可靠的闭环,你可以跑一晚上,第二天清点错误,且不必担心漏了什么。
时间才是最难移植的那部分
从技术上讲,这次移植最困难的部分已经不是汇编语法、不是硬件时序。最难的部分是“上下文”。1993 年的作者默认为语言、为当时的硬件语义留下了无数个没有明说的“当然”。而 2025 年的 Claude 并不天然理解这些当然。它需要有人告诉它哪些“当然”是环境注入的、哪些是核心逻辑的。
这个过程无法完全自动化,它需要一种跨时间域的代码直觉。所幸那位开发者本人就是作者本人——他不仅是 30 年后的工程师,也是唯一一个能真正理解那个年代代码呼吸节奏的人。
是他让 AI 的迁移翻译有了上下文,是他定下字节级校验的标准,也是他选择了把 1993 年的原版嵌进 2025 年的启动菜单——给这个时代留下一颗可以打开的时间胶囊。这不叫“AI 取代程序员”。这叫一位依然记得 68000 指令集的程序员,找到了一个比自己年轻三十岁的队友。

