独立开发·阅读约 2 分钟·
33 年后,我用 AI 把 1993 年的 68000 汇编游戏搬进了 Godot:一个人的重制实验

33 年后,我用 AI 把 1993 年的 68000 汇编游戏搬进了 Godot:一个人的重制实验

1993 年,巴格达的一位工程系学生在制裁中、用 512KB 内存的 Amiga 500 纯汇编写成了伊拉克第一款商业游戏。33 年后,他用 Claude Code 把 72,758 行 68000 汇编和新旧两代代码库搬进 Godot,重制版上架 iOS/Android、秋季登陆 Steam。全程一个人:他提问、试玩、做决定,重活全交给 AI——然后花了几周才发现 AI 犯下的、人类才看得出的错。

原文来源:Babylonian Twins — 独立游戏开发者用 Claude Code 把自己 1993 年写的 72,758 行 68000 汇编游戏搬进 Godot:AI 干重活、人做判断,重制版今秋上 Steam。

1993 年,巴格达。一位二十多岁的工程系学生在一台 Amiga 500 上做游戏:512KB 内存、没有硬盘、接电视玩。制裁之下没有互联网、没有开发资料,只有一本 Amiga 硬件参考手册和每天几小时的电。所有精灵、所有扫描线都是手写 68000 汇编,7 万多行,没有注释的习惯——因为他从没想过会有第二个人来读这些代码。

游戏叫 Babylonian Twins(巴比伦双子),是伊拉克第一款商业游戏。然后 Commodore 倒闭、制裁吓跑了发行商,做好的游戏在架子上躺了十几年。2008 年,一个 Amiga 论坛从他兄弟上传的 YouTube 视频里认出了这游戏,顺藤摸瓜找到了作者本人。2010 年,同一团队手工把它移植到 iPhone——从零写引擎,34,000 行 C++,搭上无数个夜晚和周末。苹果和谷歌都推荐过它,累计下载超过两百万。

然后到了 2026 年。这次移植,作者本人几乎没写代码。

三步实验,全部成功

作者给自己设计了一个三步实验,每步都以前一步成功为前提:

第一步,安全题:把 2010 年那 34,000 行 C++ 引擎搬进 Godot 4。周三晚上 22:23 开工,21 分钟后两个角色已经可以玩——碰撞、物理、镜头、切换全好了。到凌晨 2:15,导出 macOS、iOS、Android 全流程跑通。作者说:"那一晚它搬的每一行都是我当年花几个月写下的。我带着困惑去睡了。" 手感调校又花了三天——跳跃弧线、蹦床时机、奖励连打的命中判定,7 月 2 到 4 号分批修完。测试是他和 13 岁的儿子一起做的,父子俩每晚玩新构建,成了项目里他最珍惜的部分。

第二步,不公平题:把 1993 年原版 72,758 行 68000 汇编搬进 Godot。这批代码是给一台已停产机器写的:文件名在 2008 年转存时被截短、所有 include 指向不存在的名字、五个关卡源文件里有一个在数据表中间断掉——世上没有第二份。星期天下午 14:34 开始,15 分钟内 vasm 工具链就复现了与出厂二进制逐字节一致的产物。为了让汇编器输出与当年 ASM-One 完全一致,AI 自己写了个预处理层,桥接了五种方言差异。最难的是 org 指令——无链接器、无重定位,内存布局全靠手排,而 ASM-One 的 org 还能把位置计数器往回拨,vasm 不行。第一个 workaround 错了一处:一个重绕块里的 ds.b 800 被展开成 800 个零字节,导致文件后半段(铜列表在内)整体偏移 944 字节——游戏能汇编、能启动,但画出来是错的。

还有约 108 字节怎么都对不上。作者后来才想明白:ASM-One 是汇编进内存的,游戏上磁盘靠的是"把运行过的内存存出来"——出厂文件其实是运行中游戏的快照,变量区里残留着当年机器上的值,而全新汇编那里是零。代码先写后读,零值无害。作者说,他读到这里时没当回事,几周后才意识到这是整个项目最重要的一件事:从此以后,关于这个游戏的任何说法,都可以用逐字节比对来裁决。 他自己 18 年都没想过要花一个下午把二进制从源码重建一遍。

第三步,贪婪题:把 1993 原版塞进新游戏里,买重制版送原版。一个晚上(21:58 到 23:43)搞定。老游戏以访客身份跑在自己的命名空间里,引擎进游戏切 50Hz、出来切回 60Hz。作者原以为这功能要吃掉一周然后被砍掉,结果 Steam 版就这样带着 1993 原版一起发货了。

—— 广告 ——

格式逆向:它读代码,而不是猜格式

每个文件格式,AI 都是找到读取它的那段代码、从代码反推出来的。关卡加载器是 1,652 行无注释 68000,作者以前宁可开十六进制编辑器也不碰它。

关卡是一长串数字,每个数字代表"在这里放第 47 号图",是作者 1993 年的私有布局。一年前他让老模型干过这活,折腾好几轮、给了大量提示才勉强搞定。这次什么都没解释——AI 找到绘图例程、看懂网格怎么遍历、从文件别处的常量推出宽高,五个关卡一次全对。然后它把自己提取的数据重新渲染,和作者 2020 年截的全关大图逐像素对比,不一致就回去找原因,最后揪出两个铜效果(天空渐变和水色循环)。算下来:五张全关大图,零像素差异。

地图像素只是每个格子的半个故事。每个格子是一个 16 位字,图片只占低 8 位,高 6 位是属性——这格子的隐形物理:1 是实地,2/3 可爬,10 到 13 是四种方向的伤害,14 直接秒杀,63 是门。这些规则没有任何文档,是靠两个例程各自读取同一个字的不同半区才还原出来的。作者在 1993 年给伤害例程起的名字叫 rmhEnjury——"injury"(受伤)的拼写错误,三十三年后依然如故。

还有一处让作者自己都意外的发现:门根本不在地图数据里。他坚信了三十三年"地图是唯一事实来源、门是地图数据"——错。地图上有洞,门是运行时由一段 18 字节的对象记录按 1×4 图块列盖上去的。这就是为什么"照搬地图数据"的移植会得到一座门口全是天空的塔。作者说,这个事实他三十三年都不会去查,因为从没有人告诉过他该怀疑。

AI 犯的错,人类几周后才发现

文章最诚实的一段在这里。作者玩了几周,才发现两个 AI 埋下的 bug:

守卫 bug:第二关走廊里走着走着凭空挨打。打他的是一个站在 13 格之上、隔着实心岩石的持矛守卫。原版里守卫的推人判定上下都有边界(cmp.w #4cmp.w #-2 都检查),移植版丢掉了上界检查——原本只管自己三行范围的推人,变成了穿透整个地图列的隔空攻击。

蹦床 bug:"蹦床感觉太高了。"这是作者唯一的反馈。他建了个 20 行模拟器验证物理:预测 19.1 格,实测 19.5,物理没问题。问题出在输入语义——2010 版是事件驱动,当年为了绕一个 tvOS 怪癖做的 workaround 让"按住跳跃"被读成"已松开",而 Godot 是轮询输入,一直在报"按住"。这导致高跳需要一次干脆利落的新按压——而这正是手机上的实际手感。源代码里看不出任何异常,因为从源码视角什么都没发生。"你得在场——拿着手机、绕着一个电视机里的 bug 干活——才会知道。"

还有一串小的:每个关卡都有一层原版从不渲染的隐藏美术层(门开或假墙塌时才露出),"忠实渲染"的结果是每扇暗门从一开始就敞着;敌人先于玩家移动会让蹦床跳被计两次,一蹦二十格;一个写着 "p1,p2,p3,p4"(四棵棕榈)的门被当成了一把名字奇怪的单钥匙,教程出口永远打不开。作者自己 2010 年手写移植时也犯过同类错误——"只是我花了好几个月,慢慢地犯。"

连上架都是它干的

发布工作也是 AI 干的:五种像素尺寸、十一种语言的截图(截图从游戏本体启动生成,AI 从不渲染商店图里的文字——都是真字体真翻译,出过错:俄语和韩语字幕一度变成一排行空格);商店文案;Steam 的网页表单它用浏览器驱动填写,登录和所有"提交/发布/定价"按钮由作者来按。

它还读了十五年来的全部评论——Google Play 官方 API 只给最近七天,剩下的用公开爬虫一语言一语言拉。然后列出哪些评论描述的是真实缺陷,作者批准了清单。其中有一条一星差评,拼写糟糕,平时会直接划过去的那种:

"第一关的门过不去。开了但关卡不结束。"

按字面读,这是个 bug 报告,而且是对的:游戏里"开门"和"走过门"是两个动作,提示存在于全部十一种语言里,但只放在了十八个关卡中的两个——恰好漏掉了最后一个免费关卡。于是那个正在决定这游戏值不值得付费的玩家,站在一扇敞开的门前不知道该干嘛,得出结论:游戏坏了。这个 bug 十五年没人发现,测试员没发现,两次重建也没发现,最后被一个陌生人的一星差评揪了出来。修复以 2.0.3 推送。作者说:"那条评论我留着。"

一个人的重制,意味着什么

"我没做这次移植。我提出要求、每晚玩结果、说哪里不对,然后做那几个需要 1993 年的我在场的决定。文件格式和汇编阅读是 AI 的活,怎么把三十年前的代码搬过来也是它的决定,而且它干得比我跟进的速度还快。"

原版游戏现在免费发布在 itch.io(配 FS-UAE 等模拟器运行);Definitive Edition 已上 iOS 和 Android,Steam 版(Windows/Mac/Linux)今秋发售,内含 1993 原版作为第二个可启动项。游戏本体不含任何 Amiga 代码——数据被一次性解码成 PNG/WAV/JSON,行为用 GDScript 重写。想要真家伙?下载免费镜像和模拟器。

这篇文章本身也是这么写出来的:作者把移植笔记、对旧游戏关键部分的记忆、两个代码库的仓库扔给模型,它出了初稿,作者逐行改了一周。代码、时间戳和截图都是真的。他自己唯一没亲自验证的,是那 108 字节的解释——"模型告诉我那是运行后内存快照的残留,我读过去就继续了,到现在也没自己查过。"

对一个独立开发者来说,这个故事最有价值的部分不是"AI 能搬代码",而是分工的边界清晰地显现出来:机器擅长逐字节的忠实与大规模的重写,人负责那些"得在场才知道"的东西——手感、节奏、一个 1993 年才存在的拼写错误、一段只有握着手机绕开电视 bug 才记得的历史。AI 让一个人的产能接近一支团队,但"这游戏对不对"的最终裁判,仍然只能是那个 33 年前坐在巴格达、对着 50 度高温和每天几小时电写游戏的人。

分享到
微博Twitter

© 2026 四月

原文链接:https://www.aprilzz.com/indie/amiga-game-llm-godot-port