Skip to the page
It's Decomplicated
Nintendo, 2017

Nintendo Switch decomp guide

Fork a working Switch recomp, then fix one crash at a time. A full decomp is years away.

What this system is like

Switch games run on a 64-bit ARM chip. Since October 2026, more than a dozen games got native PC builds. Every project we read used static recompilation. That means a tool turns the game's machine code into C, and you write a stand-in for the console around it.

You do not start from zero. Most of the projects we read copied an older Switch recomp and changed only the game parts. Your first job is to pick that base. Then you strip out the old game's patches and fix what breaks.

The hard parts are the same each time. The game expects Nintendo's own system and its own graphics API, called NVN. Its shaders are machine code for an NVIDIA chip. They must be turned into Vulkan shaders.

A full decomp is a different story. No Switch game is fully decompiled yet. The oldest large project, for Breath of the Wild, is about 21% done after six years. Plan Path B as a long project, and be ready to accept code that does not match byte for byte.

Copy a sister project

Twelve of the fifteen projects we read began as a copy of another Switch recomp. TotK Recomp took its lifter from LAS Recomp. Then three more games were built on TotK Recomp. Picking the right base saves you weeks.

Huge code files

A Switch game's main can hold 50 MB of code or more. Pokemon Scarlet's has 52 MiB. Lifting it with two workers ran out of memory. Compiling one game can take from 5 to 45 minutes.

A private graphics API

Games talk to NVN, not to the GPU directly. Every project we could read rebuilt NVN on a PC graphics API, most often Vulkan. Shaders are NVIDIA machine code. They must be translated, often with the Ryujinx emulator's translator.

The game expects three cores

Horizon gives a game three CPU cores with strict priorities. Some games keep data per core with no locks. Free-running PC threads then crash or hang the game. TotK Recomp had to copy the console's scheduler.

You never ship the game

Every project we could read builds the game code on the player's own PC from their own dump. The repo holds only tools and the runtime. In many of them, a content check script guards each commit.

No public original compiler

Nintendo's compiler is a private fork of Clang. Decomp projects use the closest public Clang instead. Small functions match. Big ones often do not.

Two paths

Path A

Get it running on PC

A Python lifter reads each NSO module and writes one C function per game function. A runtime stands in for Horizon, its services, audio, input and NVN. NVN calls go to Vulkan, and shaders are translated to SPIR-V. A Unicorn test checks that the lifter translates each ARM instruction correctly. You build on the player's PC from their own dump.

Go to the steps

Path B

Full decomp for porting

You write C++ that a public Clang compiles to the same bytes as the game. A tool called tools/check compares each function. Small functions often match. Big ones may never match, because Nintendo's compiler is private. For those, you keep readable code and test it against the running recomp.

Go to the steps

Path A: Get it running on PC

A Python lifter reads each NSO module and writes one C function per game function. A runtime stands in for Horizon, its services, audio, input and NVN. NVN calls go to Vulkan, and shaders are translated to SPIR-V. A Unicorn test checks that the lifter translates each ARM instruction correctly. You build on the player's PC from their own dump.

Method: static recompilation (fork of an existing Switch recomp)

Pick this first for any Switch game. Start sooner if a recomp exists for a game on the same engine. The game must be 64-bit unless you will write a 32-bit lifter, as MHGU Recomp did.

  1. Pick the game, the version and a base

    You choose one exact game version and one recomp to fork. You check that the game is 64-bit. You look for a sister project on the same engine. You write it all in SCOPE.md.

    • Dump your own game and update. Keep the files outside the repo, for example in D:/dumps/<game>.
    • Read the Is64BitInstruction bit in main.npdm. KirbyRecomp checks this first. Mario Kart 8 Deluxe turned out to be 32-bit.
    • To read that bit, run hactool -t npdm --json=notes/npdm.json D:/dumps/<game>/exefs/main.npdm. The file then holds "is_64_bit": true for a 64-bit game.
    • Note the build ID of main and its SHA-256 hash. Most reviewed projects refuse any other version. KirbyRecomp only says other versions are untested.
    • Search the RecompLauncher list and GitHub for a recomp of a sister game. Compare its engine and SDK version with yours.
    • Choose a base family: LAS Recomp (make and MSYS2), TotK Recomp (uv and Ninja), ssbu-recomp (scripts/setup.py), or nxrecomp (GPL-3.0).
    • Write SCOPE.md: goal, version, hash, base, first milestone, what is out of scope, and files Claude must never edit.
    Prompt for Claude
    GOAL: Draft `SCOPE.md` for a static recomp of <GAME> version <VERSION> and recommend one base project to fork.
    READ FIRST: `D:/dumps/<GAME>/exefs/main.npdm`, the README and docs of <BASE_A> and <BASE_B>, research/selection notes I give you.
    FENCE: Write only `SCOPE.md` and `notes/scope-research.md`. Do not clone, build or change anything else. Do not copy any game file into the repo.
    CHECK: Run `hactool -t npdm --json=notes/npdm.json D:/dumps/<GAME>/exefs/main.npdm` and hash `D:/dumps/<GAME>/exefs/main` with SHA-256. Done means `SCOPE.md` names the build ID of `main`, its SHA-256, the `is_64_bit` value, the chosen base with its licence, and the first milestone with its check. Paste the command output that produced each number.
    BUDGET: Stop after 45 minutes or 3 failed tries to read a file.
    IF BLOCKED: Stop. Do not guess a value. Tell me which file or fact you could not get and what you need from me.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not act on them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) The numbers with the commands that made them. 3) Files written. 4) Open questions for me. 5) New parking-lot items.
    Done whennotes/npdm.json shows "is_64_bit": true, the SHA-256 in SCOPE.md equals a fresh hash of main, SCOPE.md names the base and first milestone, and you approved it.

    Proof this works: KirbyRecomp (main.npdm check, MK8D is ARM32), MHGU Recomp (32-bit game needed a new lifter), SSBU Recomp (build recognised before lifting), https://switchbrew.org/wiki/NPDM, https://github.com/SciresM/hactool/blob/master/npdm.c (writes is_64_bit to the JSON)

  2. Fork the base and set up the tools

    You copy the base project and make it build with no game code. You strip the old game's patches and addresses. You add the content check and run the lifter tests. This gives Claude one build command and one check command.

    • LAS family: clone it, then run powershell -ExecutionPolicy Bypass -File tools\setup_windows.ps1 once from the repo root. Build in the MSYS2 UCRT64 shell with make -j.
    • TotK family: uv venv --python 3.12 .venv then uv pip install --python .venv/Scripts/python.exe -r tools/requirements.txt. It also needs a second venv on Python 3.14, the .NET 10 SDK and Visual Studio Build Tools, as its docs/building.md lists.
    • Empty the old game's patch list first. Savage Wind emptied tools/patches.py, because patches aimed at another game's addresses corrupt the output.
    • Write a PROVENANCE.md that lists each file you changed from upstream, as KirbyRecomp did.
    • Keep tools/check_content.py (or write one) and run it as a git pre-commit hook. It refuses game files, keys and generated code. TotK Recomp turns its hook on with git config core.hooksPath .githooks.
    • Run the base's lifter test. LAS: tools/test_simd.py. TotK: the tests/diff/ scripts. MHGU: make test-lift.
    Prompt for Claude
    GOAL: Make the forked base build its runtime with no game code, and make its lifter test pass.
    READ FIRST: `SCOPE.md`, `CONTRIBUTING.md`, `docs/architecture.md`, the base's build doc.
    FENCE: Edit only `tools/patches.py` (to empty it), `PROVENANCE.md`, `.githooks/`, `CLAUDE.md` and `notes/`. Do not touch the lifter, the runtime or `tools/vendor/`. Do not add features or refactors.
    CHECK: Run `<BUILD_COMMAND>` and `<LIFTER_TEST_COMMAND>`. Done means the build ends with no errors and the lifter test reports 0 mismatches. Also run `python tools/check_content.py --staged` and show it passes.
    BUDGET: Stop after 3 failed builds with the same error, or 60 minutes with no progress.
    IF BLOCKED: Stop. Do not work around a missing tool. Tell me the exact error, what you tried, and what you need me to install.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Paste the last 20 lines of the build and the test summary. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenThe runtime builds with no game code, the lifter test reports 0 mismatches, and the content check passes.

    Proof this works: Savage Wind Recomp (emptied tools/patches.py first), KirbyRecomp (PROVENANCE.md), TotK Recomp (check_content.py as hook and CI), https://github.com/peiikai/LASRecomp

  3. Survey the code before you lift

    You measure the game's code and compare it with the base game. You count modules, sizes, imports and the SDK version. The difference tells you what the runtime lacks before anything runs.

    • Have Claude write a probe script like Tera Recomp's tools/sv_analyze.py or Savage Wind's tools/sw_probe.py. It prints sizes and imports without writing C.
    • Count imported nn:: functions by namespace. Mark each one as handled by the base or missing.
    • Look for C++ exception tables, TLS (thread-local data) use and setjmp. Witch Time found exception tables and TLS were new to its base. Tera Recomp and Savage Wind had to add setjmp support.
    • Open main in Ghidra with the Switch loader to check odd spots. Commit only counts and build IDs, never code.
    • Save the ledger as notes/imports.csv with columns: name, module, status, owner.
    Prompt for Claude
    GOAL: Produce `notes/imports.csv` and `notes/survey.md` that compare <GAME>'s ExeFS with the base game's.
    READ FIRST: `SCOPE.md`, `D:/dumps/<GAME>/exefs/` (read only), the base's list of handled imports in `<RUNTIME_IMPORT_TABLE>`.
    FENCE: Write only `tools/survey.py`, `notes/imports.csv` and `notes/survey.md`. The dump is read-only. Do not paste disassembly into any file.
    CHECK: Run `python tools/survey.py D:/dumps/<GAME>/exefs`. Done means every module is listed with size and build ID, every import has a status, and the totals in `notes/survey.md` add up.
    BUDGET: Stop after 90 minutes or 3 failed runs of the script.
    IF BLOCKED: Stop. Tell me which file could not be parsed and the exact error.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Paste the script's summary lines. 3) Files written. 4) The top 10 missing imports by call count. 5) New parking-lot items.
    Done whennotes/imports.csv lists every import with a status, and notes/survey.md names the SDK version and new features the base lacks.

    Proof this works: Tera Recomp (tools/sv_analyze.py, docs/phase1-analysis.md; setjmp needed a runtime helper), Witch Time (docs/RE_NOTES.md: exception tables, TLS, 32 new NVN entry points), Savage Wind Recomp (tools/sw_probe.py; setjmp in sdk needed an HLE longjmp)

  4. Lift and link the whole game

    You run the lifter over every module and link the result. You do not try to run it yet. You count what the lifter could not handle. The goal is zero unsupported instructions and a clean link.

    • LAS family: make gen once, then make -j.
    • TotK family: .venv/Scripts/python recomp/gen.py --exefs build/extracted/<ver>/exefs --out generated/<ver> --patches recomp/patches-<ver>.txt then .venv/Scripts/python tools/build_game.py --version <ver>. Your fork's patch file starts empty.
    • If memory runs out, lift with one worker. Tera Recomp used --jobs 1 for a 52 MiB main. TotK's gen.py also halves its workers by itself when one runs out of memory.
    • List unhandled instructions, traps and unresolved jump tables in notes/lift-report.md.
    • Fix each gap in the generator, never in generated/. Re-run the Unicorn test after each lifter change.
    Prompt for Claude
    GOAL: Lift every module of <GAME> and link it, with 0 unsupported instructions.
    READ FIRST: `SCOPE.md`, `notes/survey.md`, `docs/architecture.md`, the lifter source in `recomp/`.
    FENCE: Edit only the lifter in `recomp/` and its tests. Never edit files in `generated/`. Do not touch the runtime.
    CHECK: Run `<LIFT_COMMAND>` then `<LINK_COMMAND>` then `<LIFTER_TEST_COMMAND>`. Done means the link succeeds, the lift log reports 0 unsupported instructions, and the lifter test reports 0 mismatches.
    BUDGET: One lifter gap per try. Stop after 3 failed tries on the same gap.
    IF BLOCKED: Stop. Name the instruction or pattern, its address in `main`, and what you tried.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix runtime issues here.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Paste the lift summary and the test summary. 3) Files changed. 4) Gaps left, with counts. 5) New parking-lot items.
    Done whenThe game links, the lift log shows 0 unsupported instructions, and the Unicorn lifter test shows 0 mismatches.

    Proof this works: Tera Recomp (phase 2: lift and link before running), Witch Time (55,277 functions lifted in 5 s), TotK Recomp (gen.py and build_game.py steps)

  5. Boot to the first frame

    You run the game and fix each stop on the way to the first picture. A strict mode prints every missing import by name. Each stop gets one row in a boot log. This is first light.

    • Add a strict mode that traps any call to an unhandled import and prints its name, like Witch Time's WT_STRICT=report.
    • Keep notes/boot-log.md as a table: Stop, Cause, Fix, file. Tera Recomp did this for each crash.
    • Add a scripted run with a scratch save folder and a screenshot at a set frame, like LAS Recomp's tools/shot.sh.
    • The TotK family already has one: .venv\Scripts\python tools\run_game.py build\<dir> --save <name> --seconds 30 --shot out.png. Add --script <input.txt> to replay input.
    • Use a crash-address tool like LAS Recomp's tools/sym.py to map a crash to main+0x....
    Prompt for Claude
    GOAL: Get <GAME> to draw its first frame with no crash in a scripted run.
    READ FIRST: `SCOPE.md`, `notes/boot-log.md`, `notes/imports.csv`, `docs/architecture.md`.
    FENCE: Edit only `runtime/` and `notes/`. Never edit `generated/`. Do not add stubs that return success without a comment that names the cause.
    CHECK: Run `<SCRIPTED_RUN_COMMAND>` with a time limit and a screenshot at the end, for example `.venv\Scripts\python tools\run_game.py build\<DIR> --save <SAVE> --seconds 30 --shot notes/first-light.png`. Done means the run exits without a crash and the screenshot shows the game's first screen. Attach the screenshot path and the last 30 log lines.
    BUDGET: One stop per try. Stop after 3 failed fixes on the same stop, or 60 minutes with no new row in the boot log.
    IF BLOCKED: Stop. Give the crash address, the missing import or service, and what you tried.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Screenshot path and log lines. 3) Files changed. 4) New boot-log rows. 5) New parking-lot items.
    Done whenA scripted run shows the game's first screen in a saved screenshot and exits without a crash.

    Proof this works: Witch Time (strict mode, title at frame 600), Tera Recomp (docs/phase3-boot.md Stop/Cause/Fix table), LAS Recomp (tools/shot.sh, tools/sym.py), https://github.com/valentderah/totk-pc-recomp/blob/main/docs/agents/running.md (run_game.py flags)

  6. Fix one crash or glitch at a time

    This is the grind. Each task is one crash, one missing service or one wrong picture. Claude must prove the cause before it changes code. Shader work gets its own offline count.

    • Dump every shader the game uses, then translate and validate all of them offline. Witch Time tracked this as a number: 7,838 of 7,838.
    • Run with Vulkan validation layers on. Treat any new message as a bug.
    • When static reading fails, compare with a working emulator run. Tera Recomp attached gdb to Ryujinx to find a missing object.
    • Write each finding as a numbered note with symptom, cause and fix, as FEFW Recomp did in docs/debug/NNN.md.
    • Write dead ends down too, so no session tries them again.
    Prompt for Claude
    GOAL: Find and fix the cause of <BUG> (seen at <WHERE_IN_GAME>).
    READ FIRST: `SCOPE.md`, `notes/symptoms.md`, `notes/debug/`, the log at `<LOG_PATH>`.
    FENCE: Edit only `runtime/` and `notes/`. Never edit `generated/`. A stub, clamp, retry or longer timeout is allowed only if the cause is known and named in a comment.
    CHECK: First write the cause with evidence: the faulting address, the wrong value and who wrote it. Then run `<SCRIPTED_RUN_COMMAND>` before and after the fix. Done means the bug is gone in the after-run screenshot or log, and `<REGRESSION_COMMAND>` still passes.
    BUDGET: Stop after 2 refuted ideas or 90 minutes with no proven cause.
    IF BLOCKED: Stop. List what you checked, what each check ruled out, and what evidence you need.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Cause with evidence, and before and after proof. 3) Files changed. 4) A new `notes/debug/NNN.md` entry. 5) New parking-lot items.
    Done whenThe bug's cause is written with evidence, and a scripted run before and after shows it fixed with the regression set still passing.

    Proof this works: Witch Time (tools/mxcheck.c shader count), Tera Recomp (gdb on Ryujinx found the missing root node), FEFW Recomp (numbered debug notes), LAS Recomp (AGENTS.md: find why before changing code)

  7. Build a regression set

    You make sure old fixes stay fixed. Scripted routes replay the same input. A deterministic mode can hash the game state each frame. Checks that need no game file can run in CI.

    • Record input routes from a fixed save, like B2 Recomp's tests/route_first_fight.txt.
    • If you can, add a deterministic mode that logs a state hash per frame. SSBU Recomp compares logs before and after a change. The first different line names the frame.
    • Add self-tests that need no game, like TotK Recomp's --selftest and --probe-* switches.
    • Run the synthetic lifter test in CI on every push, as SSBU Recomp and KirbyRecomp do.
    • Put each risky change behind a switch, and compare whole runs with it off and on.
    Prompt for Claude
    GOAL: Add a regression command that replays <N> recorded routes and checks each one.
    READ FIRST: `SCOPE.md`, `notes/PROGRESS.md`, the scripted run tool `<RUN_TOOL>`.
    FENCE: Edit only `tests/`, `tools/regress.*` and `notes/`. Do not change game behavior in `runtime/`.
    CHECK: Run `<REGRESSION_COMMAND>` twice on the same build. Done means every route passes both times with the same result. Then break one known fix on a scratch branch and show the command fails.
    BUDGET: Stop after 3 failed tries to make a route stable.
    IF BLOCKED: Stop. Tell me which route is not repeatable and what changes between runs.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Output of both runs and of the broken run. 3) Files changed. 4) Routes still missing. 5) New parking-lot items.
    Done when<REGRESSION_COMMAND> passes twice in a row and fails when a known fix is removed.

    Proof this works: SSBU Recomp (deterministic state hash log), B2 Recomp (scripts/bench.py with A/B mode), TotK Recomp (--selftest and probes)

  8. Package it without game code

    You make the build run on a player's PC from their own dump. The installer checks the dump's hashes first. The release holds no game code. You document known problems plainly.

    • Check the player's dump by SHA-256 or build ID before any work, and stop on a mismatch.
    • Bundle the generator and a compiler, as LAS Recomp does with PyInstaller and zig cc. KirbyRecomp pins ziglang from PyPI.
    • Make setup resumable, with named steps and a log per step, as B2 Recomp's scripts/setup.py does.
    • Stamp the built game library with an ID so a stale one never loads, as Savage Wind does.
    • Tell players that antivirus may remove the big unsigned game DLL.
    Prompt for Claude
    GOAL: Make a release that builds <GAME> on a clean PC from the player's own dump.
    READ FIRST: `SCOPE.md`, `docs/building.md`, `tools/check_content.py`.
    FENCE: Edit only `installer/`, `tools/make_release.*`, `docs/` and `notes/`. Do not change the lifter or runtime.
    CHECK: On a clean checkout, run `<RELEASE_COMMAND>`, then run the installer against `D:/dumps/<GAME>`. Done means the game reaches the title in a scripted run, a wrong dump is refused with a clear message, and `python tools/check_content.py` finds no game content in the release folder.
    BUDGET: Stop after 3 failed release builds.
    IF BLOCKED: Stop. Paste the failing step's log.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof for all three checks. 3) Files changed. 4) Known issues for the README. 5) New parking-lot items.
    Done whenA clean checkout builds a release, and the installer refuses a wrong dump. The game reaches the title. The content check passes on the release folder.

    Proof this works: LAS Recomp (frozen generator and zig cc), B2 Recomp (ten resumable setup steps), Savage Wind Recomp (GAMELIB_ID), Metroid Dread Recomp (RomFS manifest check)

Path B: Full decomp for porting

You write C++ that a public Clang compiles to the same bytes as the game. A tool called tools/check compares each function. Small functions often match. Big ones may never match, because Nintendo's compiler is private. For those, you keep readable code and test it against the running recomp.

Method: matching decompilation in C++ with upstream Clang, plus non-matching code checked by tests

Pick this only after Path A works, or when a decomp of your game already exists. Expect years, not months. Choose a small game if you want to finish.

  1. Check prior work and pick the compiler

    You look for an existing decomp of your game or its engine. You find which SDK version built the game. The SDK version tells you which public Clang is closest. You decide what counts as done.

    • Check zeldaret/botw, MonsterDruide1/OdysseyDecomp and sbergeron42/ssbu-decomp for shared code such as sead or SDK parts.
    • Find the SDK version from the ExeFS, as Tera Recomp's survey script did.
    • Match the SDK to a Clang version. ssbu-decomp uses upstream LLVM 8.0.0 for SDK 8.2.1. The BotW decomp fetches Clang 4.0.1.
    • Write in SCOPE.md that big functions may stay non-matching, and how they will be tested instead.
    Prompt for Claude
    GOAL: Draft the Path B part of `SCOPE.md` for <GAME> <VERSION>: prior work, SDK version, compiler choice and the meaning of done.
    READ FIRST: `SCOPE.md`, the READMEs of zeldaret/botw, MonsterDruide1/OdysseyDecomp and sbergeron42/ssbu-decomp, `D:/dumps/<GAME>/exefs/sdk` (read only).
    FENCE: Write only `SCOPE.md` and `notes/decomp-scope.md`. Do not set up a build yet.
    CHECK: Run `python tools/survey.py D:/dumps/<GAME>/exefs` and paste the SDK version line. Done means the draft names that SDK version, the chosen Clang version with a source, any shared library code already decompiled elsewhere, and the rule for non-matching functions.
    BUDGET: Stop after 60 minutes.
    IF BLOCKED: Stop. Say which fact you could not confirm. Do not guess a compiler version.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Each fact with its source. 3) Files written. 4) Open questions. 5) New parking-lot items.
    Done whenSCOPE.md names the SDK version, the Clang version with its source, prior work to reuse, and the non-matching rule, and you approved it.

    Proof this works: https://github.com/sbergeron42/ssbu-decomp, https://botw.link/contribute/installation, Tera Recomp (SDK version from ExeFS survey)

  2. Set up the matching build in WSL

    You copy the layout the BotW and Odyssey decomps use. It has CMake, Ninja, a pinned Clang and the nx-decomp-tools checker. The build must work with an empty source tree. Then Claude has one build and one check command.

    • In WSL: sudo apt install python3 ninja-build cmake ccache xdelta3 clang libssl-dev pkg-config. BotW needs Python 3.12 or newer.
    • BotW needs CMake 3.30 or newer. Ubuntu 24.04 ships an older one, so also run pip install cmake (or use CMake's own APT repository).
    • Install Rust with curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh. BotW's setup builds some of its tools from Rust code.
    • Clone the repo inside WSL, not under /mnt/c. Building from the Windows side is much slower.
    • Add nx-decomp-tools as a submodule, then run git submodule update --init --recursive.
    • Write tools/setup.py <path to main> like BotW's. It sets up the venv, the checker, the converted main and the pinned Clang.
    • Build with ninja -C build, then run tools/check. It should print OK.
    Prompt for Claude
    GOAL: Make an empty decomp project for <GAME> that builds and passes `tools/check`.
    READ FIRST: `SCOPE.md`, the BotW decomp's `tools/setup.py` and `CMakeLists.txt` as a pattern, `notes/decomp-scope.md`.
    FENCE: Edit only `CMakeLists.txt`, `tools/setup.py`, `toolchain/`, `.gitmodules` and `notes/`. Keep `main` and every dumped file outside the repo or in an ignored folder.
    CHECK: Run `tools/setup.py <MAIN_PATH>`, `ninja -C build` and `tools/check`. Done means the build has no errors and `tools/check` prints `OK`.
    BUDGET: Stop after 3 failed setup runs with the same error.
    IF BLOCKED: Stop. Paste the error and say which tool or version is missing.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Paste the output of all three commands. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenninja -C build succeeds and tools/check prints OK on a fresh WSL clone.

    Proof this works: https://botw.link/contribute/installation, https://github.com/MonsterDruide1/OdysseyDecomp, https://github.com/open-ead/nx-decomp-tools

  3. Build the function list

    You list every function with its address, size, status and name. Library code is marked so nobody decompiles it by hand. Names come from real evidence only. This file is the ledger for all later work.

    • Load main in Ghidra with the Switch loader. Export a CSV with the columns Address,Quality,Size,Name, like BotW's data/uking_functions.csv.
    • Take names from the binary's exported symbols first. ssbu-decomp calls these ground truth.
    • Mark known library code, such as sead, NintendoSDK, zstd or Lua, so workers skip it.
    • Sort functions by size. Small ones match most often with public Clang.
    Prompt for Claude
    GOAL: Create `data/functions.csv` for <GAME> with every function's address, quality, size and name.
    READ FIRST: `SCOPE.md`, the Ghidra project at `<GHIDRA_PROJECT>`, BotW's `data/uking_functions.csv` header as a format example.
    FENCE: Write only `tools/export_functions.py`, `data/functions.csv` and `notes/map.md`. Do not rename anything without a source. No disassembly in any committed file.
    CHECK: Run `python tools/export_functions.py` and `tools/check`. Done means the CSV loads in the checker with no errors, the sizes add up to the `.text` size within 1%, and `notes/map.md` gives counts by status and by library.
    BUDGET: Stop after 2 hours or 3 failed exports.
    IF BLOCKED: Stop. Tell me what the exporter could not resolve.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Paste the counts and the size check. 3) Files written. 4) Ranges that look wrong. 5) New parking-lot items.
    Done whendata/functions.csv covers all of .text within 1%, loads in tools/check, and library code is marked.

    Proof this works: BotW decomp (data/uking_functions.csv), ssbu-decomp (data/functions.csv from Ghidra, 39,635 entries), https://github.com/Adubbz/Ghidra-Switch-Loader

  4. Match one small function

    You prove the whole chain works on one tiny function. Claude writes C++, builds, and compares. The checker shows no difference. Then the CSV row is updated.

    • Pick a small leaf function with a known name.
    • Write it in C++ without copying Ghidra's output word for word. Keep calls and offsets the same.
    • Run tools/check -mw <function name> to see the diff. It rebuilds on each save.
    • Mark the CSV row. BotW uses m for minor and M for major differences.
    Prompt for Claude
    GOAL: Match the function <FUNCTION_NAME> at <ADDRESS> byte for byte.
    READ FIRST: `SCOPE.md`, `data/functions.csv`, the header `<HEADER_PATH>`, Ghidra's view of <ADDRESS>.
    FENCE: Edit only `<SOURCE_FILE>`, `<HEADER_PATH>` and the one CSV row. No inline assembly, no naked functions, no `goto` to force a match.
    CHECK: Run `tools/check <FUNCTION_NAME>`. Done means it reports no difference, and `tools/check` with no argument still prints `OK`.
    BUDGET: Stop after 5 meaningfully different tries.
    IF BLOCKED: Stop. Mark the row `M` or `m`, add a `NON_MATCHING:` comment, and tell me the exact differing instructions.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Paste the check output. 3) Files changed. 4) What you tried. 5) New parking-lot items.
    Done whentools/check <function> shows no difference and the full tools/check prints OK.

    Proof this works: https://botw.link/contribute/how-to-decompile, ssbu-decomp (verify_all.py byte compare)

  5. Grind functions in parallel

    Many workers each take one file or one class. Each works in its own git worktree with its own territory. A script reviews each diff for banned tricks. Only verified work is merged.

    • Give each worker exclusive files, as ssbu-decomp's pools do. A lead session merges.
    • Start each worker with claude -w <name> so it gets its own worktree under .claude/worktrees/.
    • A new worktree has no ignored files, such as build/ or the converted main. Link big folders with the worktree.symlinkDirectories setting, or give workers absolute paths.
    • Write a diff reviewer like ssbu-decomp's tools/review_diff.py. It rejects naked functions and raw Ghidra names like uVar1.
    • Run the full tools/check after each merge, not only per function.
    • Send functions that fail 5 tries to the hard queue.
    Prompt for Claude
    GOAL: As lead, pick the next <N> unmatched functions under <SIZE> bytes and run one worker per function.
    READ FIRST: `SCOPE.md`, `data/functions.csv`, `notes/PROGRESS.md`, `notes/claims.md`.
    FENCE: You edit only `notes/claims.md` and `notes/PROGRESS.md`. Each worker edits only its claimed source file in its own worktree. Nobody edits `data/functions.csv` except through the merge step.
    CHECK: For each worker, run `tools/check <FUNCTION_NAME>` and `python tools/review_diff.py <BRANCH>` in its worktree. After merging, run `tools/check` on the main branch. Done means every merged function shows no difference and the main branch prints `OK`.
    BUDGET: Each worker stops after 5 tries. Stop the round after <N> functions or 3 hours.
    IF BLOCKED: Stop the worker. Put the function in `notes/hard-queue.md` with the exact differing instructions.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) A table: function, result, check output line. 3) Branches merged. 4) Hard-queue additions. 5) New parking-lot items.
    Done whenEvery merged function passes tools/check, the review script passes, and the main branch prints OK.

    Proof this works: ssbu-decomp (pools on worktrees, review_diff.py), https://github.com/sbergeron42/ssbu-decomp, https://code.claude.com/docs/en/worktrees.md (claude -w, ignored files are absent)

  6. Name structs with proof

    Matching needs correct types. Claude reads many functions that touch the same struct offset and builds the struct. Every field name needs a source. Guesses are tagged as guesses.

    • Tag each field as [derived: ...] or [inferred: ...], as ssbu-decomp does.
    • Leave unknown fields as unk_0xNN.
    • Follow BotW's rule: do not reimplement a component you cannot name.
    • Keep placeholder structs in their own folder with a research list.
    Prompt for Claude
    GOAL: Define the struct used at <ADDRESS_LIST> with every field typed and sourced.
    READ FIRST: `SCOPE.md`, the functions at <ADDRESS_LIST> in Ghidra, `include/` headers that touch this type.
    FENCE: Edit only `<HEADER_PATH>` and `data/undefined_types.md`. Do not rename anything elsewhere.
    CHECK: Run `ninja -C build` and `tools/check`. Done means the build passes, `tools/check` still prints `OK`, and each field has a `[derived:]` or `[inferred:]` tag naming its source.
    BUDGET: Stop after 90 minutes.
    IF BLOCKED: Stop. List the offsets you could not type and why.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Check output. 3) Files changed. 4) Fields left unknown. 5) New parking-lot items.
    Done whenThe header builds, tools/check prints OK, and every field has a source tag or stays unk_0xNN.

    Proof this works: ssbu-decomp (naming provenance tags), BotW decomp (AGENTS.md: research before reimplementing)

  7. Test non-matching code in the recomp

    Some functions will never match with public Clang. You still need proof they work. You swap your C++ into the working recomp in place of the lifted function. Then you replay a route and compare state logs.

    • Use the Path A recomp as the test bench. SSBU Recomp checks decompiled fighter scripts this way.
    • Add a switch that picks the lifted or the decompiled version of each function.
    • Replay the same scripted input with a per-frame state hash log, before and after.
    • Record each function's result in the CSV notes.
    Prompt for Claude
    GOAL: Prove the non-matching function <FUNCTION_NAME> behaves like the original.
    READ FIRST: `SCOPE.md`, `<SOURCE_FILE>`, the recomp's override switch doc `<OVERRIDE_DOC>`, the route `<ROUTE_FILE>`.
    FENCE: Edit only the override table `<OVERRIDE_TABLE>` and `notes/`. Do not edit the decompiled function to make the test pass without telling me.
    CHECK: Run `<DETERMINISTIC_RUN> --route <ROUTE_FILE>` with the lifted version, then with the decompiled one. Done means the two state hash logs are identical.
    BUDGET: Stop after 3 runs that differ.
    IF BLOCKED: Stop. Give the first differing log line and the frame.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Both log hashes. 3) Files changed. 4) Functions still untested. 5) New parking-lot items.
    Done whenThe state hash logs from the lifted and decompiled versions are identical on the same route.

    Proof this works: SSBU Recomp (fighter scripts: 20,256 of 23,834 functions equal as C++, checked by differential tests)

  8. Port: build the game from source

    You replace lifted functions with your source, one module at a time. The recomp runtime stays as the console layer. Each swap must pass the same golden runs. This is how the decomp reaches other systems.

    • Keep the runtime's NVN-on-Vulkan layer as the graphics interface.
    • Switch modules from lifted to decompiled source behind the override table.
    • Run the regression routes from Path A after each module.
    • Build for a second target only after the PC build passes. LAS Recomp shows one runtime can serve Windows, Linux and macOS.
    Prompt for Claude
    GOAL: Build <MODULE> of <GAME> from decompiled source instead of lifted code, and keep every golden run passing.
    READ FIRST: `SCOPE.md`, `notes/PROGRESS.md`, the override table `<OVERRIDE_TABLE>`, `<REGRESSION_COMMAND>` docs.
    FENCE: Edit only the build files for <MODULE> and the override table. Do not change runtime behavior.
    CHECK: Run `<REGRESSION_COMMAND>`. Done means every route passes with <MODULE> fully from source, and the count of lifted functions in <MODULE> is 0.
    BUDGET: Stop after 3 failed regression runs.
    IF BLOCKED: Stop. Name the function and route that fail, with the first differing log line.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Regression output. 3) Files changed. 4) Lifted functions left per module. 5) New parking-lot items.
    Done whenThe module builds from source with 0 lifted functions, and every regression route passes.

    Proof this works: SSBU Recomp (readable C++ where people edit, checked against lifted originals), LAS Recomp (one runtime on Windows, macOS and Linux)

Tools you need

ToolWhat it doesHow to get itHow we know
LAS Recomp
Required both
A working Switch recomp with its own Python lifter, runtime and NVN layer. Several projects forked it as a base.
Path A Path B
`git clone https://github.com/peiikai/LASRecomp`, then `powershell -ExecutionPolicy Bypass -File tools\setup_windows.ps1` once from the repo root. It installs MSYS2 and Python 3.12. Needs a CPU with AVX2 and a GPU with Vulkan 1.3. Development happens on the newest `beta_<n>` branch.README read 2026-11-13 (latest release beta_5.4); used by: Savage Wind, MHGU Recomp, KirbyRecomp, TotK Recomp
TotK Recomp
Helpful Windows
A second base family. It uses uv, Ninja and the Ryujinx shader translator. Its AGENTS.md is a strong model for your own.
Path A
`git clone https://github.com/valentderah/totk-pc-recomp`, then `uv venv --python 3.12 .venv` and the steps in `docs/building.md`. Allow about 60 GB of disk.README, AGENTS.md and docs/building.md read 2026-11-13 (release v0.4.0); used by: XC2 Recomp, Astral Chain Recomp, Tera Recomp
MSYS2 (UCRT64 with Clang and lld)
Required Windows
A Windows shell with Clang, lld, make and many libraries. Generated C uses GNU extensions, so Microsoft's cl.exe cannot build it.
Path A
Run `msys2-x86_64-20260927.exe` from msys2.org and install to `C:\msys64`. Then in the UCRT64 shell, for the LAS family (MHGU Recomp's list): `pacman -S --needed make git diffutils mingw-w64-ucrt-x86_64-clang mingw-w64-ucrt-x86_64-lld mingw-w64-ucrt-x86_64-pkgconf mingw-w64-ucrt-x86_64-sdl3 mingw-w64-ucrt-x86_64-shaderc mingw-w64-ucrt-x86_64-nasm mingw-w64-ucrt-x86_64-vulkan-headers mingw-w64-ucrt-x86_64-vulkan-loader mingw-w64-ucrt-x86_64-vulkan-memory-allocator`. The TotK family uses the longer list in its `docs/building.md`.msys2.org read 2026-11-13 (installer name); package list copied from MHGU Recomp README and checked against TotK docs/building.md 2026-11-13; used by: LAS, Savage Wind, TotK, XC2, Tera, MHGU
uv
Helpful both
Makes Python environments fast and pins their versions. The TotK family uses two of them.
Path A Path B
`powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"`README read 2026-11-13 (0.13.8); used by: TotK, XC2, Astral Chain, Tera, FEFW
Capstone
Required both
A disassembler library. Lifters use it to decode each ARM instruction.
Path A
`pip install capstone` inside the project venv (5.0.9 is the current release)PyPI read 2026-11-13; used by: LAS, Savage Wind, SSBU, MHGU, FEFW, KirbyRecomp, SuperWonders
Unicorn
Required both
A CPU emulator. Projects run each ARM instruction in Unicorn and in the lifted C, then compare registers and memory. It is GPL, so keep it in tests only.
Path A
`pip install unicorn` inside the project venv (2.1.4 is the current release)PyPI and repo read 2026-11-13 (GPL-2.0); used by 13 of 15 reviewed projects
Ghidra
Required both
A free disassembler and decompiler. You use it to read the game's code and export function lists.
Path A Path B
First install JDK 21 (64-bit). Then download `ghidra_12.1.2_PUBLIC_20260605.zip` from the releases page and unzip it. Use 12.1.2, because the Switch loader release is built for it. Run `ghidraRun.bat`.README at tag Ghidra_12.1.2_build read 2026-11-13 (asks for JDK 21; the newer 12.2 asks for JDK 25); TotK docs/building.md also pairs 12.1.2 with JDK 21; used by: B2 Recomp, Witch Time, TotK, XC2, Savage Wind, ssbu-decomp
Ghidra-Switch-Loader
Required both
A Ghidra add-on that opens Switch NSO, NRO and similar files.
Path A Path B
Download `SwitchLoader-1.6.1-0f38957-Ghidra_12.1.2.zip` from Releases. In Ghidra use File, Install Extensions, press `+`, pick the zip, and restart.README and releases read 2026-11-13; used by: B2 Recomp, Witch Time, TotK, XC2, Tera
hactool
Helpful Windows
Unpacks NSP, XCI and NCA files into exefs and romfs folders. It needs your own prod.keys. Skip it if your dump is already extracted.
Path A Path B
Download `hactool-1.4.0-win.zip` from Releases. Example: `hactool -k <your prod.keys> --exefsdir=exefs --romfsdir=romfs <file.nca>`. To read `main.npdm`: `hactool -t npdm --json=npdm.json main.npdm`.README usage and npdm.c read 2026-11-13 (flags take =; the JSON has is_64_bit); TotK, XC2, Astral Chain and Tera build a patched 1.4.0 with tools/build_hactool.py
.NET 10 SDK and Visual Studio Build Tools
Helpful Windows
The TotK family builds the Ryujinx shader translator into one exe with .NET. The .NET build calls Microsoft's linker from Build Tools.
Path A
`winget install --id Microsoft.DotNet.SDK.10 -e`. Then Visual Studio Build Tools 2026 with the C++ workload: TotK's docs name the winget package `Microsoft.VisualStudio.BuildTools` with `--add Microsoft.VisualStudio.Workload.VCTools --includeRecommended`. Add `C:\Program Files (x86)\Microsoft Visual Studio\Installer` to PATH.TotK docs/building.md toolchain table read 2026-11-13; winget syntax from learn.microsoft.com read 2026-11-13; used by: TotK, XC2, Astral Chain, Tera, FEFW. Required only for the TotK family and other bases that use the Ryujinx translator.
Ryujinx (Ryubing)
Helpful both
An open-source Switch emulator under the MIT licence. Recomps borrow its shader translator. You can also run the game in it to compare behavior.
Path A
Download a build from ryujinx.app/download. Base projects fetch the translator source with their own scripts, such as TotK's `tools/build_xlate.py`.ryujinx.app read 2026-11-13 (MIT, source on a Forgejo server); the old GitHub repo returns 404; used by: Tera Recomp (gdb on Ryujinx), TotK family and FEFW (translator)
Zig and PyInstaller
Helpful both
Tools to package a release. PyInstaller freezes the Python lifter into one exe. zig cc is a small C compiler that builds the game code on the player's PC.
Path A
`pip install pyinstaller` and `pip install ziglang` in the project venv. LAS Recomp instead runs `make gen-helper` and `tools/fetch_zig.sh`.PyPI read 2026-11-13 (ziglang 0.17.1, pyinstaller 6.22.3); LAS README read 2026-11-13; used by: LAS Recomp, Savage Wind (PyInstaller and zig cc), KirbyRecomp (ziglang)
Vulkan SDK
Required both
Gives you Vulkan validation layers and spirv-val. Recomps use them to catch graphics mistakes and bad translated shaders.
Path A
Download the Windows installer from vulkan.lunarg.com (latest is 1.4.363.1).vulkan.lunarg.com/sdk/latest/windows.txt read 2026-11-13; used by: TotK, XC2, Tera, SuperWonders, Witch Time
llvm-mingw
Helpful Windows
A ready-made Clang toolchain for Windows in one zip. Some projects bundle it so players need no Visual Studio.
Path A
Download the `ucrt-x86_64` zip of release 20261104 and unzip it.README and release read 2026-11-13; used by: B2 Recomp, Witch Time, XC2 Recomp, SuperWonders
Linux build tools for matching (WSL)
Required WSL/Linux
The BotW-style decomp builds with CMake and Ninja, caches with ccache, and builds some tools with Rust. Install them inside WSL.
Path B
`sudo apt install python3 ninja-build cmake ccache xdelta3 clang libssl-dev pkg-config`, then `pip install cmake` for CMake 3.30 or newer, then `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`.botw.link installation page and rustup.rs read 2026-11-13 (CMake 3.30+, Python 3.12+; Ubuntu 24.04's CMake is too old); OdysseyDecomp README lists a similar apt line
nx-decomp-tools (viking and asm-differ)
Required WSL/Linux
The checker behind tools/check in Switch decomps. It compares your compiled function with the original and shows a diff.
Path B
Add it as a git submodule, then `git submodule update --init --recursive`. BotW's `tools/setup.py` builds the checker.repo file list read 2026-11-13 (MIT, holds viking and asm-differ); used by: BotW decomp, Odyssey decomp, ssbu-decomp
Clang (old upstream version)
Required both
The public compiler closest to the one that built your game. Matching depends on picking the right version.
Path B
Let your `tools/setup.py` download it, as BotW's does for Clang 4.0.1. On Windows, ssbu-decomp installs LLVM 8.0.0 (`LLVM-8.0.0-win64.exe` from releases.llvm.org) to `C:\llvm-8.0.0\`.botw.link installation page, ssbu-decomp README and releases.llvm.org/8.0.0 read 2026-11-13
objdiff
Helpful both
A diff tool for decomp projects with a window and a command-line version. It lists ARM64 for Switch.
Path B
Download `objdiff-windows-x86_64.exe` or `objdiff-cli-windows-x86_64.exe` from release v3.8.3.README and release v3.8.3 read 2026-11-13 (ARM64 Switch listed)

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.

reverse-engineer-anything (REA)

MCP server

B2 Recomp and Witch Time say AI did their reverse engineering with Ghidra and REA. TotK Recomp lists the REA skill too. Rated use with care: its fallback runs npx -y rea-agents@latest, which fetches the newest package.

`npx rea-agents setup` (needs Node.js 22, 24 or 26 and npm). It uses your Ghidra install. Its Windows Ghidra support is marked experimental. The matching skill is `npx skills add morluto/rea --skill reverse-engineer-anything -a claude-code`.

static-recomp-scope-plan

skills.sh

Makes you write down the exact game build, the scenes to test and the numbers to hit. That is your SCOPE.md for step 1.

`npx skills add bgyss/switchrecomp --skill static-recomp-scope-plan -a claude-code`

static-recomp-av-compare

skills.sh

Scores your port's video and sound against recordings you made of the real game. Each scene passes or fails. Needs ffmpeg and Python 3. It was written for Codex, so fix its script paths for Claude Code.

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

systematic-debugging

skills.sh

No fix until the cause is found. This is the same rule LAS Recomp's AGENTS.md sets for crashes.

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

verification-before-completion

skills.sh

Claude may not say done without fresh proof. On Switch, the proof is a screenshot, a log line or a tools/check result.

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

matcher and orchestrator

skills.sh

For Path B. One matches a single function with a try limit. The other runs workers in their own worktrees and merges only checked work. Describe tools/check in AGENTS.md first. They expect the original compiler. On Switch, tell them the public Clang is the stand-in. If the compiler is missing, the orchestrator points to Internet Archive, so say no to that.

`npx skills add lemiur/game-decompilation-skill-for-claude --skill matcher -a claude-code` and the same with `--skill orchestrator`. The matcher calls the other `lemiur` matching skills by name, so install those too.

ghidra-headless

skills.sh

Runs Ghidra with no window and saves functions and symbols to files. Useful for the function list without an MCP server. Install the Switch loader first.

`npx skills add trailofbits/skills-curated --skill ghidra-headless -a claude-code` (needs bash, such as Git Bash, on Windows, and you set `GHIDRA_HOME` yourself)

switch-scripted-run

write-your-own

Every Path A check needs a game run Claude can start alone. One skill keeps every run the same and keeps the user's real saves safe.

Make `.claude/skills/switch-scripted-run/SKILL.md`. It runs the build with a scratch save folder, an input script, a frame limit and a screenshot at frame N. It greps the log for crash lines and named markers, and returns pass or fail with the screenshot path. Copy the idea from LAS Recomp's `tools/shot.sh` and TotK Recomp's `tools/run_game.py`.

nx-match-one

write-your-own

Path B workers then all follow the same loop, with the same banned list ssbu-decomp's reviewer enforces.

Make `.claude/skills/nx-match-one/SKILL.md`. It takes one function name, runs `tools/check <name>`, allows 5 tries, bans inline assembly, naked functions and Ghidra names like `uVar1`, and updates the one CSV row. On failure it writes a `NON_MATCHING:` comment with the differing instructions.

Claude setup for this system

Path A units are one missing import, one crash, one shader family or one graphics bug. Each unit has a scripted run with a screenshot or log line as its check. Lifter changes are their own units and must pass the Unicorn test. Path B units are one function, or one source file for a worker in its own worktree. Keep each unit's notes in a numbered file so the next session can read them.

Which model and effort for each job

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

JobWhat it means on this systemMax 20x (now called Ultra)Max 5x (now called Max)
Plan the projectChoose the base project, the game version and the 64-bit check. For Path B, find the SDK version and pick the closest Clang.Fable 5.2
effort high
One session. This choice shapes months of work.
Opus 5.5
effort high
Use Fable 5.2 for this one session if you have weekly room.
Set up the projectFork the base, empty the old game's patches, set up MSYS2 or uv, and add the content check hook. For Path B, set up WSL, the submodule and tools/check.Opus 5.5
effort medium
Sonnet 5.5
effort medium
Study the game fileSurvey the ExeFS: modules, imports, SDK version and new features. For Path B, build the function list and type structs with sources.Opus 5.5
effort high
Opus 5.5
effort medium
Raise to high for function edges and data layouts. A mistake there spreads.
Build the runtimeAdd missing Horizon services, NVN calls and audio paths. Model the three-core scheduler if the game needs it.Opus 5.5
effort high
Opus 5.5
effort medium
Raise to high for timing and graphics bugs.
Find a bugFind one crash or glitch from logs, validation layers, crash addresses or an emulator run under gdb. Prove the cause before any fix.Opus 5.5
effort high
After two failed tries with full evidence, move to Fable 5.2.
Opus 5.5
effort high
One bug at a time.
Bulk unitsMany small units: missing imports with a known shape, shader translator gaps from the offline count, or small functions to match in Path B.Sonnet 5.5
effort medium
Haiku 5.5 for the plainest units.
Sonnet 5.5
effort medium
Fewer workers at once. Haiku 5.5 for the plainest units.
Hard unitsLifter bugs, jump tables, memory ordering, spin waits, and Path B functions that failed 5 tries.Fable 5.2
effort high
Go to xhigh only after a failed try at high.
Opus 5.5
effort high
Send only the last few that still fail to Fable 5.2.
Check the workA fresh session re-runs the scripted run or tools/check, reads the diff, and hunts for stubs, edited hashes or edits in generated/.Opus 5.5
effort medium
Always a new session, never the one that did the work.
Sonnet 5.5
effort high
Always a new session, never the one that did the work.
Keep the recordsUpdate notes/PROGRESS.md, the boot log, the import ledger and the numbered debug notes.Haiku 5.5
effort medium
Haiku 5.5
effort medium

How many sessions at once

Max 20x (now called Ultra)

Path A: one lead session plus 2 to 3 workers, each in its own worktree. Only one may run the game at a time, because test windows collide. Give the others reading, shader or offline work. Path B: one lead plus 4 to 6 workers on separate source files.

Max 5x (now called Max)

Path A: one session at a time, plus a subagent for long reads like logs or Ghidra output. Path B: one lead plus 2 workers. Save hard units for when your weekly limit resets.

Lines for this project's CLAUDE.md

Add to CLAUDE.md
- Read `SCOPE.md` and `notes/PROGRESS.md` before any work. Only the owner changes `SCOPE.md`.
- Generated C is never edited by hand. Change the generator in `recomp/` and regenerate.
- Every lifter change passes the Unicorn test: `<LIFTER_TEST_COMMAND>` must report 0 mismatches.
- Every patch asserts the original instruction word, so a wrong address or version fails loudly.
- Pass the keys file path to tools. Never print, log or copy key values.
- Game files, extracted data and generated code stay in `build/` and `generated/`. Run `python tools/check_content.py --staged` before proposing a commit.
- `refs/` and `tools/vendor/` are read-only. GPL code (yuzu, suyu): read for behavior, write our own.
- A fix counts only when seen working in a scripted run: paste the screenshot path or log line. A clean build is not proof.
- Find the cause first: the faulting address, the wrong value and who wrote it. A stub, clamp, retry or longer timeout needs a comment saying why.
- Never edit the game library ID or a hash file to get past a check. Regenerate and rebuild instead.
- After a build, check the exe's modified time. A failed link leaves the old exe in place.
- Use a scratch save folder for test runs. Never close a game the user is playing. One test window at a time.
- In a worktree, use absolute paths for the dump, `build/` and `generated/`.
- Record dead ends in `notes/PROGRESS.md`: what was checked and why it fell.
- Path B: no inline assembly, naked functions or forced `goto`. Keep a function `NON_MATCHING` instead.

Keep the context small

  • Never paste whole logs. Ask Claude to grep for the crash line and the 30 lines before it. TotK Recomp's agent docs say the same.
  • Point Claude at file plus function names, not line numbers. Upstream code in refs/ moves.
  • Keep AGENTS.md short. TotK, XC2 and Tera Recomp load it with one @AGENTS.md line in CLAUDE.md. An import still loads the whole file, so it saves no context.
  • Send Ghidra reading to a subagent and ask for a short report with addresses.
  • Start each unit with /clear. The notes files carry state, not the chat.
  • Forked docs often still describe the parent game. Tell Claude which docs are current.

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 learn if your game can be done and which base fits.

Prompt for Claude
GOAL: Tell me if <GAME> <VERSION> can be brought to PC by static recomp, and which existing Switch recomp to fork.
READ FIRST: `D:/dumps/<GAME>/exefs/main.npdm` (read only), the READMEs of LAS Recomp, TotK Recomp, ssbu-recomp and nxrecomp, the RecompLauncher entries for <GAME>.
FENCE: Write only `notes/feasibility.md` and a draft `SCOPE.md`. Do not clone or build anything.
CHECK: Run `hactool -t npdm --json=notes/npdm.json D:/dumps/<GAME>/exefs/main.npdm`. Done means the report states the `is_64_bit` value from that file, the build ID of `main`, any existing recomp or decomp of this game or engine with links, and one recommended base with its licence.
BUDGET: Stop after 60 minutes.
IF BLOCKED: Stop. Say what you could not confirm. Do not guess.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Each fact with its source. 3) Files written. 4) Risks, such as 32-bit code or a new engine. 5) New parking-lot items.

A good answer: A short report with the 64-bit flag, the build ID, links to prior work, one base choice with reasons, and a draft SCOPE.md.

Map the binary

After setup, to build the import ledger for Path A or the function list for Path B.

Prompt for Claude
GOAL: Build `notes/imports.csv` for <GAME>: every imported function, its module and whether the runtime handles it.
READ FIRST: `SCOPE.md`, `D:/dumps/<GAME>/exefs/` (read only), the runtime's handler table `<HANDLER_TABLE>`.
FENCE: Write only `tools/survey.py`, `notes/imports.csv` and `notes/survey.md`. No disassembly in any file.
CHECK: Run `python tools/survey.py D:/dumps/<GAME>/exefs`. Done means every import has a status and the totals in `notes/survey.md` match the script output.
BUDGET: Stop after 90 minutes or 3 failed runs.
IF BLOCKED: Stop. Paste the error.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Paste the totals. 3) Files written. 4) Top 10 missing imports. 5) New parking-lot items.

A good answer: A CSV with every import and a status, plus counts by namespace, the SDK version and a list of new features.

Unit loop: one crash (Path A)

For each crash or missing service during the grind.

Prompt for Claude
GOAL: Fix the crash at <CRASH_ADDRESS> seen when <WHAT_THE_PLAYER_DID>.
READ FIRST: `SCOPE.md`, `notes/boot-log.md`, `notes/debug/`, the last 50 lines of `<LOG_PATH>`.
FENCE: Edit only `runtime/` and `notes/`. Never edit `generated/`. Do not add a stub that returns success unless the cause is known and written in a comment.
CHECK: Run `<SCRIPTED_RUN_COMMAND>` before and after. Done means the after-run passes the crash point, the screenshot shows the next scene, and `<REGRESSION_COMMAND>` passes.
BUDGET: Stop after 2 refuted ideas or 90 minutes.
IF BLOCKED: Stop. List each check and what it ruled out.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Cause with evidence and before and after proof. 3) Files changed. 4) New boot-log row. 5) New parking-lot items.

A good answer: A named cause with an address and a value, a small fix in the runtime, before and after proof, and one new boot-log row.

Unit loop: one function (Path B)

For each function a worker matches.

Prompt for Claude
GOAL: Match <FUNCTION_NAME> at <ADDRESS> using the project's Clang.
READ FIRST: `SCOPE.md`, its row in `data/functions.csv`, `<HEADER_PATH>`, two matched functions in the same class as examples.
FENCE: Edit only `<SOURCE_FILE>`, `<HEADER_PATH>` and that one CSV row. No inline assembly, naked functions, forced `goto`, or raw Ghidra names like `uVar1`.
CHECK: Run `tools/check <FUNCTION_NAME>` then `tools/check`. Done means no difference for the function and `OK` for the whole project.
BUDGET: 5 meaningfully different tries.
IF BLOCKED: Stop. Mark the row `m` or `M`, add a `NON_MATCHING:` comment, and report the exact differing instructions.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Check output. 3) Files changed. 4) Tries made. 5) New parking-lot items.

A good answer: Either an empty diff with OK, or a clear NON_MATCHING mark with the differing instructions and what was tried.

Batch dispatch

As the lead session, to hand out the next set of units to workers.

Prompt for Claude
GOAL: Pick the next <N> units from <LEDGER_FILE> and start one worker per unit, each in its own worktree.
READ FIRST: `SCOPE.md`, <LEDGER_FILE>, `notes/claims.md`, `notes/PROGRESS.md`.
FENCE: You edit only `notes/claims.md` and `notes/PROGRESS.md`. Each worker edits only the files its unit names. Only one worker may run the game at a time.
CHECK: For each worker, re-run its check yourself: `<UNIT_CHECK_COMMAND>`. Done means every merged unit passes, and the full check `<FULL_CHECK_COMMAND>` passes on the main branch after merging.
BUDGET: Stop the round after <N> units or 3 hours.
IF BLOCKED: Stop that worker and move its unit to `notes/hard-queue.md` with the evidence.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) A table: unit, worker, result, proof line. 3) Branches merged. 4) Units sent to the hard queue. 5) New parking-lot items.

A good answer: A table of units with pass or fail and proof lines, a clean full check after the merge, and the hard queue updated.

Debug with evidence

When a glitch or hang has no clear cause yet.

Prompt for Claude
GOAL: Find the proven cause of <SYMPTOM>. Do not fix it yet.
READ FIRST: `SCOPE.md`, `notes/symptoms.md`, `notes/debug/`, `<LOG_PATH>`.
FENCE: Edit only `notes/debug/<NNN>.md` and temporary debug switches that you list. No fixes in this task.
CHECK: Order the work so the cheapest check that could disprove an idea runs first. Run `<SCRIPTED_RUN_COMMAND>` with your debug switches on, and paste the log lines that prove the cause. Done means `notes/debug/<NNN>.md` names the cause with an address, a value or a frame dump that proves it, and lists every disproved idea.
BUDGET: Stop after 3 disproved ideas or 2 hours.
IF BLOCKED: Stop. List the evidence you have and the one thing you need, such as an emulator run under `gdb`.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) The cause and its proof. 3) Disproved ideas. 4) Debug switches added. 5) New parking-lot items.

A good answer: A numbered debug note with one proven cause, the evidence, and each disproved idea with the check that killed it.

Verify and hunt for cheating

In a fresh session after any unit is reported DONE.

Prompt for Claude
GOAL: Check that the work on branch <BRANCH> is real.
READ FIRST: `SCOPE.md`, `CLAUDE.md`, the diff `git diff main...<BRANCH>`, the claimed proof in `<REPORT_FILE>`.
FENCE: Read only. Do not fix anything.
CHECK: Re-run `<CLAIMED_CHECK_COMMAND>` yourself. Then search the diff for edits in `generated/`, `tools/vendor/` or `refs/`, changed hash or ID files, new stubs that return success, disabled tests, skipped draws, inline assembly, and changes outside the task's files. Done means a pass or fail for each item with file and line.
BUDGET: Stop after 45 minutes.
IF BLOCKED: Stop. Say which check you could not run.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Your own check output. 3) A table of each cheat check with pass or fail. 4) What must be fixed before merge. 5) New parking-lot items.

A good answer: Fresh check output plus a pass or fail table. Any stub, edited hash or edit in generated/ is named with file and line.

Status report

Once a week, or before you decide what to do next.

Prompt for Claude
GOAL: Report project status with numbers only.
READ FIRST: `SCOPE.md`, `notes/PROGRESS.md`, `notes/imports.csv` or `data/functions.csv`, `notes/hard-queue.md`, `notes/parking-lot.md`.
FENCE: Read only, except `notes/status-<DATE>.md`.
CHECK: Every number comes from a command you ran now, such as `<COUNT_COMMAND>` and `<REGRESSION_COMMAND>`. Paste each command with its output.
BUDGET: Stop after 20 minutes.
IF BLOCKED: Stop. Say which ledger is missing or broken.
OTHER PROBLEMS: List new ones in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Milestone status against `SCOPE.md`. 3) Counts: imports handled, routes passing, or functions matched by status. 4) Top 3 blockers. 5) Parking-lot items for me to decide.

A good answer: A short page of numbers, each backed by a pasted command, with the milestone state and three blockers.

Session handoff

At the end of every session, so a new one can continue from files alone.

Prompt for Claude
GOAL: Write everything the next session needs into the ledger files.
READ FIRST: `notes/PROGRESS.md`, the current unit's notes, `git status`.
FENCE: Edit only `notes/PROGRESS.md` and the current unit's note file. No code changes.
CHECK: Run `git status` and `git diff --stat`, and paste both. Done means `notes/PROGRESS.md` has today's date, what works with proof, what does not, the leading idea, dead ends with reasons, temporary debug edits still in the code, and the exact next command to run.
BUDGET: 15 minutes.
IF BLOCKED: Stop. Say what you could not record.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) The new `notes/PROGRESS.md` section. 3) Files changed. 4) Uncommitted work. 5) New parking-lot items.

A good answer: A dated section that a fresh session can follow without the chat, ending with the next command to run.

Blocked or cannot deliver

When a unit keeps failing and you need a plain answer.

Prompt for Claude
GOAL: Tell me plainly whether <UNIT> can be done with what we have.
READ FIRST: `SCOPE.md`, every note about <UNIT> in `notes/`.
FENCE: Read only, except `notes/blocked-<UNIT>.md`.
CHECK: Run the unit's own check `<UNIT_CHECK_COMMAND>` one more time and paste the output. Done means the note says CAN, CANNOT or UNKNOWN, gives the evidence for that answer, and lists at most 3 options with a rough cost each.
BUDGET: 30 minutes.
IF BLOCKED: Say UNKNOWN and name the missing evidence.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) CAN, CANNOT or UNKNOWN in the first line. 3) Evidence. 4) Options. 5) What you need me to decide.

A good answer: One word answer first, then the evidence and a short list of options. No 'should work'.

Scope change request

When Claude finds a reason to work outside the fence, such as a lifter bug found during runtime work.

Prompt for Claude
GOAL: Ask me before leaving the fence of the current task.
READ FIRST: `SCOPE.md`, the current task card.
FENCE: Do not edit any file outside the current fence until I answer.
CHECK: Run `git status` and show that no file outside the fence has changed. Done means you wrote `notes/scope-request.md` with the file you want to change, why, the evidence, the risk, and the check that will prove it.
BUDGET: 10 minutes.
IF BLOCKED: Stop and wait for my answer.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) The request in five lines. 3) What you will do if I say no.

A good answer: A short request that names one file, the reason, the evidence and the check, then waits.

Keep Claude on task

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

The detourThe rule to give Claude
Claude edits the lifted C in generated/ to fix a bug fast.Generated C is never edited by hand. Change the generator and regenerate. Add a PreToolUse hook that blocks writes to generated/.
Claude makes a missing service return success so the game moves on.No stub without a known cause written in a comment. Register every simplified call in an audit list, as SSBU Recomp's tools/audit does.
Claude edits the game library ID or a hash file when the stale-build check fails.Never edit IDs, hashes or expected-output files. Regenerate and rebuild on a mismatch. Block those files with a hook.
Claude copies code from a GPL emulator like yuzu or suyu into an MIT project.Copy only MIT, BSD, ISC, zlib or Apache-2.0 code, keep its header and add a notice row. GPL code is read for behavior only.
Claude says a fix works because the build passed.A fix counts only when a scripted run shows it working. Paste the screenshot path or log line.
Claude keeps the old game's patches and addresses after a fork, or trusts docs that still describe the parent game.Empty the inherited patch list first. Every patch asserts its original instruction word. When a doc and the code disagree, report it in notes/parking-lot.md.
Claude prints prod.keys values or commits extracted game files.Pass the keys file path only. Run python tools/check_content.py --staged before any commit, and keep it as a pre-commit hook and in CI.
In Path B, Claude forces a match with inline assembly or naked functions.Banned. Keep the function NON_MATCHING with a comment, and let a review script reject these patterns before merge.
A forked repo's .claude/settings.json turns on a third-party plugin with hooks.Read any .claude/ folder and .mcp.json before you trust a forked repo. Remove what you did not choose.

Problems other projects hit

Jump tables are missed or cut a function in two. Witch Time's lifter took an adr target for a new function.

Fix: Add a rule for the pattern. Then test jump tables against Unicorn until there are 0 disagreements, as TotK's tests/jumptables_check.py does.

Seen in: Witch Time, TotK Recomp, XC2 Recomp

The game keeps data per core with no locks. Free-running PC threads crash or hang it.

Fix: Model Horizon's three cores, priority preemption and spin-wait gates in the runtime.

Seen in: TotK Recomp, XC2 Recomp

Clang moved a load out of a guest spin-wait loop, and the game hung at boot.

Fix: Put a compiler barrier on every backward branch in lifted code. Savage Wind found the function by splitting main in halves.

Seen in: Savage Wind Recomp

ARM ordering of stlr then ldar is lost in plain C11 code on x86, so wake-ups go missing between two threads.

Fix: TotK Recomp lists this as a known trap, but its docs do not say how it was fixed. Ask Claude to show how your base lifts stlr and ldar. If a thread misses a wake-up, suspect this first.

Seen in: TotK Recomp

The reference emulator can be wrong. Unicorn 2.1.4 gave 964 false failures on some signed atomic instructions.

Fix: When Unicorn and your lifter disagree, check the ARM manual before you change the lifter. Plant known bugs to test the test.

Seen in: FEFW Recomp

Lifting a 52 MiB main with two workers ran out of memory and the workers died.

Fix: Lift with --jobs 1, and leave huge functions unoptimized so one file does not take many minutes.

Seen in: Tera Recomp, B2 Recomp, SSBU Recomp

Antivirus removes the large unsigned game DLL built on the player's PC, or flags unsigned release files.

Fix: Tell players in the README and setup screen. Build into a writable folder that is not synced.

Seen in: SSBU Recomp, Savage Wind Recomp, Witch Time

A 32-bit game cannot go through an AArch64 lifter.

Fix: Check main.npdm first. MHGU Recomp wrote a new 32-bit lifter, which is a large extra job.

Seen in: MHGU Recomp, KirbyRecomp

WSL's own Vulkan driver could not create the renderer's pipeline layouts, and builds under /mnt/c were slow.

Fix: Run the game on Windows. If you build in WSL, keep the repo on the Linux side.

Seen in: MHGU Recomp, FEFW Recomp

A failed link leaves the old exe in place, so you test old code.

Fix: Check the exe's modified time after every build, or delete it before linking.

Seen in: TotK Recomp

Game logic counts per update, so high frame rates break it.

Fix: Keep the game's own tick. Make higher frame rates an opt-in setting and test them apart.

Seen in: Savage Wind Recomp, MHGU Recomp, KirbyRecomp, Metroid Dread Recomp

In Path B, public Clang differs from Nintendo's private compiler on big functions. ssbu-decomp got 0% instruction match on zstd built with Clang 8.0.0.

Fix: Match small functions first, measure progress by bytes, not just function count, and test the rest in the recomp.

Seen in: ssbu-decomp (outside the cards)

How long it takes

Max 20x (now called Ultra)Max 5x (now called Max)One person, no AIHow sure
Path A: running on PC3 to 10 weeks2 to 6 months6 to 24 monthsmedium confidence
Path B: full decomp1 to 3 years, and a full byte match may never be reached2 to 8 years10 to 30 yearslow confidence

Read this first

We assume one medium game and one person with 10 to 15 hours a week. Path A numbers come from many dated AI-assisted Switch projects. They agree on days to a first boot and weeks to a playable game. But none says how many hours people spent, and several hid earlier work. So confidence is medium. No Switch recomp was made without AI, so the no-AI number is a guess from PS1 data. Path B numbers are low confidence. No Switch decomp is finished, and the compiler gap may block a full match.

What makes it faster or slower

  • Whether a recomp exists for a game on the same engine. Forks reached a title screen in one or two days.
  • Code size. Big games mean long lifts and compiles, often 5 to 45 minutes per build.
  • How many new NVN calls and shader features your game uses that the base lacks.
  • Whether the game is 64-bit. A 32-bit game needs a new lifter.
  • For Path B, how close a public Clang is to the game's SDK compiler.

The facts behind these numbers

ProjectWhat happenedLink
LAS RecompOwn lifter, made almost entirely with Claude Code. First commit 2026-10-14, first release 2026-10-23. 12 contributors.source
SSBU RecompOwn lifter, almost all code by AI agents. First commit 2026-10-12, first release 2026-10-19. A full 1v1 match against the CPU runs, per its README. 8 contributors.source
TotK RecompBuilt from LAS Recomp and MacNativeGames. First commit 2026-10-23, first release 2026-10-29. 53 contributors.source
MHGU RecompFirst commit 2026-10-19. Reached the village one day later. First release 2026-10-29. 365 of 598 commits have a Claude trailer.source
Astral Chain RecompFork of TotK Recomp created 2026-11-02. First release 2026-11-03. Playable to the credits by 2026-11-13.source
ssbu-decompAI-assisted matching decomp, 1 contributor, 1,638 commits from 2026-03-30 to 2026-04-13. 26.22% of functions but only 1.78% of code bytes verified.source
BotW decompFirst commit 2020-06 (repo made 2020-08). 35 contributors over time. On 2026-11-13 it was 20.8% of code. 34.9% of non-library functions were decompiled, matching or not.source
OdysseyDecompRepo made 2021-07, with history back to 2020-07. 40 contributors. 15.77% of code matched on decomp.dev on 2026-11-13.source

Projects reviewed (15)

All 15 RecompLauncher Switch projects we reviewed: the top-starred project for each of the top 12 games, plus 3 the catalog flags as AI-made. The catalog lists 67 Switch projects for 46 games, and every one is a recomp or port. Path B evidence comes from three decomps outside RecompLauncher: BotW, Odyssey and ssbu-decomp.

What each project teaches

TotK Recomp

The Legend of Zelda: Tears of the Kingdom

Top rated on RecompLauncherstatic recompplayable
recomp/gen.pyMSYS2 clang/lldNinjauvhactoolRyujinx shader translator

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

AI: yes: README says most code and docs are written by Claude Code under the maintainer's direction Agent files: AGENTS.md, CLAUDE.md, docs/agents/running.md, docs/agents/debugging.md.

Lesson: Take the CPU half from one project and the game half from another, then write only the gap. Its agent docs are the best model on this system.

Savage Wind Recomp

The Legend of Zelda: Breath of the Wild

Top rated on RecompLauncherstatic recompplayable
tools/gen.pyCapstoneUnicornMSYS2 clang/lldzig ccGNU make

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

AI: yes: README says nearly all code, tooling and reverse engineering is by Claude through Claude Code Agent files: AGENTS.md.

Lesson: After forking a sister recomp, empty the old patch list first. Patches aimed at another game's addresses corrupt the output.

LAS Recomp

The Legend of Zelda: Link's Awakening

Top rated on RecompLauncherstatic recompplayable
tools/gen.pyCapstoneUnicornclang/lldzig ccGNU make

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

AI: yes: README says it was made almost exclusively with Claude through Claude Code Agent files: AGENTS.md.

Lesson: The root of most Switch recomps. Its rule that a fix counts only when seen in game stops false 'done' reports.

FEFW Recomp

Fire Emblem: Fortune's Weave

Top rated on RecompLauncherstatic recompplayable
nxrecompCapstoneUnicornclang-clCMakeNinja

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

AI: yes: 21 of 111 commits carry a Claude co-author trailer; the README does not say

Lesson: Test your tests. Its mutation check plants 22 lifter bugs and must catch them all. The first version caught only 4.

B2 Recomp

Bayonetta 2

Top rated on RecompLauncherstatic recompplayable
ssbu-recomp lifterllvm-mingwUnicornGhidraGhidra-Switch-LoaderREA

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

AI: yes: README says AI helped reverse engineer the game with Ghidra and REA

Lesson: Make the build one command with named steps that resume. A failure names its step, and the same command picks up again.

SSBU Recomp

Super Smash Bros. Ultimate

Top rated on RecompLauncherstatic recompplayable
own Python lifterUnicornCapstoneLLVM/clang 9.0.0lld-linkglslang

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

AI: yes: README says almost all code was written by Claude agents directed by one person who is not a reverse engineer

Lesson: A per-frame state hash log with scripted input shows exactly where a change broke the game. It also checks decompiled scripts against the lifted ones.

Sky Recomp

The Legend of Zelda: Skyward Sword HD

Top rated on RecompLauncherstatic recomprepo gone

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

AI: none stated (the catalog flag was set by the store; the repo could not be read)

Lesson: The repo returned 404 when we checked. A catalog entry can vanish, so do not build on a project you cannot read.

MHGU Recomp

Monster Hunter Generations Ultimate

Top rated on RecompLauncherstatic recompplayable
tools/gen.py with a 32-bit ARM lifterCapstoneUnicornMSYS2 clang/lldGNU makeshaderc

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

AI: yes: 365 of 598 commits carry a Claude co-author trailer; the README does not say

Lesson: A 32-bit game needed a new lifter but kept LAS Recomp's runtime. Its make test-lift runs after every lifter change.

Astral Chain Recomp

Astral Chain

Top rated on RecompLauncherstatic recompplayable
recomp/gen.pyMSYS2 clang/lldNinjauvhactoolRyujinx shader translator

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

AI: none stated (CONTRIBUTING.md welcomes AI-assisted code)

Lesson: A fork of TotK Recomp went from first commit to the credits in about 11 days. Its forked docs still describe TotK, so read with care.

Metroid Dread Recomp

Metroid Dread

Top rated on RecompLauncherstatic recompplayable
SwitchRecomp (MZ Labs)winlibs GCC 14.2.0Python 3.12glslangOpenGL 4.3Vulkan

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

AI: yes: README says large parts were written with Claude

Lesson: It fixes generated C without storing it: each patch holds the hash of the file, a line range and new lines. It has no stated lifter test.

Witch Time

Bayonetta 3

Top rated on RecompLauncherstatic recompplayable
wtbuild (Rust)clang/lldllvm-mingwGhidraGhidra-Switch-LoaderREA

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

AI: yes: NOTICE.md says AI helped reverse engineer the game with Ghidra and REA Agent files: .claude/settings.json, .claude/skills/README.md, .claude/skills/better-design/SKILL.md, .mcp.json.

Lesson: Measure the binary before lifting and compare it with the sister game. It also counts shader progress offline: 7,838 of 7,838.

XC2 Recomp

Xenoblade Chronicles 2

Top rated on RecompLauncherstatic recompin progress
recomp/gen.pyhactoolMSYS2 clang/lldNinjauvUnicorn

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

AI: yes: README says most code and docs are written by Claude Code under the maintainer's direction Agent files: AGENTS.md, CLAUDE.md.

Lesson: Its tools/worktree.py gives each agent task its own worktree and links the big ignored folders instead of copying them.

SuperWonders

Super Mario Bros. Wonder

Added: developer used AIstatic recompin progress
python -m recompCapstoneLLVM-MinGWCMakeNinjaRyujinx shader translator

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

AI: yes: README says AI tools were used extensively for code, scripts and docs

Lesson: Cut graphics at the NVN API, not at the GPU's command stream. Gate merges on a measured regression suite with set limits.

Tera Recomp

Pokemon Scarlet and Violet

Added: developer used AIstatic recompin progress
recomp/gen.pyhactoolMSYS2 clang/lldNinjauvUnicorn

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

AI: yes: the developer flagged AI use for code and art; its AGENTS.md is TotK Recomp's Agent files: AGENTS.md, CLAUDE.md.

Lesson: Keep a boot log as a table of Stop, Cause and Fix. When static reading failed, a debugger on an emulator found the missing object.

KirbyRecomp

Super Kirby Clash

Added: developer used AIstatic recompin progress
vendored LAS Recomp generatorCapstoneUnicornziglangVulkan 1.3SDL

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

AI: yes: the developer flagged AI use for code; the repo does not say how

Lesson: Changing the title ID is not enough to reuse a recomp. It lists every change from the base in PROVENANCE.md.

What we could not check

  • Sky Recomp's repo returned 404, so its tools, dates and AI use are unknown.
  • FEFW Recomp's README calls its game a Switch 2 title. The catalog files it under Switch.
  • The BotW docs define only m and M in the function list. The meaning of O, W, L and U was not confirmed.
  • The Clang version the Odyssey decomp uses was not found. Its setup downloads tools from a cache repo.
  • decomp.me handles Switch code, since BotW's docs give a tools/decompme script for it. Which Switch compilers decomp.me offers was not checked.
  • No command in this guide was run here. Each one comes from the tool's own docs or a project card. No game files were used.
  • How TotK Recomp fixed the stlr and ldar order problem is not in its docs.
  • The winget lines for the .NET SDK and Build Tools come from TotK's docs and the winget manual. They were not run here.
  • How to attach gdb to Ryujinx, as Tera Recomp did, was not checked.
  • No reviewed project says how many hours of human attention it took. The time ranges are estimates.
  • Several projects hide earlier history: Savage Wind squashed its imported history, and Metroid Dread's repo was made five weeks before its first commit.
  • The packages in the MSYS2 install line come from MHGU Recomp's README, not from a test run here. The TotK family needs a longer list.
  • The upstream SwitchRecomp (MZ Labs) and SwitchGamesRecomp repos are not linked from the projects that use them.

Sources