How it really works
Each stage, the real tools, and the checks that keep Claude honest. More detail than the Overview, in the same plain words.
What is inside a game file
A game file is one long row of bytes. A byte is a number from 0 to 255. Nothing in the file says which bytes are code.
Most game files hold three kinds of bytes.
- The header. A small block at the front. It says where to load the game and where to start.
- Code. The steps the chip runs, also called machine code. Each step is one instruction. Instructions are grouped into functions, and each function does one small job.
- Data. All the rest: pictures, sound, text and level maps.
Code and data sit in blocks called sections.
The names are gone
In the studio, the game was written in a language such as C. A compiler turned the C into machine code. Each function had a name, and those names are called symbols. Studios strip them out before the game ships. Sometimes they survive in a debug build or a sister game. So the method looks for prior work first.
Byte order
A big number takes more than one byte. Big-endian chips store the big end of the number first. Little-endian chips store the small end first. An N64 game file is big-endian. A PC is little-endian. So a port, a version of the game for another system, must swap the bytes of each number it reads. A missed swap turns 1 into 16,777,216.
Chip families
Each console's main chip belongs to a family. One family runs one kind of instructions.
| Chip family | Systems that share it |
|---|---|
| MIPS | N64, PlayStation, PS2, PSP |
| PowerPC | GameCube, Wii, Wii U, Xbox 360, PS3 |
| x86 | Xbox, PC, PS4, PS5 |
| ARM | Game Boy Advance, DS, 3DS, Switch, Switch 2 |
| 68000 | Genesis, Amiga, CD-i |
| 6502 family | NES, Super Nintendo |
| Z80 family | Game Boy, Game Boy Color, Game Gear |
| SuperH | Saturn, 32X, Dreamcast |
Tools are built per family, not per console. splat cuts up N64, PlayStation, PS2 and PSP files, which are all MIPS. decomp-toolkit does that job for GameCube and Wii.
The x86 row is special. A PC is x86 too, so the old code can run behind a thin layer that fakes the console.
From bytes to assembly
Before anyone can translate the code, a tool must turn its bytes into text. That text is called assembly.
The tool is a disassembler. It prints each instruction as one short line. It needs a map that says which bytes are code and which are data. With a wrong map, it reads a picture as code and prints junk.
A splitter puts the map to work. It cuts the game file into the pieces listed in a config file. splat and decomp-toolkit are splitters.
Where each function starts and ends
Functions sit back to back. Tools guess the edges, and no one tool finds them all. On one Game Boy Advance game, the first tool found 93 functions. Ghidra, a tool for studying game files, added about 300. The final count was 663.
Jump tables
A jump table is a list of addresses stored as data. The code picks one entry and jumps to it. The target is only known while the game runs. So a tool that just reads the file can lose track. XenonRecomp, an Xbox 360 tool, says its analyser "struggles with functions containing jump tables".
Why one wrong edge spoils what follows
Say the map cuts one function in two. No C code compiles to half a function. One author found that such a function could only fail, or pass by cheating. The agent, a Claude session doing the work, cannot tell that the map is wrong. It burns its tries or fakes a result.
Recompilers suffer too. The Xbox 360 kit ReXGlue warns that you will spend "significant time manually specifying function boundaries". Data hidden inside code does the same harm.
Fix the map, not the function
When a function fails again and again, check its edges first. Fix the map and let the tool write the assembly again. Never let Claude edit the assembly by hand. One project blocks that with a hook, a script Claude Code runs before each edit.
This stage ends with a ledger: a file that lists each function and its status. Mark library code in it, so nobody rewrites it by hand.
Static recompilation, step by step
A recompiler is a translator. It reads the game's machine code and writes C that does the same steps. "Static" means it does this once, before the game runs. The result is called a recomp.
Feed it the game and the map
The recompiler takes the game's code and a config file with the function list.
It writes one C function per game function
Each function in the game becomes one function in C.
Each instruction becomes a line of C
The C cannot use the real chip, so it uses a pretend one. A register is a slot in the chip that holds one number. The registers become fields in a C struct, a named group of values. The console's memory becomes one big block of bytes.
/* The game said: add 1 to register 8 */ cpu->r8 = cpu->r8 + 1; /* The game said: save register 8 into memory */ write32(memory, cpu->r29 + 16, cpu->r8);
This sketch shows the idea. It is not real tool output.
Calls get wired up
A call to a known function becomes a plain C call. An indirect call is harder, because the game works out the target as it runs. So the recompiler builds a table from each old address to its new C function. The code looks the address up and calls what it finds.
A PC compiler builds it
The output is plain C, so a modern compiler can build it. The last step links it with the runtime.
What it cannot do alone
- Jump tables. One Switch project tests its table finder against an emulator, a program that acts like the real chip. The rule is zero mismatches.
- Code that rewrites itself. The recompiler only read the file.
DolRecompsays such code needs manual review.
The result is not an emulator. Zelda 64: Recompiled says it "cannot run any arbitrary ROM". It is not readable source code either. The C is machine-made.
Never edit the generated code. Fix the generator.
The next run of the recompiler writes the C again and wipes your edit. A fix in the recompiler or its config lasts. One author wrote that Claude "could never edit generated code directly". Back the rule with a hook that blocks such edits.
The runtime: a stand-in for the console
The translated code still thinks it lives in a console. It asks for things only a console has. The runtime is the code that answers.
| Part | What the runtime does |
|---|---|
| System calls | Answers the game's calls to the console's own software: open a file, play a sound, read the pad. |
| Graphics | Turns console draw commands into ones a PC graphics card knows. RT64 does this for N64. |
| Sound | Sends the game's sound to your PC. |
| Input | Reports a PC pad or keyboard as the console pad. |
| Timing and threads | A thread is one line of work in a program. The runtime copies the console's rules for sharing the chip between threads. Without the Switch's rules, the PC version of Tears of the Kingdom crashes or hangs. |
| Save files | Writes saves as normal files on your PC. |
Not every recompiler brings a runtime. N64Recomp pairs with N64ModernRuntime and RT64. XenonRecomp has none. ReXGlue adds one for Xbox 360 that is derived from Xenia. PS2Recomp has its own, marked experimental, with many parts not written yet.
First light
First light is the first frame on screen. You run the recompiler over the whole game, build it, and stub the system calls. A stub is a stand-in that does nothing yet. Then you fix what stops the boot, one thing at a time. The real work starts after first light. One author's N64 game booted, and the graphics fixes came after that.
Stubs are a debt. One strict PlayStation project bans them: a function works in full or it stops the game with an error. List each stub in the ledger. Never count a stubbed call as done.
Runtime work needs a reference, not guesses. One author made Claude check each choice against Ghidra. Without that rule, Claude "liked to speculate and experiment". With tools to replay inputs and take screenshots, Claude often worked alone for 60 to 90 minutes.
Matching decompilation, step by step
Decompiling means writing C source for code that exists only as bytes. The result is called a decomp. Matching adds one hard rule: your C must compile to the same bytes as the original game.
Find the original compiler and its flags
Each compiler version makes its own choices. Flags are its settings. Same bytes need the same compiler, version and flags. Snowboard Kids 2 used GCC 2.7.2 with
-O2 -mips3.Split the game into object files
An object file is the compiled form of one source file. The linker joins them into the final game. The splitter cuts target objects from the real game, and your code must equal those. A function with no C yet stays as assembly.
Get a first draft from m2c
m2cturns assembly into rough C. Alone, it matched 17 of 1,830 functions in one project. But the draft gives Claude a start and costs no tokens. Tokens are the units of text your plan counts.Build the context pack
A script gathers what Claude needs for one function. That is the target assembly, the
m2cdraft and the data types it uses. Add the functions that call it and the ones it calls. Add up to five similar matched functions with their C. Give no more.Compile and diff
The original compiler builds Claude's C.
objdiffcompares the result with the target, one function at a time. That compare is called a diff. 100% means each instruction is the same. One project's rules for Claude say "99% is failure".Change one thing, then try again
Each try goes in a new file, so a good try is never lost. Each try changes one thing. Fix the branches and loops first. Register mix-ups come last.
Run the full build check
At 100%, rebuild the whole game and compare its hash with the original. A hash is a short fingerprint of a file. Pass: commit the work to git and update the ledger. Fail: reset the files and log the try.
Which function comes next
Early on, pick the easiest function. Once those ran out, one author found a better order: the function most like one already matched. Its C becomes the worked example. Copies of one function come first: match one and the rest are free.
The permuter and its risks
decomp-permuter makes small random changes to your C and keeps the ones that score closer. But its output is odd code no person would write. One author took it out of his agent loop after Claude read that code as a clue. He got "doom loops and token burn". It also cannot fix wrong branches. Use it late, with a time limit.
Why the full build is the verdict
A per-function score is evidence, not proof. It can lie in three ways.
- One project notes that
objdiffmisses the literal pool, a block of fixed numbers beside a function. - An object file leaves each call's address blank until link time. Local tools skip those blanks. So a call to the wrong function can still score 100%.
- A change to one function, or to a file that many sources share, can shift the bytes of another.
So strong projects rebuild the whole game after each function. One project's rules file for Claude says "make compare is the only verdict".
Even 100% is not the finish. Snowboard Kids 2 still needed names, structs and assets at that point. The Melee team says AI tools "produce candidates rather than verified answers".
When matching is not possible
Sometimes you cannot match. The original compiler is unknown, or the game is too big. Then you check what the code does, not its bytes.
The main tool is the differential test. Run the same input through the original code in an emulator and through your new code. Then compare.
- Memory and registers after one function runs. One Switch project tests its translator against an emulator this way.
- A trace: a log of what the game did. One N64 port logs its draw commands and diffs them against a reference log.
- Frame pictures. One PC rewrite reached 307,199 of 307,200 pixels the same.
A fair test needs the same input both times. Record the pad presses once and replay them in both. And never ask Claude to judge by eye. One author found models "very eager to say that something is the same".
Where this is the only choice
Behaviour checks are the only choice for recompiled games, since generated C never matches bytes. The same goes for games with an unknown compiler, big modern games, rewrites and ports.
A differential test proves only the paths it ran. And with no machine check at all, results go bad fast. One team ran agents for a month with a reviewer agent as the only check. The code had wrong data layouts and made-up logic. They threw it away.
From decomp to port
A finished decomp still builds a console game. A port makes that source build for a PC or another system.
Put the console parts behind an interface
An interface is a fixed set of calls. The game keeps making the same calls, and the port swaps what sits behind them.
libultrashipdoes this for N64 games. Ship of Harkinian, the Ocarina of Time PC port, is built on it.Clean up for 64-bit
The N64 stored an address in 4 bytes. A modern PC uses 8. Number types change size too. One Smash Bros. port found a type that is 4 bytes on Windows and 8 on Linux. A matrix grew from 64 bytes to 128, and 3D shapes collapsed.
Clean up byte order
The game's data is big-endian, so the port swaps bytes as it loads. A swap must know the real shape of the data. The same port swapped each 4-byte group. One block held single bytes, and a fighter's face drew as garbage.
Pull the assets from the player's own game
Assets are the art, sound and level data. A public port cannot ship them. It ships a tool that pulls them from your own game file.
Torchis that tool forlibultrashipports.torch otr baserom.z64
The check for a port is the golden run. The game starts by itself and must reach the same known points on the new system.
The checks, strongest first
Every task needs a check a machine can run. Each kind proves less than the one above it.
| Check | What it can prove | What it cannot prove |
|---|---|---|
| 1. Byte match. The rebuilt game has the same hash as the original. | The code compiles to the same bytes. | That the C is clean. A fake match passes too. |
| 2. Differential test. The same input goes through the original and the new code. | The two act the same for the inputs you ran. | Any path the test did not reach. |
| 3. Golden run. The game starts alone and reaches a known point in a set time. | The game boots and gets that far. | What happens after that point. |
| 4. Build check. The code compiles with no errors and no new warnings. | The code is valid C. | That anything works. Never accept it alone. |
Calibrate the check first
A check that cannot fail proves nothing. So test the check before you trust it.
- Break something on purpose. Change one line in a matched file and run the check. It must fail.
- Score something known to be good. A function that already matches must score perfect.
Two projects wrote down ways their checks had lied. A stale build printed OK. The diff tool missed the literal pool. One author's advice: "Distrust your best numbers".
GOAL: Prove that our check can fail. Do not fix or improve anything.
READ FIRST: SCOPE.md, PROGRESS.md, and the check command named in CLAUDE.md.
FENCE: Edit only one matched source file, and put it back before you finish. Everything else is
read-only. Do not add features, refactors, tools or cleanups I did not ask for.
CHECK: 1) Run the check on a clean checkout. It must pass.
2) Change one line in one matched function. Run the check. It must FAIL.
3) Undo the change. Run the check. It must pass.
Done means all three results are exactly as stated.
BUDGET: Stop after 3 failed tries, or when you have made no progress for 20 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 three check outputs. 3) Files changed
(should be none). 4) What is left. 5) New parking-lot items.A good answer: starts with DONE and pastes three outputs: pass, fail, pass. If step 2 passes, your check is broken.
Running many agents
One session on one function is slow. Many at once are fast. They also waste the most when the set-up is loose.
One unit, one fresh session
A unit is the smallest piece with its own pass or fail check. In a decomp it is one function or file. In a recomp it is one crash or one missing system call. Each unit gets a new, empty session. State lives in ledger files, not in the chat.
A script picks the next unit
Do not ask Claude what to do next. A script reads the ledger and picks, which saves tokens. In one project the script also runs git reset --hard after each run, then the full check.
Cap the tries
Most matches come early. In a test of 60 functions, nearly half of all matches came on the first try. A function not matched by try three had about a one in four chance. Public projects use caps of 5 or 12 tries.
In one project, 15 in 100 wins took 28 tries or more. Those go to the hard pile. Claude does not always obey a cap written in words. One author set ten tries and saw dozens. So put the cap in the script.
Worktrees and merge trouble
Two sessions must never edit the same files. Give each its own git worktree: a second copy of the project that git keeps apart. claude --worktree <name> makes one.
- Missing game files. A new worktree holds only tracked files. List small ignored files in
.worktreeinclude. - A match that does not survive the merge. Merging joins the copies back into one. Run the full check again after it.
- Slow merges. One author with four worktrees said a full re-sync "could take more than an hour".
Which model does which unit
Use a cheaper model for bulk units and a strong one for the few hard ones. This only works under a strict check. One team got "extremely bad results" from cheap models at first. With a pass or fail byte check, the same models did well. They ended with 14 cheap agents and 2 strong ones.
The 60-function test measured the cost gap. An older Fable cost 3.5 to 4.6 times more than an older Sonnet. It matched 5 functions that Sonnet always failed.
On this site, bulk units go to Sonnet 5.5 at medium effort. A unit that fails three to five tries moves to the hard pile.
Max 20x (now called Ultra)
Hard units go to Fable 5.2 at high effort. Verified accounts have no five-hour limit. Watch the weekly limit: Fable can use at most half of it. One author on this plan ran three, then four worktrees. He warned that an Opus loop left alone could use up the plan "in a matter of days".
Max 5x (now called Max)
Hard units go to Opus 5.5 at high effort. Send only the last few to Fable 5.2. Run fewer sessions at once. You have a five-hour limit and half the weekly limit. Each platform guide gives a count.
| Job | What it is | Max 20x (now called Ultra) | Max 5x (now called Max) |
|---|---|---|---|
Plan the projectscope | Pick the approach. Study what already exists. Write the plan and the Scope Contract. | 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 projectsetup | Install tools. Write the build script and the check script. Lay out the folders. | Opus 5.5 effort medium | Sonnet 5.5 effort medium |
Study the game fileanalyze | Map the code. Find library code. Name functions. Work out data layouts. | Opus 5.5 effort high | Opus 5.5 effort mediumRaise to high for function edges and data layouts. A mistake there spreads. |
Bulk unitsbulk | Many small, similar units. Each has its own pass or fail check. Runs in parallel. | 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 unitshard | The units that bulk workers could not finish in three to five 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 runtimeruntime | Write the stand-in for the console: graphics, sound, input, files. | Opus 5.5 effort high | Opus 5.5 effort mediumRaise to high for timing and graphics bugs. |
Find a bugdebug | Find why it crashes or draws wrong. Use logs and traces. Prove the cause before any fix. | Opus 5.5 effort highAfter two failed tries with full evidence, move to Fable 5.2. | Opus 5.5 effort highOne bug at a time. |
Check the workverify | A fresh session re-runs the check and reads the changes. It hunts for cheating. | 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 recordsdocs | Update the ledgers, notes and summaries. | Haiku 5.5 effort medium | Haiku 5.5 effort medium |
The measured numbers
| What was measured | Result |
|---|---|
| 60 mixed functions, 12 tries each | 74% matched. 88% gave the same result on all three runs. |
| An N64 game with agents from day one | 100% in 84 days. The author's first game took 596 days. He says AI is only part of the reason. |
| Melee, 19,828 functions | 48.54% in January 2026. 100% in September 2026. |
| A PC shooter, up to 16 agents | About 3 months. 600 to 700 billion tokens. 83% of functions byte exact. |
| A first PlayStation recomp by a beginner | About three weeks to a playable game. |
How agents cheat, and what stopped them
Agents cheat when a check leaves room. One author wrote: "Agents have the desire to cheat if the assignment leaves room for interpretation".
| What the agent did | What stopped it |
|---|---|
| Edited the stored hash so a wrong build passed. | A hook that blocks edits to the hash file. |
| Edited the check script to skip its own function. | A build server compares a hash of the script with a stored secret. |
| Wrote raw assembly inside the C, or pinned values to registers. | A banned list in the rules file, and a hook that scans each edit. |
| Called a failed build a success. | Build text aimed at the model: "treat this as a build failure". |
| Ran the steps of a blocked command by hand. | A locked-down set-up where the agent can only submit C. |
| In recomps: stubs, fake events, a slow fallback passed off as recompiled code. | A rule of no stubs and no fallback. |
| Made up reasons, or cited scripts that never ran. | A fresh reviewer told to attack the reasons. |
| Said a match was impossible. | Proof. One author found matched functions with the same "impossible" shape. |
The guard rails
Hooks that block edits
One project's hooks block edits to the hash file and the assembly folder. Each prints what to do instead. Hooks leak, so they are one layer of several.
A checker the agent cannot touch
Run the final check where the agent cannot write. One project uses a private build machine. Only verified work lands.
Banned constructs
Write the banned list in the rules file and state the trade. One project's line: "A clean-C 90% beats an asm 100%".
A fresh reviewer
A new session re-runs the check and reads the diff. It helps because it has not seen the worker's reasoning. It does not replace a machine check. A person still reads each change before it merges.
The page Keep Claude on task shows how to set these up.
Where it breaks
This is where the method stalls or fails, as far as the sources show.
- Very large functions. One author found that Claude "more or less gives up immediately" past 1,000 instructions.
- The last few percent. In the 60-function test, 12 functions failed on each run. One author thinks his project would have stalled near 90% without compiler experts.
- Unknown compilers. Matching needs the exact compiler and version. Without it, you fall back to behaviour checks, where small bugs can hide.
- Recomps on newer consoles. We found no first-hand numbers for an agent-built recomp on Xbox 360, PS2, PS3, GameCube, Wii or Switch.
- Quality. One decomp author says AI-heavy recomps often end up as "buggy, low-quality ports".
- Your own grasp of the code. One author names "cognitive debt" as the main risk: code you own but do not understand.
Claude may say no
Since 2026-10-27, Claude Code has a rule against building a recreation of a specific existing game. It was written about remaking games from scratch. No source says how it applies to decomp or recomp work. If Claude says no, take that as the answer. This site offers no way around it.
Claude may switch models
Safety checks can move a session from Fable 5.2 or Opus 5.5 to an older model. This happens when content looks like security work. It can happen on the first request. The session stays on the older model until you run /model. Nobody in our sources tested how often decomp work sets this off.
Two more things are not known. Anthropic's docs do not say how good Claude is at this work. And no author has published what a whole project cost in dollars.
Rules of the road
This hobby rests on other people's free work. A few rules keep you welcome in it.
- Use only a copy of the game you own. Dump it yourself.
- Keep game files, keys and assets outside the repo, the folder git tracks, or in ignored folders.
- A public repo holds your own code only. No game data, no copied assembly, no generated C.
- Borrow code only under a licence that allows it, and keep the credit.
One Switch project checks this by script before each commit. Its installer builds the game code on the player's own PC.
What other projects say about AI
| Project | Its rule on AI-written code |
|---|---|
N64Recomp | Not accepted. "AI must not be used to generate code for contributions to this project". |
| Zelda 64: Recompiled | Not accepted in any form. |
| HarbourMasters | Accepted when small, disclosed and understood. Changes over a thousand lines are likely to be closed. |
| decomp.dev | The progress site closed its main index in October 2026. It adds no new projects. Old pages remain. |
N64Recomp gives its reason: AI tools patch things "in aggressive ways" to get one game working, and break others. The decomp.dev author named harms too: forks that finish someone's decomp with AI, and rushed ports.
Do not send AI-written code where it is banned
Read a project's contributing file before you send it code. If it says no AI, the answer is no. Never hide how code was made.
Say plainly what you made. A recompiled game is not a decomp, and a decomp is not a port. One author who finished two N64 games wrote: "The community was more important than any model".
Sources
- Lewis: N64 agents
- Lewis: one-function loop
- Lewis: the long tail
- Lewis: reaching 100%
- Lewis: 84 days
- Lewis: the recomp
- Snowboard Kids 2: hooks
- Snowboard Kids 2: loop
- Snowboard Kids 2: check
- Snowboard Kids 2: rules
- Snowboard Kids: compiler notes
- Macabeus: the 60-function test
- Macabeus: Fable against Sonnet
- Macabeus: Klonoa from zero
- Klonoa: rules file
- Klonoa: multi-agent command
- Melee: decomp skill
- Melee: lint hooks
- Melee: FAQ
- Melee: pull request 2076
- Melee: the last function
- Price-Burns: Star Fox Adventures
- Star Fox: rules file
- Maurice Heumann: 16 agents
- Stanley: PlayStation recompiler
- Stanley: replay tests
- psxrecomp: rules file
- Mario 64 DS: rules
- Piotr Migdal: pixel checks
- decomp.wtf wiki
- Zelda 64: Recompiled
- Zelda Switch recomp
- BattleShip port notes
- splat
- decomp-toolkit
- objdiff
- m2c
- decomp-permuter
- Ocarina of Time decomp
- N64Recomp
- N64ModernRuntime
- RT64
- XenonRecomp
- ReXGlue wiki
- PS2Recomp
- DolRecomp
- libultraship
- Torch
- Ship of Harkinian
- N64Recomp: rule on AI
- HarbourMasters: rule on AI
- decomp.dev statement
- Press report on decomp.dev
- Game Developer: games rule
- Claude docs: model switch
- Claude docs: worktrees
- Claude docs: best practices
- Claude plans and limits
- Claude help: Fable limits