Skip to the page
It's Decomplicated
Nintendo, 2025

Nintendo Switch 2 decomp guide

Fork a working Switch 2 recomp, then fix shaders and crashes. A full decomp is barely started.

What this system is like

Switch 2 games run on a 64-bit ARM chip, like the first Switch. In the weeks around November 2026, people built native PC versions of nine Switch 2 games. Nearly all of them used static recompilation. A tool turns the game's machine code into C, and you write a stand-in for the console around it.

Most projects did not start from zero. They copied a Switch 1 recomp, such as TotK Recomp, and added the Switch 2 parts. Only three wrote their own lifter: Space Animals Recomp, Kart Recomp and TOoT:R. Later projects copied a Switch 2 recomp, such as DKB Recomp. One fork reached the title screen on its first day.

The new hard part is graphics. Switch 2 games use NVN 2, a new version of Nintendo's private graphics API. Their shaders are machine code for an NVIDIA Ampere chip. Many projects first convert them to the older Switch 1 shader code, then to Vulkan. Shaders that fail to convert are the most common blocker.

A full decomp is far off. We found one attempt, for Fire Emblem: Fortune's Weave. It checks behavior in an emulator and matches no bytes yet. Nobody has byte-matched any Switch 2 code. To match bytes you need the compiler version Nintendo used, and no project has named it yet.

Ampere shaders are the wall

Switch 1 shader tools only read the older Maxwell code. Many projects lower Ampere shaders to Maxwell with code from Eglantine, an emulator fork. Then a Ryujinx-based tool makes SPIR-V. A shader that will not lower can stop the game cold.

You fork, and the fork carries old baggage

Half of the 14 reviewed recomps copy TotK Recomp or DKB Recomp. The copy keeps old docs, old names and old settings. MTF ShadowRacket and yoshi4pc still ship Donkey Kong docs. Tell Claude which docs are current.

Newer ARM instructions

The CPU has new instructions, such as CAS, LDAPR and pointer signing (PAC). Lifters made for Switch 1 must learn them. Test each new kind against Unicorn, a CPU emulator. Run the old and new code side by side and compare.

Big memory and GPU faults

DKB Recomp commits about 14 GB of memory. Several projects need 16 GB of RAM plus a big page file. GPU 'device lost' crashes differ by vendor and driver. Plan for tests on more than one PC.

The game is built on the player's PC

No project ships game code. A launcher checks the player's dump by hash and builds the game locally. Shader translation can add one or two hours. Your build must refuse every other game version.

Path B has almost no prior art

One project, fefw, is decompiling a Switch 2 game. It gives credit only to code that behaves the same in an emulator. Nothing is byte-matched. You would be one of the first.

Two paths

Path A

Get it running on PC

You fork a working Switch 2 recomp and point it at your game. A Python lifter turns each ARM function into C or C++. A runtime stands in for Horizon OS and answers the NVN 2 calls with Vulkan. Shaders are lowered from Ampere to Maxwell and then turned into SPIR-V. You then fix one crash or glitch at a time.

Go to the steps

Path B

Full decomp for porting

You rewrite the game as readable C and C++, one function at a time. You cannot check bytes yet, because nobody knows which compiler version to use. So each rebuilt function runs next to the original in an emulator with the same inputs. Credit goes only to code that behaved the same. Library code comes from the exact upstream sources the game links.

Go to the steps

Path A: Get it running on PC

You fork a working Switch 2 recomp and point it at your game. A Python lifter turns each ARM function into C or C++. A runtime stands in for Horizon OS and answers the NVN 2 calls with Vulkan. Shaders are lowered from Ampere to Maxwell and then turned into SPIR-V. You then fix one crash or glitch at a time.

Method: static recompilation

Pick this first. It is how every playable Switch 2 project we read was made. Pick a base that already runs a game on the same engine if one exists.

  1. Pick the game, the version and a base

    You choose one exact game version and one recomp to fork. You note the hashes that prove the version. You look for a sibling project on the same engine. You write it all in SCOPE.md.

    • Dump your own game and update. Keep the .nup file outside the repo, for example in D:/dumps/<game>.
    • Write down the title ID and the update version. TOoT:R supports only update v131072. Most reviewed projects refuse any version they were not built for. Kart Recomp and MKW Recomp take two versions, 1.0.0 and 1.8.0.
    • Get the SHA-256 of exefs/main once it is extracted, with Get-FileHash. ocarina-recomp checks this hash before it builds.
    • Search RecompLauncher and GitHub for a recomp of a sibling game. Compare the engine, such as Unreal Engine 5 in Yoshi.
    • Choose a base family. DKB Recomp uses MSYS2 Clang, uv and Ninja. nxrecomp uses clang-cl, CMake and Ninja. Check each licence. DKB Recomp is GPL-3.0-or-later, nxrecomp is GPL-3.0 and TotK Recomp is MIT. NX2navi keeps its own changes all rights reserved, so you may read it but not copy it.
    • Write SCOPE.md: goal, version, hashes, base, first milestone and its check, what is out of scope, and files Claude must never edit.
    Prompt for Claude
    GOAL: Draft `SCOPE.md` for a static recomp of <GAME> update <VERSION> on Switch 2, and recommend one base project to fork.
    READ FIRST: The README and AGENTS.md of <BASE_A> and <BASE_B>, the hash list I give you in <HASH_FILE>, and `notes/prior-work.md` if it exists.
    FENCE: Write only `SCOPE.md` and `notes/scope-research.md`. Do not clone, build or change anything else. Never copy any game file into the repo.
    CHECK: Run `(Get-FileHash <DUMP_DIR>\exefs\main -Algorithm SHA256).Hash`. Done means it equals the hash in `SCOPE.md`, and `SCOPE.md` also names the title ID, the update version, the chosen base with its licence, and the first milestone with its check. Each number shows the command or file it came from.
    BUDGET: Stop after 45 minutes or 3 failed tries to read a file.
    IF BLOCKED: Stop. Do not guess a value. Tell me which 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 their sources. 3) Files written. 4) Open questions for me. 5) New parking-lot items.
    Done whenGet-FileHash on exefs\main gives the same SHA-256 that SCOPE.md lists. SCOPE.md also names the title ID, version, base, licence and first milestone, and you approved it.

    Proof this works: ocarina-recomp (hash gate on exefs main), TOoT:R (only update v131072 accepted), yoshi4pc and HWAoI (forks of DKB Recomp), Kart Recomp and MKW Recomp (versions 1.0.0 and 1.8.0), https://github.com/drakolordx7/nxrecomp, NX2navi README, License section

  2. Fork the base and set up the tools

    You fork the base and install its tools on Windows. You add the content guard so no game file is ever committed. You write CLAUDE.md and the progress files.

    • Install MSYS2 to C:\msys64. In the UCRT64 shell run pacman -Syuu twice. The first pass updates the core and exits.
    • Then run pacman -S --needed --noconfirm mingw-w64-ucrt-x86_64-{clang,lld,ninja,gcc,make,pkgconf,sdl3,opus,libvpx,zstd,vulkan-devel,vulkan-memory-allocator,vulkan-validation-layers,shaderc,spirv-tools} base-devel git unzip. This is the list in DKB's docs/building.md.
    • Install Visual Studio Build Tools with the C++ workload: winget id Microsoft.VisualStudio.BuildTools, with --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended. The shader translator's build calls its linker.
    • Add C:\Program Files (x86)\Microsoft Visual Studio\Installer to your PATH. The translator build needs vswhere.exe from there.
    • Install the .NET 10 SDK with winget install Microsoft.DotNet.SDK.10. The shader translator needs it.
    • Install Git for Windows with winget install Git.Git, as ocarina-recomp does, so git works in PowerShell.
    • Make the Python venvs: uv venv --python 3.12 .venv, then uv pip install --python .venv/Scripts/python.exe -r tools/requirements.txt. Do the same with --python 3.14, .venv-py314 and tools/requirements-py314.txt. The extract scripts need Python 3.14.
    • Run git config core.hooksPath .githooks so the content guard runs before each commit.
    • Put your dump and key paths in config.local.toml, which git ignores.
    • Build the shader translator: .venv/Scripts/python tools/build_xlate.py.
    • Copy the base's AGENTS.md. Add one line to CLAUDE.md: @AGENTS.md. Create notes/PROGRESS.md and notes/parking-lot.md.
    Prompt for Claude
    GOAL: Make the forked repo build its tools and pass the content guard on this PC.
    READ FIRST: `SCOPE.md`, `AGENTS.md`, `docs/building.md`, and the README section on building.
    FENCE: Edit only `config.local.toml`, `notes/`, `CLAUDE.md` and setup scripts under `tools/setup/`. Do not change `recomp/`, `runtime/` or `.github/`. Do not run the game.
    CHECK: `python tools/check_content.py` exits 0. `.venv/Scripts/python tools/build_xlate.py` ends with `build/xlate/totk_xlate.exe` present. On a DKB-line base, `.venv/Scripts/python tools/test.py --tier 0-1` shows no FAIL. Paste all outputs.
    BUDGET: Stop after 3 failed installs of the same tool, or 60 minutes.
    IF BLOCKED: Stop. Do not install a different tool version than `docs/building.md` names. Tell me what failed and the exact error.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: both outputs. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenpython tools/check_content.py exits 0, build/xlate/totk_xlate.exe exists, and tools/test.py --tier 0-1 shows no FAIL.

    Proof this works: DKB Recomp docs/building.md (toolchain table, pacman line, PATH notes, test tiers), ocarina-recomp (winget and pacman lists), yoshi4pc (two uv venvs, core.hooksPath), NX2navi (config.local.toml, build_xlate.py), DKB Recomp (check_content.py in CI)

  3. Survey the dump before you lift

    You extract the code and learn its shape first. You count modules, imports, NVN 2 calls and shaders. You find what the base does not support yet. This saves days of blind fixes later.

    • Extract the newest update from your .nup: .venv-py314/Scripts/python tools/extract_nup.py <game.nup> --select latest --pack --out build/extracted/<ver>.
    • If main is ZBIC-packed, unpack it. ocarina-recomp uses kinnay's zbic code for this.
    • Run a scan of imports, relocations, NVN 2 procs and SM86 shader opcodes. MTF ShadowRacket has tools/universal_ns2_to_pc.py scan --exefs <exefs> --romfs <romfs>.
    • Write the expected-hash file: .venv/Scripts/python tools/dkb_expected.py --exefs <exefs> --name <ver> --display <VERSION>.
    • Count the shader stages in the RomFS. DKB Recomp runs .venv/Scripts/python tools/dkb_shader_census.py --version <ver> --out build/<ver>. For its game that found about 18,800 stages.
    • Optional: open the module in Ghidra with the Switch loader to read code by address.
    • Save the results in notes/survey.md: modules with sizes, missing imports, new NVN 2 calls and the shader count.
    Prompt for Claude
    GOAL: Write `notes/survey.md` with the facts about <GAME> <VERSION> that the base does not cover yet.
    READ FIRST: `SCOPE.md`, `notes/PROGRESS.md`, the scan output in `build/scan/`, and `docs/architecture.md`.
    FENCE: Write only `notes/survey.md` and `tools/data/expected-<VER>.json`. Do not edit `recomp/` or `runtime/`. Never print key values.
    CHECK: `notes/survey.md` lists every module with its size and build ID, the imports the runtime lacks, the NVN 2 procs the runtime lacks, and the count of shader stages. Each list names the command that made it. Re-run each named command. Done means every count matches.
    BUDGET: Stop after 60 minutes or 3 failed tool runs.
    IF BLOCKED: Stop. Tell me which tool failed and the exact error.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) The counts. 3) Files written. 4) The three biggest gaps you see. 5) New parking-lot items.
    Done whennotes/survey.md lists modules, missing imports, missing NVN 2 calls and a shader count, each with the command that made it.

    Proof this works: MTF ShadowRacket (scan before init and build), yoshi4pc (extract_nup.py, expected hash manifest), DKB Recomp (dkb_expected.py), DKB Recomp docs/dkb-testing.md (dkb_shader_census.py), https://switchbrew.org/wiki/NSO

  4. Lift and link the whole game

    You run the lifter over every module and build the program. Nothing has to run yet. You only need a clean link and passing lifter tests. New instruction kinds get their own tests now.

    • Lift: .venv/Scripts/python recomp/gen.py --exefs <exefs> --out generated/<ver> --modules main,sdk --patches recomp/patches-<ver>.txt. That is DKB's line. If your game has subsdk0, add it to --modules, as ocarina-recomp does.
    • Build: .venv/Scripts/python tools/build_game.py --version <ver> --expected tools/data/expected-<ver>.json --exefs <exefs> --romfs build/extracted/<ver>/romfs.
    • Run the lifter's differential tests against Unicorn. On the DKB line they are tests/diff/simd.py, tests/diff/atomic.py, tests/diff/lift.py, tests/diff/func.py and tests/jumptables_check.py. Run each with .venv/Scripts/python. The last must report 0 disagreements.
    • For each new instruction kind, add a test first. yoshi4pc added tests/yoshi_udot_check.py with 400 cases for UDOT.
    • Put game-only fixes in the patch file, never in generated/. ocarina-recomp uses recomp/patches.py and tools/oot/patch_generated.py.
    Prompt for Claude
    GOAL: Lift all modules of <GAME> <VERSION> and link the exe with no errors.
    READ FIRST: `SCOPE.md`, `notes/survey.md`, `AGENTS.md`, and `recomp/README.md` if it exists.
    FENCE: Edit only `recomp/`, `tests/` and `recomp/patches-<VER>.txt`. Never edit `generated/` by hand. Do not touch `runtime/` in this task.
    CHECK: `tools/build_game.py --version <VER>` ends with the exe linked. Then run the Unicorn tests: on the DKB line `tests/diff/simd.py`, `tests/diff/atomic.py`, `tests/diff/lift.py`, `tests/diff/func.py` and `tests/jumptables_check.py`. Done means each passes and the last reports 0 disagreements. Paste the last 20 lines of each.
    BUDGET: Stop after 5 failed builds or 90 minutes.
    IF BLOCKED: Stop. Do not stub out an instruction to get a link. Tell me the instruction, the address and the error.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: both outputs. 3) Files changed. 4) New instruction kinds and their tests. 5) New parking-lot items.
    Done whenThe exe links, and the Unicorn lifter tests report 0 mismatches.

    Proof this works: DKB Recomp (gen.py and build_game.py commands in the README; Unicorn test list in docs/building.md), ocarina-recomp (--modules main,sdk,subsdk0), yoshi4pc (UDOT differential check), NX2navi (tests/diff, jumptables_check.py), Space Animals Recomp (Unicorn bench for every module)

  5. Boot to the first frame

    You run the game with no person at the controls. You fix the first crashes in order. You stop when a scripted run shows the first real picture. Count shader failures now, before you chase gameplay.

    • Run with input turned off so your keyboard does not move the game. ocarina-recomp uses TOTK_INPUT=none.
    • Start each run from an empty save folder. On the DKB line, set TOTK_PROFILE_DIR=<scratch folder>.
    • Save a picture with no person at the keys. On the DKB line, TOTK_DUMP=<frame> writes that frame's render targets as PNG files to dump\. Never publish them.
    • The DKB line has no single scripted-run command. Write tools/scripted_run.ps1 that sets these variables, starts the exe, waits, and copies the PNG and the last log lines. Kart Recomp's HOST_INPUT_SCRIPT and HOST_RENDER_HIDDEN show the same idea.
    • Read the log next to the exe. Fix the first crash only, then run again.
    • Check the NVN 2 API version the runtime reports. Ink Raiders crashed because it reported 30 and the game wanted 39 or higher. DKB Recomp has tests/nvn_version_test.py for this.
    • Count shader stages that fail to lower. yoshi4pc's tools/dkb_lower_test.cpp found 86 of 378 failing.
    • Save a screenshot from the scripted run in notes/boot-log.md, with the commit hash.
    Prompt for Claude
    GOAL: Make <GAME> boot to <FIRST_SCREEN> in a scripted run with no input.
    READ FIRST: `notes/PROGRESS.md`, `notes/boot-log.md`, the last run's log at <LOG_PATH>, and `docs/maxwell.md`.
    FENCE: Edit only `runtime/` and `recomp/patches-<VER>.txt`. Never edit `generated/`. Do not hide a draw or skip a shader to make a picture.
    CHECK: Run `<SCRIPTED_RUN_COMMAND>` (for example `tools/scripted_run.ps1`) with `TOTK_INPUT=none` and a fresh `TOTK_PROFILE_DIR`. Done means the saved frame shows <FIRST_SCREEN> and the log has no fatal line. Paste the screenshot path and the last 20 log lines.
    BUDGET: Stop after 5 runs with no new progress, or 2 hours.
    IF BLOCKED: Stop. Tell me the faulting address, the last log lines and what you ruled out.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: screenshot path and log lines. 3) Files changed. 4) The crash list in order. 5) New parking-lot items.
    Done whenA scripted run with no input saves a screenshot of the first real screen, and the log has no fatal line.

    Proof this works: ocarina-recomp (TOTK_INPUT=none), Project: Ink Raiders (NVN2 minor version 30 versus 39), yoshi4pc (title screen on day 1, shader census), Kart Recomp (HOST_INPUT_SCRIPT and HOST_RENDER_HIDDEN runs), DKB Recomp docs/dkb-testing.md (TOTK_PROFILE_DIR, TOTK_DUMP)

  6. Fix one crash or glitch at a time

    This is the long grind. Each unit is one crash, one missing call or one wrong picture. Prove the cause before the fix. Compare with a Switch 2 emulator that runs the game.

    • Capture a whole frame, then bisect by a stable shader hash. Program numbers change every launch, as MKW-THWOMP found.
    • Compare draws with a reference emulator. ocarina-recomp compared against Lichii's draw trace. DKB Recomp reads Eglantine first.
    • Fix shader bugs in the translator, not in the game. MKW-THWOMP traced phantom plants to badly translated culling shaders.
    • Re-run the Unicorn tests after any lifter change.
    • Write each dead end in notes/PROGRESS.md, like MKW-THWOMP's 'Do not repeat these' table.
    Prompt for Claude
    GOAL: Find and fix the cause of <BUG> seen at <PLACE_IN_GAME>.
    READ FIRST: `notes/PROGRESS.md` (dead ends), the capture at <CAPTURE_PATH>, `docs/maxwell.md`, and the matching code in the reference emulator under `refs/`.
    FENCE: Edit only <FILES_FOR_THIS_BUG>. `refs/` and `generated/` are read-only. Do not skip draws, drop resolution or turn off effects to hide the bug.
    CHECK: Run `<SCRIPTED_RUN_COMMAND>` to <PLACE_IN_GAME>. Done means the screenshot shows the fix and `<LIFTER_TEST_COMMAND>` still passes. Paste both.
    BUDGET: Stop after 3 failed fixes or 2 hours. Prove the cause before each fix.
    IF BLOCKED: Stop. Tell me the evidence you have, the causes you ruled out, and what you need.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: the cause with addresses, and screenshot paths. 3) Files changed. 4) Dead ends to record. 5) New parking-lot items.
    Done whenThe scripted run shows the fix, the lifter tests pass, and the cause is written in notes/PROGRESS.md.

    Proof this works: MKW-THWOMP (frame capture, bisect by shader hash, dead-end table), ocarina-recomp (Lichii draw trace), DKB Recomp (Eglantine as the reference), MKW Recomp (capture once, replay against the game's image)

  7. Build a regression set

    Old fixes must stay fixed. You save scripted runs, captures and tests that run without you. A fresh session can then check any change in minutes.

    • Record a frame capture once and replay it after each graphics change. MKW Recomp uses MKW_CAPTURE=1 and tools/test/replay.sh.
    • Keep three to five scripted runs that reach known places. Kart Recomp uses HOST_INPUT_SCRIPT with a hidden window.
    • Run Vulkan validation layers on each run and count the errors. DKB Recomp and HWAoI Recomp do validation-layer runs. Kart Recomp turns them on with HOST_VK_VALIDATION.
    • Make one test command. DKB Recomp has tools/test.py, which runs every check in tests/manifest.toml and writes build/test/runner/report.json.
    • Measure speed inside one run by switching settings back and forth. MKW Recomp found separate runs differ by up to 12 ms per frame.
    Prompt for Claude
    GOAL: Build `tools/regress` that runs <N> scripted runs, the frame replays and the lifter tests, and prints one PASS or FAIL line each.
    READ FIRST: `notes/PROGRESS.md`, `notes/boot-log.md`, and the input scripts in <SCRIPTS_DIR>.
    FENCE: Edit only `tools/regress*`, `tests/` and <SCRIPTS_DIR>. Do not change `runtime/` or `recomp/`. Do not lower any threshold to make a run pass.
    CHECK: `tools/regress` on a clean checkout prints PASS for every item. Then break one known fix on a scratch branch and confirm the matching item prints FAIL.
    BUDGET: Stop after 2 hours or 3 failed tries to make one item stable.
    IF BLOCKED: Stop. Tell me which item is flaky and what you saw.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: both outputs. 3) Files changed. 4) Items still flaky. 5) New parking-lot items.
    Done whentools/regress prints PASS on a clean checkout and FAIL when a known fix is reverted.

    Proof this works: MKW Recomp (capture replay, in-run A/B timing), Kart Recomp (scripted hidden-window races), DKB Recomp (tools/test.py, validation layers), HWAoI Recomp (validation-layer runs), GreenKid-MV (scripts/regress.py check --games in its agent rules)

  8. Package it without game code

    Players build the game from their own dump. You ship only your code and a launcher. The launcher checks the version by hash and gives a clear message if it is wrong.

    • Check the dump against your hash table before any work. Recompia checks exefs hashes against dump_hashes.json.
    • Let the launcher run the lift, compile and shader steps on the player's PC. NX2navi's setup takes 20 to 45 minutes once.
    • Cache compiled units so an update rebuilds only what changed. Recompia's rebuild_impact.py counts the units a change touches.
    • Run python tools/check_content.py --staged before every commit, and the same check in CI.
    • List every borrowed file and its licence in THIRD_PARTY_NOTICES.md.
    Prompt for Claude
    GOAL: Make a release zip that builds <GAME> from the player's own dump and contains no game data.
    READ FIRST: `SCOPE.md`, `tools/data/expected-<VER>.json`, `THIRD_PARTY_NOTICES.md`, and the base's installer docs.
    FENCE: Edit only `launcher/`, `installer/` and `tools/make_release*`. Do not add any file made from the game. Do not change `.github/` without asking me.
    CHECK: `python tools/check_content.py` passes on the repo. A file list of the zip shows nothing from `build/`, `generated/`, `dump/` or your game folder. A test install with a wrong-version dump stops with a clear message. A test install with the right dump reaches <FIRST_SCREEN>.
    BUDGET: Stop after 3 hours or 3 failed test installs.
    IF BLOCKED: Stop. Tell me what failed and the exact message.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: check output and both install results. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenThe content check passes, the zip holds no game-derived file, a wrong dump is refused, and a right dump builds and boots.

    Proof this works: Recompia (dump_hashes.json, rebuild_impact.py), NX2navi (launcher builds on the player's PC), Space Animals Recomp (checks the .nup by index hashes), GreenKid-MV (refuses game folders inside a git repo)

Path B: Full decomp for porting

You rewrite the game as readable C and C++, one function at a time. You cannot check bytes yet, because nobody knows which compiler version to use. So each rebuilt function runs next to the original in an emulator with the same inputs. Credit goes only to code that behaved the same. Library code comes from the exact upstream sources the game links.

Method: non-matching decompilation

Pick this after Path A works, or if you want readable source above all. Expect a long project with weaker proof than a byte match. Only one public Switch 2 project does this today.

  1. Check prior work and set the proof rule

    You check whether anyone has started your game. You accept that nobody can byte-match Switch 2 code yet. You write down exactly what earns credit. This rule is the heart of the project.

    • Search GitHub for your game name plus decomp. The only Switch 2 decomp we found is vexcited/fefw.
    • Read how fefw gives credit: only original instructions that the side-by-side runs used, with identical results.
    • Write the credit rule in SCOPE.md: which states are compared (registers, memory), how many random inputs, and what counts as used.
    • List the libraries the game links. fefw keeps PhysX 5.6.0, musl 1.1.19, Opus 1.3.1 and others as upstream sources.
    • Name what is out of scope, such as byte matching and shaders.
    Prompt for Claude
    GOAL: Draft `SCOPE.md` for a non-matching, behavior-verified decomp of <GAME> <VERSION>.
    READ FIRST: The fefw README at https://github.com/vexcited/fefw, `notes/survey.md` from Path A, and the string list in <STRINGS_FILE>.
    FENCE: Write only `SCOPE.md` and `notes/scope-research.md`. Do not create code. Never copy game files into the repo.
    CHECK: `SCOPE.md` states the credit rule in testable terms, lists each linked library with a version and the string or symbol that proves it, and names the first milestone with its check.
    BUDGET: Stop after 60 minutes.
    IF BLOCKED: Stop. Do not guess a library version. Tell me which ones you could not prove.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) The library list with proofs. 3) Files written. 4) Open questions for me. 5) New parking-lot items.
    Done whenSCOPE.md has a testable credit rule and a proven library list, and you approved it.

    Proof this works: fefw (behavior-verified credit, vendored libraries), https://github.com/vexcited/fefw

  2. Set up the repo and the AArch64 build in WSL

    You lay out the repo like fefw. You install a Clang that can build AArch64 code. You add the progress report so numbers come from a script, not from Claude.

    • In WSL (Ubuntu 24.04) run sudo apt install clang lld ninja-build python3-venv. Ubuntu 24.04 ships Clang 18.
    • Make the folders: src/game, src/<library>, include/, data/ledger/ and tools/.
    • Compile for the console's CPU with clang -target aarch64-unknown-linux-gnu -c <file>.c. Pick one target and keep it.
    • Set up the harness venv: python3 -m venv .venv, then .venv/bin/pip install unicorn capstone.
    • Download objdiff-cli-linux-x86_64 from objdiff release v3.8.3. Run sha256sum on it and compare with the digest GitHub lists for that file. Pin the hash in CI, as fefw's progress.yml does for v3.8.2.
    Prompt for Claude
    GOAL: Create the decomp repo layout, the AArch64 build and an empty progress report that runs.
    READ FIRST: `SCOPE.md`, and fefw's `.github/workflows/progress.yml` and `tools/objdiff_report.py`.
    FENCE: Edit only the new repo's `tools/`, `data/`, `CLAUDE.md` and build files. Keep all game files outside the repo. Do not write any game function yet.
    CHECK: `ninja` builds an empty object for AArch64 with no errors, and `python3 tools/report.py` prints 0.0% with the module sizes from `data/baseline.json`. Paste both.
    BUDGET: Stop after 90 minutes or 3 failed installs.
    IF BLOCKED: Stop. Tell me what failed and the exact error.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: both outputs. 3) Files created. 4) What is left. 5) New parking-lot items.
    Done whenThe empty AArch64 build passes and the report script prints 0.0% with correct module sizes.

    Proof this works: fefw (layout, progress.yml, sha256-pinned objdiff-cli), https://github.com/encounter/objdiff/releases/tag/v3.8.3, https://clang.llvm.org/docs/CrossCompilation.html, https://packages.ubuntu.com/noble/clang

  3. Build the function ledger

    You list every function with its address and size. You mark library and SDK code so nobody writes it by hand. The ledger is the single source of progress.

    • Load each module in Ghidra with the Switch loader, or as an ELF made by a tool like Kart Recomp's tools/nso.py.
    • Export one CSV per module: address,size,status,source,name. fefw keeps data/ledger/main.csv, rtld.csv, sdk.csv and subsdk0.csv to subsdk2.csv.
    • Write data/baseline.json with each module's text size and function count. fefw's main is 27,316,080 bytes and 89,170 functions.
    • Mark functions that belong to a known library. Match them by strings and symbols, not by guess.
    • Make the report refuse more credit than a module has. fefw's tools/ledger.py raises an error if it does. It also rejects unknown status values, duplicate rows, rows not 4-byte aligned, and rows with no name or source.
    • fefw's ledger.py is a library with a validate() function and no command line. Give yours a validate command, so python3 tools/ledger.py validate works as a check.
    Prompt for Claude
    GOAL: Produce `data/ledger/<MODULE>.csv` and `data/baseline.json` for <GAME> from the Ghidra export at <EXPORT_PATH>.
    READ FIRST: `SCOPE.md`, the export, and fefw's `tools/ledger.py` for the column rules.
    FENCE: Write only `data/` and `tools/ledger.py`. Do not edit `src/`. Do not copy disassembly into the repo.
    CHECK: `python3 tools/ledger.py validate` passes. Every address is 4-byte aligned. The size sum per module is at most the text size. Paste the output.
    BUDGET: Stop after 2 hours or 3 failed exports.
    IF BLOCKED: Stop. Tell me which module or range failed and why.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: validate output. 3) Counts per module and per library. 4) Ranges you are unsure of. 5) New parking-lot items.
    Done whentools/ledger.py validate passes and every function has a module, address, size and status.

    Proof this works: fefw (data/ledger CSVs, baseline.json, ledger.py checks), https://github.com/vexcited/fefw/blob/main/tools/ledger.py, NX2navi (Ghidra 12.1.2 with Ghidra-Switch-Loader), Kart Recomp (nso.py writes an ELF for Ghidra)

  4. Prove the harness on one small function

    You rebuild one tiny function and test it next to the original. Then you break it on purpose. The harness must catch the break, or it is not a check.

    • Write the harness: load the original module and your object in Unicorn, set the same random registers and memory, run both, compare.
    • Pick a short leaf function with no calls. Kart Recomp tested 2,481 integer leaf functions this way.
    • Run 1,000 random cases or more. Log which original instructions ran.
    • Change one operator in your C and confirm the harness fails. Space Animals Recomp mutated its output on purpose to prove its bench.
    • Watch for Unicorn bugs. Unicorn 2.1.4 compares some 8, 16 and 32-bit ldsmax and ldsmin results as unsigned.
    Prompt for Claude
    GOAL: Rebuild function <NAME> at <ADDRESS> in C and prove the harness passes it and fails a broken copy.
    READ FIRST: `SCOPE.md` (credit rule), `data/ledger/<MODULE>.csv`, and the Ghidra output for <ADDRESS> in <EXPORT_DIR>.
    FENCE: Edit only `src/game/<FILE>.c`, `tools/harness/` and `data/ledger/<MODULE>.csv`. No inline assembly. Do not edit `data/baseline.json`.
    CHECK: `tools/harness/run <NAME> --cases 1000` prints PASS. A copy with one operator changed prints FAIL. Paste both.
    BUDGET: Stop after 5 failed tries.
    IF BLOCKED: Stop. Tell me what differs: the register or address, and one failing input.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: both outputs. 3) Files changed. 4) Instructions covered by the runs. 5) New parking-lot items.
    Done whenThe harness passes the rebuilt function on 1,000 cases and fails the broken copy.

    Proof this works: Space Animals Recomp (Unicorn bench, mutation test, ldsmax note), Kart Recomp (leaf functions identical on every case), fefw (credit only for exercised instructions)

  5. Put library code in first

    Much of the binary is open-source libraries. You add their exact upstream sources, unchanged. Then you test those functions with the harness. This gives cheap, honest progress.

    • Add each library at the proven version under src/<library>, unchanged. fefw keeps musl 1.1.19 and libc++ 18.1.8 this way.
    • If a change is needed to match the shipped build, write it in src/<library>/MODIFIED.md.
    • Map each library function to its ledger row by symbol or string.
    • Run the harness on all library rows and credit only what passes.
    Prompt for Claude
    GOAL: Add <LIBRARY> <VERSION> under `src/<LIBRARY>` and credit the ledger rows that pass the harness.
    READ FIRST: `SCOPE.md` (library list and proofs), `data/ledger/<MODULE>.csv`, and the upstream release at <UPSTREAM_URL>.
    FENCE: Edit only `src/<LIBRARY>/` and the matching ledger rows. Keep upstream files byte-identical. Any change goes in `MODIFIED.md` with a reason.
    CHECK: `tools/harness/run --library <LIBRARY>` prints PASS or FAIL per function. Only PASS rows change status. `python3 tools/ledger.py validate` passes.
    BUDGET: Stop after 3 hours or when 20 functions in a row fail.
    IF BLOCKED: Stop. A run of failures may mean a wrong version. Tell me the evidence.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Pass and fail counts. 3) Files changed. 4) Suspect version issues. 5) New parking-lot items.
    Done whenThe library is in src/ unchanged or with MODIFIED.md, and only harness-passing rows are credited.

    Proof this works: fefw (15 vendored libraries, MODIFIED.md rule)

  6. Grind game functions in parallel

    Workers take one source file each, in their own worktree. Each function must pass the harness before it is credited. Hard ones go to a queue with notes.

    • Give each worker one file and its ledger rows. One writer per file.
    • Start with small leaf functions, then their callers.
    • Commit each passing function with its harness output in the message.
    • Mark doubtful rows disputed, as fefw does, instead of deleting them.
    • Send functions that fail five tries to notes/hard-queue.md with the failing input.
    Prompt for Claude
    GOAL: Rebuild the functions listed for `src/game/<FILE>.c` until each passes the harness or is queued as hard.
    READ FIRST: `CLAUDE.md`, the ledger rows for <FILE>, the Ghidra output in <EXPORT_DIR>, and three passing functions from nearby files.
    FENCE: Edit only `src/game/<FILE>.c`, its header in `include/game/`, and its ledger rows. No inline assembly. Work only in this worktree; use absolute paths for the dump.
    CHECK: `tools/harness/run --file <FILE>` prints PASS for each credited function. `python3 tools/ledger.py validate` passes.
    BUDGET: 5 tries per function. Stop the file after 3 hours.
    IF BLOCKED: Move the function to `notes/hard-queue.md` with one failing input. Do not weaken the harness.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Table: function, result, proof line. 3) Files changed. 4) Hard-queue items. 5) New parking-lot items.
    Done whenEvery function in the file passes the harness or sits in the hard queue, and the ledger validates.

    Proof this works: fefw (disputed status, per-function ledger), https://github.com/vexcited/fefw

  7. Verify the numbers from outside

    A score Claude reports is a claim. A fresh session re-runs the harness and reads the diffs. It hunts for cheats: weak tests, edited baselines and copied bytes.

    • Run the progress report in CI from the ledger, as fefw's progress.yml does.
    • Have a fresh session re-run the harness on a random 5% of credited rows.
    • Check that data/baseline.json and the harness did not change in worker branches.
    • Search for inline assembly and embedded byte arrays in src/game/.
    Prompt for Claude
    GOAL: Audit the last <N> credited functions and report any that do not truly pass.
    READ FIRST: `SCOPE.md` (credit rule), `git log` since <COMMIT>, and the ledger diff.
    FENCE: Read-only. Write only `notes/audit-<DATE>.md`. Do not fix anything.
    CHECK: Re-run `tools/harness/run` on each audited function. Done means a table of function, claimed result, re-run result, and any cheat found.
    BUDGET: Stop after 2 hours.
    IF BLOCKED: Stop. Tell me what you could not re-run.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) The table. 3) Files written. 4) Rows that should be `disputed`. 5) New parking-lot items.
    Done whenThe audit table shows every re-run result, and failed rows are marked disputed.

    Proof this works: fefw (CI progress report, disputed rows), ai-decomp-practice research, section C3 (cheats seen)

  8. Port: swap decompiled code into the recomp

    A decomp becomes a port by running it. The realistic route is your Path A build. Replace lifted functions with decompiled ones by name, a few at a time. The game must still pass the regression runs.

    • Use the runtime's replace-by-name hook. MKW Recomp replaces Nintendo SDK functions by name. ocarina-recomp keeps overrides in runtime/ov_*.c.
    • Swap in one source file at a time.
    • Run tools/regress from Path A after each swap.
    • When most game code is swapped, build for a new system. Fix 64-bit pointer and Windows long issues. Windows long is 32 bits.
    Prompt for Claude
    GOAL: Replace the lifted versions of the functions in `src/game/<FILE>.c` with the decompiled ones in the Path A build.
    READ FIRST: `notes/PROGRESS.md`, the runtime's override docs, and `tools/regress` output from the last good run.
    FENCE: Edit only the override list and the build files that add <FILE>. Never edit `generated/`. Do not change decompiled code to pass; report instead.
    CHECK: `tools/regress` prints PASS for every item with the swap in place. Paste it.
    BUDGET: Stop after 3 failed regress runs.
    IF BLOCKED: Stop. Tell me which item failed and which function you suspect, with evidence.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: regress output. 3) Files changed. 4) Functions that broke the game. 5) New parking-lot items.
    Done whentools/regress passes with the file's decompiled functions in place of the lifted ones.

    Proof this works: MKW Recomp (SDK functions replaced by name), ocarina-recomp (runtime/ov_*.c overrides, Windows long is 32 bits)

Tools you need

ToolWhat it doesHow to get itHow we know
DKB Recomp
Helpful Windows
A Switch 2 static recomp of Donkey Kong Bananza. It has the NVN 2 front end, Ampere shader lowering and movie support. Three reviewed projects forked it.
Path A
`git clone https://github.com/Lucas-blip-png/dkb-pc-recomp`, then follow its README section 'Building from source'.README and docs/building.md read 2026-11-13 (GPL-3.0-or-later; current release 0.3.0; default branch bananza); forked by HWAoI Recomp, yoshi4pc, MTF ShadowRacket
TotK Recomp
Helpful both
A Switch 1 recomp of Tears of the Kingdom. It is the root of the DKB line: lifter, Horizon host and Vulkan back end.
Path A
`git clone https://github.com/valentderah/totk-pc-recomp`, then read `docs/building.md`.README and release v0.4.0 read 2026-11-13 (MIT, Windows and Linux); base of DKB, ocarina-recomp, MKW Recomp, MKW-THWOMP
nxrecomp
Helpful Windows
A shared recompiler, runtime and tools, with one folder per game. Its README lists Nintendo Switch games. Recompia's Switch 2 Pokopia port uses its lifter.
Path A
`git clone https://github.com/drakolordx7/nxrecomp`. Needs VS Build Tools, LLVM clang-cl, CMake, Ninja, sccache, the Vulkan SDK, Python 3.13 with `uv`, and .NET 10.README read 2026-11-13 (GPL-3.0; layout now base/ and games/<id>/); used by: Recompia, pokopia-recomp
MSYS2 (UCRT64 with Clang, lld and Ninja)
Required Windows
A Unix-like shell and package manager for Windows. The DKB line builds the lifted C with its Clang.
Path A
Run `msys2-x86_64-20260927.exe` from msys2.org and install to `C:\msys64`. In the UCRT64 shell run `pacman -Syuu` twice, then `pacman -S --needed --noconfirm mingw-w64-ucrt-x86_64-{clang,lld,ninja,gcc,make,pkgconf,sdl3,opus,libvpx,zstd,vulkan-devel,vulkan-memory-allocator,vulkan-validation-layers,shaderc,spirv-tools} base-devel git unzip`.msys2.org read 2026-11-13; package line copied from DKB Recomp docs/building.md (read 2026-11-13); ocarina-recomp's list adds dav1d; used by: DKB, NX2navi, MTF, yoshi4pc, HWAoI, MKW-THWOMP
uv
Required both
A fast Python installer. It makes the venvs the build scripts run in.
Path A Path B
`powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"`Release 0.13.8 read 2026-11-13; used by: NX2navi, DKB, yoshi4pc, MKW Recomp, Recompia
.NET 10 SDK
Required both
Builds the Ryujinx-based shader translator that turns Maxwell shader code into SPIR-V.
Path A
`winget install Microsoft.DotNet.SDK.10`Download page read 2026-11-13 (SDK 10.0.1xx); winget line from ocarina-recomp and DKB's docs/building.md; used by: DKB, NX2navi, Kart, MKW-THWOMP, Recompia
Visual Studio Build Tools (C++ workload)
Required Windows
Microsoft's C++ compiler and linker without the full editor. The .NET shader translator build calls its linker. nxrecomp also builds with it.
Path A
winget id `Microsoft.VisualStudio.BuildTools` with `--add Microsoft.VisualStudio.Workload.VCTools --includeRecommended`. Then add `C:\Program Files (x86)\Microsoft Visual Studio\Installer` to PATH for `vswhere.exe`.DKB Recomp docs/building.md read 2026-11-13 (Build Tools 2026, C++ workload, Windows SDK 10.0.26100; vswhere PATH note); yoshi4pc README names VS 2026 C++ Build Tools; nxrecomp README lists Visual Studio Build Tools (C++)
Vulkan SDK
Required both
Headers, validation layers and shader tools such as spirv-dis and spirv-cross. You need them to debug the renderer.
Path A
`winget install KhronosGroup.VulkanSDK`, or 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; winget id from DKB Recomp docs/building.md (verified with 1.4.363); used by: nxrecomp, MKW-THWOMP, NX2navi, DKB
Unicorn
Required both
A CPU emulator you drive from Python. It runs original ARM code next to the lifted or rebuilt code, so you can compare results.
Path A Path B
`pip install unicorn` inside the project venv (2.1.4 is current).PyPI read 2026-11-13 (2.1.4, Windows wheels listed; repo GPL-2.0); used by 9 of the 14 static recomps here: NX2navi, DKB, ocarina, MTF, yoshi4pc, HWAoI, Space Animals, Kart, MKW Recomp
Capstone
Helpful both
A disassembler library. Lifters and scripts use it to decode ARM instructions.
Path A Path B
`pip install capstone` inside the project venv (5.0.9 is current).PyPI read 2026-11-13; used by: Kart Recomp, Space Animals Recomp, MKW Recomp
Ghidra
Helpful both
A free reverse engineering tool. It shows the game's code as assembly and rough C, by address.
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.Releases read 2026-11-13 (latest 12.2, 12.1.2 still listed); README at tag Ghidra_12.1.2_build says JDK 21 64-bit; DKB's docs/building.md also pairs 12.1.2 with JDK 21; used by: NX2navi, GreenKid-MV (analyzeHeadless)
Ghidra-Switch-Loader
Helpful both
A Ghidra add-on that opens Switch NSO and NRO files with the right layout.
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 release read 2026-11-13 (ISC); NX2navi lists Ghidra 12.1.2 with this loader
zbic
Helpful both
A Python package for ZBIC, the newer packing used in some NSO files. You need it if main will not load.
Path A Path B
`pip install zbic` inside the project venv. It gives `zbic.decompress(data)` and `zbic.compress(data)`.README and PyPI read 2026-11-13 (GPL-2.0; PyPI 1.0.1.post1 with Windows wheels); used by: ocarina-recomp, TOoT:R; switchbrew NSO page: flag bit 7 UseZbicCompression, zstd-based, firmware 22.0.0+
Lichii
Helpful both
An open-source Switch and Switch 2 emulator that calls itself experimental. Use it as a reference to compare draws and behavior.
Path A Path B
Download `lichii-windows-x86_64.zip` from the GitHub releases page only, extract all of it and run `lichii.exe`. Lichii has no official website, and one fake download site carried malware.README and release build-177 read 2026-11-13 (GPL-3.0); used by: ocarina-recomp (draw trace compare)
objdiff
Helpful both
A diff and progress tool for decomps. It supports ARM64. fefw runs objdiff-cli in CI for its progress report.
Path B
Download `objdiff-cli-windows-x86_64.exe` or `objdiff-cli-linux-x86_64` from release v3.8.3. Compare its SHA-256 with the digest GitHub lists for the file.README and release v3.8.3 read 2026-11-13 (ARM64 (Switch) listed; release assets carry sha256 digests); fefw pins v3.8.2 by SHA-256 in progress.yml
Clang and lld in WSL
Required WSL/Linux
Builds your decompiled C for the console's ARM CPU, so the harness can run it next to the original.
Path B
In WSL (Ubuntu 24.04): `sudo apt install clang lld ninja-build python3-venv`. Then compile with `clang -target aarch64-unknown-linux-gnu -c <file>.c`.Clang cross-compilation page and packages.ubuntu.com/noble/clang (1:18.0-59~exp2) read 2026-11-13; target triple form from that page

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

Lets Claude read functions, strings and cross-references from the game file through tools. ocarina-recomp ships this skill in .claude/skills. Most of its manual is about apps, not consoles. Use it with care: its fallback runs the newest rea-agents package from npm.

`npx rea-agents setup` (needs Node.js 22 or newer and npm). It can use your Ghidra install; its README calls Ghidra on Windows 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 define a correct port before work starts: the exact build, the scenes to test and the numbers to hit. That fits Step 1 of Path A. No skills.sh skill is made for Switch 2. This one and the others here are general.

`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 of the real game, scene by scene. It was written for Codex, so fix its script paths.

`npx skills add bgyss/switchrecomp --skill static-recomp-av-compare -a claude-code` (needs `ffmpeg` and your own recordings)

systematic-debugging

skills.sh

No fix until the cause is found. GPU faults on this system tempt Claude to skip draws. This skill pushes it to prove the cause first.

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

verification-before-completion

skills.sh

Claude may not say done without fresh proof. Here that means a screenshot path, a log line or a harness PASS.

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

handoff

skills.sh

Writes a short note so a fresh session can carry on. MKW-THWOMP and Ink Raiders kept handover files like this.

`npx skills add mattpocock/skills --skill handoff -a claude-code`. Tell it to save inside your repo, not the temp folder.

ghidra-headless

skills.sh

Runs Ghidra with no window and saves functions and code to files. Good for the Path B ledger without an MCP server.

`npx skills add trailofbits/skills-curated --skill ghidra-headless -a claude-code` (needs JDK 17 or newer and Git Bash on Windows; set `GHIDRA_HOME` yourself)

dispatching-parallel-agents

skills.sh

Shows the lead session how to brief workers and when not to split. Useful for Path B files and for offline shader work in Path A.

`npx skills add obra/superpowers --skill dispatching-parallel-agents -a claude-code`

ns2-scripted-run

write-your-own

Every Path A check is a scripted run. One skill makes them the same each time, as Kart Recomp's and Ink Raiders' scripted runs did.

Make `.claude/skills/ns2-scripted-run/SKILL.md`. It runs the exe with input off, an input script, a scratch save folder and a frame limit. It saves a screenshot and the last 30 log lines. It first checks that the exe is newer than the last build. It refuses to start if the game is already running.

ns2-shader-census

write-your-own

Shader gaps are the main blocker on Switch 2. yoshi4pc and DKB counted them offline before chasing gameplay.

Make `.claude/skills/ns2-shader-census/SKILL.md`. It runs the offline lowering test over all dumped shader stages. It prints a table of failures grouped by opcode, with a count for each. It never edits the translator.

ns2-behavior-check

write-your-own

Path B lives on this one check. A skill keeps every worker using the same rule and the same stop point.

Make `.claude/skills/ns2-behavior-check/SKILL.md`. It takes one function name and runs `tools/harness/run <name> --cases 1000`. It allows 5 tries, bans inline assembly and byte arrays, and updates the ledger row only on PASS.

Claude setup for this system

Path A units are one crash, one missing NVN 2 call, one shader group or one wrong picture. Each has a scripted run with a screenshot or log line as its check. Lifter changes are their own units and must pass the Unicorn tests. Path B units are one function, or one source file per worker. Keep notes in files 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 projectPick the base, the exact game version and its hashes. For Path B, write the credit rule and prove the library list.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, install MSYS2, uv and .NET 10, and add the content guard hook. For Path B, set up WSL, Clang and the harness.Opus 5.5
effort medium
Sonnet 5.5
effort medium
Study the game fileSurvey the dump: modules, imports, NVN 2 calls and shader counts. For Path B, build the function ledger and spot library code.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 2 calls, movie decoding and the thread scheduler. Fix memory and Vulkan back-end gaps.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, frame captures, validation layers or a Lichii compare. 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 lowering gaps from the census, or small Path B functions.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, new ARM instruction kinds, GPU device-lost faults, 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 the harness and reads the diff. It hunts for skipped draws, stubs, edited hashes and 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 dead-end table and the Path B ledger summary.Haiku 5.5
effort medium
Haiku 5.5
effort medium

How many sessions at once

Max 20x (now called Ultra)

Path A: one lead plus 2 to 3 workers, each in its own worktree. Only one may run the game at a time. Give the others offline work such as shader lowering or lifter tests. 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/` or the patch file, then regenerate.
- Every lifter change passes the Unicorn differential tests: `<LIFTER_TEST_COMMAND>` must report 0 mismatches. On the DKB line that means `tests/diff/*.py` and `tests/jumptables_check.py`.
- Pass the keys file path to tools. Never print, log or copy key values.
- Game files, extracted data, shaders 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. Cite upstream code by project, file and function, not line number.
- Do not hide a bug to clean a screenshot: no skipped draws, lower resolution or disabled effects.
- A fix counts only when seen in a scripted run: paste the screenshot path or log line. A clean build is not proof.
- Before you say a fix failed, compare the exe's modified time with the log's time.
- Ask before any long headless run or batch of screenshots. Never close a game the user is playing.
- Do not change `.github/` checks or tests to make them pass. Fix the code instead.
- In a worktree, use absolute paths for the dump, `build/` and `generated/`.
- Record dead ends in `notes/PROGRESS.md`: what was tried and why it failed.
- Report generation, compile, link, boot and play as separate milestones. Claim only the ones you saw.
- Path B: no inline assembly or byte arrays. Credit a function only after `tools/harness/run` prints PASS.

Keep the context small

  • Never paste whole logs. Ask Claude to find the crash line and the 30 lines before it.
  • Point Claude at file and function names, not line numbers. Code in refs/ moves, as DKB's agent rules warn.
  • Keep AGENTS.md short and load it from CLAUDE.md with one @AGENTS.md line, as DKB and NX2navi do.
  • Send Ghidra reading and shader dumps 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 describe the parent game. Tell Claude which docs are current, or delete the stale ones.

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 Switch 2 game is a good target and which base fits.

Prompt for Claude
GOAL: Tell me if <GAME> <VERSION> on Switch 2 can reach a first frame with a static recomp, and which base to fork.
READ FIRST: The RecompLauncher entries and GitHub repos I list in <LINKS_FILE>, and the READMEs of DKB Recomp and nxrecomp.
FENCE: Read only. Write only `notes/feasibility.md`. Do not clone or build anything.
CHECK: The note names any sibling project on the same engine, the base you pick, its licence, and the three biggest risks. Each claim has a link. Run `curl -sIL -o /dev/null -w "%{http_code}" <LINK>` on every link. Done means each prints 200.
BUDGET: Stop after 45 minutes.
IF BLOCKED: Stop. Say plainly if this game is not a good first target and why.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Yes, no or not yet, with reasons. 3) Files written. 4) What you need from me. 5) New parking-lot items.

A good answer: A short note that picks one base, names a sibling project if one exists, and lists real risks with links.

Map the binary

After extraction, to list what the base lacks for this game.

Prompt for Claude
GOAL: List the imports, NVN 2 procs and shader opcodes in <GAME> that the runtime does not handle yet.
READ FIRST: `notes/survey.md`, the scan output in `build/scan/`, and the runtime's import table at <IMPORT_TABLE_FILE>.
FENCE: Read only, except `notes/gaps.md`. Do not edit `runtime/`.
CHECK: `notes/gaps.md` has three tables with a count each. Every row names the module and the address or proc name. Re-run the scan command named in `notes/survey.md`. Done means its counts match the tables.
BUDGET: Stop after 60 minutes.
IF BLOCKED: Stop. Tell me which input file is missing.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) The three counts. 3) Files written. 4) The gaps you would fix first. 5) New parking-lot items.

A good answer: Three tables with counts and addresses, and a short order for fixing them.

Unit loop: one crash (Path A)

For each crash or glitch in the grind.

Prompt for Claude
GOAL: Fix crash <CRASH_ID> at address <ADDRESS> in <MODULE>.
READ FIRST: `notes/PROGRESS.md` (dead ends), the crash log at <LOG_PATH>, and Ghidra output for <ADDRESS>.
FENCE: Edit only `runtime/` and `recomp/patches-<VER>.txt`. Never edit `generated/`. No stub without the proven cause in a comment.
CHECK: `<SCRIPTED_RUN_COMMAND>` passes the place where it crashed, and `<LIFTER_TEST_COMMAND>` still passes. Paste the screenshot path and the log line.
BUDGET: Stop after 3 failed fixes or 90 minutes.
IF BLOCKED: Stop. Tell me the cause you suspect, the proof you have, and what you ruled out.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof. 3) Files changed. 4) Dead ends to record. 5) New parking-lot items.

A good answer: The proven cause with an address, a small fix, and a scripted run that now passes that spot.

Unit loop: one function (Path B)

For each function a worker rebuilds.

Prompt for Claude
GOAL: Rebuild <FUNCTION> at <ADDRESS> in `src/game/<FILE>.c` so it passes the harness.
READ FIRST: The ledger row, Ghidra output for <ADDRESS>, and two passing functions that call or are called by it.
FENCE: Edit only `src/game/<FILE>.c`, its header and its ledger row. No inline assembly or byte arrays. Do not edit the harness or `data/baseline.json`.
CHECK: `tools/harness/run <FUNCTION> --cases 1000` prints PASS. Paste it.
BUDGET: 5 tries.
IF BLOCKED: Add it to `notes/hard-queue.md` with one failing input and stop.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof. 3) Files changed. 4) Instructions the runs covered. 5) New parking-lot items.

A good answer: Readable C that passes 1,000 cases, with the ledger row updated and nothing else touched.

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` and `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: Re-run each worker's check yourself with `<UNIT_CHECK_COMMAND>`. Done means every merged unit passes, and `<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) 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 an updated hard queue.

Debug with evidence

When a GPU fault, a wrong picture or a hang has no clear cause.

Prompt for Claude
GOAL: Find the cause of <SYMPTOM> without changing any code.
READ FIRST: `notes/PROGRESS.md`, the frame capture at <CAPTURE_PATH>, the validation layer log at <VK_LOG>, and `docs/maxwell.md`.
FENCE: Read only. You may add logging on a scratch branch. Write findings only to `notes/debug-<ID>.md`.
CHECK: The note names the shader by stable hash or the function by address, shows the wrong value, and shows where it came from. Re-run `<SCRIPTED_RUN_COMMAND>` on the scratch branch. Done means the log shows the same wrong value at the place the note names. Compare with Lichii if it runs the scene.
BUDGET: Stop after 2 hours.
IF BLOCKED: Stop. List what you ruled out and the next test you would run.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) The cause with evidence. 3) Files written. 4) A proposed fix, not applied. 5) New parking-lot items.

A good answer: A cause tied to one shader hash or address, with captured values, and a fix proposal that waits for approval.

Verify and hunt for cheating

After any session claims DONE. Use a fresh session.

Prompt for Claude
GOAL: Check that the work in <BRANCH> is real and inside its fence.
READ FIRST: The task card for that work, `git diff <BASE>..<BRANCH>`, and its REPORT.
FENCE: Read only. Write only `notes/verify-<BRANCH>.md`. Do not fix anything.
CHECK: Re-run the card's check yourself. Search the diff for skipped draws, new stubs, edits in `generated/`, changed hash files, changed tests or CI, and lowered settings. Done means a pass or fail line for each.
BUDGET: Stop after 60 minutes.
IF BLOCKED: Stop. Tell me which check you could not run.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Your re-run output. 3) The cheat checklist with results. 4) Files outside the fence. 5) New parking-lot items.

A good answer: Your own re-run output, a checklist with no surprises, or a clear list of what was faked.

Status report

Once a week, or before you plan the next round.

Prompt for Claude
GOAL: Write a status report with numbers only from the ledger files and test output.
READ FIRST: `notes/PROGRESS.md`, `notes/boot-log.md`, the ledger in `data/ledger/` if any, and the last `tools/regress` output.
FENCE: Write only `notes/status-<DATE>.md`. Run only read-only commands and `tools/regress`.
CHECK: Every number in the report names the file or command it came from. No estimate is shown as a fact. Run `tools/regress` once more. Done means its PASS and FAIL lines match the report.
BUDGET: 30 minutes.
IF BLOCKED: Stop. Say which number you could not get.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Milestones reached, as separate lines. 3) Open bugs by count. 4) Top three risks. 5) New parking-lot items.

A good answer: A short page with sourced numbers, separate lines for boot and play, and no padding.

Session handoff

At the end of a session, or before your limit runs out.

Prompt for Claude
GOAL: Update the notes so a fresh session can continue without this chat.
READ FIRST: `notes/PROGRESS.md`, `git status` and `git log -5`.
FENCE: Edit only `notes/PROGRESS.md` and `notes/HANDOFF.md`. Do not change code.
CHECK: `notes/HANDOFF.md` lists the current task, the last check output, the files touched, the dead ends found today, and the next three steps. Every path is absolute. Run `git status --short`. Done means every changed file it lists is named in `notes/HANDOFF.md`.
BUDGET: 15 minutes.
IF BLOCKED: Stop. Tell me what you could not write down.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) The handoff text. 3) Files changed. 4) Uncommitted work. 5) New parking-lot items.

A good answer: A handoff file a new session can act on at once, with dead ends and exact paths.

Blocked or cannot deliver

When a unit keeps failing, or Claude seems stuck in a loop.

Prompt for Claude
GOAL: Give me a plain answer about <TASK>: can it be done now, and what would it take?
READ FIRST: `notes/PROGRESS.md`, `notes/hard-queue.md` and the last three reports on this task.
FENCE: Read only. Write only `notes/blocked-<ID>.md`.
CHECK: `Get-Content notes/blocked-<ID>.md -TotalCount 1` prints CAN, CANNOT or NOT YET. The note lists every option with its cost in sessions and what it needs from me.
BUDGET: 30 minutes.
IF BLOCKED: Say so in the first line and why.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) The one-word answer. 3) The options. 4) Your pick and why. 5) New parking-lot items.

A good answer: A one-word answer first, honest options, and no new attempt hidden inside the report.

Scope change request

When the work seems to need something outside the fence or SCOPE.md.

Prompt for Claude
GOAL: Ask me before you leave the fence for <TASK>.
READ FIRST: `SCOPE.md` and the task card you were given.
FENCE: Do not make the change. Write only `notes/scope-request-<ID>.md`.
CHECK: The request names the files or rules it would break, why the task needs it, the smallest change that would do, and how to check it.
BUDGET: 15 minutes.
IF BLOCKED: Stop and wait for my answer.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`.
REPORT: 1) BLOCKED until I answer. 2) The request. 3) Files written. 4) What you will do if I say no. 5) New parking-lot items.

A good answer: A small, clear request that waits for a yes or no. No change was made.

Keep Claude on task

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

The 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 recomp/ or the patch file and regenerate. Add a hook that blocks writes to generated/.
Claude skips a draw, drops resolution or turns off an effect so the screenshot looks right.Fidelity stays. Do not hide lights, skip draws, drop resolution or disable effects to clean a picture. MKW-THWOMP's handover says this.
Claude copies fixes or addresses from the parent game into your game.Do not reuse another game's address patches, save paths or shader hacks without proof. An unsupported path must fail visibly. HWAoI's AGENTS.md says this.
Claude makes CI green by changing the check.Do not change .github/ workflows, release checks or tests without owner permission. A failing check is fixed in the code. Recompia's AGENTS.md says this.
Claude reports 'playable' after a clean compile.Generation, compile, link, boot and play are separate milestones. Report only the ones you saw, with proof.
Claude starts the game or a batch of runs while you are playing, or uses your keyboard.Ask before any headless run, profile or screenshot batch. Use TOTK_INPUT=none. Never close a running game.
Claude reaches for an interpreter or GPU emulation when a fix is hard.No CPU interpreter, no JIT and no GPU emulation below NVN 2. If a fix seems to need one, it is the wrong fix. MKW Recomp's AGENTS.md says this.
Claude marks a Path B function verified when the harness only ran part of it.Credit only instructions the harness ran with identical results. Mark doubtful rows disputed, never delete them.

Problems other projects hit

Ampere shaders fail to lower to Maxwell, and the game aborts when a shader is rejected.

Fix: Run an offline census of all shader stages first. Fix lowering by opcode group. Do not return false from the shader setup call, because the game aborts.

Seen in: yoshi4pc, DKB Recomp

Vulkan 'device lost' crashes on some GPUs, often on instanced light quads.

Fix: Find the faulting shader and draw by stable hash. Keep any skip rule narrow. One broad skip rule also hid the whole 3D world.

Seen in: DKB Recomp, MKW-THWOMP, MTF ShadowRacket, MKW Recomp

The game needs about 14 GB of memory or more, so 16 GB PCs run out.

Fix: State 16 GB plus a large page file as the minimum, and 32 GB as comfortable. Run in handheld mode by default if docked mode grows images.

Seen in: DKB Recomp, ocarina-recomp, Project: Ink Raiders, NX2navi

Windows long is 32 bits, so 1L << 40 quietly dropped every indirect mesh draw for days.

Fix: Use fixed-size types such as uint64_t in runtime code. On Windows, long holds only 32 bits.

Seen in: ocarina-recomp

The .NET NativeAOT build fails at link when vswhere.exe is not on PATH, or a stray 32-bit cmake or ninja is picked up.

Fix: Put vswhere.exe on PATH. Call Ninja by its full path in C:/msys64/ucrt64/bin.

Seen in: NX2navi, ocarina-recomp, MTF ShadowRacket

Forked docs, env vars and branding still describe the parent game, which misleads Claude.

Fix: Delete or mark stale docs on day one. List the current docs in CLAUDE.md.

Seen in: MTF ShadowRacket, yoshi4pc, ocarina-recomp, HWAoI Recomp

The game's API version check fails, so a core object is never created and the game crashes later.

Fix: Check which NVN 2 API version the game asks for. Ink Raiders reported 30 when the game needed 39 or higher.

Seen in: Project: Ink Raiders

Separate runs differ by up to 12 ms per frame, so speed tests mislead.

Fix: Compare settings inside one run, switching every few seconds. Do not judge speed with tracing on.

Seen in: MKW Recomp, MKW-THWOMP, Project: Ink Raiders

A lifter or compile flag change forces every player to rebuild all units, up to an hour.

Fix: Measure the cost with a script like rebuild_impact.py and batch such changes into one release.

Seen in: Recompia, pokopia-recomp

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 monthslow confidence
Path B: full decomp6 months to 3 years, for behavior-verified code; nobody has a byte-matching setup yet1 to 6 years10 to 30 yearslow confidence

Read this first

We assume one medium game and one person with 10 to 15 hours a week. Where the history is visible, AI-assisted Switch 2 projects reached a first release 1 to 16 days after their first commit. The 1-day case, Recompia, built on a parent project. Most were teams of 15 to 37 people, or full-time work, on a working base. Kart Recomp was one person in 11 days, hours not stated. No project records hours, every project is under a month old, and only Space Animals reports a full playthrough. So Path A confidence is low. No Switch 2 project predates coding agents, so the no-AI numbers borrow from Switch 1. Path B rests on one project, fefw. It reports 73.6% behavior-verified after 12 days. That credit counts only code its emulator runs touched, and nobody else can re-run it. A readable decomp you can port needs much more, so our Path B range is far longer.

What makes it faster or slower

  • Whether a recomp exists for a game on the same engine. A fork of DKB Recomp reached a title screen on its first day.
  • How many shader stages fail to lower. yoshi4pc stalled on 86 of 378.
  • How many new NVN 2 calls, services and movie formats your game uses that the base lacks.
  • How many GPUs you can test on. Device-lost faults differ by vendor and driver.
  • For Path B, the size of the game. fefw's main alone has 89,170 functions.

The facts behind these numbers

ProjectWhat happenedLink
MKW RecompREADME: written with Claude doing most of the typing in about ten days of full-time work from 2026-10-30. The GitHub history starts 2026-11-09. First release 2026-11-09. 15 contributors.source
DKB RecompREADME: most code written by Claude Code. First commit 2026-10-23 on TotK history. First release 2026-11-08. 30 contributors.source
NX2naviFirst commit 2026-11-04. First release 2026-11-08. 37 contributors. CLAUDE.md and an AUDIT.md for agent sessions.source
RecompiaREADME: developed mainly with AI. First commit 2026-11-02. First GitHub release (v0.2.0) 2026-11-03. 17 contributors. It mirrors a parent project, pokopia-native, so not all of this work is its own.source
Space Animals RecompREADME: almost all code by Claude Code, one human. Work dated 2026-11-08, release 2026-11-10. The whole game finished several times.source
yoshi4pcFork of DKB Recomp created 2026-11-12. Title screen and menus the same day. Gameplay blocked by shader lowering.source
Kart RecompOne contributor and its own lifter. First commit 2026-11-01. First release 2026-11-12. AI use is a catalog flag only; hours not stated.source
fefwFirst commit 2026-11-02. 994 commits by 2026-11-14, one contributor. Commit message reports 73.6% behavior-verified, nothing byte-matched.source

Projects reviewed (18)

Every project we found. There are fewer than 10 games on RecompLauncher for Switch 2: 14 projects for 6 games. We added 4 projects from outside it, for 4 more games. That makes 10 games, with no spare. Two RecompLauncher repos are gone (404). Two other entries, pokopia-recomp and Recompia, now lead to the same repo.

What each project teaches

NX2navi

The Legend of Zelda: Ocarina of Time

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

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

AI: yes: catalog flag; CLAUDE.md imports AGENTS.md, and AUDIT.md tracks agent audit phases Agent files: AGENTS.md, CLAUDE.md, AUDIT.md.

Lesson: Borrow the CPU and host parts from Switch 1 ports, and test the lifter against Unicorn. A written GPU behavior guide, docs/maxwell.md, helps Claude read graphics bugs.

ocarina-recomp

The Legend of Zelda: Ocarina of Time

Lower rated on RecompLauncherstatic recompstalled
recomp/gen.pyMSYS2 Clang/lldNinjaRyujinx shader translatorEglantine loweringzbic

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

AI: yes: catalog flag; AGENTS.md and CLAUDE.md; ships the REA skill Agent files: AGENTS.md, CLAUDE.md, .claude/skills.

Lesson: Compare draws with a reference emulator and keep test runs free of your own input. Its Windows long bug shows how small type mistakes can hide for days.

DKB Recomp

Donkey Kong Bananza

Top rated on RecompLauncherstatic recompplayable
recomp/gen.pyMSYS2 ClangNinjaEglantine loweringRyujinx shader translatorUnicorn

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

AI: yes: README says most code and docs are written by Claude Code Agent files: AGENTS.md, CLAUDE.md.

Lesson: Fork the nearest working port and add only the Switch 2 parts. Its phase plan and dated devlog let others check each milestone.

Recompia

Pokemon Pokopia

Top rated on RecompLauncherstatic recompplayable
nxrecompclang-clCMakeNinjaZig.NET 10 shader translator

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

AI: yes: README says it is developed mainly with AI under human review Agent files: .claude/CLAUDE.md, AGENTS.md, PROJECT.md, GEMINI.md.

Lesson: Keep game facts out of shared code, and forbid agents from editing checks. One rule file serves every agent tool.

pokopia-recomp

Pokemon Pokopia

Lower rated on RecompLauncherstatic recompplayable
nxrecompZigLLVM.NET 10 shader translatorvcpkgTauri 2

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

AI: yes: README says it is developed mainly with AI under human review Agent files: .claude/CLAUDE.md, AGENTS.md, PROJECT.md, GEMINI.md.

Lesson: This catalog entry now redirects to Dittobyte/Recompia, so it is the same repo. Measure how many units a change forces players to rebuild before you merge it. Batch costly changes into one release.

MKW Recomp

Mario Kart World

Top rated on RecompLauncherstatic recompin progress
recomp/gen.pyown SM86 shader translatorclang/lldllvm-mingwuvUnicorn

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

AI: yes: README says Claude did most of the typing over about ten days Agent files: AGENTS.md.

Lesson: Capture frames once and replay them to test the renderer in seconds. Turn each mistake into a written rule with a script that checks it.

Pokopia Recomp

Pokopia

Lower rated on RecompLauncherotherrepo gone

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

AI: none stated

Lesson: The repo is gone (404), so nothing can be learned from its code. Keep your own copy of anything you build on.

Space Animals Recomp

Star Fox

Top rated on RecompLauncherstatic recompplayable
own recomp/a64GCC 16.2glslangUnicorn benchCapstoneVulkan 1.3

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

AI: yes: README says nearly all code is written by Claude through Claude Code, directed by one person

Lesson: Prove your test bench first by breaking the code on purpose. One person with Claude Code built a new recompiler and finished the game this way.

GreenKid-MV

The Legend of Zelda: Ocarina of Time

Lower rated on RecompLauncherotherin progress
nxnativeNVN-on-MetalRyujinx shader translatorSPIRV-CrossXcode 27.2Ghidra headless

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

AI: yes: catalog flag; inherited AGENTS.md; upstream commits credit Claude Code and Codex Agent files: AGENTS.md.

Lesson: On an ARM Mac the game code can run natively with small rewrites. Pin the engine version and key every patch to the NSO build ID.

Kart Recomp

Mario Kart World

Lower rated on RecompLauncherstatic recompplayable
tools/lift.pyCapstoneLLVM MinGWRyujinx-derived shader translatorUnicorn difftest

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

AI: yes: catalog flag only; the repo says nothing

Lesson: LLVM MinGW compiled the main module in 5 minutes against 46 with MSVC. Scripted hidden-window runs let an agent test without a person.

HWAoI Recomp

Hyrule Warriors: Age of Imprisonment

Top rated on RecompLauncherstatic recompin progress
recomp/gen.pyclang/lldNinjatotk_xlateEglantine loweringhactool

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

AI: yes: catalog flag; AGENTS.md and CLAUDE.md Agent files: AGENTS.md, docs/upstream/AGENTS.md, docs/upstream/CLAUDE.md.

Lesson: Pin the forked base commit and refuse any other game build. Report generation, linking, boot and play as separate milestones.

MKW-THWOMP

Mario Kart World

Lower rated on RecompLauncherstatic recompin progress
recomp/ (LAS Recomp)MSYS2 clangninjapatched Ryujinx shader translatorspirv-crossframe capture tools

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

AI: yes: catalog flag; HANDOVER.md has a section written by Claude Agent files: HANDOVER.md.

Lesson: A handover file with a table of failed attempts stops the next session from repeating them. Bisect render bugs by stable shader hash.

TOoT:R

The Legend of Zelda: Ocarina of Time

Lower rated on RecompLauncherstatic recompplayable
own recompilerdynarmic decoderEden shader recompilersiritCMakeclang/lld

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

AI: yes: catalog flag only

Lesson: Build the game code once into a library, so runtime-only changes rebuild in minutes. Give host threads a 16 MiB stack on Windows.

Sacred Forest

The Legend of Zelda: Ocarina of Time

Lower rated on RecompLauncherotherrepo gone

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

AI: none stated

Lesson: The repo is gone (404). The catalog says it built on Hookshot, which is also gone now.

yoshi4pc

Yoshi and the Mysterious Book

From outside RecompLauncherstatic recompin progress
recomp/gen.pyMSYS2 clang/lld/ninjatotk_xlateEglantine loweringUnicorn

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

AI: none stated; has AGENTS.md and CLAUDE.md from DKB Agent files: AGENTS.md, CLAUDE.md.

Lesson: A fork reached the title screen in a day, then stalled on 86 shaders that will not lower. Count shader failures before you plan gameplay.

MTF ShadowRacket

Mario Tennis Fever

From outside RecompLauncherstatic recompplayable
recomp/gen.pyuniversal_ns2_to_pc.pyMSYS2 clang/lldninjaNativeAOT shader translatorEglantine lowering

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

AI: yes: AGENTS.md and CLAUDE.md, plus an AI prompting playbook; no catalog flag Agent files: AGENTS.md, CLAUDE.md, docs/UNIVERSAL_NS2_TO_PC_PLAYBOOK.md.

Lesson: Scan the dump before lifting so Claude works from facts. Keep one shared runtime and flag game quirks by title ID.

Project: Ink Raiders

Splatoon Raiders

From outside RecompLauncherstatic recompplayable
nxrecomp-style lifterVS 2022 Build Tools with ClangCMakeNinja.NET shader translatorTauri launcher

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

AI: yes: HANDOFF.md notes a Claude Code session; the README does not say Agent files: HANDOFF.md, PORT_STATUS.md.

Lesson: A numbered milestone log let sessions resume fast. Check the NVN 2 API version the game expects before you chase a crash.

fefw

Fire Emblem: Fortune's Weave

From outside RecompLaunchernon-matching decompin progress
objdiff-cli v3.8.2tools/objdiff_report.pytools/ledger.pyunnamed emulator

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

AI: none stated

Lesson: The only Switch 2 decomp we found. It credits code by behavior in an emulator and keeps a per-function ledger. Nobody can re-run its check without the game.

What we could not check

  • The original compiler and its version. The libc++ 18.1.8 and 21.1.8 headers in fefw are only a hint.
  • The .nup container format. We found no switchbrew page for it.
  • Whether Ghidra-Switch-Loader opens ZBIC-packed NSO files. Its README does not say.
  • The Path B toolchain in this guide (WSL Clang with an AArch64 target and a Unicorn harness) is our suggestion. fefw does not publish its build or name its emulator.
  • fefw's 73.6% figure comes from its commit messages. It cannot be re-run without the game.
  • Playability claims are the authors' own. We did not run any of these games.
  • Hookshot and pokopia-native returned 404 on 2026-11-13. What we say about them comes from the review cards.
  • The 16 MiB stack fact for TOoT:R comes from the review card's reading of its CMake file.
  • Swapping decompiled game functions into a recomp by name (Path B, last step) is our suggestion. The reviewed projects only replace SDK functions this way.
  • No project records how many hours of human work it took. Our time ranges are estimates from dates.
  • The no-AI time ranges borrow from Switch 1 and other systems, because no Switch 2 project predates agents.
  • No step in this guide was run here. Commands come from the projects' READMEs and docs, read on 2026-11-13.
  • The Unicorn test list, tools/test.py and the knobs TOTK_PROFILE_DIR and TOTK_DUMP come from DKB Recomp's docs. Forks such as yoshi4pc may have changed them.
  • tools/scripted_run.ps1 is our suggestion. DKB Recomp's docs name no single scripted-run command.
  • Whether the Ampere census in yoshi4pc (tools/dkb_lower_test.cpp) and DKB's dkb_shader_census.py count the same thing was not checked.
  • Stars come from the catalog on 2026-11-13. Live counts have since moved a little.

Sources