Skip to the page
It's Decomplicated
Nintendo, 2011

Nintendo 3DS decomp guide

A ready recompiler boots many games in a day. A full decomp is a huge C++ job.

What this system is like

The 3DS is the newest hot spot for PC ports. Nine of the ten projects we read use static recompilation. A tool reads the game's ARM code and writes C. A runtime then stands in for the console. Four projects simply reused one free pair of tools: 3dsrecomp and Zakuro.

That pair changes the job. With it, Shin Megami Tensei IV reached its title screen on day one. Fire Emblem: Awakening had a release three days after its first commit. Your work is mostly the last mile: missed functions, runtime bugs, PC features and long play tests.

A full decomp is a different story. Games are big C++ programs built with ARM's own compiler, armcc. Several matching projects started in late 2026, some run by AI agents. The furthest, for Monster Hunter 4 Ultimate, had 82% of its functions matched but only 44% of its code bytes. No 3DS game is fully decompiled yet, and none has been ported from a decomp.

Almost all of this runs on Windows. You need your own game, dumped and decrypted on a modded 3DS with GodMode9. The dump and anything made from it never go in your repo.

A ready recompiler and runtime

3dsrecomp turns ARM code into C. Zakuro stands in for the console: kernel, services, GPU and sound. Code the recompiler misses still runs in Zakuro's interpreter. So a game can play before every function is found. Both tools call themselves a work in progress, and Zakuro lists the games it was tested on in COMPATIBILITY.md.

Code hides in modules

Many games load extra code from .cro files, like Windows DLLs. Function finders must read those too. Some functions are only reached through a pointer in data. Those need a hint or a seed file by hand.

Two screens and a touch panel

The top screen is 400 by 240 pixels, and there is a touch screen below. Most PC work on the 3DS is about layout: one screen, widescreen and a HUD that moves. DekUI and Dragon Quest VIII spent most of their own work there. MSR2DS built a one-screen layout too.

One region, one build

Each region and each update is different code. Every project we read supports one exact build and checks its hash. Pick your version first and never mix dumps.

Big C++ games for Path B

3DS games are large C++ programs. A Link Between Worlds has 25,986 functions. Pokemon Ultra Sun has 61,471. The compiler is ARM's armcc, which is not free. Matching is possible, but the hard tail is long.

Two paths

Path A

Get it running on PC

The game's ARM code is turned into C ahead of time and compiled for the PC. A runtime replaces the kernel, services, GPU and sound. On the 3DS you rarely write those yourself: 3dsrecomp and Zakuro already exist. Your job is scope, checks, missed code, runtime bugs and PC features.

Go to the steps

Path B

Full decomp for porting

You write C++ that armcc turns into the game's exact bytes, one function at a time. A judge script compares each function. Then you link the whole code.bin and compare its hash. Several AI-driven projects began in 2026. None is finished, and none has been ported yet.

Go to the steps

Path A: Get it running on PC

The game's ARM code is turned into C ahead of time and compiled for the PC. A runtime replaces the kernel, services, GPU and sound. On the 3DS you rarely write those yourself: 3dsrecomp and Zakuro already exist. Your job is scope, checks, missed code, runtime bugs and PC features.

Method: static recompilation

Pick this first for almost every game. Four of the ten projects we read got playable this way within days of their first commit.

  1. Scope the game and pick one exact build

    Pick one game, one region and one revision. Dump and decrypt your own card. Look for prior work, because a game may already run on Zakuro. Write it all in SCOPE.md.

    • GodMode9 runs only on a 3DS with custom firmware. Its README sends you to 3ds.hacks.guide or fastboot3DS for that setup.
    • Dump your card on a modded 3DS with GodMode9: [C:] GAMECART, then Dump cart (trimmed), then Decrypt file if needed.
    • Hash the dump in PowerShell: Get-FileHash <GAME>.3ds -Algorithm SHA256.
    • Check COMPATIBILITY.md in the Zakuro repo and the RecompLauncher list for your game.
    • Search GitHub for <GAME> recomp and <GAME> decomp. Note the title ID and region of each hit.
    • Write SCOPE.md: game, region, title ID, SHA-256, goal, technique, first milestone and its check.
    • Make empty files PROGRESS.md and notes/parking-lot.md.
    Prompt for Claude
    GOAL: Write a one-page `SCOPE.md` for a static recomp of <GAME> (<REGION>, title ID <TITLE_ID>, SHA-256 <HASH>).
    READ FIRST: `notes/prior-work.md` (my search results), the `Zakuro` `COMPATIBILITY.md`, the RecompLauncher entry if any. Do not open the dump.
    FENCE: Edit only `SCOPE.md` and `notes/prior-work.md`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `Select-String -Path SCOPE.md -Pattern '^#'`. `SCOPE.md` must have these headings: Goal, Dump and hash, Technique, Prior work, Milestone 1 and its check, Out of scope, Never edit. Done means every heading has real content and every prior-work claim has a URL.
    BUDGET: Stop after 30 minutes or 3 drafts.
    IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenSCOPE.md has all seven headings filled, and you approved it.

    Proof this works: Shin Megami Tensei IV Recomp, Fire Emblem: Awakening for Windows, https://github.com/watchmakerers/clockwork

  2. Set up the tools and the repo

    Install Rust, a C compiler and the two upstream tools. Pin them to exact versions. Lay out a repo that holds only your own code. Add the one check command and CLAUDE.md.

    • Install Rust with the installer from rustup.rs, then run rustup default stable-x86_64-pc-windows-gnu. The MSVC toolchain failed for Shin Megami Tensei IV. The 3dsrecomp port doc says MSVC Rust needs LLVM clang and llvm-ar instead.
    • Install MinGW gcc: winget install BrechtSanders.WinLibs.POSIX.UCRT, or MSYS2 with pacman -S mingw-w64-ucrt-x86_64-gcc.
    • Install the tools at a fixed commit: cargo install --git https://github.com/fearkov/3dsrecomp --rev <COMMIT> --locked --features verify recomp3ds and cargo install --git https://github.com/fearkov/zakuro --rev <COMMIT> --locked zakuro. Cargo puts 3dsrecomp and zakuro in ~/.cargo/bin.
    • Write the commit of each tool into SCOPE.md. Awakening pinned 3dsrecomp at 9db0d8b and Zakuro at 80d78be.
    • Make folders dump/, out/, logs/ and add them to .gitignore. Put your dump outside the repo or in dump/.
    • Write tools/check.ps1. It rebuilds and runs the boot probe from step 5. Run it as powershell -NoProfile -ExecutionPolicy Bypass -File tools/check.ps1, so the script policy cannot block it. Write CLAUDE.md from the list in this guide.
    Prompt for Claude
    GOAL: Set up the repo for <GAME> so one command builds the recompiled code and one command runs the check.
    READ FIRST: `SCOPE.md`, the `3dsrecomp` README and `docs/port.md`, the `Zakuro` README.
    FENCE: Edit only `tools/`, `.gitignore`, `CLAUDE.md`, `PROGRESS.md` and `README.md`. Never copy the dump or anything made from it into the repo. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `3dsrecomp` with no arguments, `zakuro --help`, then `git status --ignored`. Done means the first prints its `usage, 3dsrecomp analyze` lines, the second prints its options, the pinned commits are in `SCOPE.md`, and `dump/` and `out/` show as ignored.
    BUDGET: Stop after 45 minutes or 3 failed installs.
    IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenBoth tools print their usage text in a fresh terminal, their commits are written down, and git status --ignored shows dump/ and out/ ignored.

    Proof this works: Shin Megami Tensei IV Recomp, Fire Emblem: Awakening for Windows, https://github.com/fearkov/3dsrecomp

  3. Map the game: coverage, modules and services

    Find out how much code the recompiler finds before you build. List the CRO modules and the services the game uses. This sets your risks. Save it as a ledger file.

    • Run 3dsrecomp analyze <path>\<GAME>.3ds and save the output to logs/analyze.txt.
    • Unpack the code with ctrtool --exefsdir=out/exefs --romfsdir=out/romfs --exheader=out/exheader.bin <GAME>.3ds.
    • Save the file info: ctrtool -i <GAME>.3ds > logs/info.txt. The ExHeader in it lists the services the game may call.
    • List the .cro files in out/romfs/cro/, if there are any.
    • Optional: load the game in Ghidra with a CTR loader, which reads CXI and CRO files. The loader is untested; see the tools list.
    • Write notes/ledger.csv with columns: id, kind (crash, hang, missing call, gfx), address, status, proof.
    Prompt for Claude
    GOAL: Write `notes/map.md` and an empty `notes/ledger.csv` for <GAME> from the recompiler's analysis.
    READ FIRST: `logs/analyze.txt`, the file list of `out/romfs/cro/`, `logs/info.txt` (the output of `ctrtool -i`).
    FENCE: Edit only `notes/map.md` and `notes/ledger.csv`. Do not run a build. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `3dsrecomp analyze <GAME>.3ds` again and compare its numbers with the note. Done means `notes/map.md` gives the code coverage percent from `analyze`, the count of CRO modules, and the list of services from the ExHeader, each with the command that produced it.
    BUDGET: Stop after 30 minutes.
    IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whennotes/map.md holds the coverage percent, the module count and the service list, each with its source command.

    Proof this works: https://github.com/watchmakerers/clockwork/blob/master/docs/PHASE0.md, Shin Megami Tensei IV Recomp, MSR2DS

  4. First light: build and boot to the title screen

    Run the recompiler over the whole game and start it in Zakuro. The first build is slow, often 10 to 25 minutes. The goal is one picture: the title screen.

    • Run 3dsrecomp build <GAME>.3ds out/recomp. Save the output to logs/build.txt.
    • Start the game with zakuro <GAME>.3ds --recompiled out/recomp --data test/. --data keeps test saves out of your own.
    • If you want a program of your own, run 3dsrecomp port <GAME>.3ds <DIR>, then cargo build --release inside <DIR>. After you update 3dsrecomp, run cargo update -p zakuro there first.
    • On Windows, a ported program may need a bigger main stack. Dragon Quest VIII asked the linker for 8 MiB.
    • Run a smoke test with no window: zakuro <GAME>.3ds --recompiled out/recomp --data test/ --headless 1800. It runs 1,800 frames, then prints a report.
    • Take a screenshot of the title screen and save it in logs/.
    Prompt for Claude
    GOAL: Build <GAME> with `3dsrecomp` and boot it in `Zakuro` to the title screen.
    READ FIRST: `SCOPE.md`, `notes/map.md`, the `3dsrecomp` README.
    FENCE: Edit only `tools/` and `logs/`. Never edit the generated C in `out/recomp/`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `zakuro <GAME>.3ds --recompiled out/recomp --data test/ --headless 1800`. Done means it prints `Completed after 1800 frames` and no `fatal errors:` line, and a title-screen screenshot is saved in `logs/`.
    BUDGET: Stop after 3 failed builds. A build takes up to 25 minutes, so do not rebuild without a new reason.
    IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenzakuro <GAME>.3ds --recompiled out/recomp --data test/ --headless 1800 prints Completed after 1800 frames with no fatal errors: line, and a title-screen screenshot from the recompiled build is in logs/.

    Proof this works: Shin Megami Tensei IV Recomp, Fire Emblem Fates Special Edition Recomp, Dragon Quest VIII 3DS Recomp, https://github.com/fearkov/zakuro/blob/main/crates/zakuro/src/cli.rs

  5. Build golden runs that need no person

    Make the check run by itself. A boot probe starts the game, presses keys on a timer, saves a picture and stops. Now Claude can test without you at the controller.

    • Write tools/boot_probe.py. It starts the game with a time limit, for example --seconds 15, and saves the log.
    • Give the test its own data folder with --data test/. Never use the folder you play from.
    • Record the keys once: set ZAKURO_RECORD=test/inputs/<RUN>.rec and play to the checkpoint. Replay them with ZAKURO_REPLAY=test/inputs/<RUN>.rec. A replay starts the game clock where the recording did. MSR2DS also found keys more reliable than menu clicks.
    • Save a screenshot at each checkpoint. Name it after the checkpoint, such as logs/golden/01-title.png.
    • Make tools/check.ps1 run every golden run and print PASS or FAIL for each.
    Prompt for Claude
    GOAL: Write `tools/boot_probe.py` and three golden runs for <GAME>: title screen, file select, first playable scene.
    READ FIRST: `tools/check.ps1`, `notes/map.md`, the key map in the `Zakuro` README, the output of `zakuro --help`.
    FENCE: Edit only `tools/` and `test/`. Never touch my play folder <PLAY_FOLDER>. Stop only the game process you started, never others by name. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `tools/check.ps1`. Done means it prints PASS for all three runs, twice in a row, and each run saves its screenshot.
    BUDGET: Stop after 90 minutes or 5 failed tries on one run.
    IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whentools/check.ps1 prints PASS for three golden runs twice in a row, with screenshots saved.

    Proof this works: Luigi's Mansion 2 Recompiled, MSR2DS, Clockwork, https://github.com/fearkov/zakuro

  6. Grind: fix missed code and crashes, one at a time

    Play, find a break, and fix that one break. Most breaks are missed functions or a runtime bug. Fix missed functions with hints, never by editing generated C. Send runtime bugs upstream with a trace.

    • After a play session, read the log of addresses that still ran in the interpreter. The next build takes them in.
    • Run 3dsrecomp hints <GAME>.3ds. It prints your game's section for hints.txt from the addresses Zakuro logged.
    • Add that section, or a start you found by hand, to 3dsrecomp's hints.txt. Each section starts with = <title id> <code hash>. Keep it as a patch file in your repo.
    • For a crash in Zakuro, write a short trace of the cause. Shin Megami Tensei IV's report was fixed upstream within hours.
    • Add one row per bug to notes/ledger.csv, and one golden run that shows the fix.
    • Rebuild and run tools/check.ps1 before you mark a row done.
    Prompt for Claude
    GOAL: Fix ledger row <ID> in <GAME>: <SYMPTOM> at <ADDRESS or SCENE>.
    READ FIRST: `notes/ledger.csv` row <ID>, `logs/<RUN>.txt`, `CLAUDE.md`, the `3dsrecomp` `docs/overrides.md`.
    FENCE: Edit only `patches/`, `overrides/` and `tools/`. Never edit generated C in `out/`. Never return fake success from a service to get past a hang. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `tools/check.ps1`. Done means the golden run for row <ID> passes, every older golden run still passes, and the cause is written in `notes/bugs/<ID>.md`.
    BUDGET: Stop after 4 failed fixes, or after 60 minutes with no new evidence.
    IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenThe ledger row has a cause, a fix and a golden run, and the full check passes.

    Proof this works: Fire Emblem: Awakening for Windows, Luigi's Mansion 2 Recompiled, Shin Megami Tensei IV Recomp

  7. Add PC features with overrides

    Change the game the safe way. An override is a C function that replaces one game function by address. Widescreen, one-screen layouts and speed options all came this way. Each change gets a switch and a golden run.

    • Write the change in overrides/<feature>.c with RECOMP_OVERRIDE(0x<ADDRESS>). An odd address means a Thumb function.
    • Build with 3dsrecomp build <GAME>.3ds out/recomp --overrides overrides/.
    • For widescreen, Shin Megami Tensei IV searched .code for the float 400/240 (0x3FD55555) and followed it to the perspective setup.
    • If you must patch generated C, anchor the patch on the instruction comment so it fails loudly after a rebuild.
    • Leave the game's speed alone: 60 fps cheats made Shin Megami Tensei IV run twice as fast.
    Prompt for Claude
    GOAL: Add <FEATURE> to <GAME> as an override, behind a setting that is off by default.
    READ FIRST: `docs/overrides.md` in `3dsrecomp`, `notes/map.md`, the function at <ADDRESS> in Ghidra.
    FENCE: Edit only `overrides/<FEATURE>.c` and the settings file. Never edit generated C. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `tools/check.ps1`. Done means all golden runs pass with the setting off, a new golden run shows the feature with it on, and the screenshot is saved.
    BUDGET: Stop after 4 failed builds or 90 minutes.
    IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenThe feature works behind its setting, and every golden run still passes with the setting off.

    Proof this works: Shin Megami Tensei IV Recomp, https://github.com/fearkov/3dsrecomp/blob/main/docs/overrides.md, Dragon Quest VIII 3DS Recomp

  8. Harden: regression set, clean build, safe package

    Make sure old fixes stay fixed. Build from a clean clone. Ship only your own code. Users build the game from their own dump.

    • Run 3dsrecomp verify <GAME>.3ds <LIBRARY>. It needs the verify feature from step 2. It compares recompiled functions against Zakuro's interpreter. A build with no folder puts the library in %APPDATA%\3dsrecomp\.
    • Clone the repo into a new folder and run tools/check.ps1 there.
    • Check the dump's hash before any build. Refuse other regions with a clear message.
    • Package the launcher, patches and overrides only. Never ship out/, the dump, saves or shader caches.
    • Collect third-party licences. 3dsrecomp had no licence file, so Awakening noted its MIT Cargo.toml instead.
    Prompt for Claude
    GOAL: Prove the <GAME> port builds and passes all checks from a clean clone, and package it with no game data.
    READ FIRST: `CLAUDE.md`, `tools/check.ps1`, `notes/ledger.csv`, the packaging script.
    FENCE: Edit only `tools/package.ps1`, `README.md` and `LICENSES/`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Clone into <CLEAN_DIR> and run `tools/check.ps1`. Then list the package files. Done means every golden run passes there, `3dsrecomp verify` reports no new mismatches, and no file in the package comes from the game.
    BUDGET: Stop after 60 minutes.
    IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenA clean clone passes every golden run, and the package holds no file made from the game.

    Proof this works: TriAevum: Echoes of Time, Woohoo! Flight School, https://github.com/fearkov/3dsrecomp

Path B: Full decomp for porting

You write C++ that armcc turns into the game's exact bytes, one function at a time. A judge script compares each function. Then you link the whole code.bin and compare its hash. Several AI-driven projects began in 2026. None is finished, and none has been ported yet.

Method: matching decompilation

Pick this only for a game you care about deeply, with months to give. Have Path A working first, because its golden runs become the checks for the port.

  1. Scope: pick the game, build and compiler

    Choose one game and one exact code.bin. Look for an existing decomp first. Find which armcc build made the game. Decide between byte matching and a looser structure check.

    • Search GitHub for <GAME> decomp. Look at zeldaret/oot3d, 7akeem0/albw-decomp-ai, Tsukimi-Labs/Solstice and RedShyGuy/acnl-decomp to see the options.
    • Read the SDK strings in the plain region of the dump. They name the SDK version.
    • Test small functions on decomp.me, platform n3ds, against armcc 4.0, 4.1 and 5.04 builds.
    • Decide: byte matching with armcc, or structure checking with GCC like the ACNL project.
    • Write SCOPE.md with the code.bin SHA-1, the compiler build, default flags and the first milestone.
    Prompt for Claude
    GOAL: Write `SCOPE.md` for a matching decomp of <GAME> (<REGION>, `code.bin` SHA-1 <HASH>).
    READ FIRST: `notes/prior-work.md`, my decomp.me tests in `notes/compiler-tests.md`, the README of `7akeem0/albw-decomp-ai`.
    FENCE: Edit only `SCOPE.md` and `notes/`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `Select-String -Path SCOPE.md -Pattern 'armcc|https://'` and paste the hits. `SCOPE.md` names the compiler build and default flags with proof, the match rule (byte or structure), the library code to skip, and milestone 1 with its check. Done means each claim has a URL or a test file.
    BUDGET: Stop after 45 minutes.
    IF BLOCKED: Stop. If no compiler build fits, say so plainly and list the builds you tried.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenSCOPE.md names one compiler build with test proof, and you approved it.

    Proof this works: https://github.com/7akeem0/albw-decomp-ai, https://github.com/zeldaret/oot3d, https://github.com/RedShyGuy/acnl-decomp

  2. Set up the judge and calibrate it

    The judge compiles one source and compares it with the game's bytes. Set it up on Windows, since armcc is a Windows program. Then prove the judge can fail. A judge that always says MATCH is worse than none.

    • Put the armcc build at toolchain/armcc/<VERSION>/<BUILD>/bin/armcc.exe. That is where matching-decomp-tools looks. ALBW uses tools/armcc/4.1/b1049/bin/armcc.exe.
    • Install Python 3.10 or newer, then run pip install capstone.
    • Add Tsukimi-Labs/matching-decomp-tools as tools/, or write a small fn.py like ALBW's. Copy tools/project.example.toml to project.toml and fill in the versions, compiler and flags.
    • Put your own exheader.bin, exefs/code.bin and romfs/*.cro in orig/<VERSION>/, ignored by git.
    • Calibrate: check a tiny known function and expect RESULT: MATCH. Change one constant and expect DIFFER.
    Prompt for Claude
    GOAL: Set up the matching judge for <GAME> and prove it can both pass and fail.
    READ FIRST: `SCOPE.md`, `tools/README.md`, `tools/CLAUDE.md` and `tools/project.example.toml` of `matching-decomp-tools`.
    FENCE: Edit only `project.toml`, `project.local.toml`, `.gitignore` and `notes/calibration.md`. Never commit the compiler or any game file. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `python -I tools/match.py check notes/calib/ok.cpp <ADDR>` and then on `notes/calib/broken.cpp`. Done means the first prints `RESULT: MATCH` and the second prints `DIFFER`, both pasted in `notes/calibration.md`.
    BUDGET: Stop after 45 minutes or 3 failed compiler runs.
    IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenThe judge prints MATCH for a known-good source and DIFFER for a broken one.

    Proof this works: https://github.com/Tsukimi-Labs/matching-decomp-tools, https://github.com/7akeem0/albw-decomp-ai, https://github.com/macabeus/asmlift/blob/main/.claude/commands/dogfood-klonoa.md

  3. Map the binary: function table, classes and libraries

    List every function with its start, size and mode (ARM or Thumb). Mark library code so nobody matches it by hand. Read class names from the game's RTTI, which is C++ type data the compiler keeps.

    • Open the game in a Ghidra project. functable.py reads it through python -I tools/local/ghidra_server.py serve, which needs a Python with pyghidra.
    • Run python -I tools/refresh.py --table. It runs functable.py, rtti.py and ctors.py, then the other table steps. Fix hidden starts with tailstarts.py --apply and unreached.py --apply.
    • Read classify.py's output: it names each function's class, slot and library.
    • Mark sdk, nw, middleware and armlib rows as library code. Solstice decompiles only game code.
    • Put starts Ghidra misses in config/<VERSION>/extra_starts.txt. ALBW also kept a not_starts.txt.
    Prompt for Claude
    GOAL: Build the function ledger for <GAME>: every function with start, end, mode, class and library.
    READ FIRST: `orig/<VERSION>/`, the output of `python -I tools/functable.py --census`, the tool docs in `tools/README.md`.
    FENCE: Edit only `config/<VERSION>/` and `notes/map.md`. Do not write any C source. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `python -I tools/progress.py`. Done means it reads the table with no errors, and `notes/map.md` gives counts by library and the share of Thumb code.
    BUDGET: Stop after 2 hours or 3 failed table builds.
    IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenfunctions.csv covers the whole binary, and progress.py reads it without errors.

    Proof this works: https://github.com/Tsukimi-Labs/Solstice, https://github.com/7akeem0/albw-decomp-ai, https://github.com/AlgebraManiacABC/3DS-Decomp-Pipeline

  4. First light: match one small function end to end

    Prove the loop on one tiny function. Write the C++, run the judge, and commit only on MATCH. Now you know the compiler, flags and headers work together.

    • Pick a function under 64 bytes from the ledger.
    • Read it with python -I tools/match.py show <ADDR> 40.
    • Write it in src/main/<namespace>/<File>.cpp with a //! <ADDR> <symbol> line above it.
    • Run python -I tools/match.py check <file> <ADDR> --sym <symbol>.
    • Commit only when it prints RESULT: MATCH.
    Prompt for Claude
    GOAL: Match function <ADDR> (<SIZE> bytes) of <GAME> in `src/main/<PATH>.cpp`.
    READ FIRST: `AGENTS.md`, `python -I tools/match.py show <ADDR> 40`, its row in `config/<VERSION>/functions.csv`, its class header.
    FENCE: Edit only `src/main/<PATH>.cpp`. Never write in a `generated/` folder. No weak declarations, `__schedule_barrier`, inline asm or dummy locals. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `python -I tools/match.py check src/main/<PATH>.cpp <ADDR> --sym <SYMBOL>`. Done means it prints `RESULT: MATCH`.
    BUDGET: Stop after 8 checks with no progress. Leave the best source with a comment on what differs.
    IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenOne function prints RESULT: MATCH and is committed.

    Proof this works: https://github.com/Tsukimi-Labs/Solstice/blob/master/AGENTS.md, https://github.com/7akeem0/albw-decomp-ai

  5. Take the free wins before spending tokens

    Tools can write some functions with no AI at all. Small functions, empty destructors and twins come first. A twin is a function with the same code as one you already matched.

    • Run python -I tools/refresh.py --derive. It writes tiny functions, destructors and twins into generated/ folders.
    • Run twins.py --apply after every batch. Solstice and ALBW both gained whole families this way.
    • Pick the next hand-written function from the top of build/<VERSION>/twins.txt. One match there unlocks a family.
    • Batch compile many files in one call. ALBW found it about 20 times faster.
    Prompt for Claude
    GOAL: Run the machine-only stages for <GAME> and report how many functions they matched.
    READ FIRST: `CLAUDE.md`, `tools/README.md`.
    FENCE: Run only `refresh.py`, `twins.py`, `progress.py` and `honest.py`. Edit nothing by hand. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `python -I tools/progress.py` before and after. Done means you paste both counts and `honest.py` reports no new tricks.
    BUDGET: Stop after 60 minutes.
    IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenprogress.py shows the new count, and honest.py is clean.

    Proof this works: https://github.com/Tsukimi-Labs/matching-decomp-tools, https://github.com/7akeem0/albw-decomp-ai/blob/master/docs/LESSONS.md

  6. Grind: many workers, one batch of functions each

    Now hand out functions in small batches. Each worker gets a packet and runs only the judge. Size sets the batch: many tiny ones, or one big one. Every merge reruns the judge on the merged branch.

    • Make packets with python -I tools/local/packets.py --name <BATCH>. A packet gives each function's address, its declaration, its --sym name and the members it uses.
    • Give each worker its own git worktree, for example claude -w batch-<N>. A new worktree lacks ignored folders like orig/ and toolchain/, so list them in .worktreeinclude or the worktree.symlinkDirectories setting.
    • Functions of 17 to 256 bytes go 10 to 15 per worker. Functions of 257 to 1,024 bytes go 1 to 3. Bigger ones go 1 per worker.
    • Stop each function after 8 checks without progress. Record what was tried.
    • After merging, run progress.py, twins.py --apply and honest.py on the main branch.
    Prompt for Claude
    GOAL: Match the functions in packet <PACKET_FILE> of <GAME>.
    READ FIRST: `AGENTS.md` (all of it), the packet, the class headers it names.
    FENCE: Edit only the source files the packet names. Run `tools/match.py` and nothing else. Never edit a header that starts with `// generated by tools/headers.py`; report header fixes instead. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: For each function run `python -I tools/match.py check <file> <where> --sym <symbol>`. Done means each function is reported as MATCH or open, one line each.
    BUDGET: Stop each function after 8 checks with no progress. Stop the batch after 90 minutes.
    IF BLOCKED: Stop. Report the function, the best diff and what you tried. Do not reach for a trick.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: One line per function: `<where> <status> <file>`, then any header problems you found.
    Done whenEvery packet function is MATCH or open with notes, and the merged branch passes progress.py and honest.py.

    Proof this works: https://github.com/Tsukimi-Labs/Solstice/blob/master/CLAUDE.md, https://github.com/7akeem0/albw-decomp-ai, https://bytematch.dev/mhvuze/mh4u-decomp, https://code.claude.com/docs/en/worktrees.md

  7. Crack the hard tail with shared headers

    The last third is hard on 3DS games. ALBW found the main blocker: small inline helpers from the game's headers. Fix a helper once in a shared header, and many functions match. Per-function flags matter too.

    • Collect the open functions that share a helper, such as a constructor or a setter.
    • Write the helper once in include/, and check it against every function that uses it. Remove a header's // generated by tools/headers.py line first, or the tool rewrites it.
    • Try per-function flags. About 850 ALBW functions needed --apcs=/fpic, which stops tail calls.
    • Turn hack matches into honest ones. ALBW removed about 76 needless barriers or dummy locals.
    • Write each compiler rule you prove into notes/compiler-quirks.md, never per-function notes.
    Prompt for Claude
    GOAL: Find the inline helper behind open functions <LIST> of <GAME> and write it once in a shared header.
    READ FIRST: `docs/LESSONS.md` of ALBW, `notes/compiler-quirks.md`, the open functions' best sources and diffs.
    FENCE: Edit only `include/<HEADER>.h` and the listed sources. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `python -I tools/match.py check` on every listed function and `python -I tools/honest.py`. Done means more functions match than before and none that matched now fails.
    BUDGET: Stop after 2 hours or 15 header tries.
    IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenThe header change raises the match count and breaks no earlier match.

    Proof this works: https://github.com/7akeem0/albw-decomp-ai/blob/master/docs/LESSONS.md, https://github.com/Tsukimi-Labs/Solstice

  8. Harden: link the whole binary and audit relocations

    A function-level match is evidence, not the verdict. Link everything and compare the whole code.bin hash. Audit relocations too, because a call to the wrong function can still look matched.

    • With 3DS-Decomp-Pipeline, run python main.py <DIR> --skip-split --recreate-binaries. It links, rebuilds the binary and checks its SHA-256.
    • Or follow zeldaret/oot3d: cmake -B build -S . -G "Unix Makefiles", then cmake --build build -t check, which prints build/code.bin: OK.
    • Run a relocation identity audit. ALBW removed 419 false matches this way.
    • Make an objdiff report with python -I tools/objexport.py --report. Sites like decomp.dev and bytematch.dev show progress from these reports.
    Prompt for Claude
    GOAL: Link <GAME> from matched sources plus the split originals and compare the full `code.bin` hash.
    READ FIRST: `CLAUDE.md`, the pipeline README, `notes/calibration.md`.
    FENCE: Edit only the build config and `notes/`. Never edit expected hashes or the judge. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `python main.py <DIR> --skip-split --recreate-binaries`, or `cmake --build build -t check` in an OoT3D-style repo. Done means the rebuilt `code.bin` has the original SHA-256, and the relocation audit lists zero wrong targets.
    BUDGET: Stop after 2 hours.
    IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenThe rebuilt code.bin hash equals the original, and the relocation audit is clean.

    Proof this works: https://github.com/zeldaret/oot3d, https://github.com/AlgebraManiacABC/3DS-Decomp-Pipeline, https://github.com/7akeem0/albw-decomp-ai

  9. Port: run the decomp on a PC

    Nobody has done this for a 3DS game yet. Plan it as a new runtime under the decomp. The runtime replaces the nn SDK calls, the GPU and the sound with PC parts. The recomp runtimes show what that takes.

    • Compile the matched source with a PC compiler. Fix 64-bit pointer problems one class at a time.
    • Put the SDK calls behind one interface. Use Zakuro or the Clockwork runtime as a model for kernel, services, PICA200 and DSP.
    • Note that TriAevum built a source-native route for Ocarina of Time 3D, then removed it on 2026-10-03.
    • Reuse your Path A golden runs as the check for the port.
    Prompt for Claude
    GOAL: Write a port plan for <GAME> from the decomp to Windows, with one first milestone.
    READ FIRST: `SCOPE.md`, `notes/map.md`, the `Zakuro` and `Clockwork` READMEs, `docs/port.md` of `3dsrecomp`.
    FENCE: Edit only `notes/port-plan.md`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `python -I tools/progress.py` and put its totals at the top of the plan. Done means the plan lists every SDK area to replace, names what each Path A golden run will prove, and states plainly what is not known yet.
    BUDGET: Stop after 60 minutes.
    IF BLOCKED: Stop. If the decomp is too incomplete to port, say so with the numbers from `progress.py`.
    OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
    REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.
    Done whenThe port plan is approved, and its first milestone passes a Path A golden run on the PC build.

    Proof this works: TriAevum: Echoes of Time, https://github.com/watchmakerers/clockwork, https://github.com/fearkov/zakuro

Tools you need

ToolWhat it doesHow to get itHow we know
Python 3.10 or newer
Required both
Runs the Path B tools, the pipeline, Capstone and your boot probe.
Path A Path B
winget install Python.Python.3.12matching-decomp-tools README asks for Python 3.10 or later; 3DS-Decomp-Pipeline asks for 3.10+. The winget-pkgs repo has Python.Python.3.12 (read 2026-11-13).
Git for Windows
Required both
Version control. You need it for clones, submodules, patch files and worktrees.
Path A Path B
winget install Git.GitFire Emblem: Awakening applies its patches with git apply; matching-decomp-tools goes in as a git submodule. The winget-pkgs repo has Git.Git (read 2026-11-13).
3dsrecomp
Required both
Finds the functions in a 3DS game and turns ARM, Thumb and VFP code into C. It can also check its output against Zakuro's interpreter, and make a game into its own program.
Path A
cargo install --git https://github.com/fearkov/3dsrecomp --rev <COMMIT> --locked --features verify recomp3ds (drop --features verify if you do not need the verify command)README, docs/overrides.md, docs/port.md, Cargo.toml (package recomp3ds, program 3dsrecomp, feature verify) and src/main.rs usage read 2026-11-13. No releases and no licence file; Cargo.toml says MIT. Works on Linux and on Windows with MinGW gcc. Used by: Shin Megami Tensei IV Recomp, Fire Emblem: Awakening, Fire Emblem Fates SE, Dragon Quest VIII.
Zakuro
Required both
The runtime and launcher that plays a recompiled game. It covers the kernel, services, GPU and sound, and interprets any code that was not recompiled.
Path A
Download zakuro-windows-x86_64.zip from the releases page (v0.2.32 on 2026-11-06), or cargo install --git https://github.com/fearkov/zakuro --rev <COMMIT> --locked zakuroREADME, releases, COMPATIBILITY.md and crates/zakuro/src/cli.rs read 2026-11-13 (options --recompiled, --data, --headless) (MIT; building needs Rust 1.95 or newer). Used by the same four projects as 3dsrecomp.
Rust (rustup) with the GNU toolchain
Required both
Builds 3dsrecomp, Zakuro and any ported program. Use the GNU target on Windows so it matches MinGW gcc.
Path A
Run the installer from https://rustup.rs, then rustup default stable-x86_64-pc-windows-gnuShin Megami Tensei IV Recomp README (the MSVC toolchain failed); 3dsrecomp docs/port.md read 2026-11-13 (compiler must match the Rust toolchain).
MinGW-w64 gcc (WinLibs or MSYS2)
Required Windows
The C compiler for the generated code on Windows. Plain MSVC could not build Woohoo's generated C.
Path A
winget install BrechtSanders.WinLibs.POSIX.UCRT, or install MSYS2 (msys2-x86_64-20260927.exe) and run pacman -S mingw-w64-ucrt-x86_64-gcc3dsrecomp README (read 2026-11-13) names MinGW-w64 through MSYS2 or WinLibs; msys2.org read 2026-11-13. Used by: Shin Megami Tensei IV Recomp, Woohoo! Flight School, MSR2DS.
Zig
Helpful both
A small download that brings its own C compiler (zig cc). Zakuro offers it when no gcc or clang is found.
Path A
Download the Windows zip from https://ziglang.org/download/ (0.17.1 is the newest listed), unzip, and add it to PATHZakuro README and ziglang.org download index read 2026-11-13. Used by: Fire Emblem Fates SE (0.17.1), MSR2DS (0.15.2).
GodMode9
Required 3DS console
A file browser that runs on a modded 3DS. It dumps your own game card and decrypts it.
Path A Path B
Runs on the console, not the PC. Follow the setup in the README; Clockwork's README gives the dump stepsREADME read 2026-11-13; dump steps in the Clockwork README read 2026-11-13. Used by: Clockwork, Shin Megami Tensei IV Recomp, Animal Crossing decomp.
ctrtool (Project_CTR)
Required both
Reads 3DS files and unpacks the ExHeader, the ExeFS (with code.bin) and the RomFS from a decrypted dump.
Path A Path B
Download ctrtool-v1.3.0-win_x64.zip from the Project_CTR releases page. Example: ctrtool --exefsdir=out/exefs --romfsdir=out/romfs --exheader=out/exheader.bin game.3dsctrtool/README.md and releases read 2026-11-13 (options --exefsdir, --romfsdir, --exheader, --decompresscode). Named by the Animal Crossing decomp.
Azahar
Helpful both
An open 3DS emulator. Use it to see how a scene should look and sound when your build looks wrong.
Path A Path B
Download azahar-windows-msvc-2126.2.zip, or its installer, from the releases pageREADME read 2026-11-13 (GPL-3.0). DekUI and MSR2DS 1.x forked it; Clockwork and Woohoo read it for behaviour only, because copying its code would make an MIT project GPL.
Ghidra with a CTR loader
Helpful both
A free disassembler. A CTR loader lets it open CXI, CIA, CRO and CRS files so you can read code, strings and modules.
Path A Path B
Unzip ghidra_12.2_PUBLIC_20261016.zip (needs JDK 25: winget install EclipseAdoptium.Temurin.25.JDK). For GhidraMCP, use ghidra_12.1.4_PUBLIC_20260921.zip with JDK 21 instead. The loader Martmists-GH/ghidra-ctr-loader has no release; you would build it with Gradle against your Ghidra (its build.gradle.kts needs GHIDRA_INSTALL_DIR). UntestedGhidra README at tags Ghidra_12.2_build (JDK 25) and Ghidra_12.1.4_build (JDK 21), release assets and winget-pkgs read 2026-11-13; ghidra-ctr-loader README and build.gradle.kts read 2026-11-13 (last change 2024-01). TriAevum used Ghidra; matching-decomp-tools builds its function table from a Ghidra project.
Capstone and Unicorn (Python)
Helpful both
Capstone disassembles ARM code. Unicorn runs it. Together they let you test recompiled functions against a real ARM CPU model.
Path A Path B
pip install capstone unicornPyPI pages read 2026-11-13 (capstone 5.0.9, unicorn 2.1.4). MSR2DS tested 22,697 functions against Unicorn; ALBW's fn.py needs capstone.
armcc (ARM Compiler 4.1 or RVCT 4.0)
Required Windows
The compiler the games were built with. Path B needs the exact build, because only it gives the same bytes.
Path B
No official free download. matching-decomp-tools and Solstice use decomp.me's builds: armcc.zip from the compilers release of decompme/compilers, unpacked into toolchain/armcc/. ALBW asks for your own licensed copy. armcc belongs to Arm; whether you may use these builds is your calldecomp.me source read 2026-11-13: platform n3ds lists armcc 4.0 builds 771 to 902, 4.1 builds 561 to 1454, and 5.04 build 82. decompme/compilers release 'compilers' has armcc.zip (read 2026-11-13). matching-decomp-tools CLAUDE.md names it. ALBW uses 4.1 build 1049; zeldaret/oot3d uses RVCT 4.0 build 821.
matching-decomp-tools
Helpful Windows
A judge and helpers for armcc matching: function table, class headers from RTTI, twins, tiny-function writer and a check for tricks.
Path B
git submodule add https://github.com/Tsukimi-Labs/matching-decomp-tools toolsREADME, CLAUDE.md, match.py and tool docstrings read 2026-11-13 (MIT, made for Pokemon Ultra Sun and Ultra Moon; needs Python 3.10+ and capstone 5; Windows only for now). Used by: Solstice.
objdiff
Helpful both
Compares your compiled object with the original, function by function, and writes progress reports. It supports 3DS ARM code.
Path B
Download objdiff-windows-x86_64.exe and objdiff-cli-windows-x86_64.exe from the releases page (v3.8.3)README read 2026-11-13 (lists ARM for GBA, DS and 3DS). Release assets read 2026-11-13. Monster Hunter 4 Ultimate shows progress on bytematch.dev and Animal Crossing on decomp.dev, both from objdiff reports; matching-decomp-tools writes them with objexport.py.
3DS-Decomp-Pipeline
Helpful both
Splits code.bin and .cro files into objects, compares your compiled code, links it back and checks the final hash.
Path B
git clone https://github.com/AlgebraManiacABC/3DS-Decomp-Pipeline, pip install pyyaml, and put arm-none-eabi-ld and arm-none-eabi-objcopy (devkitARM) in its tools/ folder. Then python main.py <working_dir>README read 2026-11-13: needs Python 3.10+, PyYAML and devkitARM ld and objcopy; OS not stated. Its compare step masks relocated bytes, so pair it with a relocation check.
CMake and Ninja
Helpful both
Build systems used by most projects here, from the runtimes to the OoT3D decomp's check target.
Path A Path B
In MSYS2: pacman -S --needed mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-ninjaUsed by: Clockwork, Luigi's Mansion 2, Woohoo! Flight School, MSR2DS (MSYS2 pacman line from its card), zeldaret/oot3d README read 2026-11-13.

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.

static-recomp-scope-plan

skills.sh

Makes you write down the exact build, the test scenes and the numbers to hit before Path A starts. It fits the one-region rule on the 3DS.

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

static-recomp-av-compare

skills.sh

Scores your build's video and sound against your own recordings, scene by scene. Record the scenes in Azahar. It was written for Codex, so fix its script paths.

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

matcher and orchestrator

skills.sh

A strict one-function method and a many-worker plan with one worktree each. Describe your armcc judge in AGENTS.md so the skills can call it. The vetted list says to install the other lemiur matching skills too, because they call each other by name. The orchestrator points to Internet Archive for a missing compiler; whether that is legal for you is your call.

npx skills add lemiur/game-decompilation-skill-for-claude --skill matcher -a claude-code (repeat with --skill orchestrator)

systematic-debugging

skills.sh

No fix before the cause is found, and a stop after three failed fixes. That suits Zakuro crashes and missed-function hangs.

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

verification-before-completion

skills.sh

Claude must run the check and show the output before it says done. It backs up the golden runs and RESULT: MATCH.

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. Tell it to save in notes/, not the temp folder.

npx skills add mattpocock/skills --skill handoff -a claude-code

ghidra-headless

skills.sh

Runs Ghidra with no window and saves functions and strings to files. It needs bash (Git Bash on Windows) and JDK 17 or newer. Load the CXI with a CTR loader first. Set GHIDRA_HOME yourself on Windows.

npx skills add trailofbits/skills-curated --skill ghidra-headless -a claude-code

GhidraMCP

MCP server

Lets Claude ask Ghidra for a function, its callers and its strings, instead of reading pasted listings. First install uv (winget install astral-sh.uv) and the plugin from its release zip with File, Install Extensions. Its README asks for Ghidra 12.1.4.

claude mcp add ghidra -- uvx --from git+https://github.com/LaurieWired/GhidraMCP ghidra-mcp --ghidra-server http://127.0.0.1:8080/

3ds-golden-run (write your own)

write-your-own

Gives every session the same way to boot, press keys and judge a scene. Luigi's Mansion 2 and MSR2DS both built this by hand.

Make `.claude/skills/3ds-golden-run/SKILL.md`. It says: run `tools/boot_probe.py --seconds <N> --run <NAME>` from `test/`, never from the play folder; stop only the process it started; compare `logs/golden/<NAME>.png`; print PASS or FAIL with the log path.

armcc-match (write your own)

write-your-own

Puts the ALBW and Solstice rules into one place every worker reads. Keep it short and point to notes/compiler-quirks.md for proven rules.

Make `.claude/skills/armcc-match/SKILL.md`. It lists: the judge command, the default flags, the banned tricks (weak, `__schedule_barrier`, inline asm, dummy or volatile locals), the 8-check stop rule, and the one-line report format.

Claude setup for this system

For Path A, one card is one crash, one hang, one missed function or one bad scene. Each card names the golden run that shows it. A PC feature is its own card with its own setting. For Path B, one card is one packet: up to 15 tiny functions, or one big one. A script picks the next packet from the ledger and the twins list, not Claude.

Which model and effort for each job

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

JobWhat it means on this systemMax 20x (now called Ultra)Max 5x (now called Max)
Plan the projectPick the game build and check its hash. Look for prior work on Zakuro, RecompLauncher and GitHub. For Path B, find the armcc build. Write SCOPE.md.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 projectInstall Rust with the GNU target, MinGW gcc, 3dsrecomp and Zakuro, pinned. For Path B, set up the judge and prove it can fail.Opus 5.5
effort medium
Sonnet 5.5
effort medium
Study the game fileRun 3dsrecomp analyze, list CRO modules and services, and build the function table with classes from RTTI.Opus 5.5
effort high
Opus 5.5
effort medium
Raise to high for function edges and data layouts. A mistake there spreads.
Bulk unitsPackets of small functions in Path B. In Path A, adding many missed function starts from the interpreter log.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 unitsFunctions over 1 KB, shared inline helpers in headers, and tail-call or register quirks of armcc.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.
Build the runtimeChanges to services, the GSP command path or the PICA200 renderer. On this system, prefer a clear upstream report to a local fork.Opus 5.5
effort high
Opus 5.5
effort medium
Raise to high for timing and graphics bugs.
Find a bugFind why a scene hangs, crashes or draws wrong, using the boot probe log, an Azahar reference and call traces.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.
Check the workA fresh session reruns the golden runs or the judge, checks for edited generated C, fake service returns and hack matches.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 PROGRESS.md, notes/ledger.csv, notes/bugs/ and notes/compiler-quirks.md from the commits.Haiku 5.5
effort medium
Haiku 5.5
effort medium

How many sessions at once

Max 20x (now called Ultra)

Path A: one lead plus 2 debug workers, each in its own worktree with its own test/ folder. A full recompile can take 25 minutes and all your cores, so let only one worker build at a time. Path B: one lead plus 4 to 6 workers on packets. Cap compiler jobs per worker; ALBW ran one at a time under Wine to save memory.

Max 5x (now called Max)

Path A: one session at a time, and batch several bugs per build. Path B: one lead plus 1 or 2 workers, small functions first. Let the machine-only stages run often, since they cost no tokens. Save the weekly limit for hard and debug jobs.

Lines for this project's CLAUDE.md

Add to CLAUDE.md
- Read `SCOPE.md` and `PROGRESS.md` at the start of every session.
- The one check is `powershell -NoProfile -ExecutionPolicy Bypass -File tools/check.ps1` (Path A) or `python -I tools/match.py check` (Path B). Do not report DONE until it passes; paste its output.
- Never edit generated C in `out/` or any `generated/` folder. Fix it with `hints.txt`, an override or a patch, then rebuild.
- Nothing made from the game goes into git: the dump, generated C, `librecomp.a`, saves, shader caches, texture or frame dumps.
- `run/` is my play folder. Tests run from `test/` only. Never stop game processes by name; stop only the one you started.
- A service you do not know must stop with a named error. Never return fake success to get past a hang.
- Matched means the judge prints `RESULT: MATCH`. Never claim a match from reading a diff.
- No weak declarations, `__schedule_barrier`, inline asm, or dummy or volatile locals to force a match. An honest miss beats a hack.
- `honest_allow.txt`, flag sets and expected hashes are mine. Propose changes; do not edit them.
- In a worktree, use absolute paths in every command.
- Never build with more than `-j <N>`. MSR2DS set 8, because its PC reset under all-core builds.
- When you fix a real bug, write `notes/bugs/<ID>.md` with symptom, cause, fix and the golden run that proves it.
- Do not send pull requests to `3dsrecomp` or `Zakuro` without my review; they discard code that is entirely vibecoded. Commit or push only when I ask.

Keep the context small

  • Give Claude an address and a file path, not pasted disassembly. Let it run match.py show or ask Ghidra itself.
  • Keep build logs in files. Ask for the last 50 lines or a grep, never the whole 25-minute log.
  • Hand each worker AGENTS.md and its packet only. Solstice found that a decompiler's C in the packet did not help.
  • Start a fresh session for each ledger row or packet. State lives in notes/ledger.csv and PROGRESS.md.
  • Keep CLAUDE.md short. Put proven compiler rules in notes/compiler-quirks.md and point to it.

More prompts for this system

Each step above has its own prompt. These extra prompts cover the rest of the work. Fill in the parts in <ANGLE_BRACKETS>.

Scope and feasibility

Before any work, to choose Path A, Path B or both for one game.

Prompt for Claude
GOAL: Tell me if <GAME> (<REGION>, title ID <TITLE_ID>, SHA-256 <HASH>) can be recompiled with `3dsrecomp` and `Zakuro`, and whether a decomp exists.
READ FIRST: `notes/prior-work.md`, the `Zakuro` `COMPATIBILITY.md`, RecompLauncher, GitHub results for `<GAME> recomp` and `<GAME> decomp`.
FENCE: Edit only `SCOPE.md` (draft) and `notes/prior-work.md`. Do not open or copy the dump. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
CHECK: Run `Select-String -Path SCOPE.md -Pattern 'https://'` and paste the hits. Done means `SCOPE.md` names one technique, lists prior work with URLs, gives the region and title ID, and lists the three biggest risks (CRO modules, data-pointer functions, region lock).
BUDGET: Stop after 40 minutes.
IF BLOCKED: Stop. Say what you could not find. Do not guess facts.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: the URLs. 3) Files changed. 4) What is left. 5) New parking-lot items.

A good answer: DONE, one technique, links to any recomp or decomp, the title ID, and three named risks.

Map the binary

Once the dump is unpacked, before the first Path B function.

Prompt for Claude
GOAL: Write `config/<VERSION>/functions.csv` for <GAME>: start, end, mode, class, library for every function in `code.bin` and each `.cro`.
READ FIRST: `orig/<VERSION>/`, the output of `python -I tools/functable.py --census`, the RTTI tools' output.
FENCE: Edit only `config/<VERSION>/` and `notes/map.md`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
CHECK: Run `python -I tools/progress.py`. Done means it loads the table with no errors and `notes/map.md` gives counts by library and by mode.
BUDGET: Stop after 2 hours.
IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.

A good answer: DONE, a full table, counts per library, and a short list of address ranges it was unsure about.

Unit loop, Path A: one crash

For each crash, hang or missed function in the ledger.

Prompt for Claude
GOAL: Find and fix the cause of ledger row <ID> (<SYMPTOM>) in <GAME>.
READ FIRST: `notes/ledger.csv` row <ID>, `logs/<RUN>.txt`, `CLAUDE.md`.
FENCE: Edit only `patches/`, `overrides/` and `notes/bugs/<ID>.md`. Never edit generated C. Never fake a service reply. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
CHECK: Run `tools/check.ps1`. Done means the row's golden run passes and all older runs still pass.
BUDGET: Stop after 4 failed fixes or 60 minutes with no new evidence.
IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.

A good answer: DONE with the cause in one sentence, the fix, and the pasted PASS lines for every golden run.

Unit loop, Path B: one function

For each function a worker takes from a packet.

Prompt for Claude
GOAL: Match function <WHERE> of <GAME>.
READ FIRST: `AGENTS.md`, `python -I tools/match.py show <WHERE> 40`, the function's class header.
FENCE: Edit only `<SOURCE_FILE>`. Run `tools/match.py` and nothing else. No banned tricks. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
CHECK: Run `python -I tools/match.py check <SOURCE_FILE> <WHERE> --sym <SYMBOL>`. Done means `RESULT: MATCH`.
BUDGET: Stop after 8 checks with no progress.
IF BLOCKED: Stop. Leave the best source with a comment saying what differs and what you tried.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
REPORT: One line: `<WHERE> <MATCH or open> <file>`, then any header problem you found.

A good answer: One line with MATCH, or open with a clear note, and nothing changed outside the file.

Batch dispatch

From a lead session, to start the next round of Path B workers.

Prompt for Claude
GOAL: Hand out the next <N> packets for <GAME> to <N> workers, one worktree each.
READ FIRST: `CLAUDE.md`, `build/<VERSION>/twins.txt`, the output of `python -I tools/progress.py`.
FENCE: Edit only `notes/dispatch-<DATE>.md`. Workers edit only the files in their packet. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
CHECK: On the merged branch, run `python -I tools/progress.py`, `python -I tools/twins.py --apply`, then `python -I tools/honest.py`. Done means each worker reported, the merged branch passes `progress.py` and `honest.py`, and `twins.py --apply` ran after the merge.
BUDGET: Stop the round after 2 hours. Merge only what passed.
IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.

A good answer: A table of packets with MATCH and open counts, the new total, and a clean honest.py.

Debug with evidence

When a scene draws wrong or hangs and the cause is unclear.

Prompt for Claude
GOAL: Find the cause of <SYMPTOM> in <SCENE> of <GAME>. Do not fix it yet.
READ FIRST: `logs/<RUN>.txt`, the same scene recorded in Azahar at <RECORDING>, `notes/bugs/` for similar past bugs.
FENCE: Edit only `notes/bugs/<ID>.md` and throwaway probe builds in `scratch/`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
CHECK: Run the probe or golden run the note names, and paste its output. It must show the symptom now. Done means the note names one cause, with a log line, a trace or a frame compare that proves it, and one test that would show the fix works.
BUDGET: Stop after 90 minutes or 5 dead ends. Write each dead end in the note.
IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.

A good answer: One proven cause with evidence, the dead ends listed, and a proposed check. No code change.

Verify: hunt for cheating

After any claimed milestone, in a fresh session that did not do the work.

Prompt for Claude
GOAL: Check that the work in commits <RANGE> of <GAME> is real.
READ FIRST: `CLAUDE.md`, `git log <RANGE>`, `git diff <RANGE>`.
FENCE: Edit only `notes/verify-<DATE>.md`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
CHECK: Rerun `tools/check.ps1` or `python -I tools/progress.py` and `python -I tools/honest.py` yourself. Done means you list any edited generated C, fake service returns, edited hashes, weak or barrier tricks, stubs, or files outside the fence.
BUDGET: Stop after 60 minutes.
IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.

A good answer: A list with each claim marked confirmed or not, the pasted check output, and any cheat found with its file and line.

Status report

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

Prompt for Claude
GOAL: Write a status report for <GAME> from the ledgers only.
READ FIRST: `PROGRESS.md`, `notes/ledger.csv`, `python -I tools/progress.py` output, `notes/parking-lot.md`.
FENCE: Edit only `notes/status-<DATE>.md`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
CHECK: Run `python -I tools/progress.py` (Path B) or `tools/check.ps1` (Path A) and use only its numbers. Done means every number has its source file, and the report fits on one screen: done, open, blocked, next three cards.
BUDGET: Stop after 20 minutes.
IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.

A good answer: Numbers with sources, no padding, and three next cards.

Session handoff

At the end of every working session.

Prompt for Claude
GOAL: Write down what the next session needs to carry on with <GAME>.
READ FIRST: `PROGRESS.md`, `git log -10`, `notes/ledger.csv`.
FENCE: Edit only `PROGRESS.md` and `notes/handoff.md`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
CHECK: Run `git status --short` and `git log -1 --oneline`, and paste both. Done means every changed file is listed and `notes/handoff.md` says what works, what is in progress, the exact next command, the open questions, and the pinned tool commits.
BUDGET: Stop after 15 minutes.
IF BLOCKED: Stop. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.

A good answer: A short note a new session can act on with no chat history.

Blocked or cannot deliver

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

Prompt for Claude
GOAL: Tell me plainly if <TASK> on <GAME> can be done with the tools we have.
READ FIRST: `notes/bugs/<ID>.md` or the function's notes, `notes/compiler-quirks.md`.
FENCE: Edit only `notes/blocked-<ID>.md`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
CHECK: Run the failing check once more and paste its output. Done means the note says CAN, CANNOT or UNKNOWN, gives the evidence, and lists at most three options with their cost.
BUDGET: Stop after 30 minutes.
IF BLOCKED: Say BLOCKED and list what you need from me.
OTHER PROBLEMS: Write them in `notes/parking-lot.md`. Do not fix them.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.

A good answer: One word answer, the evidence, and short options. No new attempt at the task.

Scope change request

When Claude finds work outside the fence that seems needed.

Prompt for Claude
GOAL: Ask me before you leave the fence for <TASK>.
READ FIRST: `SCOPE.md`, `notes/parking-lot.md`.
FENCE: Edit only `notes/scope-request-<DATE>.md`. Change no code. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
CHECK: Run `git status --short`. Done means it shows only the new note, and the note says what you want to change, why, which files, the risk, and how we would check it.
BUDGET: Stop after 15 minutes.
IF BLOCKED: Stop and wait for my yes or no.
REPORT: 1) DONE, PARTIAL or BLOCKED. 2) Proof: paste the check output. 3) Files changed. 4) What is left. 5) New parking-lot items.

A good answer: A short request I can answer yes or no, with no code changed.

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 generated C in out/ to get past a crash. The next rebuild wipes the fix.Never edit generated C. Fix it with hints.txt, RECOMP_OVERRIDE or an anchored patch, then rebuild.
Claude makes a service return success with no work, so a hang goes away. The bug comes back later in a worse place.A service you do not know stops with a named error. No fake replies. Clockwork made missed code fail loudly with the address.
Claude says the game is recompiled while much of it still runs in the interpreter.Report coverage from the interpreter log with every claim. TriAevum gated releases on zero leftover interpreted entries.
Claude runs tests in your play folder, or kills the game by name while you are playing.Tests run from test/ only. Stop only the process you started. These two rules come from the MSR2DS CLAUDE.md.
Claude forces a Path B match with weak, __schedule_barrier, inline asm or a dummy local.Those tricks are banned. A match that needs one is recorded as a hack and stays open. An honest miss beats a hack.
Claude trusts a MATCH from a judge that masks relocations, so a call to the wrong function passes.Every match also passes a relocation identity check, and the full code.bin hash is the final verdict. ALBW removed 419 false matches.
Claude pastes Ghidra or m2c output and edits it toward a match. The code stays shaped like the machine code.Decompiler C is a reference, never a draft. Write the function from what it does.
Claude commits files made from the game, like Dragon Quest VIII's .bin and .o files in its repo root.Nothing made from the game goes into git. Check git status --ignored before every commit.

Problems other projects hit

The Windows toolchain fails. Rust on MSVC did not work, and an old 32-bit MinGW first on PATH broke the build.

Fix: Use stable-x86_64-pc-windows-gnu with a current 64-bit MinGW. Check that where.exe gcc shows the right one first.

Seen in: Shin Megami Tensei IV Recomp

MSVC cannot build some generated C, because it uses GCC and Clang builtins.

Fix: Use MinGW gcc or Clang, and pass -G Ninja so CMake does not pick Visual Studio.

Seen in: Woohoo! Flight School

The function finder misses code. A function reached only through a data pointer, a hidden jump table, and a conditional trap read as a path end all stopped games.

Fix: Add the start to hints.txt or a seed file. Keep a fallback interpreter and feed its log of missed addresses into the next build.

Seen in: Luigi's Mansion 2 Recompiled, Clockwork, Fire Emblem: Awakening for Windows, MSR2DS

Only one region and revision works. Every other dump has different code.

Fix: Pin the dump's hash in SCOPE.md, check it before each build, and refuse other dumps with a clear message.

Seen in: Fire Emblem: Awakening for Windows, Luigi's Mansion 2 Recompiled, DekUI, Woohoo! Flight School

A blank screen turned out to be the screen recorder. It could not read the Vulkan window.

Fix: Capture the whole desktop, or have the game save its own frames, before you chase a graphics bug.

Seen in: Shin Megami Tensei IV Recomp

A crash after naming the hero came from Zakuro reusing a closed event handle.

Fix: Trace the handle's life, report it upstream with the trace, and pin the fixed version. It was fixed in v0.2.27.

Seen in: Shin Megami Tensei IV Recomp

A 60 fps cheat made the whole game run twice as fast, and turning it off did not undo it.

Fix: Keep the game's logic at its own rate. Use frame interpolation for smooth motion instead.

Seen in: Shin Megami Tensei IV Recomp, TriAevum: Echoes of Time

Timers froze after 68.8 seconds, and 3D models drew black.

Fix: Use 64-bit-safe tick math, and add fragment lighting early. Compare against a software renderer kept as the reference.

Seen in: Clockwork

zig c++ sometimes quit with code 5 under heavy parallel load on Windows.

Fix: Compile the failed files again on their own, and cap parallel jobs.

Seen in: MSR2DS

In Path B, a judge that hid relocated words reported matches that called the wrong function.

Fix: Check relocations by symbol, and rebuild and hash the whole code.bin as the last check.

Seen in: https://github.com/7akeem0/albw-decomp-ai

Some games draw text with the console's system font. Zakuro cannot make that font; it asks for a dump at sysdata/shared_font.bin.

Fix: Dump the font from your own console, or make a stand-in font on your machine as Luigi's Mansion 2 did. Never commit either one.

Seen in: Luigi's Mansion 2 Recompiled, https://github.com/fearkov/zakuro/blob/main/crates/zakuro/src/cli.rs

How long it takes

Max 20x (now called Ultra)Max 5x (now called Max)One person, no AIHow sure
Path A: running on PC2 to 8 weeks5 to 20 weeks3 to 12 monthsmedium confidence
Path B: full decomp1 to 3 years2 to 6 years5 to 10 yearslow confidence

Read this first

These ranges assume one medium game and one person giving 10 to 15 hours a week. Path A rests on four dated AI-assisted 3DS projects. They agree on weeks, not months. But their private work before the first commit is unknown, and none was played to the end by its author. So we rate it medium. Path B has no finished 3DS decomp at all, so its numbers are a rough guess from partial progress. Every reviewed 3DS port is from 2026, so no project shows the pace without AI. The no-AI ranges are estimates too.

What makes it faster or slower

  • Whether 3dsrecomp and Zakuro already run your game. If they do, you start at the title screen on day one.
  • How much code hides behind data pointers and CRO modules. Each missed function needs a hint.
  • How much PC work you want: one-screen layout, widescreen and HUD changes took most of the time in DekUI and Dragon Quest VIII.
  • Game size for Path B: 26,000 to 61,000 functions in the 3DS decomps we found.
  • Access to the exact armcc build. Without it, byte matching is not possible.
  • Whether you build golden runs early. Without them, every check needs you at the controller.

The facts behind these numbers

ProjectWhat happenedLink
Fire Emblem: Awakening for WindowsBuilt on 3dsrecomp and Zakuro. First commit 2026-11-05, v1.0.0 on 2026-11-08, v1.0.17 on 2026-11-12. One person; commits carry Claude trailers.source
Shin Megami Tensei IV RecompBuilt on 3dsrecomp and Zakuro. Title screen on 2026-10-13, the day of the first commit; first release 2026-10-16. One person; AI use not stated.source
Dragon Quest VIII 3DS RecompBuilt on 3dsrecomp and Zakuro by a non-programmer with AI. First commit and first release 2026-10-31; reached gameplay and battles.source
MSR2DSOwn recompiler. First commit 2026-10-08 (an Azahar import), emulator-based v1.0 on 2026-10-29, native v2.0 on 2026-11-05. Its own estimate was 1.5 to 3 months. Claude trailers on commits.source
TriAevum: Echoes of TimeOwn translator. Docs dated from 2026-07-29; public repo and first release 2026-09-07; 1,526 commits by 2026-11-12. README says entirely AI-assisted.source
A Link Between Worlds decompMany LLM agents. 16,544 matched functions at first publication on 2026-10-15. A relocation audit then removed 419. By 2026-10-28: 16,660 matched, 15,871 honest, of 25,986. The rest is a hard tail.source
Monster Hunter 4 Ultimate decompRepo 2026-10-07. By 2026-11-12: 32,615 of 39,637 functions (82.3%), but only 43.7% of code bytes matched. AI use not stated.source
zeldaret/oot3dHuman matching decomp started 2024-09-24. Only 15 commits by 2026-09-04; AI use not stated.source

Projects reviewed (10)

We took the top-starred project for each of the 10 games RecompLauncher lists for the 3DS. Two second projects for the same games were left out. None is a matching decomp, so Path B uses the 3DS decomps we found on GitHub, listed under sources.

What each project teaches

TriAevum: Echoes of Time

The Legend of Zelda: Ocarina of Time 3D

Top rated on RecompLauncherstatic recompplayable
own whole-AOT translator (Python)LLVM clang-clCMakeNinjaNRI and VulkanSDL2

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

AI: yes: the README says development is entirely AI-assisted under human direction; the tool is not named

Lesson: Check with saved checkpoints, not by eye. It compares frame pixels and game memory between old and new builds.

DekUI

The Legend of Zelda: Majora's Mask 3D

Top rated on RecompLauncheremulator-basedplayable
Azahar forkCMakeNinjaClangQt 6Vulkan

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

AI: yes: the README says AI was used heavily to find each element the game draws and move it to the top screen

Lesson: With no decomp, an emulator fork with a game layer still works. Keep a written release checklist next to the automated tests.

MSR2DS

Metroid: Samus Returns

Top rated on RecompLauncherstatic recompplayable
own Python recompilerCapstoneUnicornZigCMakeNinja

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

AI: yes: release commits carry Claude co-author trailers; a CLAUDE.md is in the history Agent files: CLAUDE.md (deleted; in history at commit 7fac0b0).

Lesson: Go in stages that each stay playable. It started as an emulator fork, swapped in recompiled code, then dropped the emulator.

Shin Megami Tensei IV Recomp

Shin Megami Tensei IV

Top rated on RecompLauncherstatic recompplayable
3dsrecompZakuroRust (GNU)MinGW-w64 gcc

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

AI: none stated

Lesson: With 3dsrecomp and Zakuro, the repo holds only glue. Use community cheat addresses as a map, then confirm each hook in the generated C.

Woohoo! Flight School

Pilotwings Resort

Top rated on RecompLauncherstatic recompplayable
arm2c.py (own)funcs.pyCMakeNinjaMinGW-w64SDL2

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

AI: yes: catalog flag set by the store; the repo says nothing

Lesson: A one-game recompiler can be small. Hash-gate the input, and count unsupported instructions so the build says what is missing.

Fire Emblem: Awakening for Windows

Fire Emblem: Awakening

Top rated on RecompLauncherstatic recompplayable
3dsrecompZakuroRustMinGW-w64 gccgit apply patches

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

AI: yes: most feature commits carry Claude co-author trailers; catalog flag

Lesson: Keep the repo a thin patch stack on pinned upstream commits. Add missed function starts as hints, not recompiler changes.

Clockwork

Yo-kai Watch

Top rated on RecompLauncherstatic recompplayable
own Rust recompilerctrxCMakeNinjaSDL3qemu-arm

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

AI: yes: catalog flag set by the store; the repo says nothing

Lesson: Test the emitted C against real ARM with random states, and break the emitter on purpose once to prove the test works.

Luigi's Mansion 2 Recompiled

Luigi's Mansion: Dark Moon

Top rated on RecompLauncherstatic recompin progress
Clockwork recompiler (pinned)MSVCCMakeNinjaDXCXbyak

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

AI: none stated

Lesson: Another game's recompiler can be reused. Pin it, patch it with scripts, and prove it first on one pure function.

Fire Emblem Fates Special Edition Recomp

Fire Emblem Fates: Special Edition

Top rated on RecompLauncherstatic recompplayable
3dsrecomp (prebuilt)Zakuro (prebuilt)ZigC# and .NET 10

Started: 2026-11. First release: 2026-11. Code: C#.

AI: yes: two commits end with 'Assisted-by: Cindy (cindy.app)', and cindy.app calls itself an open-source AI agent; the README says nothing

Lesson: A port can start as just a launcher. But it must name the tool versions, or nobody else can rebuild it.

Dragon Quest VIII 3DS Recomp

Dragon Quest VIII: Journey of the Cursed King

Top rated on RecompLauncherstatic recompin progress
3dsrecompZakuroCargo

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

AI: yes: the developer says he cannot program and built it with AI help

Lesson: A non-programmer reached gameplay with ready tools and AI. Without build steps in the repo, though, nobody can repeat it.

What we could not check

  • The time ranges are estimates. No project reports hours per week, and private work before each first commit is unknown.
  • No 3DS game has a finished matching decomp, and none has been ported from a decomp. The Path B port step is a plan, not a proven road.
  • How a hobbyist can get a legal copy of armcc is not settled. ALBW asks for your own licensed copy. matching-decomp-tools uses decomp.me's public armcc.zip; we did not check its licence terms.
  • The install steps for ghidra-ctr-loader are not in its README, and it was last updated in January 2024. It has no release; whether it builds against Ghidra 12 is unknown. We did not test it.
  • We did not run 3dsrecomp, Zakuro or ctrtool ourselves. Commands come from their READMEs, their source code (src/main.rs, cli.rs, lib.rs) and the project cards.
  • The Solstice tool names packets.py, functable.py and the RTTI tools come from its docs. We did not run them.
  • GhidraMCP asks for Ghidra 12.1.4, so the guide says to use that version with it. We did not test it with 12.2.
  • Whether AI was used on Shin Megami Tensei IV Recomp, Luigi's Mansion 2 and the MH4U decomp is not stated in their repos.
  • The 60 fps speed-up rule applies to the games tested by the Zakuro author and by Shin Megami Tensei IV. Other games may differ.
  • We could not read 3dbrew with our web tool, so we read its raw wiki text instead.
  • Zakuro's --headless report and its ZAKURO_RECORD and ZAKURO_REPLAY switches come from its source code. No reviewed project shows them in use.
  • decomp.me answered 403 to our scripted check, so its 3DS compiler list was read from its GitHub source instead.
  • The Solstice packet sizes come from its CLAUDE.md, measured on its own project. Other games may need other sizes.

Sources