Porting my 1993 Amiga game to Godot, with an LLM reading the 68000 assembly
Porting my 1993 Amiga game to Godot, with an LLM reading the 68000 assembly
By Rabah Shihab | September 1, 2026
In 1993, while living in Baghdad, I developed a game titled Babylonian Twins. The hardware constraints were extreme: an Amiga 500 with only 512KB of RAM, no hard drive, and a standard TV for a monitor.
The 1993 Technical Landscape
The game was written entirely in pure 68000 assembly. Every single scanline and sprite was meticulously crafted by hand.
| Role | Contributor |
|---|---|
| Programming | Rabah Shihab |
| Art | Murtadha Salman |
| Music | Mahir AlSalman |
The development environment was primitive. I had no internet access and no modern tutorials—only a single copy of the Amiga Hardware Reference Manual. I programmed the hardware directly, often working during the few hours a day when electricity was available. The conditions were brutal; the disk drive survived the disk drive died three times due to the 50°C summer heat and the constant swapping of floppy disks necessitated by the limited memory.
On the Amiga, "by hand" means the game doesn't ask the operating system for anything while it runs.
At startup, the game would seize total control of the machine by saving interrupt vectors and disabling OS interrupts:
move.l #$dff000,a0 ;Base for hardware registers
lea save(pc),a1 ;Get the system
move.w # $4000 ,intena(A0) ;from the AMIGA
(Note: The comment "from the AMIGA" was written by me in 1993).
From that moment, the game managed everything:
- Visuals: The display used a custom copper list (the Amiga's programmable video coprocessor), which was updated in real-time for sky colors and sprites.
- Movement: Tiles were moved by writing directly to the blitter's registers and polling the "done" flag.
- Input: The joystick was read from the hardware port; the fire button was mapped to a single pin on a CIA chip.
The OS was only re-engaged between levels to load new files from the disk.
A Long Road to Rediscovery
Babylonian Twins was the first commercial game produced in Iraq, but it remained obscure for years. Between the collapse of Commodore and the chilling effect of sanctions on publishers, the game simply sat on a shelf.
It wasn't until 2008 that an Amiga forum discovered the game via my brother's YouTube uploads. They tracked me down to acquire the original disks. Later, the original team rebuilt the game for the iPhone using a custom engine—roughly 34,000 lines of C++—developed over countless nights and weekends. This version was featured by both Apple and Google, eventually surpassing two million downloads.
The Modern Port: Enter the LLM
Recently, I decided to move the game to Godot 4. While I provided the creative direction and "feel" checks, the heavy lifting—reading assembly and handling file formats—was performed by an AI.
A year prior, I had tried using an LLM to decode my binary level maps. It eventually succeeded, but only after significant prompting and hints. I suspected that 68000 assembly is underrepresented in LLM training sets; if a model is truly "reasoning" rather than "recalling," this is where it proves itself.
For the July 4th weekend, I structured the project into three specific goals:
The Implementation Process
I utilized Claude Code, giving the AI access to my terminal and filesystem. This allowed it to:
- Edit files.
- Run the assembler (
vasm). - Build and launch the game.
- Diff the output to verify that rebuilt binaries matched the 1993 originals.
To automate testing, the AI added several command-line flags:
--level=<name>: Direct level loading.--pose=<spec>: Precise twin positioning.--drive=<spec>: Scripted frame-by-frame input.--probe: Dumps the state of gates, doors, and keys.--screenshot=<path>: Renders a frame and exits.
This transformed subjective questions like "Does the jump feel right?" into machine-readable data:
drive[btw_jump:2.2] pos=(25.44, 24.04) vel=(0.00, -14.51) ground=false apex_y=22.48
The AI also implemented two headless checks: one to compile all scripts and another to validate every level build. For the Amiga side, it managed the toolchain via vasm and FS-UAE.
The Results
Step One: The "Safe Ask" The 34,000 lines of C++ were ported in a single Wednesday evening.
| Time | Milestone |
|---|---|
| 22:23 | Godot 4 scaffold, asset sync, TMX pipeline |
| 22:44 | Playable twins (collision, physics, camera) |
| 23:19 | All 38 entity types ported |
| 00:35 | Full game flow (menus, story, saves) |
| 02:15 | Exported to macOS, iOS, and Android |
It took only twenty-one minutes to go from an empty project to a playable character.
Refining the "Feel" While the code moved quickly, the nuance took longer. Over July 2nd, 3rd, and 4th, I worked in batches to fix:
- Jump arcs
- Trampoline timing
- Hit detection (rewarding "mashing")
This phase became an unexpected bonding experience with my son. He had always known I made the game, but he had never seen me actually working on it.
Technical Constants
To ensure consistency across versions, the game maintains the same internal logic:
- Update Rate: Fixed .
- Coordinate System: Gameplay state is tracked in tile units, where:
Visualizing the transition from 68k Assembly to Godot 4.