Rabah Shihab built Babylonian Twins in Baghdad in 1993 — pure 68000 assembly on an Amiga 500 (512KB RAM, no hard drive), the first commercial game made in Iraq, shelved for years after Commodore collapsed. In 2026 he gave the sources to Claude Fable 5 in Claude Code and let it port the game to Godot — and then read what it had done weeks later. This is that postmortem, written with the same LLM but edited line-by-line over a week. What the AI shipped is remarkable; what it got wrong is the instructive part.
Three conditional asks, all three worked
- Step 1 (the control): his own 2010 iOS engine — 34,000 lines of C++ — moved into Godot 4. 21 minutes from empty project to a playable character; all 38 entity types and the full screen flow by 2:15 AM. Getting it to feel right took three more days (jump arcs, trampoline timing, hit detection)
- Step 2 (the unfair ask): the original 72,758 lines of 68000 assembly, for a machine out of production, rebuilt in Godot at the Amiga’s 50 Hz
- Step 3 (the greedy ask): the 1993 original running inside the modern game — one evening of work, not the week he assumed; the retro game runs as a guest at 50 Hz and the engine switches back to 60
The discipline that made it verifiable
- Claude Code ran the real toolchain: vasm to assemble, FS-UAE to boot, byte-identical output against the shipped binaries as the bar
- It added CLI flags so “does the jump feel right” became machine-readable (
--drivescripts button presses frame by frame,--probedumps switch/door/key state) - The 108 bytes: shipped Amiga files were memory snapshots saved after the game had run, not clean assembler output — fresh assembly has zeros where the disk had variable values. From then on, every claim about the game was settled by comparing bytes
- The author’s honest caveat: this explanation is the part he never personally verified
Reverse-engineering 1993 formats by reading the code that reads them
- Levels: no header, no dimensions, inside a compressed chunk. The LLM found the drawing routine, inferred width/height from constants, produced all five maps on the first pass, then pixel-compared against 2020 captures — zero differing pixels once it accounted for two copper effects (sky gradient, water color cycle)
- Map cell properties: each cell is one 16-bit word — 6 bits of “what this square does” (1 solid, 2-3 climbable, 10-13 hurts-with-direction, 14 kills, 63 door), 1 bank bit, 8 tile bits. Recovered because two routines read the same word and each revealed half
- Object tables: enemies are word rows — marker, frame, position, then behavior attached as a named offset (
SahamR-grb; saham is Arabic for arrow). The LLM found the routine that walks the tables and let it name the fields - The 1993 map editor (MEDITOR.S, written in four days in February 1993) was assembled, pointed at the real Level 2 data, and booted in an emulator to prove the formats
- Doors aren’t in the map — the author was sure they were. An 18-byte object record stamps doors onto the map at runtime. That’s why naively porting the level data leaves doorways full of sky
- Sprite sheet ambiguity: Amiga planar formats make
frames × width × height × 2 × 5ambiguous (double-width frames vs. two facing rows — both fit every byte). The LLM flagged it and asked; it was two facing rows
Where it went wrong (the part worth studying)
- The guard bug: a doorman’s shove is fenced on both sides (
4 rows below? not my problem/too far above? also not my problem). The port kept the lower bound and dropped the upper — a shove meant for three rows ran the whole map column, through solid rock, into a corridor the guard never appears in - Hidden second tile layers (secret passages behind doors/fake walls) rendered “faithfully” = every secret standing open from the start
- Moving enemies before players instead of after → a trampoline jump counted twice, 20 tiles in the air
- A sound-loop length computed as stereo when effects are mono cut every sound off halfway
- A feature he requested (twins swapping at any distance) corrupted statues — the proximity check was never a distance limit; the idle twin is stamped into the map as a statue, and two stamped statues eat each other’s tiles. He killed the feature on the 1993 build
- The trampoline bug: physics was provably right (simulation predicted 19.1 tiles, build measured 19.5). It was input semantics — a tvOS workaround made the 2010 build read a held jump as released until re-pressed; Godot polls input and kept reporting the hold. The source doesn’t record this anywhere: “You’d have to have been there, holding the phone, working around a bug in a television”
- A stranger’s one-star review (“cant get through door on level one”) exposed a real 15-year-old bug no tester or rebuild found: opening the exit and walking through are two separate actions, and the prompt explaining that was missing from the last free level. Fixed as 2.0.3. He keeps the review
What shipped
- The download contains no Amiga code: data (packed chunks, planar graphics, music) decoded once by Python scripts into PNG/WAV/JSON; behavior rewritten in GDScript. The real thing is a free disk image + emulator
- Release work automated: screenshots at five sizes in eleven languages rendered from the real game with real fonts (AI never renders store-image text), store listings, icons, Steamworks forms driven through the browser — human presses submit/publish/release
- Original 1993 game free on itch.io; Definitive Edition live on iOS/Android with a Steam release (Windows/Mac/Linux) this fall, the 1993 game inside as a second launch option
“It took me weeks to see that this was the most important thing in the project, and that nobody had asked for it. From then on, every claim about this game could be settled by comparing bytes. I wouldn’t have done it myself.” — Rabah Shihab, on the byte-identical rebuild
“I made the same kind of mistake myself in 2010, slowly, over months.” — Rabah Shihab, on the guard bug