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
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.
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.
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.
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
.nupfile outside the repo, for example inD:/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/mainonce it is extracted, withGet-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,
uvand 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 ClaudeGOAL: 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-FileHashonexefs\maingives the same SHA-256 thatSCOPE.mdlists.SCOPE.mdalso 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
- Dump your own game and update. Keep the
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.mdand the progress files.- Install MSYS2 to
C:\msys64. In the UCRT64 shell runpacman -Syuutwice. 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'sdocs/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\Installerto your PATH. The translator build needsvswhere.exefrom 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, sogitworks in PowerShell. - Make the Python venvs:
uv venv --python 3.12 .venv, thenuv pip install --python .venv/Scripts/python.exe -r tools/requirements.txt. Do the same with--python 3.14,.venv-py314andtools/requirements-py314.txt. The extract scripts need Python 3.14. - Run
git config core.hooksPath .githooksso 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 toCLAUDE.md:@AGENTS.md. Createnotes/PROGRESS.mdandnotes/parking-lot.md.
Prompt for ClaudeGOAL: 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.pyexits 0,build/xlate/totk_xlate.exeexists, andtools/test.py --tier 0-1shows 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)
- Install MSYS2 to
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
mainis ZBIC-packed, unpack it. ocarina-recomp uses kinnay'szbiccode 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 ClaudeGOAL: 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.mdlists 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
- Extract the newest update from your
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 hassubsdk0, 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.pyandtests/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.pywith 400 cases for UDOT. - Put game-only fixes in the patch file, never in
generated/. ocarina-recomp usesrecomp/patches.pyandtools/oot/patch_generated.py.
Prompt for ClaudeGOAL: 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)
- Lift:
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 todump\. Never publish them. - The DKB line has no single scripted-run command. Write
tools/scripted_run.ps1that sets these variables, starts the exe, waits, and copies the PNG and the last log lines. Kart Recomp'sHOST_INPUT_SCRIPTandHOST_RENDER_HIDDENshow 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.pyfor this. - Count shader stages that fail to lower. yoshi4pc's
tools/dkb_lower_test.cppfound 86 of 378 failing. - Save a screenshot from the scripted run in
notes/boot-log.md, with the commit hash.
Prompt for ClaudeGOAL: 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)
- Run with input turned off so your keyboard does not move the game. ocarina-recomp uses
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 ClaudeGOAL: 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 innotes/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)
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=1andtools/test/replay.sh. - Keep three to five scripted runs that reach known places. Kart Recomp uses
HOST_INPUT_SCRIPTwith 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 intests/manifest.tomland writesbuild/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 ClaudeGOAL: 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/regressprints 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)
- Record a frame capture once and replay it after each graphics change. MKW Recomp uses
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
exefshashes againstdump_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.pycounts the units a change touches. - Run
python tools/check_content.py --stagedbefore every commit, and the same check in CI. - List every borrowed file and its licence in
THIRD_PARTY_NOTICES.md.
Prompt for ClaudeGOAL: 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)
- Check the dump against your hash table before any work. Recompia checks
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.
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 isvexcited/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 ClaudeGOAL: 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.mdhas 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
- Search GitHub for your game name plus
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/andtools/. - 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_64from objdiff release v3.8.3. Runsha256sumon it and compare with the digest GitHub lists for that file. Pin the hash in CI, as fefw'sprogress.ymldoes for v3.8.2.
Prompt for ClaudeGOAL: 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
- In WSL (Ubuntu 24.04) run
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 keepsdata/ledger/main.csv,rtld.csv,sdk.csvandsubsdk0.csvtosubsdk2.csv. - Write
data/baseline.jsonwith 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.pyraises 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.pyis a library with avalidate()function and no command line. Give yours avalidatecommand, sopython3 tools/ledger.py validateworks as a check.
Prompt for ClaudeGOAL: 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 validatepasses 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)
- Load each module in Ghidra with the Switch loader, or as an ELF made by a tool like Kart Recomp's
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
ldsmaxandldsminresults as unsigned.
Prompt for ClaudeGOAL: 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)
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 ClaudeGOAL: 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 insrc/unchanged or withMODIFIED.md, and only harness-passing rows are credited.Proof this works: fefw (15 vendored libraries, MODIFIED.md rule)
- Add each library at the proven version under
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.mdwith the failing input.
Prompt for ClaudeGOAL: 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
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.ymldoes. - Have a fresh session re-run the harness on a random 5% of credited rows.
- Check that
data/baseline.jsonand the harness did not change in worker branches. - Search for inline assembly and embedded byte arrays in
src/game/.
Prompt for ClaudeGOAL: 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 markeddisputed.Proof this works: fefw (CI progress report, disputed rows), ai-decomp-practice research, section C3 (cheats seen)
- Run the progress report in CI from the ledger, as fefw's
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/regressfrom Path A after each swap. - When most game code is swapped, build for a new system. Fix 64-bit pointer and Windows
longissues. Windowslongis 32 bits.
Prompt for ClaudeGOAL: 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/regresspasses 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)
- Use the runtime's replace-by-name hook. MKW Recomp replaces Nintendo SDK functions by name. ocarina-recomp keeps overrides in
Tools you need
| Tool | What it does | How to get it | How 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)
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
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
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
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
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
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
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
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
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
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
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.
| Job | What it means on this system | Max 20x (now called Ultra) | Max 5x (now called Max) |
|---|---|---|---|
| Plan the project | Pick 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 highOne session. This choice shapes months of work. | Opus 5.5 effort highUse Fable 5.2 for this one session if you have weekly room. |
| Set up the project | Fork 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 file | Survey 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 mediumRaise to high for function edges and data layouts. A mistake there spreads. |
| Build the runtime | Add 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 mediumRaise to high for timing and graphics bugs. |
| Find a bug | Find one crash or glitch from logs, frame captures, validation layers or a Lichii compare. Prove the cause before any fix. | Opus 5.5 effort highAfter two failed tries with full evidence, move to Fable 5.2. | Opus 5.5 effort highOne bug at a time. |
| Bulk units | Many small units: missing imports with a known shape, shader lowering gaps from the census, or small Path B functions. | Sonnet 5.5 effort mediumHaiku 5.5 for the plainest units. | Sonnet 5.5 effort mediumFewer workers at once. Haiku 5.5 for the plainest units. |
| Hard units | Lifter bugs, new ARM instruction kinds, GPU device-lost faults, and Path B functions that failed 5 tries. | Fable 5.2 effort highGo to xhigh only after a failed try at high. | Opus 5.5 effort highSend only the last few that still fail to Fable 5.2. |
| Check the work | A 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 mediumAlways a new session, never the one that did the work. | Sonnet 5.5 effort highAlways a new session, never the one that did the work. |
| Keep the records | Update 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
- 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.mdshort and load it fromCLAUDE.mdwith one@AGENTS.mdline, 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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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 detour | The 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 AI | How sure | |
|---|---|---|---|---|
| Path A: running on PC | 3 to 10 weeks | 2 to 6 months | 6 to 24 months | low confidence |
| Path B: full decomp | 6 months to 3 years, for behavior-verified code; nobody has a byte-matching setup yet | 1 to 6 years | 10 to 30 years | low 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
mainalone has 89,170 functions.
The facts behind these numbers
| Project | What happened | Link |
|---|---|---|
| MKW Recomp | README: 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 Recomp | README: most code written by Claude Code. First commit 2026-10-23 on TotK history. First release 2026-11-08. 30 contributors. | source |
| NX2navi | First commit 2026-11-04. First release 2026-11-08. 37 contributors. CLAUDE.md and an AUDIT.md for agent sessions. | source |
| Recompia | README: 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 Recomp | README: almost all code by Claude Code, one human. Work dated 2026-11-08, release 2026-11-10. The whole game finished several times. | source |
| yoshi4pc | Fork of DKB Recomp created 2026-11-12. Title screen and menus the same day. Gameplay blocked by shader lowering. | source |
| Kart Recomp | One 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 |
| fefw | First 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
.nupcontainer 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.pyand the knobsTOTK_PROFILE_DIRandTOTK_DUMPcome from DKB Recomp's docs. Forks such as yoshi4pc may have changed them. tools/scripted_run.ps1is 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'sdkb_shader_census.pycount the same thing was not checked. - Stars come from the catalog on 2026-11-13. Live counts have since moved a little.
Sources
- DKB Recomp README
- DKB Recomp: building from source (toolchain, pacman line, checks)
- DKB Recomp: testing guide (shader census, run settings)
- yoshi4pc README (venvs, extract_nup.py, shader blocker)
- MTF ShadowRacket README (scan, init, build)
- fefw ledger checks (tools/ledger.py)
- zbic on PyPI
- Visual Studio Build Tools
- TotK Recomp README
- nxrecomp README
- MKW Recomp README
- NX2navi README
- fefw README, CI and ledger
- Switchbrew: NSO
- Switchbrew: Switch 2 Tegra T239
- Tom's Hardware: Switch 2 SoC die shot
- Lichii README and releases
- Eden emulator
- eden-nx2 fork
- Ghidra-Switch-Loader
- objdiff README
- Clang cross-compilation
- Ubuntu 24.04 clang package
- Unicorn on PyPI
- zbic
- REA
- Vulkan SDK