Xbox decomp guide
An x86 console with two good recompilers: ports come fast, but a true decomp needs Microsoft's compiler.
What this system is like
The original Xbox runs x86 code, the same kind of code a PC runs. That makes it one of the easiest consoles to bring to a PC. Two free toolkits, xboxrecomp and XboxXBERecomp, turn a game's default.xbe into C or C++. Most of the 140 Xbox projects on RecompLauncher are recomps like these.
Path A is static recompilation. A tool translates every function ahead of time. You then fix one crash, one missing system call or one wrong picture at a time. Several dated projects with AI help reached a first release in three to four weeks. They started from a working toolkit.
Path B is harder. A matching decomp is possible. The Halo 1 decomp reports 99.5% of its bytes matching. Halo 2 has matched about 73% of its game code. But matching needs the exact Microsoft compiler from the Xbox SDK, called the XDK. Nobody may share it, and this guide cannot help you get it. Without it, you rewrite the recompiled functions as readable C, one at a time. You check each one by running it, not by its bytes.
Everything in this guide runs on Windows 11. Use WSL only for Linux builds and for project scripts written for bash. Keep your disc files outside the repo. The reviewed recomps ship no game code. They lift it on the player's PC from the player's own disc.
Same chip family as your PC
The Xbox CPU is x86, like your PC. The lifted code keeps the same byte order and the same math rules. The original machine code can even run inside a 32-bit test program, so xboxrecomp checks lifted C against the real CPU.
The SDK is inside every game
Each game carries its own copy of Direct3D 8, DirectSound and the C runtime. You must find that library code and replace it, not decompile it. xbe_symbols and XbSymbolDatabase find it by byte signatures.
Indirect calls are the hard part
Calls through a pointer have no fixed target. The xboxrecomp authors call them the hardest ten percent. Projects log every missed target, feed it back as a seed, and run the recompiler again.
Two ways to fake the graphics
Some ports replace Direct3D 8 calls with Direct3D 12 or Vulkan code. Others keep a model of the NV2A chip, taken from the xemu emulator. Both kinds reached playable games.
Matching needs a compiler nobody may share
Byte matching needs the exact XDK compiler. It is Microsoft's tool, and no open compiler copies its output yet. Halo 2 also used link-time code generation. That gives many functions their own odd ways to pass arguments.
Two paths
Get it running on PC
A recompiler reads default.xbe and writes one C or C++ function for each x86 function. A runtime stands in for the kernel, Direct3D 8, DirectSound and the pad. You build the result into a Windows program. Then you fix one boot stop at a time until the game plays. Thirteen of the fifteen reviewed projects work this way.
Full decomp for porting
You start from your working Path A build. You rewrite one recompiled function at a time as readable C. Each rewrite must act exactly like the lifted function, checked by running both. When no lifted game code is left, you drop the recompiler and port the code. If you lawfully own the right XDK compiler, you can match bytes instead, as Halo 2 does.
Path A: Get it running on PC
A recompiler reads default.xbe and writes one C or C++ function for each x86 function. A runtime stands in for the kernel, Direct3D 8, DirectSound and the pad. You build the result into a Windows program. Then you fix one boot stop at a time until the game plays. Thirteen of the fifteen reviewed projects work this way.
Method: static recompilation
Pick this first for any Xbox game. It is the fastest way to a running game. Its output also becomes the test oracle for Path B.
Scope the game and pin the exact disc
Pick one game and one release. Look for earlier ports, and for ports of sister games on the same engine. Pick the toolkit. Write the Scope Contract so every later session builds the same file.
- Search RecompLauncher and GitHub for your game and its engine. Athelas ports four Lord of the Rings games from one shared SDK.
- Extract your own disc with
extract-xiso -x <your.iso> -d game_files. - Record the hash in PowerShell:
Get-FileHash game_files/default.xbe -Algorithm SHA256. - Note the region. Most reviewed ports support one release only, such as USA for Def Jam or PAL for Finest Hour.
- Count the
.xbefiles. Splinter Cell: Double Agent has two, and each needs its own recompiled image. - Pick
XboxXBERecompfor a Windows port with Direct3D 12. Pickxboxrecompif you also want Linux or macOS. Its README names both. - Write
SCOPE.md: game, region, hash, toolkit and commit, milestone, and what is out of scope.
Prompt for ClaudeGOAL: Draft SCOPE.md for a static recompilation of <GAME> for the original Xbox. READ FIRST: `notes/game-files.txt` (my file list and the `default.xbe` SHA-256), `notes/prior-work.md` if it exists. 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 '^## (Game|Region|Hash|Executables|Toolkit|Milestone|Out of scope)$'`. Done means it prints 7 lines. The Hash section holds the same SHA-256 that `Get-FileHash game_files/default.xbe -Algorithm SHA256` prints. The Toolkit section names `XboxXBERecomp` or `xboxrecomp`, a commit, and one reason. BUDGET: Stop after 30 minutes of searching for prior work. 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: the Select-String output and both hashes. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenTheSelect-Stringcheck prints 7 lines, the Hash section equals theGet-FileHashoutput, and you have approvedSCOPE.md.Proof this works: Athelas, Def Jam FFNY Recomp, SCDA XBE Recomp, Finest Hour Remastered, https://github.com/XboxDev/extract-xiso
Set up the repo, the toolkit and one check
Make a repo that holds only your own code. Pin the toolkit to one commit. Write one script that builds and one that checks. Game files and generated code stay out of git.
- Install Visual Studio 2022 with Desktop development with C++, C++ Clang tools for Windows, and C++ CMake tools for Windows.
- Install Python 3.10 or newer, then run
py -3 -m pip install capstone pytest. - For
XboxXBERecomp, copy itstemplates/gamefolder and put the SDK insdk/at a pinned commit. - For
xboxrecomp, clone it beside your project and copytemplates/new-gameto start your game repo. - Add
assets/,game_files/,generated/andsrc/recomp/gen/to.gitignore. - Write
tools/check.ps1. It builds, starts the game with a time limit, and prints PASS or FAIL. - Write
CLAUDE.md,PROGRESS.mdandnotes/functions.csvwith a status column.
Prompt for ClaudeGOAL: Make `pwsh tools/check.ps1` build the project and print PASS or FAIL for the current milestone. READ FIRST: `SCOPE.md`, the toolkit README at `<TOOLKIT_DIR>/README.md`, `CLAUDE.md`. FENCE: Edit only `tools/`, `CMakeLists.txt`, `build.bat`, `.gitignore` and `PROGRESS.md`. The toolkit folder and `assets/` are read-only. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `pwsh tools/check.ps1`. Done means it runs to the end, prints PASS or FAIL with a reason, and `git status --porcelain --ignored assets generated` shows those folders as ignored. BUDGET: Stop after 4 failed tries at the same error. 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 whenpwsh tools/check.ps1runs from a clean clone and prints PASS or FAIL, and no game file shows ingit status.Proof this works: OpenShao, Darkwatch: Darker Edition, BLACK XBE Recomp, https://github.com/TGP482/XboxXBERecomp, https://github.com/sp00nznet/xboxrecomp
Map the XBE and find the library code
Read the file's sections, library versions and functions. Mark every XDK, C runtime and middleware function so nobody decompiles it by hand. Save it all as a ledger.
- For
xboxrecomp: runpy -3 -m tools.xbe_parser game_files/default.xbe --json game_files/default_analysis.json. - Then run
py -3 -m tools.disasm game_files/default.xbe, thenpy -3 -m tools.func_id game_files/default.xbe -v. - Then run
py -3 -m tools.abi_analysis game_files/default.xbe -v. Without it, every signature is a guess. - For
XboxXBERecomp: runxbe_symbols assets/default.xbe sdk/xdk --library <Game>.dll --out config/game.toml. Misses stay at 0 and become trapping stubs. - Load the XBE into Ghidra 12.1.4 with the
ghidra-xbeloader. It names library code withXbSymbolDatabase. - Write one row per function to
notes/functions.csv: address, size, owner (game, XDK, CRT, middleware), status.
Prompt for ClaudeGOAL: Fill `notes/functions.csv` with every function in `default.xbe` and mark who owns it. READ FIRST: `SCOPE.md`, `<TOOLKIT_DIR>/tools/disasm/output/functions.json` or `config/game.toml`, `notes/ghidra-export.csv` if it exists. FENCE: Edit only `notes/functions.csv`, `notes/findings.md` and `tools/make_ledger.py`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `py -3 tools/make_ledger.py --verify`. Done means it prints the function count, the count per owner, and zero rows with an empty owner or size. BUDGET: Stop after 90 minutes or 4 failed 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 verify output. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whennotes/functions.csvlists every function with size, owner and status, and the verify script reports no empty rows.Proof this works: Ninja Gaiden Black Recomp, Finest Hour Remastered, JSRF Unleashed, https://github.com/XboxDev/ghidra-xbe
- For
First light: lift everything and reach the first frame
Run the recompiler over the whole file. Build it. Start it and fix only what stops the first frame. Expect it to crash many times first.
- For
xboxrecomp: runpy -3 -m tools.recomp game_files/default.xbe --all --split 250 --gen-dir ../mygame/src/recomp/gen. - Then build:
cmake -S . -B buildandcmake --build build --config Release. - For
XboxXBERecomp: runbuild.bat. The first build lifts the whole game and can take 30 to 90 minutes. - Run the game with a time limit and save the log to
runs/<date>/log.txt. - Fix each stop with a toolkit setting or an override. Never edit the generated files.
- Save a screenshot of the first frame as the first golden picture.
Prompt for ClaudeGOAL: Make the recompiled <GAME> open a window and draw its first frame. READ FIRST: `SCOPE.md`, `PROGRESS.md`, the last 50 lines of `runs/latest/log.txt`, `<TOOLKIT_DIR>/docs/GETTING_STARTED.md` or `sdk/README.md`. FENCE: Edit only `src/` (not generated folders), `config/` and `notes/`. `generated/`, `src/recomp/gen/`, the toolkit and `assets/` are read-only. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `pwsh tools/check.ps1 -Boot`. Done means it prints PASS and saves `runs/latest/frame0.png` that is not all one colour. BUDGET: Fix one stop per try. Stop after 6 tries with no new progress. 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 and the last log lines. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenpwsh tools/check.ps1 -Bootprints PASS and the saved first frame shows the game's own picture.Proof this works: JSRF Unleashed, BLACK XBE Recomp, https://github.com/sp00nznet/xboxrecomp
- For
Grind the boot stops, one at a time
Each run stops somewhere new. Sort the stop into a type and apply the fix that type needs. Log every fix. This is where most Path A time goes.
- Missing function: add its address as a seed (
[functions]ingame.toml, or the seed JSON), then run the recompiler again. - Missed indirect call: read the
[ICALL]failure, add the target as a seed, then lift and build again. Ninja Gaiden Black automates this withtools/feedback.sh. - Recompiler bug: override that one function (
X86_FUNC(sub_XXXXXXXX)orrecomp_lookup_manual()). Report it upstream. - Missing kernel or XDK call: write it in the runtime. Check what
xemudoes first. - Check every seed. Takedawn found that log seeds split
memcpyand sent the game down a dashboard path. - Write each fix to
notes/boot-log.mdwith the stop address and the run that proved it.
Prompt for ClaudeGOAL: Get <GAME> past the stop at <ADDRESS or LOG LINE> without breaking any earlier golden run. READ FIRST: `PROGRESS.md`, `notes/boot-log.md`, the 50 log lines around the stop in `runs/latest/log.txt`, the row for <ADDRESS> in `notes/functions.csv`. FENCE: Edit only `config/`, `src/hooks/` or `src/game/`, and `notes/`. Generated code, the toolkit and `assets/` are read-only. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `pwsh tools/check.ps1 -Golden`. Done means every golden run prints PASS and the new run gets past <ADDRESS>. BUDGET: Stop after 2 runs that stop at the same place. Then compare the two logs and name the first difference before any new change. 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 whenpwsh tools/check.ps1 -Goldenprints PASS, and a run under one minute reaches the next natural event, such as the menu.Proof this works: Def Jam FFNY Recomp, Ninja Gaiden Black Recomp, Takedawn, DOAXVB RE
- Missing function: add its address as a seed (
Make graphics and sound match the real game
Most bugs now are wrong pictures and wrong sound. Use
xemurunning your own disc as the reference. Fix only what differs fromxemu, not what you think looks wrong.- Run the same scene in
xemuand in your build. Save a picture from each. - With
XboxXBERecomp, setXBE_CAPTURE_DIRand press F3 to save one frame's textures, shaders and state. - Ninja Gaiden Black keeps the
xemurenderer as a switch (NGB_RENDERER=xemu) to tell port bugs from game bugs. - Put each fix in
src/, one feature per file, such asfov.cpporfpsfixes.cpp. - Above 30 or 60 FPS, find the game's frame pacer. Darkwatch had a door that stayed shut at 144 FPS.
Prompt for ClaudeGOAL: Fix one graphics or sound difference: <SYMPTOM> in <SCENE>. READ FIRST: `notes/bugs.md` row <BUG_ID>, the capture summary in `runs/<RUN>/frame.txt`, the `xemu` reference picture `refs/<SCENE>.png`. FENCE: Edit only `src/gpu/`, `src/d3d/`, `src/audio/` or `src/game/`, and `notes/`. Generated code, the toolkit and `assets/` are read-only. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `pwsh tools/check.ps1 -Golden -Scene <SCENE>`. Done means it prints PASS and the compare score against `refs/<SCENE>.png` is within the limit in `tools/limits.json`. BUDGET: Stop after 4 tries, or if the cause is not proven after 45 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 and both scores. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenThe scene's compare check passes against thexemupicture and every older golden run still passes.Proof this works: Ninja Gaiden Black Recomp, OpenShao, Darkwatch: Darker Edition, Midtown Madness 3
- Run the same scene in
Harden: golden runs, regressions and headless tests
Old fixes must stay fixed. Build runs that start, play by script and stop by themselves. Then you can trust every later change.
- Feed pad input from a file and save frames at set times, as Ninja Gaiden Black does with
RECOMP_PAD_LIVEandNV2A_CAPTURE. - Run tests with no window and no sound. Point saves at a scratch folder, never your real saves.
- Keep a regression list: menu, first level, a save and load, a cutscene. Def Jam's full regression takes about an hour.
- Add a hygiene check that fails if any game file or generated code is staged. Def Jam runs
git add -A --dry-runbefore each commit. - Separate automated results from your own play tests in every report, as OpenShao requires.
Prompt for ClaudeGOAL: Add the scripted golden run <RUN_NAME> to `pwsh tools/check.ps1 -Golden`. READ FIRST: `tests/golden/README.md`, `notes/golden-runs.md`, one existing run in `tests/golden/<EXAMPLE>/`. FENCE: Edit only `tests/golden/<RUN_NAME>/`, `tools/check.ps1` and `notes/golden-runs.md`. Game code, generated code and `assets/` are read-only. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `pwsh tools/check.ps1 -Golden` twice. Done means both runs print PASS for <RUN_NAME>, and a run with the pad file removed prints FAIL. BUDGET: Stop after 4 failed 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 all three outputs. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenThe full golden set passes twice in a row on a clean checkout, and a broken input makes it fail.Proof this works: Ninja Gaiden Black Recomp, Def Jam FFNY Recomp, OpenShao, Midtown Madness 3
- Feed pad input from a file and save frames at set times, as Ninja Gaiden Black does with
Package it so players build from their own disc
Ship your code, never the game's. The player supplies the disc. Your launcher checks the hash, then builds the game code on the player's PC.
- Check the player's
default.xbeby SHA-256 before building. Darkwatch refuses any other file. - Build the game code on first start. A release made with
XboxXBERecompships the recompiler, Clang and LLD for this, as SCDA's does. - Pin every dependency and the LLVM version. Finest Hour's build comes out byte for byte the same as its release.
- Accept a full
.iso, a trimmed.xiso, or a folder. Read the game part at offset0x18300000for a full image. - Expect antivirus warnings for an unsigned launcher. Say so in the README.
Prompt for ClaudeGOAL: Make `pwsh tools/package.ps1` produce a release folder that holds no game code or game data. READ FIRST: `SCOPE.md`, `tools/package.ps1`, `notes/release-checklist.md`. FENCE: Edit only `tools/package.ps1`, `launcher/` and `notes/release-checklist.md`. Game code, generated code and `assets/` are read-only. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `pwsh tools/package.ps1 -Out dist/test` then `py -3 tools/hygiene.py dist/test`. Done means hygiene prints PASS, and a fresh install from `dist/test` boots to the menu with my disc. BUDGET: Stop after 4 failed 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 both outputs. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenThe hygiene check passes on the release folder and a clean install boots to the menu from your own disc.Proof this works: Darkwatch: Darker Edition, Finest Hour Remastered, SCDA XBE Recomp, The Warriors Recomp
- Check the player's
Path B: Full decomp for porting
You start from your working Path A build. You rewrite one recompiled function at a time as readable C. Each rewrite must act exactly like the lifted function, checked by running both. When no lifted game code is left, you drop the recompiler and port the code. If you lawfully own the right XDK compiler, you can match bytes instead, as Halo 2 does.
Method: non-matching decompilation on top of a recomp (matching only with your own lawful XDK compiler)
Pick this only after Path A plays. Pick it when you want source code you can read, change and build for other systems. Expect months to years.
Scope: matching or non-matching
Find out which XDK built your game. Decide how each function will be checked. Matching needs Microsoft's compiler for that exact XDK. Without it, use the behaviour check.
- Read the library versions with
py -3 -m tools.xbe_parser game_files/default.xbe --json game_files/default_analysis.json. - Look for an existing decomp first. Halo 1 (
punpckhdq/halo) and Halo 2 (kirklandsig/halo2-decompiled) exist. - Check for RTTI class names. The
xboxrecompdocs say Half-Life 2 for Xbox yields 2,336 class names. - Write the check method into
SCOPE.md: byte match, or behaviour match against the lifted function andxemu. - Write down that SDK, Bink and other library code is replaced, not decompiled, as Halo 2 and DOAXVB do.
Prompt for ClaudeGOAL: Add a Path B section to SCOPE.md that names the check every rewritten function must pass. READ FIRST: `SCOPE.md`, `game_files/default_analysis.json` (library versions), `notes/prior-work.md`. 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. Do not search for, download or link any XDK or SDK file. CHECK: Run `Select-String -Path SCOPE.md -Pattern '^## (Path B check|XDK build|Library code|Out of scope B)$'`. Done means it prints 4 lines, and the XDK build matches the version in the analysis JSON. 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: the Select-String output and the version line. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenTheSelect-Stringcheck prints 4 lines, the XDK build matches the analysis JSON, and you approvedSCOPE.md.Proof this works: https://github.com/kirklandsig/halo2-decompiled, https://github.com/punpckhdq/halo, DOAXVB RE, https://github.com/sp00nznet/xboxrecomp/blob/main/docs/DECOMP.md
- Read the library versions with
Set up the per-function checks
Build the tools that judge one function. Split the XBE into one file per function. Make the conformance check run. Make a way to swap in your C for one function.
- Split the code:
py -3 -m tools.split game_files/default.xbe --out build/split. Each.sfile holds the exact bytes. - Run the conformance check once:
py -3 -m tools.conformance. It runs real x86 code and lifted C on the same inputs. - Pick the swap method. DOAXVB registers hand-written functions in
recomp_lookup_manual(). Ninja Gaiden Black usestools/take_function.pyandsrc/manual_functions.json. - Write
tools/fncheck.ps1 <ADDR>. It builds with your C swapped in, then runs the golden runs. - Matching only: Halo 2 uses
python tools/check.py, which builds the whole game and compares every function's bytes.
Prompt for ClaudeGOAL: Make `pwsh tools/fncheck.ps1 <ADDR>` judge one rewritten function by behaviour. READ FIRST: `SCOPE.md` (Path B check), `<TOOLKIT_DIR>/docs/DECOMP.md`, `build/split/manifest.json` entry for <ADDR>. FENCE: Edit only `tools/fncheck.ps1`, `tools/` helpers and `notes/`. Game sources, generated code and `assets/` are read-only. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `pwsh tools/fncheck.ps1 <KNOWN_GOOD_ADDR>` and `pwsh tools/fncheck.ps1 <ADDR> -Broken`. Done means the first prints PASS and the second, with one constant changed on purpose, prints FAIL. BUDGET: Stop after 4 failed 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 both outputs. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenThe check passes a known-good function and fails a function you broke on purpose.Proof this works: DOAXVB RE, Ninja Gaiden Black Recomp, https://github.com/sp00nznet/xboxrecomp/blob/main/docs/DECOMP.md
- Split the code:
Map the game code and pick an order
Only game-owned code gets rewritten. Order the work so callees come before callers. Group functions by the data they share.
- Copy the owner column from
notes/functions.csv. Drop XDK, C runtime, Bink and other middleware rows. - Use
called_byandcalls_toinbuild/split/manifest.jsonto list leaf functions first. - Group by data clusters. DOAXVB found that lifted neighbours depend on fixed addresses and layouts.
- Trust
detection_method. A function found byprologueis real. One found byimm_ref_targetis a guess. - Add columns: cluster, rewrite status, check result, and who holds it.
Prompt for ClaudeGOAL: Add cluster and order columns to `notes/functions.csv` for every game-owned function. READ FIRST: `notes/functions.csv`, `build/split/manifest.json`, `SCOPE.md` (Library code section). FENCE: Edit only `notes/functions.csv`, `notes/clusters.md` and `tools/order.py`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `py -3 tools/order.py --verify`. Done means every game-owned row has a cluster and an order number, no library row has one, and every function comes after all its game-owned callees. BUDGET: Stop after 90 minutes or 4 failed 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 verify output. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenThe order check passes and the ledger shows how many game functions are left to rewrite.Proof this works: DOAXVB RE, https://github.com/sp00nznet/xboxrecomp/blob/main/docs/DECOMP.md, https://github.com/kirklandsig/halo2-decompiled
- Copy the owner column from
First light: one function, end to end
Prove the whole loop on one small leaf function. Rewrite it, swap it in, and pass the check. Then the loop is ready for many workers.
- Pick a leaf with no calls that the conformance check can run.
- Read its
.sfile inbuild/split/asm/text/. The bytes are data and the instructions are comments. - Write clear C in
src/decomp/<cluster>/. Register it as an override of the lifted function. - Run
pwsh tools/fncheck.ps1 <ADDR>and the full golden set. - Matching only: the function counts when
python tools/check.py <va>reports it as matched.
Prompt for ClaudeGOAL: Rewrite `sub_<ADDR>` as readable C that acts exactly like the lifted version. READ FIRST: `build/split/asm/text/sub_<ADDR>.s`, its row in `notes/functions.csv`, `include/game/`. FENCE: Edit only `src/decomp/<CLUSTER>/<NAME>.c` and the override list. Generated code, the toolkit and `assets/` are read-only. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `pwsh tools/fncheck.ps1 <ADDR>` and `pwsh tools/check.ps1 -Golden`. Done means both print PASS and the function no longer calls its lifted copy. BUDGET: Stop after 5 tries with no gain. IF BLOCKED: Stop. Keep the last passing version. 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: both outputs. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenOne game function runs from your C, its check passes, and all golden runs still pass.Proof this works: DOAXVB RE, Ninja Gaiden Black Recomp, https://github.com/kirklandsig/halo2-decompiled/blob/main/docs/START_HERE.md
Grind: rewrite functions in parallel
Now many workers each take one function or one small cluster. Each works in its own worktree. A lead merges only work that passes on the merged branch.
- Hand out the next functions with no open callees, smallest first.
- One worker per function or cluster, in its own git worktree. Halo 2 lets contributors claim ranges of up to
0x2000bytes. - Run the full golden set after every merge, not only in the worktree.
- Never keep a change that makes an earlier passing function fail. Halo 2's prompt makes this a hard rule.
- Send functions that fail five tries to a hard-job queue.
Prompt for ClaudeGOAL: Rewrite the next <N> ready functions in cluster <CLUSTER> as readable C. READ FIRST: `notes/functions.csv` rows with status `ready` in <CLUSTER>, `notes/clusters.md`, the `.s` files in `build/split/asm/`. FENCE: Edit only `src/decomp/<CLUSTER>/` and the override list. Generated code, other clusters, the toolkit and `assets/` are read-only. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: For each function run `pwsh tools/fncheck.ps1 <ADDR>`. At the end run `pwsh tools/check.ps1 -Golden`. Done means every kept function prints PASS and the golden set passes. BUDGET: Stop after 5 tries per function. Skip it and mark it `hard`. 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: the per-function results and the golden output. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenpwsh tools/check.ps1 -Goldenprints PASS on the merged branch, and the ledger shows the cluster's functions as rewritten.Proof this works: https://github.com/kirklandsig/halo2-decompiled, DOAXVB RE
Name things and recover the data types
Working C with
sub_names is not yet a readable decomp. Give functions, fields and files real names based on what the code does. Do not change behaviour while you rename.- Name by what the code does, or keep
function_<va>. Halo 2 bans names from leaked symbols or debug builds. - Build structs from the fields functions read. Check each size and offset against the code.
- OpenCE generates headers from a PDB and checks every struct size and offset. Use that only if your PDB is lawful.
- Move functions into files named after their subsystem.
- Run the full check after every rename batch. Nothing may change.
Prompt for ClaudeGOAL: Give the functions and structs in cluster <CLUSTER> real names and types without changing behaviour. READ FIRST: `src/decomp/<CLUSTER>/`, `notes/clusters.md`, `notes/findings.md`. FENCE: Edit only `src/decomp/<CLUSTER>/`, `include/game/` and `notes/findings.md`. Generated code and `assets/` are read-only. Do not use names from leaked source, PDBs or maps. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `pwsh tools/check.ps1 -Golden` and `py -3 tools/struct_check.py <CLUSTER>`. Done means both print PASS, and every new name has a line in `notes/findings.md` saying how you know it. BUDGET: Stop after 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: both outputs. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenThe cluster has nosub_names left, the struct check passes and the golden set passes.Proof this works: https://github.com/kirklandsig/halo2-decompiled, OpenCE
- Name by what the code does, or keep
Harden: compare a whole playthrough
Per-function checks miss bugs between functions. Replay recorded input in your build and in
xemu, then compare frames. Make the game deterministic first so frames can match.- Futurama replays full playthroughs on the port and the original, and reports all 752,000 frames matching.
- Turn off fused multiply-add with
-ffp-contract=offon Clang. Fix timing and random seeds. - Find original bugs that read uninitialised memory. Give them fixed values and list each in a bug table.
- Keep a list of original bugs you left alone, so nobody fixes them by mistake.
Prompt for ClaudeGOAL: Make the replay of `tests/replays/<LEVEL>.pad` match the `xemu` reference frames. READ FIRST: `tests/replays/README.md`, `refs/<LEVEL>/` frame list, `notes/original-bugs.md`. FENCE: Edit only `src/decomp/`, `tests/replays/` and `notes/`. `refs/`, generated code and `assets/` are read-only. Do not edit reference frames or loosen limits. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `py -3 tools/replay_compare.py <LEVEL>`. Done means it prints PASS and 0 differing frames. BUDGET: Stop after 3 tries on the same first differing frame. 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 compare output and the first differing frame number. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenpy -3 tools/replay_compare.py --allprints PASS with 0 differing frames on a clean checkout.Proof this works: Futurama: The Game, OpenCE
Port: replace the console layer
Once no lifted game code remains, drop the recompiler. Put a thin layer under the game that does Direct3D 8, DirectSound and the pad on the new system. Keep the game sources almost unchanged.
- OpenCE builds the Halo CE decomp nearly unchanged. Its
d3d8_gl.cdoes Direct3D 8 on OpenGL, and SDL3 does sound and input. - Mark every change to decompiled files with a fixed comment, such as
port:. - Keep 32-bit struct layouts. OpenCE builds with Clang in MSVC's style:
-fms-extensions -fshort-wchar -malign-double -fcommon. - Read assets from the player's disc image at run time, as Futurama does with its
Xdvdfsreader. - Run the same replays on the new system. Use WSL with Ubuntu 24.04 for the Linux build.
Prompt for ClaudeGOAL: Build <GAME> for <TARGET> with the console layer and no recompiled code. READ FIRST: `SCOPE.md`, `port/README.md`, `notes/port-plan.md`. FENCE: Edit only `port/` and lines in `src/decomp/` marked `port:`. Every other game source line is read-only. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `py -3 tools/ci_build.py <TARGET> release` then `py -3 tools/replay_compare.py --all --target <TARGET>`. Done means the build has no recomp sources and every replay prints PASS. BUDGET: Stop after 4 tries at the same error. 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 both outputs. 3) Files changed. 4) What is left. 5) New parking-lot items.
Done whenThe new build contains no lifted code and passes the same replays as the PC build.Proof this works: OpenCE, Futurama: The Game
- OpenCE builds the Halo CE decomp nearly unchanged. Its
Tools you need
| Tool | What it does | How to get it | How we know |
|---|---|---|---|
| xboxrecomp Required both | A Python pipeline that parses, maps and lifts an XBE to C, plus runtime libraries for the kernel, graphics, sound and pad. It also splits the XBE into one file per function and runs a check against the real CPU. Path A Path B | `git clone https://github.com/sp00nznet/xboxrecomp.git`, then `git checkout v0.17.0` (or the commit your project pins) | README, docs/DECOMP.md and lessons-learned.md (read 2026-11-13); used by: JSRF Unleashed, Ninja Gaiden Black Recomp, Takedawn, DOAXVB RE, Def Jam FFNY Recomp, Midtown Madness 3 |
| XboxXBERecomp Required Windows | A recompiler that turns an XBE into C++ for 64-bit Windows, with Direct3D 12 and XAudio2. Its xbe_symbols tool finds XDK functions and writes game.toml. It also handles games built with link-time code generation.Path A | Copy or add as a submodule at `sdk/`: `git submodule add https://github.com/TGP482/XboxXBERecomp sdk`, then check out one commit | README (read 2026-11-13): sdk/ install, templates/game, xbe_symbols command, LTCG support, F3 capture; no releases; the names XboxXBE-Recomp and Xbox-XBERecomp redirect here; used by: BLACK, SCDA, OpenShao, Darkwatch, Athelas, Finest Hour, The Warriors |
| extract-xiso Required both | Lists and extracts the files on an Xbox disc image. Use -x to extract and -d to pick the folder.Path A Path B | Download `extract-xiso-Win64_Release.zip` from the latest release and unzip it | README and release build-202609111233 (read 2026-11-13); used by: The Warriors, DOAXVB RE, Def Jam FFNY Recomp |
| Python 3 with capstone Required both | Runs the xboxrecomp pipeline and the check scripts. capstone is the x86 disassembler the pipeline uses.Path A Path B | Install Python 3.10 or newer, then `py -3 -m pip install capstone pytest`. Pin the version your project uses, such as `capstone==5.0.9` | PyPI shows capstone 5.0.9 (read 2026-11-13); DOAXVB pins 5.0.9, Midtown Madness 3 pins 5.0.7 |
| Visual Studio 2022 with Clang, CMake and Ninja Required Windows | The Windows compilers and build tools. XboxXBERecomp needs its Clang tools. xboxrecomp builds with MSVC.Path A Path B | Run the Visual Studio 2022 installer. Pick Desktop development with C++, C++ Clang tools for Windows, and C++ CMake tools for Windows | used by: BLACK XBE Recomp, SCDA XBE Recomp, Finest Hour Remastered (build steps in their cards); xboxrecomp README prerequisites (read 2026-11-13) |
| Ghidra 12.1.4 Helpful both | A free disassembler and decompiler. You use it to study functions and name library code. Path A Path B | Download `ghidra_12.1.4_PUBLIC_20260921.zip` from the releases page and unzip it. Install the JDK version that Ghidra's install guide names. `GhidrAssistMCP` needs Java 25 or newer | release list (read 2026-11-13): 12.2 is newest, but ghidra-xbe and GhidraMCP target 12.1.4; used by: OpenShao, DOAXVB RE, Def Jam FFNY Recomp |
| ghidra-xbe Helpful both | A Ghidra loader for .xbe files. It names XDK library functions by matching them against XbSymbolDatabase.Path A Path B | Download `ghidra_12.1.4_PUBLIC_20261016_ghidra-xbe.zip` and copy it into Ghidra's `Extensions/Ghidra` folder. Start Ghidra, pick File, Install Extensions, and select `XboxExecutableLoader` | README and release build-202610161023 (read 2026-11-13); linked from the JSRF Unleashed card |
| XbSymbolDatabase Helpful both | A library of byte patterns that find XDK functions in a game. It works inside ghidra-xbe and other tools.Path A | Nothing to install by hand. It comes inside `ghidra-xbe` | README (read 2026-11-13); used by: Ninja Gaiden Black Recomp (names 97 Direct3D functions), Athelas |
| xemu Helpful both | An original Xbox emulator. Projects use it as the reference for how the real game should look, sound and behave. Path A Path B | Download `xemu-0.8.139-windows-x86_64.zip` and unzip it. It needs an MCPX boot ROM, a BIOS and a hard disk image. Read xemu's Required Files page first: it says to dump the ROM and BIOS from your own Xbox, offers a blank disk image, and warns that a plain retail BIOS cannot boot games | release v0.8.139 assets and xemu.app required-files page (read 2026-11-13); used by: Ninja Gaiden Black Recomp, DOAXVB RE, Midtown Madness 3, Def Jam FFNY Recomp |
| llvm-mingw Helpful WSL/Linux | A Clang toolchain that builds Windows programs from Linux. Some projects build their Windows release this way inside WSL. Path A Path B | In WSL, download `llvm-mingw-20261104-ucrt-ubuntu-22.04-x86_64.tar.xz` from the releases page and unpack it | release 20261104 (read 2026-11-13); used by: JSRF Unleashed, Ninja Gaiden Black Recomp, Takedawn, DOAXVB RE |
| XboxLLR Helpful Windows | A third Xbox recompiler, in early beta. It stops with a clear error at any target it cannot handle, instead of guessing. Path A | Download `xboxllr-build-tool-windows-x64-2026.11.13.1.zip` from its releases. MSVC and CMake are still needed | README (read 2026-11-13): Blinx and JSRF are its only public games; listed in research/topics/ai-decomp-practice.md B3 |
| PowerShell 7 Required Windows | Runs the pwsh scripts that every check in this guide uses, such as pwsh tools/check.ps1.Path A Path B | `winget install --id Microsoft.PowerShell --source winget` | Microsoft install page (read 2026-11-13); Darkwatch builds with PowerShell 7 scripts |
| Git Required both | Clones the toolkits and keeps your repo. Its worktrees let parallel workers each have their own copy. Path A Path B | `winget install --id Git.Git -e --source winget` | git-scm.com Windows install page (read 2026-11-13); every reviewed project is a git repo, and OpenShao, Takedawn and Def Jam build steps start with git clone |
| WSL Helpful Windows | Runs Linux inside Windows 11. You need it only for a Linux build, bash-only scripts and llvm-mingw.Path A Path B | `wsl --install`, then pick an Ubuntu name from `wsl --list --online` and run `wsl --install -d <DistroName>` | Microsoft WSL install page (read 2026-11-13); used for Linux work by: JSRF Unleashed, Ninja Gaiden Black Recomp, Takedawn |
| XDK compiler (only for matching) Helpful Windows | The Microsoft compiler that built the game, such as cl 13.10.3077 in XDK 5849. Byte matching is impossible without the exact one.Path B | Not available for download. Use it only if you lawfully have it. No project, and not this guide, will help you get it | halo2-decompiled README and docs/START_HERE.md, punpckhdq/halo 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.
debug-game-in-emulator
It runs xemu the same way every time: a throwaway data folder, a log and a time limit. Claude must name the failing layer before changing code. It refuses to fetch a BIOS.
npx skills add xsyetopz/skills --skill debug-game-in-emulator -a claude-code
x86-cpp-reversing
A method for rebuilding the C++ classes of a 32-bit x86 program. Every finding must point to an instruction. That fits Path B struct work. It needs radare2, binutils and Python LIEF.
npx skills add gavmor/x86-cpp-reversing-skill --skill x86-cpp-reversing -a claude-code
reverse-engineer-binary
Claude must read the assembly first and give an address with every claim. Install the Ghidra bridge yourself, not through the skill.
npx skills add xsyetopz/skills --skill reverse-engineer-binary -a claude-code
decompile-to-matching-c-cpp
Rules against fake matches, with notes for MSVC on x86. Use it only on the matching route, with your own lawful XDK compiler. Its tool list, such as splat and m2c, is for other systems, so use only its rules.
npx skills add xsyetopz/skills --skill decompile-to-matching-c-cpp -a claude-code
verification-before-completion
Claude may not say done without fresh proof. DOAXVB's rule is the same: a crash-free run is not gameplay progress.
npx skills add obra/superpowers --skill verification-before-completion -a claude-code
systematic-debugging
No fix until the cause is proven. That matches Def Jam's rule to compare two failed runs before the next change.
npx skills add obra/superpowers --skill systematic-debugging -a claude-code
handoff
Writes a short note for the next session. Tell it to save inside the repo, the way Def Jam rewrites its handoff section in PROGRESS.md.
npx skills add mattpocock/skills --skill handoff -a claude-code
GhidraMCP
Claude can list, decompile and rename functions in your open Ghidra project. It targets the same Ghidra version as ghidra-xbe. It and GhidrAssistMCP both use port 8080 by default, so run one at a time or change a port.
Install uv. Download `GhidraMCP-release-2-0.zip`. In Ghidra 12.1.4, pick File, Install Extensions, and add the `ghidra_12.1.4_PUBLIC_<date>_GhidraMCP.zip` from that download. Restart Ghidra and turn on `GhidraMCPPlugin` under File, Configure, Developer. Then run `claude mcp add ghidra -- uvx --from git+https://github.com/LaurieWired/GhidraMCP ghidra-mcp --ghidra-server http://127.0.0.1:8080/`
GhidrAssistMCP
DOAXVB RE uses it. Its rule: pass program_name on every call and check which file is open first.
Run Ghidra on Java 25 or newer. Add `ghidra_12.1_PUBLIC_20261009_GhidrAssistMCP-3.0.0.zip` with File, Install Extensions, Add Extension. Then run `claude mcp add --transport http ghidrassist http://localhost:8080/mcp`
triage-run (write your own)
Def Jam keeps this exact skill, because its logs reach hundreds of megabytes. It turns every crash into the same short report.
A skill in `.claude/skills/triage-run/SKILL.md`. Input: a run folder. It runs `py -3 tools/triage.py <run> --tail 80` and `--grep ICALL`, never reads the whole log, and writes ten lines: stop type, stop address, last ICALL targets, and the fix type from the fix order.
take-function (write your own)
Ninja Gaiden Black does this with tools/take_function.py. Every Path B rewrite then starts from the same copy, so later differences are your edits.
A skill in `.claude/skills/take-function/SKILL.md`. Input: one address. It copies that lifted function into `src/decomp/unsorted/sub_<ADDR>.c`, adds the address to the override list, rebuilds, and runs `pwsh tools/fncheck.ps1 <ADDR>`. It stops if the address is not in the ledger.
Claude setup for this system
Cut Path A by stop point. One unit is one boot stop, one missed call target, or one wrong picture, each with a repro run. Cut Path B by function or small data cluster. One unit is one rewritten function with its behaviour check. Keep XDK, C runtime and middleware out of every unit. A unit ends with the golden runs, never with a build alone.
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 disc, the region and the toolkit. Look for sister games on the same engine. For Path B, decide matching or behaviour checks. Write SCOPE.md. | 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 | Install Visual Studio with Clang, pin the toolkit commit, and write tools/check.ps1. Add the ignore rules that keep disc files and generated code out of git. | Opus 5.5 effort medium | Sonnet 5.5 effort medium |
| Study the game file | Run the map tools and Ghidra with ghidra-xbe. Mark library code. Find missed functions and jump tables. Record each finding with its address and how you know it. | Opus 5.5 effort high | Opus 5.5 effort mediumRaise to high for function edges and data layouts. A mistake there spreads. |
| Bulk units | Add seeds for missed functions, one address each. In Path B, rewrite small leaf functions that the check can prove. | 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 | Indirect calls through broken object tables, x87 math, exception handlers, high-FPS timing, and functions that failed five bulk 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. |
| Build the runtime | Kernel calls, Direct3D 8 on Direct3D 12 or Vulkan, DirectSound, the pad, saves and movies. Check each against xemu. | Opus 5.5 effort high | Opus 5.5 effort mediumRaise to high for timing and graphics bugs. |
| Find a bug | Crashes, hangs and wrong pictures. Use the ICALL trace, frame captures, log slices and xemu. Prove the cause before the 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. |
| Check the work | A fresh session reruns the golden runs and reads the diff. It hunts for edits to generated code, new stubs, forced game state and loosened limits. | Opus 5.5 effort mediumAlways a new session, never the one that did the work. | Sonnet 5.5 effort highAlways a new session, never the one that did the work. |
| Keep the records | Update PROGRESS.md, notes/functions.csv, notes/boot-log.md and the bug list after each unit. | Haiku 5.5 effort medium | Haiku 5.5 effort medium |
How many sessions at once
Max 20x (now called Ultra)
Run one lead and three to five workers, each in its own worktree. Path A bugs often share state, so keep debug work to one or two sessions. Run only one game at a time per machine, as Def Jam requires. Path B can use more workers, one per function cluster.
Max 5x (now called Max)
Run one lead and one or two workers. Give workers seeds and leaf functions. Keep debug, runtime and hard jobs to one at a time.
Lines for this project's CLAUDE.md
- Read `SCOPE.md` and `PROGRESS.md` at the start of every session. - Never edit generated code in `generated/` or `src/recomp/gen/`. Fix the recompiler config, a seed or an override instead. - `assets/`, `game_files/` and the toolkit folder are read-only. Never commit an XBE, disc image, lifted code, saves or captures. Run `git add -A --dry-run` before every commit. - The only proof is `pwsh tools/check.ps1 -Golden`. A clean build or a crash-free run is not progress. - Report what you saw happen. Forcing the game into a state is a guess, not a result. - After two runs stop at the same place, stop changing things. Compare both logs and name the first difference. - Never read a whole run log. Use `py -3 tools/triage.py` with `--tail`, `--grep` or `--around`. - Run the game only under a time limit, with no window on my desktop and no sound. Stop only your own process, by its ID. - Record every finding in `notes/findings.md`: address, what it does, how you know, and confidence. Record dead ends too. - Do not move the toolkit pin unless I ask. Play-test the new pin before anything else. - In a worktree, use absolute paths and run the full check before you report. - Start every report with DONE, PARTIAL or BLOCKED, then paste the check output.
Keep the context small
- Never let Claude list or read the generated folder. Point it at one function by name.
- Give the stop address and 50 log lines, not the whole log. Def Jam's logs reach hundreds of megabytes.
- Store Ghidra results as short conclusions, such as an address and what it does. OpenShao keeps only text notes.
- Add
Read(./assets/**)andRead(./game_files/**)topermissions.denyin.claude/settings.json. - Keep a code map that lists which file holds each feature, as Darkwatch does in
CODE_MAP.md. - Use
/clearbetween units. The state lives in the ledger files, not the chat.
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 check
Before any work on a new Xbox game.
GOAL: Tell me if <GAME> can be ported with an existing Xbox recompiler, and draft SCOPE.md. READ FIRST: `notes/game-files.txt` (file list and `default.xbe` SHA-256), the output of `py -3 -m tools.xbe_parser game_files/default.xbe --json game_files/default_analysis.json`. FENCE: Edit only `SCOPE.md` and `notes/prior-work.md`. Everything else is read-only. Do not download any game file, BIOS, key or SDK. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `Select-String -Path SCOPE.md -Pattern '^## (Game|Region|Hash|Executables|XDK build|Toolkit|Prior work|Risks|Milestone)$'`. Done means it prints 9 lines, the Hash section equals what `Get-FileHash game_files/default.xbe -Algorithm SHA256` prints, and Prior work gives a URL for every project. BUDGET: Stop after 45 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: the section list and the hash line. 3) Files changed. 4) What is left. 5) New parking-lot items.
A good answer: A one-page SCOPE.md with the hash, the number of XBE files, the XDK build, two or three earlier projects, and a plain risk list.
Map the binary
Once the toolkit runs, before the first lift.
GOAL: Produce `notes/functions.csv` with one row per function in `default.xbe`. READ FIRST: `<TOOLKIT_DIR>/tools/disasm/output/functions.json`, `<TOOLKIT_DIR>/tools/func_id/output/`, `notes/ghidra-export.csv`. FENCE: Edit only `notes/functions.csv`, `notes/findings.md` and `tools/make_ledger.py`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `py -3 tools/make_ledger.py --verify`. Done means it prints the total, the count per owner (game, XDK, CRT, middleware, unknown), and zero empty rows. BUDGET: Stop after 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: the verify output. 3) Files changed. 4) What is left. 5) New parking-lot items.
A good answer: A ledger with thousands of rows, a short count per owner, and a list of low-confidence rows in notes/findings.md.
Unit loop, Path A: one boot stop
Each time the game stops in a new place.
GOAL: Get past the stop at <ADDRESS>. READ FIRST: the triage summary from `py -3 tools/triage.py runs/latest --tail 80`, `notes/boot-log.md`, the ledger row for <ADDRESS>. FENCE: Edit only `config/`, `src/hooks/`, `src/game/` and `notes/boot-log.md`. Generated code, the toolkit and `assets/` are read-only. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `pwsh tools/check.ps1 -Golden`. Done means all golden runs pass and a new run gets past <ADDRESS>. BUDGET: Stop after 2 runs that stop at the same address. 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: the check output and the new stop. 3) Files changed. 4) What is left. 5) New parking-lot items.
A good answer: DONE, one seed or one override, a new boot-log line naming the stop type, and every golden run still passing.
Unit loop, Path B: one function
Each time a worker rewrites one lifted function.
GOAL: Rewrite `sub_<ADDR>` as readable C that acts exactly like the lifted version. READ FIRST: `build/split/asm/text/sub_<ADDR>.s`, its row in `notes/functions.csv`, `include/game/`. FENCE: Edit only `src/decomp/<CLUSTER>/<NAME>.c` and the override list. Generated code and `assets/` are read-only. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `pwsh tools/fncheck.ps1 <ADDR>` and `pwsh tools/check.ps1 -Golden`. Done means both print PASS and the function no longer calls its lifted copy. BUDGET: Stop after 5 tries with no gain. IF BLOCKED: Stop. Keep the last passing version. 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: both outputs. 3) Files changed. 4) What is left. 5) New parking-lot items.
A good answer: DONE with two PASS lines, one new file, plain loops instead of goto, and no call to the lifted function.
Batch dispatch (lead session)
When the ledger has many ready units and you want several workers.
GOAL: Start one worker for each of the next <N> ready units and collect their reports. READ FIRST: `notes/functions.csv` (status `ready`), `notes/claims.md`, the unit loop prompt in `prompts/unit-loop.md`. FENCE: Edit only `notes/claims.md` and `PROGRESS.md`. Workers edit only their own unit's files, each in its own worktree. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: After merging, run `pwsh tools/check.ps1 -Golden` on the main branch. Done means it prints PASS, and `notes/claims.md` shows each unit as merged, failed or hard. BUDGET: At most <N> workers at once. Each worker has 5 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: the check output after merge. 3) Files changed. 4) A table of units and results. 5) New parking-lot items.
A good answer: A table of units with merged, failed or hard, one golden PASS on the merged branch, and no two workers on the same files.
Debug with evidence
A crash, hang or wrong picture whose cause is not known.
GOAL: Find the proven cause of <BUG>. Do not fix it yet. READ FIRST: `notes/bugs.md` row <BUG_ID>, `py -3 tools/triage.py runs/<RUN> --around <ADDRESS>`, the matching `xemu` run notes. FENCE: Read-only, except `notes/bugs.md` and `notes/findings.md`. You may add logging in `src/hooks/debug_<BUG_ID>.c`. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `git status --porcelain`. Done means it shows changes only in `notes/` and `src/hooks/debug_<BUG_ID>.c`. You name one cause, show the log lines or capture that prove it, and describe a test that would fail if you are wrong. BUDGET: Stop after 3 runs, or 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: the evidence lines. 3) Files changed. 4) The fix you suggest. 5) New parking-lot items.
A good answer: One named cause, such as a missed jump table at an address, with the log lines and a test that would prove it wrong.
Verify (hunt for cheating)
After any unit a worker calls DONE. Always in a fresh session.
GOAL: Check that the work in branch <BRANCH> is real. READ FIRST: `git diff main...<BRANCH>`, the worker's report, `CLAUDE.md`. FENCE: Read-only. Write only `notes/reviews/<BRANCH>.md`. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `pwsh tools/check.ps1 -Golden` on the branch. Done means you list: any edit to generated code, the toolkit, `refs/` or `tools/check.ps1`; any new stub or forced state; any loosened limit or skipped test; any file outside the fence. BUDGET: Stop after 45 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) PASS or FAIL. 2) Proof: the check output. 3) Each problem with file and line. 4) What to fix. 5) New parking-lot items.
A good answer: PASS with a clean check, or FAIL with file and line for each problem, such as a new early return in a hook.
Status report
Once a week, or before you plan the next block of work.
GOAL: Give me the project status in numbers. READ FIRST: `PROGRESS.md`, `notes/functions.csv`, `notes/bugs.md`, the last golden output in `runs/golden/latest.txt`. FENCE: Read-only, except the Status section of `PROGRESS.md`. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `py -3 tools/make_ledger.py --verify` and `pwsh tools/check.ps1 -Golden`. Done means every number in your report matches those outputs or a named file. No number is guessed. 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) Milestone and how far along. 3) Golden runs passing out of total. 4) Open bugs by type. 5) Path B functions rewritten out of total.
A good answer: Five short lines of numbers, each with its source file, and no padding.
Session handoff
At the end of every session, or before your usage runs out.
GOAL: Write what the next session needs into the ledger files. READ FIRST: `PROGRESS.md`, `notes/boot-log.md`, `git status`, `git log -5 --oneline`. FENCE: Edit only the Handoff section of `PROGRESS.md` and `notes/findings.md`. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `Select-String -Path PROGRESS.md -Pattern '^### (Works|In progress|Next command|Open questions|Dead ends)$'`. Done means it prints 5 lines, Works holds the last check output, and Next command holds one exact command. BUDGET: Stop after 10 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 new Handoff section. 3) Files changed. 4) What is left. 5) New parking-lot items.
A good answer: A Handoff section that a new session can follow in five minutes, ending with one exact command to run next.
Blocked or cannot deliver
When a unit keeps failing and Claude keeps trying the same thing.
GOAL: Tell me plainly whether <TASK> can be done with what we have. READ FIRST: `notes/findings.md`, the last three reports for <TASK>, `SCOPE.md`. FENCE: Read-only, except `notes/blocked.md`. Do not try another fix. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `Select-String -Path notes/blocked.md -Pattern '^## (Cannot do|Proof|Tried|Options)$'`. Done means it prints 4 lines, and Options lists two or three choices with their cost. 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) BLOCKED or NOT BLOCKED. 2) Proof: the key evidence. 3) Files changed. 4) The options. 5) New parking-lot items.
A good answer: A plain BLOCKED with the reason, such as needing the XDK compiler for a byte match, and two honest options.
Scope change request
When Claude finds that the fix needs files outside its fence.
GOAL: Ask me before you leave the fence for <TASK>. READ FIRST: `SCOPE.md`, the current task card, the file you want to change. FENCE: Read-only. Write only `notes/scope-requests.md`. Do not add features, refactors, tools or cleanups I did not ask for. CHECK: Run `git status --porcelain` and `Select-String -Path notes/scope-requests.md -Pattern '^## (File|Change|Why|Undo)$'`. Done means only `notes/scope-requests.md` changed and the search prints 4 lines: the file, the change, why the fence cannot do it, and the undo plan. 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) Request written: yes or no. 2) The file and change. 3) The reason. 4) The undo plan. 5) New parking-lot items.
A good answer: A short request, such as a one-line change to the toolkit fork, that you can approve or refuse.
Keep Claude on task
These are the detours Claude tends to take on this system, and the rule that stops each one. The full method is on Stay on Task.
| The detour | The rule to give Claude |
|---|---|
| Claude edits the generated C to make a crash go away. | Never edit generated code. Change the recompiler config, a seed, or an override, then lift again. DOAXVB and Takedawn both state this rule. |
| Claude forces the game into a state and reports it as progress. | Report what you saw happen. Forced state is a guess. Progress means reaching a later natural event in a run under one minute (DOAXVB). |
| Claude says the game works because it booted once. | A boot test proves only boot. Show movement or gameplay captures before you claim gameplay works (Midtown Madness 3). |
| Claude fixes the original game's own bugs while chasing port bugs. | Check the same scene in xemu first. If xemu shows it too, it is the game's bug. Log it and leave it (Ninja Gaiden Black). |
| Claude reads a huge run log and loses track of the task. | Never read a whole log. Use tools/triage.py slices with --tail, --grep or --around (Def Jam). |
| Claude takes over your screen, plays sound, or kills game processes it did not start. | Run headless with sound off and a scratch save folder. Kill only your own process, by its ID (Ninja Gaiden Black, OpenCE). |
| Claude stages game files, lifted code or captures in a commit. | Run git add -A --dry-run before every commit. Hashes may be committed, bytes may not (Def Jam). |
| Claude updates the toolkit to the newest commit to get a fix. | Do not move the toolkit pin unless asked. DOAXVB's move to upstream broke animation, a texture and hotel routing. |
Problems other projects hit
The port works only with one exact release of the game. Other regions or a combo disc fail.
Fix: Pin one default.xbe hash in SCOPE.md and check it before every build. Support a second region with a binary patch, as BLACK does.
Seen in: JSRF Unleashed, Finest Hour Remastered, Athelas, BLACK XBE Recomp
A full disc image has a video part first. Tools that expect the game part at offset 0 fail.
Fix: Read the game part at offset 0x18300000, or make a trimmed .xiso for xemu.
Seen in: Darkwatch: Darker Edition, Midtown Madness 3
The lifter missed code that only a jump past a switch table reaches. Switch cases ran into each other.
Fix: Feed reached targets back as seeds and lift again. Check generated code near jump tables.
Seen in: Ninja Gaiden Black Recomp
Seeds taken from run logs were wrong. They split memcpy and sent the game down a dashboard path.
Fix: Check each seed against the function it lands in before you keep it.
Seen in: Takedawn
Memory mirrors made with VirtualAlloc were copies, not aliases. Writes went missing without a crash.
Fix: Map memory with CreateFileMapping so every mirror points at the same pages.
Seen in: JSRF Unleashed
Higher frame rates broke game logic: a door stayed shut and enemies vanished.
Fix: Find the frame pacer and fix the timing at the logic. Keep simulation at the original rate where you can.
Seen in: Darkwatch: Darker Edition, Athelas
The first full build can take 30 to 90 minutes. Some host or lifter changes force a full rebuild.
Fix: Put lifted code in its own DLL and stamp it, so host changes rebuild fast. Batch recompiler changes.
Seen in: BLACK XBE Recomp, SCDA XBE Recomp, The Warriors Recomp, Def Jam FFNY Recomp
The SDK was fetched from its main branch, so an upstream change broke the build.
Fix: Pin the toolkit to one commit and record it in one file.
Seen in: BLACK XBE Recomp, Finest Hour Remastered
A running game holds the exe, so the link fails with LNK1168. It looks like a code error.
Fix: Stop the game before every build. Run only one game at a time.
Seen in: Def Jam FFNY Recomp
Compiling millions of lines of lifted C ran out of memory.
Fix: Use --split 250, not 1000. The xboxrecomp README says 1000 does not build in 15 GB. Ninja Gaiden Black also caps build memory.
Seen in: Ninja Gaiden Black Recomp
A handler for division by zero broke the game's own error recovery.
Fix: Do not catch exceptions the game itself may raise. Handle only faults your runtime made.
Seen in: JSRF Unleashed
Antivirus deleted or locked new files, such as an unsigned launcher or fresh compiler files.
Fix: Warn players in the README. Retry file moves in setup scripts.
Seen in: Athelas, DOAXVB RE, Takedawn
How long it takes
| Max 20x (now called Ultra) | Max 5x (now called Max) | One person, no AI | How sure | |
|---|---|---|---|---|
| Path A: running on PC | 4 to 12 weeks | 2.5 to 7 months | 6 to 18 months | medium confidence |
| Path B: full decomp | 6 months to 2 years | 1 to 5 years | 5 to 10 years, not realistic for one person | low confidence |
Read this first
All numbers assume one medium-sized game and one person giving 10 to 15 hours a week. Path A comes from four dated Xbox projects with AI help. Each reached a first release three to four weeks after it began, on an existing toolkit. Their makers' real hours are unknown and probably higher. So the ranges are stretched, and confidence is medium, not high. No Xbox recomp predates coding agents, so the no-AI range borrows from the Xbox 360. Path B is a rough guess. Futurama says it finished a non-matching decomp with AI help, but its repo hides its history. Halo 2 is a team effort and is not done.
What makes it faster or slower
- A toolkit that already ran a game on the same engine. Athelas ports four games from one shared SDK.
- How many indirect calls the analysis misses. Each one is a run, a seed and a rebuild.
- Graphics style. Standard Direct3D 8 calls are easier than custom push buffer code.
- Link-time optimised builds. They give functions odd calling rules, for both the recompiler and matching.
- For Path B, the number of game functions. Halo 2 has about 11,300, plus Havok.
The facts behind these numbers
| Project | What happened | Link |
|---|---|---|
| xboxrecomp and Burnout 3 | The toolkit README says Burnout 3 went from an empty repo to rendering 3D tracks in about two weeks. Built with Claude Code. | source |
| Def Jam FFNY Recomp | Planning decision dated 2026-09-17. First commit 2026-10-04. First release 2026-10-11. Claude Code and Codex. | source |
| DOAXVB RE | First commit 2026-08-16. First alpha 2026-09-11. Beta 0.6.2 on 2026-11-02. Uses AI agents extensively. | source |
| Midtown Madness 3 | First commit 2026-09-26, which includes history from the upstream mm3-recomp. First release 2026-10-21. Maintained with Codex help. | source |
| Ninja Gaiden Black Recomp | First commit 2026-10-05. First release 2026-10-26. Four contributors and an AGENTS.md. | source |
| Halo 2 decomp | Matching. First commit 2026-10-01. 72.93% of game code bytes matched by 2026-11-13. 14 contributors with Claude and Codex lanes. | source |
| Halo 1 decomp | First commit 2025-11-27 in punpckhdq/halo, which has 11 contributors. The bnunu/halo-1 fork's README says 99.5% byte matching. AI use not stated. | source |
| Futurama: The Game | Non-matching decomp. Repo and first release both 2026-10-25, so earlier history is hidden. Release 1.4.0 on 2026-11-02 says all 22 levels match frame for frame. Developer declared AI use. | source |
Projects reviewed (15)
We took the top-starred project for each of the top 12 games on RecompLauncher. We added the three biggest projects whose makers say they used AI. RecompLauncher lists 140 projects for 108 Xbox games. For Path B we also read two decomps outside the list: Halo 1 and Halo 2.
What each project teaches
OpenCE
Halo: Combat Evolved
Started: 2025-11. First release: 2026-11. Code: C.
AI: yes: AGENTS.md; SDK stand-in headers were written by agents from public sources and the PDB Agent files: AGENTS.md.
Lesson: Once a decomp exists, a port is mostly a platform layer. OpenCE marks every change to decompiled code with port:.
BLACK XBE Recomp
Black
Started: 2026-10. First release: 2026-10. Code: C++.
AI: none stated
Lesson: The repo holds only host code and one game.toml. xbe_symbols writes the table of XDK functions to replace.
Takedawn
Burnout 3: Takedown
Started: 2026-10. First release: 2026-10. Code: C.
AI: yes: README says Claude does much of the typing while the maintainer decides and tests
Lesson: Keep per-game data in the game repo and shared fixes in the toolkit. Check seeds from logs, because some are wrong.
SCDA XBE Recomp
Tom Clancy's Splinter Cell: Double Agent
Started: 2026-09. First release: 2026-10. Code: C++.
AI: none stated
Lesson: Two XBE files mean two recompiled images and a handover between them. Lifted code lives in a DLL, so host changes rebuild fast.
OpenShao
Mortal Kombat: Shaolin Monks
Started: 2026-10. First release: 2026-10. Code: C++.
AI: yes: README says AI helps with analysis, code, debugging, tests and docs Agent files: AGENTS.md.
Lesson: Pin the SDK and apply your changes from a script. One build script tests before it packages.
Ninja Gaiden Black Recomp
Ninja Gaiden Black
Started: 2026-10. First release: 2026-10. Code: C.
AI: yes: AGENTS.md written for coding agents; catalog flag set by the store Agent files: AGENTS.md.
Lesson: A feedback loop records missed call targets and lifts again. The xemu renderer stays as the judge of whose bug it is.
JSRF Unleashed
Jet Set Radio Future
Started: 2026-03. First release: 2026-10. Code: C and Python.
AI: yes: CONTRIBUTORS.md says parts were made with AI coding tools
Lesson: The lifter handled 9,333 of 9,342 functions. Only nine were written by hand.
Def Jam FFNY Recomp
Def Jam: Fight for NY
Started: 2026-10. First release: 2026-10. Code: Python and C.
AI: yes: README credits Claude Code and Codex; CLAUDE.md, AGENTS.md and four skills Agent files: AGENTS.md, CLAUDE.md, .claude/agents/log-triage.md, .claude/agents/re-reader.md.
Lesson: The best agent setup reviewed here. A fixed fix order, log slices, and a handoff any agent can resume.
DOAXVB RE
Dead or Alive Xtreme Beach Volleyball
Started: 2026-08. First release: 2026-09. Code: C and C++.
AI: yes: README says it uses AI coding agents extensively Agent files: AGENTS.md.
Lesson: A recipe pins the lifter and the hash of every generated file. It also shows the slow road from recomp to readable source.
Darkwatch: Darker Edition
Darkwatch
Started: 2026-10. First release: 2026-10. Code: C++ and Python.
AI: none stated
Lesson: Carry SDK changes as one patch on a pinned commit. Release notes say plainly what was not tested.
Athelas
The Lord of the Rings: The Two Towers, The Return of the King, The Fellowship of the Ring, The Third Age
Started: 2026-10. First release: 2026-10. Code: C++.
AI: yes: README says it was made with the help of Claude (Anthropic)
Lesson: One shared SDK served four games on one engine. The PC version of the same engine helped find the frame pacer.
Finest Hour Remastered
Call of Duty: Finest Hour
Started: 2026-10. First release: 2026-10. Code: C++.
AI: none stated for code; textures upscaled with AI models
Lesson: Fix wrong analysis in the config, not the output. A pinned compiler makes the build byte for byte the same as the release.
Midtown Madness 3
Midtown Madness 3
Started: 2026-09. First release: 2026-10. Code: Python and C.
AI: yes: DEVELOPERS.md says it is maintained with help from OpenAI Codex Agent files: AGENTS.md.
Lesson: A test harness owns its own process, saves and input. Boot tests do not count as gameplay.
Futurama: The Game
Futurama
Started: 2026-10. First release: 2026-10. Code: C++.
AI: yes: developer declared AI use for code in the catalog; the repo says nothing
Lesson: A non-matching decomp of a whole game, checked by frames. The README says all 752,000 frames of a playthrough match.
The Warriors Recomp
The Warriors
Started: 2026-10. First release: 2026-11. Code: C++.
AI: yes: README says AI helped with function boundaries, launcher wiring and crash triage
Lesson: With a mature SDK, a first alpha came three days after the first commit. Region and language need their own handling.
What we could not check
- The Xbox CPU and RAM facts come from the
XboxXBERecompREADME and thexboxrecompmemory doc. They are not from the Xbox dev wiki. The wiki returned an error (HTTP 429) when read. - The plugin file name inside the GhidraMCP release download. The README names it, but the zip was not opened.
- The
claude mcp addline for GhidrAssistMCP. It follows Claude Code's own MCP docs; the GhidrAssistMCP README gives only the URL. - Whether
extract-xisoreads every full two-part disc dump. Its README talks about XISO files. DOAXVB and Def Jam use it on their dumps. - How long Futurama took. Its repo is an export with hidden history.
- Which compiler most retail Xbox games used. Only Halo 1 and Halo 2 state theirs.
- The real hours behind any project's dates. Several repos hide their early history, such as Finest Hour, Darkwatch and Futurama.
- Whether the Halo 1 decomp used AI. Its README does not say.
- Which emulator Futurama used for its frame compare. The repo does not say.
- Whether the GhidrAssistMCP build for Ghidra 12.1 loads in Ghidra 12.1.4.
- The
tools/fncheck.ps1,tools/check.ps1,tools/triage.pyand similar scripts in the prompts are scripts you write. Their names follow the reviewed projects, but no toolkit ships them. - That
objdifforreccmpcan check Xbox code.reccmpsays it supports only old MSVC versions on PE files, so this guide does not use either. - How XboxLLR compares in practice. Only its README was read.
- Whether every reviewed port checks the disc hash in code. Some cards could not confirm it.
Sources
- xboxrecomp README (v0.17.0)
- xboxrecomp: Using xboxrecomp for Decompilation
- xboxrecomp: Lessons Learned
- xboxrecomp: XBE File Format Reference
- xboxrecomp: Memory Layout Reproduction
- Xbox XBE Recomp README
- extract-xiso README and releases
- ghidra-xbe README and releases
- XbSymbolDatabase README
- xemu releases
- xemu required files
- Ghidra releases
- GhidraMCP README
- GhidrAssistMCP README
- llvm-mingw releases
- XboxLLR README
- Halo 2 decompilation README
- Halo 2 decompilation: Start here
- Halo 1 decompilation (punpckhdq)
- Halo 1 decompilation (bnunu fork)
- RalliSport Challenge 2 recomp README
- reccmp README
- capstone on PyPI
- Claude Code: connect to MCP servers
- Claude Code: permissions
- Install PowerShell on Windows
- Install Git on Windows
- Install WSL
- Def Jam FFNY Recomp
- DOAXVB RE
- Ninja Gaiden Black Recomp
- OpenCE
- Futurama: The Game