
- 7万2758行の68000アセンブリをLLMが解析し、vasmで当時のバイナリをバイト一致で再現した
- Claude Code上でLLMがビルドやゲーム起動を自律的に繰り返し、自動テスト用のフラグも追加した
- Godot標準のCharacterBody2Dを使わず、独自の衝突判定をそのまま移植して操作感を維持した
何が起きたのか
開発者は1993年、イラクのバグダッドでAmiga 500向けのゲーム「Babylonian Twins」を制作した。512KBのメモリしかない環境で、グラフィックスやサウンドを68000アセンブリで直接制御しており、このゲームはイラクで初めて商業公開されたゲームだったとされる。その後、2010年にiPhone向けへ約34,000行のC++で手作業移植され、AppleとGoogleで特集されて約200万ダウンロードを超えた。
今回の記事では、同じ作者がLLMを使い、2010年版のC++エンジンと1993年版の68000アセンブリをそれぞれGodot 4へ移植した過程が報告されている。使われたのはClaude Fable 5というモデルで、作業は3段階に分かれ、最初にC++エンジンをGodotへ移し、次にアセンブリ版をGodot上で再現し、最後に2つを1つのアプリから起動できるようにした。すべて成功したという。
LLMは何をしたのか
作業環境はClaude Codeだ。LLMはターミナルとファイルシステムにアクセスでき、ファイル編集、アセンブラの実行、ゲームのビルドと起動、出力の確認までを自動的に行えた。実際にvasmを使って1993年のソースを組み立て直し、当時のバイナリとdiffを取って一致させる作業から始めている。
アセンブラの方言差にも対応が必要だった。当時の開発環境ASM-Oneとvasmでは、cmp命令のエンコーディングや、データを特定アドレスに配置するorgの挙動が異なるため、LLMはそれらの差分を埋める前処理を書いた。さらに、出荷済みバイナリが実行後のメモリを保存したスナップショットであることも判明し、変数領域に約108バイトの差があることが確かめられた。
移植先で変えなかったこと
注目すべきは、Godotが標準で用意するCharacterBody2Dやmove_and_slide()をプレイヤーに使っていない点だ。オリジナルの手書き移動処理と約150行の衝突判定をNode2D上にほぼそのまま移植し、当時の操作感を保った。コードの中には、作者が15年前に感覚で入れた0.49という数値や、未来の自分に向けたコメントも残っている。
実行レートも分けて維持している。2010年のiOS版は60Hzで動くように調整されていたが、1993年のAmiga版は50Hzだ。速度に毎フレーム0.85を掛けるような処理は、フレームレートが変わると結果が違ってくるため、2つの時計を統一せず、それぞれのレートで動かす判断をしている。
見えた限界と課題
一方で、自動化の範囲には限界がある。LLMはゲームのスクリーンショットを出力するが、その画像を人間が見て判断する必要があり、現代版と旧版の自動的な画像比較は行っていない。操作感についても、作者と13歳の息子が実際に遊んで確認したとされている。
作者は数週間後にコードを読み返し、一部の判断が誤っていたことも報告している。ASM-One独自のorgを処理する最初の回避策が誤り、ファイル内の後続データが944バイトずれたケースがあった。LLMの出力を追跡可能な形で検証する仕組みの重要性が、この事例からは見えてくる。
| 比較項目 | 2010年C++エンジン | 1993年Amiga版 |
|---|---|---|
| 対象だったコード | 34,000行のC++ | 72,758行の68000アセンブリ |
| 元の実行環境 | iPhone向け(60Hz) | Amiga 500(50Hz) |
| Godot上での扱い | 60Hzの実行レートを維持 | 50Hzの実行レートを維持 |
| 移植時の判断基準 | 既存コードの移動 | バイナリのバイト一致を再現 |
From then on, every claim about this game could be settled by comparing bytes.
それ以降、このゲームに関するあらゆる主張は、バイト同士を比較することで検証できるようになった。
今後の見通し
今回の記事は単なる成功談ではなく、LLMが誤った判断をしたことや、数週間気づかれなかった問題にも触れている。今後、同じ手法が他のレトロゲームや古いコードベースに適用され、成功・失敗事例が蓄積されれば、LLMによる移行作業の適用範囲がより明確になるだろう。特に、バイト一致のような自動検証が使える領域と、人間の確認が必要な領域の切り分けが進むかどうかが、実務での採用判断を左右しそうだ。
日本の開発者・IT企業にとっての意味
日本では、古いゲームや業務システムのソースコードが残っていても、言語や実行環境の変化で再ビルドすらできないケースは少なくない。今回の事例は、LLMにビルドツールと実行環境を与え、バイト一致という明確な基準を用意すれば、レトロなアセンブリコードでも現行エンジンへ移植できる可能性を示している。一方で、操作感のような定性的な品質はLLMでは判定できず、作者自身による数週間の確認が必要だった。日本の開発現場でも、人手では追いきれないコードの調査にLLMを使う際は、機械的に検証できる基準と、人間による最終確認をセットで設計することが重要になりそうだ。
気になる点
- 今回の移植には、どのLLMが使われたのか?
- 記事ではClaude Fable 5と紹介されている。実行はターミナル上で動くClaude Codeを使い、ファイルシステムやビルドツールに触れられる状態で作業させたとされる。モデルの正確な仕様や利用条件は記事では公表されていない。
- 実際にバイト一致まで再現できたのか?
- 再現できたと記事にはある。1993年当時のソースをApple Silicon Mac上でvasmを使って組み立て直し、出荷バイナリとdiffを取って一致を確認した。ただし出荷ディスクは実行後のメモリ保存由来のデータであるため、変数領域には約108バイトの差が残ることも判明している。
用語解説
- Godot
- 2D・3Dゲーム向けのオープンソースゲームエンジン。シーン管理やスクリプト言語を持ち、複数プラットフォーム向けに書き出せる。
- 68000アセンブリ
- モトローラのCPU「68000」向けの低水準言語。機械語に近く、ハードウェアを直接制御するために使われる。
- Claude Code
- LLMをターミナル上で操作し、ファイル編集やコマンド実行を行わせる対話環境。エージェント的にビルドやテストを進められる。
- vasm
- 複数のCPUに対応するアセンブラ。アセンブリ言語で書かれたソースを機械語のバイナリに変換する。
- FS-UAE
- Amigaをエミュレーションするソフトウェア。記事では再現したバイナリが実際に起動するかの確認に使われた。
- CharacterBody2D
- Godotが提供するキャラクター移動用の物理ボディ。move_and_slide()などで地面や壁との衝突を処理する。
出典
Porting my 1993 Amiga game to Godot, with an LLM reading the 68000 assembly
https://babyloniantwins.com/blog/porting-a-1993-amiga-game-to-godot
AI導入も顧問も、お任せください
何から手をつけるか、どこまでAIに任せるか。自社の業務に合わせて整理し、導入から運用まで伴走します。相談だけでも構いません。
AI導入について相談する