Nintendo 64 decomp guide
One of the best-tooled consoles. Recomp gets you playing fast; a full decomp is slow but proven.
What this system is like
The Nintendo 64 has some of the most finished tools of any console. A free tool called N64Recomp turns the game's code into C. A runtime and a renderer then run that C on your PC. Five of the fifteen projects we read used this road.
The other road is a full decomp. You write C that the game's own compiler turns back into the exact same bytes. The compilers are known, and community builds of them run on Linux today. Many big N64 games already have a finished decomp, so check first.
AI helps a lot here, but it does not do the job alone. One developer matched a whole N64 game with agents in 84 days. He was already an expert, and other experts still helped with about one match in twenty. The upstream recomp teams refuse AI-written code. They also ask that AI not be used to study their code. So use their tools as released, and keep your own work in your own repo.
Recomp builds run on Windows. Matching builds run best in WSL. Your ROM never goes in the repo.
A ready recompiler
N64Recomp turns MIPS code into C, one function per file. N64ModernRuntime stands in for the console's system code. RT64 draws the graphics. You mostly write config files, not a recompiler.
Known compilers that run today
Most games were built with IDO 5.3, IDO 7.1 or KMC GCC 2.7.2. ido-static-recomp runs both IDO versions on Linux. A GCC 2.7.2 build made to match KMC GCC output also runs on Linux. That makes a byte-perfect match possible. Newer consoles often lack this.
Prior work for many games
Big games like Ocarina of Time, Mario 64 and Star Fox 64 already have decomps. A decomp gives you function names for a recomp, or source for a port. Always check before you start.
Overlays and compression
Many games swap code in and out of the same RAM area. Some pack code with their own compression. You must decompress the ROM and list every overlay. Otherwise the recompiler sees the wrong code.
Upstream says no to AI code
The N64Recomp, RT64, Zelda, Banjo and Donkey Kong 64 teams reject AI-written pull requests. Their CONTRIBUTING.md files also ask people not to use AI to study their code. Harbour Masters accepts small, disclosed AI help. Use the released tools, and keep AI fixes as patches in your own repo.
Two paths
Get it running on PC
You give N64Recomp the ROM and a list of functions. It writes C for every function. You build that C with N64ModernRuntime and RT64 into a Windows program. Then you fix one crash or missing call at a time. You fix the config, never the made code.
Full decomp for porting
You split the ROM, then write C for each function. The game's own compiler must turn your C into the same bytes. A script rebuilds the whole ROM and checks its hash. When every function matches, you swap the console parts for PC parts with libultraship and Torch.
Path A: Get it running on PC
You give N64Recomp the ROM and a list of functions. It writes C for every function. You build that C with N64ModernRuntime and RT64 into a Windows program. Then you fix one crash or missing call at a time. You fix the config, never the made code.
Method: static recompilation
Pick this first. It is the fastest road to a playable game. It works even when no decomp exists, as WinBack and Super Robot Wars 64 show.
Scope the game and look for prior work
Pick one game and one exact ROM version. Check if a decomp, symbol list or recomp exists. A decomp saves weeks, because it names the functions for you. Write it all in
SCOPE.md.- Dump your own cartridge. Get its SHA-1 with
sha1sum baserom.us.z64in WSL, orcertutil -hashfile baserom.us.z64 SHA1in Windows. - Search GitHub for
<GAME> decompand<GAME> recomp. Look at then64decompandzeldaretgroups. - Check the RecompLauncher list for a recomp of the same game.
- Write
SCOPE.md: game, region, SHA-1, goal, technique, first milestone and its check. - Make
notes/parking-lot.mdandPROGRESS.mdas empty files.
Prompt for ClaudeGOAL: Write a one-page `SCOPE.md` for a static recomp of <GAME> (<REGION>, SHA-1 <HASH>). READ FIRST: `notes/prior-work.md` (my search results). Do not open the ROM. FENCE: Edit only `SCOPE.md` and `notes/prior-work.md`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `grep -c "^## " SCOPE.md`. Done means it prints 7 or more, for these headings: Goal, ROM and hash, Technique, Prior work, Milestone 1 and its check, Out of scope, Never edit. Every heading has real content and every prior-work claim has a URL. BUDGET: Stop after 30 minutes or 3 drafts. IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the headings. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whengrep -c "^## " SCOPE.mdprints 7 or more, and you approved the file.Proof this works: WinBack Recompiled, Marchwind64, Donkey Kong 64: Recompiled
- Dump your own cartridge. Get its SHA-1 with
Set up the repo and the tools
Copy the layout of a recent recomp. WinBack Recompiled is a good model, and it was built with Claude Code. Banjo: Recompiled is thinner, but its team asks that AI not be used on it, so read that one yourself. Install the build tools on Windows and build
N64Recompfrom source. Keep the ROM and all made code out of git.- Install Visual Studio 2022 with "Desktop development with C++", "C++ Clang compiler for Windows" and "C++ CMake tools for Windows". Also install Ninja, Python 3 and Git. WinBack used a separate LLVM install for
clang-cl; either works. - Run every
cmakecommand inside the Visual Studio x64 build setup. Copy WinBack'stools\vsenv.cmd: it callsvcvars64.bat, puts LLVM on the path, then runs your command. - Clone the recompiler:
git clone --recurse-submodules https://github.com/N64Recomp/N64Recomp deps/N64Recomp. - Build it as WinBack does:
tools\vsenv.cmd cmake -S deps/N64Recomp -B deps/N64Recomp/build -G Ninja -DCMAKE_BUILD_TYPE=Release, thentools\vsenv.cmd cmake --build deps/N64Recomp/build. This makesN64RecompandRSPRecomp. - Add
N64ModernRuntimeandRT64as git submodules, pinned to one commit each. - Make a Python venv:
python -m venv .venv, then.venv/Scripts/python -m pip install "splat64[mips]". - Put
rom/,generated/,build/anddeps/in.gitignore. - Write one check script, for example
tools/check.ps1, that regenerates and builds.
Prompt for ClaudeGOAL: Lay out the repo for a <GAME> recomp so one command regenerates and builds, even if the build is still empty. READ FIRST: `SCOPE.md`, the WinBack layout notes at https://github.com/RetroPulse03/WinBackRecomp/blob/main/docs/DEVELOPMENT.md, the `N64Recomp` README. FENCE: Edit only `CMakeLists.txt`, `tools/`, `config/`, `.gitignore`, `CLAUDE.md`, `PROGRESS.md`. Never copy the ROM or anything made from it into git. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `powershell -File tools/check.ps1`. Done means it exits 0 and `git status` shows no file from `rom/` or `generated/`. BUDGET: Stop after 3 failed tries, or 45 minutes with no progress. IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me. Do not install anything system-wide; ask me. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output and `git status`. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whentools/check.ps1exits 0 on a fresh clone, andgit statuslists no ROM-derived file.Proof this works: WinBack Recompiled, Banjo: Recompiled, https://github.com/N64Recomp/N64Recomp
- Install Visual Studio 2022 with "Desktop development with C++", "C++ Clang compiler for Windows" and "C++ CMake tools for Windows". Also install Ninja, Python 3 and Git. WinBack used a separate LLVM install for
Decompress and split the ROM
Some games pack their code. Unpack it first, or the recompiler reads noise. Then split the ROM with
splatso you know where code and data sit. This gives Claude a map of small pieces.- If the game uses compression, use the unpacker its decomp uses. Zelda used
z64decompress. Banjo usedbk_rom_compressor. - Make a first config:
.venv/Scripts/python -m splat create_config rom/baserom.us.z64. It writes a.yamlfile named from the ROM header into the current folder. - Move that file to
config/<game>.us.yamland fix the paths inside it, as WinBack did. - Split it:
.venv/Scripts/python -m splat split config/<game>.us.yaml. - List every overlay: where it sits in the ROM and where it loads in RAM.
- Hash the unpacked ROM and write that hash in
SCOPE.mdtoo.
Prompt for ClaudeGOAL: Produce a `splat` config for <GAME> that splits the ROM with no errors and lists every code segment and overlay. READ FIRST: `SCOPE.md`, `config/<game>.us.yaml`, the `splat` wiki pages on segments. FENCE: Edit only `config/<game>.us.yaml` and `notes/segments.md`. The ROM and everything in `generated/` are read-only. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `.venv/Scripts/python -m splat split config/<game>.us.yaml`. Done means it ends with no error and `notes/segments.md` lists each segment with ROM start, RAM address and size. BUDGET: Stop after 5 failed tries, or 60 minutes with no progress. IF BLOCKED: Stop. Do not work around it. If the code looks compressed, say so and stop. Tell me what you tried and what you need from me. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the last 20 lines of the split output. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done when.venv/Scripts/python -m splat split config/<game>.us.yamlexits 0 andnotes/segments.mdlists every code segment and overlay with addresses.Proof this works: WinBack Recompiled, Zelda 64: Recompiled, Banjo: Recompiled
- If the game uses compression, use the unpacker its decomp uses. Zelda used
Name the library code and write the symbols file
N64Recompswaps libultra functions for its own versions by name. A missed name means the old code pokes hardware that is not there. So find and name every library function first. Then write the symbols file the recompiler reads.- Scan with
n64sym rom/baserom.us.z64 -s -f splat -o config/n64sym_addrs.txt. - Check each hit by hand. The tool warns that ROM scans can be wrong.
- Keep hand-made names in
config/symbol_addrs.txt. - Write a small script that turns the split plus names into the
N64Recompsymbols TOML. WinBack calls ittools/gen_recomp_syms.py. - Point the main config at it with
symbols_file_path. You need no ELF file; Banjo leaveself_pathout. - If a decomp exists, take its names instead, like Zelda and Banjo did.
Prompt for ClaudeGOAL: Build `config/<game>.syms.toml` with every function's name, address and size, with all libultra functions named. READ FIRST: `notes/segments.md`, `config/n64sym_addrs.txt`, `config/symbol_addrs.txt`, `tools/gen_recomp_syms.py`. FENCE: Edit only `config/symbol_addrs.txt`, `tools/gen_recomp_syms.py` and `notes/library.md`. Never edit files in `generated/`. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `.venv/Scripts/python tools/gen_recomp_syms.py` then `deps/N64Recomp/build/N64Recomp config/<game>.us.toml`. Done means both exit 0 and `notes/library.md` lists each libultra function with how you confirmed it. BUDGET: Stop after 5 failed tries, or 60 minutes with no progress. IF BLOCKED: Stop. Do not guess a name you cannot confirm. Mark it UNCONFIRMED in `notes/library.md` and tell me. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste both command outputs. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whendeps/N64Recomp/build/N64Recomp config/<game>.us.tomlexits 0 and every libultra function innotes/library.mdis named and checked.Proof this works: WinBack Recompiled, Marchwind64, https://github.com/shygoo/n64sym
- Scan with
First light: boot to the first frame
Run the recompiler on the whole game. Recompile the audio microcode too. Build it all with the runtime and the renderer. The goal is one window with the game's first picture in it.
- Run
deps/N64Recomp/build/N64Recomp config/<game>.us.tomlto write the C intogenerated/. - Run
deps/N64Recomp/build/RSPRecomp config/aspMain.us.tomlfor the audio microcode. - Configure:
tools\vsenv.cmd cmake -S . -B build -G Ninja -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_BUILD_TYPE=RelWithDebInfo. - Build:
tools\vsenv.cmd cmake --build build. - Run the game and save a screenshot of the first frame.
Prompt for ClaudeGOAL: Build <GAME> with `N64Recomp`, `N64ModernRuntime` and `RT64` and show the first frame (the logo). READ FIRST: `SCOPE.md`, `config/<game>.us.toml`, `config/aspMain.us.toml`, `CMakeLists.txt`. FENCE: Edit only `config/`, `src/main/`, `src/game/` and `CMakeLists.txt`. Never edit `generated/` or `deps/`. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `powershell -File tools/check.ps1`, then start the game for 20 seconds. Done means the build exits 0 and a screenshot shows the logo. A build that only compiles is not done. BUDGET: Stop after 5 failed tries, or 90 minutes with no progress. IF BLOCKED: Stop. Do not stub a call to fake progress. Tell me the exact error 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: build output tail and the screenshot path. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenThe built program opens a window and a saved screenshot shows the game's first logo.Proof this works: Zelda 64: Recompiled, Banjo: Recompiled, WinBack Recompiled
- Run
Build a way to run the game with no person
Claude cannot hold a controller. Add switches that press buttons at set times, jump to a level and save screenshots. Then every fix can be checked by a script. This is the golden run from the method.
- Add environment variables for scripted input, like WinBack's
WINBACK_AUTOPRESSandWINBACK_JUMP. - Write
tools/capture_test.ps1that runs the game for N seconds and saves screenshots and a log. - Print plain log lines for key events, like scene loaded or save written.
- Optional: expose the same controls as an MCP server, like Super Robot Wars 64 did.
- Write three golden runs: boot to title, start a new game, reach the first level.
Prompt for ClaudeGOAL: Add a scripted run mode so `tools/capture_test.ps1 <SCRIPT>` boots <GAME>, plays a fixed input list, and saves screenshots and a log. READ FIRST: `src/main/`, `src/game/`, `notes/runs.md`. FENCE: Edit only `src/main/`, `src/game/debug_*`, `tools/capture_test.ps1` and `tests/runs/`. Never edit `generated/`. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `powershell -File tools/capture_test.ps1 tests/runs/boot_to_title.txt`. Done means it exits 0, saves at least 3 screenshots, and the log shows the title scene line. BUDGET: Stop after 4 failed tries, or 60 minutes with no progress. IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the log lines and list the screenshots. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whentools/capture_test.ps1 tests/runs/boot_to_title.txtexits 0 and its log shows the title scene.Proof this works: WinBack Recompiled, Marchwind64
- Add environment variables for scripted input, like WinBack's
Grind: one crash or one bad frame at a time
Now play through the game in small steps. Each card fixes one crash, one hang or one wrong picture. Fix it in the config, a hook or a C patch. Check drawing against a trusted emulator, not by eye.
- Log each bug in
PROGRESS.mdwith the run that shows it. - Fix odd code in the TOML:
stubs,ignored,manual_funcs,function_sizes,[[patches.hook]]. - Write game changes as C in
patches/and run them back throughN64Recomp. - For a hang, look for loops that wait on another thread. The runtime only switches threads inside libultra calls.
- Compare frames with the
aresemulator or ParaLLEl-RDP output. - Write each root cause to
notes/bugs/<topic>_<date>.md.
Prompt for ClaudeGOAL: Fix bug <BUG_ID> (<ONE-LINE SYMPTOM>) so golden run `<RUN>` passes. READ FIRST: `PROGRESS.md` entry <BUG_ID>, `notes/bugs/`, the log from `tools/capture_test.ps1 <RUN>`. FENCE: Edit only `config/`, `patches/`, `src/game/`. Never edit `generated/`; change the config and regenerate. Fix drawing bugs in the renderer patches, never by changing game code. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `powershell -File tools/check.ps1` and then `tools/capture_test.ps1 <RUN>`. Done means both pass and all older golden runs still pass. BUDGET: Stop after 3 failed fixes, or 60 minutes with no progress. IF BLOCKED: Stop. Do not stub the failing call. Tell me the cause you proved, what you tried, 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: paste all golden run results. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenThe golden run for the bug passes, and every older golden run still passes.Proof this works: WinBack Recompiled, Donkey Kong 64: Recompiled, Marchwind64
- Log each bug in
Harden: regression runs, pins and a clean release
Make sure old fixes stay fixed. Pin every tool to one commit. Keep your fixes to other people's code as patch files. Ship a build with no game data, and have it check the player's ROM hash.
- Run every golden run after each change, using one script:
tools/run_all.ps1. - Pin
N64Recomp,N64ModernRuntimeandRT64commits in a file, like WinBack's pinned list. - Keep changes to them as numbered files in
patches/with one reason each. - Make the game refuse any ROM whose SHA-1 is wrong.
- Build from a clean clone and run all golden runs before you call it a release.
Prompt for ClaudeGOAL: Make <GAME> rebuild from a clean clone and pass every golden run, with pinned deps and no ROM data in the output. READ FIRST: `PROGRESS.md`, `patches/README.md`, `tools/run_all.ps1`. FENCE: Edit only `tools/`, `patches/README.md`, `deps.lock` and `PROGRESS.md`. Do not change game behavior. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: In a fresh clone, run `powershell -File tools/check.ps1` then `tools/run_all.ps1`. Done means both exit 0 and the release folder holds no ROM-derived file. BUDGET: Stop after 3 failed tries, or 60 minutes with no progress. IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the run_all summary. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenA fresh clone builds with one command, every golden run passes, and the release has no game data.Proof this works: WinBack Recompiled, Zelda 64: Recompiled, Ship of Harkinian
- Run every golden run after each change, using one script:
Path B: Full decomp for porting
You split the ROM, then write C for each function. The game's own compiler must turn your C into the same bytes. A script rebuilds the whole ROM and checks its hash. When every function matches, you swap the console parts for PC parts with libultraship and Torch.
Method: matching decompilation
Pick this when you want real source that can be ported anywhere. First check for a finished decomp. If one exists, skip to the port steps.
Scope: prior work and the compiler
Check for an existing decomp before anything else. Then make a first guess at which compiler built the game. IDO and GCC leave different marks in the code. The wrong compiler can never match. You prove the guess later, in the first-light step.
- Search GitHub and decomp.dev for
<GAME> decomp. - Look up decomps of the studio's other games and note their compiler.
- If you already split the ROM for Path A, look at a few functions. IDO and KMC GCC lay out stack frames in different ways.
- Ask in the N64 decomp Discord which compiler the studio's other games used.
- Write the compiler guess, its evidence and the ROM SHA-1 in
SCOPE.md.
Prompt for ClaudeGOAL: Name the most likely compiler and flags for <GAME>, with evidence, so the first-light step can prove it. READ FIRST: `SCOPE.md`, `notes/prior-work.md`, and if they exist, three small functions in `asm/` that I name: <FUNC1>, <FUNC2>, <FUNC3>. FENCE: Edit only `SCOPE.md` and `notes/compiler.md`. Everything else is read-only. Do not install anything. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `grep -E "^(Compiler|Flags|Evidence):" notes/compiler.md`. Done means all three lines print, and Evidence lists at least two sources with URLs or file paths. BUDGET: Stop after 30 minutes. IF BLOCKED: Stop. Say which compilers you ruled out and why. Do not guess without evidence. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the grep output. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whengrep -E "^(Compiler|Flags|Evidence):" notes/compiler.mdprints three lines, and you approved the guess inSCOPE.md.Proof this works: https://blog.chrislewis.au/decompiling-a-nintendo-64-game-in-84-days/, https://github.com/decompals/ido-static-recomp, https://github.com/decompals/mips-gcc-2.7.2
- Search GitHub and decomp.dev for
Set up the matching build in WSL
Matching builds are made for Linux. Clone into the WSL file system, not under
/mnt/c. Set up the old compiler,splatand a build that prints OK when the ROM matches. That OK is your one check.- In Ubuntu:
sudo apt install make git python3 python3-venv python3-pip binutils-mips-linux-gnu. - Make a venv:
python3 -m venv .venv, then.venv/bin/pip install -U "splat64[mips]". - Download the Linux build of
ido-static-recomp(IDO 5.3 or 7.1) ormips-gcc-2.7.2intotools/. - Vendor
asm-processorintotools/if the game uses IDO. - Write
tools/build-and-verify.shthat rebuilds and checks the ROM SHA-1. - Add Claude Code hooks that block edits to the
.sha1file and toasm/.
Prompt for ClaudeGOAL: Make `./tools/build-and-verify.sh` rebuild <GAME> from the split assembly and print `OK` because the SHA-1 matches. READ FIRST: `SCOPE.md`, `Makefile`, the `splat` config, the Snowboard Kids decomp README as a pattern. FENCE: Edit only `Makefile`, `tools/`, `.claude/settings.json` and `CLAUDE.md`. Never edit `<game>.sha1` or `asm/`. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `./tools/build-and-verify.sh`. Done means the last line is `build/<game>.z64: OK`. Then break one byte in a copy and show the check fails. BUDGET: Stop after 5 failed tries, or 90 minutes with no progress. IF BLOCKED: Stop. Do not edit the expected hash. Tell me what blocked you, what you tried, and what you need from me. 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 when./tools/build-and-verify.shprintsOKon a clean clone, and fails when one byte is changed.Proof this works: https://github.com/cdlewis/snowboardkids-decomp, https://github.com/zeldaret/oot, https://github.com/ethteck/splat
- In Ubuntu:
Map the binary into a function ledger
List every function with its size and a status column. Mark library code, so nobody matches it by hand. Sort the rest from easy to hard. This file is the to-do list for every worker.
- Name libultra functions with
n64sym, then compare againstultralibsources. - Write
ledger.csvwith columns: name, file, address, size, status, owner. - Mark library functions as
liband try the matchingultralibversion first. - Run
m2con every function once as a cheap first pass. Keep only exact matches. - Sort the rest by size and by likeness to already-matched code.
Prompt for ClaudeGOAL: Write `ledger.csv` listing every function in <GAME> with address, size and status, with libultra marked. READ FIRST: `SCOPE.md`, the `splat` config, `asm/` file list, `notes/library.md`. FENCE: Edit only `ledger.csv`, `tools/make_ledger.py` and `notes/library.md`. `asm/` is read-only. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `python3 tools/make_ledger.py --verify`. Done means it reports zero functions missing from the ledger and the size total equals the code size from `splat`. BUDGET: Stop after 4 failed tries, or 60 minutes with no progress. IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the verify output and counts by status. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whentools/make_ledger.py --verifyreports no missing functions and sizes add up.Proof this works: https://blog.chrislewis.au/decompiling-a-nintendo-64-game-in-84-days/, https://github.com/decompals/ultralib, https://github.com/matt-kempster/m2c
- Name libultra functions with
First light: match one function end to end
Prove the whole loop on one small function. Swap its assembly for C. Rebuild. The full ROM hash must still match. Now you know the pipeline works, and that your compiler guess was right.
- Pick a short function with no loops from the ledger.
- If no flag set matches after a few tries, go back to
notes/compiler.mdand try the next compiler guess. - Get a draft with
python3 tools/m2c/m2c.py -t mips-ido-c asm/<file>.s(usemips-gcc-cfor GCC games). - Put the C in
src/, replacing itsINCLUDE_ASMline. - Check the diff with
asm-differorobjdiff. - Run
./tools/build-and-verify.shand commit only if it prints OK.
Prompt for ClaudeGOAL: Match function <FUNC> in `src/<FILE>.c` so the full ROM still builds to the original SHA-1. READ FIRST: `asm/nonmatchings/<FILE>/<FUNC>.s`, `include/`, the m2c draft. FENCE: Edit only `src/<FILE>.c` and its header. Never edit `asm/`, the `.sha1` file or the build scripts. No inline assembly. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `./tools/build-and-verify.sh`. Done means it prints `OK` and the `INCLUDE_ASM` line for <FUNC> is gone. BUDGET: Stop after 10 attempts with no gain. Save each attempt as a new file `scratch/<FUNC>_n.c`. IF BLOCKED: Stop. Report the best diff score and the first differing instructions. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenOneINCLUDE_ASMis gone, C is in its place, andbuild-and-verify.shprintsOK.Proof this works: https://blog.chrislewis.au/the-unexpected-effectiveness-of-one-shot-decompilation-with-claude/, https://github.com/simonlindholm/asm-differ
Grind: the bulk worker loop
Now match functions one per session. A script picks the next one, not Claude. Each worker gets its own git worktree. Commit after every match and reset after every failure.
- Run 3 or 4 worktrees:
git worktree add ../wt1 -b wt1. - Split the ledger between them so no two workers touch one file.
- Run one function per headless session:
claude -p "<CARD>". It runs once and exits. - For runs with nobody watching, pre-approve only the tools the card needs with
--allowedTools, and add--permission-mode dontAskso anything else is refused. - After each run: if
build-and-verify.shpasses, commit; if not,git reset --hard. - Merge worktrees often, and run the full check again after each merge.
- Update
ledger.csvandPROGRESS.mdfrom the commits, not from chat.
Prompt for ClaudeGOAL: Match function <FUNC> (ledger row <ROW>) in worktree <WT>. READ FIRST: `CLAUDE.md`, `notes/compiler-quirks.md`, `asm/nonmatchings/<FILE>/<FUNC>.s`, up to 3 similar matched functions: <REFS>. FENCE: Work only in the absolute path <WT>. Edit only `src/<FILE>.c` and `scratch/`. Never edit `asm/`, the `.sha1` file, `tools/` or other files. No inline assembly or register pins. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `<WT>/tools/build-and-verify.sh`. Done means it prints `OK` and <FUNC> is C. BUDGET: Stop after 10 attempts with no gain, or 25 minutes. IF BLOCKED: Stop. Write <FUNC> and the best score in `notes/hard.md`. Do not try the next function. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenThe ledger's matched count rises, andbuild-and-verify.shprintsOKon the merged main branch.Proof this works: https://blog.chrislewis.au/decompiling-a-nintendo-64-game-in-84-days/, https://github.com/cdlewis/nigel, BattleShip
- Run 3 or 4 worktrees:
The hard tail: big functions and compiler quirks
The last tenth is the hardest part. Huge functions, display lists and matrix math resist matching. Use the permuter only as an idea source. Ask human experts. Record every trick in one shared quirks file.
- Send functions from
notes/hard.mdtohardsessions, one at a time. - Run
decomp-permuterfrom its folder:./import.py <REPO>/src/<file>.c <REPO>/asm/nonmatchings/<file>/<func>.s, then./permuter.py nonmatchings/<func> -j 4. - Have Claude explain any permuter win before keeping it.
- Write general compiler tricks in
notes/compiler-quirks.md, never one-off notes. - Post the hardest ones on decomp.me and ask in the N64 decomp Discord.
Prompt for ClaudeGOAL: Match hard function <FUNC>, or prove what blocks it. READ FIRST: `notes/hard.md` entry for <FUNC>, `notes/compiler-quirks.md`, earlier attempts in `scratch/<FUNC>_*.c`. FENCE: Edit only `src/<FILE>.c`, `scratch/` and `notes/compiler-quirks.md`. No inline assembly, `asm("")` barriers, register pins or compiler changes. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `./tools/build-and-verify.sh`. Done means it prints `OK` with <FUNC> in plain C. BUDGET: Stop after 15 attempts with no gain, or 60 minutes. IF BLOCKED: Stop. Name the exact differing instructions and your best idea of why. "Compiler artifact" alone is not an answer. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output or the best diff. 3) Files changed. 4) What is left. 5) New parking-lot items.Done whenEvery ledger row is matched or has a written blocker that a person has read.Proof this works: https://blog.chrislewis.au/the-long-tail-of-llm-assisted-decompilation/, https://github.com/simonlindholm/decomp-permuter
- Send functions from
Harden the decomp and hunt for cheats
A fresh agent checks the claimed work. It rebuilds from scratch and searches for banned tricks. Bad matches go back to the queue. Clean names and types help the port later.
- Clone fresh and run
./tools/build-and-verify.sh. - Search for cheats:
grep -rn -E "__asm__|asm\(|register .* asm" src/. - Check
git log -pfor any change to the.sha1file orasm/. - Rename
func_XXXXnames to real names as you learn them. - Turn pointer math into struct access where you can.
Prompt for ClaudeGOAL: Independently check the last <N> matched functions and list any that cheat. READ FIRST: `CLAUDE.md` rules on banned constructs, `git log --oneline -<N>`. FENCE: Read-only. Edit only `notes/verify-<DATE>.md`. Do not fix anything. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: In a fresh clone, run `./tools/build-and-verify.sh` and the grep for inline assembly. Done means the report lists every function as CLEAN or SUSPECT, with the reason. BUDGET: Stop after 45 minutes. IF BLOCKED: Stop. Tell me what you could not check and why. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the build output and grep output. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenA fresh clone printsOK, and the verify report shows no SUSPECT function left unresolved.Proof this works: https://blog.chrislewis.au/the-long-tail-of-llm-assisted-decompilation/, https://github.com/cdlewis/snowboardkids2-decomp
- Clone fresh and run
Port: put the decomp on libultraship
Now swap the console parts for PC parts.
libultrashipreplaces libultra and draws display lists.Torchpulls assets from the player's ROM. First make every file compile on PC, then link.- Add
libultrashipandTorchas pinned git submodules. Fork them only if you must. - Do a compile sweep: build every file with the PC compiler and group the errors by type.
- Fix N64 types declared as
long; they must stay 32-bit on a 64-bit PC. - Wrap each change to decomp files in
#ifdef PORT. - On Windows, set up the build as Starship does:
cmake -S . -B build/x64 -G "Visual Studio 17 2022" -T v143 -A x64. - Describe assets in YAML for
Torch, and extract them from your ROM withcmake --build build/x64 --target ExtractAssets. - Build the game:
cmake --build build/x64.
Prompt for ClaudeGOAL: Make every decomp source file of <GAME> compile and link on PC against `libultraship`. READ FIRST: `SCOPE.md`, `notes/port-errors.md`, the libultraship porting guide at https://kenix3.github.io/libultraship/PORTING.html. FENCE: Edit only `port/`, `CMakeLists.txt`, `yamls/`, and decomp files inside `#ifdef PORT` blocks. Never remove the original N64 code path. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `cmake --build build/x64`. Done means zero errors, and `./tools/build-and-verify.sh` in WSL still prints `OK` for the N64 build. BUDGET: Stop after one error class per session, or 60 minutes. IF BLOCKED: Stop. Do not silence warnings like implicit function declaration. Tell me what blocked you. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste error counts before and after. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenThe PC build has zero errors, and the N64 build still printsOK.Proof this works: BattleShip, Project Midas, Starship
- Add
Port: golden runs and graphics traces
Make the PC build boot and play. Compare its display lists to an emulator's, not by eye. Fix byte order and struct layout bugs with proof. Ship with no game data.
- Add a trace switch that dumps the display list each frame, like BattleShip's
SSB64_GBI_TRACE=1. - Capture the same frames from an emulator and diff them with a small script.
- Fix big-endian data at load time, with small per-struct fixes.
- Add
_Static_assertchecks on struct sizes. - Run boot, menu and first-level golden runs after every fix.
Prompt for ClaudeGOAL: Fix graphics bug <BUG_ID> in the PC port using a display-list trace diff. READ FIRST: `notes/bugs/`, the port trace and the emulator trace for frame <N>. FENCE: Edit only `port/` and decomp lines inside `#ifdef PORT`. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run the trace diff for frame <N>. Done means no differing commands, and all golden runs pass. BUDGET: Stop after 3 failed fixes, or 60 minutes with no progress. IF BLOCKED: Stop. Do not change the trace tool or the reference trace. Tell me the first differing command and your evidence. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the diff summary and golden run results. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenThe trace diff for the chosen frames is empty, and every golden run passes on PC.Proof this works: BattleShip, Project Midas
- Add a trace switch that dumps the display list each frame, like BattleShip's
Tools you need
| Tool | What it does | How to get it | How we know |
|---|---|---|---|
| N64Recomp (with RSPRecomp) Required both | Turns N64 MIPS code into C, one function per file. RSPRecomp does the same for audio and graphics microcode.Path A | git clone --recurse-submodules https://github.com/N64Recomp/N64Recomp deps/N64Recomp, then cmake -S deps/N64Recomp -B deps/N64Recomp/build -G Ninja -DCMAKE_BUILD_TYPE=Release and cmake --build deps/N64Recomp/build (on Windows, inside the Visual Studio x64 build setup) | README, CONTRIBUTING.md, CMakeLists.txt and src/config.cpp read 2026-11-13 (CMake 3.20+, C++20; the CLI target is named N64Recomp; the config reads symbols_file_path, stubs, ignored, manual_funcs, function_sizes and hooks, though the README still says an ELF is required). Windows build commands from WinBack's tools/fetch_deps.sh, read 2026-11-13. Used by: Zelda 64: Recompiled, Banjo: Recompiled, Donkey Kong 64: Recompiled, WinBack Recompiled, Marchwind64. |
| N64ModernRuntime Required both | Stands in for libultra on PC: threads, audio, timers, controllers, overlays and saves. Path A | Add as a git submodule and use add_subdirectory in your CMakeLists.txt | README read 2026-11-13 (developed with Clang 15). Used by all five recomp projects reviewed. |
| RT64 Required both | Draws N64 graphics with D3D12, Vulkan or Metal. Adds widescreen, high frame rate and texture packs. Path A | Add as a git submodule (git submodule update --init --recursive) and build it with your project | README read 2026-11-13 (Windows 10/11, Linux, macOS). Used by: Zelda 64: Recompiled, Banjo: Recompiled, WinBack Recompiled. |
| splat (splat64) Required both | Splits an N64 ROM into code, data and assets, and writes assembly files. Path A Path B | python3 -m pip install -U "splat64[mips]" | README and wiki Quickstart read 2026-11-13 (create_config and split commands). Used by: WinBack Recompiled, PaperBoat. |
| n64sym Helpful Windows | Finds known library functions, like libultra, inside a ROM and names them. Path A Path B | Download n64sym-v0.9a.zip from the releases page | README and releases read 2026-11-13 (v0.9a, 2020-11-09; ROM scans may be wrong; can output splat symbol files). Used by: Marchwind64 (355 libultra labels, reviewed by hand). WinBack used only its signature file, through its own tools/sigmatch.py. Whether the release zip holds anything but a Windows build was not checked. |
| Visual Studio 2022 Build Tools with LLVM Clang Required Windows | The Windows compilers for the recomp build. Recomp projects build with clang-cl.Path A Path B | In the Visual Studio 2022 installer, pick "Desktop development with C++", then the optional parts "C++ Clang compiler for Windows" and "C++ CMake tools for Windows" | Microsoft Learn pages "CMake projects in Visual Studio" and "Clang/LLVM support in Visual Studio CMake projects" read 2026-11-13 (part names). Build steps in the cards for WinBack Recompiled and PaperBoat (clang-cl), and Starship BUILDING.md (MSVC v143) read 2026-11-13. |
| CMake and Ninja Required both | CMake sets up the build. Ninja runs it fast. Path A Path B | Windows: the Visual Studio part "C++ CMake tools for Windows" adds CMake, or use the installer from cmake.org; get `ninja.exe` from the Ninja releases page (https://github.com/ninja-build/ninja/releases). WSL: sudo apt install cmake ninja-build | Used by every recomp and port card reviewed (BUILDING.md steps). Microsoft Learn read 2026-11-13 says the C++ CMake tools part installs with Desktop C++. Torch README (read 2026-11-13) gives the apt line. Whether Visual Studio also puts Ninja on your path was not confirmed. |
| ares Helpful Windows | An accurate N64 emulator. Use it as the reference when you compare frames, memory or audio. Path A Path B | Download ares-windows-x64.zip from the v148 release | README and releases read 2026-11-13 (v148, 2026-05-30). Used by: Marchwind64 (v148 as reference); Zelda 64: Recompiled took RSP code from it. |
| ido-static-recomp Required WSL/Linux | Runs SGI's old IDO 5.3 and 7.1 compilers on modern machines, so IDO games can match. Path B | Download ido-5.3-recomp-linux.tar.gz or ido-7.1-recomp-linux.tar.gz from the v1.2 release into tools/ | README and releases read 2026-11-13 (v1.2 has Linux, macOS and Windows tarballs). Used by: Snowboard Kids decomp, Project Midas (N64 build). |
| mips-gcc-2.7.2 Helpful WSL/Linux | A GCC 2.7.2 build that matches KMC GCC output, for games not built with IDO. Path B | Download gcc-2.7.2-linux.tar.gz from the v0.1 release into tools/ | Repo description ("tailored to match kmc-gcc output") and releases read 2026-11-13 (v0.1: Linux and macOS builds only). Snowboard Kids 2 used GCC 2.7.2 per its author's blog. Which GCC build that project uses was not checked. |
| asm-processor Required both | Lets C files hold assembly for functions not matched yet, so IDO builds still work. Path B | Vendor it into tools/asm-processor, or download the 1.0.1 release binary for your system | README and releases read 2026-11-13 (1.0.1 has Windows, Linux and macOS binaries; IDO only). Used by: Snowboard Kids decomp (tools/asm-processor submodule, .gitmodules read 2026-11-13). None of the 15 reviewed projects names it. |
| m2c Helpful both | Turns MIPS assembly into a first draft of C. The draft rarely matches, but it saves typing. Path B | git clone https://github.com/matt-kempster/m2c tools/m2c, then python3 tools/m2c/m2c.py --help | README read 2026-11-13 (targets mips-ido-c and mips-gcc-c). Snowboard Kids used it as a free first pass. |
| asm-differ and objdiff Required both | Show your compiled function next to the original, instruction by instruction, with a score. Path B | pip install 'asm-differ @ git+https://github.com/simonlindholm/asm-differ.git' ; or download objdiff-cli from the objdiff releases page | asm-differ README and objdiff README and v3.8.3 release read 2026-11-13 (objdiff supports MIPS N64). Starship keeps asm-differ as a submodule. |
| decomp-permuter Helpful WSL/Linux | Tries many small random changes to your C to find a closer match. Path B | git clone https://github.com/simonlindholm/decomp-permuter tools/permuter, then python3 -m pip install toml Levenshtein | README and import.py read 2026-11-13 (MIPS IDO, possibly GCC; import.py makes nonmatchings/<func>; pynacl is only for the shared network mode). Snowboard Kids keeps it as a submodule. Snowboard Kids 2 removed it from the agent loop. |
| libultraship and Torch Required both | libultraship replaces libultra on PC and draws display lists. Torch pulls assets out of the player's ROM into an .o2r file.Path B | Add both as pinned git submodules; build with CMake (Visual Studio 2022 with the v143 tools on Windows) | libultraship README and porting guide link, Torch README, and Starship BUILDING.md read 2026-11-13. Used by: Ship of Harkinian, Starship, SpaghettiKart, Ghostship, PaperBoat, BattleShip. |
| WSL 2 with Ubuntu Required Windows | A Linux system inside Windows. Path B matching builds run here. Path B | Follow Microsoft's WSL install guide (https://learn.microsoft.com/en-us/windows/wsl/install), then clone your repo inside the Linux file system, not under /mnt/c | Ocarina of Time decomp README read 2026-11-13 (recommends WSL; clone into the Linux file system because IDO cannot handle Windows line endings). splat Quickstart read 2026-11-13 assumes Ubuntu, WSL2 or Docker. |
| MIPS binutils, Python 3 and Git (in WSL) Required WSL/Linux | The MIPS assembler and linker that the matching build calls, plus Python for splat and Git.Path B | sudo apt install make git python3 python3-venv python3-pip binutils-mips-linux-gnu | Snowboard Kids and Snowboard Kids 2 READMEs and the Ocarina of Time README read 2026-11-13 (all name binutils-mips-linux-gnu). |
| Python 3 and Git (on Windows) Required Windows | Python runs splat and your helper scripts. Git holds your code and pins the tools.Path A Path B | Install Python 3 from python.org and Git for Windows, then make a venv in the repo: python -m venv .venv | WinBack card build steps (Python 3, Git, python -m venv .venv). Starship BUILDING.md read 2026-11-13 also asks for Python 3 and Git. |
| ultralib Helpful WSL/Linux | A rebuilt copy of libultra source. Library functions in your game often match it as-is, so agents start from it, not from scratch. Path B | git clone https://github.com/decompals/ultralib tools/ultralib (read its README for the versions it can build) | README read 2026-11-13 (builds libultra 2.0I to 2.0L for IDO and GCC). Snowboard Kids' author says agents had to be pushed to use library source first. |
| ROM decompressor (game specific) Helpful both | Unpacks a game whose code is compressed, so the recompiler or splitter sees real code. Each game family has its own tool. Path A Path B | Use the tool the game's decomp uses. Zelda games: build or download `z64decompress` and run z64decompress rom-in.z64 rom-out.z64 | z64decompress README read 2026-11-13 (usage line). Zelda 64: Recompiled card names it; Banjo: Recompiled uses bk_rom_compressor; Donkey Kong 64: Recompiled uses the DK64 decomp's script. |
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.
n64-decomp
A full N64 guide for both matching and N64Recomp ports. It loads one topic at a time and keeps a state file.
npx skills add dohmboy64bit/n64-decomp-skill --skill n64-decomp -a claude-code
n64-decomp-setup
Step-by-step start of an N64 decomp: split with splat, build with ninja, add a hash check, then find the compiler. Its clean step deletes three folders, so read it first. skills.sh still lists it under its old name, n64-decomp.
npx skills add marijnvdwerf/agent-skills --skill n64-decomp-setup -a claude-code
n64-decomp-splat
A reference for editing a splat config. It stops Claude from guessing how segments are written.
npx skills add marijnvdwerf/agent-skills --skill n64-decomp-splat -a claude-code
n64-decomp-ido
Explains how asm-processor lets C and assembly share one file. Use it only for games built with IDO.
npx skills add marijnvdwerf/agent-skills --skill n64-decomp-ido -a claude-code
matching-decomp
Gives Claude the dk.py tool for one-function-at-a-time matching on MIPS splat projects. It commits and resets by itself, so save your work first.
npx skills add ketbome/decomp-skills --skill matching-decomp -a claude-code
recompile-console-binary
Rules for N64Recomp work. Its main rule: never edit the made code; change the config and run the tool again.
npx skills add xsyetopz/skills --skill recompile-console-binary -a claude-code
verification-before-completion
Claude may not say done without fresh proof. That stops false reports of a match or a fixed crash.
npx skills add obra/superpowers --skill verification-before-completion -a claude-code
using-git-worktrees
Keeps each parallel matching worker in its own worktree. BattleShip and Snowboard Kids both worked this way.
npx skills add obra/superpowers --skill using-git-worktrees -a claude-code
Game debug MCP server
Lets Claude start the game, press buttons, take screenshots and read memory by itself. Marchwind64 used this for every fix.
Copy the pattern of Marchwind64's `tools/recomp/debug/mcp_server.py`: a plain Python stdio server listed in `.mcp.json` that talks to a debug port in your game
run-golden (write your own)
Gives every Path A and port card the same in-game check. BattleShip Remix built this as its remix-smoke-tests skill.
A skill folder `.claude/skills/run-golden/` with SKILL.md and scripts: boot the game with an input script, save screenshots and the log to a fresh run folder, make a contact sheet, and print PASS or FAIL. Rules: never rebuild during a run; look at the screenshots, not just the exit code.
match-one (write your own)
Same steps for every function, so results stay steady. It copies the Snowboard Kids 2 per-function setup.
A skill folder `.claude/skills/match-one/` with SKILL.md: make a scratch folder for one function, write each attempt as a new numbered file, run `build-and-verify.sh`, stop after 10 tries with no gain, and log the result to `notes/hard.md`.
Claude setup for this system
For Path A, one card is one crash, one hang, one missing call or one bad frame. Each card names the golden run that shows the bug. For Path B, one card is one function, checked by the full ROM hash. For the port, one card is one class of compile error or one trace diff. A script picks the next unit, not Claude.
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.
| Job | What it means on this system | Max 20x (now called Ultra) | Max 5x (now called Max) |
|---|---|---|---|
| Plan the project | Check for an existing decomp or recomp of your game. Find the compiler. Write SCOPE.md with the ROM hash. | Fable 5.2 effort highOne session. This choice shapes months of work. | Opus 5.5 effort highUse Fable 5.2 for this one session if you have weekly room. |
| Set up the project | Build N64Recomp, set up CMake with clang-cl, or set up the WSL matching build that prints OK. Add the hooks. | Opus 5.5 effort medium | Sonnet 5.5 effort medium |
| Study the game file | Split the ROM with splat, list overlays, name libultra with n64sym, and write the symbols TOML or the function ledger. | Opus 5.5 effort high | Opus 5.5 effort mediumRaise to high for function edges and data layouts. A mistake there spreads. |
| Bulk units | Match small and medium functions, one per session, in parallel worktrees. Also simple config fixes like stubbing a known debug call. | Sonnet 5.5 effort mediumHaiku 5.5 for the plainest units. | Sonnet 5.5 effort mediumFewer workers at once. Haiku 5.5 for the plainest units. |
| Hard units | Functions over a few hundred instructions, display-list macros, matrix math and IDO register quirks that bulk workers gave up on. | Fable 5.2 effort highGo to xhigh only after a failed try at high. | Opus 5.5 effort highSend only the last few that still fail to Fable 5.2. |
| Build the runtime | Hooks into N64ModernRuntime, overlay loading, audio timing, renderer patches for RT64, and the scripted-run switches. | Opus 5.5 effort high | Opus 5.5 effort mediumRaise to high for timing and graphics bugs. |
| Find a bug | Find why the recomp hangs or draws wrong, using logs, display-list dumps and an ares reference. Prove the cause first. | Opus 5.5 effort highAfter two failed tries with full evidence, move to Fable 5.2. | Opus 5.5 effort highOne bug at a time. |
| Check the work | A fresh session rebuilds from a clean clone, greps for inline assembly and hash edits, and reruns all golden runs. | Opus 5.5 effort mediumAlways a new session, never the one that did the work. | Sonnet 5.5 effort highAlways a new session, never the one that did the work. |
| Keep the records | Update ledger.csv, PROGRESS.md, notes/bugs/ and notes/compiler-quirks.md from the commits. | Haiku 5.5 effort medium | Haiku 5.5 effort medium |
How many sessions at once
Max 20x (now called Ultra)
Path B: run one lead session plus 3 or 4 matching workers, each in its own worktree. Snowboard Kids used four worktrees. Path A: run 1 or 2 debug sessions at once, each on a different bug with its own run folder. Keep build jobs at -j 4 per worker so the PC does not run out of memory.
Max 5x (now called Max)
Path B: run one lead plus 1 or 2 workers, and let the bulk loop run overnight. Path A: one debug session at a time. Save the weekly limit for hard and debug jobs, and keep docs jobs short.
Lines for this project's CLAUDE.md
- Read `SCOPE.md` and `PROGRESS.md` at the start of every session.
- The one check is `./tools/build-and-verify.sh` (Path B) or `tools/check.ps1` plus the golden runs (Path A). Do not report DONE until it passes; paste its output.
- Never edit `generated/` or `asm/`. These are made by tools. Change the config or `symbol_addrs.txt` and regenerate.
- Never edit the `.sha1` file, the build-and-verify script or the golden-run reference images.
- No inline assembly, `asm("")` barriers or register pins to force a match. A matching hash does not make a cheat acceptable.
- Never commit the ROM or anything made from it. `rom/`, `generated/` and `build/` stay ignored.
- Fix drawing bugs in the renderer patches, never by changing game code.
- Unknown system calls must stop with a named error. Never return fake success with an empty stub.
- In a worktree, always use absolute paths in commands. The working folder resets between commands.
- When you fix a real bug, write `notes/bugs/<topic>_<YYYY-MM-DD>.md` with symptom, cause and fix.
- Do not send pull requests to `N64Recomp`, `RT64` or the Zelda and Banjo recomps. They reject AI-written code. Keep fixes as patch files here.
- Cap builds at `-j 4`. Side ideas go to `notes/parking-lot.md`.Keep the context small
- Give Claude a function name and a file path, not pasted assembly. Snowboard Kids 2 found Claude ignored pasted listings anyway.
- Start each matching worker in its scratch folder, not the repo root, so it does not spend tokens exploring.
- Keep
CLAUDE.mdshort and point to topic files likenotes/compiler-quirks.md, as WinBack and BattleShip did. - Hand over at most three similar matched functions as examples per card.
- For a graphics bug, give the first differing display-list command from a trace diff, not a description of the picture.
- Clear the chat after every unit. State lives in
ledger.csvandPROGRESS.md.
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 a port of an existing decomp.
GOAL: Tell me if <GAME> (<REGION>, SHA-1 <HASH>) can be recompiled or decompiled, by which technique, and what exists already. READ FIRST: `notes/prior-work.md`, the RecompLauncher entry if any, GitHub search results for `<GAME> decomp` and `<GAME> recomp`. FENCE: Edit only `SCOPE.md` (draft) and `notes/prior-work.md`. Do not open or copy the ROM. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `grep -E "^## (Technique|Prior work|Compiler|Risks)" SCOPE.md` and `grep -c http notes/prior-work.md`. Done means all four headings print, the URL count is above zero, `SCOPE.md` names one technique and the compiler or "unknown", and it lists the three biggest risks (compression, overlays, missing decomp). BUDGET: Stop after 40 minutes. IF BLOCKED: Stop. Say what you could not find. Do not guess facts. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: the URLs. 3) Files changed. 4) What is left. 5) New parking-lot items.
A good answer: DONE, one clear technique, links to any decomp or recomp, the compiler or "unknown", and three named risks.
Map the binary
After the split, before first light, to get the full function list.
GOAL: Produce `ledger.csv` for <GAME> with every function's name, address, size, segment and status. READ FIRST: `notes/segments.md`, `config/symbol_addrs.txt`, `config/n64sym_addrs.txt`. FENCE: Edit only `ledger.csv`, `tools/make_ledger.py` and `notes/library.md`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `python3 tools/make_ledger.py --verify`. Done means no missing functions, sizes add up, and libultra rows are marked `lib`. BUDGET: Stop after 4 failed tries, or 60 minutes. IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: counts by status and segment. 3) Files changed. 4) What is left. 5) New parking-lot items.
A good answer: A count table, such as 2,100 functions, 300 lib, 1,800 to do, plus the verify output.
Unit loop, Path A: one recomp bug
For each crash, hang or bad frame in the recomp.
GOAL: Fix <BUG_ID>: <SYMPTOM>, seen in golden run `<RUN>`. READ FIRST: `PROGRESS.md` entry <BUG_ID>, the run log, `notes/bugs/`. FENCE: Edit only `config/<game>.us.toml`, `patches/` and `src/game/`. Never edit `generated/`. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `powershell -File tools/check.ps1` then `powershell -File tools/run_all.ps1`. Done means `<RUN>` passes and no older run fails. BUDGET: Stop after 3 failed fixes, or 60 minutes. IF BLOCKED: Stop. Do not stub the call or skip the scene. Tell me the proven cause and your options. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: run_all summary. 3) Files changed. 4) What is left. 5) New parking-lot items.
A good answer: DONE, a one-line cause (for example a missed osAiGetLength name), the config change, and every run passing.
Unit loop, Path B: one function
For each function in the bulk matching loop.
GOAL: Match <FUNC> in `src/<FILE>.c`. READ FIRST: `asm/nonmatchings/<FILE>/<FUNC>.s`, `notes/compiler-quirks.md`, similar matched functions <REFS>. FENCE: Edit only `src/<FILE>.c` and `scratch/<FUNC>_*.c`. Never edit `asm/`, the `.sha1` file or `tools/`. No inline assembly. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `./tools/build-and-verify.sh`. Done means it prints `OK`. BUDGET: Stop after 10 attempts with no gain. One change per attempt. IF BLOCKED: Stop. Log <FUNC> and the best score in `notes/hard.md`. Do not start another function. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.
A good answer: DONE with build/<game>.z64: OK, or BLOCKED with the score and the first differing instructions.
Batch dispatch
From the lead session, to hand out the next set of functions or bugs.
GOAL: Pick the next <N> units from `ledger.csv` and start one worker per unit, each in its own worktree. READ FIRST: `ledger.csv`, `notes/hard.md`, `git worktree list`. FENCE: Edit only the `owner` column in `ledger.csv`. Never give two workers the same file. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `git worktree list` and `git diff ledger.csv`. Done means one worktree per worker, each worker got the unit loop card with its absolute worktree path, and the diff shows exactly <N> owner changes. BUDGET: Stop after dispatching <N> units. IF BLOCKED: Stop. Tell me which units could not be assigned and why. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: the table of unit, worker, worktree. 3) Files changed. 4) What is left. 5) New parking-lot items.
A good answer: A short table with one row per worker and no file shared between two rows.
Debug with evidence
When the recomp or port crashes or hangs and the cause is not clear.
GOAL: Find the cause of <SYMPTOM> in <GAME>. Do not fix it yet. READ FIRST: the log of `<RUN>`, `notes/bugs/`, the display-list dump or memory watch if one exists. FENCE: Edit only `notes/debug-<BUG_ID>.md` and temporary log lines in `src/game/debug_*`. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `powershell -File tools/capture_test.ps1 <RUN>` once with your test switch on and once with it off. Done means the bug appears and vanishes on purpose, and the note shows the log or trace lines that prove it. BUDGET: Stop after 60 minutes or 3 wrong theories. IF BLOCKED: Stop. List the theories you ruled out and the evidence you still need. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: the log lines. 3) Files changed. 4) What is left. 5) New parking-lot items.
A good answer: A proven cause, such as a loop waiting on another thread, with the log lines that show it.
Verify: hunt for cheating
In a fresh session after any batch of claimed matches or fixes.
GOAL: Check the work since commit <SHA> and list anything that cheats or breaks the rules. READ FIRST: `CLAUDE.md`, `git log --stat <SHA>..HEAD`. FENCE: Read-only. Write only `notes/verify-<DATE>.md`. Do not fix anything. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: In a fresh clone, run the one check command and every golden run. Grep for inline assembly, edits to `.sha1`, `asm/` or `generated/`, empty stubs and disabled runs. Done means each commit is CLEAN or SUSPECT with a reason. BUDGET: Stop after 45 minutes. IF BLOCKED: Stop. Tell me 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: check output and grep output. 3) Files changed. 4) What is left. 5) New parking-lot items.
A good answer: A list of commits, most CLEAN, any SUSPECT one with the exact line and rule it breaks.
Status report
Once a week, or before you plan the next block of work.
GOAL: Report project status with numbers only. READ FIRST: `ledger.csv`, `PROGRESS.md`, `notes/hard.md`, `git log --since="7 days ago" --oneline`. FENCE: Read-only except `PROGRESS.md`. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run the one check command once (`./tools/build-and-verify.sh` or `powershell -File tools/run_all.ps1`) and paste it. Done means it ran, and every number traces to a file or command you name. BUDGET: Stop after 15 minutes. IF BLOCKED: Stop. Say which number you could not get. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: matched and total, bugs open and closed, golden runs passing. 3) Files changed. 4) Biggest blocker. 5) New parking-lot items.
A good answer: Five lines of numbers, such as 1,412 of 2,145 matched, 38 in notes/hard.md, 6 of 6 golden runs passing.
Session handoff
Before you stop for the day or before the context fills up.
GOAL: Write down everything the next session needs to carry on. READ FIRST: this session's work, `PROGRESS.md`, `git status`. FENCE: Edit only `PROGRESS.md` and `notes/handoff-<DATE>.md`. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `git status --short`. Done means only `PROGRESS.md` and the handoff note changed, and the note lists the current unit, the last check output, what was tried, dead ends, and the next card to run. BUDGET: Stop after 10 minutes. IF BLOCKED: Stop. Say what state you could not record. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: the note path. 3) Files changed. 4) What is left. 5) New parking-lot items.
A good answer: A short note a new session can follow without the old chat.
Blocked or cannot deliver
When a unit keeps failing and you need a plain answer.
GOAL: Tell me plainly whether <UNIT> can be finished, and if not, why. READ FIRST: `notes/hard.md` or `notes/bugs/` for <UNIT>, all attempts in `scratch/`. FENCE: Read-only. Write only `notes/blocked-<UNIT>.md`. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run the unit's check once more (`./tools/build-and-verify.sh` or its golden run) and paste the result. Done means the note says CAN, CANNOT YET or CANNOT, with that output, the evidence and the best result so far. BUDGET: Stop after 20 minutes. IF BLOCKED: Stop. Say which evidence is missing. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: best score or last run output. 3) Files changed. 4) Two or three options with cost. 5) New parking-lot items.
A good answer: A one-word verdict, the best score, and options such as ask an IDO expert, split the function, or leave it as assembly.
Scope change request
When Claude thinks the fix needs files outside the fence.
GOAL: Ask me before you leave the fence for <UNIT>. READ FIRST: `SCOPE.md`, the current task card. FENCE: Do not edit anything. Write only `notes/scope-request-<DATE>.md`. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `git status --short`. Done means the request note is the only change, and it names each file you want to touch, why, the risk, and a way to undo it. BUDGET: Stop after 10 minutes. IF BLOCKED: Stop and wait for my answer. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: the request path. 3) Files changed: none. 4) What you will do if I say yes. 5) New parking-lot items.
A good answer: A short request with a list of files and reasons, and no edits made.
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 detour | The rule to give Claude |
|---|---|
Claude edits the made C in generated/ to get past a crash. The next regen wipes the fix. | Never edit generated/. Change config/<game>.us.toml or a C patch and regenerate. Block generated/ with a hook. |
| Claude cannot match a function, so it changes the expected SHA-1. This happened on Snowboard Kids 2. | The .sha1 file and build-and-verify.sh are read-only. A PreToolUse hook blocks edits and exits with code 2. |
| Claude adds inline assembly or register pins to force a match and calls it done. | No __asm__, asm("") barriers or register pins in src/. A verify session greps for them after each batch. |
| Claude returns zero from an unknown system call so the next screen shows up. | Unknown calls stop with a named error. No empty stubs. Marchwind64 wrote this rule into its plan. |
| Claude patches game code to hide a drawing bug that is really in the renderer. | Fix drawing bugs in the RT64 patches, checked against an emulator frame. WinBack's CLAUDE.md says this. |
| Claude says "it booted" or "it compiles" and reports DONE. | Build, boot, scene and full play are separate levels. Name the level and paste the golden-run proof. |
| Claude in a worktree runs a relative build path and builds the main tree by mistake. | Use absolute worktree paths in every command. BattleShip put this in its CLAUDE.md. |
Problems other projects hit
The build needs a decompressed ROM, but players load the normal ROM. People mix the two up.
Fix: Name each file clearly. Check the build ROM and the play ROM by their own SHA-1.
Seen in: Zelda 64: Recompiled, Banjo: Recompiled, Donkey Kong 64: Recompiled
A libultra function was not named, so the original code read a hardware register and crashed.
Fix: Name every library function before first light. Check n64sym hits by hand.
Seen in: WinBack Recompiled, Marchwind64
The game hung because a loop waited on memory that another thread writes. The runtime only switches threads inside libultra calls.
Fix: Add a hook that yields at the top of the loop, or rewrite that function as a patch.
Seen in: WinBack Recompiled
Several overlays load at the same RAM address, so one address can mean many functions.
Fix: Name functions by ROM segment plus address. Use runtime lookups for calls between overlays.
Seen in: Marchwind64, BattleShip Remix
GCC tail merging made jump-table cases land in code split off elsewhere. The build stopped with a switch-case error.
Fix: Teach the symbol script about shared tails, and name the odd functions by hand.
Seen in: WinBack Recompiled
On a 64-bit PC, N64 types declared as long doubled in size and broke every 3D transform.
Fix: Make those types 32-bit, and grep for long in decomp headers before the port.
Seen in: BattleShip
Big-endian data read through small struct fields came out flipped on PC.
Fix: Byte-swap at load time, then add small per-struct fixes. Write a lint for the whole bug class.
Seen in: Project Midas, BattleShip
RT64 had gaps for some games, like a missing line command. Upstream will not take AI-written fixes.
Fix: Keep renderer fixes as numbered local patch files with a reason each.
Seen in: WinBack Recompiled
Cloning without submodules left libultraship and Torch empty, and the build failed.
Fix: Clone with --recursive, or run git submodule update --init --recursive.
Seen in: Ship of Harkinian, Starship, SpaghettiKart
How long it takes
| Max 20x (now called Ultra) | Max 5x (now called Max) | One person, no AI | How sure | |
|---|---|---|---|---|
| Path A: running on PC | 6 to 16 weeks | 3 to 9 months | 6 to 18 months | medium confidence |
| Path B: full decomp | 6 to 17 months | 1 to 3 years | 3 to 6 years | low confidence |
Read this first
These ranges assume one medium-sized game and one person giving 10 to 15 hours a week. No project reports its hours, and the fast ones worked much more: BattleShip's author called it night and day work. The AI recomp numbers come from two dated projects, and their private work before the first commit is not known. The decomp numbers come from one expert with a ready harness, expert helpers and borrowed usage; a newcomer will likely be slower. Treat every range as a rough guide, not a promise.
What makes it faster or slower
- Whether a decomp already exists. It gives names for a recomp and source for a port.
- Compression and overlays. Each overlay must be found and listed by hand.
- The compiler. IDO games have a hard tail of register quirks that needs experts.
- Game size. Snowboard Kids had 2,145 functions; big games have several times more.
- Whether you build scripted golden runs early. Without them, every check needs you at the controller.
- Your usage limit. The Snowboard Kids author borrowed usage from three other people. He also wrote that one unattended task could use up a Max 20x plan in days.
The facts behind these numbers
| Project | What happened | Link |
|---|---|---|
| Marchwind64 (Super Robot Wars 64) | Recomp with no decomp. First commit 2026-08-02; stage 1 cleared natively by 2026-09-08; first release 2026-10-07. 3 contributors, AI used for debugging. | source |
| WinBack Recompiled | One person. Repo and first release 2026-11-01; mission 1 playable by v0.3. The author says Claude Code did most of the work. | source |
| BattleShip (Super Smash Bros.) | Port of a 96% decomp, one person with Claude. First commit 2026-04-04, first beta 2026-05-01. | source |
| Snowboard Kids decomp | 2,145 functions, IDO 5.3. Matched in 84 days (repo 2026-05-28 to 2026-08-19) with agents from day one, by an author with nearly two years of practice. About 4.8% of matching commits had expert help. | source |
| Snowboard Kids 2 decomp | 2,995 functions, GCC 2.7.2. First commit 2024-09-28, last match 2026-05-17: 596 days. A headless agent loop took it from about 25% to 58% fast. It then stalled near 75% for months before it reached 100%. | source |
| Banjo: Recompiled | No AI. First commit 2025-02-17, first release 2026-01-24, 13 contributors who already owned the tools. | source |
| Zelda 64: Recompiled | No AI. First commit 2023-02-19, first release 2024-05-10, 23 contributors. The recompiler itself was started three months earlier, on 2022-11-16. | source |
Projects reviewed (15)
We took the top project for each of the top 12 games on RecompLauncher. We added the three whose makers say they used AI. None of the 15 is a matching decomp. So Path B also uses the Snowboard Kids and Ocarina of Time decomps.
What each project teaches
Zelda 64: Recompiled
The Legend of Zelda: Majora's Mask
Started: 2023-02. First release: 2024-05. Code: C and C++.
AI: none stated; the team bans AI-written code
Lesson: Keep the recompiler inputs as small text configs. Write game changes as C patches that go through the same recompiler.
Ship of Harkinian
The Legend of Zelda: Ocarina of Time
Started: 2022-03. First release: 2023-08. Code: C and C++.
AI: none stated; catalog flag set by the store
Lesson: Split the port into game code, a reusable libultra stand-in and port-only code. Never ship assets; pull them from the player's ROM.
SpaghettiKart
Mario Kart 64
Started: 2020-10. First release: 2025-11. Code: C and C++.
AI: none stated; catalog flag set by the store
Lesson: Tell users the one ROM, region and byte order they need up front, and pin the extractor as a submodule.
Starship
Star Fox 64
Started: 2023-09. First release: 2024-12. Code: C.
AI: none stated
Lesson: Finish the decomp first, then add a separate port folder. Asset extraction runs as a build target.
Banjo: Recompiled
Banjo-Kazooie
Started: 2025-02. First release: 2026-01. Code: C and C++.
AI: none stated; the team bans AI-written code
Lesson: Its thin layout is a good template, but its team asks that AI not be used on it, so study it yourself. A ROM plus a symbols TOML is enough; no ELF is needed.
Perfect Dark Port
Perfect Dark
Started: 2019-09. First release: 2024-05. Code: C.
AI: none stated
Lesson: Fork the decomp and add a port folder. Reuse a renderer and audio mixer from other ports instead of writing new ones.
Super Mario 64 Co-op DX
Super Mario 64 [Co-op DX]
Started: 2019-08. First release: 2024-07. Code: C.
AI: none stated
Lesson: A finished port can carry years of new work. Build without a ROM so public CI can check every platform.
Ghostship
Super Mario 64
Started: 2019-08. First release: 2026-01. Code: C and C++.
AI: none stated
Lesson: Key every supported ROM by SHA-1 and refuse unknown dumps with a clear message.
Donkey Kong 64: Recompiled
Donkey Kong 64
Started: 2025-02. First release: 2026-08. Code: C and C++.
AI: none stated
Lesson: You can start a recomp by copying another one. Hook the game's overlay loader instead of rewriting it.
PaperBoat
Paper Mario
Started: 2019-03. First release: 2026-09. Code: C.
AI: none stated for its own code; the README accepts disclosed AI-assisted pull requests under the Harbour Masters policy
Lesson: On Windows, build C99 decomp code with clang-cl, not plain MSVC, to avoid big edits to decomp files.
BattleShip
Super Smash Bros.
Started: 2026-04. First release: 2026-05. Code: C and C++.
AI: yes: the author built it alone with Claude up to v0.3-beta Agent files: CLAUDE.md.
Lesson: Diff display-list traces against an emulator so Claude works from data. Give each parallel session its own worktree.
Project Midas
GoldenEye 007
Started: 2026-10. First release: 2026-10. Code: C.
AI: yes: README says Claude was used in making it
Lesson: Start a port with a compile sweep that groups errors by type. When you find a bug class, write a lint for all of it.
Marchwind64
Super Robot Wars 64
Started: 2026-08. First release: 2026-10. Code: C++ and Python.
AI: yes: Claude Code drives the game through an MCP debug server; machine translation and AI art Agent files: .mcp.json, web/public/docs/mini-stage/llms.txt.
Lesson: With no decomp, recover the layout yourself and prove the pipeline on one small function first. An MCP debug server lets Claude test alone.
WinBack Recompiled
WinBack: Covert Operations
Started: 2026-11. First release: 2026-11. Code: C++.
AI: yes: the author says Claude Code wrote most of the code and docs Agent files: CLAUDE.md.
Lesson: A full recomp pipeline works with no decomp: splat, then n64sym, then N64Recomp. Scripted input lets Claude check its own fixes.
BattleShip Remix
Smash Remix
Started: 2026-04. First release: 2026-11. Code: C and C++.
AI: yes: the developer says Claude helped write the port code Agent files: AGENTS.md, .claude/skills/remix-smoke-tests/SKILL.md.
Lesson: A skill that runs the real game headless gives every task an in-game test. Audit completeness with a script, not by memory.
What we could not check
- The time ranges are estimates from a few projects. No project reports hours per week.
- How much private work came before the first public commit of WinBack Recompiled and Project Midas is unknown.
- The
N64RecompREADME still says an ELF file is required and that hooks are not built yet. Its config source readssymbols_file_pathand hooks, and Banjo, Donkey Kong 64 and Marchwind64 use them. We did not run it ourselves. - We did not test whether
ido-static-recomp's Windows build works with N64 decomp Makefiles on plain Windows. The projects we read use Linux or WSL. - The
N64Recompbuild commands come from WinBack'stools/fetch_deps.sh. We did not run them. splaton plain Windows: its Quickstart assumes Ubuntu, WSL2 or Docker. WinBack runs it on Windows. We did not test it.- Whether Visual Studio puts Ninja on your path was not confirmed. The Visual Studio download page was opened, but only the Microsoft Learn pages were read for part names.
- The
decomp-permutercommand line was read from its README andimport.py, not run. - None of the commands, scripts or prompts in this guide were run end to end on a real game here. They come from project files and tool docs.
- The skills.sh skills listed here were not run on an N64 project.
- Whether the Pilotwings 64 team used AI is not stated.
- Whether a Claude Code rule against recreating existing games affects decomp or recomp work is not known.
Sources
- N64Recomp README
- N64Recomp CONTRIBUTING.md (AI policy)
- N64ModernRuntime README
- RT64 README
- splat README
- splat wiki Quickstart
- n64sym README
- ares README and releases
- ido-static-recomp README
- mips-gcc-2.7.2
- asm-processor README
- m2c README
- asm-differ README
- objdiff README
- decomp-permuter README
- libultraship README
- Torch README
- ultralib README
- Ocarina of Time decomp README (WSL advice)
- Snowboard Kids decomp README
- Snowboard Kids 2 decomp README
- Chris Lewis: Decompiling a Nintendo 64 Game in 84 Days
- Chris Lewis: The Long Tail of LLM-Assisted Decompilation
- N64brew wiki: ROM Header
- N64brew wiki: Libultra
- N64brew wiki: Main Page (hardware index)
- Marchwind64 debug interface guide
- WinBack Recompiled development notes
- WinBack Recompiled tools/fetch_deps.sh (N64Recomp build commands)
- N64Recomp config parser (src/config.cpp)
- RT64 CONTRIBUTING.md (AI policy)
- Harbour Masters AI policy
- Starship BUILDING.md (Windows port build)
- libultraship porting guide
- z64decompress README
- Microsoft Learn: CMake projects in Visual Studio
- Microsoft Learn: Clang/LLVM support in Visual Studio CMake projects
- Microsoft Learn: Install WSL
- Chris Lewis: Using Coding Agents to Decompile Nintendo 64 Games
- Claude Code docs: run Claude Code programmatically (claude -p)
- Claude Code docs: hooks
- RecompLauncher
- Python downloads