Nintendo GameCube decomp guide
Strong tools, many finished decomps, and a fast path to a running game.
What this system is like
The GameCube is one of the best systems for this hobby. Every game uses the same chip, the same compiler family and the same Nintendo code library. That library is called the SDK, short for software kit. Tools know it well, so they can name much of the code for you.
There are two proven ways to get a game running on PC. If someone already finished a decomp of your game, you port it. You compile its C code for PC and let Aurora draw the pictures. If no decomp exists, you recompile. DolRecomp or gcn-recomp turns the game's machine code into C, and a runtime stands in for the console.
A full decomp is slower but very doable. The decomp-toolkit tools run on plain Windows, with no WSL. Melee, Animal Crossing, Mario Party 4, Pikmin and Star Fox Adventures reached 100%. Twilight Princess matches fully, but not every unit is linked yet. Agents helped finish Melee and Star Fox Adventures in 2026.
The hard parts are speed and the last few percent. Recompiled code can run too slow in busy scenes. The last functions of a decomp can take as long as the first half.
One main file, plus modules
Game code lives in main.dol. Many games add .rel modules that load later. Wind Waker has 415 of them. Your tools must handle both, or you miss part of the game.
Every game shares one SDK
All games link the same Nintendo library. dtk spots its functions by their bytes. Recomps replace those functions by name instead of converting them. A finished decomp of one game teaches you a lot about the next.
Big-endian and 32-bit
The console stores numbers high byte first. It also uses 4-byte pointers. A PC uses the opposite byte order and 8-byte pointers. Ports must fix both, or data from the disc reads wrong.
The tools run on Windows
The dtk-template docs say to use native Windows tools. They say WSL is not needed. That is rare among consoles, and it saves you setup time.
Many decomps are already done
Full or near-full decomps exist for Melee, Twilight Princess, Animal Crossing, Mario Party 4, Pikmin and Star Fox Adventures. Check before you start. Porting a finished decomp is the fastest route there is.
Speed is the recomp wall
Two reviewed recomps ran too slow in busy scenes. Both fell back to Dolphin's built-in CPU translator. Plan time for profiling from the start.
Two paths
Get it running on PC
First check if a decomp of your game exists. If it does, port it with Path B's last steps. If not, a recompiler turns main.dol and its .rel modules into C. A runtime stands in for the console: graphics, sound, discs and saves. You fix one crash at a time with a scripted test run until the game plays.
Full decomp for porting
You write C and C++ that the original CodeWarrior compiler turns back into the same bytes. decomp-toolkit splits the game into pieces, and objdiff scores each function. When every piece matches, the rebuilt main.dol has the same hash as yours. Then you port it: compile the code for PC and let Aurora stand in for the console.
Path A: Get it running on PC
First check if a decomp of your game exists. If it does, port it with Path B's last steps. If not, a recompiler turns main.dol and its .rel modules into C. A runtime stands in for the console: graphics, sound, discs and saves. You fix one crash at a time with a scripted test run until the game plays.
Method: static recompilation
Pick this when no decomp of your game exists and you want to play soon. It does not give you readable source code.
Scope the game and look for prior work
You pin the exact disc you own. You look for an existing decomp or symbol file. Then you write a one-page plan that the owner signs off.
- Check your dump:
dtk disc verify game.isoornodtool verify game.iso. Both compare it with the Redump list. - Read the disc ID and the DOL:
dtk disc info game.isoanddtk dol info 'game.iso:sys/main.dol'. - Copy the DOL to a work folder outside the repo:
dtk vfs cp 'game.iso:sys/main.dol' <WORK_DIR>. Hash it withdtk shasum <WORK_DIR>/main.doland write the hash down. - Search GitHub and
decomp.devfor a decomp of your game. Even a partial one gives yousymbols.txt, a list of function names and addresses. - List the disc with
dtk vfs ls -r -s 'game.iso:'and count the.relfiles. Some games pack them in.arcarchives. List those too, such asdtk vfs ls 'game.iso:files/RELS.arc:'. - Look for middleware names in strings, such as CRI or THP video.
- Write
SCOPE.md: game, disc ID, DOL hash, technique, first milestone, what is out of scope.
Prompt for ClaudeGOAL: Draft `SCOPE.md` for a GameCube recomp of <GAME>, disc <DISC_ID>. READ FIRST: `notes/disc-info.txt` (output of `dtk disc info` and `dtk dol info`), the GitHub search results I pasted in `notes/prior-work.md`. FENCE: Edit only `SCOPE.md` and `notes/prior-work.md`. Do not build or download anything. CHECK: Run `dtk shasum <WORK_DIR>/main.dol` and compare it with the hash in `SCOPE.md`. Done means they agree, and `SCOPE.md` names the disc ID, the number of `.rel` files, any decomp or `symbols.txt` found, the chosen recompiler (`DolRecomp` or `gcn-recomp`) and the first milestone with its check. BUDGET: Stop after 30 minutes of reading. IF BLOCKED: Stop. Tell me which fact you could not confirm and where you looked. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) The draft. 3) Files changed. 4) Open questions for me. 5) New parking-lot items.
Done whenSCOPE.mdlists the disc ID, the DOL hash, the module count, prior work and the first milestone, and you approved it.Proof this works: Luigi's Mansion Recomp, Eternal Darkness Recomp, Spongebob Squarepants: Revenge of the Flying Dutchman, https://github.com/encounter/decomp-toolkit
- Check your dump:
Set up the repo, tools and one check
You make a repo that holds only your own code. The disc and all generated C stay outside it. You add one command that builds and one that runs a check.
- Route 1,
DolRecompwithModernGekko(in WSL): make a repo fromModernGekko-Template, thengit clone --recurse-submodules <your-repo>. - Install the WSL packages the template lists, starting with
sudo apt-get install -y ninja-build build-essential pkg-config cmake. Then runmake check. - Use WSL for Route 1. The
DolRecompREADME saysModernGekkodoes not build with MSVC yet. - Route 2,
gcn-recomp(Windows or WSL): add it as a submodule and callgcn_add_game()with your disc ID and DOL hash. Build withcmake -S . -B build -G Ninjaandninja -C build. - Pin every upstream tool to one commit. Keep your fixes as numbered patch files that a script applies.
- Put
iso/,extracted/,generated/andbuild/in.gitignore. - Write
CLAUDE.md,PROGRESS.mdandnotes/parking-lot.md.
Prompt for ClaudeGOAL: Make the repo build the recompiler and runtime with one command, and add `tools/check.sh` that runs the current check. READ FIRST: `SCOPE.md`, the `ModernGekko-Template` README (or `gcn-recomp` README), `CLAUDE.md`. FENCE: Edit only `Makefile`, `CMakeLists.txt`, `tools/`, `.gitignore`, `PROGRESS.md`. Do not touch `lib/` submodules. Do not add features. CHECK: Run `make check` (or `cmake -S . -B build -G Ninja && ninja -C build`). Done means it exits 0, and `git status` shows no disc or generated files. BUDGET: Stop after 3 failed tries at the same error. IF BLOCKED: Stop. Do not work around it. Paste the error and tell me 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 the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenmake check(or the CMake build) exits 0 on a clean clone, andgit statuslists no game files.Proof this works: F-ZERO GLINUX, Eternal Darkness Recomp, Naruto: Clash of Ninja Collection, https://github.com/ExpansionPak/ModernGekko-Template
- Route 1,
Map the code
You list every function with its address and size. You mark SDK code so nobody converts it by hand. You also note anything that will need runtime work.
- Get function edges:
dtk dol config main.dol -o config/<ID>/config.yml, addsymbols:andsplits:paths, thendtk dol split config/<ID>/config.yml build/<ID>. - If a decomp exists, take its
symbols.txtinstead. It names every function. - Find
OSSaveContext,OSLoadContext,OSReportandOSPanic.dtkmay leave some asfn_names, so check them by hand. - Run the recompiler once and save its list of possible self-modifying code. That means code that rewrites itself.
- Save the map to
notes/functions.csvwith columns: address, size, name, kind (game or SDK), status. - Have Claude write
tools/check_map.pyfirst. It compares the CSV withsymbols.txtand with the section sizes fromdtk dol info.
Prompt for ClaudeGOAL: Produce `notes/functions.csv` for <DISC_ID>: every function with address, size, name, kind (game or SDK) and status. READ FIRST: `SCOPE.md`, `config/<DISC_ID>/symbols.txt`, the self-modifying code report at `<PATH>`. FENCE: Edit only `notes/functions.csv`, `notes/map.md` and `config/<DISC_ID>/`. Do not edit generated C. CHECK: Run `python tools/check_map.py`. Done means every address in `symbols.txt` is in the CSV, sizes add up to the code section sizes from `dtk dol info`, and the five OS functions named in `notes/map.md` are present. BUDGET: Stop after 2 hours or 3 failed check runs. IF BLOCKED: Stop. List the functions you could not place 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 check output. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whennotes/functions.csvcovers every function, its sizes match the section sizes, and the OS functions are named.Proof this works: Naruto: Clash of Ninja Collection, Luigi's Mansion Recomp, Spongebob Squarepants: Revenge of the Flying Dutchman
- Get function edges:
Boot to the first frame
You recompile the whole game and run it with no person at the keys. The goal is one picture on screen and a clean exit. This is the smallest proof that the pipeline works.
- Route 1:
make run ISO=/path/to/game.iso. For a run with no window, addRUN_ARGS="--headless --graphics Null". - Or call the recompiler by hand:
./dolrecomp --gamecube extracted/sys/main.dol build. - Route 2: build, then run the headless bench, for example
./build/<game>_bench --seconds=20. - Make a crash end with a non-zero exit code, so a script can read it.
- Write the first golden run into
tools/check.sh: boot, wait a set time, check the exit code and one log line.
Prompt for ClaudeGOAL: Make the recompiled game boot headless for 20 seconds and exit cleanly. READ FIRST: `SCOPE.md`, `notes/map.md`, `PROGRESS.md`, the last run log at `<LOG_PATH>`. FENCE: Edit only runtime and host code under `<RUNTIME_DIR>/` and `tools/`. Never edit files under `build/` or `generated/`. If the generated C is wrong, describe the recompiler fix instead. CHECK: Run `tools/check.sh boot`. Done means exit code 0 and the log shows `<FIRST_LOG_LINE>`. BUDGET: Stop after 4 failed fixes or 90 minutes without progress. IF BLOCKED: Stop. Paste the last 40 log lines and say which layer failed: recompiler, runtime, SDK stand-in or disc reads. 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 whentools/check.sh bootexits 0 and the log shows the first frame line within 20 seconds.Proof this works: F-ZERO GLINUX, Naruto: Clash of Ninja Collection, https://github.com/ExpansionPak/DolRecomp
- Route 1:
Stand in for the SDK at its edges
You replace a few Nintendo OS functions with runtime code. Thread switching, the idle loop and error reports are the usual ones. You also make disc reads and audio take real time, as on the console.
- With
gcn-recomp, fillrecomp/hle.txt(OSSaveContext,OSLoadContext,OSReport,OSPanic,OSResetSystem),recomp/idle.txtandrecomp/special_calls.txt. - Put the address of
OSSaveContextitself inspecial_calls.txt, not the call site. - Point
idle.txtat the backward branch of the idle spin insideSelectThread. - Make disc reads take time and make the audio interrupt tick evenly. Instant reads broke boot in Luigi's Mansion.
- Report the console region the disc names. A PAL disc panics if the runtime says NTSC.
- Add a frame-keyed input script now, such as
GCN_INPUT="frame:BUTTON:duration". Then a script can press Start with no person. - On the
ModernGekkoroute, the Dolphin-based runtime already stands in for the SDK. Use this step only for the bugs it misses.
Prompt for ClaudeGOAL: Get <GAME> from boot to the title screen by fixing the SDK stand-in, one function at a time. READ FIRST: `notes/map.md`, `recomp/hle.txt`, `recomp/idle.txt`, `recomp/special_calls.txt`, the failing log at `<LOG_PATH>`. FENCE: Edit only `recomp/*.txt` and `<RUNTIME_DIR>/hle_*`. Do not put game addresses or game names in shared runtime code. They go in the game's tables. CHECK: Run `tools/check.sh title`. Done means the scripted input `<INPUT_SCRIPT>` reaches the title screen and the log line `<TITLE_LOG_LINE>` appears. BUDGET: Stop after 3 failed tries on the same function. IF BLOCKED: Stop. Name the SDK function, the guest address and the fault text. 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 whentools/check.sh titlereaches the title screen with scripted input and no person.Proof this works: Naruto: Clash of Ninja Collection, Luigi's Mansion Recomp, https://github.com/ethannicholas/gcn-recomp
- With
Grind: one crash or bug per session
You build a repeatable test run first. Then each session fixes one crash, one missing call or one drawing bug. A per-frame hash tells you if a fix changed anything else.
- Use the input script from the last step for every route. Luigi's Mansion reads the same kind of script with
--input <file>. - Add a per-frame hash of guest memory, or a frame dump by frame number. Ring Out compared 7,000 frames this way.
- Keep a list of routes: menu, first level, a busy scene. Run them all after each fix.
- Fix bugs in the recompiler or runtime. Save recompiler fixes as patch files. Never hand-edit the generated C.
- Log every finding and dead end in
notes/findings.md.
Prompt for ClaudeGOAL: Fix one bug: <BUG_DESCRIPTION>, seen on route <ROUTE> at frame <FRAME>. READ FIRST: `PROGRESS.md`, `notes/findings.md`, the run log `<LOG_PATH>`, the frame dump `<DUMP_PATH>`. FENCE: Edit only `<RUNTIME_DIR>/` and `patches/`. Never edit `build/` or `generated/`. No new features. CHECK: Run `tools/check.sh routes`. Done means route <ROUTE> passes and every other route keeps the same frame hashes as before. BUDGET: Stop after 3 failed fixes. Prove the cause before each fix. IF BLOCKED: Stop. Show the evidence you have and what you need to see next. 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 whentools/check.sh routespasses for every route and the hashes of untouched routes did not change.Proof this works: Ring Out, Luigi's Mansion Recomp, BlueWake
- Use the input script from the last step for every route. Luigi's Mansion reads the same kind of script with
Make it fast enough
Recompiled code can be slow in busy scenes. You measure first, from a fixed save state and a fixed route. You compare with Dolphin running the same game, so you know if the slowdown is yours.
- Pick one busy scene and one save state. Measure frames per second and CPU cycles there.
- Have Claude write
tools/bench.sh. It loads the save state, runs a fixed number of frames, and prints frames per second and the frame hash. - Run the same scene in Dolphin. If Dolphin shows the same bug or slowdown, it is not a recompiler bug.
- Profile. Fix hot spots in the generator, such as cache instructions handled inline.
- Try profile-guided builds:
llvm-profdatawith the sameclangthat builds the game. - Keep a table of ideas you measured and dropped, so no session tries them again.
Prompt for ClaudeGOAL: Raise frame rate in <SCENE> from <CURRENT_FPS> to <TARGET_FPS> without changing game behaviour. READ FIRST: `notes/perf.md` (measured and rejected ideas), the profile at `<PROFILE_PATH>`, `tools/bench.sh`. FENCE: Edit only the recompiler patch files in `patches/` and `<RUNTIME_DIR>/`. Do not change game timing or skip frames. CHECK: Run `tools/bench.sh <SCENE>` three times. Done means the median meets <TARGET_FPS> and the frame hash column matches the old build. BUDGET: Stop after 3 ideas that do not help. Log each in `notes/perf.md`. IF BLOCKED: Stop. Report the hottest functions and your next idea. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the bench output. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whentools/bench.shmeets the target in the chosen scene with the same frame hashes as before.Proof this works: Spongebob Squarepants: Revenge of the Flying Dutchman, Ring Out, BlueWake, F-ZERO GLINUX
Harden and package
You make old fixes stay fixed. You make the program check the user's disc. You prove that nothing from the game ends up in your repo or your release.
- Check the disc ID and the SHA-1 of
main.dolbefore you build. Also check each disc file by size and CRC-32. - Add a script that fails if any disc-derived file is staged or packed, like
tools/check_publish.py. - Run every route from a clean clone with a scratch save folder, never your real saves.
- Build Linux packages in an older container, so they run on older systems.
- Write down what you tested and on which device.
Prompt for ClaudeGOAL: Make the full check pass on a clean clone, including the disc check and the publish check. READ FIRST: `PROGRESS.md`, `tools/check.sh`, `tools/check_publish.py`. FENCE: Edit only `tools/` and `packaging/`. Do not change runtime behaviour. CHECK: In a fresh clone, run `tools/check.sh all`. Done means all routes pass, a wrong disc is rejected, and `tools/check_publish.py` finds no game data. BUDGET: Stop after 3 failed runs on the same step. IF BLOCKED: Stop. Name the failing step and paste its output. 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 whentools/check.sh allpasses on a clean clone, rejects a wrong disc, and the publish check finds no game data.Proof this works: Luigi's Mansion Recomp, Naruto: Clash of Ninja Collection, BlueWake
- Check the disc ID and the SHA-1 of
Path B: Full decomp for porting
You write C and C++ that the original CodeWarrior compiler turns back into the same bytes. decomp-toolkit splits the game into pieces, and objdiff scores each function. When every piece matches, the rebuilt main.dol has the same hash as yours. Then you port it: compile the code for PC and let Aurora stand in for the console.
Method: matching decompilation
Pick this when you want real source code that can go to other systems. It takes many months. First check that nobody has already done it.
Scope: find prior work and the compiler
Many GameCube decomps exist, some complete. You check for one first. If none fits, you pick the version, find hints about the compiler and write the plan.
- Search GitHub and
decomp.devfor your game. Several games are already at 100%. - Look for sister games on the same engine. Wind Waker and Twilight Princess share engine code.
- Look on the disc for
.mapfiles or a debug build:dtk vfs ls -r -s 'game.iso:'. A map file fills in names for free. - Note the project rules of any decomp you build on.
zeldaret/twwcloses pull requests that are mainly AI-made, so keep your AI work in your own fork. - Write
SCOPE.md: game ID and revision, DOL and REL hashes, likely compiler version, milestones.
Prompt for ClaudeGOAL: Draft `SCOPE.md` for a matching decomp of <GAME> (<GAME_ID>, revision <REV>). READ FIRST: `notes/prior-work.md`, `notes/disc-info.txt`, the dtk-template docs `docs/getting_started.md`. FENCE: Edit only `SCOPE.md` and `notes/prior-work.md`. Do not set up the repo yet. CHECK: Run `dtk disc verify <DISC_PATH>` and paste the result. Done means the disc matches Redump, and `SCOPE.md` names the game ID, the SHA-1 of `main.dol` and each `.rel`, any map or debug files found, related decomps, their AI rules, and the first matching milestone. BUDGET: Stop after 45 minutes of reading. IF BLOCKED: Stop. Tell me what you could not confirm. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) The draft. 3) Files changed. 4) Open questions. 5) New parking-lot items.
Done whenSCOPE.mdlists the hashes, prior work, the compiler guess and the first milestone, and you approved it.Proof this works: https://github.com/zeldaret/tww, https://github.com/zeldaret/tp, Dusklight
- Search GitHub and
Set up dtk-template on Windows
You make the project from
dtk-template. It needs only Python and Ninja on Windows. It downloads the right compilers,dtkandobjdiff-cliby itself, intobuild/tools/.- Create a repo from
dtk-templateand clone it. - Install Python, then install Ninja with
pip install ninja. - Rename
orig/GAMEIDandconfig/GAMEIDto your game ID. Put your disc image, or the files Dolphin extracts, inorig/<GAMEID>. They stay out of git. - The hash command reads loose files. If you used a disc image, extract it to a folder outside the repo first. Use Dolphin's Extract Entire Disc, or
dtk disc extract <DISC_FILE> <OUT_DIR>. Point the paths below at that folder. - Make the hash file:
dtk shasum orig/<GAMEID>/sys/main.dol orig/<GAMEID>/files/*.rel -o config/<GAMEID>/build.sha1. Then edit its paths to point atbuild/instead oforig/. - Add your game ID to
VERSIONSinconfigure.py. Runpython configure.py, thenninja. - Add a hook that blocks edits to
build.sha1andorig/.
Prompt for ClaudeGOAL: Make `python configure.py` and `ninja` run the first analysis for <GAMEID>. READ FIRST: `SCOPE.md`, `docs/getting_started.md`, `config/<GAMEID>/config.example.yml`. FENCE: Edit only `configure.py` (the `VERSIONS` list and settings), `config/<GAMEID>/config.yml` and `.claude/settings.json`. Never edit `config/<GAMEID>/build.sha1` after it is made. Never touch `orig/`. CHECK: Run `python configure.py` then `ninja`. Done means `config/<GAMEID>/symbols.txt` and `splits.txt` exist. BUDGET: Stop after 3 failed tries at the same error. IF BLOCKED: Stop. Paste the error and the config section it points to. 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 whenninjafinishes the first analysis and writessymbols.txtandsplits.txt.Proof this works: https://github.com/encounter/dtk-template, https://github.com/zeldaret/tww, Animal Crossing PC Port (now named Nookery)
- Create a repo from
Map the binary and split it into units
You fix the split points so each unit matches one original source file. You mark SDK and library code. The ledger is the progress report that the build writes.
- Fix split points in
splits.txtand names insymbols.txt. Wrong edges make a function impossible to match. - Set up
__init_cpp_exceptions.cppas the dtk-template docs describe, if the game uses C++. - Put SDK,
MSL_C, Runtime and JSystem units in their own progress category, such assdk. - Borrow names from decomps of sister games that link the same libraries.
- Read progress from
build/<GAMEID>/report.json. Save a baseline withninja baseline.
Prompt for ClaudeGOAL: Clean up the splits for <AREA> so each unit is one original file, and label SDK units. READ FIRST: `config/<GAMEID>/splits.txt`, `config/<GAMEID>/symbols.txt`, `notes/sdk-units.md`. FENCE: Edit only `splits.txt`, `symbols.txt`, `configure.py` object lists and `notes/`. Do not write C yet. CHECK: Run `ninja`. Done means the `build.sha1` check still passes and `build/<GAMEID>/report.json` lists the new units. BUDGET: Stop after 3 failed builds. IF BLOCKED: Stop. Show the dtk error and the address range. 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 whenninjastill passes the hash check andreport.jsonlists every unit with a category.Proof this works: https://github.com/encounter/dtk-template, Ring Out, Eternal Darkness Recomp
- Fix split points in
Match one small unit end to end
You prove the whole loop on one small file. You write its C, mark it as matching, and the full build still gives the same bytes.
- Pick a small unit with few functions. SDK units are good first picks.
- Get a C draft with
m2cusing the PowerPC andmwcctargets. - Compare with
objdiff-cli diff -p . -u <unit> -o - <function>, or theobjdiffwindow. The template saves the CLI asbuild/tools/objdiff-cli.exe. Add that folder toPATHor call it by its full path. - When it is 100%, change its line in
configure.pytoObject(Matching, "<file>"). - Run
ninja. Thebuild.sha1check must pass with the unit linked.
Prompt for ClaudeGOAL: Match unit <UNIT> fully and link it. READ FIRST: `CLAUDE.md`, the unit's asm at `build/<GAMEID>/asm/<UNIT>.s`, matched units in `src/` that look similar. FENCE: Edit only `src/<UNIT>.c`, its header, and its one line in `configure.py`. No inline asm, no `#pragma` tricks. CHECK: Run `objdiff-cli diff -p . -u <UNIT> -o - <FUNCTION>` for each function, then `ninja`. Done means every function is 100% and the `build.sha1` check passes with `Object(Matching, ...)`. BUDGET: Stop after 5 real attempts per function. IF BLOCKED: Stop. Paste the best diff and say which instructions differ. 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 whenninjapasses thebuild.sha1check with the unit set toMatching.Proof this works: https://github.com/encounter/objdiff, https://github.com/doldecomp/melee/pull/2076, https://github.com/matt-kempster/m2c
Grind: one function per session
This is most of the work. A script picks the next easy function. A worker gets one function, five tries and a fresh chat. Matches are kept and failures are logged.
- Sort open functions by size. Do small ones first, then ones that look like matched code.
- Give each worker its own git worktree, a separate copy of the project folder.
- Each worker runs
m2c, edits C, and checks withobjdiff-cli diff. - Commit each verified match. Reset on failure and log what was tried.
- Run
ninja changesbefore each merge. It lists any function that got worse.
Prompt for ClaudeGOAL: Match function <FUNCTION> in unit <UNIT> to 100%. READ FIRST: `CLAUDE.md`, `notes/compiler-quirks.md`, the asm for <FUNCTION>, up to three similar matched functions: <LIST>. FENCE: Edit only `src/<UNIT>.c` and `include/<UNIT>.h`. Do not edit `configure.py`, `config/`, `build.sha1` or other units. No inline asm. CHECK: Run `objdiff-cli diff -p . -u <UNIT> -o - <FUNCTION>`, then `ninja` and `ninja changes`. Done means 100%, the hash check passes and no other function got worse. BUDGET: Stop after 5 real attempts. Each attempt must differ from the last. IF BLOCKED: Stop. Log the best score and the differing instructions in `notes/attempts/<FUNCTION>.md`. 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 whenobjdiff-clishows 100%,ninjapasses the hash check andninja changesshows no losses.Proof this works: https://github.com/doldecomp/melee/pull/2076, https://github.com/zcanann/SFA-Decomp, https://github.com/lukechampine/melee-harness
Crack the hard tail
Some functions stall at 95 to 99%. You send these to a stronger job type with more context. You do not accept 'impossible' without proof.
- Ask why it fails first. Is it register choice, order, a missing inline or wrong types?
- Search matched code for the same instruction pattern. Star Fox Adventures found 'impossible' shapes already matched elsewhere.
- Try
decomp-permuterin WSL on near misses. Addpermuter_settings.tomlwithbuild_system = "ninja"at the project root first, soimport.pyreadsbuild.ninja. Treat its output as a hint, not an answer. - Keep a shared
notes/compiler-quirks.mdwith general CodeWarrior lessons only. - If clean C cannot match, leave the unit
NonMatching. A clean 90% beats a hacked 100%.
Prompt for ClaudeGOAL: Find why <FUNCTION> stops at <SCORE>% and match it with clean C, or prove what blocks it. READ FIRST: `notes/attempts/<FUNCTION>.md`, `notes/compiler-quirks.md`, the current diff from `objdiff-cli diff -p . -u <UNIT> -o - <FUNCTION>`. FENCE: Edit only `src/<UNIT>.c`, `include/<UNIT>.h` and `notes/`. No inline asm, `asm("")` barriers, `#pragma` sandwiches or fake `volatile`. CHECK: `objdiff-cli` shows 100%, `ninja` passes the hash check and `ninja changes` shows no losses. BUDGET: Stop after 6 attempts or 2 hours. IF BLOCKED: Stop. Name the exact differing instructions and a cause you can test. 'Compiler artifact' is not a cause. 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 function is 100% with clean C, ornotes/attempts/names the exact blocker and the unit staysNonMatching.Proof this works: https://jpb.dev/blog/teaching-a-model-to-decompile, https://github.com/simonlindholm/decomp-permuter, https://github.com/zcanann/SFA-Decomp
Verify and link everything
A fresh session with no memory of the work checks it. It reruns the build, reads the diffs and hunts for cheats. Then every unit gets linked.
- Start a new session and run
ninjafrom a clean clone. - Search the diff for
asm,#pragma, editedbuild.sha1and units markedMatchingthat are not 100%. - Check that no matched function lost its match after a merge.
- Link the last units until
report.jsonshows 100% linked.
Prompt for ClaudeGOAL: Check the last <N> merged matches for real results and cheating. READ FIRST: `git log --oneline -<N>`, `CLAUDE.md` rules, `build/<GAMEID>/report.json`. FENCE: Read only. Do not edit any file. Write findings to `notes/verify-<DATE>.md` only. CHECK: From a clean clone run `python configure.py` and `ninja`. Done means you report the hash check result and list every rule break found. BUDGET: Stop after 60 minutes. IF BLOCKED: Stop. Say what you could not check and why. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) PASS or FAIL. 2) Proof: paste the check output. 3) Each problem with file and line. 4) What you did not check. 5) New parking-lot items.
Done whenA fresh session reports PASS from a clean clone andreport.jsonshows 100% matched and linked.Proof this works: https://github.com/doldecomp/melee/pull/3409, https://github.com/doldecomp/melee/wiki/FAQ
- Start a new session and run
Port: build the code for PC on Aurora
You compile the decomp's code with a PC compiler.
Aurorastands in for graphics, input, disc and memory card. Your PC code lives in its own folder, and every change to game code is marked.- Add Aurora as a submodule in
extern/aurora. In CMake, calladd_subdirectory(extern/aurora EXCLUDE_FROM_ALL)and linkaurora::core,aurora::gx,aurora::mainandaurora::vi. Turn onAURORA_ENABLE_DVD, which is off by default, to read the disc image. - Put PC code in
pc/orsrc/platform/. Wrap changes to game code in#if TARGET_PCor mark them with// PORT:. - Add two switches now: a disc path option (Dusklight uses
--dvd <path>) and an exit-after-frames setting (melee-pc usesMELEE_EXIT_AFTER_FRAMES). The check below needs both. - Fix byte order. melee-pc marks disc structs with GCC's
scalar_storage_order("big-endian"). - Fix 8-byte pointers. Keep guest addresses below 4 GiB, or ship a 32-bit build too.
- Let a script write abort-on-call stubs for missing symbols, checked against an allow list.
Prompt for ClaudeGOAL: Make the PC build of <GAME> link and show the title screen from my disc image. READ FIRST: `SCOPE.md`, Aurora `docs/building.md`, `pc/README.md`, the link errors at `<LOG_PATH>`. FENCE: Edit only `pc/`, `CMakeLists.txt` and game files where a change is wrapped in `#if TARGET_PC` with a `// PORT:` note. Do not reformat game code. CHECK: Run `cmake --build build` then `build/<GAME> --dvd <DISC_PATH>` with `<EXIT_AFTER_FRAMES>`. Done means exit code 0 and the title log line appears. BUDGET: Stop after 4 failed fixes on one error. IF BLOCKED: Stop. Paste the error and say if it is byte order, pointer size, a missing SDK call or a link clash. 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 PC build links and reaches the title screen from the disc image in a scripted run.Proof this works: Dusklight, melee-pc, Strikers, Animal Crossing PC Port (now named Nookery), https://github.com/encounter/aurora
- Add Aurora as a submodule in
Port: test without a person and harden
You add switches that let a script run the game the same way each time. Then old fixes stay fixed. CI builds and tests with no disc at all.
- Add record and replay of input, a fixed random seed and a fixed time step.
- Add a boot-to-scene switch next to the exit-after-frames switch. Judge runs by exit code and log lines.
- Build the game code once with
-m32and size checks, to catch struct sizes that grew. - Label tests that need the disc, and leave them out of CI.
- Keep one status table that says what works and on which hardware.
Prompt for ClaudeGOAL: Add a smoke test that boots <SCENE>, runs <N> frames from a recorded input file, and fails on a crash or a missing log line. READ FIRST: `pc/`, `tests/`, `notes/findings.md`. FENCE: Edit only `pc/`, `tests/` and `tools/`. Do not change game logic. CHECK: Run `ctest --test-dir build --output-on-failure` and `tools/smoke_test.py`. Done means both pass, and breaking the scene on purpose makes the smoke test fail. BUDGET: Stop after 3 failed tries. IF BLOCKED: Stop. Say what the test cannot see 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 the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenctestand the smoke runs pass on a clean clone, and a broken build makes them fail.Proof this works: Strikers, melee-pc, Open Nectar
Tools you need
| Tool | What it does | How to get it | How we know |
|---|---|---|---|
| decomp-toolkit (dtk) Required both | Reads discs, DOLs and RELs. It finds function edges, names SDK code, and splits the game into objects for a matching build. Path A Path B | Download `dtk-windows-x86_64.exe` from the releases page (v1.8.4) and rename it `dtk.exe`. `dtk-template` downloads its own pinned copy (v1.8.3). | tool README, src/cmd/shasum.rs and releases (read 2026-11-13: v1.8.4, 2026-09-09); dtk-template configure.py pins v1.8.3; used by: Naruto: Clash of Ninja Collection, Luigi's Mansion Recomp |
| dtk-template Required both | A ready project layout for a GameCube matching decomp. One configure.py sets up the build, the compilers and the progress report.Path B | Create a repo from the template on GitHub, then `pip install ninja`. Python and Ninja are the only needs on Windows. | README, docs/getting_started.md, docs/dependencies.md, configure.py and tools/project.py (read 2026-11-13). The docs also cover Linux, where it downloads wibo to run the compilers. |
| objdiff and objdiff-cli Required both | Compares your compiled object with the original, function by function. The CLI gives a score Claude can read. Path B | `dtk-template` downloads `objdiff-cli` into `build/tools/` (pinned v3.6.1). For the window, download `objdiff-windows-x86_64.exe` from the releases page (v3.8.3). | README, releases (v3.8.3, 2026-10-19), objdiff-cli/src/cmd/diff.rs (-p, -u, -o, symbol; JSON output by default) and dtk-template tools/project.py (read 2026-11-13) |
| nodtool (nod) Helpful both | Reads GameCube disc images: ISO, RVZ, WIA, CISO, GCZ, WBFS and TGC. It can verify a dump against Redump, extract files, and convert .rvz to .iso.Path A Path B | Download `nodtool-windows-x86_64.exe` from the releases page (v2.0.0-alpha.12, a test release), or `cargo install --locked nodtool`. `dtk disc` commands wrap the same library. | README and releases (read 2026-11-13); used by: Naruto: Clash of Ninja Collection, BlueWake (Windows builder), Dusklight (links its releases) |
| DolRecomp Required both | Turns GameCube main.dol and .rel code into C. It flags code that may rewrite itself, for you to patch by hand.Path A | `git clone https://github.com/ExpansionPak/DolRecomp`, then `cmake -S . -B build` and `cmake --build build --config Release`. Needs CMake 3.16 or newer and a C11 compiler. | README (read 2026-11-13: Windows builds tested with MSVC and MinGW; SMC is reported, not fixed); used by: BlueWake, Eternal Darkness Recomp, Ring Out, F-ZERO GLINUX, Spongebob Squarepants: Revenge of the Flying Dutchman |
| ModernGekko-Template Helpful WSL/Linux | A starter repo that wires DolRecomp to the ModernGekko runtime, which is based on Dolphin. One make run goes from disc to a window.Path A | Use the template on GitHub, then `git clone --recurse-submodules <your-repo>` and `make check` in WSL. | README (read 2026-11-13); used by: F-ZERO GLINUX, Ring Out (ModernGekko fork) |
| gcn-recomp Helpful both | A recompiler and runtime in one. It draws through its own OpenGL GX code, not Aurora. Each game adds a symbol file and three small tables. Path A | Add it as a git submodule and call `gcn_add_game()` in your `CMakeLists.txt`. Needs CMake 3.20, Ninja, Python 3, a C++20 compiler and SDL2. On Windows the first configure builds SDL2 for you. | README (read 2026-11-13); used by: Naruto: Clash of Ninja Collection |
| Aurora Required both | Stands in for the GameCube's graphics, controller, disc and memory card code. It draws through Direct3D 12, Vulkan or Metal. Path A Path B | Add as a git submodule in `extern/aurora`, then `add_subdirectory(extern/aurora EXCLUDE_FROM_ALL)` in CMake 3.25 or newer. | README and docs/building.md (read 2026-11-13); used by: Dusklight, melee-pc, Strikers, Luigi's Mansion Recomp |
| Dolphin Required both | The GameCube emulator. Use it as the reference run, to convert discs with dolphin-tool, and as a debugger through its GDB stub.Path A Path B | Download the Windows build from the Dolphin site, dolphin-emu.org. | GitHub repo answers (2026-11-13); dolphin-emu.org refused scripted requests (403), so its download page was not read. GDB stub setting from the dolphin-debugger-mcp README. Used by: Spongebob Squarepants: Revenge of the Flying Dutchman, F-ZERO GLINUX (dolphin-tool) |
| m2c Helpful both | Turns PowerPC assembly into a first C draft. It knows CodeWarrior's name style. Path B | `git clone https://github.com/matt-kempster/m2c`, then `python m2c.py -t ppc-mwcc-c <file.s>`. | README (read 2026-11-13): targets are platform-compiler-language, with ppc, mwcc and c listed; used by: Animal Crossing PC Port (docs/m2c_basics.md) |
| decomp-permuter Helpful WSL/Linux | Tries many small rewrites of a near-miss function to find one that matches. It supports PowerPC. Path B | In WSL: `git clone https://github.com/simonlindholm/decomp-permuter` and `python3 -m pip install toml`. Add `permuter_settings.toml` with `build_system = "ninja"` to your project root. Then `./import.py <file.c> <file.s>` and `./permuter.py <dir>`. See `./permuter.py -h` for the `-j` thread option. | README (read 2026-11-13): supports PowerPC; Ninja projects need permuter_settings.toml. The README says only its permuter@home mode fails on native Windows. This guide uses WSL to stay safe. |
| Ghidra with GameCube Loader Helpful both | Ghidra reads machine code and shows a rough C view. The loader teaches it DOL, REL and symbol map files. Path A Path B | Install Ghidra 12.1. Copy `GameCubeLoader-1.3.0-921504c-Ghidra_12.1.zip` (release 1.3.1) into `<Ghidra folder>/Extensions/Ghidra`. Start Ghidra and finish with File, Install Extensions. | README and releases (read 2026-11-13: release 1.3.1, 2026-05-24); used by: Animal Crossing PC Port (docs/ghidra_setup.md) |
| LLVM clang and llvm-profdata Helpful both | Compiles the generated C fast. Profile-guided builds with llvm-profdata gave 10 to 14% more speed in Ring Out.Path A | Install LLVM for Windows from llvm.org, or `sudo apt install clang lld llvm` in WSL. | used by: Ring Out, BlueWake, Luigi's Mansion Recomp, Eternal Darkness Recomp |
| CMake and Ninja Required both | Build tools. Almost every reviewed GameCube project uses them. Path A Path B | `pip install ninja` and install CMake 3.25 or newer from cmake.org. | dtk-template docs/dependencies.md (read 2026-11-13); used by: Dusklight, BlueWake, Strikers |
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.
decompile-to-matching-c-cpp
Rules for C that builds to the same bytes, with a ban on fake matches. It names decomp-toolkit, objdiff-cli and the permuter, which are the GameCube tools.
npx skills add xsyetopz/skills --skill decompile-to-matching-c-cpp -a claude-code
matcher and wall-identifier
matcher works one function with proof first. wall-identifier finds why a function will not match before more tries are spent. Describe your dtk project in AGENTS.md for them. matcher calls the other lemiur matching skills by name, so install those too.
npx skills add lemiur/game-decompilation-skill-for-claude --skill matcher -a claude-code (then the same with --skill wall-identifier)
debug-game-in-emulator
Runs Dolphin the same way each time, with a throwaway data folder, a log and a time limit. Good for reference runs in Path A.
npx skills add xsyetopz/skills --skill debug-game-in-emulator -a claude-code
verification-before-completion
Claude may not say done without fresh proof. That stops 'it boots' claims made from a headless run that never reached gameplay.
npx skills add obra/superpowers --skill verification-before-completion -a claude-code
dispatching-parallel-agents and using-git-worktrees
Helps the lead session hand one function or one bug to each worker. Each worker gets its own folder copy.
npx skills add obra/superpowers --skill dispatching-parallel-agents -a claude-code (and --skill using-git-worktrees)
handoff
Writes a short note so a fresh session can carry on. Tell it to save the note in notes/, not the temp folder.
npx skills add mattpocock/skills --skill handoff -a claude-code
dolphin-debugger-mcp
Lets Claude set breakpoints and read memory in a running game. It was built for the Star Fox Adventures decomp, which used it to fix names guessed from code alone. For another game it reads config/<GAMEID>/symbols.txt from your dtk project.
Quit Dolphin. Set `GDBPort = 2159` under `[General]` in `Dolphin.ini`. Then `claude mcp add dolphin -e DOLPHIN_REPO_ROOT=<repo> -e DOLPHIN_GAMEID=<GAMEID> -- python3 <path>/server.py`.
GhidraMCP
Lets Claude ask Ghidra for functions, cross references and a rough C view, with the GameCube Loader handling DOL and REL files.
Install Ghidra 12.1.4 and `uv`. Add the extension zip from release 2.0 with File, Install Extensions. Then `claude mcp add ghidra -- uvx --from git+https://github.com/LaurieWired/GhidraMCP ghidra-mcp --ghidra-server http://127.0.0.1:8080/`.
Edit hooks that guard shared code
gcn-recomp runs tools/check_generic.py after every edit to keep game names out of shared code. The melee-harness runs lint hooks for match hacks.
In `.claude/settings.json`, add a `PostToolUse` hook on Edit and Write that runs your check script, and a `PreToolUse` hook that exits 2 on edits to `build.sha1`, `orig/` or `generated/`.
gc-match-one
Every worker matches the same way and leaves a trail. This copies what melee-harness checkdiff.py does for Melee.
A skill with one script: rebuild one unit with its exact `build.ninja` command, run `objdiff-cli diff -p . -u <unit> -o - <fn>`, print the score and differing lines, and append the try to `notes/attempts/<fn>.md`. Stop text after 5 tries.
gc-golden-run
Gives Path A one pass or fail answer per route, like Ring Out's determinism harness and Luigi's Mansion's frame dumps.
A skill with one script: start the build headless with a scratch save folder and an input script, run N frames, hash guest memory each frame, and compare with `tests/golden/<route>.hashes`. Print PASS or the first frame that differs.
Claude setup for this system
In Path A, one unit is one crash, one missing SDK call or one drawing bug on one route. Its check is a scripted run with frame hashes. In Path B, one unit is one function in one file. Its check is the objdiff-cli score plus the full ninja hash check. Keep shared runtime code free of game addresses, so fixes do not clash. Write every result in a ledger file, not the chat.
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, symbol file or sister game. Choose recomp or decomp. Write SCOPE.md with the disc ID and DOL 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 dtk-template or the recompiler and runtime. Write tools/check.sh, the hooks and .gitignore for disc files. | Opus 5.5 effort medium | Sonnet 5.5 effort medium |
| Study the game file | Fix split points and names with dtk. Find the OS functions the runtime needs. Mark SDK, JSystem and middleware units. | 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 functions, one per worker. In Path A, fill simple SDK stand-ins and missing GX calls. | 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 stuck at 95 to 99%. Paired-single math. Code that rewrites itself. Big C++ functions with inlines. | 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 | The SDK stand-in: threads, idle loop, disc read timing, audio DSP, memory card. In ports, the Aurora glue and byte-order fixes. | Opus 5.5 effort high | Opus 5.5 effort mediumRaise to high for timing and graphics bugs. |
| Find a bug | Black screens, hangs and slow scenes. Compare with Dolphin first, then read traces, frame dumps and guest addresses. | 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 reruns ninja or the route checks from a clean clone. It hunts for inline asm, edited hashes, stubs and fake 'done'. | 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 PROGRESS.md, notes/functions.csv, notes/findings.md and the dead-end list after each session. | Haiku 5.5 effort medium | Haiku 5.5 effort medium |
How many sessions at once
Max 20x (now called Ultra)
Path B: one lead plus four to six workers, each in its own worktree on one function. Run ninja changes before each merge. Path A: two or three sessions, one bug each, with one game instance per session. Check that no other game copy is running before you time anything.
Max 5x (now called Max)
Path B: one lead and one or two workers. Run long hard-tail jobs at night. Path A: one session at a time, one bug per session, and a fresh session to verify.
Lines for this project's CLAUDE.md
- Read `SCOPE.md` and `PROGRESS.md` at the start of every session.
- The only check is `ninja` (Path B) or `tools/check.sh` (Path A). A score from objdiff is evidence. The full build is the verdict.
- Never edit `config/<GAMEID>/build.sha1`, anything in `orig/`, or anything in `build/` or `generated/`.
- Generated C is never edited by hand. Fix the recompiler and save the fix as a numbered file in `patches/`.
- No inline asm, `asm("")` barriers, per-function `#pragma` blocks or fake `volatile` to force a match. Leave the unit `NonMatching`.
- Nothing game-specific in shared runtime code. A game address belongs in the game's tables, not in a constant.
- Never commit or quote disc images, extracted files, generated C, disassembly or saves.
- Say what you ran and on what device. A build that compiles is not a game that plays.
- Test with a scratch save folder and `--input` scripts, never the owner's real saves.
- Do not update or reset submodules. Pinned commits plus `patches/` are the source of truth.
- Record findings in `notes/findings.md` and dead ends in `notes/dead-ends.md`. Side issues go to `notes/parking-lot.md`.
- In a worktree, use absolute paths and run the build there, not in the main folder.
- Call `objdiff-cli` from `build/tools/`, where `dtk-template` puts it.Keep the context small
- Give Claude one function name and its unit, not a whole
.sfile. Let it runobjdiff-cliitself. - Do not paste Dolphin logs. Save them to a file and give the path and the frame number.
- Add
Readdeny rules forbuild/,generated/andorig/, so searches skip huge machine-made files. - Use a subagent to read a sister game's decomp and report back the few matched functions that look alike.
- Run
/clearbetween functions or bugs. State lives in the ledger files, so nothing is lost.
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 recomp, port or decomp for your game.
GOAL: Tell me the best route to get <GAME> (<DISC_ID>) running on PC, and draft `SCOPE.md`. READ FIRST: `notes/disc-info.txt`, `notes/prior-work.md`. FENCE: Read only, except `SCOPE.md` and `notes/prior-work.md`. Do not install or download anything. CHECK: Run `dtk disc verify <DISC_PATH>` and `dtk dol info '<DISC_PATH>:sys/main.dol'`, and paste both. Done means the disc matches Redump, and the draft names one route (port of an existing decomp, `DolRecomp` recomp, or `gcn-recomp` recomp), the reason, the first milestone and its check command. BUDGET: Stop after 45 minutes. IF BLOCKED: Stop. Say which fact decides the route and how I can get it. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) The route and why. 3) Risks: speed, RELs, self-modifying code, middleware. 4) The `SCOPE.md` draft. 5) Questions for me.
A good answer: One route with a reason tied to facts about the disc and prior work. Clear risks. A short SCOPE.md draft. No code.
Map the binary
After setup, to build the function ledger for either path.
GOAL: Build `notes/functions.csv` for <GAMEID> from `dtk` output. READ FIRST: `config/<GAMEID>/symbols.txt`, `config/<GAMEID>/splits.txt`, `dtk dol info` output in `notes/`. FENCE: Edit only `notes/` files. Do not edit `config/` in this task. CHECK: Run `python tools/check_map.py`. Done means every symbol is listed once with size and kind, and the size totals match each section. BUDGET: Stop after 3 failed check runs. IF BLOCKED: Stop. List the address ranges you could not explain. 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) Counts: game, SDK, JSystem, unknown. 4) What is left. 5) New parking-lot items.
A good answer: A CSV with every function and a count table. Unknown ranges are listed, not guessed.
Unit loop, Path A: fix one bug
For each crash, hang or drawing bug in the recomp.
GOAL: Fix <BUG> on route <ROUTE>. READ FIRST: `PROGRESS.md`, `notes/findings.md`, `notes/dead-ends.md`, log `<LOG_PATH>`. FENCE: Edit only `<RUNTIME_DIR>/` and `patches/`. Never edit `generated/` or `build/`. No game addresses in shared code. CHECK: Run `tools/check.sh routes`. Done means <ROUTE> passes and all other route hashes are unchanged. BUDGET: Stop after 3 failed fixes. Prove the cause before each one. IF BLOCKED: Stop. Show the evidence and the next thing you need to see. 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) Cause in one sentence. 5) New parking-lot items.
A good answer: DONE with the route output pasted, one cause named, and one small change in the runtime or a patch file.
Unit loop, Path B: match one function
For each function in the bulk matching loop.
GOAL: Match <FUNCTION> in <UNIT> to 100% with clean C. READ FIRST: `CLAUDE.md`, `notes/compiler-quirks.md`, `notes/attempts/<FUNCTION>.md` if it exists, similar matched functions: <LIST>. FENCE: Edit only `src/<UNIT>.c` and `include/<UNIT>.h`. No inline asm. Do not touch `configure.py` or `config/`. CHECK: Run `objdiff-cli diff -p . -u <UNIT> -o - <FUNCTION>`, then `ninja` and `ninja changes`. Done means 100%, the hash check passes and no other function lost score. BUDGET: Stop after 5 real attempts. IF BLOCKED: Stop. Log the best score and the differing instructions in `notes/attempts/<FUNCTION>.md`. 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) Best score if not done. 5) New parking-lot items.
A good answer: DONE with a pasted 100% diff and a passing ninja, or PARTIAL with the best score and exact differences logged.
Batch dispatch
In the lead session, to hand out the next set of functions or bugs.
GOAL: Pick the next <N> open units and start one worker per unit, each in its own worktree. READ FIRST: `notes/functions.csv` (status column), `build/<GAMEID>/report.json`, `notes/dead-ends.md`. FENCE: Edit only `notes/functions.csv` (mark units as claimed). Workers edit only their own unit. CHECK: After workers finish, run `ninja` and `ninja changes` on the merged branch. Done means every merge passes and the ledger matches the report. BUDGET: Stop after one round of <N> units. IF BLOCKED: Stop. List which merges failed 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 merged check output. 3) Units matched, partial, failed. 4) Units to send to a hard job. 5) New parking-lot items.
A good answer: A table of units with outcomes, a passing merged build, and a short list of units for the hard job type.
Debug with evidence
When the game hangs, draws black or runs slow and the cause is not known.
GOAL: Find the cause of <SYMPTOM> at <ROUTE>/<FRAME>. Do not fix it yet. READ FIRST: `notes/findings.md`, log `<LOG_PATH>`, frame dump `<DUMP_PATH>`. FENCE: You may add logging behind an environment switch in `<RUNTIME_DIR>/`. No fixes. CHECK: Run the same route in Dolphin. Done means you state whether Dolphin shows the symptom, and name the guest function and address where behaviour first differs. BUDGET: Stop after 90 minutes. IF BLOCKED: Stop. List what you ruled out and what tool or trace you need. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Evidence: log lines, addresses, Dolphin result. 3) The cause in one sentence. 4) A proposed fix and its check. 5) New parking-lot items.
A good answer: A cause proven with a Dolphin comparison and a guest address, plus a fix plan. No code change yet.
Verify and hunt for cheating
After every batch, in a brand new session.
GOAL: Check that the last <N> commits did what they claim, and find any cheating. READ FIRST: `git log -<N> --stat`, `CLAUDE.md`. FENCE: Read only. Write findings to `notes/verify-<DATE>.md` only. CHECK: From a clean clone, run `ninja` (Path B) or `tools/check.sh all` (Path A). Then search the diff for: `asm`, `#pragma`, changes to `build.sha1`, edits under `generated/` or `orig/`, new stubs, disabled tests, game addresses in shared code. 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) PASS or FAIL. 2) Proof: paste the check output. 3) Each problem with commit and file. 4) What you did not check. 5) New parking-lot items.
A good answer: PASS or FAIL first, the pasted check output, and a list of problems with commit and file. No edits.
Status report
At the end of a day or week.
GOAL: Write a status report from the ledgers only. READ FIRST: `PROGRESS.md`, `notes/functions.csv`, `build/<GAMEID>/report.json` or the last `tools/check.sh all` output. FENCE: Edit only `PROGRESS.md`. Do not run new work. CHECK: Run `ninja progress` (Path B), or read the last `tools/check.sh all` log (Path A). Done means every number in the report comes from that output or a file you name, and the totals match. BUDGET: Stop after 15 minutes. IF BLOCKED: Stop. Say which ledger is missing or out of date. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) Matched and linked percent, or routes passing. 2) Change since last report. 3) Top three blockers. 4) Next three units. 5) Parking-lot items for me to decide.
A good answer: Five short lines of numbers with their source files. No padding and no guesses.
Session handoff
Before you close a long session or switch tasks.
GOAL: Write what the next session needs into the ledger files. READ FIRST: This session's changes (`git diff --stat`), `PROGRESS.md`. FENCE: Edit only `PROGRESS.md`, `notes/findings.md` and `notes/dead-ends.md`. CHECK: Run `git status --short` and `git diff --stat`. Done means only the three ledger files changed, and `PROGRESS.md` lists the current unit, its last check output, and the next step. BUDGET: Stop after 10 minutes. IF BLOCKED: Stop. Say what state is only in the chat. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) DONE or PARTIAL. 2) Files changed. 3) The next step in one sentence. 4) Dead ends added. 5) New parking-lot items.
A good answer: Updated ledger files that name the unit, the last check result, the next step and any dead ends.
Blocked or cannot deliver
When a unit keeps failing and you need a plain answer.
GOAL: Tell me plainly whether <UNIT_OR_BUG> can be done with the current tools and rules. READ FIRST: `notes/attempts/<UNIT>.md` or `notes/findings.md`, `CLAUDE.md`. FENCE: Read only. No new attempts. CHECK: Run the last check command from the attempts file once more and paste its output. Done means your answer names the exact blocker (instructions, missing tool, runtime gap or rule) and links each claim to a file or log line. BUDGET: Stop after 20 minutes. IF BLOCKED: Say 'I do not know yet' and what would answer it. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) CAN, CANNOT, or UNKNOWN. 2) The blocker. 3) Two or three options with cost. 4) What you would need from me. 5) New parking-lot items.
A good answer: One word answer first, a precise blocker with proof, and options. No 'should work' and no new code.
Scope change request
When Claude needs to work outside its fence.
GOAL: Ask me before you leave the fence for <TASK>. READ FIRST: `SCOPE.md`, the task card you were given. FENCE: Make no edits outside the original fence while you wait. CHECK: Run `git status --short`. Done means it shows no edits outside the fence, and the request names the files you want to touch, why, the risk, and how you would check the change. BUDGET: One short request. Then stop and wait. IF BLOCKED: Stop. Do not work around the fence. OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them. REPORT: 1) BLOCKED. 2) Files and reason. 3) Risk. 4) The check you would run. 5) What happens if I say no.
A good answer: A short request with files, reason, risk and check. Claude waits for a yes or no.
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 generated C in build/ or generated/ to fix one bug. | Generated C is never edited by hand. Fix the recompiler and save the change as a numbered patch. A hook blocks edits under generated/ and build/. |
| Claude puts one game's addresses or names into shared runtime code. | If a change needs to know about one game, it needs a parameter or a hook, not a constant. Run tools/check_generic.py after every edit. |
| Claude reports the game as playable after a headless run or a good internal counter. | Say what you ran and on what device. A headless boot is not gameplay. Only the owner's play test can mark a feature as tested. |
| Claude calls a build a static recomp while it runs on Dolphin's JIT or an interpreter fallback. | Read the runtime's shutdown line before any claim. Describe JIT builds as Dolphin-based. |
Claude edits build.sha1, marks a unit Matching early, or uses inline asm to force a match. | Block edits to build.sha1 and orig/ with a hook. No asm, #pragma blocks or fake volatile. A clean 90% beats a hacked 100%. |
| Claude says the last few percent is a compiler artifact and gives up. | 'Compiler artifact' is not a cause. Name the differing instructions and search matched code for the same shape first. |
| Claude updates submodules or resets pinned tools and loses the project's patches. | Do not update or reset submodules. Pinned commits plus patches/ are the truth. Ask before you change a pin. |
| Claude tests with the owner's real save files or settings. | Always test with a scratch save folder and --input scripts. Never touch the real saves. |
Problems other projects hit
The recompiled CPU code ran too slow in busy scenes, about 10 to 40 frames per second.
Fix: Measure from one save state and compare with Dolphin's JIT on the same scene. Profile, fix the generator, and try profile-guided builds.
Seen in: F-ZERO GLINUX, Spongebob Squarepants: Revenge of the Flying Dutchman, BlueWake
A table entry pointed at the call site of OSSaveContext. It built fine, then crashed on the first thread switch.
Fix: Put the address of the function itself in special_calls.txt. Check each table entry against the disassembly.
Seen in: Naruto: Clash of Ninja Collection
A PAL disc panicked on boot, and later showed a black window while audio played.
Fix: Report the region the disc names. Finish a frame on the EFB copy, not on the video line count.
Seen in: Naruto: Clash of Ninja Collection
A disc with the right DOL but damaged files passed the hash check and crashed at the title.
Fix: Check every disc file by size and CRC-32 as well as the DOL hash.
Seen in: Luigi's Mansion Recomp
DolRecomp got some paired-single math wrong when the output register was also an input.
Fix: Keep a patch on the pinned recompiler, and test paired-single functions against Dolphin.
Seen in: Eternal Darkness Recomp
Code patched by a memory write did nothing, because the recompiled copy never changes.
Fix: Apply code-changing cheats to the DOL before recompiling, and rebuild. Patch real self-modifying code by hand.
Seen in: Naruto: Clash of Ninja Collection, Spongebob Squarepants: Revenge of the Flying Dutchman
In ports, 4-byte pointers and big-endian disc data broke on 64-bit PCs.
Fix: Keep disc structs big-endian with GCC's scalar_storage_order, or keep guest addresses below 4 GiB. Check struct sizes with an -m32 build.
Seen in: melee-pc, SMS Launcher
A missing symbol in a port linked as a silent stub and only crashed during play.
Fix: Generate abort-on-call stubs from an allow list, so a new missing symbol stops the build.
Seen in: Strikers
The decomp left out the empty GXEnd call, but Aurora needs it to send the draw.
Fix: Make sure every GXBegin has a GXEnd in the PC build.
Seen in: melee-pc
Windows builds failed on long paths and on folders with spaces.
Fix: Clone to a short path such as C:\dev. Unzip MinGW tools to a path with no spaces.
Seen in: F-ZERO GLINUX, Naruto: Clash of Ninja Collection
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 | 4 to 12 weeks | 2 to 7 months | 6 to 24 months | medium confidence |
| Path B: full decomp | 9 to 24 months | 2 to 5 years | 4 to 8 years | low confidence |
Read this first
All ranges assume one medium-sized game and one person with 10 to 15 hours a week. Path A numbers come from at least three dated AI-made recomps. But none says how many hours went in, and some hid earlier work. So Path A confidence is medium. Path B numbers come from only two AI-helped decomps, Melee and Star Fox Adventures. Both were team efforts, so one person will be slower, and Path B confidence is low. The no-AI numbers come from team decomps that took about 2.5 to 6 years. No GameCube recomp predates agents, so the no-AI Path A range is a rough guess.
What makes it faster or slower
- Whether a decomp or
symbols.txtalready exists. With one, Luigi's Mansion went from first public commit to release in nine days, after earlier work in another repo. - How many
.relmodules the game has, and whether it uses code that rewrites itself. - Speed. Two of five
DolRecompgames fell back to Dolphin's JIT, so plan profiling time. - Middleware. CRI video, embedded Python or custom audio each need runtime work.
- For Path B, the size of the game and how much C++ it uses. The last few percent can take as long as the first half.
The facts behind these numbers
| Project | What happened | Link |
|---|---|---|
| Ring Out | First commit 2026-07-27, first release 2026-08-24, one person, README credits Claude for much of the code. | source |
| BlueWake | Feasibility study 2026-08-09, first commit 2026-09-28, first release 2026-09-29, 14 contributors, substantial AI help stated. | source |
| Luigi's Mansion Recomp | First commit 2026-10-07, first release 2026-10-16, run as a Claude Code project; built on a partial decomp's symbols. | source |
| doldecomp/melee | Repo created 2020-06-30. 48.54% matched on 2026-01-10. Last function merged 2026-09-07 in a PR labelled ai-assisted. | source |
| SFA-Decomp (Star Fox Adventures) | Repo created 2026-02-10. Agent loop script agentic_loop.py added 2026-04-13. On 2026-11-13 decomp.dev showed 100% decompiled and 100% linked. 9 contributors on GitHub. | source |
| zeldaret/tp (Twilight Princess) | Repo created 2020-08-29. README now says the GameCube code is completely matching, but not every unit is linked yet. No AI statement in the README. | source |
| projectPiki/pikmin | Repo created 2021-09-28. Reported 100% decompiled on 2026-07-23, the GC/Wii decomp group's fifth GameCube game to get there. | source |
Projects reviewed (15)
The top-starred project for each of the top 12 games on RecompLauncher, plus three projects whose developers say they used AI.
What each project teaches
Dusklight
The Legend of Zelda: Twilight Princess
Started: 2025-11. First release: 2026-04. Code: C++ and C.
AI: none stated; the project closes PRs that are mainly AI-made
Lesson: A finished decomp plus Aurora is the strongest route. Wrap every port change in #if TARGET_PC and keep the original lines.
Animal Crossing PC Port (now named Nookery)
Animal Crossing
Started: 2026-03. First release: 2026-03. Code: C.
AI: yes: README says AI assisted the PC port code only
Lesson: The author's own OpenGL layer was replaced by Aurora. That one switch made Mac, iPhone and Android possible.
Metroid Prime Port
Metroid Prime
Started: unknown. First release: 2026-10. Code: unknown.
AI: store flag only; repo could not be read
Lesson: The repo returned 404 a day after its last release. Save the docs of any project you learn from while they are online.
BlueWake
The Legend of Zelda: The Wind Waker
Started: 2026-09. First release: 2026-09. Code: C, Python and C++.
AI: yes: README says substantial AI help for code, tests, docs and debugging Agent files: AGENTS.md, CLAUDE.md, .claude/settings.json.
Lesson: Recompile the DOL and all 415 RELs as one module. Check the disc and the generated source digest before the long compile.
melee-pc
Super Smash Bros. Melee
Started: 2026-09. First release: 2026-09. Code: C.
AI: store flag only; the repo says nothing about AI
Lesson: Keep disc data big-endian and let GCC swap bytes. Make the build fail early if the compiler ignores that rule.
SMS Launcher
Super Mario Sunshine
Started: 2026-09. First release: 2026-10. Code: JavaScript.
AI: store flag; repo has agent rules for Claude Code and Codex Agent files: AGENTS.md, CLAUDE.md.
Lesson: Turn an agent rule into a failing test. Its changelog test fails if a version has no player note.
Strikers
Super Mario Strikers
Started: 2026-09. First release: 2026-09. Code: C++ and C.
AI: none stated
Lesson: Make linking a gate. Missing symbols become abort stubs only if an allow list names them.
Luigi's Mansion Recomp
Luigi's Mansion
Started: 2026-10. First release: 2026-10. Code: C++ and C.
AI: yes: run as a Claude Code project with a large CLAUDE.md Agent files: CLAUDE.md.
Lesson: A partial decomp's symbol list is enough for a recomp. Replace SDK functions by name instead of recompiling them.
Open Nectar
Pikmin
Started: 2026-09. First release: 2026-09. Code: C++ and C.
AI: yes: README has an AI disclosure and names Claude as a tool
Lesson: Keep decomp code untouched and put the port layer in its own folder. Label tests that need the disc and skip them in CI.
Echoes Unbound
Metroid Prime 2: Echoes
Started: unknown. First release: 2026-10. Code: unknown.
AI: none stated
Lesson: Only catalog facts survive. A guide cannot learn from a repo that is gone, so treat it as unproven.
Eternal Darkness Recomp
Eternal Darkness: Sanity's Requiem
Started: 2026-10. First release: 2026-10. Code: C and C++.
AI: store flag only; the repo says nothing about AI
Lesson: Pin each tool to a commit in one script and keep fixes as patch files. Newer recompiler commits changed the output and broke the build.
Ring Out
Soulcalibur II
Started: 2026-07. First release: 2026-08. Code: C and C++.
AI: yes: README credits Claude with a large share of the code, under human direction
Lesson: Build a frame-keyed input script and per-frame hash early. It became the check for every recompiler change.
F-ZERO GLINUX
F-Zero GX
Started: 2026-07. First release: 2026-10. Code: Shell and Python.
AI: yes: developer says Claude helped with code, packaging and the README
Lesson: Keep a known-good comparison path. Switching to the JIT showed the recompiled CPU code, not graphics, made races slow.
Naruto: Clash of Ninja Collection
Naruto: Clash of Ninja
Started: 2026-10. First release: 2026-10. Code: C++ and C.
AI: yes: developer flag; vendored gcn-recomp has a CLAUDE.md and an edit hook Agent files: .github/copilot-instructions.md, gcn-recomp/CLAUDE.md, gcn-recomp/.claude/settings.json.
Lesson: Games on one SDK share structure. Once one ran, its sequels only needed the same three tables at new addresses.
Spongebob Squarepants: Revenge of the Flying Dutchman
SpongeBob SquarePants: Revenge of the Flying Dutchman
Started: 2026-11. First release: 2026-11. Code: Python.
AI: yes: developer flag for code; the catalog credits an outside AI tool; no agent files
Lesson: Keep a state file a fresh session can start from. Two recompiler fixes gave the biggest speed gains, not hand edits.
What we could not check
- Whether
ModernGekkobuilds with MSVC today. TheDolRecompREADME says it does not, while the template README lists Visual Studio. This guide sends the reader to WSL for that route. - When Star Fox Adventures reached 100% on decomp.dev. The page showed 100% decompiled and linked on 2026-11-13, but no date for reaching it.
- The date Animal Crossing's decomp reached 100%. A July 2026 article says it got there earlier, but gives no date.
- The date Twilight Princess reached a full GameCube match. The README states the match, but no date.
- The
startedmonth for Dusklight and Open Nectar is the month each repo was made. Their first commits come from the decomp they copied (2020-08 and 2021-09), and the real start of port work is not stated. - That
dtk disc extractwrites the samesys/andfiles/folders as Dolphin's Extract Entire Disc. Its README does not show the layout. - Whether the GameCube Loader zip built for Ghidra 12.1 installs on Ghidra 12.1.4, which GhidraMCP asks for.
- Whether
dolphin-debugger-mcpworks for games other than Star Fox Adventures. It readsDOLPHIN_GAMEIDand a dtkconfig/folder, but nobody here tested it. - The
Dolphindownload page. dolphin-emu.org refused scripted requests (403) on 2026-11-13. - Metroid Prime Port and Echoes Unbound: the repos return 404, so their method, tools and AI use are from the catalog only.
- How many hours a week any reviewed project took. No project states it, so all time ranges are estimates.
- The exact
m2ctarget nameppc-mwcc-c. The README gives theplatform-compiler-languagepattern and listsppc,mwccandc; the full string was not run here. - The
--graphics Nullvalue. The template README shows--headlessand--graphics Vulkan;Nullcomes from F-ZERO GLINUX notes. - No command, build or prompt in this guide was run by the fact-checker. Commands were checked against each tool's README and source only.
- Which AI tools wrote which parts of the projects that carry only a store flag.
Sources
- decomp-toolkit README
- dtk-template README and docs
- objdiff README
- nod and nodtool README
- Aurora README and building docs
- DolRecomp README
- ModernGekko-Template README
- ModernGekko README
- GXRuntime README
- gcn-recomp README
- m2c README
- decomp-permuter README
- Ghidra GameCube Loader
- dolphin-debugger-mcp README
- melee-harness README
- Melee decomp README
- Melee final PR #3409
- Wind Waker decomp README
- Twilight Princess decomp README
- Star Fox Adventures decomp on decomp.dev
- decomp.dev front page
- WiiBrew: DOL format
- WiiBrew: REL format
- GameCube technical specifications
- Android Authority: Pikmin decomp at 100%
- Jack Price-Burns: Star Fox Adventures decomp post
- Jack Price-Burns: Teaching a model to decompile
- Jack Price-Burns: Dolphin debugger MCP post
- Wind Waker decomp CONTRIBUTING (AI rule)
- Aurora building docs
- dtk-template getting started
- GhidraMCP README
- Melee PR #2076 (Claude Code match)
- Melee FAQ