Skip to the page
It's Decomplicated
Sony, 2000

PlayStation 2 decomp guide

Many fresh PS2 ports exist. The CPU is easy; VU1, graphics and timing are the hard part.

What this system is like

The PS2 has a MIPS chip, the same family as the N64 and PS1. Good tools can read it. On RecompLauncher, 88 of the 97 PS2 projects had their first release in October or November 2026. 62 of the 97 are flagged for AI use.

For Path A, most projects use static recompilation with PS2Recomp. Ghidra finds the functions, the tool writes C++, and you finish the runtime. The runtime is the stand-in for the console. The CPU code is the easy part. The VU1 vector chip, the graphics chip (the GS) and the sound chip take most of the time.

For Path B, PS2 games were built with known compilers. Sony's ee-gcc and Metrowerks mwcps2 are both on decomp.me. splat supports PS2. With AI agents, Tenkaichi 3 matched 95% of its main program in three days. gt4-decomp matched 98% of its functions in under six weeks. A port of a decomp still needs a full PC layer after that.

Most Path A work runs on Windows. Path B's matching build runs in WSL. You need your own disc. PCSX2 also needs a BIOS dumped from your own console.

The CPU is easy, the side chips are not

The main CPU is plain MIPS with extra media instructions. The hard parts are VU1 microcode, the GS graphics chip, the IOP and SPU2 sound. In the reviewed recomps, most bugs and slow spots were there.

Two kinds of code on one disc

The ELF holds CPU code. VU1 programs are separate microcode, sometimes encrypted, as in GT4. Ports record them at run time and compile them ahead of time.

Floats do not act like a PC's

The PS2 FPU has no infinities or NaNs, and it rounds toward zero. Plain PC floats gave NaNs in Tenkaichi 3. Ports keep a PS2 float model.

Known compilers, ready to use

Games used Sony ee-gcc builds or Metrowerks mwcps2. decomp.me hosts dozens of them. That makes matching practical, even for C++ games like GT4.

A wave of AI-built ports

Of 97 PS2 projects on RecompLauncher, 88 had a first release in October or November 2026. 62 are flagged for AI use. You have many examples, and their agent rules, to copy.

Two paths

Path A

Get it running on PC

Ghidra finds every function in the ELF. PS2Recomp turns them into C++. You build that with a runtime that stands in for the console. Then you fix one missing call or crash at a time, and compile VU1 programs ahead of time. Fixes go in overrides, never in the machine-made code.

Go to the steps

Path B

Full decomp for porting

splat cuts the ELF into assembly. You write C that the game's own compiler turns back into the same bytes. A per-function diff checks each piece, and the full build must match byte for byte. Then you add a PC layer and port it, as Tenkaichi 3, ICO and RECVX did.

Go to the steps

Path A: Get it running on PC

Ghidra finds every function in the ELF. PS2Recomp turns them into C++. You build that with a runtime that stands in for the console. Then you fix one missing call or crash at a time, and compile VU1 programs ahead of time. Fixes go in overrides, never in the machine-made code.

Method: static recompilation

Pick this to play soon on PC. It is the path most reviewed PS2 projects took. Pick a port of a decomp instead if a finished decomp already exists.

  1. Scope the game and look for prior work

    Pick one game and one exact disc. The boot file on the disc is named after the serial, like SLUS_215.90. Search for work that already exists. Many PS2 games already have a port or a decomp. Write SCOPE.md and get it approved before any code.

    • In WSL, run sudo apt install 7zip. Copy SYSTEM.CNF out of your disc to a folder outside any repo: 7z x mygame.iso SYSTEM.CNF -o$HOME/ps2disc.
    • Read the BOOT2 line in SYSTEM.CNF. It names the boot file. Copy that file out the same way, then hash it: sha1sum $HOME/ps2disc/SLUS_XXX.YY. Put the serial and hash in SCOPE.md.
    • Search GitHub and RecompLauncher for the game name plus recomp, decomp and port. Check sister games on the same engine too.
    • Check for a prototype, demo or debug build. Some keep debug symbols, which the EE add-on for Ghidra can read. The ICO decomp rebuilds a prototype and a demo as well as five retail discs.
    • Write SCOPE.md: goal, serial, hash, technique, first milestone and its check, what is out of scope, what Claude must never edit.
    Prompt for Claude
    GOAL: Draft `SCOPE.md` for a PC port of <GAME> (serial <SERIAL>) by static recompilation with `PS2Recomp`.
    READ FIRST: `notes/disc-facts.md` (my serial, `SYSTEM.CNF` text and the boot ELF SHA-1). The `PS2Recomp` README at https://github.com/ran-j/PS2Recomp.
    FENCE: Write only `SCOPE.md` and `notes/prior-work.md`. Do not open, copy or upload any game file. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `grep -cE '^## (Goal|Game and hash|Technique|Milestone 1|Out of scope|Never edit)' SCOPE.md`. Done means it prints 6. Each line in `notes/prior-work.md` has a URL you opened.
    BUDGET: Stop after 45 minutes of searching.
    IF BLOCKED: If you cannot tell whether prior work exists, stop and say so. 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) The prior-work list with URLs. 3) Your recommended technique and why. 4) Open questions for me.
    Done whengrep -cE '^## (Goal|Game and hash|Technique|Milestone 1|Out of scope|Never edit)' SCOPE.md prints 6, the file holds the serial and SHA-1, and its last line is Approved: <date> in your words.

    Proof this works: GTA Vice City Stories recomp (one supported executable, checked by SHA-1), God of War Native PC (games/<id>/game.toml holds the hashes), https://github.com/ran-j/PS2Recomp, Project Cane (the author asks for debug builds with symbols before trying Sly 2 and Sly 3)

  2. Set up the repo, the tools and one check

    Make a repo that holds only your own code. The disc image and anything taken from it stay in ignored folders. Install PS2Recomp, a compiler, CMake and Ninja. Then write one script that builds and one that checks.

    • Make folders: game/ (your disc files, ignored), config/, overrides/, generated/ (ignored), notes/, tools/.
    • Add game/, generated/, *.iso, *.elf and build/ to .gitignore. Add a pre-commit hook that refuses files from those folders.
    • Pull the boot file into the ignored folder: 7z x mygame.iso SLUS_XXX.YY -ogame.
    • Build PS2Recomp as its README says: git clone --recurse-submodules https://github.com/ran-j/PS2Recomp.git, cd PS2Recomp, cmake -S . -B out/build, then cmake --build out/build --config Debug.
    • First install Visual Studio 2022 Build Tools with the Desktop development with C++ workload. The PS2Recomp README says it is tested mainly with MSVC. The first build fetches its own libraries and took about 8 minutes in this site's test.
    • Write tools/check.py. It checks the ELF hash, builds, and runs the game headless for a set time. It prints PASS or FAIL.
    • Write a short CLAUDE.md and an empty PROGRESS.md.
    Prompt for Claude
    GOAL: Create the repo layout, the build script and the one check command for the <GAME> recomp.
    READ FIRST: `SCOPE.md`, `CLAUDE.md`, the `PS2Recomp` README Build section.
    FENCE: Edit only `tools/`, `.gitignore`, `.githooks/`, `CMakeLists.txt` and `PROGRESS.md`. Never copy anything from `game/` into tracked folders. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `python tools/check.py --hash-only`. Done means it prints the expected SHA-1 and PASS. Then run `git status --ignored` and show that `game/` is ignored.
    BUDGET: Stop after 3 failed tries at the same error.
    IF BLOCKED: If a tool will not install or build, 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 whenpython tools/check.py --hash-only prints PASS, and git status shows no game file as tracked.

    Proof this works: DW5XL Recomp (.githooks scan for game-derived files; CI check that no game data is tracked), https://github.com/ran-j/PS2Recomp, This site's hands-on test (2026-11-13): PS2Recomp built on Windows with Visual Studio Build Tools 2022 and printed its usage

  3. Map the ELF in Ghidra

    The recompiler needs to know where every function starts. Retail games have no names, so Ghidra finds the functions. Load the boot ELF with the Emotion Engine extension. Export the function list with the script that comes with PS2Recomp.

    • Install JDK 21 and Ghidra 12.1.4. Then add the matching ghidra-emotionengine-reloaded zip through File > Install Extensions.
    • Import game/SLUS_XXX.YY with the language r5900:LE:32:default. Run auto-analysis.
    • Run ps2xRecomp/tools/ghidra/ExportPS2Functions.java. Save the CSV map and the TOML in config/.
    • Add functions Ghidra missed. They hide behind pointers and vtables (tables of function pointers). GTA VCS added 833 this way.
    • Feed only real function starts to the recompiler, not branch labels. Labels made GTA VCS output 67k files with copied code.
    • Mark Sony library code (libgraph, libvu0, libvif, libcdvd, libpad, libmc) in notes/functions.csv with a status column.
    Prompt for Claude
    GOAL: Produce the function map for <GAME> and a ledger of every function with address, size, library tag and status.
    READ FIRST: `SCOPE.md`, `config/ghidra_export.csv`, `notes/ghidra-setup.md`. Use the Ghidra MCP read-only.
    FENCE: Write only `config/funcmap.csv` and `notes/functions.csv`. Do not rename or retype anything in the Ghidra project. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `python tools/validate_map.py config/funcmap.csv`. Done means no overlaps, no starts inside another function, and the count matches the ledger.
    BUDGET: Stop after 2 hours or 3 failed fixes of the same overlap.
    IF BLOCKED: If Ghidra is not reachable, 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) Function count, library count, and the validator output. 3) Files changed. 4) Addresses you were unsure about. 5) New parking-lot items.
    Done whenconfig/funcmap.csv passes the validator, and notes/functions.csv has one row per function with a status.

    Proof this works: DW5XL Recomp (ExportPS2Functions.java, validate_function_map.py), GTA Vice City Stories recomp (find_missing_functions.py), GT4 Recomp (1,105 entries added from gt4-decomp)

  4. Run the recompiler and build

    Now PS2Recomp turns the whole ELF into C++. The output is machine-made and is never edited by hand. You build it with the runtime. The first goal is a clean build, not a running game.

    • Write config/recomp.toml with general.input, general.ghidra_output and general.output = "generated/".
    • Keep general.patch_syscalls = false, as the README recommends.
    • Run ps2_recomp config/recomp.toml.
    • Build the output with the runtime: cmake -S . -B build -G Ninja then cmake --build build.
    • Put the build in a short folder like C:\ps2work. Long Windows paths broke the God of War build.
    • Record the generated file count and build time in PROGRESS.md.
    Prompt for Claude
    GOAL: Recompile the ELF with `ps2_recomp` and get a clean build of the generated C++ with the runtime.
    READ FIRST: `config/recomp.toml`, `config/funcmap.csv`, the `PS2Recomp` README Configuration section.
    FENCE: Edit only `config/recomp.toml` and `CMakeLists.txt`. Never edit files in `generated/`. If generated code is wrong, report which instruction and address. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `python tools/check.py --build`. Done means the build ends with no errors and you paste the last 20 lines.
    BUDGET: Stop after 3 failed builds with the same error.
    IF BLOCKED: If the recompiler itself crashes or emits code that cannot compile, 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 whenpython tools/check.py --build ends with no errors, and no file in generated/ was edited by hand.

    Proof this works: GoW PC port (ps2_recomp build-gen/recomp.toml; generated runner files never hand-edited), https://github.com/ran-j/PS2Recomp

  5. Boot to the first frame

    This is first light. The game starts, the runtime answers its system calls, and a window shows a picture. Expect many missing calls. Fix them one at a time. A stub that just returns success hides a problem, so use one only to learn which calls matter.

    • Run with a minimal config and no aggressive skipping, as the PS2Recomp README says.
    • Fix hard blockers first: function not found, a syscall TODO, or a disc read stub.
    • Bind stripped library calls by address, for example sceCdRead@0x00123456 in stubs.
    • Use ret0@0xADDR only to sort calls by importance. Replace each one with a real version later.
    • Let the game's own SDK code run when you can. DW5XL found the runtime's versions of libgraph, libvu0 and libvif were wrong for its game.
    • Save a screenshot of the first frame and the log line that proves it.
    Prompt for Claude
    GOAL: Get <GAME> to show its first frame (the <LOGO_OR_SCREEN>) from a cold start.
    READ FIRST: `PROGRESS.md`, the last run log `logs/run-latest.txt`, the `PS2Recomp` README section Recommended Iteration Loop.
    FENCE: Edit only `overrides/` and the `stubs` list in `config/recomp.toml`. Never edit `generated/`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `python tools/check.py --boot --seconds 60`. Done means it saves `out/first-frame.png` and the log has no fatal error.
    BUDGET: Fix one blocker per try. Stop after 5 tries without a new blocker passed.
    IF BLOCKED: If a blocker needs hardware you cannot model from docs or PCSX2, 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 whenpython tools/check.py --boot --seconds 60 saves a first-frame picture, and every temporary ret0 stub is listed in PROGRESS.md.

    Proof this works: DW5XL Recomp (HLE stubs for libgraph, libvu0, libvif were wrong; game SDK code runs as guest code), https://github.com/ran-j/PS2Recomp

  6. Grind: one crash or missing call per task

    Now play further, one problem at a time. Each fix goes in an override bound to a function address, not in generated code. Compare with PCSX2 to see what the real game does. Write each finding down with its address.

    • Write each problem as one issue: what happens, where it stops, the log line.
    • Write a test that fails on the bug first. DW5XL makes this a hard rule.
    • Fix it in overrides/, bound by address. An override calls the original for anything it does not replace. Register it with PS2_REGISTER_GAME_OVERRIDE from ps2xRuntime/include/game_overrides.h.
    • Never rely on code after the original function returns. Recompiled functions can pause and resume mid-way.
    • Run PCSX2 with your own BIOS for reference. Compare screenshots at the same point.
    • Add every address you learn to notes/game-internals.md, with how you found it.
    Prompt for Claude
    GOAL: Fix issue <ISSUE_ID>: <ONE_LINE_SYMPTOM>.
    READ FIRST: `notes/issues/<ISSUE_ID>/spec.md`, `notes/game-internals.md`, the failing log `logs/<ISSUE_ID>.txt`.
    FENCE: Edit only `overrides/`, `tests/` and `notes/issues/<ISSUE_ID>/`. Never edit `generated/` or a test's pass rule. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: First show the new test fails. Then run `python tools/check.py --test <ISSUE_ID>` and `python tools/check.py --regress`. Done means both pass.
    BUDGET: Stop after 3 failed fixes or 90 minutes without new evidence.
    IF BLOCKED: If the cause is in the recompiler, not the game, 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 issue's test failed before the fix and passes after, and the full regression run still passes.

    Proof this works: DW5XL Recomp (test first, must fail on the bug), GoW PC port (overrides by address call the original), GTA Vice City Stories recomp (hook rule; findings in docs/game-internals.md), https://github.com/ran-j/PS2Recomp (Game Override Hooks section)

  7. Make VU1 and the graphics fast and right

    The PS2 draws through VU1, a small vector chip with its own programs called microcode. Interpreting it is slow. Projects compile the microcode ahead of time and keep the interpreter as a checker. Every change must give the same pictures.

    • Record the VU1 programs the game uploads during a scripted run. God of War plays itself hidden for four minutes to do this.
    • Compile them ahead of time. Keep the interpreter and a switch to compare, like PS2X_VU1_LIFT_VERIFY=1 in DW5XL.
    • Save frames from the same scripted run before and after. Compare them pixel by pixel.
    • Try paraLLEl-GS as a reference renderer. GTA VCS kept it opt-in because it hung one GPU.
    • Turn off fused multiply-add: compile with -ffp-contract=off and no fast-math, as ICO PC does. Bit-exact checks depend on it.
    • Measure frame time before and after each change on the same PC.
    Prompt for Claude
    GOAL: Compile VU1 program <VU_KEY> ahead of time and prove it draws the same as the interpreter.
    READ FIRST: `notes/vu1-programs.md`, `tools/compare_frames.py --help`, the scripted run `runs/<RUN>.args`.
    FENCE: Edit only `runtime/vu1/` and `tests/vu1/`. Keep the interpreter path and its switch. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `python tools/check.py --vu-verify <VU_KEY>` and `python tools/compare_frames.py runs/<RUN>`. Done means zero differences in both.
    BUDGET: Stop after 3 failed tries or if frames differ for a reason you cannot explain.
    IF BLOCKED: If an instruction's behaviour is unclear in the docs and in PCSX2, 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 verify switch reports no difference, and the frame compare shows zero changed pixels on the scripted run.

    Proof this works: DW5XL Recomp (compare_frames.py, lift verify switches), GT4 Recomp (--vu1-verify), God of War Native PC (recorded VU1 code compiled ahead of time)

  8. Harden: regression runs, packaging, no game data

    Lock in what works. Record scripted runs that a machine can replay with no person. Store only picture hashes in the repo. Ship a builder that makes the game on the player's PC from the player's own disc.

    • Record runs with timed button presses. God of War uses GOW_PAD_TEST=1 and a log marker that proves gameplay was reached.
    • Store only picture CRCs (short checksums) for each run. Stuntman keeps 79 for its title-to-stunt run.
    • Run every recorded run after any renderer, memory, DMA or VU change.
    • Never run tests on the player's real memory card. Give each run its own data folder.
    • Package a builder: recompiler, sources and compiler. It checks the disc by hash and compiles locally.
    • Run git ls-files and confirm no ELF, ISO, generated C++ or frame dump is tracked.
    Prompt for Claude
    GOAL: Add a regression set of <N> scripted runs and make `python tools/check.py --regress` run them all.
    READ FIRST: `PROGRESS.md`, `runs/README.md`, `CLAUDE.md`.
    FENCE: Edit only `runs/`, `tools/` and `PROGRESS.md`. Store hashes only, never frames or game data. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `python tools/check.py --regress` twice on a clean checkout. Done means the same PASS both times.
    BUDGET: Stop after 3 failed tries at one run.
    IF BLOCKED: If a run is not repeatable, stop and show the two differing results. 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 whenpython tools/check.py --regress passes twice in a row on a clean checkout, and git ls-files shows no game-derived file.

    Proof this works: Stuntman (regress.py with recorded picture CRCs), God of War Native PC (scripted smoke run with a log marker), GTA Vice City Stories recomp (VCS_DATA_DIR keeps tests off the user's card)

Path B: Full decomp for porting

splat cuts the ELF into assembly. You write C that the game's own compiler turns back into the same bytes. A per-function diff checks each piece, and the full build must match byte for byte. Then you add a PC layer and port it, as Tenkaichi 3, ICO and RECVX did.

Method: matching decompilation

Pick this to read and change the game's code, or to port it to more systems. It takes longer. Check first: several PS2 games already have a decomp you can build on.

  1. Scope: compiler, prior work and size

    A matching decomp needs the game's original compiler. On PS2 that is usually a Sony ee-gcc build or Metrowerks mwcps2. Find which one, and check for a decomp that already exists. Count the functions so you know the size.

    • Search GitHub for <game> decomp and decomp.dev. Many PS2 decomps already exist, like Sly 1, Kingdom Hearts and PaRappa 2.
    • Look at the strings in the ELF for a compiler version. gt4-decomp names ee-gcc 2.96 build 001003-1 with -O2 -G0. Tenkaichi 3 tested its guess against every public ee-gcc and 118 flag sets.
    • Compare with the PS2 compilers on decomp.me. Its list has ee-gcc2.9, ee-gcc2.95, ee-gcc2.96, ee-gcc3.2 and many mwcps2 builds.
    • Note C or C++. C++ games add vtables and name mangling.
    • Write SCOPE.md with the serial, hash, compiler guess and function count.
    Prompt for Claude
    GOAL: Draft `SCOPE.md` for a matching decomp of <GAME> (serial <SERIAL>) and name the most likely compiler.
    READ FIRST: `notes/disc-facts.md`, the compiler list at https://github.com/decompme/compilers/tree/main/platforms/ps2.
    FENCE: Write only `SCOPE.md` and `notes/prior-work.md`. Do not download compilers or game files. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `grep -cE '^## (Compiler|Evidence|Function count|Prior work)' SCOPE.md`. Done means it prints 4. The file names one compiler with its evidence (a string, a code pattern or a sister game) and a function count from Ghidra.
    BUDGET: Stop after 1 hour.
    IF BLOCKED: If two compilers fit equally, stop and list both with evidence. 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) Compiler guess and evidence. 3) Prior work with URLs. 4) Function count. 5) Open questions.
    Done whengrep -cE '^## (Compiler|Evidence|Function count|Prior work)' SCOPE.md prints 4, the file holds the hash, and its last line is Approved: <date> in your words.

    Proof this works: gt4-decomp README (compiler identified as ee-gcc 2.96 001003-1), Tenkaichi 3 Decomp (compared its ee-gcc 2.96 with every public ee-gcc), https://github.com/decompme/compilers

  2. Set up splat and a byte-exact build in WSL

    splat cuts the ELF into assembly files. Your build puts them back together. The rebuilt file must match the original byte for byte before you write any C. This runs in WSL.

    • In WSL: sudo apt install python3-venv binutils-mips-linux-gnu.
    • Make a venv in the project: python3 -m venv .venv, then .venv/bin/pip install -U "splat64[mips]". Run source .venv/bin/activate in each new shell. This route was tested here on Ubuntu 24.04.
    • Copy SLUS_XXX.YY into the project. Add it, *.rom, asm/ and build/ to .gitignore.
    • Run python3 -m splat create_config SLUS_XXX.YY. It writes the .yaml and the .rom, and prints the objcopy command it used.
    • Put that command in your configure script: mips-linux-gnu-objcopy -O binary --gap-fill=0x00 SLUS_XXX.YY SLUS_XXX.YY.rom.
    • Split: python3 -m splat split SLUS_XXX.YY.yaml.
    • Write configure.py that writes build.ninja. Add a check rule that runs cmp against the original.
    • Get the compiler from the decompme/compilers release named compilers into tools/. Keep it out of git. For an mwcps2 game, run mwccps2.exe through wibo, as recvx-decomp does on Linux.
    • If ee-gcc crashes when it calls its own assembler, compile to assembly first. Then assemble with the MIPS binutils and a prelude file, as Tenkaichi 3 does.
    Prompt for Claude
    GOAL: Make `python3 configure.py && ninja` rebuild <SERIAL> from split assembly, byte for byte.
    READ FIRST: `SCOPE.md`, `SLUS_XXX.YY.yaml`, the splat Quickstart-Elf page https://github.com/ethteck/splat/wiki/Quickstart-Elf.
    FENCE: Edit only `configure.py`, the `.yaml`, `symbol_addrs.txt` and `tools/`. Never edit files in `asm/` by hand; change the yaml and split again. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `python3 configure.py && ninja && cmp build/SLUS_XXX.YY.rom SLUS_XXX.YY.rom`. Done means `cmp` prints nothing and exits 0.
    BUDGET: Stop after 3 failed tries at the same mismatch.
    IF BLOCKED: If `splat` cannot split a section, stop and show the error. 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 whenninja then cmp against the original ROM exits 0 with all code still as assembly.

    Proof this works: Tenkaichi 3 Decomp (configure.py, ninja, cmp of SLUS_216.78.rom), https://github.com/ethteck/splat, https://github.com/ethteck/splat/wiki/Quickstart-Elf, This site's hands-on test (2026-11-13): splat 0.50.1 installed in a venv on WSL Ubuntu 24.04 and split a test ROM

  3. Map files, symbols and library code

    Cut the code into files the way the developers did. Name what you can prove. Mark Sony SDK and middleware code, like CRI sound and movie code, so nobody decompiles it by hand. Save all of it as a ledger.

    • Find file edges from gaps, alignment and string groups. Add them as subsegments in the .yaml.
    • Put names in symbol_addrs.txt. Mark guesses with // guess, as Tenkaichi 3 does.
    • Tag SDK and middleware objects. Tenkaichi 3 matched them as library objects, not by hand.
    • List VU microcode separately. It is assembled from listings, not compiled from C. Tenkaichi 3 builds its nine VU1 programs with vuasm.py.
    • Write notes/functions.csv: address, size, file, library tag, status.
    Prompt for Claude
    GOAL: Split the code into source files and write the function ledger for <SERIAL>.
    READ FIRST: `SLUS_XXX.YY.yaml`, `symbol_addrs.txt`, Ghidra read-only through the MCP.
    FENCE: Edit only the `.yaml`, `symbol_addrs.txt` and `notes/functions.csv`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `python3 configure.py && ninja && cmp build/SLUS_XXX.YY.rom SLUS_XXX.YY.rom`. Done means `cmp` exits 0 and every function is in the ledger once.
    BUDGET: Stop after 2 hours or when `cmp` fails twice in a row.
    IF BLOCKED: If a split breaks the match and you cannot see why, 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 byte check still passes, and notes/functions.csv lists every function with a file and a status.

    Proof this works: Tenkaichi 3 Decomp (config/symbols/*.txt with evidence and guesses marked), ICO PC (game code in one folder per original programmer)

  4. Match the first unit end to end

    Prove the whole loop on one small file. Write C, compile it with the original compiler, and compare each function. When the file matches and the full build still passes, the tools are right.

    • Pick a small file with few functions and no floats.
    • Get a draft from m2c: python3 <M2C_DIR>/m2c.py -t mipsee-gcc-c -f <func> asm/nonmatchings/<file>/<func>.s. Run m2c.py by its full path or from its own folder.
    • Compare per function with objdiff or a script like Tenkaichi 3's fdiff.py.
    • Replace INCLUDE_ASM lines with C only when the diff is clean.
    • Run the full byte check. A function match alone is not proof.
    Prompt for Claude
    GOAL: Match every function in `src/<FILE>.c` against the original.
    READ FIRST: `asm/nonmatchings/<FILE>/`, `include/`, `notes/compiler.md`.
    FENCE: Edit only `src/<FILE>.c` and its header. No inline assembly, no register pins, no edits to `asm/`, the yaml or the expected hash. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `python3 tools/fdiff.py src/<FILE>.c` for each function, then `python3 configure.py && ninja`. Done means every function prints OK and `cmp` passes.
    BUDGET: At most 5 different serious tries per function. Then leave it as `INCLUDE_ASM` with your best try under `#if 0`.
    IF BLOCKED: If the toolchain itself seems wrong, 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 whenEvery function in the file prints OK in the per-function check, and the full cmp check passes.

    Proof this works: Tenkaichi 3 Decomp (fdiff.py OK per function plus the cmp gate), https://github.com/encounter/objdiff, https://github.com/matt-kempster/m2c, This site's hands-on test (2026-11-13): m2c turned a splat MIPS function into C on Windows

  5. Grind: many workers on separate address ranges

    Now the bulk work. Give each worker its own file list and address range. Workers run only the per-function check. One lead session owns the full build, splat and git. This is how Tenkaichi 3 reached 95% in three days.

    • Write one shared brief: rules, compiler notes, report format.
    • Give each worker its own git worktree and a disjoint set of files.
    • Workers run only fdiff.py. They never run configure.py, splat, ninja or git.
    • Workers read assembly from a frozen copy, not the live asm/ folder.
    • The lead merges, runs the full cmp gate, then commits.
    • Order work easy first. Later, pick functions most like ones already matched.
    Prompt for Claude
    GOAL: Lead session: hand out the next <N> files from `notes/functions.csv` to <N> workers and merge their verified results.
    READ FIRST: `notes/functions.csv`, `docs/agent_rules.md`, `docs/brief.md`.
    FENCE: Workers edit only their own files in their own worktree. Only you run `configure.py`, `ninja` and git. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: After each merge run `python3 configure.py && ninja && python3 scripts/progress.py`. Done means `cmp` passes and the ledger matches the progress numbers.
    BUDGET: Stop the batch when 2 merges in a row fail the gate.
    IF BLOCKED: If two workers touched the same file, stop and tell me. 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) Gate output and new progress percent. 3) Files merged. 4) Files sent back. 5) New parking-lot items.
    Done whenAfter each batch, the full cmp gate passes and notes/functions.csv shows the new matches.

    Proof this works: Tenkaichi 3 Decomp (one integrator, up to 10 agents, per-function checker only), gt4-decomp (98.0% of functions matched with AI agents)

  6. The hard tail: permuter and behaviour tests

    Some functions will not match after real effort. Try the permuter on near misses. For the rest, prove the C behaves the same instead. A behaviour test runs the original bytes and your C on the same random inputs and compares.

    • In WSL, add permuter_settings.toml to the project root with build_system = "ninja". Its default assembler flags are for the N64, so also set assembler_command for your PS2 as.
    • Import a near miss: ./import.py src/<file>.c asm/nonmatchings/<file>/<func>.s. Then run ./permuter.py -j <N> nonmatchings/<func>/.
    • Check every permuter result by hand. Tenkaichi 3 found a score of 0 that was wrong.
    • Build a behaviour test like Tenkaichi 3's gdt.py. Run each unmatched function on 4,000 seeds.
    • Compare return value, outgoing calls and memory writes.
    • Mark these functions as behaviour-checked, not matched, in the ledger.
    Prompt for Claude
    GOAL: Resolve function <FUNC> in `src/<FILE>.c`: match it, or prove its C behaves the same.
    READ FIRST: `notes/hard/<FUNC>.md` (earlier tries), the diff from `tools/fdiff.py`.
    FENCE: Edit only `src/<FILE>.c` and `notes/hard/<FUNC>.md`. No inline assembly. No changes to the checker or its masks. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `python3 tools/fdiff.py src/<FILE>.c <FUNC>`. If it is not OK, run `python3 tools/difftest.py src/<FILE>.c <FUNC> 4000`. Done means OK, or 4,000 seeds with no difference.
    BUDGET: Stop after 60 serious variants without progress. Write what you learned.
    IF BLOCKED: If the function reads data the test cannot model, 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 function prints OK, or the behaviour test passes 4,000 seeds and the ledger says behaviour-checked.

    Proof this works: Tenkaichi 3 Decomp (permuter, differential interpreter, 60-variant rule), https://github.com/simonlindholm/decomp-permuter

  7. Harden: the gate, data sections and a second check

    Make the build the only judge. Run the full gate before every commit. Check data and float constants, because the per-function diff cannot see them. Have a fresh session hunt for cheats.

    • Run the cmp gate before every commit outside docs/. Tenkaichi 3 added this after two broken commits.
    • Compare the bits of every float constant with the original data.
    • Block edits to asm/, the expected hash and the check script with a PreToolUse hook. When the hook exits with code 2, Claude Code blocks the edit.
    • Grep for banned tricks: inline asm and changed checker settings. Also count FAKE MATCH tags. Tenkaichi 3 marks about 21 openly, so a person can review them.
    • Write the progress numbers from the build, never by hand.
    Prompt for Claude
    GOAL: Audit the last <N> commits for fake matches and broken rules.
    READ FIRST: `git log -<N> --stat`, `CLAUDE.md`, `docs/agent_rules.md`.
    FENCE: Read only. Write findings to `notes/audit-<DATE>.md`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `python3 configure.py && ninja` from a clean checkout and grep for inline asm and checker edits. Done means the gate passes and each finding cites a file and line.
    BUDGET: Stop after 1 hour.
    IF BLOCKED: If the gate fails on a clean checkout, stop at once. 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) Gate output. 3) Findings with file and line. 4) Commits to revert. 5) New parking-lot items.
    Done whenA fresh checkout passes the gate, and the audit file lists every finding with a file and line.

    Proof this works: Tenkaichi 3 Decomp (gate before every commit; float constant rule), gt4-decomp (progress written by tools/update_readme.py, never by hand), https://code.claude.com/docs/en/hooks (exit code 2 blocks a PreToolUse call)

  8. Port: compile the decomp for PC

    Matching PS2 code does not run on a PC by itself. You add a port layer: one module for each piece of PS2 hardware or Sony library. Every change to game code sits behind a flag, with the PS2 original kept.

    • Wrap every game code change in #ifdef TARGET_PC with the original under #else.
    • Make one stand-in per piece: libcdvd, libpad, libmc, SIF, SPU2, GS and VU1.
    • Compile game code with -fno-strict-aliasing -fwrapv -ffp-contract=off -fsigned-char, as ICO and RECVX do.
    • Keep pointers 4 bytes or audit every struct. ICO found records grew from 0xC0 to 0xF0 bytes.
    • Model PS2 floats. The EE FPU has no infinities or NaNs. Tenkaichi 3 got NaNs on the first battle frame with plain PC floats.
    • Build with GCC or Clang with the GNU ABI. RECVX found MSVC and Clang lay out its data wrong; ICO bans MSVC.
    Prompt for Claude
    GOAL: Make the port layer stand-in for <MODULE> (for example `libpad`) and boot the PC build past it.
    READ FIRST: `port/README.md`, `notes/functions.csv`, the ps2tek section on the hardware under <MODULE> at https://psi-rockin.github.io/ps2tek/.
    FENCE: Edit only `port/<MODULE>/` and lines inside `#ifdef TARGET_PC` blocks. Keep the PS2 original under `#else`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `cmake --build build-pc && ctest --test-dir build-pc` and `python3 tools/golden.py --until <MARKER>`. Done means tests pass and the marker appears.
    BUDGET: Stop after 3 failed tries.
    IF BLOCKED: If the game relies on hardware you cannot model from docs, 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 PC build passes its tests and reaches the named point in a scripted run, and the PS2 build still passes cmp.

    Proof this works: ICO PC (port layer per hardware module; EE semantics flags), RECVX Enhanced Port (#ifdef TARGET_PC, GCC only), Tenkaichi 3 Decomp (soft-float PS2 model, __ptr32 pointers)

  9. Port golden runs against PCSX2

    Prove the PC build plays the same as the console. Record a replay in PCSX2 and play it back on the PC build. Compare game state frame by frame. Also rebuild with a different memory layout and check nothing changes.

    • Record inputs and a save state in PCSX2. Tenkaichi 3 compared health and positions bit for bit.
    • Hash key game state each frame and compare builds, like BT3_HASH.
    • Build twice with padding before code and data. RECVX compares every 10th frame up to frame 1800.
    • A layout difference can mean retail code reads memory it never wrote. RECVX found two such bugs and fixed them on PC. Keep the game's own bugs in the matching code; Tenkaichi 3 logs them in docs/known_bugs.md.
    • Add each run to CI with synthetic data, or to a local regression set that needs your disc.
    Prompt for Claude
    GOAL: Make the PC build replay <REPLAY> with the same per-frame state as PCSX2.
    READ FIRST: `runs/<REPLAY>/`, `tools/compare_hash.py --help`, `docs/known_bugs.md`.
    FENCE: Edit only `port/` and `TARGET_PC` blocks. Never change the replay or the reference hashes. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
    CHECK: Run `python3 tools/compare_hash.py runs/<REPLAY>`. Done means every frame's hash matches.
    BUDGET: Stop after 3 failed fixes of the first differing frame.
    IF BLOCKED: If the first difference comes from a retail bug, stop and describe it. 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 whenpython3 tools/compare_hash.py runs/<REPLAY> reports zero differing frames, and the layout test shows identical frames.

    Proof this works: Tenkaichi 3 Decomp (PCSX2 replay compare, BT3_HASH), RECVX Enhanced Port (layout_check.sh with a padded build)

Tools you need

ToolWhat it doesHow to get itHow we know
PS2Recomp
Required both
Turns a PS2 ELF into C++ and gives a runtime that stands in for the console. The runtime is partial, so you add to it.
Path A
`git clone --recurse-submodules https://github.com/ran-j/PS2Recomp.git`, `cd PS2Recomp`, `cmake -S . -B out/build`, then `cmake --build out/build --config Debug`tool README and CI workflow (read 2026-11-13; CI builds on Ubuntu and Windows MSVC); built on Windows in this site's hands-on test (2026-11-13); used by: DW5XL Recomp, GTA Vice City Stories recomp, God of War Native PC, GoW PC port
Ghidra
Required both
A free tool that reads machine code and shows it as assembly and rough C. You use it to find every function start.
Path A Path B
Install JDK 21. Download the 12.1.4 release zip from the releases page, unzip it, then run `ghidraRun.bat`Ghidra README at tag Ghidra_12.1.4_build names JDK 21; the current README names JDK 25 for 12.2 (both read 2026-11-13); 12.1.4 used by: DW5XL Recomp, GTA Vice City Stories recomp (with JDK 21)
ghidra-emotionengine-reloaded
Required both
A Ghidra add-on for the PS2 CPU. It reads the extra PS2 instructions and can load PCSX2 save states.
Path A Path B
Download the zip that matches your Ghidra version from the releases page. In Ghidra use `File > Install Extensions`tool README and releases (v2.1.39, read 2026-11-13); used by: DW5XL Recomp
PCSX2
Required both
The main PS2 emulator. It is your reference for how the real game looks, sounds and behaves.
Path A Path B
Download the installer from https://pcsx2.net/downloads/. Dump the BIOS from your own consoletool README (v2.8.2, read 2026-11-13); BIOS page https://pcsx2.net/docs/setup/bios/ (read 2026-11-13); used by: DW5XL, Stuntman, rac-rs, Tenkaichi 3
llvm-mingw
Helpful Windows
A Clang compiler for Windows that you unpack and use. Several PS2 ports build their Windows version with it.
Path A
Download `llvm-mingw-<version>-ucrt-x86_64.zip` from the releases page and unpack it to a short path like `C:\llvm-mingw`tool README and releases (20261104, read 2026-11-13); used by: GTA Vice City Stories recomp, God of War Native PC, GoW PC port, ICO PC
Visual Studio 2022 Build Tools
Required Windows
Microsoft's C++ compiler (MSVC) for Windows. PS2Recomp is tested mainly with it, and CMake finds it by itself.
Path A
Download Build Tools for Visual Studio 2022 from https://visualstudio.microsoft.com/downloads/ and pick the **Desktop development with C++** workloadPS2Recomp README (read 2026-11-13); PS2Recomp built with Build Tools 2022 in this site's hands-on test; used by: Project Cane, GT3 Revisited, ps2-port-engine (Visual Studio 2022)
CMake and Ninja
Required both
CMake writes the build files and Ninja runs them fast. Every recomp and port reviewed here uses both.
Path A Path B
In WSL: `sudo apt install cmake ninja-build`. On Windows they come with Visual Studio 2022 C++, or from their release pagesrepos checked 2026-11-13 (Kitware/CMake, ninja-build/ninja); PS2Recomp README needs CMake 3.20+; used by: DW5XL, GTA VCS, Tenkaichi 3
paraLLEl-GS
Helpful both
Draws PS2 graphics on the GPU with Vulkan. Ports use it as a renderer or as a reference.
Path A
`git clone https://github.com/Arntzen-Software/parallel-gs.git` and pin a commit, as DW5XL doestool README (read 2026-11-13); used by: DW5XL Recomp, GTA Vice City Stories recomp (opt-in)
ps2-port-engine
Helpful Windows
A second PS2 pipeline. It turns each function into C++ and tests it against the original code in an interpreter.
Path A
In your game repo: `git submodule add https://github.com/danielgomesvieira2000/ps2-port-engine engine`. Needs Python 3.10+ and Visual Studio 2022 C++tool README (read 2026-11-13); used by: Stuntman, Burnout 3 PC
7-Zip
Required both
Opens a disc image so you can copy out the boot ELF and other files.
Path A Path B
In WSL: `sudo apt install 7zip`, then `7z x mygame.iso SLUS_XXX.YY -ogame/`Ubuntu noble package page and file list (7zip 23.01 gives /usr/bin/7z), 7-Zip -o switch docs (read 2026-11-13); used by: Tenkaichi 3 Decomp (7z reads the disc)
splat
Required WSL/Linux
Cuts the PS2 ELF into assembly and data files, and writes the linker script that puts them back.
Path B
In WSL: `python3 -m venv .venv`, then `.venv/bin/pip install -U "splat64[mips]"` (the README gives `python3 -m pip install -U splat64[mips]`)tool README and Quickstart-Elf page (read 2026-11-13); installed and run in a venv on Windows and WSL in this site's hands-on test; used by: Tenkaichi 3 Decomp, gt4-decomp
MIPS binutils
Required WSL/Linux
The assembler, linker and objcopy for MIPS. The decompals build adds fixes for PS2 compilers.
Path B
In WSL: `sudo apt install binutils-mips-linux-gnu`. For the PS2 fork, download `binutils-mips-ps2-decompals-linux-x86-64.tar.gz` from its releasessplat Quickstart-Elf and fork README (v0.10, read 2026-11-13); used by: Tenkaichi 3 Decomp
PS2 original compilers (decomp.me set)
Required WSL/Linux
Copies of Sony's ee-gcc builds and Metrowerks mwcps2, as used on decomp.me. A match needs the exact one.
Path B
Download the archive for your compiler from the `decompme/compilers` release named `compilers`, for example `ee-gcc2.96.tar.xz`, into `tools/`repo platforms/ps2, the compilers release asset list and the ee-gcc2.96 Dockerfile (read 2026-11-13); used by: Tenkaichi 3 Decomp (ee-gcc 2.96), recvx-decomp (mwccps2.exe, run with wibo on Linux)
wibo
Helpful WSL/Linux
Runs small 32-bit Windows command-line programs on Linux. You need it to run the Metrowerks mwccps2.exe compiler in WSL.
Path B
Download `wibo-i686` (or the newer `wibo-x86_64`) from the releases page, then `chmod +x` ittool README and releases (1.2.0, read 2026-11-13); wibo-x86_64 ran in WSL in this site's hands-on test; used by: recvx-decomp (README)
objdiff
Helpful both
Shows the original and your rebuilt function side by side and marks every difference. It supports PS2 MIPS.
Path B
Download `objdiff-windows-x86_64.exe` (GUI) or the CLI from the releases pagetool README (read 2026-11-13); progress format used by: gt4-decomp
m2c
Helpful both
Turns MIPS assembly into a first C draft. It has a target for the PS2 CPU.
Path B
`git clone https://github.com/matt-kempster/m2c`, then run `python3 m2c/m2c.py -t mipsee-gcc-c -f <func> <file>.s`tool README (mipsee platform, read 2026-11-13) and m2c/options.py, which parses mipsee-gcc-c as platform, compiler, language; run on Windows in this site's hands-on test; gt4-decomp counts sources free of m2c macros
decomp-permuter
Helpful WSL/Linux
Tries many small rewrites of a function to find one that matches. Use it only on near misses.
Path B
In WSL: `git clone https://github.com/simonlindholm/decomp-permuter`, then in a venv `pip install pynacl toml Levenshtein`. Add `permuter_settings.toml` with `build_system = "ninja"`tool README and import.py (read 2026-11-13: permuter@home not on native Windows, WSL works; Ninja projects need permuter_settings.toml; default assembler flags are for the N64); help runs in this site's hands-on test; used by: Tenkaichi 3 Decomp

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.

ps2-recomp-Agent-SKILL

skills.sh

Rules for PS2Recomp ports with a large PS2 hardware guide. Use with care: do not let Claude run its GhydraMCP download script.

npx skills add hkmodd/ps2-recomp-agent-skill --skill ps2-recomp-Agent-SKILL -a claude-code

recompile-console-binary

skills.sh

Covers PS2Recomp. Its main rule matches the reviewed projects: never edit the machine-made code, fix the settings and run again.

npx skills add xsyetopz/skills --skill recompile-console-binary -a claude-code

debug-game-in-emulator

skills.sh

Makes each PCSX2 run the same: a throwaway data folder, a log and a time limit. Claude must name the failing layer before a fix.

npx skills add xsyetopz/skills --skill debug-game-in-emulator -a claude-code

matching-decomp

skills.sh

A one-function-at-a-time loop for splat style MIPS projects, with state in files. It lists PS2. It makes commits, so save your work first.

npx skills add ketbome/decomp-skills --skill matching-decomp -a claude-code

orchestrator

skills.sh

Runs many workers, each in its own worktree and slice of the game. Every merge must pass the byte check, like the Tenkaichi 3 gate. If a compiler is missing, it points to Internet Archive; whether that is legal for you is your call.

npx skills add lemiur/game-decompilation-skill-for-claude --skill orchestrator -a claude-code

decompile-to-matching-c-cpp

skills.sh

Rules for C that builds to the same bytes, with compiler notes. It lists PS2 and bans fake matches. It is text only; read it first, since the author is new.

npx skills add xsyetopz/skills --skill decompile-to-matching-c-cpp -a claude-code

native-platform-porting

skills.sh

For the Path B port step. It warns Claude not to hide a small emulator inside the port.

npx skills add lemiur/game-decompilation-skill-for-claude --skill native-platform-porting -a claude-code

verification-before-completion

skills.sh

Claude may not say done without running the check and showing the output. It fits DW5XL's rule that a failing test is reported as failing.

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

GhidraMCP

MCP server

Lets Claude read functions and cross-references from your Ghidra project. DW5XL and 3SX used a Ghidra MCP server. It can also rename, so tell Claude to keep it read-only.

First install the plugin zip from its releases with `File > Install Extensions` in Ghidra 12.1.4, and install `uv`. Then: claude mcp add ghidra -- uvx --from git+https://github.com/LaurieWired/GhidraMCP ghidra-mcp --ghidra-server http://127.0.0.1:8080/

ps2-bringup (write your own)

write-your-own

Gives every session the same bring-up loop. Stuntman ships skills like this in engine/.claude/skills.

Make `.claude/skills/ps2-bringup/SKILL.md`. It says: run `python tools/check.py --boot`, read the stop report, fix one item in `overrides/` by address, never edit `generated/`, no stub that returns success, rerun `--regress`, then commit with before and after numbers.

ps2-match-unit (write your own)

write-your-own

Puts the Tenkaichi 3 agent rules in one place, so every worker gets them without a long prompt.

Make `.claude/skills/ps2-match-unit/SKILL.md`. It names your compiler and flags, says `fdiff.py` is the only tool to run, bans inline asm and checker edits, caps tries at 5, and sets the report: file, OK count, `INCLUDE_ASM` left, guessed names.

Claude setup for this system

On PS2 the natural unit is small. For Path A, one task is one crash, one missing system call, or one VU1 program. For Path B, one task is one source file inside one address range. Every unit has its own check: a failing test that turns green, a frame compare, or the per-function diff. One lead session owns the full build, the game runs and git. Workers never run the whole game or the full gate.

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 disc and serial, search for an existing port or decomp, and name the compiler or recompiler. 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 projectLay out the repo, keep the disc out of git, build PS2Recomp or the splat project, and write tools/check.py.Opus 5.5
effort medium
Sonnet 5.5
effort medium
Study the game fileFind function starts in Ghidra with the EE add-on, add functions hidden behind pointers, and tag Sony SDK and middleware code.Opus 5.5
effort high
Opus 5.5
effort medium
Raise to high for function edges and data layouts. A mistake there spreads.
Bulk unitsPath B: match one source file per worker with the per-function check. Path A: replace temporary ret0 stubs with real versions.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 that failed five tries, permuter runs, and behaviour tests for functions that will not match.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 runtimeWrite the stand-ins for the GS, VU1, SPU2 sound, the IOP, the disc, pads and memory cards. Check each against the slow path or PCSX2.Opus 5.5
effort high
Opus 5.5
effort medium
Raise to high for timing and graphics bugs.
Find a bugFind why a run hangs, draws black or desyncs. Use the run log, a GS frame dump or a PCSX2 comparison. Prove the cause before a fix.Opus 5.5
effort high
After two failed tries with full evidence, move to Fable 5.2.
Opus 5.5
effort high
One bug at a time.
Check the workA fresh session reruns the gate on a clean checkout and hunts for weakened tests, edited hashes and edits to generated code.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, the function ledger, notes/game-internals.md and the handoff note.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 two or three workers, each in its own worktree. Only the lead builds and runs the game, because in God of War a header change rebuilds about 6,400 files. Path B: one lead plus six to ten workers on separate address ranges. Tenkaichi 3 capped itself at ten.

Max 5x (now called Max)

Path A: one session at a time, with one more for a verify pass. Path B: one lead plus two or three workers. Give only the hard tail the hard job type.

Lines for this project's CLAUDE.md

Add to CLAUDE.md
- Read `SCOPE.md` and `PROGRESS.md` at the start of every session.
- Never edit files in `generated/`. Fix the config, an override, or the recompiler instead.
- The one check is `python tools/check.py`. A claim of PASS must paste its output and name its log.
- Never change a test's pass rule, a reference hash or a recorded picture CRC to make a check pass.
- Game files stay in `game/` and are never committed: no ISO, ELF, IRX, generated C++, disassembly or frame dumps.
- Overrides are bound by function address and call the original for anything they do not replace.
- Do not add a stub that returns success for missing hardware. Implement it from docs and PCSX2, with a test.
- Ghidra is read-only for workers. Do not rename, retype or save the project.
- Write every address you learn into `notes/game-internals.md`, with how you found it. Mark it verified or guess.
- Workers run only `tools/fdiff.py`. Only the lead runs `configure.py`, `splat`, `ninja` and git.
- In a worktree, use absolute paths and your own scratch folder. Kill only the process ID you started.
- Ask before launching the game if another copy is running. Never test on my real memory card.

Keep the context small

  • Give Claude an address and a file path, not pasted disassembly. Let it read the one function it needs.
  • Keep CLAUDE.md short and point to docs/ by topic. Long rule files get skipped.
  • Use a subagent to read a big log or the Ghidra export, and have it report ten lines back.
  • Clear the chat after each task. State lives in PROGRESS.md and the ledger, not in the chat.
  • Batch Ghidra lookups. Headless Ghidra takes 30 to 60 seconds to start each time.
  • Turn off verbose logging and frame dumps unless the task needs them. They slow the game and fill the disk.

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 decide if this PS2 game can be done and how.

Prompt for Claude
GOAL: Tell me if <GAME> (serial <SERIAL>) can be ported to PC, by which technique, and what already exists.
READ FIRST: `notes/disc-facts.md`, https://github.com/ran-j/PS2Recomp, https://github.com/decompme/compilers/tree/main/platforms/ps2.
FENCE: Write only `notes/feasibility.md` and a draft `SCOPE.md`. Do not touch game files. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
CHECK: Write one claim per line starting with `- `. Run `grep -c '^- ' notes/feasibility.md` and `grep -cE '^- .*(https://|disc-facts)' notes/feasibility.md`. Done means both print the same number.
BUDGET: Stop after 1 hour.
IF BLOCKED: If the game uses a custom language or an unknown compiler, stop and say so. 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) Recommended path: recomp, matching decomp, or port of an existing decomp. 3) Prior work with URLs. 4) Risks: VU1 code, overlays, C++. 5) Questions for me.

A good answer: A short file that names one technique and lists prior work with links. It flags risks like VU1 microcode or overlays. It ends with a draft SCOPE.md.

Map the binary

After setup, to build the function ledger from Ghidra.

Prompt for Claude
GOAL: Build `notes/functions.csv` for <SERIAL> with address, size, library tag and status for every function.
READ FIRST: `config/ghidra_export.csv`, Ghidra through the MCP (read-only), `SCOPE.md`.
FENCE: Write only `notes/functions.csv` and `notes/map-notes.md`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
CHECK: Run `python tools/validate_map.py notes/functions.csv`. Done means no overlaps and the count matches the export plus any added entries.
BUDGET: Stop after 2 hours.
IF BLOCKED: If more than 5% of the code has no function, 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 ledger with one row per function, SDK and middleware tagged, a list of functions added from pointer tables, and the validator output pasted.

Unit loop: one recomp issue

Path A, for each crash, hang or missing call.

Prompt for Claude
GOAL: Fix one issue: <SYMPTOM> at <ADDRESS_OR_LOG_LINE>.
READ FIRST: `notes/issues/<ID>/spec.md`, `logs/<ID>.txt`, `notes/game-internals.md`.
FENCE: Edit only `overrides/`, `tests/` and `notes/issues/<ID>/`. Never edit `generated/`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
CHECK: Show the new test failing first. Then run `python tools/check.py --test <ID>` and `python tools/check.py --regress`. Done means both pass.
BUDGET: Stop after 3 failed fixes.
IF BLOCKED: If the bug is in the recompiler, stop and describe the instruction. 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 a failing-then-passing test, one override file changed, the regression output pasted, and the address added to the internals notes.

Unit loop: one decomp file

Path B, for each worker's file.

Prompt for Claude
GOAL: Match the functions in `src/<FILE>.c` (address range <START>-<END>).
READ FIRST: `docs/agent_rules.md`, `notes/compiler.md`, the frozen asm snapshot `snap/<DATE>/asm/`.
FENCE: Edit only `src/<FILE>.c` and your own symbol file. No inline asm. Do not run `configure.py`, `splat`, `ninja` or git. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
CHECK: Run `python3 tools/fdiff.py src/<FILE>.c`. Done means OK for each function you claim.
BUDGET: Five serious tries per function. Then `INCLUDE_ASM` with your best try under `#if 0` and a note.
IF BLOCKED: If a header change is needed, stop and ask. 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) fdiff output. 3) Functions OK versus `INCLUDE_ASM`. 4) Guessed names. 5) Doc notes marked verified or inferred.

A good answer: A list of functions marked OK or INCLUDE_ASM, with the fdiff output pasted. Float constants are checked by hand. Unsure names are marked as guesses.

Batch dispatch

Path B lead session, to hand out the next batch of files.

Prompt for Claude
GOAL: Pick the next <N> unmatched files from `notes/functions.csv` and start one worker per file in its own worktree.
READ FIRST: `notes/functions.csv`, `docs/agent_rules.md`, `docs/brief.md`.
FENCE: Assign disjoint files only. Edit only `notes/assignments.md`. Workers follow `docs/agent_rules.md`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
CHECK: When workers report, merge one at a time and run `python3 configure.py && ninja`. Done means `cmp` passes after every merge.
BUDGET: Stop the batch if two merges in a row fail the gate.
IF BLOCKED: If a worker reports a toolchain problem, pause the batch. 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) Gate output after the last merge. 3) Files merged and files returned. 4) New progress percent. 5) Parking-lot items.

A good answer: An assignment table with no shared files. A merge log with the gate result after each merge. A new progress number taken from the build.

Debug with evidence

When the recomp hangs, draws black, or drifts from PCSX2.

Prompt for Claude
GOAL: Find the cause of <SYMPTOM>. Do not fix it yet.
READ FIRST: `logs/<RUN>.txt`, the GS frame dump `dumps/<FRAME>`, the PCSX2 screenshot `ref/<FRAME>.png`.
FENCE: Read only, plus new files in `notes/debug/<ID>/`. Turn on tracing only for the one subsystem you test. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
CHECK: Name the first address or frame where the PC build and PCSX2 differ, with the log lines that prove it.
BUDGET: Stop after 2 hours or 3 disproved theories.
IF BLOCKED: If you cannot reproduce it twice, 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) The proven cause with evidence. 3) Theories ruled out and how. 4) The smallest fix you propose. 5) Parking-lot items.

A good answer: One proven cause, with the log lines or frame that show it. A list of ruled-out ideas. A proposed fix that is not yet applied.

Verify: hunt for cheating

After any batch of claimed fixes or matches. Always a fresh session.

Prompt for Claude
GOAL: Check that the work in commits <RANGE> is real.
READ FIRST: `git log <RANGE> --stat`, `CLAUDE.md`, `tools/check.py`.
FENCE: Read only. Write findings to `notes/verify-<DATE>.md`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
CHECK: From a clean checkout run `python tools/check.py --regress` (Path A) or `python3 configure.py && ninja` (Path B). Look for edited tests, hashes, CRCs, generated files, inline asm and new success stubs.
BUDGET: Stop after 1 hour.
IF BLOCKED: If the check fails on a clean checkout, stop and report that first. 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) Check output. 3) Each finding with file and line. 4) Commits to revert. 5) Parking-lot items.

A good answer: A clean-checkout check result and a list of findings, each with a file and line, or a plain statement that nothing was found.

Status report

Weekly, or when you return after a break.

Prompt for Claude
GOAL: Report project status with numbers from the ledgers only.
READ FIRST: `PROGRESS.md`, `notes/functions.csv`, `notes/parking-lot.md`, the last regress log.
FENCE: Read only. Write only `notes/status-<DATE>.md`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
CHECK: Every number cites the file it came from. Run `python tools/check.py --regress` and paste the summary line.
BUDGET: Stop after 20 minutes.
IF BLOCKED: If two files disagree, stop and show both. 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 status. 3) Counts: matched, stubs left, open issues. 4) Top three blockers. 5) Parking-lot size.

A good answer: A short page of numbers, each with its source file, plus the regress summary line and the top three blockers. No padding.

Session handoff

At the end of every session, before you clear the chat.

Prompt for Claude
GOAL: Write what the next session needs into the ledger files.
READ FIRST: `PROGRESS.md`, `notes/handoff.md`, this session's work.
FENCE: Edit only `PROGRESS.md`, `notes/handoff.md` and `notes/dead-ends.md`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
CHECK: Run the project check (`python tools/check.py --regress` or `python3 configure.py && ninja`) and `git status --short`. Paste both into `notes/handoff.md`. Done means it also names the next task and every dead end tried.
BUDGET: Stop after 15 minutes.
IF BLOCKED: If you are unsure what is done, mark it PARTIAL and say why. 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) Next task in one line. 3) Last check output. 4) Dead ends added. 5) Files changed.

A good answer: Updated PROGRESS.md and notes/handoff.md with the next task, the last check result and new dead ends, so no session repeats them.

Blocked or cannot deliver

When a task has stalled or Claude keeps saying it should work.

Prompt for Claude
GOAL: Give me a plain answer on <TASK>: can it be done now, and if not, why.
READ FIRST: `notes/issues/<ID>/work.md`, the last three check outputs.
FENCE: Read only. Write only `notes/issues/<ID>/blocked.md`. Everything else is read-only. Do not add features, refactors, tools or cleanups I did not ask for.
CHECK: Run the task's own check command once more and paste its output. Start with DONE, PARTIAL or BLOCKED. Every claim cites a log or file.
BUDGET: Stop after 20 minutes.
IF BLOCKED: If the honest answer is no, say no first. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
REPORT: 1) Outcome word. 2) What cannot be done and why. 3) What was tried. 4) Two or three options with cost. 5) What you need from me.

A good answer: A first line that says BLOCKED or PARTIAL, the reason with evidence, and two or three options with their cost. No "should work".

Scope change request

When Claude finds work outside the fence, like a recompiler bug or a renderer swap.

Prompt for Claude
GOAL: Ask me before leaving the fence for <CHANGE>.
READ FIRST: `SCOPE.md`, the issue that led here.
FENCE: Change nothing. Write only `notes/scope-requests.md`. 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 only `notes/scope-requests.md` changed, and the request names the files, the reason, the risk and the check.
BUDGET: Stop after 15 minutes.
IF BLOCKED: If the change touches `generated/` or the check script, say so in the first line. Do not work around it. Tell me what blocked you, what you tried, and what you need from me.
REPORT: 1) The change in one line. 2) Why it is needed now. 3) Files it touches. 4) Its check. 5) What happens if I say no.

A good answer: One clear request that you can answer yes or no, with the files, the risk and the check spelled out.

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 fixes a bug by editing the machine-made C++ in generated/. The next recompile wipes the fix.Never edit generated/. Fix it in an override bound by address, in the config, or in the recompiler. Block the folder with a hook.
Claude adds a stub that returns success so the game gets past a missing call. The real problem is hidden.Temporary ret0 stubs are allowed only to sort calls, and each is listed in PROGRESS.md. Real code must follow the docs and PCSX2, with a test.
Claude loosens a test, a time window or a threshold to make it pass. DW5XL saw this on 2026-10-19.Never change a test's pass rule. A failing test is reported as failing. Only I change tests or reference values.
Claude writes extracted game files into a new folder that git does not ignore, then commits them.Game data lives only in game/ and build/. A pre-commit hook rejects ELF, ISO, IRX, generated C++ and dumps. Never use --no-verify.
Claude says a function matches, or a fix works, without running the check.Do not claim a match you did not see fdiff print OK for. Every PASS names its log and pastes the output.
Claude kills every game process by name and closes the copy you were playing.Kill only the process ID you started. Ask before you launch the game.
Claude hand-writes shell heredocs that turn \n into real line breaks inside C++ strings.Patch files with the edit tool or a script file, never a shell heredoc. Both GTA VCS and Stuntman hit this.

Problems other projects hit

Branch labels in the function map made the recompiler copy code many times: 67k files and 572 MB.

Fix: Feed only real Ghidra functions. GTA VCS then got 9,584 files, 243 MB and no errors.

Seen in: GTA Vice City Stories recomp

Functions reached only through pointers and vtables were missing, so the game stopped at untranslated code.

Fix: Add them from a script or an existing decomp's symbol list. GTA VCS added 833; GT4 added 1,105.

Seen in: GTA Vice City Stories recomp, GT4 Recomp, God of War Native PC

The runtime's ready-made versions of Sony libraries were wrong for the game: wrong clears, wrong matrix order, wrong tags.

Fix: Let the game's own SDK code run as guest code. Replace only what touches hardware.

Seen in: DW5XL Recomp

Translator bugs gave wrong colours on every texture and a wrong square root. In Stuntman the interpreter had the same bug, so its tests passed.

Fix: Check each new instruction against the hardware docs, not only against your own interpreter. Log every runtime patch with its reason.

Seen in: GTA Vice City Stories recomp, Stuntman

Plain PC floats gave NaNs on the first battle frame. The PS2 FPU has no infinities or NaNs.

Fix: Use a PS2 float model. Tenkaichi 3 builds game code with soft floats checked against PCSX2.

Seen in: Tenkaichi 3 Decomp, Stuntman, GT3 Revisited

VU1 microcode ran in the interpreter, so combat was slow. In GTA VCS the interpreter took 75% of the frame.

Fix: Record the programs and compile them ahead of time. Keep the interpreter as a checker.

Seen in: GoW PC port, GTA Vice City Stories recomp, GT4 Recomp

A first screen stayed black because textures upload from an interrupt the host ignored.

Fix: Model the VIF interrupt bit. Write each such finding in FINDINGS.md with its address.

Seen in: Stuntman

On 64-bit PCs, records holding pointers grew, so casts of fixed buffers overflowed.

Fix: Keep pointers 4 bytes, or audit every struct with scripts that fail CI.

Seen in: ICO PC, Tenkaichi 3 Decomp

Windows builds broke on long paths and on patch files checked out with Windows line endings.

Fix: Build in a short folder like C:\ps2work. Add *.patch -text to .gitattributes.

Seen in: God of War Native PC

Changing a header that generated code includes rebuilt about 6,400 files each time.

Fix: Put experiments in an override file that only needs a relink. Batch build file changes.

Seen in: GoW PC port, GTA Vice City Stories recomp

How long it takes

Max 20x (now called Ultra)Max 5x (now called Max)One person, no AIHow sure
Path A: running on PC4 to 12 weeks10 to 30 weeks1.5 to 4 yearsmedium confidence
Path B: full decomp12 to 40 weeks30 to 100 weeks3 to 10 yearslow confidence

Read this first

These numbers assume one medium game and one person giving 10 to 15 hours a week. For Path A, four dated AI projects agree on weeks, not months, to a first release. But they do not say their hours, and many reused another project's runtime or history. Path B is less sure. Only Tenkaichi 3 has a dated AI decomp and a playable port, and gt4-decomp's port does not run yet. Treat the ranges as a rough guide, not a promise.

What makes it faster or slower

  • Prior work. A game with an existing decomp, a sister game or a working runtime fork can take days instead of weeks.
  • VU1 microcode and the GS. Games that draw through many VU1 programs need recording, compiling and frame checks.
  • C or C++. C++ games add vtables, hidden functions and harder matching.
  • The original compiler. A known ee-gcc build on decomp.me is fast to set up. An odd one can block Path B.
  • Overlays and extra binaries. Tenkaichi 3 had a second binary; DW5XL had three overlays.
  • Your machine. A full build of the generated C++ took 10 to 90 minutes in the reviewed projects.

The facts behind these numbers

ProjectWhat happenedLink
DW5XL RecompFirst commit 2026-10-13. First release 2026-10-20. Latest release 2026-11-08; the README says all modes work (beta). One contributor, agent files.source
GTA Vice City Stories recompFirst commit 2026-10-21. Fully native 2026-10-26. First release 2026-10-30. Two contributors, agent files.source
StuntmanFirst commit 2026-10-16. First release 2026-10-29, on an engine built for Burnout 3. One contributor, Claude Code.source
GT4 RecompFirst commit 2026-09-09. First release 2026-10-21. Eight contributors, agent files.source
Tenkaichi 3 DecompWork order agreed 2026-10-03. 94.96% of the main binary matched by 2026-10-05 with up to 10 agents at once. Port released 2026-10-06.source
gt4-decompRepo created 2026-10-06. By November 2026, 98.0% of 30,875 functions matched, but only 89.6% of code bytes. Mostly done by Claude agents. Its PC port is not playable yet.source
recvx-decompRepo created 2024-07-24 by a team. README says the game is now decompiled. It says AI gave negligible results in 2024 and much of 2025.source
Sly 1 decompRepo created 2021-11-09. Still a work in progress in November 2026.source
Project CaneOne person. First commit 2023-09-03. First playable release 2026-10-21. No AI stated.source

Projects reviewed (15)

The top-starred project for each of the top 12 PS2 games on RecompLauncher, plus three AI-flagged projects. RecompLauncher lists 97 PS2 projects for 76 games. Two of the 15 cover God of War and one is a launcher.

What each project teaches

OpenGOAL

Jak and Daxter: The Precursor Legacy, Jak II and Jak 3

Top rated on RecompLaunchernon-matching decompplayable
OpenGOAL decompilergoalcCMakeTask

Started: 2020-08. First release: 2024-04. Code: GOAL (Lisp) and C++.

AI: none stated; AI_POLICY.md bans AI commits in master Agent files: AGENTS.md.

Lesson: The games were written in a custom Lisp, so the team built its own decompiler and compiler. It took a team of 76 several years.

Tenkaichi 3 Decomp

Dragon Ball Z: Budokai Tenkaichi 3

Top rated on RecompLauncherport of a decompplayable
splatee-gcc 2.96ninjafdiff.pydecomp-permuterclang

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

AI: yes: README says made with the help of AI; about 150 agents Agent files: docs/agent_rules.md, docs/decomp_guide.md, docs/status.md.

Lesson: Many workers on separate address ranges, one lead that owns the build, and a byte gate before every commit. It matched about 95% in three days.

Grand Theft Auto Vice City Stories

Grand Theft Auto: Vice City Stories

Top rated on RecompLauncherstatic recompplayable
PS2RecompGhidra 12.1.4llvm-mingwCMakeNinjaSDL3

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

AI: yes: AGENTS.md is the contract for AI agents Agent files: AGENTS.md, CLAUDE.md.

Lesson: Replace each emulated layer with native code one at a time, and check it against the old path. Keep the old path behind a switch.

GT4 Recomp

Gran Turismo 4

Top rated on RecompLauncherstatic recompplayable
ps2-web-recompgt4_vu_recompclang-clCMakeNinjaVulkan

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

AI: yes: AGENTS.md guides every AI coding agent Agent files: AGENTS.md, CLAUDE.md, AGENT-BRIEF-COREGS2.md, docs/AGENT-WORKFLOW.md.

Lesson: Pin every input and output by hash, so nobody can quietly re-pin to hide a difference. Use a matching decomp's symbols to find missing functions.

ICO PC

ICO

Top rated on RecompLauncherport of a decompplayable
gcc 14llvm-mingwmingw-w64CMakeNinjaSDL3

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

AI: none stated in the repo; RecompLauncher flags AI use for code

Lesson: Keep game code and the port layer in separate trees. Carry the old compiler's rules with flags, and audit struct sizes on 64-bit.

Project Cane

Sly Cooper and the Thievius Raccoonus

Top rated on RecompLaunchernon-matching decompplayable
Visual Studio 2022CMakeOpenGLFFmpeg

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

AI: none stated

Lesson: One person grew a map viewer into a full port in about three years. Its repo describes no tests or hashes, so accuracy is hard to judge.

3SX

Street Fighter III: 3rd Strike

Top rated on RecompLauncherport of a decompplayable
clangCMakeMSYS2SDL3Ghidra MCP

Started: 2024-09. First release: 2026-02. Code: C.

AI: none stated; ships one agent skill Agent files: .agents/skills/compare-cps3-code/SKILL.md.

Lesson: Build on a finished matching decomp, then check behaviour frame by frame against emulator RAM dumps from real replays.

GT3 Revisited

Gran Turismo 3: A-Spec

Top rated on RecompLauncherreimplementationplayable
CMakeSDL3Visual Studio 2022

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

AI: yes: commit trailers name Claude

Lesson: Write how each system behaves in prose first, then code against it. Replay the disc's demos as a test.

rac-rs

Ratchet & Clank

Top rated on RecompLauncherstatic recompplayable
recgen_iso.pyvugen_iso.pyRustwgpuzig

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

AI: none stated in the repo; RecompLauncher flags AI use for code

Lesson: Ship only the generator and generate game code from the player's disc. Test rewrites by comparing game memory on the same frames.

RECVX Enhanced Port

Resident Evil Code: Veronica X

Top rated on RecompLauncherport of a decompplayable
GCC 32-bitmingw-w64CMakeNinjaOpenGLSDL3

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

AI: yes: README says most code was written by AI coding agents

Lesson: Keep the decomp's own PS2 layer and emulate the hardware under it. Rebuild with a different memory layout to find reads of unwritten memory.

OpenGOAL Launcher

OpenGOAL Launcher

Top rated on RecompLauncherothercomplete
Tauri v2RustSvelte 5

Started: 2022-02. First release: 2022-08. Code: Svelte, Rust and TypeScript.

AI: none stated

Lesson: A launcher can hide a long pipeline: check the disc, decompile, compile, run. It just calls the project's own tools in order.

God of War Native PC

God of War

Top rated on RecompLauncherstatic recompplayable
PS2RecompGhidrallvm-mingwCMakeNinjaQt 6

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

AI: yes: AGENTS.md says it is maintained mainly by AI agents Agent files: AGENTS.md, CLAUDE.md.

Lesson: Keep a ledger of failed experiments so a new session does not repeat them. Keep your changes as small numbered patches on a pinned runtime.

God of War (2005)

God of War

Added: developer used AIstatic recompin progress
ps2_recomp (Rust)Rabbitizerllvm-mingwCMakeNinjaTauri

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

AI: yes: the developer says AI was used for code Agent files: AGENTS.md, CLAUDE.md.

Lesson: When you rewrite a tool, prove its output is byte-identical to the old one. Write agent rules for sharing a PC with the player.

Stuntman

Stuntman

Added: developer used AIstatic recompplayable
ps2-port-engineVisual Studio 2022CMakeNinjaVulkanSDL 3

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

AI: yes: README credits Claude Code Agent files: engine/.claude/skills/ps2-decomp/SKILL.md, engine/.claude/skills/ps2-port/SKILL.md, engine/.claude/skills/ps2-release/SKILL.md.

Lesson: Only verified code counts. Each function is run against the original in an interpreter, and picture CRCs guard every change.

DW5XL Recomp

Dynasty Warriors 5: Xtreme Legends

Added: developer used AIstatic recompplayable
PS2RecompGhidra 12.1.4ghidra-emotionengine-reloadedGhidraMCPClangparaLLEl-GS

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

AI: yes: AGENTS.md working agreement; commits name Claude Agent files: AGENTS.md, CLAUDE.md.

Lesson: Approve a spec before work, write a failing test first, and never change a test's pass rule. It wrote that rule after an agent did.

What we could not check

  • Whether 7z reads every PS2 disc image, such as dual-layer DVDs. Tenkaichi 3 uses it; DW5XL uses bsdtar.
  • How many hours a week the dated projects took, and how much private work came before their first public commit.
  • Whether the ICO decomp used AI. Its README does not say.
  • Whether Windows users can run the ee-gcc compiler builds natively. This guide assumes WSL, as the reviewed decomps do.
  • The tools/check.py, validate_map.py, difftest.py, golden.py and compare_hash.py scripts are ones you write. Their names follow the reviewed projects but are not standard tools.
  • Which other compilers PS2 games used besides ee-gcc and mwcps2. SN Systems tools were not checked.
  • No step was run on a real PS2 game here. PS2Recomp, splat, m2c, wibo and the permuter were only installed and started, or run on test files.
  • PS2Recomp was built on Windows only. Its CI also builds on Ubuntu, but WSL was not tested here.
  • The assembler_command the permuter needs for PS2 code. Its defaults are for the N64; the right PS2 flags were not worked out here.
  • The Path B time ranges. Only one dated AI project (Tenkaichi 3) reached a playable port, so the confidence is low.

Sources