logo
Kurashizu Blogwhere ideas flow
  • Home
  • News
  • Blog
  • About
  • Home
  • News
  • Blog
  • About

© 2026 Kurashizu. All rights reserved.

Admin·New Post·Service Status
Powered by Cloudflare·31.10.26
← Back to news

Porting my 1993 Amiga game to Godot, with an LLM reading the 68000 assembly

Original article
babyloniantwins.com|357 points|123 comments|by rabahs|Sep 3, 2026

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.

RoleContributor
ProgrammingRabah Shihab
ArtMurtadha Salman
MusicMahir 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:

  1. Edit files.
  2. Run the assembler (vasm).
  3. Build and launch the game.
  4. 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.

TimeMilestone
22:23Godot 4 scaffold, asset sync, TMX pipeline
22:44Playable twins (collision, physics, camera)
23:19All 38 entity types ported
00:35Full game flow (menus, story, saves)
02:15Exported 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 60Hz60\text{Hz}60Hz.
  • Coordinate System: Gameplay state is tracked in tile units, where: 1.0 unit=48px tile\text{1.0 unit} = 48\text{px tile}1.0 unit=48px tile

Amiga Game Concept Visualizing the transition from 68k Assembly to Godot 4.