Skip to the page
It's Decomplicated
Commodore, 1985

Amiga decomp guide

No ready recompiler exists. You build a small one per game, and tests keep it honest.

What this system is like

Amiga games run on a Motorola 68000 chip. Most games skip the operating system and drive the custom chips directly. Many were written by hand in assembly, not in C. So there is no shared tool like the ones other systems have.

For Path A, every reviewed recomp wrote its own small recompiler. A recompiler turns the game's machine code into C. Three AI-assisted ports took an easier first step. They ran the original code on a tiny Amiga model built for that one game. Then they swapped in C code piece by piece.

Path B means a byte-exact rebuild of the game first. You disassemble it with IRA and assemble it again with vasm. The hash must match. Then you turn each routine into C, with a test against an emulator for each one. No reviewed project is a byte-matching C decomp. The closest is ReDMCSB, a C rebuild of Dungeon Master. Its site says each build is the same as the original or very close.

Most steps run on Windows. WSL is handy for scripts, IRA and make. Expect weeks for Path A and many months for Path B.

No shared recompiler

N64 has N64Recomp. The Amiga has nothing like it. DuckTales wrote its recompiler in Python. James Pond 2 wrote one in C++. Plan to write and test your own.

Games own the hardware

Most action games turn the OS off and program the chips directly. So you model the copper, blitter, Paula and the two CIA timer chips. Timing details matter, like when an interrupt fires.

Many games load their own tracks

A lot of disks have no file system. The game reads raw tracks with its own loader, often with copy protection. Ports replace that loader with a plain file read from a WHDLoad install or an .adf.

Assembly, not C

Most action games were hand-written 68000 assembly. There is no C compiler to match. Path B here is a byte-exact rebuild of the assembly, then C that passes tests. A few games were C, like DuckTales with Aztec C.

Strong reference tools

Musashi and Moira are free 68000 cores you can link into your own program. They give you a reference to test every translated instruction. WinUAE has a full debugger for checking real behavior.

Many disk formats

The same game can come as .adf, .ipf, .dms, raw tracks or a WHDLoad folder. Reviewed ports pick one or two and check each file by SHA-256. Pick your formats early.

Two paths

Path A

Get it running on PC

First you run the game's own 68000 code on a tiny Amiga model in C or C++. It uses a free CPU core like Musashi or Moira. That gives you a playable build and a reference. Then a recompiler you write turns the code into C, one routine at a time. An interpreter catches any code the recompiler missed. A test compares every translated instruction with the interpreter.

Go to the steps

Path B

Full decomp for porting

Most Amiga games were hand-written assembly, so there is no C to match. You first rebuild the game file byte for byte from a labeled disassembly. Then you name every routine. Then you turn each routine into C and test it against the 68000 core. Last, you run the whole game in lockstep with the original and port it.

Go to the steps

Path A: Get it running on PC

First you run the game's own 68000 code on a tiny Amiga model in C or C++. It uses a free CPU core like Musashi or Moira. That gives you a playable build and a reference. Then a recompiler you write turns the code into C, one routine at a time. An interpreter catches any code the recompiler missed. A test compares every translated instruction with the interpreter.

Method: game-specific static recompilation, built on a small interpreter machine first

Pick this first for any game. It is the fastest route to a running game, and the tests and maps help Path B later. If the game's source was released, like Gloom, read that first instead.

  1. Pick the game and pin its files

    You choose one game and one exact release. Amiga games come in many disk forms. You hash each game file, not only the whole disk. You also look for work that already exists.

    • Keep your own disk images in a folder outside the repo, like D:/amiga-games/<GAME>/.
    • In WSL, try xdftool disk1.adf list. If it lists files, the game is an AmigaDOS program. If it fails, the game uses its own track loader.
    • Unpack a DOS disk outside the repo with xdftool disk1.adf unpack <OUT_DIR>, then run sha256sum on each file.
    • Note the chip set (OCS or ECS for A500, AGA for A1200) and the disk format (.adf, .ipf or WHDLoad).
    • Search RecompLauncher, GitHub and the WHDLoad site for prior work. Check for a source release, like the one Gloom had.
    • Write SCOPE.md: game, release, file hashes, chip set, goal, technique, first milestone and its check.
    Prompt for Claude
    GOAL: Draft SCOPE.md for a Path A port of <GAME> (<RELEASE>, <CHIPSET>).
    READ FIRST: `xdftool <ABSOLUTE_PATH_TO_ADF> list` output, https://www.whdload.de/, https://github.com/cnvogelg/amitools
    FENCE: Create only `SCOPE.md`, `notes/hashes.sha256` and `notes/prior-work.md`. Do not copy any game file into the repo. Do not write code.
    CHECK: Run `sha256sum -c <ABSOLUTE_PATH_TO_REPO>/notes/hashes.sha256` inside the unpacked game folder. Done means it prints OK for every file, and SCOPE.md lists every game file with its SHA-256, the disk format, DOS or track loader, the chip set, prior work with links, the first milestone and its check, and an out-of-scope list.
    BUDGET: Stop after 45 minutes of searching for prior work.
    IF BLOCKED: Stop. Do not guess a release or a hash. Tell me what is missing.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the xdftool and sha256sum output. 3) Files changed. 4) Prior work found, with links. 5) New parking-lot items.
    Done whensha256sum -c notes/hashes.sha256 prints OK for every game file, SCOPE.md names the disk type, and you approved it.

    Proof this works: Lightmere, BloodCash, ZGloom-x86, https://amitools.readthedocs.io/en/latest/tools/xdftool.html

  2. Set up the repo, tools and one check

    You make a repo that holds only your code. Game files and machine-made C stay out of git. You install the build tools and the CPU core. You write one command that builds and runs a headless test.

    • In WSL: sudo apt install build-essential cmake ninja-build git python3-venv libsdl2-dev lhasa.
    • Make a Python venv, then pip install amitools capstone ziglang.
    • Outside the repo, build IRA (see its tool entry) and clone amiga68ktools. Step 3 uses both.
    • Add the CPU core as a pinned submodule: git submodule add https://github.com/kstenerud/Musashi vendor/musashi.
    • On Windows, the sanviler ports use Visual Studio 2022 with vcpkg: cmake --preset windows-vcpkg then cmake --build --preset release.
    • Put *.adf, *.ipf, *.dms, gamedata/, build/ and gen/ in .gitignore before the first commit.
    • Write tools/check.sh. It regenerates, builds and runs the game headless for a set number of frames.
    • Write CLAUDE.md, PROGRESS.md and an empty notes/parking-lot.md.
    Prompt for Claude
    GOAL: Make one command, `tools/check.sh`, that builds the <GAME> port and runs it headless for <N> frames.
    READ FIRST: `SCOPE.md`, `vendor/musashi/readme.txt`, `CMakeLists.txt`.
    FENCE: Edit only `tools/check.sh`, `CMakeLists.txt`, `.gitignore`, `CLAUDE.md`, `PROGRESS.md`. Do not edit anything in `vendor/`. Do not add features or tools I did not ask for.
    CHECK: Run `bash tools/check.sh`. Done means it builds with CMake and Ninja and exits 0. Then break one source file on purpose and show the script exits non-zero.
    BUDGET: Stop after 3 failed tries at the same error.
    IF BLOCKED: Stop. Do not work around a missing package. Tell me the exact error and the command.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste both check outputs. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenbash tools/check.sh exits 0, and exits non-zero when you break the build.

    Proof this works: James Pond 2: Codename RoboCod - Recompiled, Lightmere, DuckTales Amiga Recompilation

  3. Map the game code

    You find out how the game loads and where its code is. You list every routine, the OS calls, the chip register writes and the disk loader. You also mark code that changes itself. This map becomes your ledger.

    • For a DOS game, run hunktool info -d <GAME_EXE>. It dumps the hunk structure: hunks, sizes and overlays. Add -R to see each relocation.
    • Load the program in Ghidra 12.2 with the ghidra_amiga_ldr add-on. The add-on picks Ghidra's built-in 68000 family language, so you need no CPU add-on.
    • Make a text listing too: ira -A -KEEPZH -NEWSTYLE -COMPAT=bi -PREPROC <GAME_EXE>. It writes <GAME_EXE>.asm and a .cnf config.
    • For a track-loader game, boot it in WinUAE with 1 MB chip RAM and no fast RAM. Open the debugger with Shift+F12. Save RAM with S dump.bin 0 $100000.
    • Mark OS calls (JSR -n(A6)), writes to $DFF000 and up, the disk loader, interrupt handlers and copper lists.
    • Flag self-modifying code with amiga68ktools: python3 <AMIGA68KTOOLS>/68kchecker/m68kchecker.py -i <GAME_EXE>.asm > notes/smc.txt. Its hits are guesses, so check each one.
    • Write ledger/functions.csv: address, size, name, kind, status.
    Prompt for Claude
    GOAL: Write `ledger/functions.csv` and `notes/map.md` for <GAME>: routines, OS calls, chip writes, disk loader, interrupts and self-modifying code.
    READ FIRST: `SCOPE.md`, `hunktool info -d <ABSOLUTE_PATH_TO_EXE>` output, the IRA listing `<ABSOLUTE_PATH_TO_ASM>` (search it, do not read it whole), http://amigadev.elowar.com/read/ADCD_2.1/Hardware_Manual_guide/node0000.html
    FENCE: Edit only `ledger/functions.csv`, `notes/map.md` and `tools/make_ledger.py`. Do not edit game files or the IRA listing.
    CHECK: Run `python3 tools/make_ledger.py`. Done means one row per routine, the hunk count matches hunktool, and every entry in map.md cites listing lines (address and instruction).
    BUDGET: Stop after 2 hours, or after 20 minutes with no new entry.
    IF BLOCKED: Stop. If the code is packed or loaded from raw tracks, say so and stop. Do not decode bytes by hand.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: row counts per kind. 3) Files changed. 4) Addresses you could not explain. 5) New parking-lot items.
    Done whenpython3 tools/make_ledger.py exits 0, every row in ledger/functions.csv has a status, and its hunk count matches hunktool info -d.

    Proof this works: DuckTales Amiga Recompilation, James Pond 2: Codename RoboCod - Recompiled, https://tetracorp.github.io/guide/reverse-engineering-amiga.html, https://github.com/jotd666/amiga68ktools

  4. Run the original code on a small machine

    This is first light. You run the game's own code on a CPU core with a tiny Amiga model around it. You add only the chip parts the game uses. You replace the disk loader with a file read. No Kickstart ROM is needed.

    • Link Musashi (C) or Moira (C++) as the CPU. Give it chip RAM and the custom chip registers.
    • Load the hunks yourself and apply the relocations. For a track loader, load the RAM dump or the boot code.
    • Hook the loader's address and read straight from the user's files, as BloodCash and Lightmere do.
    • Answer only the OS calls the game makes. DuckTales handled about 70 library calls this way.
    • Add a headless mode: no window, scripted keys by frame number, and a screenshot at frame N. James Pond 2 has --headless N, --input and --shot F:file.png.
    Prompt for Claude
    GOAL: Boot <GAME> to its title screen on the interpreter machine, headless.
    READ FIRST: `SCOPE.md`, `notes/map.md` (loader and OS call sections), `vendor/musashi/m68k.h`.
    FENCE: Edit only `runtime/` and `tools/check.sh`. Do not edit game files. No Kickstart ROM. No game bytes in source files.
    CHECK: Run `bash tools/check.sh`, then `build/<GAME> --headless <N> --shot <N>:logs/title.png`. Done means it exits 0 and logs/title.png shows the title screen.
    BUDGET: Stop after 3 failed tries at the same crash, or 2 hours.
    IF BLOCKED: Stop. Tell me the last PC address, the last OS call or chip write, and what you tried.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: run output and the screenshot path. 3) Files changed. 4) OS calls and chip parts still faked. 5) New parking-lot items.
    Done whenbuild/<GAME> --headless <N> --shot <N>:logs/title.png exits 0 and writes the image. You look at it once, then save its SHA-256 in tests/expected/title.sha256, so later runs check it by script.

    Proof this works: BloodCash, Lightmere, Radiant Fighter: A Shadow Fighter Recomp, https://github.com/kstenerud/Musashi, https://dirkwhoffmann.github.io/Moira

  5. Write the recompiler

    Now you turn the code into C. You write a small tool that reads the game file and the ledger. It writes C into gen/ on every build. Code it missed still runs on the interpreter, so the game never stops.

    • Write the tool in Python or C++. DuckTales used tools/analyze.py then tools/recomp.py. James Pond 2 used jp2-recomp.
    • Emit one C function per run of code, with a label per instruction and a dispatcher for jumps through tables.
    • Insert a POLL() call at each backward branch. The runtime then runs frames, interrupts, sound and input.
    • Keep override lists for special routines: replace, gate or add a prologue, like DuckTales does.
    • Mark code that rewrites itself as interpreter-only. James Pond 2 did this for its music player.
    • Regenerate gen/ on every build. Never edit it by hand.
    Prompt for Claude
    GOAL: Make the recompiler turn <HUNK_OR_RANGE> of <GAME> into C in `gen/`, with interpreter fallback for anything it skips.
    READ FIRST: `ledger/functions.csv`, `notes/map.md` (self-modifying code section), `tools/recomp.py`.
    FENCE: Edit only `tools/recomp.py`, `runtime/` and `tools/check.sh`. Never edit files in `gen/`. Do not translate code marked self-modifying.
    CHECK: Run `bash tools/check.sh`, then `build/<GAME> --headless <N> --shot <N>:logs/title_recomp.png`. Done means it exits 0, the shot matches logs/title.png from the interpreter build, and the log prints the count of interpreted addresses.
    BUDGET: Stop after 3 failed builds with the same error.
    IF BLOCKED: Stop. Do not patch generated C. Tell me the first error, the instruction and its address.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: build output, both screenshot paths, the interpreted count. 3) Files changed. 4) Instructions not yet handled. 5) New parking-lot items.
    Done whenThe recompiled build's headless shot at frame N has the hash in tests/expected/title.sha256. The log prints how many addresses still run on the interpreter.

    Proof this works: DuckTales Amiga Recompilation, James Pond 2: Codename RoboCod - Recompiled, Dogs of War Atari ST Recomp

  6. Test every translated instruction

    A build that runs is not proof. You test each translated instruction against the interpreter. Both start from the same random state. Registers, flags and every written byte must match.

    • Have the recompiler write one test per instruction into gen/tests.cpp, like James Pond 2 does.
    • Run each test from a random register, flag and memory state in both the C and Musashi. Compare registers, the status register, the PC and every byte written.
    • Check your own instruction decoder against capstone on every instruction. DuckTales checked 44,545.
    • Add a lockstep run: play the same input in both builds and compare all RAM each frame. Dogs of War did this over all 12 missions.
    • Break one translation on purpose and show the test fails.
    Prompt for Claude
    GOAL: Make `build/<GAME>-difftest` compare every translated instruction with Musashi and report zero mismatches.
    READ FIRST: `tools/recomp.py`, `runtime/cpu.h`, `notes/findings.md`.
    FENCE: Edit only `tools/difftest.cpp`, `tools/recomp.py` (test output only) and `CMakeLists.txt`. Do not change the seed list or skip any instruction.
    CHECK: Run `build/<GAME>-difftest --adf <ABSOLUTE_PATH_TO_GAME>`. Done means it prints zero mismatches. Then break one opcode handler and show it fails with that address.
    BUDGET: Stop after 3 failed tries.
    IF BLOCKED: Stop. List the instructions you cannot set up a fair test for.
    OTHER PROBLEMS: Write mismatches you find in `notes/parking-lot.md`. Do not fix them in this task.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: both outputs. 3) Files changed. 4) Instruction count tested. 5) New parking-lot items.
    Done whenThe difftest passes on every translated instruction, and fails when you break one handler.

    Proof this works: James Pond 2: Codename RoboCod - Recompiled, DuckTales Amiga Recompilation, Dogs of War Atari ST Recomp

  7. Close code gaps and fix chip bugs

    Now you grind. Some code only runs through jump tables, so the recompiler misses it. Some chip behavior is wrong, so pictures or sound break. You fix one gap or one bug per session, with proof first.

    • Record which addresses ran on the interpreter during play. Sweep every level headless with the game's cheat, like James Pond 2's tools/sweep.py.
    • Feed the coverage file back to the recompiler and rebuild. Watch the interpreted count fall.
    • For a chip bug, record the input, then trace it. DuckTales used HLE_TRACE, write watchpoints and memory dumps.
    • Check the same moment in the WinUAE debugger. Use w 1 <ADDR> 4 W to watch writes.
    • Fix the runtime or the recompiler. Rerun the difftest and the check.
    Prompt for Claude
    GOAL: Find and fix the cause of <BUG> seen at frame <N> of `tests/inputs/<ROUTE>.txt`.
    READ FIRST: `notes/map.md`, `notes/findings.md`, the Hardware Reference Manual chapter on <CHIP_PART>, the screenshot `logs/<FILE>.png`.
    FENCE: Edit only `<RUNTIME_OR_RECOMPILER_FILE>` and `notes/findings.md`. Never edit `gen/`. No game-specific hacks in the shared machine code unless I approve them.
    CHECK: Replay the route with a screenshot at frame <N>, then run `build/<GAME>-difftest` and `bash tools/check.sh`. Done means the frame is right and both pass.
    BUDGET: Stop after 2 failed fixes. Write the cause first. No fix before the cause is proven with a trace.
    IF BLOCKED: Stop. Tell me the evidence you have, the ideas you ruled out, and what you need.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: before and after screenshots and the trace lines. 3) Files changed. 4) Cause in one sentence, with addresses and registers. 5) New parking-lot items.
    Done whenEach route in tests/inputs/ gives its expected screenshot hash, and build/<GAME>-difftest passes. The interpreted count is zero, or notes/map.md gives a reason for each address left.

    Proof this works: James Pond 2: Codename RoboCod - Recompiled, DuckTales Amiga Recompilation, https://tetracorp.github.io/guide/uae-debugger-intro.html

  8. Harden it and ship without the game

    You turn your routes into a regression set. Then you package the program. The package holds no game code or data. It checks the player's own files by hash and says plainly why it rejects one.

    • Save a RAM hash or screenshot at set frames for each route. Write tools/regress.sh to replay them all.
    • Check each user file by SHA-256 at start, like Lightmere. Store only the hashes in the repo.
    • Write a package script that refuses to finish if it finds game bytes. DuckTales' make_dist.sh does this.
    • Test at 125% and 150% Windows display scaling. All three sanviler ports had to fix blur there.
    • Unzip the package on a clean PC and run it with your own disks.
    Prompt for Claude
    GOAL: Make `tools/regress.sh` and `tools/package.sh` for <GAME>, so a release is tested and holds no game data.
    READ FIRST: `SCOPE.md`, `PROGRESS.md`, `tests/inputs/`.
    FENCE: Edit only `tools/regress.sh`, `tools/package.sh`, `tests/expected/` for routes I name, and `PROGRESS.md`. Do not put game files, RAM dumps or `gen/` in the package.
    CHECK: Run `bash tools/regress.sh`, then `bash tools/package.sh`. Done means every route passes, the package scan finds zero game bytes, and the unzipped program starts with my files and refuses a wrong one with a clear message.
    BUDGET: Stop after 3 failed tries.
    IF BLOCKED: Stop. Tell me which route is not repeatable, or which file the package needs.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: all three outputs. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenbash tools/regress.sh exits 0 on a fresh clone, bash tools/package.sh reports zero game bytes, and the unzipped program refuses a wrong file with a clear message.

    Proof this works: DuckTales Amiga Recompilation, Lightmere, Dogs of War Atari ST Recomp, BloodCash

Path B: Full decomp for porting

Most Amiga games were hand-written assembly, so there is no C to match. You first rebuild the game file byte for byte from a labeled disassembly. Then you name every routine. Then you turn each routine into C and test it against the 68000 core. Last, you run the whole game in lockstep with the original and port it.

Method: byte-matching reassembly, then C checked by differential tests (non-matching decomp)

Pick this when you want readable source that can move to other systems. Do Path A first, since its maps, coverage and difftest feed this path. If the game was written in C, ask if a matching C decomp is possible with the original compiler.

  1. Find out how the game was built

    You check for prior work and for signs of the original tools. A source release or an old reconstruction can save years. Signs of a C compiler change the plan. You write the scope.

    • Search for a source release, a remake, a WHDLoad install and EAB forum threads about the game.
    • Look for a full reconstruction like ReDMCSB, Christophe Fontanel's C rebuild of Dungeon Master. Its 2021 release builds the Amiga versions too.
    • Look for compiler signs. DuckTales showed Aztec C: an A5 frame pointer and globals read off A4. Hand assembly has no such pattern.
    • Write SCOPE.md: file hashes, assembler or compiler guess with proof, port target, and the checks.
    Prompt for Claude
    GOAL: Find prior work for <GAME> and say how it was built, then draft SCOPE.md for Path B.
    READ FIRST: `notes/map.md` from Path A, the IRA listing `<ABSOLUTE_PATH_TO_ASM>` (search only), https://www.dungeon-master.com/forum/viewtopic.php?t=29805 as an example of a reconstruction.
    FENCE: Create only `SCOPE.md` and `notes/prior-work.md`. Do not download game files or other people's disassemblies of this game into the repo.
    CHECK: Run `sha256sum -c notes/hashes.sha256` in the game folder; it must print OK. Done means SCOPE.md names the build tool guess (assembler or a named C compiler) with at least three listing lines as proof, lists prior work with links and dates, and names the port target.
    BUDGET: Stop after 60 minutes.
    IF BLOCKED: Stop. Say what you could not check.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: the listing lines. 3) Files changed. 4) Your recommended start. 5) New parking-lot items.
    Done whenSCOPE.md names the build tool guess with proof, names the port target, and you approved it.

    Proof this works: DuckTales Amiga Recompilation, ZGloom-x86, https://www.dungeon-master.com/forum/viewtopic.php?t=29805, http://dmweb.free.fr/community/redmcsb/

  2. Rebuild the game file byte for byte

    You turn the game file into assembly that rebuilds it exactly. IRA writes the source. vasm assembles it back into a hunk file. The hash must match. This is the check for the rest of Path B.

    • In WSL, get ira.lha from Aminet and unpack it with lhasa -x ira.lha (sudo apt install lhasa). Then run make in the ira/ folder.
    • In WSL, clone the vasm source mirror and run make CPU=m68k SYNTAX=mot. That builds vasmm68k_mot.
    • Run ira -A -KEEPZH -NEWSTYLE -COMPAT=bi -PREPROC <GAME_EXE>, fix code and data ranges in the .cnf, then run it again with -CONFIG.
    • Assemble: vasmm68k_mot -no-opt -Fhunkexe -nosym -o build/<GAME_EXE> <GAME_EXE>.asm.
    • Write make compare: it builds, then checks sha256sum against the hash in SCOPE.md.
    • For a track-loader game, rebuild the loaded code block as a raw binary instead, and compare that.
    Prompt for Claude
    GOAL: Make `make compare` rebuild <GAME_EXE> from IRA source with vasm and match the SHA-256 in SCOPE.md.
    READ FIRST: `SCOPE.md`, the IRA readme and `ira_config.doc`, https://github.com/StarWolf3000/vasm-mirror
    FENCE: Edit only `Makefile`, `<GAME_EXE>.cnf` and `tools/`. Do not edit the expected hash file. The game file stays at `<ABSOLUTE_PATH_TO_EXE>`.
    CHECK: Run `make compare`. Done means it prints OK with the SCOPE.md hash. Then change one byte in the .asm and show `make compare` fails.
    BUDGET: Stop after 3 failed tries at the same mismatch.
    IF BLOCKED: Stop. Paste the first differing offset from `cmp -l` and the listing lines around it.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: both outputs. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenmake compare prints OK, and fails when one byte is changed.

    Proof this works: https://aminet.net/package/dev/asm/ira, https://tetracorp.github.io/guide/reverse-engineering-amiga.html, https://github.com/StarWolf3000/vasm-mirror

  3. Split code from data and list every routine

    A raw disassembly guesses where code starts. Wrong guesses turn tables into fake code. You feed it real proof of what ran. Then you build the routine ledger.

    • Use the coverage files from Path A. They list every address that ran.
    • Mark code and data ranges in the .cnf with that proof. Rerun IRA with -CONFIG.
    • Run make compare after each change.
    • Write ledger/routines.csv: hunk, offset, size, name, status (raw, named, in C).
    Prompt for Claude
    GOAL: Build `ledger/routines.csv` for <GAME> and a `.cnf` that marks every code and data range.
    READ FIRST: `SCOPE.md`, `coverage/<FILE>` from Path A, `<GAME_EXE>.cnf`.
    FENCE: Edit only `<GAME_EXE>.cnf`, `ledger/routines.csv` and `tools/make_ledger.py`. Do not hand-edit the generated .asm in this task.
    CHECK: Run `make compare`. Done means OK, and every address in the coverage file sits inside a routine in the ledger.
    BUDGET: Stop after 2 hours or 3 failed compares.
    IF BLOCKED: Stop. List the ranges you cannot class as code or data.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: compare output and row counts. 3) Files changed. 4) Unknown ranges. 5) New parking-lot items.
    Done whenmake compare prints OK, and every covered address belongs to a routine in the ledger.

    Proof this works: James Pond 2: Codename RoboCod - Recompiled, https://aminet.net/package/dev/asm/ira

  4. Name one routine end to end

    You take one small routine all the way. You name it, its labels and the RAM it uses. You swap raw numbers for chip register names. The file must still match.

    • Pick a short routine, like the joystick reader.
    • Run python3 <AMIGA68KTOOLS>/tools/cheapres.py -i <GAME_EXE>.asm -o notes/named.asm. It names OS calls and custom chip registers. Copy the names you trust into the .cnf.
    • Add names with SYMBOL, LABEL and COMMENT lines in the .cnf, so names survive a rerun of IRA.
    • Watch the routine's RAM in the WinUAE debugger to confirm what each variable means.
    • Run make compare. Set the ledger status to named.
    Prompt for Claude
    GOAL: Fully name and comment routine <HUNK:OFFSET> in the <GAME> disassembly.
    READ FIRST: the ledger row for <HUNK:OFFSET>, the routine's lines in `<GAME_EXE>.asm`, `notes/ram-map.md`.
    FENCE: Edit only the `.cnf` entries for this routine, `notes/ram-map.md` and its ledger row. Do not change any byte the build emits.
    CHECK: Run `make compare`. Done means OK, no raw chip address is left in the routine, and the ledger row says `named`.
    BUDGET: Stop after 3 failed compares or 30 minutes.
    IF BLOCKED: Stop. Say which value you cannot explain and what you checked.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: compare output and the diff. 3) Files changed. 4) Names you are unsure of. 5) New parking-lot items.
    Done whenmake compare prints OK and the routine has names in place of raw addresses.

    Proof this works: https://github.com/jotd666/amiga68ktools, https://tetracorp.github.io/guide/uae-debugger-intro.html

  5. Name every routine in parallel

    Now you repeat the unit loop many times. Each worker takes routines from one slice of the ledger. Easy leaf routines go first. Every change must keep make compare at OK.

    • Sort the ledger: leaf routines first, then routines whose callees are all named.
    • Give each worker one hunk or address range and its own git worktree.
    • All names live in the .cnf, so assign .cnf sections to one worker each.
    • Run make compare after every routine and again after each merge.
    • Record dead ends in notes/findings.md.
    Prompt for Claude
    GOAL: Name the next <N> `raw` routines in range <START>-<END>, one at a time.
    READ FIRST: `ledger/routines.csv` (rows in that range only), `notes/ram-map.md`, `notes/findings.md`.
    FENCE: Edit only the `.cnf` section for <START>-<END>, `notes/ram-map.md` and ledger rows in that range. Work in worktree `<ABSOLUTE_WORKTREE_PATH>`. Do not touch other ranges.
    CHECK: Run `make compare` after each routine. Done means OK each time and each finished row says `named`.
    BUDGET: Skip a routine after 3 failed tries and mark it `hard`.
    IF BLOCKED: Stop. Tell me which routine and why.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: the last compare output. 3) Files changed. 4) Routines named, routines marked hard. 5) New parking-lot items.
    Done whenEvery ledger row says named or hard, and make compare prints OK on the merged branch.

    Proof this works: https://github.com/jotd666/amiga68ktools, https://aminet.net/package/dev/asm/ira

  6. Pull out the graphics and tables

    A port needs the art and data as real files. You turn bitplane graphics into PNG images. The build turns them back into the same bytes. The hash must not change.

    • Find each graphics block in the ledger and the .cnf.
    • Write it out as PNG with bitplanelib.py from amiga68ktools. It reads and writes bitplanes with the palette order.
    • Add a make rule that turns the PNG back into bitplanes and includes it with incbin.
    • Do the same for level and text tables as labeled data.
    • Run make clean && make compare after each block. Keep extracted files out of git.
    Prompt for Claude
    GOAL: Move graphics block <LABEL> out of the .asm into `assets/<NAME>.png`, rebuilt to the same bytes.
    READ FIRST: `<GAME_EXE>.cnf`, `Makefile`, `amiga68ktools/lib/bitplanelib.py`.
    FENCE: Edit only `Makefile`, `tools/` and the lines for <LABEL>. Do not commit the PNG or any other file made from game data.
    CHECK: Run `make clean && make compare`. Done means OK.
    BUDGET: Stop after 3 failed compares.
    IF BLOCKED: Stop. Tell me the plane count, size or palette layout you could not match.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: compare output. 3) Files changed. 4) Blocks left. 5) New parking-lot items.
    Done whenmake clean && make compare prints OK with graphics built from PNG files.

    Proof this works: https://github.com/jotd666/amiga68ktools, Lightmere

  7. Turn each routine into C with a test

    Now you write C, one routine per ticket. Each C function keeps the original instruction as a comment. A test runs the C and the 68000 core from the same state. Both must leave the same registers and memory.

    • Follow Dogs of War: one C function per routine, the address and original instruction in a comment, named registers and RAM.
    • Keep return addresses on the emulated stack, so RAM stays the same as on a real Amiga.
    • Take start states from saved game snapshots, plus random states, like the James Pond 2 difftest.
    • Run the C and Musashi from each state. Compare registers, flags and every byte written.
    • Set the ledger status to in C only when the test passes and fails when you revert a line.
    Prompt for Claude
    GOAL: Turn routine <HUNK:OFFSET> (<NAME>) into C with a differential test.
    READ FIRST: the routine's named lines in `<GAME_EXE>.asm`, its ledger row, `notes/ram-map.md`, at most 3 already-done C routines it calls.
    FENCE: Edit only `src/<FILE>.c`, `tests/diff/<NAME>.cpp` and the ledger row. Do not edit the .asm, the snapshots or the test harness.
    CHECK: Run `build/difftest --routine <NAME> --states tests/states/`. Done means zero mismatches on every state, and a mismatch when you revert one line of the C.
    BUDGET: After 3 failed tries, stop and mark the row `hard`.
    IF BLOCKED: Stop. Tell me which instruction or flag you could not settle.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: test output, and output with the line reverted. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenEvery routine is in C or hard, and each C routine passes its test and fails when a line is reverted.

    Proof this works: Dogs of War Atari ST Recomp, James Pond 2: Codename RoboCod - Recompiled, https://github.com/kstenerud/Musashi

  8. Run the whole game in lockstep

    Routine tests do not prove the whole game. You run the C game and the reference machine side by side. Same input, same start. All RAM, the palette and the sound registers must match every frame.

    • Use the Path A interpreter machine as the reference. It runs the original, unchanged code.
    • Feed both the same scripted input and compare after every frame. Dogs of War compared 4 MB of RAM, sound registers and palette.
    • Cover every level with recorded routes or an auto-pilot.
    • On a mismatch, print the frame, the address and the last routine run.
    Prompt for Claude
    GOAL: Make `tools/lockstep.sh` run route <ROUTE> in the C build and the reference machine and compare RAM, palette and sound registers every frame.
    READ FIRST: `PROGRESS.md`, `tests/inputs/<ROUTE>.txt`, `runtime/machine.h`.
    FENCE: Edit only `tools/lockstep.sh`, `tools/compare_state.py` and `tests/lockstep/`. Do not change game code in this task.
    CHECK: Run `bash tools/lockstep.sh <ROUTE>`. Done means it exits 0 only when every frame matches, and prints the first differing frame and address when not.
    BUDGET: Stop after 3 failed tries.
    IF BLOCKED: Stop. Tell me which frame cannot be lined up and why.
    OTHER PROBLEMS: Write differences you find in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: the run output. 3) Files changed. 4) Differences found. 5) New parking-lot items.
    Done whenbash tools/lockstep.sh <ROUTE> exits 0 for every route in tests/inputs/.

    Proof this works: Dogs of War Atari ST Recomp, Lightmere

  9. Port it to a new system

    Now you move the chip parts behind a clean layer. The game code then calls your layer, not raw registers. You fix byte order and pointer size. You build for the new system and replay the same routes.

    • Turn copper, blitter and bitplane output into a frame buffer. Turn Paula writes into SDL audio.
    • The 68000 is big-endian and a PC is little-endian. Swap bytes when reading game data.
    • Replace 32-bit Amiga addresses stored in tables with indexes or real pointers for 64-bit systems.
    • Fix original out-of-bounds reads. They were harmless on the Amiga and crash on a modern OS.
    • Build for the new target and replay every route. James Pond 2 reached Android and PlayStation 5 from one code base.
    Prompt for Claude
    GOAL: Move <CHIP_PART> access in <SOURCE_FILES> behind `platform/<PART>.h`, with no change in behavior.
    READ FIRST: `PROGRESS.md`, `platform/`, the files named above.
    FENCE: Edit only the files named above and `platform/`. Do not change game logic or data layout.
    CHECK: Run `bash tools/lockstep.sh <ROUTE>` and `bash tools/regress.sh`. Done means both pass on the PC build, and the <TARGET> build boots to the title screen.
    BUDGET: Stop after 3 failed tries.
    IF BLOCKED: Stop. Tell me which register access cannot move without a logic change.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: both outputs and a target screenshot. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenbash tools/lockstep.sh <ROUTE> and bash tools/regress.sh pass on the PC build, and the new system's title shot matches its expected hash.

    Proof this works: James Pond 2: Codename RoboCod - Recompiled, Open Fodder, https://codeberg.org/CyCl0ne/DungeonMasterZIG

Tools you need

ToolWhat it doesHow to get itHow we know
Ghidra 12.2
Helpful both
A free disassembler and decompiler. Its built-in 68000 family module has 68020, 68030 and 68040 modes. The Amiga loader uses it for 68000 games.
Path A Path B
Install a 64-bit JDK 25. Download `ghidra_12.2_PUBLIC_20261016.zip` from the Ghidra releases page and unzip itRelease Ghidra_12.2_build (2026-10-22, asset ghidra_12.2_PUBLIC_20261016.zip), GettingStarted.md at that tag (JDK 25, File > Install Extensions) and Processors/68000/data/languages/68000.ldefs read 2026-11-13
ghidra_amiga_ldr (nicodex fork)
Helpful both
A Ghidra add-on that loads Amiga hunk programs, with their hunks and relocations.
Path A Path B
Download `ghidra_12.2_PUBLIC_20261029_ghidra_amiga_ldr.zip` from release v2.4. In Ghidra: File, Install Extensions, plus button, pick the zip, restartReleases read 2026-11-13: v2.4 (2026-10-29) has a Ghidra 12.2 build, v2.3 has 12.0.x builds, none for 12.1.x; the original lab313ru repo stops at Ghidra 10.3.1. AmigaHunkLoader.java picks language 68000:BE:32:default. Named in the tetracorp reverse engineering guide
IRA 2.11
Required WSL/Linux
An Amiga reassembler. It turns a hunk program into source that vasm can rebuild to the same bytes. A config file marks code and data.
Path A Path B
In WSL: `sudo apt install lhasa`, download `dev/asm/ira.lha` from Aminet, run `lhasa -x ira.lha`, then `make` in the `ira/` folder. A `Makefile.win32` exists but was only tested with Visual C++ 6Aminet page, readme and archive list read 2026-11-13 (2.11, 2025-02-09; ira/Makefile for gcc, Makefile.win32 tested with VC6; vasm -no-opt -Fhunkexe -nosym example); lhasa man page and Ubuntu noble package page; usage from the tetracorp guide; used by wikinger2 and by jotd666's amiga68ktools
vasm (`vasmm68k_mot`)
Required WSL/Linux
A 68000 assembler with Motorola syntax. It writes Amiga hunk programs. Path B uses it to rebuild the game.
Path B
WSL: `git clone https://github.com/StarWolf3000/vasm-mirror`, then run `make CPU=m68k SYNTAX=mot` in it. The README also lists `Makefile.Win32` for Visual Studio; that was not triedMirror README and doc/*.texi read 2026-11-13 (make CPU=m68k SYNTAX=mot, -Fhunkexe, -nosym, -no-opt, incbin). The prebuilt-amiga-dev-tools repo now has no releases. The home site sun.hasenbraten.de said 'under maintenance' that day
amitools 0.9.0 (`xdftool`, `hunktool`)
Required both
Python tools for Amiga disk images and programs. xdftool lists and unpacks .adf files. hunktool prints the hunks of a program.
Path A Path B
`pip install amitools` (Python 3.11 or newer, in a venv)README, xdftool.rst, vamos.rst and hunktool.py read 2026-11-13; PyPI 0.9.0 dated 2026-11-05
ADFlib (`unadf`)
Helpful both
A C library that reads Amiga floppy and hard disk images. Its unadf tool unpacks an .adf.
Path A
`git clone https://github.com/adflib/ADFlib`, then build it as its `INSTALL` file says, or link it as a submodule like RodLegacyREADME read 2026-11-13 (tested on Linux, Windows MSVC and MSYS2, macOS); used by RodLegacy
WinUAE 6.0.3
Helpful Windows
A full Amiga emulator for Windows with a strong debugger. Use it to check real behavior and dump RAM.
Path A Path B
Download the 64-bit installer (`.msi`) or the 64-bit zip from winuae.netDownload page read 2026-11-13; debugger commands from the tetracorp UAE debugger guide; used as a reference in the tetracorp workflow
Musashi
Required both
A 68000 to 68040 CPU core in plain C. James Pond 2 links it as the fallback CPU and the test reference.
Path A Path B
`git submodule add https://github.com/kstenerud/Musashi vendor/musashi`README read 2026-11-13 (version 4.10, ANSI C89, MIT-style licence); used by James Pond 2 and inside amitools' vamos
Moira
Helpful both
A C++20 68000, 68010 and 68020 core made for Amiga emulation. It counts cycles exactly.
Path A
`git submodule add https://github.com/dirkwhoffmann/Moira ext/moira`Project page read 2026-11-13 (C++20, MIT); used by BloodCash, Lightmere and Radiant Fighter
Capstone 5.0.9
Helpful both
A disassembler library with 68000 support. Use it to check your own instruction decoder.
Path A
`pip install capstone`PyPI read 2026-11-13 (5.0.9); repo lists M68K; DuckTales pinned 5.0.7 and checked 44,545 instructions against it
CMake, Ninja and SDL2
Required both
The build tools and the window, sound and input library the ports use. Some use SDL3 instead.
Path A Path B
WSL: `sudo apt install build-essential cmake ninja-build libsdl2-dev`. Windows: Visual Studio 2022 with `vcpkg`, then `cmake --preset windows-vcpkg`Build steps in the BloodCash, Lightmere and Radiant Fighter cards; James Pond 2 and Open Fodder use SDL3
Zig (`ziglang` from pip)
Helpful both
A C compiler you install with pip. It builds Windows and Linux programs from one machine.
Path A Path B
`pip install ziglang`, then build with `python -m ziglang cc`PyPI read 2026-11-13 (0.17.1); DuckTales pinned Zig 0.16.0 this way; Dogs of War builds its Windows zip with Zig
Greaseweazle 1.23
Helpful both
A USB board and tools that read your own floppies. It writes .adf images, or raw flux for protected disks.
Path A Path B
Windows: unzip `greaseweazle-1.23-win64.zip` and run `gw.exe`. Linux: `pipx install git+https://github.com/keirf/greaseweazle@latest`README, release v1.23 and the Supported Image Types wiki page read 2026-11-13; DuckTales copies CAPSImg.dll from Greaseweazle 1.23
amiga68ktools
Helpful both
Python scripts for IRA listings. They name OS calls and chip registers, flag self-modifying code and convert bitplanes to PNG.
Path A Path B
`git clone https://github.com/jotd666/amiga68ktools` and add its `lib` folder to `PYTHONPATH`README, 68kchecker/readme.txt (-i my_source.asm) and tools/cheapres.py options (-i, -o) read 2026-11-13; written by jotd666, the author of gods-deluxe

Skills and add-ons

Read any skill before you install it. A skill is a set of instructions that Claude will follow. See Tools and Skills for the full list and safety notes.

GhidraMCP

MCP server

Claude can ask Ghidra what an address does, with names and cross references. The PS1 recomp author made a reachable Ghidra server a start-of-session rule.

Install `uv`. Install the extension zip from release 2.0 with File, Install Extensions. Then run `claude mcp add ghidra -- uvx --from git+https://github.com/LaurieWired/GhidraMCP ghidra-mcp --ghidra-server http://127.0.0.1:8080/`. Release 2.0 is built for Ghidra 12.1.4, and no Amiga loader build exists for 12.1.4. So the two ready-made zips cannot share one Ghidra.

ghidra-headless

skills.sh

Runs Ghidra with no window and saves functions and strings to files. Use it when the MCP plugin and the Amiga loader need different Ghidra versions.

npx skills add trailofbits/skills-curated --skill ghidra-headless -a claude-code

reverse-engineer-binary

skills.sh

Claude must read the code first and give an address with every claim. Install the Ghidra bridge yourself; do not let it add one.

npx skills add xsyetopz/skills --skill reverse-engineer-binary -a claude-code

engine-reimplementation

skills.sh

A table of routes to new systems, with the work and the check for each. Four of ten Amiga projects chose a remake, so read it before you pick.

npx skills add madpai/game-decomp-compendium --skill engine-reimplementation -a claude-code

static-recomp-av-compare

skills.sh

Scores your port's video and sound against your own recordings of the game. Its script paths need a fix for Claude Code.

npx skills add bgyss/switchrecomp --skill static-recomp-av-compare -a claude-code

verification-before-completion

skills.sh

Claude may not say done without fresh proof. Here that is a difftest with zero mismatches, a headless screenshot or make compare.

npx skills add obra/superpowers --skill verification-before-completion -a claude-code

systematic-debugging

skills.sh

No fix until the cause is found. Chip timing bugs, like a lost Paula interrupt, need exactly this.

npx skills add obra/superpowers --skill systematic-debugging -a claude-code

using-git-worktrees

skills.sh

Keeps each worker in its own copy of the repo. Its setup step may run installs, so watch it the first time.

npx skills add obra/superpowers --skill using-git-worktrees -a claude-code

handoff

skills.sh

Writes a short note so a fresh session can carry on. Tell it to save the note inside your project.

npx skills add mattpocock/skills --skill handoff -a claude-code

Plan mode and subagents

built-in

Plan the recompiler design before any code. Send a subagent to search a large IRA listing and report back short.

Built into Claude Code. Plan mode uses a read-only Plan agent. A custom subagent with `isolation: worktree` works in its own temporary git worktree.

amiga-difftest (write your own)

write-your-own

James Pond 2's difftest is the strongest check seen on Amiga. A skill makes every session run it the same way.

A `.claude/skills/amiga-difftest/SKILL.md` that: 1) rebuilds with `bash tools/check.sh`; 2) runs `build/<GAME>-difftest` on all states; 3) on a mismatch, prints the address, the instruction, both register sets and the differing bytes; 4) writes the result to `notes/findings.md`. Rule: never change the seed list or skip an instruction.

amiga-headless-shot (write your own)

write-your-own

Claude cannot judge a window. All six AI-assisted recomp and emulator-based ports here built a headless runner.

A `.claude/skills/amiga-headless-shot/SKILL.md` plus `tools/shot.sh`. It runs the build with `--headless <N>`, an input file and `--shot <F>:logs/<NAME>.png`, then compares the image hash with `tests/expected/`. It prints PASS or FAIL with the frame number.

Claude setup for this system

Cut Amiga work by address range and by chip part. On Path A, one unit is one interpreted address, one crash, or one chip bug, with a recorded input that shows it. On Path B, one unit is one routine from the ledger. Every unit has one check: a difftest with zero mismatches, a headless screenshot, a lockstep run or make compare. Keep game files outside the repo and give Claude their absolute paths.

Which model and effort for each job

The model and effort names come from one shared table, so they stay the same on every guide. See Claude Setup for the reasons.

JobWhat it means on this systemMax 20x (now called Ultra)Max 5x (now called Max)
Plan the projectPin the exact release by per-file SHA-256. Decide DOS program or track loader. Look for a source release, a remake or a reconstruction. Write SCOPE.md.Fable 5.2
effort high
One session. This choice shapes months of work.
Opus 5.5
effort high
Use Fable 5.2 for this one session if you have weekly room.
Set up the projectVendor Musashi or Moira, install amitools, IRA and vasm, write tools/check.sh or make compare, and fill .gitignore before any disk image is near the repo.Opus 5.5
effort medium
Sonnet 5.5
effort medium
Study the game fileRead hunks with hunktool, list OS calls and chip writes, find the disk loader, jump tables and self-modifying code. Build the ledger.Opus 5.5
effort high
Opus 5.5
effort medium
Raise to high for function edges and data layouts. A mistake there spreads.
Bulk unitsInterpreted addresses with clear proof, routines to name on Path B, and simple routines to turn into C. One per worker, each with its check.Sonnet 5.5
effort medium
Haiku 5.5 for the plainest units.
Sonnet 5.5
effort medium
Fewer workers at once. Haiku 5.5 for the plainest units.
Hard unitsSelf-modifying code, routines that return by dropping their return address, odd instructions like MOVEP, and units that failed three times in bulk.Fable 5.2
effort high
Go to xhigh only after a failed try at high.
Opus 5.5
effort high
Send only the last few that still fail to Fable 5.2.
Build the runtimeThe small Amiga model: copper, blitter, bitplanes, sprites, Paula sound and interrupts, CIA timers, keyboard, and the replaced disk loader.Opus 5.5
effort high
Opus 5.5
effort medium
Raise to high for timing and graphics bugs.
Find a bugFlicker, hangs, wrong speed and wrong colors. Prove the cause with a trace, a watchpoint or a RAM dump before any fix.Opus 5.5
effort high
After two failed tries with full evidence, move to Fable 5.2.
Opus 5.5
effort high
One bug at a time.
Check the workA fresh session reruns the difftest, the routes and make compare. It looks for edited expected files, skipped instructions, stubs and edits in gen/.Opus 5.5
effort medium
Always a new session, never the one that did the work.
Sonnet 5.5
effort high
Always a new session, never the one that did the work.
Keep the recordsUpdate PROGRESS.md, ledger counts, the interpreted address count, notes/findings.md and the parking lot after each batch.Haiku 5.5
effort medium
Haiku 5.5
effort medium

How many sessions at once

Max 20x (now called Ultra)

Path A: 2 to 3 sessions at once while the runtime is young. Each takes one chip part or one bug, in its own worktree. One writer per runtime file. Path B: 4 to 6 workers on separate address ranges plus one lead session. Run make compare after each merge.

Max 5x (now called Max)

Path A: 1 session, with a second one only for a separate tool like the difftest. Path B: 2 workers plus the lead. Send hard units to one session at a time, and batch the docs updates at the end of the day.

Lines for this project's CLAUDE.md

Add to CLAUDE.md
- Read `SCOPE.md` and `PROGRESS.md` at the start of every session.
- Never edit files in `gen/`. They are rebuilt from the game file. Fix `tools/recomp.py` or `runtime/`, then regenerate.
- Game files live at `<ABSOLUTE_PATH_TO_GAME_FILES>`. Never copy them, RAM dumps, exported texts or graphics into the repo.
- The one check is `bash tools/check.sh` (Path A) or `make compare` (Path B). No pasted output means not done.
- Never launch the game window to judge a picture. Use the headless runner and its screenshots. I do the visual checks.
- Give the address and the listing lines from IRA or Ghidra for every claim about code.
- Do not edit expected hashes, difftest seeds, files in `tests/expected/` or the check scripts. Ask me first.
- Keep file-format readers free of SDL so their tests run with no window.
- Game-specific hooks go in `src/<game>/`. Keep the shared machine code free of them.
- Cheats and skip switches stay behind flags, and they turn off high-score saving.
- Do not install or fetch libraries. Dependencies are vendored.
- In a worktree, use absolute paths for game files and tools. Gitignored files are not copied in.
- Write side issues in `notes/parking-lot.md` and dead ends in `notes/findings.md`. Do not act on them.
- Start every report with DONE, PARTIAL or BLOCKED.

Keep the context small

  • Never let Claude read gen/ or a full IRA listing. DuckTales' machine-made C was about 196,000 lines. Have it grep for an address and read a few lines.
  • Give Claude one route's trace lines, not the whole log. Turn on one trace channel at a time.
  • Pass a Ghidra address, not pasted assembly. Let the MCP server or a subagent fetch it.
  • On Path B, give each worker its address range and those ledger rows only.
  • Add Read deny rules for gen/**, logs/** and the game file folder.
  • Clear the chat after each unit. The ledger and the findings file carry the state.

More prompts for this system

Each step above has its own prompt. These extra prompts cover the rest of the work. Fill in the parts in <ANGLE_BRACKETS>.

Scope and feasibility

Before any work, to choose Path A, Path B or both for one game.

Prompt for Claude
GOAL: Tell me if <GAME> (<RELEASE>) suits Path A, Path B, or both, and draft SCOPE.md.
READ FIRST: `xdftool <ABSOLUTE_PATH_TO_ADF> list` output, `hunktool info -d <ABSOLUTE_PATH_TO_EXE>` output if it is a DOS program, https://github.com/cnvogelg/amitools
FENCE: Create only `SCOPE.md`, `notes/hashes.sha256` and `notes/prior-work.md`. No code. Do not copy game files.
CHECK: Run `sha256sum -c <ABSOLUTE_PATH_TO_REPO>/notes/hashes.sha256` in the unpacked game folder; it must print OK for every file. Done means SCOPE.md lists per-file SHA-256, DOS program or track loader, chip set, hunk and overlay count, C or assembly guess with proof, prior work with links, the chosen path, the first milestone with its check, and an out-of-scope list.
BUDGET: 60 minutes.
IF BLOCKED: Stop. Say what you could not check.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: tool outputs. 3) Files changed. 4) Risks you see. 5) New parking-lot items.

A good answer: A one-page SCOPE.md with hashes, the loader type, and a plain list of risks such as copy protection, AGA, overlays or self-modifying code.

Map the binary

After setup, to build the ledger both paths use.

Prompt for Claude
GOAL: Build `ledger/functions.csv` from the IRA config and the hunk info for <GAME_EXE>.
READ FIRST: `<GAME_EXE>.cnf`, `hunktool info -d <ABSOLUTE_PATH_TO_EXE>` output, `notes/map.md`.
FENCE: Edit only `ledger/functions.csv` and `tools/make_ledger.py`. Do not read the .asm whole; use a script.
CHECK: Run `python3 tools/make_ledger.py`. Done means one row per routine with hunk, offset, size, kind and status, and per-hunk byte totals match hunktool.
BUDGET: 3 failed tries.
IF BLOCKED: Stop. Tell me which fields are missing.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: both totals. 3) Files changed. 4) Odd entries. 5) New parking-lot items.

A good answer: A CSV built by a script you can rerun, with totals that match hunktool. Odd entries are flagged, not hidden.

Unit loop: one interpreted address (Path A)

For each address the log says still runs on the interpreter.

Prompt for Claude
GOAL: Make the recompiler translate the code at <ADDRESS> so it no longer runs on the interpreter.
READ FIRST: `notes/map.md`, the coverage lines for <ADDRESS>, the IRA or Ghidra listing at <ADDRESS>.
FENCE: Edit only the entry list in `tools/recomp.py` config and `notes/map.md`. Never edit `gen/`. Do not add an address you have not proven is code.
CHECK: Regenerate, rebuild, replay `tests/inputs/<ROUTE>.txt`, then run `build/<GAME>-difftest`. Done means <ADDRESS> is gone from the interpreted list and the difftest shows zero mismatches.
BUDGET: 3 tries or 30 minutes.
IF BLOCKED: Stop. If it is self-modifying code or data, say so with the listing.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: before and after counts and difftest output. 3) Files changed. 4) Addresses left. 5) New parking-lot items.

A good answer: A listing that proves the code, one added entry, a lower interpreted count, and a clean difftest.

Unit loop: one routine into C (Path B)

For each named routine in the ledger.

Prompt for Claude
GOAL: Turn routine <HUNK:OFFSET> into C with a differential test.
READ FIRST: the ledger row, the routine's lines in `<GAME_EXE>.asm`, `notes/ram-map.md`.
FENCE: Edit only `src/<FILE>.c`, `tests/diff/<NAME>.cpp` and the ledger row.
CHECK: Run `build/difftest --routine <NAME> --states tests/states/`. Done means zero mismatches, a mismatch when one C line is reverted, and the row says `in C`.
BUDGET: 3 failed tries, then mark it `hard`.
IF BLOCKED: Stop. Say which instruction you could not settle.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: both test outputs. 3) Files changed. 4) Unsure names or flags. 5) New parking-lot items.

A good answer: Plain C with the original instruction in a comment on each line, a passing test, and proof the test can fail.

Batch dispatch

In the lead session, to hand out the next batch of units.

Prompt for Claude
GOAL: Start <N> workers, one per unit, from the top of the ledger.
READ FIRST: `ledger/functions.csv` (status column only), `PROGRESS.md`.
FENCE: Do not edit code yourself. Give each worker its own worktree, one address range, and the unit-loop card with its unit filled in.
CHECK: Done means every worker returned DONE, PARTIAL or BLOCKED, and `bash tools/check.sh` (or `make compare`) passes on the merged branch.
BUDGET: Stop the batch if two workers fail on the same cause.
IF BLOCKED: Stop. Tell me the shared cause.
OTHER PROBLEMS: Collect workers' parking-lot items in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: the merged check output. 3) Units done, partial, blocked. 4) What is next. 5) New parking-lot items.

A good answer: A short table of units and results, one merged check output, and a stop the moment two workers hit the same wall.

Debug with evidence

When a picture, sound or speed is wrong and the cause is not known.

Prompt for Claude
GOAL: Find the cause of <SYMPTOM> at frame <N> of `tests/inputs/<ROUTE>.txt`. Do not fix it yet.
READ FIRST: `notes/findings.md`, the Hardware Reference Manual chapter on <CHIP_PART>, `runtime/<FILE>`.
FENCE: Edit only `notes/findings.md`. You may turn on trace switches and run the WinUAE debugger. No code changes.
CHECK: Replay `tests/inputs/<ROUTE>.txt` headless with one trace switch on, up to frame <N>. Done means findings.md names the cause with proof: trace lines, register values or a watchpoint hit, plus the same moment in WinUAE.
BUDGET: 90 minutes.
IF BLOCKED: Stop. List the ideas you ruled out and what evidence you still need.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: the trace lines. 3) Files changed. 4) The cause in one sentence. 5) New parking-lot items.

A good answer: One proven cause, like a copper list entry written in the wrong order, with the trace that shows it. No fix yet.

Verify: hunt for cheating

After a batch, in a fresh session with no memory of the work.

Prompt for Claude
GOAL: Check that the last <N> units claimed DONE are real.
READ FIRST: `git log` for the batch, `PROGRESS.md`, the ledger rows for those units.
FENCE: Read only. Do not fix anything.
CHECK: Rerun `bash tools/check.sh`, `build/<GAME>-difftest` and `bash tools/regress.sh`. Then search the diff for edits in `gen/`, `tests/expected/`, seed lists or check scripts, new skip lists, stubbed routines, and cheat flags left on.
BUDGET: 60 minutes.
IF BLOCKED: Stop. Tell me which check you could not run.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: all check outputs. 3) Units that pass. 4) Units that fail, with the line that shows it. 5) New parking-lot items.

A good answer: Each unit is marked real or not real, with the exact file and line for any problem.

Status report

At the end of a day or before a decision.

Prompt for Claude
GOAL: Give me a status report for <GAME> from the files, not from memory.
READ FIRST: `PROGRESS.md`, `ledger/functions.csv`, `notes/findings.md`, `notes/parking-lot.md`.
FENCE: Read only.
CHECK: Done means every number comes from a file or a command you ran: routines by status, interpreted address count, difftest result, routes passing.
BUDGET: 15 minutes.
IF BLOCKED: Stop. Say which number you could not get.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: the commands and their output. 3) Numbers table. 4) Top 3 risks. 5) Parking-lot items that need my decision.

A good answer: A short table of numbers with their sources, three risks, and the decisions only you can make.

Session handoff

Before you stop for the day or run low on usage.

Prompt for Claude
GOAL: Write what the next session needs into the ledger files.
READ FIRST: `PROGRESS.md`, `git status`, `git log -5`.
FENCE: Edit only `PROGRESS.md` and `notes/findings.md`. Do not commit half-done code without saying so.
CHECK: Run `bash tools/check.sh` (or `make compare`) and `git status --short`, and paste both into PROGRESS.md. Done means PROGRESS.md has: what works with proof, the unit in progress and its state, the exact next command to run, dead ends, and open questions.
BUDGET: 15 minutes.
IF BLOCKED: Stop. Tell me what you could not record.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: the new PROGRESS.md section. 3) Files changed. 4) What is left. 5) New parking-lot items.

A good answer: A fresh session can start from PROGRESS.md alone and run the next command with no questions.

Blocked or cannot deliver

When a unit keeps failing, or a goal looks impossible.

Prompt for Claude
GOAL: Tell me plainly whether <TASK> can be done, and what it would take.
READ FIRST: `notes/findings.md` entries for <TASK>, the last three reports on it.
FENCE: Read only.
CHECK: Rerun the failing check for <TASK> once, like `bash tools/check.sh` or `make compare`, and paste its output. Done means you answer YES, NO or NOT YET, with that output as evidence and at least two options with their cost.
BUDGET: 30 minutes.
IF BLOCKED: Stop. Say what you would need to know to answer.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: the evidence. 3) The answer. 4) Options with cost. 5) What you recommend.

A good answer: A plain answer, like NOT YET: the .ipf copy protection needs a flux decoder, with options such as using the WHDLoad files instead.

Scope change request

When Claude wants to work outside the fence, or adds a feature.

Prompt for Claude
GOAL: Ask me before you leave the fence for <TASK>.
READ FIRST: `SCOPE.md`, the current task card.
FENCE: Make no change outside the current fence until I say yes.
CHECK: Run `git status --short` and show that no file outside the current fence changed. Done means that, plus one request with: what you want to change, why the current fence blocks the task, the files it touches, the risk, and how we would check it.
BUDGET: 10 minutes.
IF BLOCKED: Stop and wait for my answer.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: the request text. 3) Files you want to touch. 4) The risk. 5) The check you propose.

A good answer: A short request you can answer yes or no, like adding widescreen only after the difftest is clean.

Add a chip feature to the machine

When the game needs a chip part your model fakes, like blitter line mode or AGA fetch.

Prompt for Claude
GOAL: Add <CHIP_FEATURE> to `runtime/<FILE>` so <GAME> draws <SCENE> right.
READ FIRST: the Hardware Reference Manual section on <CHIP_FEATURE>, `notes/findings.md`, `runtime/<FILE>`.
FENCE: Edit only `runtime/<FILE>`, `tests/chip/` and `notes/findings.md`. No game-specific code in the shared machine.
CHECK: Write a small chip test in `tests/chip/` with known pixels, like Radiant Fighter's `agatest`. Done means it passes, the scene screenshot matches `tests/expected/<SCENE>.png`, and `bash tools/regress.sh` passes.
BUDGET: Stop after 3 failed tries.
IF BLOCKED: Stop. Quote the manual text you cannot square with the game's behavior.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: test and regress output. 3) Files changed. 4) What is left. 5) New parking-lot items.

A good answer: A chip test that fails before the change and passes after, plus a matching scene screenshot.

Keep Claude on task

These are the detours Claude tends to take on this system, and the rule that stops each one. The full method is on Stay on Task.

The detourThe rule to give Claude
Claude edits the generated C in gen/ to make a bug go away. The next build wipes the fix.Never edit files in gen/. Fix the recompiler or the runtime, then regenerate. Add a hook that blocks edits there.
Claude adds guessed entry points to cut the interpreted count. Tables then turn into fake code.Add an entry point only with a coverage hit or a listing that proves it is code. Paste the proof in the report.
Claude reports the game as recompiled while much of it still runs on the interpreter.Every report prints the interpreted address count. Recompiled means that count is zero, or each address left is listed with a reason.
Claude speeds up the game logic for a smoother picture and changes how the game plays.Keep game logic at its own rate. Smooth only the drawing, like Dogs of War does. Logic changes need my approval.
Claude puts game data into source files, like a status panel shape, to save time.No bytes from game files in the repo. Rebuild data at run time from the player's files, as Lightmere had to.
Claude fixes an odd behavior that was really in the original game.Before fixing, check notes/original-bugs.md and the same moment in WinUAE. If the original does it too, record it and stop.
Claude launches the game window and says the picture looks right.Never judge pictures by eye. Use headless screenshots compared with expected files. I do the visual checks.
Claude leaves a cheat or skip switch on so a test can get past a level.Cheats stay behind a flag that turns off high-score saving. Tests that need a cheat must say so in their name.

Problems other projects hit

The screen flickered. The game wrote palette colors at fixed spots in the copper list, and the runtime had put other entries there first.

Fix: Lay out the copper list the way the game expects. Check the game's own writes with a watchpoint before you change the layout.

Seen in: DuckTales Amiga Recompilation

Sound never finished and a scene hung. Interrupt enable bits were not set the way AmigaOS leaves them. Another sound played twice because an interrupt fired too soon.

Fix: Start with the interrupt state AmigaOS leaves behind. Delay the Paula block-start interrupt, since the game clears the request after it turns on DMA.

Seen in: DuckTales Amiga Recompilation

The music player rewrites its own code while the game runs. A translated copy of that code goes stale.

Fix: Mark self-modifying ranges and leave them on the interpreter. Do not let a translated chunk run across them.

Seen in: James Pond 2: Codename RoboCod - Recompiled

Following jumps from the entry point missed code reached only through tables and pointers.

Fix: Record coverage while playing, sweep every level headless, and feed the addresses back to the recompiler.

Seen in: James Pond 2: Codename RoboCod - Recompiled

Reads past the end of arrays were harmless on the Amiga but crashed on a modern OS.

Fix: Expect these. Fix each one in the port and list it in a bugs file, like Open Fodder's BUGS.md.

Seen in: Open Fodder

Removing the slow disk loader broke the intro. Pictures and music had been timed by how long the disk took.

Fix: Add waits of the same length where the intro depended on loading time.

Seen in: BloodCash

On AGA, sprites and the panel were drawn 16 pixels too far left. The first pixel comes at DDFSTRT itself, not at an aligned spot.

Fix: Write a chip self-test with known pixels, like agatest, and fix the fetch math there first.

Seen in: Radiant Fighter: A Shadow Fighter Recomp

Windows display scaling at 125% or 150% blurred and shrank the picture.

Fix: Ask SDL for the real screen pixels and scale by whole numbers.

Seen in: BloodCash, Lightmere, Radiant Fighter: A Shadow Fighter Recomp

Many disk forms do not load: original protected releases, raw-track dumps, .dms and .ipf.

Fix: Support one or two formats well, such as .adf and WHDLoad. Name the reason when a file is rejected.

Seen in: James Pond 2: Codename RoboCod - Recompiled, BloodCash

Capstone gave different results on Windows and Linux for invalid words. That changed the function list.

Fix: Treat both outputs as undecodable, and check that function discovery gives the same list on every system.

Seen in: DuckTales Amiga Recompilation

Music played too fast, because the timer rate was assumed and not read from the game.

Fix: Take timer rates from what the game writes to the timer chip. Never assume a standard rate.

Seen in: Dogs of War Atari ST Recomp

How long it takes

Max 20x (now called Ultra)Max 5x (now called Max)One person, no AIHow sure
Path A: running on PC2 to 8 weeks5 to 20 weeks6 months to 2 yearslow confidence
Path B: full decomp3 to 9 months7 months to 2 years2 to 6 yearslow confidence

Read this first

These numbers assume one medium-sized game and one person giving 10 to 15 hours a week. Both paths are low confidence. For Path A, only Dogs of War states a duration. It is a small 68000 game from a sister system, and its hours are not given. The other AI ports show release dates but hide their early work. The no-AI Path A range is a guess from the steps, since no pre-agent Amiga recomp was reviewed. For Path B, no full Amiga decomp with AI and dates exists yet. That range leans on the pre-agent ReDMCSB and remake timelines.

What makes it faster or slower

  • Whether you reuse a machine core. The sanviler ports shared one core and went public within four days. Their earlier private work is not dated.
  • DOS program or track loader. A hunk program loads in one step. A track loader with copy protection needs RAM dumps and hooks.
  • OCS or AGA. AGA games need more chip work, like the wide fetch bug in Radiant Fighter.
  • Self-modifying code and jump tables. Each one adds coverage rounds and interpreter fallback.
  • Assembly or C. On Path B, assembly means naming every routine by hand before any C exists.
  • Your review time. Each unit needs a look at its proof, and that is your 10 to 15 hours a week.

The facts behind these numbers

ProjectWhat happenedLink
Dogs of War Atari ST RecompCHANGELOG: first analysis 2026-10-11, whole program in C 2026-10-13, version 1.0 on 2026-10-19. Nine days. 1 contributor. AI credited in README. A 68000 Atari ST game filed under Amiga.source
James Pond 2: Codename RoboCod - RecompiledFirst commit 2026-10-25 already held a working recompiler. First release 2026-10-26. 16 commits, 1 contributor. AI flagged by the store only.source
DuckTales Amiga RecompilationBoth commits and release v0.90 on 2026-10-13. 1 contributor. The repo says Claude was used. No duration stated.source
BloodCash, Lightmere, Radiant FighterThree ports by one author on a shared core, published 2026-11-07 to 2026-11-10. The developer says Claude wrote most of the analysis and code. Earlier private history is hidden.source
Open FodderFirst commit 2010-12-06. First release 2015-10-03. 14 contributors. No AI stated. A remake, not a recomp.source
gods-deluxehistory.txt: version 0.01 in March 2007, 0.9 in December 2016. Built by watching play, no original code. No AI.source
ReDMCSB (outside)C rebuild of Dungeon Master. Announced 2014-01-18 after nearly 5 years of work by one person, Atari ST only. Release 2 on 2014-08-05. A 2021-02-06 release added Amiga and other versions. Pre-agent. Builds are identical to the originals or very close.source
DungeonMasterZIG (outside)Zig port of the Amiga 3.6 release from ReDMCSB. Commits 2026-09-22 to 2026-10-20, still in progress. Has a CLAUDE.md.source
wikinger2 (outside)Rust port of a 1988 Amiga strategy game. The author worked with AI using Ghidra, IRA and FS-UAE. First commit 2026-09-11, 5 commits.source

Projects reviewed (10)

The top-starred project for each Amiga game on RecompLauncher. The catalog lists 11 projects for 10 games. All were reviewed except ZGloom-macOS, a sibling fork of ZGloom-x86 by the same author. None of the ten came from outside RecompLauncher. Three outside projects are used only as time and Path B evidence.

What each project teaches

Open Fodder

Cannon Fodder (also Cannon Fodder 2)

Top rated on RecompLauncherreimplementationplayable
C++SDL3SDL3_mixerCMakeVisual Studio 2022SOS Unpacker

Started: 2010-12. First release: 2015-10. Code: C++.

AI: none stated

Lesson: Recorded input demos replayed headless in CI catch regressions on every commit. Expect original out-of-bounds bugs to crash on a PC.

gods-deluxe

Gods

Top rated on RecompLauncherreimplementationplayable
Java 11Mavenmicromodown level editor

Started: 2020-04. First release: 2023-10. Code: Java.

AI: none stated

Lesson: A remake built by watching play gets the look right but misses hidden numbers. Scoring and weapon power were wrong until someone's disassembly was checked.

James Pond 2: Codename RoboCod - Recompiled

James Pond 2: Codename RoboCod

Top rated on RecompLauncherstatic recompplayable
jp2-recomp (own)Musashijp2-difftestSDL3CMakeNinja

Started: 2026-10. First release: 2026-10. Code: C++.

AI: yes: flagged by the store; the repo does not mention AI

Lesson: The model to copy. It recompiles at build time from your own disk, keeps Musashi as a fallback, and tests every instruction against it.

RodLegacy

Street Rod and Street Rod 2

Top rated on RecompLauncherreimplementationplayable
C++17SDL2MesonNinjaADFlibdoctest

Started: 2023-01. First release: 2026-10. Code: C++.

AI: yes: AGENTS.md for a coding agent; store flag Agent files: AGENTS.md.

Lesson: A short AGENTS.md works. It gives one build line and says where data lives. It also says "Never launch the app to verify visually."

ZGloom-x86

Gloom

Top rated on RecompLauncherreimplementationplayable
Visual Studio 2026SDL2SDL2_mixerLibXMPDeCrunchmania

Started: 2019-12. First release: 2025-11. Code: C++.

AI: yes: README badge says AI assisted coding

Lesson: Check for a source release first. Gloom's own source was out, so no decomp was needed. Read what the release does not cover.

Blood Cash: A Blood Money Recomp

Blood Money

Top rated on RecompLauncheremulator-basedplayable
Moiraown A500 chipsetSDL2CMakevcpkgbcrun

Started: 2026-11. First release: 2026-11. Code: C++.

AI: yes: developer says Claude wrote most of the analysis, code and docs

Lesson: A playable first step can skip recompiling. Run the original code on a tiny machine and replace the track loader with a file read.

Dogs of War Atari ST Recomp

Dogs of War (Atari ST)

Top rated on RecompLauncherstatic recompplayable
unnamed 68000-to-C translatorHatariUnicornZigSDL2OpenGL 3.3

Started: 2026-10. First release: 2026-10. Code: C.

AI: yes: README credits Claude and the author; store flag

Lesson: An Atari ST game filed under Amiga, on the same chip. It shows the strongest check: whole-RAM lockstep against an emulator over every mission.

DuckTales Amiga Recompilation

DuckTales: The Quest for Gold

Top rated on RecompLauncherstatic recompin progress
tools/recomp.py (own)Capstonezig ccSDL2CAPSImg

Started: 2026-10. First release: 2026-10. Code: C and Python.

AI: yes: README says the game was recompiled using Claude

Lesson: A short pipeline reruns from the game file each build. It handles about 70 OS calls in C and ships no game code at all.

Lightmere: A Darkmere Recomp

Darkmere

Top rated on RecompLauncheremulator-basedplayable
Moiraown A500 chipsetSDL2CMakevcpkgamirun

Started: 2026-11. First release: 2026-11. Code: C++.

AI: yes: developer says Claude wrote most of the analysis, code and docs

Lesson: Keep a switch back to the original at every level. Check game files by per-file SHA-256 and store only the hashes.

Radiant Fighter: A Shadow Fighter Recomp

Shadow Fighter

Top rated on RecompLauncheremulator-basedplayable
Moiraown A1200 AGA chipsetSDL2CMakevcpkgrfrun

Started: 2026-11. First release: 2026-11. Code: C++.

AI: yes: developer says Claude wrote most of the analysis, code and docs

Lesson: A chip self-test apart from the game splits chip bugs from game bugs. Swap slow routines to C one at a time.

What we could not check

  • No reviewed project is a byte-matching C decomp of an Amiga game. ReDMCSB's site says its builds are identical to the originals or very close, but which Amiga builds match exactly was not checked. Its archive was not downloaded.
  • Whether vamos from amitools can run SAS/C or Aztec C well enough for a matching C project was not tested.
  • Whether asm-differ, which supports m68k, works on Amiga hunk objects was not tested.
  • GhidraMCP 2.0 is built for Ghidra 12.1.4. The Amiga loader has builds for 12.0.x and 12.2 only. Building either one from source for the other's Ghidra was not tried.
  • The exact Greaseweazle --format name for Amiga DOS disks was not on the pages read. Run gw read --help for it.
  • The vasm home site was under maintenance on 2026-11-13. Its build line comes from the source mirror's README. The old prebuilt Windows zips are gone: the prebuilt-amiga-dev-tools repo has no releases. Building vasm or IRA natively on Windows with their Visual Studio makefiles was not tried.
  • The tools that analyzed Blood Money, Darkmere and Shadow Fighter are not named in those repos.
  • How Claude was directed in the Amiga ports is unknown. None of them publish agent files except RodLegacy's AGENTS.md.
  • The James Pond 2 and Dogs of War AI flags partly come from the store catalog, not from the repos.
  • A research note reports a Claude Code rule against recreating a specific existing game (Game Developer, 2026-10-30). Whether it affects remakes like four of these projects was not tested.
  • The scripts tools/check.sh, tools/regress.sh, tools/lockstep.sh, make compare and the difftest commands in the steps are ones you write. Their names are suggestions.
  • Whether WinUAE needs your own Kickstart ROM for a given game was not checked. The download page does not say. Do not download one from an unofficial site.
  • No command, build or prompt in this guide was run. Every tool fact comes from its docs or a reviewed project.

Sources