Back
Hhackernews·rabahs
Breakout · 2.5×25
·12 hr ago·Other · Official API

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

View original
Open source

Heat trend

Collecting trend data

The percentage is based on available heat signal, not comment count or independent people.

Breakout verdict
Basis
Running about 2.5× the median of this source's recent listed items
Metric comparison
133 vs median 54 (20 baseline samples)
Detected
09/03, 22:01
AI summary

A developer is porting their 1993 Amiga game, Babylonian Twins, to Godot. The original game was built in Baghdad on an Amiga 500 with 512KB RAM, programmed in pure 68000 assembly using only the Amiga Hardware Reference Manual. An LLM is assisting with reading the 68000 assembly code. Challenges include managing memory constraints, with one level map using 74,400 of 74,752 bytes, and discrepancies between assemblers like ASM-One and vasm regarding memory allocation and object behavior attachments.

In 1993, in Baghdad, I built a game called Babylonian Twins on an Amiga 500: 512KB of RAM, no hard drive, plugged into a TV. I was an engineering student in my twenties. Pure 68000 assembly, every sprite and every scanline by hand. Murtadha Salman drew the art and Mahir AlSalman composed the music. We were under sanctions. No internet, no game development resources, just one copy of the Amiga Hardware Reference Manual, which I used to program the hardware directly, and electricity a few hours a day. The constant floppy disk swapping (because of the small memory) and the 50°C summers killed my disk drive three times.

Left: 1993, on the Amiga. Right: 2026, the same gateway.

On the Amiga, “by hand” means the game doesn’t ask the operating system for anything while it runs. At startup it saves the interrupt vectors, switches the OS interrupts off and takes the whole machine:

move.l #$dff000,a0 ;Base for hardware registers lea save(pc),a1 ;Get the system move.w # $4000 ,intena(A0) ;from the AMIGA

“Get the system from the AMIGA” is my comment, from 1993. From that point on the display is the game’s own copper list (the Amiga’s programmable video coprocessor), rewritten on the fly for sprites and sky colours. Tiles move by writing the blitter’s registers directly and waiting on its done flag. The joystick is read straight from the hardware port, and the fire button is one pin on a CIA chip. The OS comes back only between levels, to load the next level’s files from the disk, and then it’s switched off again.

It was the first commercial game made in Iraq, and for a long time a game very few people got to play. Commodore collapsed and sanctions scared off publishers, so the finished game sat on a shelf. An Amiga forum found it in 2008 from my brother’s YouTube uploads and hunted me down for the disks; the thread is still there.

The game has been ported once before, by hand, in 2010. The same team rebuilt it for the iPhone on an engine written from scratch, about 34,000 lines of C++, over months of nights and weekends. Apple and Google featured it, and it reached over two million downloads. That story is here.

I didn’t do this port. I asked for it, played the result every night, said what felt wrong, and made the few decisions that needed somebody who was there in 1993. The file formats and the assembly reading were the AI’s work, and so were the decisions about how to carry thirty-year-old code across, and it went faster than I could follow. This post is what I found when I sat down weeks later and read what had been done to my own game. Some of it was wrong, and I didn’t notice for weeks.

Why I tried again

I’d tried this before. About a year ago I gave an earlier model the same Amiga material and asked it to make sense of my binary level maps. It got there in the end, but it took several rounds and a lot of hints from me.

Then Claude Fable 5 shipped, and I gave it the same files.

The test was deliberate. My guess was that there is little Amiga assembly code in LLM training sets. If the model was better at working things out rather than recalling them, this is where it would show.

The July 4th weekend was coming up, so I planned three steps, each one conditional on the previous working.

Step one, the safe ask: my own 2010 engine, the 34,000 lines of C++, moved into Godot 4. This was the control.

Step two, the unfair ask: the original 72,758 lines of 68000 assembly, for a machine that had gone out of production, with no comments to speak of and nothing in common with the C++. Rebuild that in Godot too, at the Amiga’s original 50 Hz.

Step three, the greedy ask: put the second one inside the first, so buying the modern game gets you the 1993 original as a second thing you can launch.

All three worked. The level format that had taken several rounds and my corrections a year earlier came out in a single pass, with no hints from me.

How it was run

I ran it in Claude Code, so it had a terminal and my filesystem. It could edit files, run the assembler, build the game, launch the game and read what came back. When I say below that it rebuilt my 1993 binaries and checked them, it did that by running vasm and diffing the output.

Early on it added a set of command-line flags to the game so it could play without me:

--level= load a level directly --pose= put the twins at exact positions --drive= press buttons on a script, frame by frame --probe dump switch / gate / door / key state --screenshot= render a frame and quit

Which turns “does the jump feel right” into something a machine can read:

drive[btw_jump:2.2] pos=(25.44, 24.04) vel=(0.00, -14.51) ground=false apex_y=22.48

It also had two headless checks it could run before showing me anything: one that compiles every script, and one that builds every level and reports failures. On the Amiga side it drove the real toolchain, vasm to assemble and FS-UAE to boot the result. What wasn’t automated: there was no image comparison on the modern port (it took screenshots, I looked at them), and nothing checked whether the game felt right.