# Retro Porting Toolkit documentation

> The complete documentation section of https://retroportingtoolkit.com as one document, in sidebar order. 58 pages, generated at build time from the same source the site renders.

Each page below is preceded by a horizontal rule and its canonical URL, and
carries the metadata from its own frontmatter. Draft pages are excluded. The
one line per page index of the same material is at `/llms.txt`.

Sections, in order: Start here, Concepts, Platforms, Guides, Working with AI agents, Reference, The fleet.

---

# Start here

> Six short pages for readers who know the emulator and porting scene, with technical ideas explained as plainly as possible.

- Canonical URL: https://retroportingtoolkit.com/docs/start
- Markdown: https://retroportingtoolkit.com/docs/start.md
- Section: Start here
- Page type: reference
- Tags: Orientation
- Last updated: 2026-08-31

---

Start here if you know emulators and fan-made ports, but static recompilation is new to you.

This documentation assumes some familiarity with how emulators and recompilation projects work. You do not need to be an expert, but terms such as game binary, runtime, native port, and command line should not be completely new.

The pages explain unfamiliar details as they appear and aim to be as beginner-friendly as the subject allows. Read them in order. By the end, you should understand what a recomp port is, what files you provide, and what the first real toolchain looks like.

- [What is static recompilation?](https://retroportingtoolkit.com/docs/start/what-is-static-recompilation.md). The idea in plain language, what it buys, and what it costs. Start here if you only read one page.
- [How is a port made?](https://retroportingtoolkit.com/docs/start/how-a-port-is-made.md). The usual path from a game file to a native application.
- [Is this emulation?](https://retroportingtoolkit.com/docs/start/is-this-emulation.md). No, but emulation is still part of the story.
- [What do I need to get started?](https://retroportingtoolkit.com/docs/start/what-you-need.md). The tools you need to play, build, or start a port.
- [Developer quickstart](https://retroportingtoolkit.com/docs/start/quickstart.md). The shortest real path from nothing to one working recomp toolchain.
- [How do I recomp my own game?](https://retroportingtoolkit.com/docs/start/recomp-your-own-game.md). You own a game and want a port of it. Start here.

When you want the ideas underneath, go to [Concepts](https://retroportingtoolkit.com/docs/concepts.md). When you want a specific console, go to [Platforms](https://retroportingtoolkit.com/docs/platforms.md).

---

# What is static recompilation?

> A game is translated before it runs, then built as a native program for your computer. The game code runs directly, while a runtime stands in for the old console around it.

- Canonical URL: https://retroportingtoolkit.com/docs/start/what-is-static-recompilation
- Markdown: https://retroportingtoolkit.com/docs/start/what-is-static-recompilation.md
- Section: Start here
- Page type: concept
- Tags: Static recompilation, Recompiler, Runtime
- Last updated: 2026-08-31
- Source repositories:
  - https://github.com/mstan/psxrecomp
  - https://github.com/mstan/snesrecomp

---

Static recompilation is a way to turn an old console game into a native app.

The starting point is the game's binary: the machine code on the disc or cartridge. Your computer cannot run that code directly, because it was made for a different machine.

A recompiler reads that old code before the game runs. It writes new source code that does the same work. Then a normal compiler builds that source code for your computer.

The result is a normal program. When you play it, your processor runs the game's translated logic directly.

## Why is it called static?

Static means the translation happens ahead of time.

The game is not being translated one instruction at a time while you play. Most of the hard work happened earlier, on a developer's machine, when the port was built.

That is different from an emulator. An emulator reads the game's old instructions while you play and acts them out on the modern machine.

## Is it always fully static?

That is the goal, but real games can make it complicated.

Some games load code later. Some jump through tables. Some copy code around in memory. If the tool cannot see that code ahead of time, the port may need another path while it is still being finished.

That path can still end in native code. A PlayStation game, for example, may load a new chunk from disc while it runs. A mature runtime can catch that chunk, translate it, keep it, and run it as compiled code later.

So keep two words separate:

**Native** means the game's logic runs as compiled code on your processor.

**Static** means the translation happened before the game ran.

A port can be native even when part of the work was not fully static yet.

## Why is it called recompilation?

The word is a little loose.

Many later games were built with compilers. For those games, recompilation means taking compiled machine code, turning it back into source code, and compiling it again for a new machine.

Older games are not always like that. NES and SNES games were often written by hand in assembly. Strictly, those games are being compiled this way for the first time.

The process is still the same enough that this site uses one word for all of it.

## What does the recompiler write?

The current projects here usually write C.

That does not mean static recompilation is defined by C. C is just the language these projects use today because normal compilers can build it almost anywhere.

The generated source code is not meant to be hand-edited. It is build output. If it is wrong, the fix belongs in the recompiler, the runtime, or the game's settings.

## What does the runtime do?

The game code still expects the old console around it.

It wants video, audio, controllers, timing, saves, memory behavior, and hardware registers. Your computer does not have that console hardware.

The runtime is the library that stands in for the console. The translated game code calls into it when it needs the machine around the game.

That is why a port is more than generated code. It is translated game logic plus a runtime that knows enough about the original console.

## What does this make possible?

A recompiled port can feel like a normal PC app.

It can have a launcher, controller settings, widescreen options, save states, rewind, mods, translations, and other features that are hard to add from outside a black-box emulator.

Those features still need discipline. The faithful game should be the baseline. Extra features should be optional, and with them off the port should behave like the original game.

## What is the hard part?

The hard part is not only translating instructions.

The hard part is knowing what is code in the first place. A game binary is just bytes. Some bytes are instructions. Some are data, graphics, audio, text, or tables. The tool has to tell the difference.

The other hard part is making one game feel finished. A build can compile and still have timing bugs, missing code paths, broken graphics, bad audio, or input problems.

That is why project maturity matters. PlayStation is the strongest starting point today. SNES is next. Other frameworks are at different stages.

## Where does emulation come in?

The game's own logic runs as native code. The console around it is recreated in software by the runtime. During development, a fallback interpreter may also catch code that has not been covered yet.

That is the honest answer. A recompiled port is not a traditional emulator running the game instruction by instruction, but it still needs software that stands in for the old machine.

See [is this emulation?](https://retroportingtoolkit.com/docs/start/is-this-emulation.md) for the longer version.

---

# How is a port made?

> The path from a game file to a native port: check the game, find its code, translate it, build it, test it, then add optional features.

- Canonical URL: https://retroportingtoolkit.com/docs/start/how-a-port-is-made
- Markdown: https://retroportingtoolkit.com/docs/start/how-a-port-is-made.md
- Section: Start here
- Page type: concept
- Tags: Porting, Pipeline, Recompiler
- Last updated: 2026-08-31
- Source repositories:
  - https://github.com/mstan/psxrecomp
  - https://github.com/mstan/snesrecomp

---

A port starts with one exact game file. It ends as a normal program for a modern computer.

It is not a rewrite from scratch. It is not a ROM loaded into a general emulator. It is a project that knows how to turn one game, usually one exact version of that game, into a native application.

The details change by console. PlayStation has the most mature path today. SNES is next. Other projects are useful, but many are still research, examples, or early toolchains. This page explains the common shape without pretending every project is equally ready.

## What happens first?

Before a game can be ported, the console needs a framework.

That framework is the shared work for one console. It contains the recompiler, the runtime, build scripts, and the rules for that machine. Building it is the long system-level job. Adding a game gets faster as the framework matures.

The game project starts by checking the file you give it. A port is tied to exact bytes at exact addresses. A different region, version, patch, bad dump, or trimmed file is not almost right. It is a different input, and the port should reject it.

## How does the tool find the game code?

A game binary is just bytes.

Some bytes are instructions. Some are images, sound, tables, text, or padding. The file does not come with labels that say which is which.

Discovery is the stage that finds the code. The tool starts from places the console guarantees, follows calls and jumps, and uses project settings for facts it cannot safely guess.

On older systems, some games were written by hand in assembly. Strictly, that code was never compiled the first time. The pipeline still treats it the same way: find the instructions, then translate them.

When discovery misses code, the port usually finds out later. The game jumps to an address with no translated function behind it, or a test run stops at a mismatch. That result feeds back into discovery.

> **A good decompilation can help.** Some games have public decompilations or
> disassemblies made by the community. Those can act like a map: this address is
> a function, this name is useful, this range is data and should not be treated
> as code. Super Mario World is a strong example. Its SNES recompilation uses
> that kind of map to make discovery clearer, while still building the port from
> your own game file.

## What does translation produce?

Translation turns the discovered machine code into source code.

The current projects here usually emit C. That is an implementation choice. Static recompilation means translating before the game runs, not specifically producing C.

The generated code is build output. If it is wrong, the fix belongs in the recompiler, the runtime, or the game's settings. Editing generated code by hand only hides the problem until the next generation pass overwrites it.

Being strict, the decoder is the part that reads the binary and writes code. Recompiler is the practical name for the whole tool around it: decoder, compiler, runtime, and the project pieces that make the result run.

## Where does the runtime fit?

The translated game code still expects a console around it. It reads controllers, draws graphics, plays sound, waits on timing, and talks to hardware addresses. A modern computer does not have that console hardware.

The runtime is the library that stands in for the console. The native game code calls into it when it needs the machine around the game.

That is why a port is not just generated C. It is translated game code plus a runtime that understands the original platform well enough to make the game behave.

## How is the result checked?

A successful build only proves that the code compiled. It does not prove the game behaves correctly.

There are two common checks.

First, the project looks for missing code paths. That means a jump or call reached an address with no translated function. This is usually a discovery problem. Fix the settings or the tool, regenerate, and build again.

Second, mature projects compare behavior against something known to be correct. That is co-simulation. A known good emulator runs the same moment of the game beside the port, with enough state exposed to compare the two. When they disagree, the first difference becomes the next debugging target.

The comparison target matters. A port agreeing with its own fallback interpreter is useful as a self-check. The stronger claim comes from matching an outside reference.

## When do enhancements happen?

Enhancements come after the base game behaves correctly.

Widescreen, mods, translation hooks, save states, and rewind are easier to trust when the unmodified port already has a solid baseline.

The default should stay faithful to the original game. Extra features belong behind switches. With those switches off, the port should behave like the game it was built from.

## Why is it a loop?

Porting is not a straight line.

A missing jump sends you back to discovery. A wrong pixel may point to the runtime. A crash may expose bad generated code. A toolchain fix means regenerating and rebuilding the games that depend on it.

That loop is where maturity comes from. The first game on a console teaches the framework what the console needs. Later games benefit from that work.

The goal is not months of custom work for every game. The goal is a framework that makes each next game easier.

---

# Is this emulation?

> Not in the usual sense. The game's own logic runs as native code, but the port still needs a runtime for the old console around it. Unfinished ports may also use a fallback interpreter until all code is covered.

- Canonical URL: https://retroportingtoolkit.com/docs/start/is-this-emulation
- Markdown: https://retroportingtoolkit.com/docs/start/is-this-emulation.md
- Section: Start here
- Page type: concept
- Tags: Emulation, Execution model, Honesty
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/psxrecomp
  - https://github.com/mstan/snesrecomp

---

Not in the way most players mean it.

In an emulator, the emulator is the program. It reads the old game's instructions while you play and acts them out for the modern machine.

In a recompiled port, the game is the program. The game's own code has already been translated and compiled for your computer. When you play, your processor runs that translated game code directly.

There is still software standing in for the old console. That part matters, and it is where the answer gets more careful.

## What runs natively?

The game's own logic runs as native code.

That means the code that decides where the player moves, what enemies do, how menus work, and how the game state changes is compiled for your computer. It is not being read one instruction at a time by an emulator during play.

This is the main difference. The port is not a general box for playing every game on that console. It is one game, rebuilt as one app.

## What does the runtime do?

The game still expects a console around it.

It asks for graphics, sound, input, timing, memory, save data, and other hardware behavior. Your PC does not have a Super Nintendo PPU or a PlayStation GPU inside it.

The runtime answers those requests. It is a normal library linked into the port. It stands in for the old machine around the game, the way any modern app uses libraries and operating system services around its own code.

Some of that work is hardware simulation. That does not make the whole port a traditional emulator. It means native game code is running on top of a runtime that knows how the old console behaved.

## Why is there sometimes an interpreter?

Some games hide code until they are running.

A game might load a new chunk from disc. It might jump through a table. It might build or copy code in a way the static pass did not fully see. Mature toolchains try to cover this before release, but unfinished ports can still have gaps.

A fallback interpreter is a safety net for those gaps. It runs missed code the slow way so the port can keep going instead of crashing at the first unknown address.

That fallback is not the goal. Projects measure it and work it down. A finished port should have full coverage and should not need the fallback during normal play.

## What does this mean when I download a port?

It should feel like a normal app.

You launch it. It checks the game file it needs from you. Then it runs that game as its own program.

You are not choosing a console core, loading a ROM into a general emulator, or tuning emulator settings before you can start. The port is built for that one game.

## Is any emulation involved at all?

Yes, depending on what you mean by emulation.

The game's own logic is native code. The console around it is recreated in software. During development, a fallback interpreter or a separate comparison emulator may also be used to find mistakes.

So the honest answer is narrow:

The port is not a traditional emulator running the game instruction by instruction. It is a native port with a runtime for the old hardware around it.

## Where should I look for a specific console?

Each console is different. PlayStation, SNES, NES, and the smaller projects do not all handle code coverage, hardware, or fallback paths the same way.

Use the [platform pages](https://retroportingtoolkit.com/docs/platforms.md) for the current answer on one console. Use [what is static recompilation?](https://retroportingtoolkit.com/docs/start/what-is-static-recompilation.md) if you want the core idea before the details.

---

# What do I need to get started?

> If you only want to play a finished port, you need the release and your own game file. If you want to build or work on ports, you need a small set of normal programming tools.

- Canonical URL: https://retroportingtoolkit.com/docs/start/what-you-need
- Markdown: https://retroportingtoolkit.com/docs/start/what-you-need.md
- Section: Start here
- Page type: guide
- Tags: Prerequisites, Build, Game files
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/psxrecomp
  - https://github.com/mstan/snesrecomp

---

It depends on what you want to do.

If you only want to play a finished port, you do not need a developer setup. Download the port, run it, and give it the game file it asks for. Some consoles may also ask for a BIOS or another system file.

If you want to build a port, test changes, or start your own game project, you need a small set of normal programming tools.

## What if I only want to play?

Go to the [games](https://retroportingtoolkit.com/games) page, pick a port, and download its release.

A finished port should behave like a normal app. On first launch, it may ask for your copy of the game. The port checks that file before it starts, because it was built for one exact game version.

That is all you need from this page if you only want to play.

This site does not provide game files or copyrighted retail BIOS files, and it does not tell you where to download them. The intended path is to legally dump them from hardware or media you own.

Some projects may include an open-source BIOS alternative when one is legal and useful. If so, the project will say that clearly.

## What tools do I need to build?

Most projects use the same five tools.

| Tool | What it is for |
|---|---|
| `git` | Downloading the project |
| C and C++ compiler | Building the recompiler, runtime, and app |
| CMake | Setting up the build |
| Ninja | Running the build |
| Python 3 | Running helper scripts |

Some projects need more, usually SDL for windows, input, and audio. A console's platform page will say when that matters.

## What should I install on Windows?

Most projects expect MSYS2 MinGW64, not PowerShell.

Install MSYS2, open the MinGW64 shell, then install the common tools:

```sh
pacman -S --needed mingw-w64-x86_64-toolchain mingw-w64-x86_64-cmake \
                   mingw-w64-x86_64-ninja mingw-w64-x86_64-ccache
```

Run build commands from that MinGW64 shell unless a project says otherwise.

## What should I install on macOS?

Install Apple's command line tools first. Then install CMake and Ninja:

```sh
brew install cmake ninja
```

Some projects also need SDL. If a build asks for it, install the SDL package named by that project.

## What should I install on Linux?

On Debian or Ubuntu, the common setup is:

```sh
sudo apt install build-essential cmake ninja-build
```

Some projects also need an SDL development package. Package names vary by distribution, so use the platform page or build error as your guide.

## What game files do I need?

For playing or porting a game, you need your own copy of that game in the format the project expects.

The exact file matters. A different region, revision, patch, bad dump, or trimmed file may be rejected. That is intentional. A port is tied to the bytes it was built around.

Some consoles also need a system file, such as a BIOS. That might mean a retail BIOS you dump yourself, or it might mean an open-source BIOS alternative supplied by the project. The platform page for that console will say when that applies.

## What do I not need yet?

You do not need to understand the whole console before you begin.

You do not need to know every command line tool by heart.

You do not need a game file for the [developer quickstart](https://retroportingtoolkit.com/docs/start/quickstart.md). That page uses psxrecomp because it is the gold-standard framework here today. Its example builds an open BIOS image, so you can run the pipeline before pointing any tool at your own game.

Future systems may not use the same exact commands, but they should follow the same shape: build the framework, provide the files the project asks for, verify the input, then run the result.

## How do I check my setup?

Open the shell you plan to build from and run:

```sh
git --version
cmake --version
ninja --version
python3 --version
```

Each command should print a version. If one is missing, install that tool before continuing.

On Windows, run this check inside MSYS2 MinGW64. A tool that works in PowerShell may still be missing from the shell that actually builds the project.

---

# Developer quickstart: psxrecomp

> Build psxrecomp, recompile an open-source PlayStation BIOS into native code, and run the project tests.

- Canonical URL: https://retroportingtoolkit.com/docs/start/quickstart
- Markdown: https://retroportingtoolkit.com/docs/start/quickstart.md
- Section: Start here
- Page type: guide
- Tags: Developer quickstart, Build, PlayStation
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/psxrecomp
  - https://github.com/mstan/nesrecomp

---

This page is for developers, port authors, and curious users who want to build a recomp toolchain.

psxrecomp is the gold-standard framework in this ecosystem right now. That does not mean every console works like PlayStation. It means this is the cleanest place to learn the shape of the work.

> **Note.** This quickstart does not build a game, and it is not required before
> playing a finished port. It recompiles an open-source PlayStation BIOS because
> that is a small, legal file the project can ship. If this works, you have
> proven the build and recompilation pipeline. A game project follows a similar
> shape.

You will build [psxrecomp](https://github.com/mstan/psxrecomp), recompile OpenBIOS into C, compile that C into a native program, and run the project tests.

## What will I have at the end?

You will have four things:

- the psxrecomp tools built on your machine
- C code generated from a PlayStation BIOS image
- a native runtime built from that generated C
- a test run that tells you whether the recompiler build is healthy

The BIOS used here is OpenBIOS, a legal open-source BIOS alternative from PCSX-Redux. This site does not provide copyrighted retail BIOS files. If a project needs a retail BIOS, the intended path is to legally dump it from your own hardware.

## Before you start

You need Git, Python 3, CMake 3.20 or newer, Ninja, and a C/C++ compiler.

If you do not have those yet, use [What do I need to get started?](https://retroportingtoolkit.com/docs/start/what-you-need.md) first.

On Windows, use the MSYS2 MinGW64 shell for the commands below. Do not use PowerShell for this quickstart.

## 1. Clone the repository

```sh
git clone https://github.com/mstan/psxrecomp.git && cd psxrecomp
git submodule update --init --recursive
```

The second command downloads the extra libraries the runtime expects. Do it now so later build steps do not fail halfway through.

## 2. Build the recompiler

```sh
cmake -S recompiler -B recompiler/build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build recompiler/build
```

This builds the tools that translate PlayStation code into C.

You should now have `psxrecomp-bios` and `psxrecomp-game` in `recompiler/build`.

## 3. Recompile the BIOS into C

This is the step where recompilation happens.

```sh
bash tools/regen_bios.sh --config bios/OpenBIOS.toml
```

The script reads the OpenBIOS image and generates C code from it. Run it from the psxrecomp folder, the one that contains `recompiler/` and `generated/`.

This step is easy to skip, but it is required. A fresh clone does not already contain the generated BIOS C.

You should now see `generated/OpenBIOS_full.c` and `generated/OpenBIOS_dispatch.c`.

If you legally dumped your own retail BIOS and want to build that backend too, this optional command uses the retail BIOS profile:

```sh
bash tools/regen_bios.sh --config bios/SCPH1001.toml
```

Use a legally obtained BIOS. This site does not provide them.

## 4. Compile the runtime against it

```sh
cmake -S runtime -B runtime/build -G Ninja -DCMAKE_BUILD_TYPE=Release -DPSX_RECOMP_UI=OFF
cmake --build runtime/build --target psx-runtime
```

This compiles the runtime. The runtime is the native program that surrounds the recompiled code and gives it the hardware services it expects.

This page turns the shared launcher UI off because the quickstart does not need it.

You should now see `runtime/build/PSXRecomp`, or `PSXRecomp.exe` on Windows.

## 5. Verify

Run the test suite:

```sh
cd recompiler/build && ctest --output-on-failure
```

CTest prints one line per test and then a summary. The result you want is:

```text
100% tests passed, 0 tests failed
```

The exact number of tests may change over time. The important part is `0 tests failed`.

These tests check the recompiler. They do not prove that a game port is faithful. For a game, the measurement is stricter: it needs to behave like the original game, not just start without crashing.

## 6. Run what you built

```sh
./runtime/build/PSXRecomp
```

With no arguments, it uses the bundled OpenBIOS. There is no game in this build and no disc to give it.

If graphics are a problem on your machine, the command line reference has the full flag list: [CLI reference](https://retroportingtoolkit.com/docs/reference/cli.md).

## What this did not get you

- **A game.** This quickstart builds the framework, not a game port.
- **A compatibility promise.** A generated project is a starting point. A real port still needs game-specific work.
- **A debug build.** `Release` builds are for speed. Use `RelWithDebInfo` later if you need debugging tools.
- **Anything redistributable from your own files.** Generated code from a retail BIOS or game file comes from your copy. Treat it that way.

## Troubleshooting

### Configure fails with `Cannot find source file: .../generated/OpenBIOS_full.c`

You skipped step 3, or you ran it after configuring the runtime. Run `bash tools/regen_bios.sh --config bios/OpenBIOS.toml`, then configure the runtime again.

### `regen_bios: no usable recompiler build dir found`

Step 2 has to come before step 3. Build the recompiler, then run the BIOS generation script again.

### A fingerprint-mismatch warning at configure time

The generated BIOS C is stale. Re-run step 3.

### `ninja: error: loading 'build.ninja'`, or `Error: could not load cache`

The configure step did not finish. Re-run the matching `cmake -S ... -B ...` command and read the first real error.

### The compiler dies with no diagnostic at all

This is often memory exhaustion. Retry with fewer build jobs:

```sh
cmake --build recompiler/build -- -j 2
```

### `SDL3 3.4+ was not found`

The SDL3 dependency could not be found or downloaded. Check network access, or install SDL3 locally and point CMake at it.

### Configure stops with a fatal error mentioning `recomp-ui`

Keep `-DPSX_RECOMP_UI=OFF` for this quickstart, or make sure submodules are initialized.

### MinGW reports `Error: too many sections`

Very large generated C files can hit a Windows object-file limit. Use a newer MinGW/binutils, or add `-Wa,-mbig-obj` for the affected build.

### CMake says it "is not able to compile a simple test program"

On MSYS2, the MinGW64 gcc needs its own `bin` directory on `PATH` for its runtime DLLs. Export it before configuring:

```sh
export PATH="/c/msys64/mingw64/bin:$PATH"
```

## If you would rather aim at a game

Go to [How do I recomp my own game?](https://retroportingtoolkit.com/docs/start/recomp-your-own-game.md).

That page starts from a game file you legally provide. Some systems may also need a BIOS or system file. This site does not provide copyrighted game files or retail BIOS files.

---

# How do I recomp my own game?

> Start with a realistic console, use a game file you own, expect a loop of build, run, observe, and fix. PlayStation is the strongest starting point today.

- Canonical URL: https://retroportingtoolkit.com/docs/start/recomp-your-own-game
- Markdown: https://retroportingtoolkit.com/docs/start/recomp-your-own-game.md
- Section: Start here
- Page type: guide
- Tags: Tutorial, PlayStation
- Last updated: 2026-08-30

---

You can try, but it is not a one-click conversion.

A recompiler can do a lot of work for you. It can find code, translate it, build a native app, and give you a place to start. It cannot promise that every game works the first time.

Think of it as starting a port project, not pressing a convert button.

## Which console should I start with?

Start with PlayStation unless you have a specific reason not to.

psxrecomp is the most mature framework in this ecosystem today. It has the strongest starter path and the clearest route from a disc image to a generated project.

SNES is the next strongest framework, especially when a game has a strong public disassembly or decompilation to help guide discovery. It is less of a single beginner path than PlayStation, but the results can be excellent.

Other consoles are at different stages. Some are useful examples. Some are research projects. Some are not yet a practical path to a playable port.

## What do I need before I start?

You need three things:

1. A game file you own, in the format the project expects.
2. A BIOS or system file, if that console needs one.
3. The normal build tools from [what do I need to get started?](https://retroportingtoolkit.com/docs/start/what-you-need.md).
4. A realistic target console from the [platform pages](https://retroportingtoolkit.com/docs/platforms.md).

The files matter. The port is built for exact bytes, not just a title. A different version of the same game may need different work.

For BIOS files, follow the platform page. Some projects can use an open-source BIOS alternative. Others need a retail BIOS dump you provide yourself.

## What does the first pass do?

The first pass tries to create a project that builds.

On PlayStation, the starter flow can inspect your disc, create the project layout, generate code, and build the result. That is the best current route for a first attempt.

The result may boot. It may get to menus. It may crash. It may run with missing audio, broken graphics, timing problems, or fallback interpreter use. That is normal early-port work.

The measurement is faithfulness. The question is not only "does it run?" The better question is "does it behave like the original game?"

## What happens after it builds?

You run the game and observe what happens.

Start simple. Does it boot? Does it show video? Does input work? Can you reach gameplay? Can you save and load? Does audio behave? Does it keep running after a few minutes?

Each answer tells you where to look next.

## Where does the real work go?

The real work is the loop.

Find missing code. Fix discovery. Regenerate. Build again. Compare behavior. Fix the runtime or game settings. Test again.

As the console framework matures, that loop gets shorter for later games. The goal is not to hand-build every game from scratch. The goal is a shared framework that keeps learning from each port.

## When should I ask for help?

Ask when you have a clear first failure.

Include the game, the console, the toolchain revision, the command you ran, and the first useful error or symptom. "It does not work" is hard to act on. "It boots, then jumps to an unknown address after the title screen" gives someone a real starting point.

If an AI assistant is helping, make it read the platform page first. Then make it explain what it is about to try before it changes anything.

## What should I not do?

Do not edit generated code by hand.

Do not assume a nearly matching game file is good enough.

Do not copy old commands from a random page if the platform page or project has moved on.

Do not treat one game's result as a promise about the whole console.

---

# Concepts

> The core ideas behind recomp ports, explained before the docs get console-specific.

- Canonical URL: https://retroportingtoolkit.com/docs/concepts
- Markdown: https://retroportingtoolkit.com/docs/concepts.md
- Section: Concepts
- Page type: reference
- Tags: Concepts
- Last updated: 2026-09-01

---

This section explains the ideas behind recomp ports.

Start here when a guide uses a word you do not know yet, or when you want to understand what a port is doing under the hood. These pages are still high level. They are meant to make the technical docs easier, not replace them.

- [What are the recompiler and runtime?](https://retroportingtoolkit.com/docs/concepts/recompiler-and-runtime.md). The two main parts most projects are built around.
- [How does a project tell code from data?](https://retroportingtoolkit.com/docs/concepts/code-discovery.md). Why finding the real program inside a game file is hard.
- [What are HLE and LLE?](https://retroportingtoolkit.com/docs/concepts/hle-and-lle.md). Two ways to handle console behavior around the game.
- [What about code you cannot see ahead of time?](https://retroportingtoolkit.com/docs/concepts/code-you-cannot-see-ahead-of-time.md). What happens when a game creates or loads code while it is running.
- [How do we compare a port to the original?](https://retroportingtoolkit.com/docs/concepts/co-simulation.md). How projects check whether the translated code still behaves correctly.
- [What does correct enough mean?](https://retroportingtoolkit.com/docs/concepts/accuracy-and-burndowns.md). How faithfulness becomes a list of concrete problems to fix.
- [When should timing be changed?](https://retroportingtoolkit.com/docs/concepts/timing-models.md). Why timing changes are advanced work and need measurement.
- [Why does determinism matter?](https://retroportingtoolkit.com/docs/concepts/determinism.md). Why save states and rewind need repeatable behavior.
- [What is the game file contract?](https://retroportingtoolkit.com/docs/concepts/the-game-file-you-supply.md). What the project expects you to provide, and why the site does not provide it.
- [Recompile the original game, then let mods do the rest](https://retroportingtoolkit.com/docs/concepts/start-with-the-original-game.md). Why patches belong in the mod layer instead of the recompiler's input.
- [What do these terms mean?](https://retroportingtoolkit.com/docs/concepts/glossary.md). Short definitions for common recomp words.

---

# What are the recompiler and runtime?

> Most recomp ports have two major parts: a tool that translates the game before launch, and a runtime that acts like the console around it.

- Canonical URL: https://retroportingtoolkit.com/docs/concepts/recompiler-and-runtime
- Markdown: https://retroportingtoolkit.com/docs/concepts/recompiler-and-runtime.md
- Section: Concepts
- Page type: concept
- Tags: Architecture, Recompiler, Runtime
- Last updated: 2026-08-30

---

Most recomp ports have two major parts.

The **recompiler** is a tool used while building the port. It reads the game's machine code and writes new source code from it. That happens before the port starts.

The **runtime** is the program that runs beside the translated game. It provides the parts of the console the game still expects: memory, video, audio, input, saves, timing, and sometimes a fallback interpreter.

The recompiler turns the game's instructions into native code. The runtime gives that native code a world to live in.

## Why does the port need both?

Translated game code is not enough by itself.

A game does not only do math and jump between functions. It reads controllers. It draws graphics. It talks to sound hardware. It waits for timing. It saves data. It expects memory to behave like the original console.

Your PC does not have that console inside it, so the runtime fills that role.

## What happens during a build?

The usual flow looks like this:

1. The project checks the game file.
2. The recompiler finds and translates the game's code.
3. A normal compiler builds the generated source.
4. The generated code and runtime are linked together.
5. The result runs like a normal app.

Some projects also compile a BIOS or other system software. Some do not need one. It depends on the console.

## What happens while the port is running?

The translated game code runs natively.

When it needs console behavior, it calls the runtime. The runtime answers those requests by acting like the original hardware or firmware closely enough for the game to behave correctly.

If the game reaches code that was not translated ahead of time, the runtime may use an interpreter. That is slower, but it keeps the game correct while the project learns about that missing code path.

## Which side owns a bug?

A good first question is: did the translated instruction do the wrong thing, or did the console around it behave wrong?

If an instruction was decoded incorrectly, that is usually a recompiler bug.

If input, audio, graphics, saves, timing, or hardware behavior is wrong, that is usually runtime work.

The split matters because a runtime fix can improve many games on the same console, while a discovery or translation fix may change the generated code for one game or one class of games.

## What does this mean for users?

For players, it mostly means a finished port should feel like a normal application.

For developers, it means the work is not just "turn ROM into C." A real port is translated game code plus a runtime that is faithful enough to make the game behave like it did on original hardware.

---

# How does a project tell code from data?

> A game file is just bytes. Before a recompiler can translate it, the project has to find which bytes are instructions and which bytes are not.

- Canonical URL: https://retroportingtoolkit.com/docs/concepts/code-discovery
- Markdown: https://retroportingtoolkit.com/docs/concepts/code-discovery.md
- Section: Concepts
- Page type: concept
- Tags: Code discovery, Recompiler
- Last updated: 2026-08-30

---

A game file is just bytes.

Some bytes are program instructions. Some are graphics, music, text, tables, padding, or other data. The file usually does not label them for you.

Before a recompiler can translate a game, it has to find the code. That step is called **discovery**.

![A short sequence of bytes can look like valid instructions from one starting point and nonsense from another.](./discovery.svg)

## Why is this hard?

The tool cannot translate every byte as code.

Data can look like code by accident. A sprite, a sound table, or a list of numbers may decode into instructions that look real but never run. If the recompiler treats that data as code, the port can become wrong in strange ways.

The tool also cannot ignore code it does not understand. If the game jumps to a function that was never translated, the port needs a fallback or the game stops there.

Good discovery is the balance: find the real code, avoid fake code, and leave room for the project to learn more while the game runs.

## Where does discovery start?

The project begins from places the console guarantees.

That might be a reset address, an interrupt address, a known executable header, or another entry point the hardware defines. From there, the tool follows calls, jumps, and branches.

When the code jumps through a table or computes an address at runtime, the tool may need help from project settings or later test runs.

## What about assembly games?

Many older games were written partly or fully in assembly.

Strictly, that code was not "compiled" from C or another high-level language the first time. It was still assembled into machine code. Recompilation still applies here because the port is translating the machine instructions that shipped in the game.

So for NES, SNES, and other assembly-heavy systems, "recompiled" means: find the original machine instructions and translate them into a modern native build.

## Can decompilations help?

Yes.

A good decompilation or disassembly can act like a map. It may identify functions, name useful addresses, or show which ranges are data instead of code.

That does not mean the port ships somebody else's decompilation. The port still builds from the game file the user provides. The decompilation helps the project understand that file.

Super Mario World is a good example of this kind of help. Community knowledge and disassembly work can make SNES discovery clearer without changing the basic contract of the port.

## What happens when discovery misses something?

A missed function is not automatically a disaster.

Mature runtimes usually have an interpreter fallback. If the game reaches code that was not translated, the interpreter can run it more slowly while the project records what happened.

That feedback helps the next build. The goal is not to stay in the interpreter forever. The goal is to learn the missing path, translate it, and make the port faster and more complete.

---

# What are HLE and LLE?

> LLE follows the console closely. HLE replaces part of the console with native code. HLE is useful, but HLE-first becomes a trap without a faithful floor.

- Canonical URL: https://retroportingtoolkit.com/docs/concepts/hle-and-lle
- Markdown: https://retroportingtoolkit.com/docs/concepts/hle-and-lle.md
- Section: Concepts
- Page type: concept
- Tags: Architecture, LLE, HLE, Correctness
- Last updated: 2026-08-31
- Source repositories:
  - https://github.com/mstan/cdirecomp
  - https://github.com/mstan/psxrecomp
  - https://github.com/mstan/ndsrecomp
  - https://github.com/mstan/snesrecomp

---

Two short terms show up a lot in recomp projects: **LLE** and **HLE**.

**LLE** means low level emulation. It follows the console closely. That can mean running the console's own firmware, recompiling it, or interpreting the original instructions.

**HLE** means high level emulation. It replaces some console behavior with native code that does the same job at a higher level.

Example: a game asks the console BIOS to read something from a disc.

With LLE, the console's own BIOS code handles the request.

With HLE, the port may skip that BIOS code and answer the request with native code.

## Is HLE bad?

No.

HLE can make a port easier to use, faster, or easier to ship. For example, a project might use HLE to skip a slow boot screen, route file access through a modern system, or replace a well-understood service with native code.

The danger is not HLE itself. The danger is HLE that becomes the only truth.

If the port replaces console behavior and has no faithful version to compare against, a wrong answer can look correct just because the game kept running.

## What is the rule?

The developer rule is: **faithful LLE is always the floor.**

That floor can be a recompiled BIOS, a recompiled system ROM, an interpreter, a trusted emulator used for comparison, or another path that follows the original machine closely.

HLE can sit above that floor. It can be faster. It can be easier to use. It can remove a BIOS or ROM file requirement when a legal replacement is good enough for the job.

But HLE should not define correctness by itself.

The LLE path is the blueprint and the success criteria. A higher-level replacement is acceptable when it behaves like the faithful path for the thing it replaces.

## Why is HLE-first a trap?

An HLE shortcut can be good enough for one game.

That is the trap.

If the project only needs one game to boot, a hand-written answer may look fine. The game asks for one behavior, the shortcut returns something close enough, and the milestone turns green.

That is why HLE can start to look like a stub. It is not automatically fake behavior, but it can become fake behavior if it replaces the console without being checked against the faithful path.

But a console ecosystem is bigger than one game. The next game may use the same BIOS call, hardware feature, timing detail, or edge case differently. Then the shortcut is no longer a shortcut. It is a game-specific hack that other games inherit.

Enough of those hacks turn the framework into a pile of special cases. They become hard to remove because something already depends on them.

LLE fights that drift. It keeps the project tied to what the machine actually did, even before every game needs every feature.

That matters later. A feature that one early game never used may become required by a later game. If the floor stays faithful, the project has a place to implement that feature correctly instead of guessing around old HLE behavior.

## Where does HLE fit?

HLE is still useful.

It can make a port faster. It can make setup easier. It can avoid asking the user for a BIOS or ROM file when a legal high-level replacement is appropriate. It can also make a finished port feel more like a normal modern app.

The key is order.

Build or keep the faithful path first. Use it as the reference. Then add HLE where it helps, with the LLE path still available to check it.

This is why mature projects care about [co-simulation](https://retroportingtoolkit.com/docs/concepts/co-simulation.md), reference emulators, fallback paths, and selectable low-level modes. They are not just developer tools. They keep convenience from silently becoming incorrect behavior.

## How do projects use this today?

psxrecomp is the clearest mature example. It can run with a low-level BIOS path, and it can also use higher-level helpers for convenience. The important part is that the lower-level path remains available as the reference.

snesrecomp leans on a faithful interpreter as its floor. That is a good fit for SNES work, where correctness and timing details matter a lot and many games are close to the hardware.

Other systems are at different levels of maturity. The useful question is not "does this project use HLE?" The useful question is "what checks the HLE path?"

## What should users take away?

For players, HLE and LLE are mostly invisible. A good port should just behave like the original game.

For developers, the distinction matters. HLE can be a practical tool, but it should not be used to fake progress. The port needs a faithful path that can catch mistakes.

---

# What about code you cannot see ahead of time?

> Some games load or create code while they run. A recomp project handles that with fallback execution, capture, and later translation.

- Canonical URL: https://retroportingtoolkit.com/docs/concepts/code-you-cannot-see-ahead-of-time
- Markdown: https://retroportingtoolkit.com/docs/concepts/code-you-cannot-see-ahead-of-time.md
- Section: Concepts
- Page type: concept
- Tags: Overlays, PlayStation, Code discovery, Nintendo DS, Game Boy Advance
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/psxrecomp
  - https://github.com/mstan/ndsrecomp
  - https://github.com/mstan/gbarecomp
  - https://github.com/mstan/snesrecomp

---

Static recompilation happens before the game runs.

That works well when the code is already present in the game file. But some games load code later, after the port has already started.

The most common example is an **overlay**. A game loads one chunk of code into memory, runs it, then loads a different chunk over the same address later.

The recompiler cannot translate code it has not seen yet. So the runtime needs a plan.

## Does the game crash when this happens?

It should not.

Mature runtimes keep an interpreter fallback. If the game reaches code that was not compiled ahead of time, the interpreter can run those instructions one at a time.

That is slower than native code, but it keeps the game moving and gives the project a chance to learn what was missing.

## Why is PlayStation the main example?

PlayStation games often stream code from the disc into RAM while the game is running.

The console only has 2 MB of main RAM. A game can be much larger than that, so it swaps code in and out as needed. One level, menu, cutscene, or mode may use code that was not present at startup.

That makes psxrecomp the strongest example of this problem. It needs to handle code that appears later, not just code that was hard to find.

## What does capture mean?

**Capture** means recording the code bytes when the game loads them.

Timing matters. The runtime wants the bytes as delivered, before the game changes them. It also watches which addresses actually execute, because that tells the recompiler where real functions begin.

Captured code can then be translated later.

## What does cache mean?

**Cache** means keeping the translated result so the same code can run natively next time.

If you visit an area of a game and the project captures an overlay there, a later run may already know about it. That area can become faster because the port no longer has to interpret that code.

This is why a PlayStation recomp can improve as more of the game is explored and captured.

## Why does the runtime check the bytes again?

The same memory address can hold different overlays at different times.

Address alone is not enough. The runtime has to check that the bytes in memory still match the code it compiled earlier.

If the bytes match, it can run the cached native code.

If they do not match, it falls back to the interpreter and may capture the new version.

That rule keeps the failure direction safe: wrong or stale native code should not run just because it lives at the same address.

## Do all consoles need this?

No.

NES is the simple negative case. The whole program is usually visible in the cartridge image, so there is usually no streamed code to discover later.

SNES can still benefit from fallback and feedback, but it does not copy the full PlayStation overlay model.

Nintendo DS has overlays, but they are usually known from the game format. That changes the problem.

Game Boy Advance does not stream code from a disc, but a game can still build or move code in memory. A fallback path can still be useful.

The real question is not cartridge versus disc. The real question is: can the bytes the CPU executes change after the build-time recompiler has looked?

---

# How do we compare a port to the original?

> Co-simulation runs the port beside a trusted emulator, compares them at the same points in game time, and stops at the first difference.

- Canonical URL: https://retroportingtoolkit.com/docs/concepts/co-simulation
- Markdown: https://retroportingtoolkit.com/docs/concepts/co-simulation.md
- Section: Concepts
- Page type: concept
- Tags: Correctness, Testing, Co-simulation
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/psxrecomp
  - https://github.com/mstan/nesrecomp
  - https://github.com/mstan/snesrecomp

---

A port can build and still be wrong.

It can boot and still be wrong. It can reach gameplay and still be wrong. Faithfulness means the port behaves like the original game on the original machine.

**Co-simulation** is one way to measure that.

The idea is simple: run the port beside a trusted emulator, feed both the same game and same input, stop both at the same point in game time, and compare their state.

If they match, the port is still on track.

If they differ, the first difference is the bug to investigate.

This is development tooling. End users benefit from the results: fewer strange bugs, better faithfulness, and stronger confidence that the port behaves like the original game.

## Why use an emulator as the reference?

The port often has more than one way to run code. It may have compiled native code and an interpreter fallback.

If those two agree, that is useful, but it does not prove the port is faithful. They could both be wrong in the same way.

A trusted emulator gives the project an outside reference. It is still software, not magic, but it is independent enough to catch mistakes the port might miss by comparing against itself.

## What gets compared?

The project compares the parts of the machine that can affect what the game does next.

That can include CPU registers, RAM, video memory, timers, interrupt state, sound state, and other device state.

It should not include host-only details, like a pointer address on your PC. Those can change for reasons that have nothing to do with the game.

The hard part is choosing the right state. Miss something important and the comparison can pass while the game is already wrong. Include something irrelevant and the comparison can fail for no useful reason.

## Why stop at the first difference?

Visible bugs usually show up late.

A broken jump may corrupt memory. Later, the screen glitches. Later still, the game crashes. If you start debugging at the crash, you are chasing the final symptom.

Co-simulation tries to stop at the first moment the port and reference disagree. That first difference is much closer to the real bug.

![The rungs are game time checkpoints. The first mismatch matters more than the final visible symptom.](./lockstep.svg)

## How do both sides stop at the same time?

They need a shared clock.

Wall-clock time is not good enough. Your PC may run one side faster than the other.

Instead, the comparison uses time from inside the emulated machine: guest cycles, frames, scanlines, or another console-specific unit.

The exact unit depends on the console. The important rule is that both sides must stop at the same point in the game's timeline.

## Does a clean co-sim run prove everything?

No.

It proves the port matched the reference for the state and time range that were checked.

It does not prove the reference emulator is perfect. It does not prove the screen and sound are correct unless those are part of the comparison. It does not prove unplayed parts of the game.

That is still powerful. A clean co-sim run is much stronger than "it seems to play fine," because it gives the project a repeatable way to find the first wrong moment.

---

# What does correct enough mean?

> A recomp port is correct enough when it behaves faithfully for a clear, measured scope. A burndown records what has been checked and what has not.

- Canonical URL: https://retroportingtoolkit.com/docs/concepts/accuracy-and-burndowns
- Markdown: https://retroportingtoolkit.com/docs/concepts/accuracy-and-burndowns.md
- Section: Concepts
- Page type: concept
- Tags: Correctness, Testing, Accuracy
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/nesrecomp
  - https://github.com/mstan/snesrecomp
  - https://github.com/mstan/gbarecomp
  - https://github.com/mstan/smsggrecomp
  - https://github.com/mstan/segagenesisrecomp

---

"Does it work?" is too vague.

A better question is: **what has been measured, against what reference, and under what scope?**

A recomp port can boot and still be wrong. It can play one level and still be wrong somewhere else. It can match the original game for one revision and fail on another.

Correctness is not a feeling. It is a claim with boundaries.

## What is a burndown?

A **burndown** is a scorecard for accuracy work.

It lists the parts of the console or port that need to be faithful, then records the current status of each part. It is not a marketing checklist. It is a way to say what has been checked and what still needs work.

The exact format can vary, but a useful burndown answers three questions:

1. What part of the machine are we talking about?
2. What reference are we comparing against?
3. How was this tested?

Without those answers, "correct" does not mean much.

## What usually gets measured?

Projects often split accuracy into areas like these:

- instruction behavior
- timing
- interrupts and events
- memory and hardware registers
- video, audio, and input
- agreement between compiled code and fallback paths
- determinism

Those areas make the work easier to discuss. They do not mean every console can be compared with one simple number.

Timing on SNES is not the same problem as timing on PlayStation. Audio on one console may be a whole separate processor. A handheld may have hardware quirks a home console never had.

The labels help organize the work. The details are still console-specific.

## When should something count as done?

An item should only count as done when it has evidence.

At minimum, that means:

- it was compared against a trustworthy reference
- it was tested in a way that can be repeated
- the scope is clear

"Looks good" is useful as a first impression. It is not enough for a correctness claim.

For mature projects, the stronger version is [co-simulation](https://retroportingtoolkit.com/docs/concepts/co-simulation.md): run the port beside a trusted reference and stop at the first difference.

## Why does scope matter?

Scope is the difference between an honest claim and an accidental overclaim.

"This game boots" is a claim.

"This game reaches the attract loop with no known differences under this test" is a stronger and clearer claim.

"This console is accurate" is usually too broad unless the project has a lot of evidence behind it.

Good docs should name the game, revision, test path, reference, and known gaps when the claim depends on them.

## How should users read maturity?

Treat maturity as practical confidence, not a universal guarantee.

psxrecomp is the gold-standard framework in this ecosystem today. SNES is the next strongest reference point. Other projects are useful, but many are still early, experimental, or focused on a smaller problem.

That is not an insult to those projects. It is just the state of the work.

A mature framework usually has better discovery, stronger runtime behavior, clearer tests, and fewer surprises when a new game is added.

## What should not be claimed?

Do not say a port is perfect because it boots.

Do not say a whole console is solved because one game looks good.

Do not say co-simulation proves real hardware behavior in every case. It proves agreement with the reference used for that test.

Do not hide scope. If a result only covers one game, one path, one region, or one build, say that.

---

# When should timing be changed?

> Timing changes are advanced work. Recomp projects try to be faithful first because relaxed timing can create softlocks, races, and bugs that only appear later.

- Canonical URL: https://retroportingtoolkit.com/docs/concepts/timing-models
- Markdown: https://retroportingtoolkit.com/docs/concepts/timing-models.md
- Section: Concepts
- Page type: concept
- Tags: Timing, Accuracy, Correctness
- Last updated: 2026-08-31
- Source repositories:
  - https://github.com/mstan/smsggrecomp
  - https://github.com/mstan/snesrecomp
  - https://github.com/mstan/gbarecomp

---

Most users should not think about timing at all.

The recomp projects try to model console timing faithfully. That is deliberate. Faithful timing avoids race conditions, softlocks, missed interrupts, broken audio, and bugs that only show up much later.

This page is for developers who are tempted to change that.

## Why be strict?

Old games were written for one machine.

They may wait for an interrupt. They may expect a hardware flag to change after a certain number of cycles. They may depend on the CPU, video hardware, audio hardware, and storage all moving in the right order.

If the port runs one part too early or too late, the game may still look fine for a while. Then it can hang, desync, skip an event, or corrupt state.

Faithful timing is rigid, sometimes to a fault, but that rigidity is useful. It makes the port less likely to depend on accidental host behavior.

## Why would anyone loosen timing?

Performance.

On a specific game, a developer may find that some timing detail is not observable, or that a cheaper model works for the paths that game uses.

That can be a valid optimization. It can also be a trap.

If the project relaxes timing because one game still passes, a later game may depend on the detail that was removed. The framework then inherits a hidden one-game assumption.

## What can go wrong?

Timing mistakes often look like unrelated bugs.

- a menu softlocks
- a cutscene never advances
- audio drifts
- input is missed
- a race condition appears only on some machines
- replay checks desync

The visible problem is usually not where the mistake started.

## What is the safe rule?

Treat the default timings as the authentic path, not the fastest path.

If you are tuning one game, you may be able to relax some values and make that game run better. That can be a valid optimization, but test it like a risky change.

Look for softlocks, missed events, broken audio, bad input timing, desyncs, and bugs that appear later than the change itself.

Keep the result specific to your game. A timing tweak that works for one game, one revision, and one test path cannot be assumed to transfer safely to other games.

## What should readers take away?

Timing is advanced port-maintenance work, not beginner setup.

For normal users, faithful timing is part of why a recomp port can feel solid. For developers, changing timing is possible, but it needs measurement because the failure mode is often a softlock or desync much later.

---

# Why does determinism matter?

> Save states, rewind, and recordings only work when the port can repeat the same game state exactly.

- Canonical URL: https://retroportingtoolkit.com/docs/concepts/determinism
- Markdown: https://retroportingtoolkit.com/docs/concepts/determinism.md
- Section: Concepts
- Page type: concept
- Tags: Correctness, Save states
- Last updated: 2026-08-31
- Source repositories:
  - https://github.com/mstan/psxrecomp
  - https://github.com/mstan/nesrecomp
  - https://github.com/mstan/DKC2Recomp
  - https://github.com/TechnicallyComputers/retcomm-rbengine
  - https://github.com/mstan/MegaManXSNESRecomp

---

Determinism means the same starting state and the same inputs produce the same result.

That sounds simple. It is not.

A recomp port is native code running on a modern computer, but the game still expects the old console's behavior. If two runs drift apart, features like save states, rewind, and input recordings become unreliable.

## Why do save states need it?

A save state captures the machine and restores it later.

For that to work, the snapshot has to include everything that can affect the game: memory, CPU state, video state, sound state, timers, device state, and any other mutable console behavior.

If the snapshot misses something, the restored game may look fine for a moment and then drift. That kind of bug is hard to see because the failure happens after the real mistake.

## Why does rewind need it?

Rewind is save states taken over and over.

The runtime keeps recent snapshots in a ring. When the player rewinds, the port loads older states and walks backward through recent gameplay.

That only feels clean when restore is complete. If audio, graphics, timers, or controller state are not restored correctly, rewind exposes it quickly.

## What makes this harder than an emulator?

An emulator usually has one central machine model. It can stop between instructions and serialize that model.

A recomp port has generated native code, runtime device models, host APIs, and sometimes multiple renderers or helper systems. The state is spread across more places.

That is manageable, but it has to be designed. Snapshot and restore are not just file save features. They are correctness features.

## What should a project guard against?

A deterministic port should avoid:

- storing host-only state in save files
- letting graphics settings change game logic
- relying on thread timing for game behavior
- accepting save states from incompatible builds
- treating "it loaded" as proof that a state restored correctly

The strict version is simple: restore the state, run again, and prove the game lands in the same place.

## What should users take away?

Save states and rewind are not just nice extras. They require the port to understand the full machine well enough to put it back exactly.

When a project supports those features well, it is usually a sign that the runtime is becoming more mature.

---

# What is the game file contract?

> Recomp projects provide the port, tools, and runtime. You provide legally obtained game files, and sometimes BIOS or system files, when the project asks for them.

- Canonical URL: https://retroportingtoolkit.com/docs/concepts/the-game-file-you-supply
- Markdown: https://retroportingtoolkit.com/docs/concepts/the-game-file-you-supply.md
- Section: Concepts
- Page type: concept
- Tags: Game files, Verification, Licensing
- Last updated: 2026-08-30

---

A recomp port usually needs a file from the original game.

That might be a cartridge dump, a disc image, or another format the project expects. Some systems may also need a BIOS or system file.

This site and these projects provide the port, the tools, and the runtime. They do not provide copyrighted game files or copyrighted retail BIOS files.

Use legally obtained files.

## Why does the exact file matter?

A port is built around exact bytes.

Region, revision, patches, bad dumps, trimmed files, and converted disc images can all change those bytes. A file that looks close to you may be a different input to the port.

That is why many ports check the file before they run. If the hash or layout does not match, the port should stop instead of guessing.

Strict checks are not there to annoy you. They keep the port tied to the game version it was built and tested against.

## What about BIOS files?

Some systems need BIOS or firmware behavior.

There are two common cases:

- The project can use a legal open-source BIOS alternative.
- The project needs a legally obtained retail BIOS or system file.

This site does not provide copyrighted retail BIOS files. If a project needs one, follow the project's instructions and use a legally obtained copy.

If a project includes an open-source BIOS alternative, it should say so clearly.

## What should never be committed?

Do not commit:

- game dumps
- disc images
- copyrighted retail BIOS files
- generated code derived from those files
- caches that contain captured game code

Keep those files local. Follow the project's ignore rules.

## Why not just support every dump?

Supporting many revisions is possible, but it is work.

Each revision may move code, change data, patch bugs, or alter timing. A port that supports one version does not automatically support another.

The honest path is to support known inputs, verify them, and add more versions deliberately.

## What should users do when verification fails?

Stop and check the basics:

- Is this the right region?
- Is this the right revision?
- Is the dump clean?
- Is the disc image still in the expected format?
- Does the project also need a BIOS or system file?

Do not look for random downloads. The intended path is to use legally obtained files and follow the project instructions.

---

# Recompile the original game, then let mods do the rest

> Recompile a clean, verified game file. Treat ROM hacks and other patches as references for optional mods, not as new base games.

- Canonical URL: https://retroportingtoolkit.com/docs/concepts/start-with-the-original-game
- Markdown: https://retroportingtoolkit.com/docs/concepts/start-with-the-original-game.md
- Section: Concepts
- Page type: concept
- Tags: Game files, Modding, ROM hacks, Verification
- Last updated: 2026-09-01

---

A recomp project should begin with an unmodified file from the original release.

Do not apply a bug fix, quality-of-life patch, translation, or other ROM hack and then recompile the result. Recompile the original game. Build the changes as mods that the port applies separately.

This keeps one verified game at the center of the project. It also gives players a faithful port when every mod is off.

## Why does the original file matter?

A recompiler works from exact bytes. Applying a patch changes those bytes.

If a project recompiles the patched file, the patch becomes part of its generated code. The project now targets a different binary, even when the patch changes only one bug or one line of text.

That creates avoidable problems:

- the port no longer has the original release as its clear baseline;
- players may need to prepare a special patched file;
- fixes and enhancements are harder to turn off or test separately;
- comparing the port with the original game becomes less direct;
- two useful patches can become two separate recomp projects instead of two compatible mods.

Start with a clean, legally obtained dump. Record its region, revision, format, and hashes. Keep it unchanged throughout the build. The [game file contract](https://retroportingtoolkit.com/docs/concepts/the-game-file-you-supply.md) explains why the exact file matters.

## Use patches as references

A ROM hack can still be valuable engineering work. Use it to learn what a mod needs to change.

Study the patch, its documentation, and the difference it produces. Find the affected code, data, text, or assets. Then express that change through the port's [mod system](https://retroportingtoolkit.com/docs/guides/write-a-mod.md).

Depending on the change, that might become:

- a guarded memory patch;
- a translation table;
- an asset overlay;
- a runtime option;
- a reviewed plugin compiled into the port.

Keep any temporary patched comparison outside the port's build and distribution flow. Do not replace the verified base file with it, and do not ask players to modify their game file.

The patch is a reference for the implementation. It is not the input to the recompiler.

## What belongs in the mod layer?

Bug fixes, quality-of-life changes, and translations belong in the mod ecosystem.

Keep each change separate when practical. Give it a clear name, target the exact supported game revision, and check the original bytes before applying it. The stock setting should make no change.

This structure makes testing easier. A developer can compare the faithful port with the original game, enable one mod, and see exactly what changed. Players can also combine compatible features without preparing a different ROM or disc image for each combination.

## What about a full custom game?

A full custom game is the narrow exception.

A project such as *The Legend of Zelda: The Sealed Palace* changes enough of the original game to become its own deliberate target. Recompiling that target can make sense when the project is truly a port of the custom game, not a shortcut for adding a few fixes or enhancements.

Treat that choice explicitly. Identify the exact custom-game file, explain its provenance and patching requirements, and keep it separate from the faithful port of the original release.

If the change could reasonably be a mod, make it a mod. Recompile the original game and let the mod layer carry the rest.

---

# What do these terms mean?

> Short definitions for common recomp words, written for readers who are still getting comfortable with the technical side.

- Canonical URL: https://retroportingtoolkit.com/docs/concepts/glossary
- Markdown: https://retroportingtoolkit.com/docs/concepts/glossary.md
- Section: Concepts
- Page type: reference
- Tags: Glossary, Vocabulary, Reference
- Last updated: 2026-08-31
- Source repositories:
  - https://github.com/mstan/psxrecomp
  - https://github.com/mstan/nesrecomp
  - https://github.com/mstan/snesrecomp
  - https://github.com/mstan/gbarecomp
  - https://github.com/mstan/segagenesisrecomp
  - https://github.com/mstan/smsggrecomp
  - https://github.com/mstan/ndsrecomp
  - https://github.com/mstan/cdirecomp

---

These are the words this site uses often.

Some terms are general. Some belong mostly to one console or one project. When that matters, the definition says so.

## A

### AOT

Ahead of time. Work done before the program runs. Static recompilation is usually AOT because the game code is translated before launch.

### Always-on ring

A debug buffer that records all the time. Developers read it after a bug happens. This is useful because many bugs are already gone by the time someone knows what to record.

## B

### Bank

A chunk of game data or generated output. On cartridge systems, a bank often means a piece of ROM that hardware can swap into the CPU's address space. Some projects use the word differently, so read the local context.

### Bank switching

Hardware swapping which ROM bank appears at a CPU address. This means one address can refer to different code or data at different times.

### Baserom

A user's own clean dump of a cartridge game. The project does not provide it.

### BIOS

System software from the original console. Some projects need a BIOS or firmware file. Some can use an open-source replacement. This site does not provide copyrighted retail BIOS files.

### Burndown

A checklist or scorecard for accuracy work. It records what has been checked, what reference was used, and what still needs work. See [What does correct enough mean?](https://retroportingtoolkit.com/docs/concepts/accuracy-and-burndowns.md).

## C

### Cache

Saved build or runtime output that can be reused later. In some projects, code discovered while playing can be compiled and cached so it runs faster next time.

### Code discovery

Finding which bytes in a game file are instructions and where functions begin. See [How does a project tell code from data?](https://retroportingtoolkit.com/docs/concepts/code-discovery.md).

### Co-simulation

Running the port beside a trusted reference and comparing them at the same points in game time. See [How do we compare a port to the original?](https://retroportingtoolkit.com/docs/concepts/co-simulation.md).

### Correctness

How faithfully the port behaves compared with the original game on the original machine, within a stated scope.

### Cycle

A small unit of console time. Many timing problems are really cycle problems.

### Cycle accurate

Modeled closely enough that individual cycles matter. Be careful with this phrase: some projects use it as a goal, not a finished status.

## D

### Decoder

The part of a recompiler that reads machine instructions and translates them into another form.

### Determinism

The same starting state and same inputs produce the same result. Save states, rewind, and recordings depend on it. See [Why does determinism matter?](https://retroportingtoolkit.com/docs/concepts/determinism.md).

### Disc image

A user's own dump of a disc game. On PlayStation, this is often a `.cue` file with matching `.bin` tracks.

### Dispatch

The runtime choosing which translated function should handle a guest address.

### Dispatch miss

The game jumped to an address that has no translated function ready. A mature runtime may interpret it, log it, or feed it back into discovery.

### Divergence

A difference between the port and a reference during testing. The first divergence is the one developers want to find.

## E

### Emulation

Acting like another machine in software. Static recompilation avoids interpreting the main game code when it can, but the runtime still models console hardware. See [Is this emulation?](https://retroportingtoolkit.com/docs/start/is-this-emulation.md).

## F

### Faithfulness

The port behaving like the original game. This is the real measurement, not just whether the app opens.

### Fallback interpreter

A small emulator inside the runtime. It can run code that was not translated ahead of time. It is slower than native code, but it keeps correctness first.

### Firmware

System software stored in or used by a console. Similar to BIOS in this context.

## G

### Game file

The game input the user provides, such as a cartridge dump or disc image. See [What is the game file contract?](https://retroportingtoolkit.com/docs/concepts/the-game-file-you-supply.md).

### Generated code

Code written by the recompiler. It is build output. Developers should fix the recompiler, runtime, or config instead of hand-editing generated code.

### Guest

The old console or game being recreated. For example, a PlayStation game is guest code running inside a native port.

## H

### HLE

High level emulation. Replacing a piece of console behavior with native code that does the same job at a higher level. HLE is useful, but HLE-first can become a trap. See [What are HLE and LLE?](https://retroportingtoolkit.com/docs/concepts/hle-and-lle.md).

### Host

The modern machine running the port.

## I

### Interpreter

Software that reads guest instructions and acts them out one at a time.

### Interrupt

A hardware event that makes the CPU stop what it is doing and run special code. Timing-sensitive games often care exactly when interrupts happen.

## L

### LLE

Low level emulation. Following the original machine closely, often by running or recompiling its own code. In these projects, faithful LLE is the floor that HLE is checked against.

## M

### Mapper

Cartridge hardware that changes which ROM data appears at which CPU addresses. This term is especially common for NES.

### Mod manifest

A file that describes a mod package, its version, its features, and the game version it targets.

## N

### Native

Running as compiled code for the host machine instead of being interpreted one instruction at a time. Native says what runs. Static says when the translation happened.

## O

### Oracle

A trusted reference used for comparison, usually a mature emulator. Co-simulation uses an oracle to decide whether the port still matches.

### Overlay

Code loaded into memory while the game runs, often replacing earlier code at the same address. This is especially important for PlayStation. See [What about code you cannot see ahead of time?](https://retroportingtoolkit.com/docs/concepts/code-you-cannot-see-ahead-of-time.md).

## P

### Probe

A read-only debugging query or tool. A probe observes behavior; it is not necessarily a playable port.

### Provenance

Where something came from. In this ecosystem it can mean how code was discovered, where a hardware behavior was learned, or which files are safe to redistribute.

## R

### Recompiler

The build-time tool that reads a game's machine code and writes source code from it. See [What are the recompiler and runtime?](https://retroportingtoolkit.com/docs/concepts/recompiler-and-runtime.md).

### Runtime

The native code that surrounds the translated game and provides console services: memory, graphics, audio, input, saves, timing, and more.

### Runtime recompilation

Translating code while the game is running because the code was not available earlier. This is different from pure AOT static recompilation, but the result can still be native code.

## S

### Save state

A snapshot of the machine that can be restored later.

### Static recompilation

Translating game code before the game runs, then compiling the result into a native program. See [What is static recompilation?](https://retroportingtoolkit.com/docs/start/what-is-static-recompilation.md).

### Stub

Made-up behavior standing in for real console or game behavior. Stubs may help during experiments, but they should not become hidden correctness claims.

> **Warning.** Stubs rot quickly, especially when AI is involved. A stub can make
> a milestone look complete while hiding the real missing behavior. The safer
> rule is no stubs, ever: stop, find the real behavior, and make the faithful
> path work.

## T

### Timing model

How the port tracks the original console's time. See [When should timing be changed?](https://retroportingtoolkit.com/docs/concepts/timing-models.md).

### Tier

A level in a runtime's dispatch path. In psxrecomp, for example, code may run as ahead-of-time native code, runtime-compiled code, or interpreter fallback. Do not assume every console uses the same ladder.

---

# Platforms

> Where each console toolchain stands, which ones are practical today, and which ones are still research.

- Canonical URL: https://retroportingtoolkit.com/docs/platforms
- Markdown: https://retroportingtoolkit.com/docs/platforms.md
- Section: Platforms
- Page type: reference
- Tags: Platforms
- Last updated: 2026-08-30

---

These pages explain the console toolchains.

They are not all at the same maturity level. Some are practical starting points. Some are useful examples. Some are research projects that teach us about the next version of the tooling.

If you are trying your first port, start with the strongest path.

## The strongest paths

- [PlayStation](https://retroportingtoolkit.com/docs/platforms/playstation.md). The gold-standard framework today. It has the clearest end-to-end path, a strong runtime, and the best example of how this ecosystem should feel.
- [SNES](https://retroportingtoolkit.com/docs/platforms/snes.md). The silver-standard framework. It has strong results and very useful lessons, especially around assembly-heavy games and community disassemblies.

## Useful but earlier

- [NES](https://retroportingtoolkit.com/docs/platforms/nes.md). A compact cartridge system where code discovery and mapper handling are the main lessons.
- [Game Boy Advance](https://retroportingtoolkit.com/docs/platforms/game-boy-advance.md). Experimental. Able to run games with enhancements, but still needs refinement.
- [Sega Genesis](https://retroportingtoolkit.com/docs/platforms/sega-genesis.md). Experimental two-CPU target. Useful for native 68000 work plus Z80 sound work.
- [Master System and Game Gear](https://retroportingtoolkit.com/docs/platforms/master-system-game-gear.md). Experimental Z80 target. Useful for timing work, but not the first place to start.
- [Nintendo DS](https://retroportingtoolkit.com/docs/platforms/nintendo-ds.md). Early and experimental. Able to run commercial titles, but still needs optimization and refinement.

## Research

- [CD-i](https://retroportingtoolkit.com/docs/platforms/cd-i.md). Research path around full system ROM behavior, not a normal game-port route.
- [Virtual Boy](https://retroportingtoolkit.com/docs/platforms/virtual-boy.md). Focused experimental target for one narrow runtime.

## How should I read these pages?

Read each page as a maturity snapshot, not a guarantee.

A console page can tell you what the framework is trying to do, what makes that console hard, and what kind of files a project may ask for. It cannot promise that every game on that console is ready.

For the general workflow, start with [How do I recomp my own game?](https://retroportingtoolkit.com/docs/start/recomp-your-own-game.md). For exact status words, use [Status vocabulary](https://retroportingtoolkit.com/docs/reference/status-vocabulary.md).

---

# PlayStation

> psxrecomp is the gold-standard framework today: it translates PS1 game code and BIOS code, handles streamed overlays, and keeps a faithful low-level path underneath convenience features.

- Canonical URL: https://retroportingtoolkit.com/docs/platforms/playstation
- Markdown: https://retroportingtoolkit.com/docs/platforms/playstation.md
- Section: Platforms
- Page type: project
- Tags: PlayStation, MIPS R3000A, GTE, Overlays
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/psxrecomp

---

PlayStation is the strongest recomp path in this ecosystem today.

[psxrecomp](https://github.com/mstan/psxrecomp) translates PlayStation game code into C, compiles that C into native code, and links it against a runtime that models the console around the game.

It also handles the part that makes PlayStation difficult: games often stream new code from the disc while they run. psxrecomp can capture that code, compile it, cache it, and use it later.

That combination is why this site uses psxrecomp as the gold-standard reference.

## What does it translate?

PlayStation games run on a MIPS R3000A CPU.

psxrecomp translates that MIPS machine code. It can also translate a PlayStation BIOS image. The generated code is then built as native code for the host machine.

The runtime provides the rest of the console: memory, disc behavior, graphics, audio, input, timing, saves, and fallback execution.

This is the split used across the ecosystem: [recompiler plus runtime](https://retroportingtoolkit.com/docs/concepts/recompiler-and-runtime.md).

## What files does it need?

For a game project, you provide your own legally obtained PlayStation disc image.

Some paths also use a BIOS. psxrecomp can use OpenBIOS, a legal open-source BIOS alternative, for some framework work. A retail BIOS path requires a legally obtained BIOS.

This site does not provide game files or copyrighted retail BIOS files.

## Why is PlayStation harder than a simple cartridge?

A PlayStation game is usually much larger than the console's RAM.

The game loads one chunk of code, runs it, then loads another chunk over the same area later. Those chunks are called overlays.

A pure build-time pass cannot see every overlay before the game runs. psxrecomp handles that with fallback interpretation, capture, compilation, and caching.

The safe rule is content matching: compiled overlay code only runs when the live bytes in memory still match the bytes it was compiled from.

See [What about code you cannot see ahead of time?](https://retroportingtoolkit.com/docs/concepts/code-you-cannot-see-ahead-of-time.md).

## What are the execution tiers?

psxrecomp has a practical ladder:

1. Native code translated ahead of time.
2. Native overlay code compiled after the game loads it.
3. Interpreter fallback for code that has not been translated yet.

The important point is that lower tiers are slower, not less faithful. A missed path should become a performance problem and a discovery task, not fake behavior.

## What about HLE?

psxrecomp keeps the low-level BIOS path as the reference.

Higher-level helpers can make setup easier or skip some slow startup behavior, but they sit above the faithful path. They do not replace the need for a correctness floor.

That is the pattern described in [What are HLE and LLE?](https://retroportingtoolkit.com/docs/concepts/hle-and-lle.md).

## What makes PlayStation a good first target?

The framework is the most mature one here.

It has a clearer build path, a stronger runtime, a useful overlay story, and a better model for how new game projects should grow. It is still not magic. A generated project is a starting point, not a promise that the game is done.

For a first serious attempt, PlayStation is the best place to learn the full shape of the work.

## What are the main limits?

- Not every game is fully native all the time.
- Overlay coverage improves as more code paths are found and captured.
- A generated game project still needs game-specific work.
- HLE paths should be checked against the faithful low-level path.
- Faithfulness is measured by behavior, not just by whether the game boots.

---

# NES

> nesrecomp is a compact cartridge example: it translates 6502 code, links a runner for NES hardware, and teaches why mappers matter.

- Canonical URL: https://retroportingtoolkit.com/docs/platforms/nes
- Markdown: https://retroportingtoolkit.com/docs/platforms/nes.md
- Section: Platforms
- Page type: project
- Tags: NES, 6502, Mappers
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/nesrecomp

---

NES is a useful early toolchain to understand because the machine is small and the problems are easy to see.

[nesrecomp](https://github.com/mstan/nesrecomp) reads the 6502 machine code in a NES cartridge dump and turns it into C. That C is compiled into native code and linked against a runner that models the NES hardware.

It is not the most mature path in the ecosystem, but it is a good example of how cartridge recompilation works.

## What does it translate?

The NES CPU is based on the 6502.

nesrecomp translates the game's CPU instructions. The runner handles the rest of the console: graphics, audio, controllers, cartridge hardware, memory, and timing.

That means the game logic can run as native code, while the runtime still acts like the NES around it.

## What files does it need?

For a game project, you provide your own legally obtained `.nes` cartridge dump.

NES does not need a BIOS file.

The exact dump matters. Region, revision, bad dumps, patches, or header differences can change what the project sees.

This site does not provide game files.

## What makes NES specific?

The main NES-specific problem is the cartridge.

Many NES cartridges contain a **mapper**. A mapper is hardware inside the cartridge that swaps which part of the ROM appears at a CPU address.

That means an address alone may not identify one piece of code. The same CPU address can refer to different banks at different times.

For a static recompiler, this matters a lot. The project has to know which bank was active when the game jumped to an address.

See [How does a project tell code from data?](https://retroportingtoolkit.com/docs/concepts/code-discovery.md).

## Is generating code enough?

No.

The framework can build a static library, but a playable port still needs game-specific configuration and runner integration.

That configuration teaches the tool about the game's banks, function starts, data regions, and indirect jumps that cannot be guessed safely.

This is a common pattern across the ecosystem: the shared framework gets better over time, but each game still needs real port work.

## What happens if discovery misses code?

A missed address should not become a fake stub.

The project can log the miss, fall back to an interpreter when available, and feed the result back into the next build. The goal is to improve discovery until the game has the native coverage it needs.

Booting is only a milestone. Faithfulness still needs testing.

## What are the main limits?

- A generated library is not a full playable port by itself.
- Mapper support is central, and not every mapper or game pattern is equally mature.
- Some discovery still needs per-game configuration.
- Correctness depends on testing, not just a successful build.

---

# SNES

> snesrecomp is the silver-standard framework today: strong results, hard CPU details, and good use of community disassembly work.

- Canonical URL: https://retroportingtoolkit.com/docs/platforms/snes
- Markdown: https://retroportingtoolkit.com/docs/platforms/snes.md
- Section: Platforms
- Page type: project
- Tags: SNES, 65816, Static recompilation, Timing
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/snesrecomp
  - https://github.com/mstan/SuperMarioWorldRecomp
  - https://github.com/mstan/MegaManXSNESRecomp

---

SNES is the next strongest recomp path after PlayStation.

[snesrecomp](https://github.com/mstan/snesrecomp) translates Super Nintendo game code into C and links it against a runtime that models the rest of the console.

The results can be excellent, especially when a game has strong public disassembly work to help guide discovery. Super Mario World is a good example of that pattern.

## What does it translate?

SNES games run on a Ricoh 5A22 CPU, based on the 65816.

snesrecomp translates the main CPU code. The runtime handles the rest of the machine: graphics, audio, DMA, cartridge mapping, timing, and enhancement chips where supported.

The audio side is not just a sound register. The SNES has separate audio hardware with its own processor and memory, so the runtime has real console work to do.

## What files does it need?

For a game project, you provide your own legally obtained `.sfc` or `.smc` cartridge dump.

SNES does not need a separate retail BIOS file.

Some SNES games use enhancement chips, such as SuperFX, DSP-1, or Cx4. snesrecomp supports these today. They were brought up with real ROM dumps and checked against the faithful low-level path.

Because those chip ROMs are small and awkward for users to obtain, snesrecomp can ship higher-level layers for them. That is a setup choice, not a compromise in the correctness floor.

The exact dump still matters. Region, revision, copier headers, patches, and bad dumps can all change what the project sees.

This site does not provide game files.

## What makes SNES hard?

The 65816 can change how wide some instructions are while the game runs.

Two status flags, usually called M and X, decide whether certain registers and immediate values are 8-bit or 16-bit. That means the same bytes can decode differently depending on CPU state.

For a static recompiler, that is a serious problem. The tool cannot only ask "what address is this?" It also has to ask "what CPU mode reached this address?"

If it guesses wrong, it can read the next instruction from the wrong byte.

## Why do disassemblies help here?

Many SNES games were written heavily in assembly.

A good community disassembly can identify functions, labels, data tables, hardware writes, and banks. That gives the project a map while still building the port from the user's own game file.

This is one reason SNES can be strong when the right game and the right existing knowledge line up.

## What is the faithful floor?

snesrecomp keeps an interpreter as the correctness floor.

That matters because the compiled path may not cover every mode or edge case yet. If the exact generated variant is not available, the runtime can fall back to the faithful path instead of guessing.

That is the same philosophy described in [What are HLE and LLE?](https://retroportingtoolkit.com/docs/concepts/hle-and-lle.md): do not fake the behavior just to make one path look complete.

## What are the main limits?

- The CPU mode problem makes discovery and code generation harder than on simpler 6502 targets.
- Enhancement chips vary by game and are not all equal.
- Timing and interrupt behavior are advanced areas that need careful testing.
- Some game support depends on strong per-game knowledge.

---

# Game Boy Advance

> gbarecomp targets ARM7TDMI games, where the hard part is one CPU switching between ARM and Thumb code while the port runs.

- Canonical URL: https://retroportingtoolkit.com/docs/platforms/game-boy-advance
- Markdown: https://retroportingtoolkit.com/docs/platforms/game-boy-advance.md
- Section: Platforms
- Page type: project
- Tags: Game Boy Advance, ARM7TDMI, Interworking, Recompiler
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/gbarecomp
  - https://github.com/mstan/MinishCapRecomp
  - https://github.com/Shy/BoktaiRecomp

---

Game Boy Advance is experimental.

[gbarecomp](https://github.com/mstan/gbarecomp) translates GBA game code into C++ and links it against a runtime that models the handheld hardware.

The framework is general-purpose in direction. It can run games and support enhancements, but it still needs refinement before it is a broad first-choice path.

## What does it translate?

The GBA uses an ARM7TDMI CPU.

That CPU can run two instruction sets:

- **ARM**, with 32-bit instructions
- **Thumb**, with 16-bit instructions

The game can switch between them while it runs.

gbarecomp translates both modes and keeps track of which mode each function belongs to.

## What files does it need?

For a playable game project, you usually provide two legally obtained files:

- the GBA game dump
- a GBA BIOS file, if the project requires it

Some framework work may use generated or open alternatives where appropriate, but retail BIOS files are not provided here.

This site does not provide game files or copyrighted retail BIOS files.

## What makes GBA hard?

The hard part is **interworking**.

ARM and Thumb share the same address space. An address alone may not be enough to say what code is there. The project also needs to know which instruction set is active.

That matters for function discovery, jump tables, branches, interrupts, and any code that switches modes.

If the mode is wrong, the recompiler reads the bytes with the wrong instruction width.

## What else does the runtime handle?

The runtime models the rest of the GBA around the translated CPU code.

That includes graphics, audio, DMA, timers, interrupts, save hardware, cartridge behavior, and special devices used by some games.

Some GBA projects also explore adaptive widescreen and other enhancements. Those features should stay opt-in and should not change the faithful default view.

## What happens if discovery misses code?

A missed function should become a visible development problem, not hidden fake behavior.

The project can use fallback execution, logs, or a cache path to keep the game moving while pointing developers at the missing coverage.

As with the other frameworks, the goal is to improve the tool and the game configuration, not patch around missing behavior with stubs.

## What are the main limits?

- The framework is still earlier than PlayStation and SNES.
- Interworking makes discovery and dispatch more complex.
- A playable project may require a legally obtained BIOS.
- Enhancements need game-specific validation.
- Generated code is a starting point, not a finished port.

---

# Sega Genesis

> segagenesisrecomp is an experimental two-CPU target: the main 68000 is translated, while the Z80 sound side has to stay tightly scheduled around it.

- Canonical URL: https://retroportingtoolkit.com/docs/platforms/sega-genesis
- Markdown: https://retroportingtoolkit.com/docs/platforms/sega-genesis.md
- Section: Platforms
- Page type: project
- Tags: Sega, 68000, Dual CPU, Audio, Widescreen
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/segagenesisrecomp
  - https://github.com/mstan/smsggrecomp

---

Sega Genesis is an experimental recomp path.

[segagenesisrecomp](https://github.com/mstan/segagenesisrecomp) translates Genesis game code into C and links it against a runtime that models the rest of the console.

The important wrinkle is that the Genesis is not only one CPU. It has a main 68000 and a Z80 sound processor that have to stay in sync.

That makes it a useful framework to study, but not the easiest first target.

## What does it translate?

Genesis game logic mainly runs on a Motorola 68000.

segagenesisrecomp translates that 68000 code ahead of time. The generated C is then compiled into native code for the host machine.

The runtime handles video, audio, input, memory, cartridge behavior, timing, and the Z80 side of the machine.

The Z80 is special. On Genesis, it is usually a sound coprocessor. That means the runtime has to interleave two processors instead of letting one translated program run freely.

## What files does it need?

For a game project, you provide your own legally obtained Genesis or Mega Drive cartridge dump.

Genesis does not need a BIOS file for the normal cartridge path.

The exact dump still matters. Region, revision, bad dumps, patches, and header differences can change what the project sees.

This site does not provide game files.

## What makes Genesis hard?

The hard part is the two-CPU shape.

The 68000 drives the game and talks to video hardware. The Z80 often runs the sound driver. Both touch shared hardware, and the timing between them matters.

If the 68000 runs too far ahead, audio or hardware state can drift. If the Z80 is modeled too loosely, a game can sound right in one scene and break in another.

The safe approach is to keep the runtime faithful first, then optimize after the behavior is understood.

## What about the Z80?

The Z80 work is shared with [Master System and Game Gear](https://retroportingtoolkit.com/docs/platforms/master-system-game-gear.md).

That matters because the same CPU has two different jobs:

- on Master System and Game Gear, the Z80 is the whole console CPU;
- on Genesis, the Z80 is a coprocessor beside the 68000.

The second job is harder to schedule. The host needs control back often enough to keep the two CPUs and the video/audio hardware aligned.

## What about widescreen?

Genesis widescreen work is usually game-specific.

Many 2D games do not draw a whole world and then crop it. They draw only what the original screen needs. Widening the view can expose empty tilemap space, stale background data, wrapped sprites, or game logic that expected the old camera width.

That does not make widescreen impossible. It means the port has to change the right game-specific draw and camera rules, and leave the original 4:3 behavior as the faithful default.

## What are the main limits?

- The framework is still experimental.
- Two-CPU timing is the central risk.
- Z80 behavior is shared with another framework but used differently here.
- Widescreen is per game, not a universal switch.
- A successful build is only the start of bring-up.

---

# Master System and Game Gear

> smsggrecomp is an experimental Z80 framework for Sega's 8-bit machines, and its flat-step mode also helps the Genesis sound CPU path.

- Canonical URL: https://retroportingtoolkit.com/docs/platforms/master-system-game-gear
- Markdown: https://retroportingtoolkit.com/docs/platforms/master-system-game-gear.md
- Section: Platforms
- Page type: project
- Tags: Sega, Z80, Flat step, Accuracy
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/smsggrecomp
  - https://github.com/mstan/segagenesisrecomp

---

Master System and Game Gear share a useful recomp path.

[smsggrecomp](https://github.com/mstan/smsggrecomp) translates Z80 game code into C and links it against a runtime for Sega's 8-bit hardware.

This ecosystem is extremely early. Treat it as a tech demo, not a ready platform.

Today it barely proves the shape with one Master System game path and one Game Gear game path. Those paths do not imply full-game, end-to-end validation, and they do not claim enhancements.

Even so, it is a good place to understand small-console recompilation: one main CPU, cartridge banking, video timing, audio, and input.

It also matters to Genesis work because Genesis uses a Z80 as its sound processor.

## What does it translate?

Master System and Game Gear games run on a Z80 CPU.

smsggrecomp translates that Z80 code ahead of time. The generated C is built as native code.

The runtime handles the rest of the machine: graphics, audio, input, cartridge mapping, interrupts, memory, and timing.

Game Gear is close to Master System, but not identical. It has a smaller visible screen, more color, and stereo audio support.

## What files does it need?

For a game project, you provide your own legally obtained cartridge dump.

Master System and Game Gear do not need a BIOS file for the normal cartridge path.

The exact dump matters. Region, revision, mapper behavior, and bad dumps can change what the project sees.

This site does not provide game files.

## What makes these systems hard?

The main issue is cartridge mapping.

Small consoles often have more game data than the CPU can see at once. A mapper swaps different ROM banks into the same CPU address range.

That means an address is not always enough. The project may also need to know which bank was active when the game reached that address.

Timing also matters. Video interrupts and audio writes happen while the CPU is running, so the runtime cannot treat time as a loose suggestion.

## What is flat step?

Flat step is a special output mode.

Normal generated code tries to run a whole function efficiently. Flat step runs one guest instruction, then returns control to the host.

That is slower, but it is useful when another machine is in charge of scheduling. Genesis needs that shape for its Z80 sound processor, because the 68000 and Z80 have to be interleaved.

This is a good example of a feature that is not only about one console. A useful framework piece can become part of another framework's runtime.

## What are the main limits?

- The framework is still extremely early.
- Treat the current game paths as tech demos.
- Whole-game validation is not guaranteed.
- Enhancements are not the point of this path yet.
- Mapper behavior and timing need game-by-game testing.
- Some debug surfaces are still developer tools, not polished user features.
- Genesis uses the Z80 work differently than Master System and Game Gear do.

---

# Nintendo DS

> ndsrecomp is an alpha-stage framework: Prime Hunters is the public example, and the toolchain can run several title paths while optimization work continues.

- Canonical URL: https://retroportingtoolkit.com/docs/platforms/nintendo-ds
- Markdown: https://retroportingtoolkit.com/docs/platforms/nintendo-ds.md
- Section: Platforms
- Page type: project
- Tags: Nintendo DS, ARM, Dual CPU, HLE
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/ndsrecomp
  - https://github.com/mstan/MetroidPrimeHuntersRecomp

---

Nintendo DS is an alpha-stage recomp path.

[ndsrecomp](https://github.com/mstan/ndsrecomp) translates Nintendo DS ARM code into C and links it against a runtime that models the handheld around it.

Publicly, the main example is Metroid Prime Hunters. The framework can run a few title paths, but it is still working through optimization and refinement.

It is not a broad beginner path yet. The system is complicated, and alpha means the basics are real while the rough edges are still expected.

Use this page as a maturity snapshot, not a compatibility promise.

## What does it translate?

The Nintendo DS has two ARM processors:

- ARM9, the main CPU;
- ARM7, the support CPU for audio, input, firmware services, and other hardware work.

ndsrecomp translates code for both processors.

The runtime then has to schedule both CPUs together and model the rest of the machine: memory, DMA, graphics, audio, input, touch, cartridge behavior, BIOS behavior, firmware behavior, and timing.

## What files does it need?

For a game project, you provide your own legally obtained cartridge dump.

Some DS paths also need BIOS or firmware files. Use legally obtained files. This site does not provide them.

Some framework work may use open-source BIOS alternatives where appropriate, but those alternatives are not the same thing as pretending the retail files do not matter. The faithful path still needs a real reference.

This site does not provide game files or copyrighted retail BIOS files.

## What makes DS hard?

The hard part is the whole-machine shape.

The two CPUs communicate with each other. They share memory in specific ways. They wait on hardware events, interrupts, DMA, timers, touch input, cartridge reads, and video timing.

If one CPU runs too far ahead of the other, the game can behave differently even when both translated instruction streams are individually correct.

That makes DS a scheduling and hardware-model problem, not just a CPU translation problem.

## What are the main limits?

- The framework is alpha-stage.
- Performance and optimization are still active problems.
- Two-CPU scheduling has to be handled carefully.
- BIOS and firmware behavior matter.
- A working title path does not mean broad compatibility.

---

# Virtual Boy

> vbrecomp is a focused tech demo today: one Mario Tennis path, no enhancement claim, and no broad platform guarantee.

- Canonical URL: https://retroportingtoolkit.com/docs/platforms/virtual-boy
- Markdown: https://retroportingtoolkit.com/docs/platforms/virtual-boy.md
- Section: Platforms
- Page type: project
- Tags: Virtual Boy, V810, Stereoscopy, Oracle
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/vbrecomp
  - https://github.com/mstan/MarioTennisVirtualBoyRecomp

---

Virtual Boy is a tech demo today.

[vbrecomp](https://github.com/mstan/vbrecomp) translates Virtual Boy game code into C and links it against a runtime for the rest of the machine.

The public proof point is Mario Tennis. That is useful, but narrow. It does not mean the framework is ready for the full library.

There is no enhancement claim here. Treat it as one working path that proves the toolchain shape.

## What does it translate?

Virtual Boy games run on a NEC V810 CPU.

vbrecomp translates that V810 machine code ahead of time. The generated C is compiled into native code.

The runtime handles memory, cartridge behavior, input, timing, and the display hardware.

## What files does it need?

For a game project, you provide your own legally obtained Virtual Boy cartridge dump.

Virtual Boy does not need a BIOS file.

The exact dump matters. A project may check the file identity before running so it does not build or launch against the wrong bytes.

This site does not provide game files.

## What makes Virtual Boy specific?

The CPU is only part of the job.

The runtime also has to model the display, input, memory behavior, timing, and the way the game expects the hardware to behave.

The display is unusual because the hardware renders separate left-eye and right-eye images. That matters for faithfulness, even if the current port does not turn it into a polished modern stereo experience.

## What is proven today?

Mario Tennis is the proof point.

That means the framework can translate and run a real game path. It does not prove broad compatibility. It does not prove every mode, every timing edge, or every game-specific hardware pattern.

Read it as a useful technical milestone, not a platform promise.

## What are the main limits?

- This is a tech demo.
- The public path is Mario Tennis.
- No enhancement path is claimed.
- Broad game support is not guaranteed.
- A second game may expose missing runtime or discovery work.

---

# CD-i

> cdirecomp is a BIOS-focused research demo today: no commercial-game support claim, and only a rough Hotel Mario intro path has been shown.

- Canonical URL: https://retroportingtoolkit.com/docs/platforms/cd-i
- Markdown: https://retroportingtoolkit.com/docs/platforms/cd-i.md
- Section: Platforms
- Page type: project
- Tags: CD-i, 68000, System ROM, Research
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/cdirecomp

---

CD-i is a BIOS-focused research demo today.

[cdirecomp](https://github.com/mstan/cdirecomp) explores recompilation for a disc-based 68000 system where the system ROM matters before normal game-port work can be trusted.

This is not a commercial-game platform yet. The current public proof is very narrow: it can barely reach the Hotel Mario intro, with visual errors. Gameplay does not work.

Treat this as machine research, not a route for starting your own playable port.

## What does it translate?

CD-i uses a 68000-family CPU.

cdirecomp translates 68000 machine code into C and links it against a runtime that models the machine around it.

The important target today is the BIOS and system path. That comes before game compatibility.

The 68000 work is related to other 68000 recomp work in the ecosystem, especially [Sega Genesis](https://retroportingtoolkit.com/docs/platforms/sega-genesis.md), but the console around the CPU is very different.

## What files does it need?

CD-i work can need both a system ROM and disc images.

Use legally obtained files. This site does not provide system ROMs, disc images, game files, or copyrighted retail BIOS files.

That requirement is part of why CD-i sits in the research group. The system path itself has to be proven before this becomes a normal game-port route.

## What makes CD-i hard?

The hard part is that the system software matters so much.

On some consoles, a game can be treated mostly as a self-contained cartridge or disc program. CD-i depends heavily on the BIOS and platform services around it.

That means shortcuts are risky. If the runtime guesses what the BIOS would have done, it might pass one screen and fail everywhere else.

The safer path is to model the low-level behavior first, then build higher-level convenience only after the faithful path can prove it.

## What is proven today?

The proof point is BIOS and early boot research.

Hotel Mario reaching an intro is a useful sign, but it is not a playable-game claim. Visual errors remain, and gameplay does not work.

Read it as a technical milestone, not a compatibility promise.

## What are the main limits?

- This is research, not a recommended first port target.
- No commercial game is supported today.
- Hotel Mario only reaches an early intro path, with visual errors.
- Gameplay does not work.
- BIOS and system behavior are still the main problem.

---

# Guides

> Practical guides for building, porting, modifying, debugging, and releasing recomp projects.

- Canonical URL: https://retroportingtoolkit.com/docs/guides
- Markdown: https://retroportingtoolkit.com/docs/guides.md
- Section: Guides
- Page type: reference
- Tags: Guides
- Last updated: 2026-08-30

---

These guides are for people who want to work on a port.

If you only want to play a finished port, start with that port's release page instead. If you are new to static recompilation, read [Start here](https://retroportingtoolkit.com/docs/start.md) first.

Each guide is meant to answer one practical question.

- [Build a toolchain](https://retroportingtoolkit.com/docs/guides/build-a-toolchain.md). Build the framework before trying a game.
- [Port a game](https://retroportingtoolkit.com/docs/guides/port-a-game.md). Start a native port from a legally supplied game file.
- [Write a mod](https://retroportingtoolkit.com/docs/guides/write-a-mod.md). Package an optional change without rewriting the player's game file.
- [Translate a game](https://retroportingtoolkit.com/docs/guides/translate-a-game.md). Replace text and verify it in-game.
- [Add widescreen](https://retroportingtoolkit.com/docs/guides/add-widescreen.md). Expand the visible area while keeping the faithful path intact.
- [Debug a divergence](https://retroportingtoolkit.com/docs/guides/debug-a-divergence.md). Find the first point where native and reference behavior disagree.
- [Set up co-simulation](https://retroportingtoolkit.com/docs/guides/set-up-co-simulation.md). Compare a recomp build against an oracle.
- [Release a port](https://retroportingtoolkit.com/docs/guides/release-a-port.md). Package a release without shipping files that do not belong there.

When a guide needs a game file or BIOS, use legally obtained files. This site does not provide them.

---

# Build a toolchain

> Build the console framework before you touch a game: the recompiler, the runtime, and the quick checks that prove your local setup works.

- Canonical URL: https://retroportingtoolkit.com/docs/guides/build-a-toolchain
- Markdown: https://retroportingtoolkit.com/docs/guides/build-a-toolchain.md
- Section: Guides
- Page type: guide
- Tags: Building, CMake, Toolchain
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/psxrecomp
  - https://github.com/mstan/nesrecomp
  - https://github.com/mstan/snesrecomp
  - https://github.com/mstan/gbarecomp
  - https://github.com/mstan/segagenesisrecomp
  - https://github.com/mstan/vbrecomp
  - https://github.com/mstan/cdirecomp
  - https://github.com/mstan/ndsrecomp

---

A toolchain is the developer side of a port.

It is not the game. It is the set of programs that can read a game file, generate native code, and build the runtime that surrounds it.

Before you try to port a game, prove the toolchain builds by itself.

## Who is this for?

This page is for people who want to build or work on ports.

If you only want to play a finished port, you probably do not need this page. Download the port, run it, and give it the game file it asks for. Some projects may also ask for a BIOS.

Use legally obtained files. This site does not provide games or retail BIOS files.

## What do I install first?

Most projects need the same basics:

| Need | Why it matters |
|---|---|
| Git | Gets the repository and its submodules. |
| CMake | Creates the build files. |
| Ninja or Visual Studio | Runs the build. |
| A C or C++ compiler | Builds the runtime and generated code. |
| Python | Runs helper scripts, tests, and packaging tools. |
| SDL | Provides windows, input, and audio for many runners. |

Exact versions vary by project. If a project has a setup script, use it first.

When something fails, read the first error. The first error is usually the one that matters.

## What am I building?

Usually two things:

1. The recompiler.
2. The runtime.

The recompiler translates the original machine code into host code.

The runtime models the console around that translated code: memory, video, audio, input, timing, storage, and other hardware behavior.

A clean toolchain build only proves the tools compile. It does not prove a game works.

## Why use PlayStation as the example?

psxrecomp is the strongest reference path today.

Other systems differ, but the shape is similar:

1. clone the framework;
2. fetch submodules;
3. build the recompiler;
4. generate any framework support files;
5. build the runtime;
6. run the project's smoke checks.

The [Developer quickstart](https://retroportingtoolkit.com/docs/start/quickstart.md) walks through that reference path.

## What changes by console?

| Console | What to expect |
|---|---|
| PlayStation | The clearest reference flow today. |
| SNES | Strong results, but more CPU-mode and game-specific discovery work. |
| NES | Small target where mappers and banking matter. |
| Game Boy Advance | Alpha/experimental work with ARM and Thumb code. Some projects need BIOS handling. |
| Sega Genesis | Two-CPU scheduling around the 68000 and Z80. |
| Master System and Game Gear | Very early Z80 tech-demo path. |
| Nintendo DS | Alpha-stage work around two ARM CPUs and optimization. |
| Virtual Boy | Focused one-game tech demo. |
| CD-i | BIOS-focused research path. |

Use the platform page for the maturity level. Use the project repository for exact build commands.

## What should I see after a good build?

You should have:

- a recompiler executable;
- a runtime build;
- any generated framework support files the project expects;
- passing smoke checks, if the project has them;
- no game file copied into the framework repository.

That last point matters. Framework repositories should not contain games, BIOS dumps, or generated game code.

## What usually goes wrong?

| Symptom | Likely cause |
|---|---|
| CMake cannot find a generated file. | A generation step was skipped. |
| CMake cannot compile a test program. | The compiler install is broken or not on PATH. |
| The UI build fails. | A submodule was not fetched. |
| The build dies with little output. | Too many compile jobs for available memory. |
| A command works in one shell but not another. | The shells have different tools on PATH. |

For large generated projects, try fewer build jobs before assuming the source is wrong.

---

# Port a game

> Start a port from one legally supplied game file, configure the recompiler, build the runtime, and fix the right layer when something breaks.

- Canonical URL: https://retroportingtoolkit.com/docs/guides/port-a-game
- Markdown: https://retroportingtoolkit.com/docs/guides/port-a-game.md
- Section: Guides
- Page type: guide
- Tags: Porting, Recompiler, Configuration
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/FaxanaduRecomp
  - https://github.com/mstan/SuperMarioBrosNESRecomp
  - https://github.com/mstan/SuperMarioWorldRecomp
  - https://github.com/mstan/MegaManX6Recomp
  - https://github.com/mstan/MinishCapRecomp
  - https://github.com/Shy/BoktaiRecomp

---

A port repository is a recipe.

It does not contain the game. It records how to turn one exact game file into a native program.

The recipe usually includes file identity checks, recompiler configuration, build scripts, runtime glue, and project-specific fixes.

Generated code is output. Do not edit it by hand. If regeneration would erase your fix, the fix belongs somewhere else.

## Before you start

You need:

- a framework that already builds;
- a legally dumped copy of the game;
- a BIOS or system file, if that console needs one;
- enough disk and memory for generated code;
- a way to run and observe the result.

Use legally obtained files. This site does not provide game files or retail BIOS files.

## Step 1. Identify the exact game

Start by proving which file the port targets.

A good port records:

- title and region;
- revision, if known;
- file size;
- hashes;
- disc serials or cartridge header fields where they matter;
- rejected formats or known-bad dumps.

This is not busywork. Static recompilation depends on exact bytes. A different revision can move code, data, overlays, or tables.

## Step 2. Fetch the framework

Most ports pin their framework.

That pin matters. A newer framework can change code generation, runtime behavior, build flags, or file layout.

If a repository uses submodules, clone with submodules or fetch them before building.

## Step 3. Teach the recompiler about the game

The game file does not explain itself.

The project may need to identify:

- where functions start;
- which bytes are data;
- which banks or overlays are active;
- which indirect calls are valid;
- which hardware addresses matter;
- which names help humans understand the binary.

Put those facts in configuration, symbols, annotations, or project-owned scripts. Do not hide them in generated C.

If a game has a public decompilation or strong disassembly, it can help a lot during discovery. Use it as an overlay for names, boundaries, and intent. Still verify everything against the exact file your port targets.

## Step 4. Generate the code

Run the project's generator or recompiler command.

The output usually lands in a generated directory.

After generation, check for missed code. A dispatch miss means the game tried to call code the recompiler did not cover. Fix that before chasing graphics, sound, timing, or gameplay bugs.

## Step 5. Build and run

The runtime links together:

- generated game code;
- console hardware behavior;
- input, video, audio, saves, and timing;
- launcher or file-picker code;
- optional mods or enhancements.

On first run, expect the port to ask for your game file. If the file does not match, a strict project should reject it instead of trying to continue blindly.

## Step 6. Fix the right layer

When something breaks, classify it before changing code.

| Problem | Usually belongs in |
|---|---|
| An instruction decoded wrong. | Recompiler. |
| Hardware behaves wrong. | Runtime. |
| A function was missed. | Discovery or config. |
| A game table or address is needed. | Game config. |
| A player-facing option is desired. | Mod or enhancement, off by default. |
| Generated C looks wrong. | The generator, then regenerate. |

Framework fixes are the best fixes. A bug found in one game is often a bug the next game would hit too.

Per-game configuration is still valid. It should describe the game, not paper over a framework bug.

## What does done mean?

Booting is not done.

A useful bring-up checklist asks:

- does the file identity check work?
- does the game reach title screen?
- does input work?
- can you reach gameplay?
- do saving and loading work?
- does audio behave?
- do menus and transitions work?
- are dispatch misses resolved?
- has the port been compared against a reference where possible?

Faithfulness is the measurement. Enhancements can come later, but the default path should behave like the original game.

---

# Write a mod

> Create a mod package that targets one verified game revision, exposes clear options, and changes the running port without rewriting the player's game file.

- Canonical URL: https://retroportingtoolkit.com/docs/guides/write-a-mod
- Markdown: https://retroportingtoolkit.com/docs/guides/write-a-mod.md
- Section: Guides
- Page type: guide
- Tags: Modding, PlayStation, NES, Configuration
- Last updated: 2026-08-31
- Source repositories:
  - https://github.com/mstan/psxrecomp
  - https://github.com/OpokXeno/xenogears-recomp
  - https://github.com/mstan/TombaRecomp
  - https://github.com/mstan/MegaManX6Recomp
  - https://github.com/mstan/nesrecomp
  - https://github.com/mstan/snesrecomp
  - https://github.com/mstan/FaxanaduRecomp

---

A mod changes how a port behaves.

It should not rewrite the player's game file. It should not ask the player to make a patched disc or patched ROM. A good mod declares what it wants changed, and the runtime applies that change in memory while the port runs.

When the mod is off, the game should return to the faithful path.

## Who is this for?

This page is for mod authors and port developers.

If you are only installing a mod, use the port's launcher or the port's own instructions.

## The three words to know

| Word | Meaning |
|---|---|
| Package | The installed archive. It has an id, version, author, license, and files. |
| Feature | One thing the player can turn on or off. A package can contain several features. |
| Operation | The actual change the runtime applies, such as a guarded byte write, overlay, or built-in plugin toggle. |

A feature is the user-facing unit. A package is the delivery unit. An operation is the low-level work.

Do not make one package per checkbox unless the package really has only one feature.

## Step 1. Target one exact game revision

A mod should say which game revision it supports.

For a disc game, use the digest the runtime expects for the mounted disc, not a random hash of one container file. For a cartridge game, use the hash and header fields the port uses.

This prevents a mod from writing bytes into the wrong version of the game.

## Step 2. Lay out the package

A simple source package looks like this:

```text
my-mod/
|-- manifest.toml
|-- README.txt
|-- LICENSE.txt
`-- assets/
    `-- replacement.bin
```

The manifest belongs at the package root. Payload paths should stay inside the package. Do not include game files, patched game files, secrets, or files you do not have permission to redistribute.

## Step 3. Write a small manifest first

Start with one disabled feature.

```toml
format_version = 1
id = "example.quick-start"
version = "1.0.0"
name = "Quick Start Example"
author = "Your name"
description = "One optional gameplay change."
resolver = "declarative"
save_compatibility = "shared"

[[target]]
game_id = "SLUS-00000"
disc_sha256 = "0000000000000000000000000000000000000000000000000000000000000000"

[[feature]]
id = "quick-start"
name = "Quick Start"
description = "Skips the startup delay."
group = "Gameplay"
default_enabled = false
```

Replace every placeholder before sharing it.

## Step 4. Use the narrowest operation

| Change | Better shape |
|---|---|
| A few known bytes change. | Guarded patch. |
| A choice like speed, language, or difficulty. | One option with valid values. |
| A large asset changes. | Overlay with hashes. |
| Host-side behavior changes. | Built-in plugin reviewed into the port. |
| Several features fight over the same bytes. | Project-owned resolver. |

Guarded patches should include the expected original bytes. That gives the launcher a chance to stop before a wrong or conflicting write happens.

## Step 5. Expose options as options

Do not create five features for five values of the same setting.

Use one feature with a typed option:

```toml
[[option]]
feature = "battle-tuning"
id = "starting-ap"
label = "Starting AP"
type = "integer"
min = 0
max = 30
step = 1
default = 4
```

The stock value should produce no change when possible. That keeps the faithful path easy to reason about.

## Step 6. Keep code trusted

A mod package should not load arbitrary native code.

If a feature needs host code, that code belongs in the port repository, reviewed and compiled ahead of time. The package can then select it by a stable plugin id.

This is a trust boundary. A mod can still change game code and assets, so players should install packages only from authors they trust. But the package format should avoid downloaded DLLs, scripts, or executables.

## Step 7. Pack and test

Pack the archive with the tool the project provides.

Then test:

- clean install;
- feature off;
- feature on;
- every option boundary;
- wrong game file;
- wrong expected bytes;
- two mods touching the same range;
- uninstall and reinstall;
- save compatibility;
- a real gameplay path past the first visible result.

A title screen check is not enough. A mod can work at boot and still break a later load, battle, save, or transition.

## Common failures

| Symptom | Likely cause |
|---|---|
| Package does not install. | Missing root manifest, bad TOML, unsafe path, or archive too large. |
| Feature appears but does nothing. | It is disabled, its condition does not match, or it resolves to the stock value. |
| Wrong target error. | The game id, executable hash, or disc hash does not match. |
| Expected bytes mismatch. | Wrong address, wrong revision, wrong endian order, or already patched input. |
| Two features conflict. | They claim different bytes in the same range. |
| Plugin unavailable. | The port did not compile in that plugin id. |

---

# Translate a game

> Build a translation table for a recompiled port without editing the game file or regenerating code.

- Canonical URL: https://retroportingtoolkit.com/docs/guides/translate-a-game
- Markdown: https://retroportingtoolkit.com/docs/guides/translate-a-game.md
- Section: Guides
- Page type: guide
- Tags: Translation, Localization, PlayStation, NES
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/psxrecomp
  - https://github.com/mstan/TsumuLightRecomp
  - https://github.com/mstan/nesrecomp
  - https://github.com/mstan/FaxanaduRecomp

---

A translation changes the text the player sees.

In a recompiled port, that does not have to mean editing the game file. The usual path is a table: match the original bytes, then provide replacement text. The runtime applies the replacement while the game draws text.

No game file is distributed. No generated code needs to be hand-edited.

## Before you start

You need:

- a working port;
- your own copy of the game;
- a debug build if the project reloads translations through a debug server;
- a way to capture screenshots;
- a way to reach the text you want to translate.

Translation is part writing and part testing. Seeing the line on screen is the proof.

## What the table does

A translation table usually records:

| Field | Meaning |
|---|---|
| Source bytes | The original text record, stored as hex. |
| Terminator | How the original string ends. |
| Language column | The replacement text for one language. |
| Optional address | A tie-breaker when the same bytes appear in more than one place. |
| Width limit | How much room the translated line has. |

The runtime matches the original bytes. If it finds a match for the selected language, it gives the game the replacement text. If it does not find a match, the original text stays.

## Three ways games draw text

Games do not all draw text the same way.

| Layer | Use it when |
|---|---|
| String replacement | The game passes a pointer to a normal text record. |
| Fixed label patch | The label lives at a known address and the game draws it one glyph at a time. |
| VRAM patch | The text is already baked into a graphic, so you replace pixels instead of characters. |

Start with string replacement. Use the other layers only for text that cannot be reached as a normal string.

## Step 1. Capture source text

Run the game with capture enabled, if the project supports it.

Then play through the screens you want to translate: menus, tutorials, dialogue, item names, results, endings, and error prompts.

The output should be an inventory of real text records. If you get thousands of binary-looking records, your capture filter is too loose.

## Step 2. Decode and write

Convert the captured bytes into a table you can edit.

A small example looks like this:

```toml
schema = 1
default_lang = "en"

[[entry]]
src_hex = "51835b818083c982c882ea"
term = "ffff"
en = "Start here!"
```

Keep the source bytes exact. Edit the translation, not the match key.

## Step 3. Apply and verify on screen

Run the game with the table loaded.

The checkpoint is visual: the translated line appears in the correct place, with correct spacing, and without breaking the box around it.

Do not count a table hit as success by itself. A counter can say the replacement applied while the line is clipped, too long, missing a glyph, or drawn on the wrong screen.

## Step 4. Reload while testing

Some projects can reload a translation table while the game is running. Others require a restart.

Use the project-supported path. Do not assume file watching exists unless the running project proves it.

The useful loop is:

1. edit one line;
2. reload or restart;
3. return to the screen;
4. take a screenshot;
5. fix width, line breaks, or wording;
6. repeat.

## Step 5. Re-capture to find gaps

After a pass, capture again and compare the live inventory to the table.

The best definition of done is simple: a full playthrough adds no new text records that need translation.

That is strict, but it catches menu paths, error prompts, and late-game text that a normal quick test misses.

## Text that needs special handling

| Problem | What it means |
|---|---|
| The text is drawn one glyph at a time. | A pointer scan may never see it. Use a fixed label entry if the project supports one. |
| The text is part of an image. | Use a VRAM or asset patch, not string replacement. |
| The line is too long. | Add line breaks, shorten it, or use the project's width controls. |
| The game crashes after replacement. | The original bytes may be part of a larger structure, not a standalone string. |
| A glyph is missing. | The font or glyph upload path may need work before the language is viable. |

---

# Add widescreen

> Widen a port without breaking the faithful 4:3 path: decide whether the game is 3D or 2D, widen what the game draws, and test for culling, wrapping, spawning, and timing bugs.

- Canonical URL: https://retroportingtoolkit.com/docs/guides/add-widescreen
- Markdown: https://retroportingtoolkit.com/docs/guides/add-widescreen.md
- Section: Guides
- Page type: guide
- Tags: Widescreen, Enhancements, PlayStation, Sega Genesis, NES, SNES
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/psxrecomp
  - https://github.com/mstan/segagenesisrecomp
  - https://github.com/mstan/snesrecomp
  - https://github.com/mstan/SuperMarioBrosNESRecomp
  - https://github.com/mstan/MegaManX6Recomp
  - https://github.com/mstan/gbarecomp
  - https://github.com/mstan/ndsrecomp
  - https://github.com/mstan/cdirecomp

---

Widescreen is easy to see and hard to finish.

Making the output surface wider is only the first step. The game may still draw only a 4:3 world. It may cull objects too early. It may wrap sprite positions. It may spawn enemies at the wrong time. It may reveal art that was never meant to be visible.

The default rule is simple: widescreen is optional, off by default, and the normal 4:3 path stays faithful.

## Before you start

You need:

- a working port;
- a known-good 4:3 reference;
- a debug build with TCP screenshot and input commands, when the project supports them;
- enough test scenes to catch edge cases.

Do not begin by changing generated code. Put widescreen behavior in runtime code, recompiler configuration, or a reviewed mod or enhancement layer.

## Step 1. Decide what kind of game you have

| Game type | What widescreen usually means |
|---|---|
| 3D | Widen the projection or render a wider view. Then fix culling, sky, backdrop, HUD anchoring, and overlays. |
| 2D | Make the engine draw more columns or rows. Then fix sprite wrapping, tile buffers, spawning, and collision. |
| Mixed | Treat each scene type separately. Menus, FMV, maps, and gameplay may need different handling. |

Do not assume there is hidden content outside the 4:3 frame. Some games truly draw only the original view.

Some games need a more direct answer: a custom renderer. [StarFoxSNESRecomp](https://github.com/mstan/StarFoxSNESRecomp) is the first example here. Its authentic 4:3 path stays on the stock renderer, while wider modes use a separate native renderer adapted from Star Fox Enhanced.

## Step 2. Protect the faithful path

At 4:3, widescreen settings should reduce to the original behavior.

That means:

- no extra cull margin;
- no shifted camera;
- no changed spawn timing;
- no different random sequence;
- no altered collision;
- no modified game file.

Output identity is the goal. The binary may differ because the port has extra runtime checks, but those checks should produce the original result when widescreen is off.

## Step 3. Widen what is drawn

For a 3D game, the first visible change is usually projection or render width. That can show more of the world, but it does not automatically make the game submit more objects.

For a 2D game, there is no projection to widen. You have to make the game's own background and sprite logic draw more content.

**Checkpoint.** The world is wider, and several things are wrong. That is normal at this stage.

## Step 4. Fix culling and object visibility

Culling is the game deciding not to draw something.

Many games compare object position against a 4:3 screen window before the renderer ever sees it. A wider projection cannot fix that. You need to find the cull sites and widen them in a controlled way.

Do not tune by eye only. Test the same scene at 4:3 and widescreen, then look for objects that pop in, vanish, or appear late.

**Checkpoint.** Objects do not pop while they are visibly inside the widescreen view.

## Step 5. Anchor the HUD

The HUD is usually presentation, not simulation.

A good widescreen pass keeps gameplay wider while keeping health bars, text boxes, timers, reticles, and menus readable. Some HUD elements should stay near the original 4:3 safe area. Others should move to the new edge. The game decides this case by case.

Check menus and overlays separately from gameplay. A fix that looks right while playing can still stretch a pause menu, split a dialogue box, or move a prompt too far from the action.

**Checkpoint.** HUD elements are readable, stable, and not stretched by accident.

## Step 6. Capture what changed

Use the debug server when the project has one. A TCP screenshot and input script gives you repeatable evidence: enter the same scene, capture the 4:3 reference, capture the widened view, and compare the result.

This matters for AI work too. The useful proof is not "the code looks right." The useful proof is a captured frame, a known input path, and a note about what changed.

The command details live in [TCP debug protocol](https://retroportingtoolkit.com/docs/reference/tcp-protocol.md). The broader inventory is [Machine-readable surfaces](https://retroportingtoolkit.com/docs/agents/machine-surfaces.md).

## Step 7. Fix 2D wrapping

Older 2D hardware often stores screen X in 8 or 9 bits. When widened positions move past that range, sprites can wrap to the other side of the screen.

Common fixes include:

- keeping a wider sidecar value;
- widening a sprite mask;
- changing the OAM visibility check;
- treating margin-only collision boxes as offscreen.

**Checkpoint.** A sprite entering a margin does not teleport, flicker, or create a phantom hitbox.

## Step 8. Check spawning and progression

Spawning can affect simulation, not just presentation.

Some games tie spawning to the camera edge. In those games, widening the edge can change when an enemy appears, where it starts, which script fires, or which random number gets consumed.

That is not true for every game. Test it before changing it. If a spawn change causes a softlock, early trigger, RNG shift, or broken route, treat that as a correctness bug.

The safe goal is that widening presentation does not silently change progression.

## Step 9. Test dense and ugly scenes

Widescreen bugs hide in scenes with:

- many sprites;
- scrolling strips;
- wraparound backgrounds;
- large bosses;
- sky domes or far backdrops;
- mode changes;
- paused menus over gameplay;
- transitions and loading screens.

Test more than the first level. Widescreen that works in one scene can break a later scene that uses another renderer path.

## 3D and 2D feel different

3D widescreen is often the easier case. You usually start by expanding the camera or projection, then fix culling, backdrop limits, sprite proportions, and HUD placement. The game world may already exist outside the old frame.

2D widescreen is usually more invasive. There may be no hidden view to reveal. The game often has to stream more tiles, draw more sprites, widen object checks, and avoid wrapping old 8-bit or 9-bit screen positions. That can touch more game-specific logic.

Mixed games need both passes. A 3D scene, a 2D menu, a world map, and an FMV player can all have different rules.

## Common failures

| Symptom | Likely cause |
|---|---|
| Black bars or voids at the edges. | The game did not draw content there, or the backdrop art ends. |
| Objects pop in late. | A 4:3 cull window is still active. |
| Sprites appear on the wrong side. | Screen X wrapped. |
| Enemies spawn inside walls. | The spawn window was widened too aggressively. |
| Collision happens from across the screen. | A margin collision box wrapped into the 4:3 area. |
| Dense scenes drop layers. | The game exceeded its primitive or tile budget. |
| 4:3 behaves differently now. | The widescreen path is leaking into the faithful path. |

---

# Debug a divergence

> When a port disagrees with the reference, start from the first visible split, classify the failure, and fix the recompiler, runtime, or game config instead of patching generated code.

- Canonical URL: https://retroportingtoolkit.com/docs/guides/debug-a-divergence
- Markdown: https://retroportingtoolkit.com/docs/guides/debug-a-divergence.md
- Section: Guides
- Page type: guide
- Tags: Debugging, Co-simulation, Correctness
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/psxrecomp
  - https://github.com/mstan/gbarecomp
  - https://github.com/mstan/segagenesisrecomp
  - https://github.com/mstan/cdirecomp
  - https://github.com/mstan/SuperMarioWorldRecomp

---

A divergence means the port and the reference stopped agreeing.

That reference might be an emulator oracle, an interpreter path, a previous known-good run, or a hardware-event trace. The important part is that you are comparing the port to something more trusted than your eyes.

Do not start by guessing. Start by finding the first moment where the two runs split.

## What should I check first?

Check for missed code before anything else.

A dispatch miss means the game jumped to code the recompiler did not translate. That can make the game skip a whole subroutine and keep running in a broken state.

If the project writes a dispatch-miss log, read it after every run. If it is not empty, fix discovery or configuration first.

Do not debug graphics, audio, timing, or gameplay while known code is missing.

## What does the report tell me?

A good divergence report tells you:

- where the two runs stopped agreeing;
- which part of the machine differs first;
- what each side thought the state was;
- what happened shortly before the split.

The first difference matters more than the biggest symptom.

A black screen ten frames later may have started as one bad register write. A bad sound effect may have started as a timer or DMA issue. A crash may have started as a missed overlay.

## Why not just inspect the broken screen?

Visible symptoms are late.

By the time a player sees a black screen, the real bug may already be several systems back.

Walk backward:

1. find the last good checkpoint;
2. find the first bad checkpoint;
3. find the first changed subsystem;
4. find the write or instruction that made it change;
5. fix the layer that produced that write.

That is slower than guessing, but it avoids fixing the symptom instead of the cause.

## What tools are usually involved?

Most mature projects grow a TCP debug server.

That server lets tools ask the running port for state: registers, memory, frame captures, screenshots, input state, timing counters, dispatch misses, and recent trace rings.

TCP is preferred here over MCP because debug clients restart often. Ports crash. Oracles restart. Harnesses reconnect. A plain TCP surface handles that better than a long-lived tool session that can get confused when the process under it disappears.

This is also useful for AI-assisted debugging. A tool can take a screenshot, press inputs, read state, compare memory, and report what changed without needing a human to stare at the window.

TCP input is not a replacement for real gameplay testing. It is useful for visual verification and basic control: moving through menus, pressing buttons, walking in a straight line, or repeating simple actions that are not timing-sensitive.

The exact commands differ by project. The shape is the same: expose the machine state through a tool surface instead of sprinkling one-off print statements through the runtime.

## How do I classify the bug?

Use the first difference to decide where the fix belongs.

| First bad thing | Likely layer |
|---|---|
| Wrong instruction result. | Recompiler or decoder. |
| Correct CPU state, wrong video memory. | Runtime hardware model or DMA path. |
| Correct memory, wrong pixels. | Renderer or presentation path. |
| Code jumps to an unknown address. | Discovery or overlay handling. |
| State changes at the wrong time. | Timing or scheduler. |
| Only one game needs a known address. | Game config. |

Do not edit generated code. Fix the source of generation or the runtime, then regenerate.

## What if the comparison tool is wrong?

That can happen.

A comparator can be blind if it fails to read real state, compares empty values, or accidentally ignores the field that changed.

Before trusting a green comparison, prove the tool can fail. Inject a known difference and make sure the run reports it in the right place.

A green run only means something if the harness is able to catch a red one.

## What if the game is slow?

First, check whether the game is actually running native code.

A fallback interpreter can keep a game moving while missing paths are discovered, but it is slower. If too much code stays in fallback, the port may work but feel bad.

Then check observer cost. Debug tools can slow the process if they ask for large dumps or screenshots too often.

After that comes real optimization work.

This can be a large phase, especially on later systems. Recompilation is not automatically fast enough just because code becomes native. The runtime, renderer, scheduler, memory model, audio path, debug hooks, and generated code shape can all matter.

Like emulator performance work, this may take many passes. It can take weeks, even with AI helping. Measure before optimizing, and keep correctness checks close while changing performance-sensitive code.

A timing shortcut that helps one game can break another.

## What should my bug report include?

A useful report includes:

1. the game and platform;
2. the framework revision;
3. the expected behavior;
4. the observed behavior;
5. the first divergence, not only the final symptom;
6. the subsystem that differs first;
7. the suspected layer;
8. the fix or next command needed;
9. the re-test plan.

That is enough for someone else to continue the investigation.

## What should I avoid?

Do not:

- edit generated code by hand;
- add game-specific hacks to a shared runtime;
- stub a missing function so the game keeps moving;
- silence an unmapped hardware read because it is noisy;
- call a green run meaningful before the comparator is tested.

Missing information is not permission to guess. Add the tool you need, then run the test again.

---

# Set up co-simulation

> Run a port beside a trusted reference, stop both at the same guest-time checkpoints, and use the first mismatch to guide debugging.

- Canonical URL: https://retroportingtoolkit.com/docs/guides/set-up-co-simulation
- Markdown: https://retroportingtoolkit.com/docs/guides/set-up-co-simulation.md
- Section: Guides
- Page type: guide
- Tags: Correctness, Testing, Co-simulation
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/psxrecomp
  - https://github.com/mstan/nesrecomp
  - https://github.com/mstan/snesrecomp
  - https://github.com/mstan/segagenesisrecomp
  - https://github.com/mstan/gbarecomp

---

Co-simulation is a developer tool.

You run the port beside a trusted reference and ask both machines the same questions at the same guest-time checkpoints.

If they agree, you gain confidence. If they split, the first split tells you where to debug.

## What is the reference?

The reference is usually an emulator people already trust.

In this ecosystem, that reference is often called an oracle.

The oracle is not shipped as the game port. It is a development tool used to answer questions like:

- what are the CPU registers now?
- what does memory look like now?
- what did the video or audio state look like at this point?
- did the port and reference reach the same hardware event?

A project may also compare the native path against its own interpreter. That is useful, but weaker. If both paths share the same bug, they can agree and still be wrong.

## What do both sides need to expose?

Both sides need a way to answer the same debug questions.

Usually that means a TCP debug server. One process is the port. The other process is the oracle. A coordinator asks both for state and compares the answers.

Useful commands often include:

- registers;
- memory reads;
- frame or screenshot capture;
- input state;
- timing counters;
- recent trace rings;
- dispatch-miss state.

The command names do not have to be identical across every framework. Inside one co-sim pair, they need to mean the same thing.

## Why guest time matters

Do not sync by wall-clock time.

Your PC is not the console. Host frame pacing, background load, debugger pauses, and TCP traffic can all change wall-clock timing.

Sync on guest time instead: cycles, frames, VBlank counts, DMA completions, interrupt counts, or another hardware event both sides can measure.

That lets the comparison ask: "At this same console moment, did both machines have the same state?"

## What about input timing?

Input can cause divergence too.

If the port and the reference receive an input on different guest frames, both machines may be correct and still split. The test was not deterministic.

This is why attract demos are powerful early co-simulation targets. Many games play a long scripted demo after the title screen. No player input is needed, so the two runs can line up cleanly and exercise a lot of game logic, video, audio, timing, and state changes.

If an attract demo depends on randomness, make the randomness deterministic before trusting the comparison. Find the RNG seed and force the same seed on both sides, or choose a path that does not depend on random input.

## What is a stride?

The stride is how often you stop and compare.

A large stride is faster but less precise. A small stride is slower but gets closer to the exact bug.

A normal workflow is:

1. start with a large stride;
2. find the first failing window;
3. run again with a smaller stride inside that window;
4. repeat until the first bad operation is close enough to inspect.

The goal is not to compare everything forever. The goal is to find the first useful disagreement.

## How do I know the harness is honest?

Prove it can fail.

A comparison tool can accidentally compare nothing and report success. It can also ignore a field that matters.

Before trusting a green run:

- run the same backend against itself and expect agreement;
- inject a known fault and expect disagreement;
- make sure the report names the right subsystem;
- make sure hashes are backed by real state, not empty values.

A green result only means something after the red path has been proven.

## What files do I need?

You need the files the project normally requires.

That may include a game file, and sometimes a BIOS or firmware file. Use legally obtained files. This site does not provide them.

Keep co-simulation out of release builds. It is diagnostic machinery for developers, not part of the normal player package.

## What do I do with the result?

If the run is green, record the setup:

- game file identity;
- framework revision;
- oracle used;
- stride;
- final frame or cycle;
- final hash or result.

That gives you a baseline to re-run after changes.

If the run is red, do not jump to the final symptom. Read the first mismatch and move to [Debug a divergence](https://retroportingtoolkit.com/docs/guides/debug-a-divergence.md).

## What are the limits?

Co-simulation is powerful, but it is not the whole release bar.

A headless run may miss feel, presentation, frame pacing, or user-facing problems. A clean comparison does not replace playtesting.

It also depends on the oracle. If the oracle is wrong, incomplete, or wired incorrectly, the comparison inherits that risk.

Use co-simulation as a discipline, not as a magic stamp.

---

# Release a port

> Package a port for players without shipping game data, retail BIOS files, generated game code, private saves, or developer-only diagnostics.

- Canonical URL: https://retroportingtoolkit.com/docs/guides/release-a-port
- Markdown: https://retroportingtoolkit.com/docs/guides/release-a-port.md
- Section: Guides
- Page type: guide
- Tags: Releasing, Packaging, Compliance
- Last updated: 2026-08-31
- Source repositories:
  - https://github.com/mstan/segagenesisrecomp
  - https://github.com/mstan/psxrecomp
  - https://github.com/mstan/gbarecomp
  - https://github.com/mstan/FaxanaduRecomp
  - https://github.com/mstan/SuperMarioWorldRecomp
  - https://github.com/Shy/BoktaiRecomp
  - https://github.com/mstan/TombaRecomp
  - https://github.com/TechnicallyComputers/retcomm-catalog

---

A release is what another person downloads.

That makes it different from your local build folder. A release should contain only what the project is allowed to distribute and what the player needs to run the port.

The most important rule is simple: do not ship game data.

## What must never be in a release?

Do not package:

- ROMs;
- disc images;
- copyrighted retail BIOS files;
- uncompiled generated game code derived from a game file, unless the project has made a deliberate release decision;
- private saves;
- debug logs;
- local config files;
- crash dumps;
- build junk.

Some projects can include legal open-source BIOS alternatives. Retail BIOS dumps are different. Use legally obtained files, and do not distribute them through the port.

## Why is this stricter than a normal app?

A native recomp port can contain compiled translated game code.

That is why this topic needs care. Some projects ship compiled ports. Others avoid shipping a finished game binary and release a setup kit or builder instead.

This is why some releases ask the player for their own game file on first run, and some projects make the player build locally.

The release shape depends on the project. The rule does not: do not distribute files you do not have the right to distribute.

## Package with a script

Do not zip a build folder by hand.

Build folders collect whatever was convenient during development: ROMs, dumps, logs, generated code, cache files, config files, and local tools.

A release script should do the opposite. It should start from an allowlist and copy only known-safe files.

A good packager:

- stages named files only;
- refuses forbidden extensions;
- strips developer configs;
- includes license and attribution files;
- checks the version stamped into the executable;
- writes one predictable archive per platform.

## What should a player receive?

Usually one archive per platform.

That archive should include:

- the executable or launcher;
- required runtime assets;
- required open-source support files, if any;
- license files;
- third-party notices;
- a short first-run note.

The first-run note should say what file the player must provide and what the project will check. Keep it practical.

## What should CI do?

CI usually cannot run the whole game path because it should not have the game file or retail BIOS.

It can still prove useful things:

- the project configures;
- the non-generated code compiles;
- unit tests pass;
- package scripts refuse forbidden files;
- release assets have the expected names;
- generated files are not accidentally committed.

If a project uses a private self-hosted runner for deeper checks, keep those files off public CI.

## What should I test before publishing?

Before publishing, test the release as a player would.

Use a clean directory. Extract the archive. Run it. Give it the game file it asks for. If a BIOS is needed, use the same path a real user would use.

Check at least:

- first launch;
- file identity rejection for the wrong file;
- file identity acceptance for the right file;
- input;
- save creation;
- relaunch after save;
- basic audio and video;
- no debug files appearing in the archive.

## What should release notes say?

Release notes should be plain.

Say:

- what changed;
- what platforms are included;
- what file the player must provide;
- whether a BIOS is needed;
- known limits;
- where to report problems.

Do not overclaim compatibility. If only part of a game is tested, say that.

## Common release failures

| Symptom | Likely cause |
|---|---|
| The game launches only on the developer machine. | A required DLL, asset, or support file was missed. |
| The launcher cannot find fonts or assets. | The package layout is wrong. |
| The wrong file is accepted. | Identity checks are too loose. |
| A crash report names a dev build. | The release was not stamped or packaged from the right commit. |

---

# Working with AI agents

> How to brief, supervise, and verify AI agents working on recomp projects.

- Canonical URL: https://retroportingtoolkit.com/docs/agents
- Markdown: https://retroportingtoolkit.com/docs/agents.md
- Section: Working with AI agents
- Page type: reference
- Tags: Agents
- Last updated: 2026-08-31

---

This section is for people using AI agents on recomp projects.

Do not assume an agent will discover these rules by crawling the site. Treat these pages as a briefing packet: give the agent the rules, point it at the local repository instructions, and make it prove its work.

- [What to tell an AI agent before it touches a recomp project](https://retroportingtoolkit.com/docs/agents/start-here.md). The human-facing overview and recommended agent setup.
- [Rules to give an AI agent](https://retroportingtoolkit.com/docs/agents/house-invariants.md). The rules an agent should follow unless the local repository says something stricter.
- [How to check AI work](https://retroportingtoolkit.com/docs/agents/verification-rituals.md). What proof counts for builds, coverage, co-simulation, screenshots, TCP checks, and releases.
- [How AI breaks recomp projects](https://retroportingtoolkit.com/docs/agents/failure-modes.md). The quiet failure modes to look for when reviewing AI-generated recomp work.
- [Debug surfaces agents can use](https://retroportingtoolkit.com/docs/agents/machine-surfaces.md). TCP servers, traces, JSON output, screenshots, input commands, and other surfaces an agent can query.
- [Making AI contributions reviewable](https://retroportingtoolkit.com/docs/agents/contributing-as-an-agent.md). Commit rules, handoff expectations, and what never belongs in a change.
- [When an agent cannot run the game](https://retroportingtoolkit.com/docs/agents/when-you-cannot-run-the-game.md). What an agent can still check without the game, display, or oracle.
- After an agent finishes, expect a recap that names the files changed, checks run, commit, and published URL.

---

# What to tell an AI agent before it touches a recomp project

> How to brief an AI agent before it works on static recompilation code.

- Canonical URL: https://retroportingtoolkit.com/docs/agents/start-here
- Markdown: https://retroportingtoolkit.com/docs/agents/start-here.md
- Section: Working with AI agents
- Page type: project
- Tags: Agents, Conventions, Verification
- Last updated: 2026-08-30

---

These pages are for people using AI agents on recomp projects.

Do not assume the agent will find this page on its own. Give it the rules. Paste the important parts into the session. Point it at the local repository instructions. Then make it prove the work.

Recomp projects are unusually easy for AI to damage. The game can boot while skipping real logic. A patch can compile while weakening accuracy. A "temporary" stub can survive for months because it looks harmless.

The goal is not to make the diff sound smart. The goal is to preserve correctness.

## What to give the agent first

Do not assume every project already has the same instruction files.

If a project already has local instructions, tell the agent to read them before editing. If it does not, start from system-agnostic templates and have the agent adapt them to that project.

These starter files are intentionally generic:

| Starter file | Use it for |
|---|---|
| [AGENTS.md](https://retroportingtoolkit.com/agent-templates/AGENTS.md) | The rules any AI agent should follow in this repo: where fixes belong, what never to edit, required checks, commit rules, and handoff expectations. |
| [CLAUDE.md](https://retroportingtoolkit.com/agent-templates/CLAUDE.md) | A compatibility file for projects that still use Claude-specific instructions. Keep it aligned with `AGENTS.md` instead of letting two rule sets drift. |
| [README.md](https://retroportingtoolkit.com/agent-templates/README.md) | Human setup: what the project is, what works today, what files the user must legally provide, and how to build or launch it. |
| [DEBUG.md](https://retroportingtoolkit.com/agent-templates/DEBUG.md) | How to observe the running port: dispatch misses, coverage, traces, screenshots, co-simulation, known failure modes, and common commands. |
| [TCP_COMMANDS.md](https://retroportingtoolkit.com/agent-templates/TCP_COMMANDS.md) | The debug protocol: port, request shape, response shape, commands, error format, and examples. Rename it to `TCP.md` if that is the local convention. |

The local repository wins when it has specific rules. These site pages are a fallback and a shared philosophy. They are not a replacement for the instructions in the repo being changed.

If the local file points at a path the agent cannot open, make it say so. It should not invent missing rules.

## What kind of work is this?

A recomp project usually has more than one repository involved.

Make the agent identify where it is working before it edits anything.

| Repo type | What it usually owns |
|---|---|
| Framework repo | Recompiler, runtime, hardware model, shared tooling. |
| Game repo | Game config, hooks, allowed assets, release packaging. |

A framework repo is the reusable system layer. It is where the console rules live: CPU behavior, memory, timing, graphics, audio, input, code generation, debug tools, and shared runtime behavior.

A game repo is the specific port. It usually says "take this game file, verify its identity, generate the code, build this app, and apply these game-specific hooks."

Many game repos include the framework as a submodule. A submodule is a pointer to another Git repository at one exact commit. It may look like a normal folder, but it has its own history. Updating a submodule means changing that pointer, and usually also committing the framework change in the framework repo first.

That distinction matters:

| Change | Usually belongs in |
|---|---|
| CPU instruction behavior | Framework repo |
| Hardware timing default | Framework repo |
| Debug server command used by every game | Framework repo |
| Code discovery rule used by many games | Framework repo |
| Game hash, serial, or identity rule | Game repo |
| Game-specific symbol overlay or config | Game repo |
| Release packaging for one port | Game repo |
| Custom renderer or enhancement for one game | Game repo, unless it becomes reusable framework behavior |

A framework bug should not be hidden in one game. A game-specific rule should not become the default for a whole console.

## Recommendations from the development team

> **Note from Matthew Stanley ([mstan](https://github.com/mstan)), aka Gamemaster**
>
> For everyday recomp work, the strongest results have come from Opus 5 and GPT 5.5 High.
>
> For extremely complex problems, the most useful pattern has been orchestration: use Fable or Sol as the lead reviewer, then have them challenge subagents running Opus 5 or GPT 5.5 High.
>
> The value is not "more agents." The value is adversarial review, independent hypotheses, and forcing every claim to come with proof.
>
> In practice, Opus 5 is strong but can struggle with very long-running tasks. GPT 5.5 High tends to hold longer solo threads better. Fable and Sol are most useful when the problem is too tangled for one everyday agent to keep straight.

Treat these as experience notes, not a permanent model ranking. The important idea is the workflow: harder recomp problems benefit from independent review and proof pressure.

## The short briefing

Give the agent this standard:

- Follow the local repo instructions first.
- Do not edit generated code.
- Do not add stubs.
- Find the first divergence.
- Align by hardware events, not frame numbers.
- Check dispatch misses after runs.
- Check coverage when the project reports it.
- Use TCP, traces, screenshots, or co-simulation when available.
- Say what could not be tested.
- Leave a handoff that another person can continue.

If the agent cannot explain how it will prove the change, it is not ready to edit.

## What proof should look like

Good proof is specific:

- the build command ran
- the game launched
- the debug server answered
- dispatch misses were empty
- coverage did not regress
- the oracle matched
- the screenshot showed the expected output
- the release archive contained only allowed files

Pick the proof that matches the claim. A screenshot does not prove timing. A build does not prove gameplay. A unit test does not prove a full route.

## What to watch for

Stop the agent when it:

- patches generated files
- adds placeholder behavior
- explains around a failing check
- treats a skipped test as a pass
- says "probably" where a trace or oracle result is needed
- uses one game to justify a framework rule
- weakens a game or BIOS identity gate
- commits dumps, game files, BIOS files, saves, or local junk

These are not style problems. They are correctness problems.

---

# Rules to give an AI agent

> The core rules an AI agent should follow when working on recomp projects.

- Canonical URL: https://retroportingtoolkit.com/docs/agents/house-invariants
- Markdown: https://retroportingtoolkit.com/docs/agents/house-invariants.md
- Section: Working with AI agents
- Page type: reference
- Tags: Agents, Conventions, Correctness
- Last updated: 2026-08-30

---

This is the rule sheet to give an agent before it edits a recomp project.

The local repository can be stricter. When it is, follow the repository. When it is silent, use these rules.

## Fix the tool, not generated output

Generated C is build output.

If generated output is wrong, the fix belongs in one of these places:

- the recompiler
- the runtime
- the game config
- the discovery input

Then regenerate.

Do not hand-edit generated files. The next regeneration deletes the fix and keeps the bug.

## No stubs

A missing implementation should fail loudly.

Do not return a fake success value. Do not skip a hardware event. Do not add "temporary" behavior that lets the game continue while lying about what happened.

Stubs are rot. AI makes this worse because it can produce confident, clean-looking stubs quickly.

If behavior is unknown, the agent should investigate, fail loudly, or stop with a clear note.

## Find the first divergence

When native and oracle disagree, the earliest mismatch is the bug to debug.

Later differences are usually consequences. A later screenshot, register value, audio glitch, or crash may only be the result of the first bad write.

## Align on hardware events

Do not compare two runs by frame number unless the project proves that frame number means the same thing on both sides.

Prefer hardware events:

- VBlank
- DMA completion
- timer overflow
- interrupt return
- a specific PC reaching a specific function
- a known synchronization register or bus event

This matters more on systems with multiple CPUs or independent devices.

## Use always-on traces

Prefer ring buffers and history queries that were recording before the bug happened.

The best workflow is: run the game, see a bug, then ask what happened before it.

Arming a trace and rerunning can change timing. It can also miss intermittent failures.

## Treat dispatch misses as blocking

A dispatch miss means the runtime tried to call code that was not generated.

That can skip a whole subroutine without crashing. Resolve dispatch misses before chasing graphics, audio, or gameplay symptoms.

## Build the missing tool

If the debug server cannot answer the question, add the query when that is reasonable.

Do not use a private print or one-off script as the only proof. The next person should be able to ask the same question.

## Unknown is allowed

Guessing is worse than saying "unknown."

If source material is stale, contradictory, or inaccessible, the agent should state the limit and continue from evidence it can check.

## Prove the change

A good recomp change leaves proof:

- build output
- test output
- dispatch-miss status
- coverage status
- oracle comparison
- screenshot or frame capture
- trace or TCP result

The proof must match the claim. Do not use a screenshot to prove timing. Do not use a compile to prove correctness.

## Do not commit private inputs

Never commit:

- game files
- retail BIOS files
- disc dumps
- private saves
- local generated junk
- large diagnostic output

Use hashes and small fixtures when a test needs identity.

## Keep identity gates strict

If the project expects one game revision, do not weaken the check so another dump passes.

Running the wrong revision through the right port creates real-looking bugs with the wrong root cause.

## Leave a clean handoff

The agent should end with:

- what changed
- what was tested
- what could not be tested
- what evidence supports the claim
- what remains unknown

Short and exact is better than polished and vague.

---

# How to check AI work

> How to decide whether an AI-generated recomp change was actually proven.

- Canonical URL: https://retroportingtoolkit.com/docs/agents/verification-rituals
- Markdown: https://retroportingtoolkit.com/docs/agents/verification-rituals.md
- Section: Working with AI agents
- Page type: reference
- Tags: Agents, Testing, Verification
- Last updated: 2026-08-30

---

Do not ask whether the agent "tested it."

Ask what the test proves.

A build proves the compiler accepted the code. It does not prove the game is correct. A screenshot proves one visual moment. It does not prove timing, input, audio, or end-to-end play.

## The minimum checklist

For most recomp changes, expect:

- the project builds
- the game starts
- dispatch misses are empty or unchanged for a known reason
- coverage did not regress, if the project reports coverage
- the debug server still answers, if the project has one
- the relevant route was observed

If the agent cannot run a check because it lacks a game file, BIOS, oracle, or platform tool, it should say that clearly.

## Match the check to the claim

| Claim | Useful proof |
|---|---|
| The code compiles. | Build log. |
| Generated output is stable. | Idempotent regeneration. |
| All needed code was found. | Empty dispatch-miss report. |
| The port stayed static. | Coverage report with no unexpected fallback. |
| Native matches reference behavior. | Co-simulation or oracle comparison. |
| The screen looks right. | Screenshot, frame dump, or visual smoke test. |
| Input works. | TCP input, scripted route, or hands-on route. |
| Performance improved. | Repeatable timing with the same route and settings. |
| A release is clean. | Allowlist package check. |

The wrong proof is a weak proof, even when it is real.

## Dispatch misses

Check the dispatch-miss artifact after every run.

The filename varies by project. The rule does not: a miss can skip game logic silently. Empty is clean. Non-empty is a blocker unless the project has already documented that exact miss as expected.

Resolve misses before debugging later symptoms.

## Coverage and fallback

Some frameworks can fall back to an interpreter or dynamic path when static coverage is incomplete.

That can help during bring-up. It is still weaker than native static execution.

When a project has a coverage report, read it. Do not call a port finished because it reached gameplay while important code was interpreted.

## Co-simulation

Co-simulation compares the native build against an oracle.

It is strongest when the route is deterministic. Attract demos are useful early because they often run without input and still exercise real game behavior.

Input timing can cause divergence. If native and oracle receive input at different hardware points, they may disagree even when both implementations are correct.

If a game has random behavior in an attract path, find the seed or make both sides use the same starting state before trusting the comparison.

## TCP debug checks

TCP debug servers are useful because recomp clients restart constantly.

A simple TCP client can disconnect, reconnect, and continue after each rebuild or crash.

Useful TCP checks include:

- `ping`
- registers
- memory reads
- screenshots or frame capture
- input for menus and basic movement
- trace queries
- dispatch-miss queries

TCP input is good for menus, simple button presses, and non-timing-sensitive movement. It is not a replacement for skilled gameplay testing.

## Visual checks

Use screenshots or frame capture when the claim is visual.

For AI review, capture the actual game output when possible. A debug buffer may miss a high-resolution renderer layer, post-processing, or final presentation.

If the project has multiple capture paths, use the one closest to what the player sees.

## Performance checks

Performance needs repeatability.

Use the same route, same build type, same settings, and similar host conditions. Run more than once.

For later systems, optimization is usually not one pass. It can take weeks of profiling and focused fixes. Avoid claiming victory from one faster boot unless that was the exact target.

## Packaging checks

Before a release, inspect the archive.

It should contain the app and allowed assets. It should not contain game files, retail BIOS files, local dumps, private saves, scratch captures, or debug leftovers.

Prefer allowlist packaging tools over zipping a build directory.

## What the agent should report

The final report should include:

- commands run
- results
- files changed
- assumptions
- missing inputs
- remaining risk

This is how the next person avoids repeating the same experiment.

---

# How AI breaks recomp projects

> The common ways AI-generated recomp changes fail even when the build looks fine.

- Canonical URL: https://retroportingtoolkit.com/docs/agents/failure-modes
- Markdown: https://retroportingtoolkit.com/docs/agents/failure-modes.md
- Section: Working with AI agents
- Page type: reference
- Tags: Agents, Correctness, Verification
- Last updated: 2026-08-30

---

AI is good at producing plausible code quickly.

That is exactly why it can be dangerous here. Recomp projects fail quietly. The game may boot. The diff may look reasonable. The failure may still be real.

Use this page as a review checklist.

## Common failure shapes

| What you see | What it may mean |
|---|---|
| One behavior never happens. | A dispatch miss skipped a subroutine. |
| A fix disappears later. | The agent edited generated output. |
| The fix only works for one game. | A framework bug was hidden in game config. |
| Tests pass but the game is wrong. | The test did not cover the route, or it skipped. |
| Native and oracle diverge at different places on each run. | The route is not deterministic, or input timing changed. |
| Two implementations agree on a wrong value. | They share the same bug, or the checker is broken. |
| A visual bug appears after a timing tweak. | The timing tweak changed real game behavior. |
| A release archive is too large or suspicious. | It may include generated junk or forbidden inputs. |

Start with the quiet failures. They are the ones AI is most likely to explain away.

## Dispatch misses

A dispatch miss is a blocking bug.

The runtime tried to call an address that has no generated function. Depending on the framework, it may log the miss, fall back, or skip the call.

Skipping is the dangerous case. The game can keep running while missing real logic.

Make the agent check the miss artifact before debugging the symptom.

## Generated output edits

Generated output is temporary.

If the agent patches it by hand, the next regeneration removes the fix. The project also loses the durable explanation of the bug.

The correct fix belongs in the generator, runtime, or config.

## One-game fixes

Sometimes a one-game fix is correct. Many times it is a framework bug wearing a local patch.

Ask what the fix means:

- Is this a real property of this game?
- Is this a code pattern the recompiler should discover?
- Will the next game need the same special case?
- Is this becoming a table of hand-entered addresses?

If the answer points at the framework, make the agent fix the framework.

## False green

A green build is weak evidence.

A green test suite is stronger, but only proves what the suite actually ran. Check for skipped tests and missing private inputs. A visual smoke test that skipped because screenshots were absent did not test visuals.

Read the details, not just the summary.

## Bad alignment

Do not compare two runs at "frame 500" unless frame 500 means the same thing on both sides.

Use hardware events or known synchronization points. This is especially important for systems with multiple CPUs, DMA, timers, audio, or link hardware.

Bad alignment creates fake divergences.

## Input timing

Input is part of the state.

If native and oracle receive input at different times, they may diverge even when both implementations are correct.

Attract demos are useful because they often need no input. Scripted input is useful when delivered at a precise, repeatable point. Manual input is useful for exploration, but weak for proof.

## Broken tools

If a screenshot command returns black, that does not prove the screen is black.

If a trace misses an event you know happened, that does not prove the event did not happen.

Fix or replace the tool before making claims from it.

## Timing optimizations

Faithful timing is usually the safe default.

A game-specific timing reduction may improve performance. It may also introduce softlocks, races, animation bugs, input bugs, or audio drift.

Treat timing changes as advanced and local to one game unless evidence proves the rule transfers.

## Packaging mistakes

Do not let an agent zip a build folder blindly.

Release archives should be assembled from an allowlist. They should not include game files, retail BIOS files, local dumps, private saves, scratch captures, or debug leftovers.

When in doubt, inspect the archive before uploading it.

---

# Debug surfaces agents can use

> The debug servers, logs, JSON outputs, traces, and scripts that make AI-assisted recomp work observable.

- Canonical URL: https://retroportingtoolkit.com/docs/agents/machine-surfaces
- Markdown: https://retroportingtoolkit.com/docs/agents/machine-surfaces.md
- Section: Working with AI agents
- Page type: reference
- Tags: Agents, Tooling, Verification
- Last updated: 2026-08-30

---

An agent should not rely only on the game window.

Recomp projects often expose machine-readable surfaces: TCP debug servers, JSON reports, trace files, screenshots, input hooks, and test exit codes.

These surfaces let the agent observe the running game without guessing.

## Useful surfaces

| Surface | What it gives |
|---|---|
| TCP debug server | Live queries against a running build. |
| Screenshot or frame capture | Visual output for human or AI review. |
| Input commands | Basic menu navigation and simple actions. |
| Dispatch-miss artifact | Missing generated functions. |
| Coverage report | Static coverage, interpreter fallback, healed code, and similar status. |
| Trace ring | Recent hardware, memory, CPU, or renderer events. |
| JSON or JSONL output | Structured logs for scripts and diffs. |
| Exit codes | Pass, fail, or skip status for automation. |
| Ghidra MCP | Disassembly and annotations when static analysis is needed. |

Use the surface that answers the question. A visual screenshot does not prove a timing claim.

## TCP debug servers

TCP is a good fit for recomp work because clients restart constantly.

During development, the user may rebuild, relaunch, crash, and relaunch again. A simple TCP client can disconnect and reconnect cleanly. Heavier harnesses may handle repeated process restarts worse.

Most TCP servers use newline-delimited JSON:

- one request per line
- one response per line
- `ok: true` for success
- `ok: false` for failure

Older servers do not all spell errors the same way. A client should handle both `error` and `err`.

## What TCP can drive

TCP input is useful for:

- pressing Start or A
- moving through menus
- clearing dialogs
- walking in a straight line
- taking repeatable screenshots
- letting an AI compare visible output

It is not enough for intense gameplay, tight timing, or subtle player control unless the project has a precise input script system.

## Screenshots and frame capture

Prefer a capture path that represents what the player actually sees.

Some projects expose multiple capture modes. A raw framebuffer may miss a high-resolution renderer layer, post-processing, or final presentation.

If the visual claim is important, use the best capture path the project provides.

## Trace rings

Trace rings are strongest when they are always on.

The agent can run the game, see a bug, then ask what happened before it. That is better than arming a trace and hoping the same timing happens again.

Useful rings include:

- CPU history
- memory writes
- DMA events
- renderer events
- input events
- dispatch misses
- timing counters

Query the narrowest useful range. Huge dumps are slow and hard to read.

## JSON output

Structured output is for scripts and comparison tools.

Good JSON output has stable fields and small records. JSONL is useful for traces because each event is one line.

If a project adds a new machine-readable output, document:

- how to enable it
- where it writes
- whether it is always on
- what one record means
- whether it changes timing

## Exit codes

Scripts should return useful exit codes.

At minimum:

| Code | Meaning |
|---|---|
| `0` | Success. |
| non-zero | Failure. |
| `77` | Skipped when running under CTest. |

If a tool uses more detail, document it near the tool. Do not make another project guess.

## Ghidra MCP

Use Ghidra when the question requires disassembly or data structure work.

Prefer the configured headless MCP workflow for these projects. Do not launch the GUI just to inspect a function.

Ghidra is not runtime proof. It can explain what the original code should do. The agent still needs to prove the recompiled build does it.

## When a surface is missing

If a project lacks the query the agent needs, add it to the debug surface when that is reasonable.

Do not hide one-off evidence in a private script or a console print that disappears after the session. The next person should be able to ask the same question.

---

# Making AI contributions reviewable

> How to keep AI-assisted recomp work auditable, testable, and easy for a maintainer to accept or reject.

- Canonical URL: https://retroportingtoolkit.com/docs/agents/contributing-as-an-agent
- Markdown: https://retroportingtoolkit.com/docs/agents/contributing-as-an-agent.md
- Section: Working with AI agents
- Page type: guide
- Tags: Agents, Conventions
- Last updated: 2026-08-30

---

AI-assisted work should be easy to review.

That does not mean the diff has to be small. It means the maintainer can tell what changed, why it changed, what proved it, and what remains unproven.

If the work cannot be reviewed, it is not ready.

## Before work starts

The agent should report the ground rules before editing:

- which repository it is in
- whether it is a framework repo or game repo
- whether a submodule is involved
- which local instruction files exist
- which required files are missing
- which checks can run locally

This catches a common mistake early: applying rules from the wrong repository.

## Commit policy

Do not let an agent invent a commit policy.

Some repositories want commits only when the user explicitly asks. Some want evidence committed next to code. Some require framework commits before game-repo submodule bumps.

When the repo is silent, the safe default is:

- make the change
- run the best available checks
- show the diff and results
- wait for explicit approval before committing

That matches the review flow most users expect.

## What never belongs in a change

Do not accept a change that adds:

- game files
- retail BIOS files
- disc images
- extracted private assets
- private saves or memory cards
- local dumps or scratch captures
- large diagnostic logs
- generated build output, unless the project explicitly tracks it

Be careful with generated code. Some projects ship compiled derived code as part of a release. That is not the same as committing uncompiled generated source from a user's game file. Avoid broad statements. Follow the project's release policy.

## What never counts as proof

These are weak claims:

- "it builds, so it works"
- "the screen looks fine"
- "the tests pass" without checking skips
- "the code path probably cannot happen"
- "the generated output looked reasonable"
- "the agent compared it to its memory of the system"

Ask for the proof that matches the claim. The [verification page](https://retroportingtoolkit.com/docs/agents/verification-rituals.md) has the checklist.

## Handoff format

When work is not finished, the handoff is the deliverable.

Use this shape:

```markdown
# Handoff: <what this session worked on>

## Where this runs
Repository, branch, commit, and required local files.

## What changed
Short list of touched areas.

## What is proven
One claim per line, with the command, trace, screenshot, or oracle result that proves it.

## What is not proven
Missing checks, missing files, skipped tests, or routes not run.

## What is not the problem
Things already ruled out, with the evidence.

---

# When an agent cannot run the game

> What AI-assisted work can and cannot prove without the game file, BIOS, display, or oracle.

- Canonical URL: https://retroportingtoolkit.com/docs/agents/when-you-cannot-run-the-game
- Markdown: https://retroportingtoolkit.com/docs/agents/when-you-cannot-run-the-game.md
- Section: Working with AI agents
- Page type: guide
- Tags: Agents, Verification, Testing
- Last updated: 2026-08-30

---

Sometimes the agent cannot run the game.

That may be fine. A clean clone often lacks the user's game file, BIOS file, display access, oracle setup, or local debug tools.

The rule is simple: the agent can still do useful work, but it must not claim proof it does not have.

## What may be missing

| Missing item | What it prevents |
|---|---|
| Game file | Regeneration, launch, runtime identity checks, gameplay verification. |
| BIOS or firmware | Boot paths for systems that require one. |
| Display or capture path | Visual claims. |
| Oracle or reference process | Correctness comparison. |
| Ghidra or disassembly access | Some code-discovery and reverse-engineering work. |
| Compiler or SDK | Build verification. |

Each missing item removes a class of claim. It does not make guessing acceptable.

## What the agent can still do

Without the game, an agent may still:

- read and explain code
- improve docs
- build framework-only tools
- run unit tests that need no private files
- check packaging scripts
- inspect config structure
- add or improve debug commands
- write a handoff for a human who can run the game

That work can be valuable. It just needs honest boundaries.

## What the agent cannot claim

Without a real run, do not accept claims like:

- the bug is fixed
- the port is playable
- dispatch misses are empty
- coverage is complete
- native matches the oracle
- timing is correct
- the visual output is correct
- the release works end to end

The agent can say "this builds" only if it built. It can say "this should be checked by running X" if it could not run X.

## Existing artifacts are not fresh proof

A log, screenshot, trace, or dispatch-miss file already in the tree is evidence about an earlier run.

It is not evidence about the current change unless the agent produced it during this session or can prove it matches the current build.

This is a common false pass. Avoid it.

## Useful partial checks

| Check | What it proves |
|---|---|
| Build | The compiler accepted the code. |
| Unit tests | The covered host logic still passes. |
| Static inspection | The diff follows project structure. |
| Package inspection | The archive or script excludes forbidden files. |
| Config validation | Required fields are present and coherent. |
| Tool wiring | A debug command is registered, documented, and callable in principle. |

Phrase the result narrowly.

## What to write down

If the agent cannot finish verification, require a handoff with:

- the exact missing resource
- what was checked anyway
- commands that were run
- tests that skipped
- the command a human should run next
- what output would confirm the change
- what output would refute it

This is not failure. It is an honest stop.

## When to stop

Stop and hand off when:

- the repo requires a tool the agent cannot access
- the change touches hardware behavior and no oracle check can run
- the change touches timing and no route can be tested
- the framework instructions are missing
- required private files are unavailable

Do not let the agent fill the gap with confidence.

---

# Reference

> Lookup pages for commands, configuration, debug protocols, statuses, and site tools.

- Canonical URL: https://retroportingtoolkit.com/docs/reference
- Markdown: https://retroportingtoolkit.com/docs/reference.md
- Section: Reference
- Page type: reference
- Tags: Reference
- Last updated: 2026-08-31

---

Reference pages are for exact names and rules.

Use them when you already know the topic and need the field, flag, command, status word, or protocol shape.

- [Command line reference](https://retroportingtoolkit.com/docs/reference/cli.md). Common command shapes and what the flags mean.
- [TCP debug protocol](https://retroportingtoolkit.com/docs/reference/tcp-protocol.md). How the debug servers talk over localhost.
- [Configuration](https://retroportingtoolkit.com/docs/reference/configuration.md). What belongs in project config and runtime config.
- [Catalog schema](https://retroportingtoolkit.com/docs/reference/catalog-schema.md). Launcher catalog fields. Skipped here pending TechnicallyComputers sign-off.
- [Status vocabulary](https://retroportingtoolkit.com/docs/reference/status-vocabulary.md). What status and maturity words mean on this site.
- [Site tools](https://retroportingtoolkit.com/docs/reference/site-tools.md). Browser-exposed tools for agents. Skipped here pending tetrisgm sign-off.

Do not treat a reference page as a tutorial. If you need the workflow, start with [Guides](https://retroportingtoolkit.com/docs/guides.md).

---

# Command line reference

> A practical map of the command line tools: what each class of tool does, when to use it, and which flags matter most.

- Canonical URL: https://retroportingtoolkit.com/docs/reference/cli
- Markdown: https://retroportingtoolkit.com/docs/reference/cli.md
- Section: Reference
- Page type: reference
- Tags: CLI, Reference, Tooling
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/psxrecomp
  - https://github.com/mstan/nesrecomp
  - https://github.com/mstan/snesrecomp
  - https://github.com/mstan/gbarecomp
  - https://github.com/mstan/segagenesisrecomp
  - https://github.com/mstan/smsggrecomp
  - https://github.com/mstan/ndsrecomp
  - https://github.com/mstan/cdirecomp
  - https://github.com/mstan/vbrecomp

---

This page is a map, not a dump of every flag in every repository.

The exact command line changes as the toolchains move. Use the project you are building as the final authority, and use `--help` when a command accepts it.

The useful part here is the shape: which tool you are running, what file it expects, and what output it should produce.

## What kinds of tools exist?

Most repositories have some mix of these:

| Tool kind | What it does |
|---|---|
| Recompiler | Reads game or BIOS machine code and writes generated C or C++. |
| Runtime | Runs the generated code and models the console around it. |
| Builder | Wraps CMake, Ninja, emitters, and project setup. |
| Debug client | Talks to a running port through TCP. |
| Packager | Creates a release archive from allowlisted files. |
| Oracle harness | Runs a trusted reference beside the port for comparison. |

If you are not sure which one you need, start from the guide instead of this page: [Build a toolchain](https://retroportingtoolkit.com/docs/guides/build-a-toolchain.md) or [Port a game](https://retroportingtoolkit.com/docs/guides/port-a-game.md).

## What files do commands usually ask for?

Common inputs are:

| Input | Meaning |
|---|---|
| Game file | The ROM, disc image, or executable you legally provide. |
| BIOS or firmware | A legally obtained system file, if the platform needs one. |
| `game.toml` | Per-game configuration: identity, entry points, output paths, runtime settings. |
| Seeds or symbols | Hints that tell the recompiler where functions and labels are. |
| Output directory | Where generated code or a new project should be written. |

This site does not provide game files or copyrighted retail BIOS files.

## PlayStation reference shape

psxrecomp is the clearest command-line reference today.

A normal developer flow looks like:

1. verify the disc;
2. generate code;
3. build the runtime;
4. run the port;
5. use TCP tools when debugging.

The important commands are grouped around those jobs:

| Command | Job |
|---|---|
| `psxrecomp build` | Create a new project from a disc and BIOS path. |
| `psxrecomp_cli.py verify-disc` | Check that the disc matches what the project expects. |
| `psxrecomp_cli.py generate` | Prepare inputs and regenerate code. |
| `psxrecomp_cli.py rebuild` | Run the CMake build. |
| `psx-runtime` | Launch the built port. |
| `tools/debug_client.py` | Send TCP debug commands to a running port or oracle. |

The common flags are the ones you would expect: `--disc`, `--bios`, `--config`, `--build-dir`, `--target`, `--debug-port`, and `--headless`.

## Other console shapes

Other systems follow the same broad pattern, but maturity differs.

| Platform | Usual command shape |
|---|---|
| NES | Build a small recompiler, pass a `.nes` file and optional game config, then build a game runner. |
| SNES | Pass a `.sfc` or `.smc` file to a project/tool wrapper, then build the generated project. |
| Game Boy Advance | Pass a `.gba` file, config, symbols, and output directory; some projects also involve BIOS handling. |
| Sega Genesis | Pass a Genesis/Mega Drive cartridge dump and `game.toml`, then build the runner. |
| Master System and Game Gear | Pass a cartridge dump and game config; this path is still tech-demo level. |
| Nintendo DS | Pass BIOS, firmware, and title data through project-specific commands; this path is alpha-stage. |
| Virtual Boy | Pass a Virtual Boy cartridge dump; the public path is still a one-game tech demo. |
| CD-i | BIOS-focused research commands; not a normal game-port route yet. |

When a platform is early, the command line is more likely to change. Do not build long-term instructions around one old command.

## How should I run commands safely?

Use these rules:

- clone with submodules when the project uses them;
- keep game files outside framework repositories;
- use release-style builds unless you are debugging;
- use fewer build jobs if generated code exhausts memory;
- keep exact commands in scripts once they work;
- do not edit generated code by hand.

A failed command is usually most useful at the first error. Later errors may only be consequences.

## How do debug commands fit in?

Debug clients usually talk to a running port over TCP.

The client sends a command like `ping`, `screenshot`, `read_ram`, or `get_registers`. The runtime answers with JSON.

That is the right tool for AI-assisted debugging too. The AI can capture a screen, press simple inputs, read state, and compare results without relying only on text logs.

See [TCP debug protocol](https://retroportingtoolkit.com/docs/reference/tcp-protocol.md) for the transport and [Debug a divergence](https://retroportingtoolkit.com/docs/guides/debug-a-divergence.md) for the workflow.

## When should I use a packager?

Use a packager when another person will download the result.

Do not zip a build folder by hand. A build folder can contain local files that should never ship.

A good package command copies only allowlisted files and rejects ROMs, disc images, retail BIOS files, generated source, logs, and local config.

See [Release a port](https://retroportingtoolkit.com/docs/guides/release-a-port.md).

---

# TCP debug protocol

> How debug clients talk to running ports: one localhost TCP socket, one JSON command per line, and simple commands for state, screenshots, input, and comparison.

- Canonical URL: https://retroportingtoolkit.com/docs/reference/tcp-protocol
- Markdown: https://retroportingtoolkit.com/docs/reference/tcp-protocol.md
- Section: Reference
- Page type: reference
- Tags: Protocol, Debugging, Agents, Tooling
- Last updated: 2026-08-30
- Source repositories:
  - https://github.com/mstan/psxrecomp
  - https://github.com/mstan/nesrecomp
  - https://github.com/mstan/gbarecomp
  - https://github.com/mstan/ndsrecomp
  - https://github.com/mstan/vbrecomp
  - https://github.com/mstan/cdirecomp
  - https://github.com/mstan/segagenesisrecomp
  - https://github.com/mstan/smsggrecomp

---

Most mature ports expose a small TCP debug server.

A tool connects to `127.0.0.1`, sends one command, and reads one response. The command can ask for registers, memory, screenshots, input state, timing, or recent trace data.

This is a development surface. It is not meant to be a polished player feature.

## Why TCP?

TCP is boring, and that is the point.

Debug work restarts processes constantly. Ports crash. Oracles restart. Harnesses launch new pairs over and over.

A plain TCP client can reconnect after each restart. A longer-lived tool session, such as MCP, is more likely to be confused by a process disappearing underneath it.

For these harnesses, TCP is usually the more reliable choice.

## What does a request look like?

The common shape is one JSON object per line:

```json
{"cmd":"ping"}
```

A response is also one JSON object:

```json
{"ok":true}
```

Many commands take extra fields:

```json
{"cmd":"read_ram","addr":4096,"len":32}
```

Some older servers also accept a bare word like `ping`. Prefer JSON for anything with arguments.

## What should a client expect?

Expect these rules unless a project says otherwise:

| Rule | What it means |
|---|---|
| Localhost only | The server listens on `127.0.0.1`. |
| One line in, one line out | Newline framing keeps clients simple. |
| One client at a time | A second client may fail or steal the session. |
| Not sub-frame | Most servers are pumped once per frame or from the main loop. |
| JSON success flag | Read `ok` before trusting any other field. |
| Two error spellings | Some servers return `error`; others return `err`. Handle both. |

Do not assume every command exists everywhere. Each console has its own hardware, so each server grows its own command set.

## What are the common commands?

Common command families are:

| Family | Examples |
|---|---|
| Heartbeat | `ping`, `status`, `frame` |
| CPU state | `get_registers`, `regs` |
| Memory | `read_ram`, `read_mem`, `read_region` |
| Video | `screenshot`, `framebuffer`, `read_vram` |
| Input | `set_input`, `press`, `clear_input`, `keys`, `touch` |
| History | `history`, `get_frame`, `frame_range`, trace rings |
| Comparison | `state_hash`, `frame_diff`, `memory_diff`, subsystem diffs |
| Missed code | `dispatch_miss_info`, dispatch-miss logs |
| Control | `pause`, `continue`, `step`, `run_to_frame`, `quit` |

The names are not perfectly consistent. Treat this table as a vocabulary guide, not a promise that every command exists on every platform.

## How does input help?

TCP input is useful for simple, repeatable actions.

An AI or script can:

- press Start on a title screen;
- move through menus;
- hold a direction for a few frames;
- capture screenshots before and after an action;
- verify that a basic screen transition happened.

It is not a replacement for real playtesting. Tight platforming, combat, rhythm, and timing-sensitive gameplay still need a person or a purpose-built input script.

## How does this help co-simulation?

Co-simulation needs two machines to answer the same questions.

One process is the port. The other is the reference. The coordinator asks both for state at the same guest-time checkpoint and compares the answers.

The two servers do not need every command in the world. They need matching commands for the state the harness compares.

See [Set up co-simulation](https://retroportingtoolkit.com/docs/guides/set-up-co-simulation.md).

## What should not go through TCP?

Avoid using TCP as a dumping ground.

If a response is huge, write it to a file and return the filename. Large socket responses can stall the main loop and create fake performance problems.

Also keep observer effects out of recorded guest state. A debug read should not appear as if the game itself touched memory.

## What if a command is missing?

Add the tool surface you need.

Do not work around missing visibility by adding one-off print statements everywhere. A repeated debugging question deserves a real command.

When adding a command, keep it small:

1. add the handler;
2. register the command;
3. mirror it on the oracle if co-simulation needs it;
4. document the request and response shape;
5. rebuild and test the debug path.

---

# Configuration

> How configuration is split between game files, runtime settings, player overrides, BIOS choices, environment variables, and build options.

- Canonical URL: https://retroportingtoolkit.com/docs/reference/configuration
- Markdown: https://retroportingtoolkit.com/docs/reference/configuration.md
- Section: Reference
- Page type: reference
- Tags: Configuration, PlayStation, TOML
- Last updated: 2026-08-31
- Source repositories:
  - https://github.com/mstan/psxrecomp

---

Configuration is how a port records decisions.

Some settings describe the game. Some describe the runtime. Some are player choices. Some are build-time switches.

Keep those layers separate. A setting in the wrong layer becomes confusing fast.

## Which file owns what?

A typical PlayStation-style project has these layers:

| Layer | What it owns |
|---|---|
| BIOS profile | Facts about a BIOS image and how it maps into memory. |
| Game config | Facts about this game and this port. |
| Runtime settings | Defaults for video, audio, input, saves, debug ports, and BIOS behavior. |
| Player settings | The player's local choices. |
| Mod state | Which optional features are enabled. |
| Environment variables | Temporary overrides for a run or build. |
| CMake options | Build-time feature switches. |

Do not use one layer as a junk drawer for another.

## What belongs in game config?

The game config should describe the port.

Common fields include:

- game name;
- serial or game id;
- disc or executable path;
- load address;
- entry point;
- text size;
- stack base;
- seed files;
- generated output directory;
- runtime defaults;
- debug port.

These are project facts. If changing the value changes what the port is, it probably belongs in `game.toml`.

## What belongs in a BIOS profile?

A BIOS profile describes a BIOS image.

It can include:

- display name;
- image id;
- ROM path;
- load address;
- entry PC;
- image size;
- expected hash;
- copy windows;
- exported runtime anchors.

A BIOS profile should not be used for player preferences. It is a description of an image, not a settings screen.

## What belongs in player settings?

Player settings are local preferences.

Examples:

- selected renderer;
- aspect ratio;
- fullscreen or windowed behavior;
- controller choices;
- language selection;
- selected BIOS path, when allowed.

A player setting should not change the identity of the port or the game file it targets.

## What about BIOS choices?

Use a legally obtained BIOS when a project requires one. This site does not provide retail BIOS files.

Some projects can use open-source BIOS alternatives where appropriate. That does not make every retail BIOS path irrelevant.

A good project is clear about:

- whether a BIOS is required;
- whether an open-source BIOS can be used;
- which retail BIOS dumps are supported;
- whether saves or states depend on the BIOS choice.

## What about widescreen and enhancements?

Enhancement settings should not change the faithful default.

For video options, the original view depends on the system.

Many older TV consoles target a 4:3 display. Game Boy Advance is closer to 3:2. Newer consoles may have 4:3 and 16:9 modes. Multi-screen systems, such as Nintendo DS, are different again.

The safe rule is not one aspect ratio. The safe rule is that the default view should match the original system and game.

Widescreen, frame interpolation, higher internal resolution, and similar features should be opt-in. They may need game-specific configuration and testing.

See [Add widescreen](https://retroportingtoolkit.com/docs/guides/add-widescreen.md).

## What wins when settings conflict?

A common runtime order is:

`environment > command line > player settings > game config > compiled default`

That order is useful because temporary choices stay temporary.

Build-time settings are different. A CMake option can change what code exists in the binary, so a runtime setting may not be able to turn it back on.

## What should environment variables do?

Use environment variables for temporary developer control.

Good uses include:

- selecting an overlay backend;
- forcing or disabling a debug path;
- setting a co-simulation stride;
- changing a cache directory;
- pinning time or randomness for a deterministic run.

Do not require normal players to manage environment variables for basic play.

## What should CMake options do?

CMake options should describe the build.

Examples:

- include debug tools;
- choose SDL backend;
- enable Vulkan support;
- build a setup wizard;
- choose which generated BIOS backends are linked.

If a feature is not compiled in, a runtime config file cannot reliably enable it later.

## What makes a config good?

A good config is:

- explicit;
- versioned with the port;
- checked against exact game files;
- small enough to review;
- separated by responsibility;
- regenerated only from known inputs;
- strict when a mismatch would be dangerous.

A loose config may feel easier during bring-up, but it can hide the bug you most need to find.

---

# Catalog schema

> How the launcher catalog describes ports, required game files, releases, launch settings, and compatibility in a form tools can read.

- Canonical URL: https://retroportingtoolkit.com/docs/reference/catalog-schema
- Markdown: https://retroportingtoolkit.com/docs/reference/catalog-schema.md
- Section: Reference
- Page type: reference
- Tags: Schema, Catalog, Launcher
- Last updated: 2026-08-31
- Source repositories:
  - https://github.com/TechnicallyComputers/retcomm-catalog

---

The catalog is the list a launcher can read when it wants to know what ports exist.

It is not the port itself. It is not a game database for every retro game. It is a small set of JSON files that answer practical questions:

- What is this port called?
- What system is it for?
- What game file does the user need to provide?
- Does it need a BIOS or firmware file?
- Where can the launcher get a release?
- How should the launcher start it?

The catalog should be boring on purpose. If a launcher has to guess, the schema did not do its job.

## The two file types

The catalog has one root file and one file per title.

| File | What it does |
|---|---|
| `index.json` | Lists the catalog version, platform defaults, and every title id. |
| `titles/<id>.json` | Describes one port. |

The title id should match in three places:

- the entry in `index.json`
- the filename under `titles/`
- the `id` field inside that title file

That keeps launcher behavior simple. A tool should not need fuzzy matching to load a catalog entry.

## `index.json`

`index.json` is the catalog table of contents.

| Field | Meaning |
|---|---|
| `schema_version` | The catalog format version. |
| `name` | A display name for the catalog. |
| `catalog_date` | When this catalog was published. |
| `release_tag` | The release tag that produced this catalog. |
| `platform_defaults` | Defaults shared by entries on the same platform. |
| `titles` | The list of title ids. Each id should have a matching `titles/<id>.json`. |

Platform defaults are useful when many ports on the same system need the same BIOS identity. A title can override that default, or opt out when it does not apply.

## Title identity

Every title manifest needs enough identity to show a human what the port is.

| Field | Meaning |
|---|---|
| `id` | Stable slug. Use lowercase letters, numbers, and hyphens. |
| `name` | Human-readable title. |
| `kind` | Usually `recomp`. Some entries may be `decomp`. |
| `platform` | The system family, such as `psx`, `snes`, `nes`, `gba`, `nds`, `genesis`, `smsgg`, `vb`, or `cdi`. |
| `description` | Short description for launchers and catalog views. |
| `homepage` | Project or release page. |
| `author_notes` | Optional note from the port author. |
| `notes` | Maintainer notes for the catalog. |

Keep descriptions short. The catalog is not where the project history belongs.

## Game file identity

The catalog uses hashes, sizes, serials, and filename hints to recognize the game file the user provides.

It does not include that game file. The user supplies their own legally obtained dump. This site does not provide game files and does not tell users how to get them.

| Field | Meaning |
|---|---|
| `rom_identity` | The checks used to recognize the correct game file. |
| `rom_identity.crc32` | CRC32 hashes, if useful. |
| `rom_identity.md5` | MD5 hashes, if useful. |
| `rom_identity.sha1` | SHA-1 hashes, if useful. |
| `rom_identity.sha256` | SHA-256 hashes, if useful. |
| `rom_identity.disc_serials` | Disc serials for systems where that is useful. |
| `rom_identity.sizes` | Expected file sizes. Useful before hashing large files. |
| `rom_identity.filenames` | Filename hints. These help the user, but should not be the only match rule. |
| `rom_identity.track_counts` | Expected track counts for disc images. |
| `rom_identity.require_cue` | Whether the entry requires a cue sheet. |
| `rom_extensions` | File extensions the launcher should scan for this entry. |

A manifest should contain at least one real identity check. A filename alone is not enough.

## BIOS identity

Some systems need a BIOS or firmware file.

Use a legally obtained BIOS if one is required. This site does not provide retail BIOS files. Some projects may provide open source BIOS alternatives where that makes sense.

| Field | Meaning |
|---|---|
| `bios_identity` | The checks used to recognize the BIOS or firmware file. |
| `bios_identity.required` | Whether the file is required. |
| `bios_identity.crc32`, `md5`, `sha1`, `sha256` | Hashes for known good files. |
| `bios_identity.sizes` | Expected file sizes. |
| `bios_identity.filenames` | Filename hints shown to the user. |

A platform default can define common BIOS rules. A title manifest should only override it when that specific title needs something different.

## Release information

Release fields tell a launcher where to find the build.

| Field | Meaning |
|---|---|
| `release.github` | Repository that publishes the release. |
| `release.tag` | Release tag to use, when fixed. |
| `release.asset_patterns` | Asset names the launcher should look for. |
| `release.prerelease` | Whether prereleases are allowed. |
| `release.source_only` | Whether users must build it themselves. |

Be careful with release wording. Some projects can ship a ready-to-run build. Some require the user to build locally after providing their own game file. The catalog should describe the distribution model without making legal claims beyond what the project actually does.

## Build and launch information

Build fields are for source-only entries. Launch fields are for installed builds.

| Field | Meaning |
|---|---|
| `build` | How a launcher or tool should build the port. |
| `build.system` | The build system, such as CMake. |
| `build.commands` | Commands to run. |
| `launch` | How to start the installed port. |
| `launch.executable` | Main executable or relative executable path. |
| `launch.args` | Arguments the launcher should pass. |
| `launch.working_dir` | Working directory to use. |

Do not hide important setup inside prose. If a launcher needs it, make it structured.

## Compatibility and extras

Optional sections describe features that a launcher may show or use.

| Field | Meaning |
|---|---|
| `status` | Short status label for the port. |
| `availability` | Whether a build is public, source-only, or unavailable. |
| `saves` | Save file locations or save behavior. |
| `enhancements` | Optional features such as widescreen, renderer work, or quality settings. |

These fields should stay factual. A launcher needs to know what exists, not why the project is exciting.

## Safe schema rules

Use structured fields for anything a tool must act on.

Keep human notes short.

Do not use markdown files in random repositories as the authority for catalog behavior. They are useful clues, but the catalog should carry the actual data a launcher needs.

When in doubt, prefer a smaller manifest that is correct over a large manifest full of guesses.

---

# Status vocabulary

> The words this site uses for project maturity, what they mean, and what they do not promise.

- Canonical URL: https://retroportingtoolkit.com/docs/reference/status-vocabulary
- Markdown: https://retroportingtoolkit.com/docs/reference/status-vocabulary.md
- Section: Reference
- Page type: reference
- Tags: Status, Vocabulary, Catalog
- Last updated: 2026-08-30

---

Status words are easy to overread.

`Playable` does not always mean finished. `Alpha` does not always mean useless. `Tech demo` does not always mean the idea failed.

This page explains how this site uses those words. It is a shared vocabulary for the site, not a legal guarantee and not a replacement for a project's own release notes.

## The two things we label

This site labels two different things.

| Label type | What it describes |
|---|---|
| Port status | How far one game port appears to be. |
| Platform maturity | How far the system-level framework appears to be. |

Do not mix them.

A game can be playable on an early framework. A framework can be strong while one game port is still rough.

## Port status

Port status describes one game.

| Status | Meaning | What it does not promise |
|---|---|---|
| Released | A public release exists. | That every mode is perfect. |
| Playable | The game can be played meaningfully. | Exhaustive testing. |
| Playable alpha | The game plays, but bugs and missing polish are expected. | A finished port. |
| Partial | Some important part works and some important part does not. | End-to-end play. |
| Tech demo | Enough works to prove the approach for that game. | A normal player experience. |
| Research | Investigation is happening. | That a playable build exists. |

If a page says exactly what was tested, believe that narrower statement first.

## Platform maturity

Platform maturity describes the recomp ecosystem for a system.

| Maturity | Meaning |
|---|---|
| Gold standard | The reference point for the rest of the ecosystem. Strong tooling, proven ports, and real outside usage. |
| Silver standard | Strong and useful, but not as broad or proven as the gold standard yet. |
| Alpha | Public and useful for real work, but still changing and still missing important polish or optimization. |
| Experimental | Can run real software in some cases, but the shape is still settling. |
| Tech demo | Exists to prove a path. Do not read it as a general porting platform yet. |
| Research | Earlier than a tech demo, or focused on discovery more than releases. |

Today, PlayStation is the gold standard reference. SNES is the silver standard reference. Other systems vary from alpha to tech demo depending on how much they can run and how much project support exists around them.

That ordering is practical, not emotional. It describes how much confidence a developer should have when starting work.

## Availability

Availability describes how a user can get the port.

| Availability | Meaning |
|---|---|
| Public build | A downloadable build is available. |
| Source only | The project is public, but the user builds it locally. |
| No public release | The work may exist, but there is no public build to use. |

Source-only is not automatically bad. Some projects choose it because users need to build from their own legally obtained game file.

## Read the smallest truthful claim

Prefer the narrowest claim on the page.

If a page says "playable through the intro", it is not playable end to end.

If a page says "one game boots", the platform is not ready for the whole library.

If a page says "known softlock", that softlock matters even when the card says `Playable alpha`.

Status words help you scan. Details still decide what you should expect.

## Avoid status inflation

Do not upgrade a status word because the idea is promising.

A port is not `Playable` because it boots. A platform is not `Alpha` because a technical demo exists. A public repository is not the same thing as a supported release.

Use plain words. Overstating maturity wastes the reader's time and creates support burden for the wrong people.

---

# Site tools

> The browser tools this site exposes to AI agents, what each one does, and why they are read-only except for drafts.

- Canonical URL: https://retroportingtoolkit.com/docs/reference/site-tools
- Markdown: https://retroportingtoolkit.com/docs/reference/site-tools.md
- Section: Reference
- Page type: reference
- Tags: Agents, WebMCP, Reference, Browser
- Last updated: 2026-08-30

---

This site exposes a small tool list for browsers that support page-provided AI tools.

The tools help an agent ask the site direct questions instead of scraping the page and guessing. They are for convenience and accuracy. They are not a private API for bypassing the site.

Most tools only read. One tool can draft a page, but it cannot publish.

## What a site tool is

A site tool is a named function registered by the page.

It has:

- a name
- a short description
- an input shape
- a result shape
- a handler that runs in the browser's page context

The browser remains in control. If your browser does not support these tools, the site still works normally.

## The tools

| Tool | What it does | Writes? |
|---|---|---|
| `search_site` | Searches games, platforms, articles, and docs. | No |
| `check_game_ported` | Checks whether this catalog already has a port for a game. | No |
| `list_platforms` | Lists supported platform pages and their maturity labels. | No |
| `get_page_markdown` | Returns one docs page as markdown. | No |
| `define_term` | Explains a glossary term. | No |
| `plan_my_port` | Gives a first-pass porting plan for a game and system. | No |
| `draft_page` | Creates a draft page for review. | Yes, draft only |

Every read result should include a URL when a page backs the answer. The user should be able to click through and check it.

## `search_site`

Use this when the user asks a general question about the site.

Example input:

```json
{ "query": "widescreen" }
```

Good results should be ranked and linked. A docs match should point near the matched heading when possible.

## `check_game_ported`

Use this before planning a new port.

Example input:

```json
{ "title": "street fighter alpha" }
```

The match is intentionally forgiving. Users do not always type exact punctuation, subtitles, or regional names.

`ported: false` means this site has no entry. It does not prove nobody has tried anywhere else.

## `list_platforms`

Use this when an agent needs the current platform list.

The result should include each platform page, status, maturity, and a short description. It should not include removed or unsupported systems.

Platform maturity is a guide for expectations. It is not a promise that every game on that system can be ported today.

## `get_page_markdown`

Use this when an agent needs the raw text of a docs page.

Example input:

```json
{ "path": "/docs/start/quickstart" }
```

Only documentation paths should be accepted. A tool like this should not fetch arbitrary websites or local files.

Users can also add `.md` to documentation URLs themselves.

## `define_term`

Use this for glossary terms.

Example input:

```json
{ "term": "co-simulation" }
```

The answer should be short and should link back to the glossary or the best matching concept page.

## `plan_my_port`

Use this for a first-pass plan.

Example input:

```json
{ "game_title": "Some Game I Own", "console": "PlayStation" }
```

The tool should check whether the game is already listed first. If it is already listed, it should point the user at that page instead of inventing a new plan.

For new work, the plan should say:

- which framework is the closest fit
- how mature that framework is
- whether scaffolding exists
- what files the user will need to legally provide
- what the first technical steps are

The result should stay honest. If a system is only a tech demo, the plan should say that plainly.

## `draft_page`

`draft_page` is the only writing tool.

It creates a draft for review. It does not publish, deploy, or silently replace an existing page.

Drafts should follow the same voice as the site:

- short paragraphs
- practical wording
- no giant code excerpts
- no source archaeology
- no claims the project cannot support

The user still decides what lands.

---

# The fleet

> Repository map, lineage, licensing, and provenance for the recomp ecosystem covered by this site.

- Canonical URL: https://retroportingtoolkit.com/docs/fleet
- Markdown: https://retroportingtoolkit.com/docs/fleet.md
- Section: The fleet
- Page type: reference
- Tags: Fleet
- Last updated: 2026-08-30

---

This section maps the projects behind the site.

Use it when you need to know where a project fits, who owns the work, what it depends on, or what can safely be claimed about its origin.

- [Every repository](https://retroportingtoolkit.com/docs/fleet/repositories.md). A repository map grouped by role.
- [Lineage and credit](https://retroportingtoolkit.com/docs/fleet/lineage-and-credit.md). How projects relate to each other and where credit belongs.
- [Licenses](https://retroportingtoolkit.com/docs/fleet/licenses.md). What the repositories declare, and where the license story is incomplete.
- [Provenance](https://retroportingtoolkit.com/docs/fleet/provenance.md). How projects record where code, behavior, and firmware knowledge came from.

This section should be factual, not promotional. It should help readers avoid misrepresenting ownership, support burden, or maturity.

---

# Every repository

> Repositories in the fleet, grouped by role, each linked and each attributed to the toolchain it belongs to, plus the dependency map showing which shared component is used by which project.

- Canonical URL: https://retroportingtoolkit.com/docs/fleet/repositories
- Markdown: https://retroportingtoolkit.com/docs/fleet/repositories.md
- Section: The fleet
- Page type: reference
- Tags: Fleet, Repositories, Index
- Last updated: 2026-08-31
- Source repositories:
  - https://github.com/mstan/psxrecomp
  - https://github.com/mstan/nesrecomp
  - https://github.com/mstan/snesrecomp
  - https://github.com/mstan/gbarecomp
  - https://github.com/mstan/recomp-ui
  - https://github.com/mstan/m68k-recomp-core
  - https://github.com/mstan/z80-recomp-core

---

The fleet includes per-console projects, shared components and game ports. Each one is listed here with its role and the toolchain it belongs to. That attribution is usually the first fact you need, and no single repository states it. For what a console's toolchain does rather than where it lives, read the [platform pages](https://retroportingtoolkit.com/docs/platforms.md).

Three shared components turned up only by resolving relative submodule URLs: `m68k-recomp-core`, `z80-recomp-core` and `recomp-ui`. No listing in the fleet shows them, and nothing else on this site links to them.

## Per-console projects

Most of these are a recompiler and a runtime for one machine. A game port is a thin repository on top of one of them. Status wording is each project's own, never upgraded.

| Repository | Console | What it is | Status in its own words |
|---|---|---|---|
| [mstan/psxrecomp](https://github.com/mstan/psxrecomp) | PlayStation | MIPS R3000A to C, translating both a BIOS image and the game executable, with disc-streamed overlays captured and compiled at run time | "The breadth-first push is essentially done; work now is depth and optimization." |
| [mstan/nesrecomp](https://github.com/mstan/nesrecomp) | NES | 6502 to C, plus a C runner library that simulates the PPU, APU, mapper and input | "This builds a static library. It does not create a playable game by itself." |
| [mstan/snesrecomp](https://github.com/mstan/snesrecomp) | SNES | 65816 to C against a C model of the rest of the console, with an interpreter kept live underneath as the correctness floor | "SNESRecomp is alpha software." |
| [mstan/gbarecomp](https://github.com/mstan/gbarecomp) | Game Boy Advance | ARM7TDMI, both ARM and Thumb, to sharded C++ against a shared GBA hardware runtime | "These projects are experimental previews and byproducts of developing the framework." |
| [mstan/segagenesisrecomp](https://github.com/mstan/segagenesisrecomp) | Sega Genesis | 68000 to native C, with the console's second processor, the Z80 sound CPU, handled by the runner | Per-feature table: 68K frontend "Active", sound Z80 static recompilation "Experimental" |
| [mstan/smsggrecomp](https://github.com/mstan/smsggrecomp) | Master System, Game Gear | One Z80 engine for both machines, the Game Gear being a platform flag rather than a fork | "**Status: early (v0.0.2) pre-release, expect bugs.**" |
| [mstan/vbrecomp](https://github.com/mstan/vbrecomp) | Virtual Boy | NEC V810 to C, plus a runtime, a TCP debug server and a Beetle VB oracle harness. No V810 interpreter exists in the project at all | The framework carries no status banner. Its downstream port states "**Status: Playable.**" |
| [mstan/ndsrecomp](https://github.com/mstan/ndsrecomp) | Nintendo DS | Both DS processors lifted to C ahead of time and interleaved on one event scheduler | "Status: very early pre-alpha (v0.0.1)" |
| [mstan/cdirecomp](https://github.com/mstan/cdirecomp) | CD-i | SCC68070 to C, recompiling and running the console's entire CD-RTOS system ROM rather than stubbing it | "Very early development" and "**Gameplay is not yet reachable.**" |

## Shared components

Separately versioned repositories that other projects consume as git submodules. The first three are the ones no listing shows.

| Repository | What it is | Consumed by |
|---|---|---|
| [mstan/m68k-recomp-core](https://github.com/mstan/m68k-recomp-core) | "Shared clean-room Motorola 68000-family static-recompiler frontend". A shared decoder, validator and annotation reader, plus two platform profiles, `genesis` and `scc68070`. Shipped as a source package, not a library, because it depends on consumer-owned headers | segagenesisrecomp, cdirecomp |
| [mstan/z80-recomp-core](https://github.com/mstan/z80-recomp-core) | "Shared Zilog Z80 static-recompiler runtime contract and verified instruction semantics". The decoder and C emitter still live in smsggrecomp; this is the platform-neutral layer their output consumes | segagenesisrecomp, smsggrecomp |
| [mstan/recomp-ui](https://github.com/mstan/recomp-ui) | "A shared, **console-agnostic launcher and in-game settings UI** for static-recompilation game ports." One Dear ImGui core, composed per console from a single profile row | 58 game ports across eight consoles |
| [TechnicallyComputers/retcomm-rbengine](https://github.com/TechnicallyComputers/retcomm-rbengine) | Portable snapshot and rollback helpers used for save states and rewind | psxrecomp |
| [TechnicallyComputers/retcomm-catalog](https://github.com/TechnicallyComputers/retcomm-catalog) | JSON manifests of supported titles, downloaded by the RetComM Launcher independently of app updates. Twelve titles at the time of this survey, all PlayStation | The launcher, over HTTP |

## Game ports

Each game port is a thin layer over one toolchain: a CMake glue file, per-game recompiler input, a small hand-written runtime shim, a `tools/` directory and a README. None of them holds a game file, and none holds the generated C. See [Port a game](https://retroportingtoolkit.com/docs/guides/port-a-game.md) for what that layer contains.

### PlayStation, on psxrecomp

Twenty repositories. Eighteen pin psxrecomp as a submodule, at path `psxrecomp` or `psxrecomp-v4`.

| Repository | Note |
|---|---|
| [mstan/TombaRecomp](https://github.com/mstan/TombaRecomp) | |
| [mstan/Tomba2Recomp](https://github.com/mstan/Tomba2Recomp) | |
| [mstan/ApeEscapeRecomp](https://github.com/mstan/ApeEscapeRecomp) | |
| [mstan/MegaManX4Recomp](https://github.com/mstan/MegaManX4Recomp) | |
| [mstan/MegaManX5Recomp](https://github.com/mstan/MegaManX5Recomp) | |
| [mstan/MegaManX6Recomp](https://github.com/mstan/MegaManX6Recomp) | The fleet's most heavily modded port, and the reason the mod package system exists |
| [mstan/TsumuLightRecomp](https://github.com/mstan/TsumuLightRecomp) | |
| [OpokXeno/xenogears-recomp](https://github.com/OpokXeno/xenogears-recomp) | Points both its psxrecomp and its recomp-ui submodules at that owner's own forks |
| [PeriBluGaming/ToyStory2Recomp](https://github.com/PeriBluGaming/ToyStory2Recomp) | Declares no submodules. Carries a partial snapshot of the framework and a vendored copy of recomp-ui as a plain tree |
| [Alexbeav/syphon-filter-2-recompiled](https://github.com/Alexbeav/syphon-filter-2-recompiled) | Declares no submodules, and ships a setup kit rather than a binary |
| [TechnicallyComputers/MastersOfTerasKasiRecomp](https://github.com/TechnicallyComputers/MastersOfTerasKasiRecomp) | Carries disc identity requirements in its `game.toml` |
| [TechnicallyComputers/BombermanPartyEditionRecomp](https://github.com/TechnicallyComputers/BombermanPartyEditionRecomp) | |
| [TechnicallyComputers/Bomberman-World-Recomp](https://github.com/TechnicallyComputers/Bomberman-World-Recomp) | |
| [TechnicallyComputers/Bomberman-Fantasy-Race-Recomp](https://github.com/TechnicallyComputers/Bomberman-Fantasy-Race-Recomp) | |
| [TechnicallyComputers/Klonoa-Door-to-Phantomile](https://github.com/TechnicallyComputers/Klonoa-Door-to-Phantomile) | |
| [TechnicallyComputers/Marvel-vs.-Capcom-Clash-of-Super-Heroes-Recomp](https://github.com/TechnicallyComputers/Marvel-vs.-Capcom-Clash-of-Super-Heroes-Recomp) | |
| [TechnicallyComputers/Metal-Slug-X-Recomp](https://github.com/TechnicallyComputers/Metal-Slug-X-Recomp) | |
| [TechnicallyComputers/Rampage---Through-Time-Recomp](https://github.com/TechnicallyComputers/Rampage---Through-Time-Recomp) | |
| [TechnicallyComputers/Street-Fighter-Alpha-3-Recomp](https://github.com/TechnicallyComputers/Street-Fighter-Alpha-3-Recomp) | |
| [TechnicallyComputers/TwistedMetal4Recomp](https://github.com/TechnicallyComputers/TwistedMetal4Recomp) | |

### NES, on nesrecomp

Ten repositories, all pinning nesrecomp as a submodule at path `nesrecomp`.

| Repository | Note |
|---|---|
| [mstan/SuperMarioBrosNESRecomp](https://github.com/mstan/SuperMarioBrosNESRecomp) | Pins a disassembly project as a second submodule, and carries a `THIRD-PARTY-LICENSES/` directory |
| [mstan/LegendOfZeldaNESRecomp](https://github.com/mstan/LegendOfZeldaNESRecomp) | |
| [mstan/MetroidNESRecomp](https://github.com/mstan/MetroidNESRecomp) | |
| [mstan/Megaman3NESRecomp](https://github.com/mstan/Megaman3NESRecomp) | |
| [mstan/FaxanaduRecomp](https://github.com/mstan/FaxanaduRecomp) | One of only two repositories in the whole fleet carrying a `MODDING.md` |
| [mstan/GumshoeNESRecomp](https://github.com/mstan/GumshoeNESRecomp) | |
| [mstan/DrMarioNesRecomp](https://github.com/mstan/DrMarioNesRecomp) | |
| [mstan/DuckHuntNESRecomp](https://github.com/mstan/DuckHuntNESRecomp) | |
| [mstan/YoshiNESRecomp](https://github.com/mstan/YoshiNESRecomp) | |
| [mstan/YoshisCookieRecomp](https://github.com/mstan/YoshisCookieRecomp) | |

### SNES, on snesrecomp

Eight repositories. Seven pin snesrecomp as a submodule; one vendors it.

| Repository | Note |
|---|---|
| [mstan/SuperMarioWorldRecomp](https://github.com/mstan/SuperMarioWorldRecomp) | The most thoroughly documented port in the fleet, and the one that builds two variants from one repository |
| [mstan/MegaManXSNESRecomp](https://github.com/mstan/MegaManXSNESRecomp) | Commits a runtime coverage manifest and feeds it back into regeneration |
| [mstan/SuperMetroidRecomp](https://github.com/mstan/SuperMetroidRecomp) | |
| [mstan/StarFoxSNESRecomp](https://github.com/mstan/StarFoxSNESRecomp) | |
| [mstan/ZeldaAlttPSNESRecomp](https://github.com/mstan/ZeldaAlttPSNESRecomp) | |
| [mstan/DKC2Recomp](https://github.com/mstan/DKC2Recomp) | Points its snesrecomp and recomp-ui submodules at `Nicktendonick` forks. MIT at the root over a noncommercial framework |
| [Team-Resurgent/MegaManX-X](https://github.com/Team-Resurgent/MegaManX-X) | Vendors snesrecomp as a plain tree, and declares recomp-ui in `.gitmodules` while shipping no gitlink for it, so a clean clone cannot configure |

One more SNES repository is in the fleet and is not named or linked here. Its license file says the repository is proprietary, confidential and meant to stay private, so this site holds it back until its owner has been asked. [Licenses](https://retroportingtoolkit.com/docs/fleet/licenses.md) does the same.

### Game Boy Advance, on gbarecomp

Fourteen repositories, all pinning gbarecomp as a submodule at path `gbarecomp`. Every one of them boots through the real recompiled BIOS, so the user supplies a BIOS dump as well as a cartridge dump.

| Repository | Note |
|---|---|
| [mstan/MinishCapRecomp](https://github.com/mstan/MinishCapRecomp) | Carries the fleet's canonical `baserom.md`, quoted on [The game file you supply](https://retroportingtoolkit.com/docs/concepts/the-game-file-you-supply.md) |
| [mstan/MegaManZeroRecomp](https://github.com/mstan/MegaManZeroRecomp) | |
| [mstan/MarioKartSuperCircuitRecomp](https://github.com/mstan/MarioKartSuperCircuitRecomp) | Pins a decompilation project as a second submodule |
| [mstan/SuperMarioAdvance2Recomp](https://github.com/mstan/SuperMarioAdvance2Recomp) | |
| [mstan/SuperMarioAdvance4Recomp](https://github.com/mstan/SuperMarioAdvance4Recomp) | |
| [mstan/WarioWareTwistedRecomp](https://github.com/mstan/WarioWareTwistedRecomp) | Pins SDL as an Android build submodule |
| [mstan/EmeraldRecomp](https://github.com/mstan/EmeraldRecomp) | Pins a decompilation project as a second submodule |
| [mstan/FireRedLeafGreenRecomp](https://github.com/mstan/FireRedLeafGreenRecomp) | Pins a decompilation project as a second submodule |
| [mstan/RubySapphireRecomp](https://github.com/mstan/RubySapphireRecomp) | Pins a decompilation project as a second submodule |
| [mstan/DragonBallZBuusFuryRecomp](https://github.com/mstan/DragonBallZBuusFuryRecomp) | |
| [mstan/DragonBallZLegacyOfGokuRecomp](https://github.com/mstan/DragonBallZLegacyOfGokuRecomp) | |
| [mstan/DragonBallZLegacyofGokuIIRecomp](https://github.com/mstan/DragonBallZLegacyofGokuIIRecomp) | |
| [mstan/ShrekGBAVideoRecomp](https://github.com/mstan/ShrekGBAVideoRecomp) | The cartridge that needed a 64 MiB mapper the toolchain calls Matrix Memory |
| [Shy/BoktaiRecomp](https://github.com/Shy/BoktaiRecomp) | Points its gbarecomp submodule at that owner's own fork |

### Sega Genesis, on segagenesisrecomp

| Repository | Note |
|---|---|
| [mstan/SonicTheHedgehogRecomp](https://github.com/mstan/SonicTheHedgehogRecomp) | The reference Genesis port. Its README reports "530+ functions" generated and "Zero dispatch misses on GHZ" |
| [mstan/SonicTheHedgehog2Recomp](https://github.com/mstan/SonicTheHedgehog2Recomp) | Has no runner of its own and reaches through the Sonic 1 repository to get to the submodule. The fleet's most heavily widescreen-configured port, at 46 injection sites |
| [mstan/Sonic3AndKnucklesRecomp](https://github.com/mstan/Sonic3AndKnucklesRecomp) | Three games in one repository as three build modes, because the lock-on cartridge is the two smaller ones combined |

### Master System and Game Gear, on smsggrecomp

| Repository | Note |
|---|---|
| [mstan/SonicTheHedgehogSMSRecomp](https://github.com/mstan/SonicTheHedgehogSMSRecomp) | One of the two bring-up titles for the toolchain |
| [mstan/SonicBlastGGRecomp](https://github.com/mstan/SonicBlastGGRecomp) | The Game Gear half of the same bring-up |

### Virtual Boy and Nintendo DS

| Repository | Console | Toolchain | Note |
|---|---|---|---|
| [mstan/MarioTennisVirtualBoyRecomp](https://github.com/mstan/MarioTennisVirtualBoyRecomp) | Virtual Boy | vbrecomp | The only vbrecomp port. Its license is scoped to build glue, CMake wiring and documentation only |
| [mstan/MetroidPrimeHuntersRecomp](https://github.com/mstan/MetroidPrimeHuntersRecomp) | Nintendo DS | ndsrecomp | The only ndsrecomp port, and it consumes the framework through an `ndsrecomp.pin` file rather than a submodule |

## What consumes what

Some repositories declare no submodules at all. The rest declare at least one, and this table collapses every declaration to one row per shared component. It tells you how far a change to a shared repository reaches.

| Component | Consumers | Who |
|---|---|---|
| [recomp-ui](https://github.com/mstan/recomp-ui) | Many gitlinks, plus vendored trees and broken declarations | Game ports on PlayStation, SNES, GBA, NES, Genesis and Virtual Boy |
| [psxrecomp](https://github.com/mstan/psxrecomp) | 18 | The PlayStation ports, at path `psxrecomp` or `psxrecomp-v4` |
| [gbarecomp](https://github.com/mstan/gbarecomp) | 14 | Every Game Boy Advance port |
| [nesrecomp](https://github.com/mstan/nesrecomp) | 10 | Every NES port |
| [snesrecomp](https://github.com/mstan/snesrecomp) | 7 gitlinks plus 1 vendored tree | Every SNES port |
| [segagenesisrecomp](https://github.com/mstan/segagenesisrecomp) | 3 | Every Genesis port |
| [m68k-recomp-core](https://github.com/mstan/m68k-recomp-core) | 2 | segagenesisrecomp and cdirecomp, both at `external/m68k-recomp-core` |
| [z80-recomp-core](https://github.com/mstan/z80-recomp-core) | 2 | segagenesisrecomp and smsggrecomp, both at `external/z80-recomp-core` |
| [smsggrecomp](https://github.com/mstan/smsggrecomp) | 2 | Both Sega 8-bit ports |
| [vbrecomp](https://github.com/mstan/vbrecomp) | 1 | The Virtual Boy port |
| [retcomm-rbengine](https://github.com/TechnicallyComputers/retcomm-rbengine) | 1 | psxrecomp, at `lib/retcomm-rbengine` |

A shared component is not the same everywhere it is used. Three details.

**recomp-ui is shared in intent and fanned out in practice.** Its 55 gitlinks pin 18 different commits. The closest is one commit behind its default branch, the furthest 231 behind. Two consumers point their submodule URL at a fork instead of the original, three suppress status reporting with `ignore = all`, and three pin a named feature branch.

**The two CPU cores are in much better shape.** Both z80-recomp-core consumers pin the identical commit, which is that repository's only commit. The two m68k-recomp-core consumers are 14 commits apart on one line of development, with cdirecomp behind rather than forked. Their shared decoder and validator are byte-identical between the two pins. All the drift sits in the Genesis profile, which is the split that repository's README asks for.

**A vendored copy inside a game port is not the framework.** `PeriBluGaming/ToyStory2Recomp` and `Team-Resurgent/MegaManX-X` each carry a partial snapshot of a framework instead of a submodule, including older attribution files that say different things. For any statement about a framework, read the framework repository.

## Two repositories that are no longer reachable

`TechnicallyComputers/Crash-Team-Racing-Recomp` and `TechnicallyComputers/Crash-Bash-Recomp` are named by game pages elsewhere on this site and no longer resolve. Another repository in the same organisation resolves normally, so this is not a network fault: both have gone private or been deleted. They are not linked here, because a link would send you to a 404. Neither could be read, so nothing here says what they held.

---

# Lineage and credit

> How the projects in this fleet descend from each other: the framework the others were modelled on, the CPU cores several toolchains share, and the commit each game port pins.

- Canonical URL: https://retroportingtoolkit.com/docs/fleet/lineage-and-credit
- Markdown: https://retroportingtoolkit.com/docs/fleet/lineage-and-credit.md
- Section: The fleet
- Page type: concept
- Tags: Lineage, Credit, Licensing
- Last updated: 2026-08-31
- Source repositories:
  - https://github.com/mstan/psxrecomp
  - https://github.com/mstan/m68k-recomp-core
  - https://github.com/mstan/z80-recomp-core
  - https://github.com/mstan/recomp-ui

---

The toolchains here are not independent projects. One of them is the model the
others were built from. Two CPU frontends were pulled out of one framework and
are now shared repositories. Every game port records the exact framework commit it was built
against. Those are the lines of descent inside the fleet, and each one can be
checked in the repositories themselves.

## psxrecomp is the model the others name

[psxrecomp](https://github.com/mstan/psxrecomp) is the PlayStation toolchain.
The others name it as their model, by name, in their own documents.

- [snesrecomp](https://github.com/mstan/snesrecomp) calls its accuracy scorecard
  "modeled on the psxrecomp `ACCURACY_BURNDOWN.md` 7-axis methodology", ports its
  timing plan from psxrecomp's, and cites psxrecomp's co-simulation document as
  the "proven PSX reference impl".
- [nesrecomp](https://github.com/mstan/nesrecomp) models the same scorecard
  "1:1". It also refused part of the design and wrote down why. psxrecomp has
  several execution tiers for code that only arrives while the game is running.
  A NES cartridge is complete before the build starts, so those tiers would have
  nothing to do.
- [segagenesisrecomp](https://github.com/mstan/segagenesisrecomp) mirrors
  psxrecomp's co-simulation harness, counts guest cycles the psxrecomp way, and
  injects widescreen the PSX way.
- [gbarecomp](https://github.com/mstan/gbarecomp) takes the same scorecard, the
  same co-simulation design, and the idea of treating the console BIOS as an
  ordinary program.
- [ndsrecomp](https://github.com/mstan/ndsrecomp) models its dispatch tiers on
  psxrecomp and lists itself in the same family.
The copying is not only design. Every PlayStation game port builds its releases
from a workflow copied out of psxrecomp, and the copy says so in its first line.

## Two CPU cores are shared repositories now

[m68k-recomp-core](https://github.com/mstan/m68k-recomp-core) is the Motorola
68000 frontend. It did not start as a shared repository. The Genesis toolchain
wrote it, the CD-i toolchain copied it, and the copy then went its own way.

From [`PROVENANCE.md`](https://github.com/mstan/m68k-recomp-core/blob/main/PROVENANCE.md):

```text title="PROVENANCE.md"
The author-owned frontend originated in `segagenesisrecomp`. CD-i copied the
frontend from `segagenesisrecomp` commit `5aa0c4f` on 2026-05-28 and developed
SCC68070/OS-9 behavior independently afterward.
```

Both now consume the extracted repository, at `external/m68k-recomp-core`. The
shared decoder and validator are byte-identical between the two pins. All the
difference sits in the Genesis profile, which is the split the README asks for.

[z80-recomp-core](https://github.com/mstan/z80-recomp-core) does the same for
the Zilog Z80, a chip that turns up in two different roles. On the Master System
and Game Gear it is the console's main CPU. On the Genesis it drives the
cartridge sound. Both toolchains pin the identical commit, which is also that
repository's only commit.

[recomp-ui](https://github.com/mstan/recomp-ui), the launcher and settings
screen, began the same way, inside one console's project.

From [`README.md`](https://github.com/mstan/recomp-ui/blob/master/README.md):

```text title="README.md"
It is the reusable extraction of the SNES-recomp "launcher_ng" launcher,
generalized behind a small C ABI.
```

Today many game ports pin it across several consoles.

## Small parts that travelled

Two components moved between projects and are credited at every stop.

The screen colour table in snesrecomp is adapted from psxrecomp, and
snesrecomp's attribution file records the exact revision it was taken from.
[DKC2Recomp](https://github.com/mstan/DKC2Recomp) then vendors that
psxrecomp-derived component under `third_party/psxrecomp_color_lut/`, carrying
all three of its license texts.

The ShadowVerifier and the colour science core came from outside the fleet, from
[JRickey/gba-recomp](https://github.com/JRickey/gba-recomp), with the author's
permission. gbarecomp and snesrecomp implemented it first. segagenesisrecomp
credits it as ported "through the gbarecomp/snesrecomp implementations with
permission". psxrecomp and [vbrecomp](https://github.com/mstan/vbrecomp) carry
their own versions in C.

## Every game port pins a commit

A game port is a thin repository over one framework, joined by a git submodule
pinned to a single commit. That pin records which version of the framework the
port was built against.

The pins are not uniform. The recomp-ui gitlinks point at many different
commits. Two ports point the submodule URL at a fork instead of the
original, and three pin a named feature branch. Two other repositories have left
the submodule mechanism and carry a snapshot of a framework as an ordinary
directory, so a fact about a framework should be read in the framework
repository, never in one of those copies.

---

# Licenses

> A repository-by-repository license census for the fleet, plus the third-party licenses each toolchain bundles or links.

- Canonical URL: https://retroportingtoolkit.com/docs/fleet/licenses
- Markdown: https://retroportingtoolkit.com/docs/fleet/licenses.md
- Section: The fleet
- Page type: reference
- Tags: Licensing, Attribution, Fleet
- Last updated: 2026-08-31
- Source repositories:
  - https://github.com/mstan/psxrecomp
  - https://github.com/mstan/snesrecomp
  - https://github.com/mstan/gbarecomp
  - https://github.com/mstan/ndsrecomp
  - https://github.com/mstan/vbrecomp
  - https://github.com/mstan/segagenesisrecomp

---

Every license below was read from the license file itself, not from a README
summary. Repositories that declare nothing are listed too: a missing license
file is a fact you need. This is what the files say. It is not legal advice.

## The census in numbers

| Measure | Count |
|---|---|
| Repositories surveyed | current fleet |
| Carrying a license file (`LICENSE`, `LICENSE.md`, `COPYING`, `LICENSE-recompiler`) | many |
| Carrying no license file at all | many |
| Distinct license identities found | 5 |

The five identities are PolyForm Noncommercial 1.0.0, MIT, GPL-3.0, a
proprietary all rights reserved notice, and one PolyForm text carrying no
copyright holder.

## Frameworks and toolchains

| Repository | License | Source file | Notes |
|---|---|---|---|
| [mstan/psxrecomp](https://github.com/mstan/psxrecomp) | PolyForm Noncommercial 1.0.0 | [`LICENSE`](https://github.com/mstan/psxrecomp/blob/master/LICENSE) | Holder `Copyright (c) 2026 Matthew Stan`. Carries the appended paragraph below |
| [mstan/snesrecomp](https://github.com/mstan/snesrecomp) | PolyForm Noncommercial 1.0.0 | [`LICENSE`](https://github.com/mstan/snesrecomp/blob/main/LICENSE) | Appended paragraph |
| [mstan/nesrecomp](https://github.com/mstan/nesrecomp) | PolyForm Noncommercial 1.0.0 | [`LICENSE`](https://github.com/mstan/nesrecomp/blob/master/LICENSE) | Appended paragraph |
| [mstan/gbarecomp](https://github.com/mstan/gbarecomp) | PolyForm Noncommercial 1.0.0 | [`LICENSE`](https://github.com/mstan/gbarecomp/blob/main/LICENSE) | Appended paragraph |
| [mstan/cdirecomp](https://github.com/mstan/cdirecomp) | PolyForm Noncommercial 1.0.0 | [`LICENSE`](https://github.com/mstan/cdirecomp/blob/master/LICENSE) | Appended paragraph |
| [mstan/segagenesisrecomp](https://github.com/mstan/segagenesisrecomp) | PolyForm Noncommercial 1.0.0 | [`LICENSE-recompiler`](https://github.com/mstan/segagenesisrecomp/blob/master/LICENSE-recompiler) and [`LICENSE.md`](https://github.com/mstan/segagenesisrecomp/blob/master/LICENSE.md) | Two license files whose text is not the same. See below |
| [mstan/ndsrecomp](https://github.com/mstan/ndsrecomp) | MIT | [`LICENSE`](https://github.com/mstan/ndsrecomp/blob/main/LICENSE) | Holder `Copyright (c) 2026 Matthew Stanley`. Covers the project's own source; the shipped `nds_runner` binary is a GPL-3.0-or-later combined work |
| [mstan/vbrecomp](https://github.com/mstan/vbrecomp) | MIT | [`LICENSE`](https://github.com/mstan/vbrecomp/blob/master/LICENSE) | 53 lines: the MIT text plus an in-file `# Attribution` section |
| [mstan/smsggrecomp](https://github.com/mstan/smsggrecomp) | **None** | no license file | README states the license is "Not yet declared" |

## Shared services and components

| Repository | License | Source file | Notes |
|---|---|---|---|
| [TechnicallyComputers/retcomm-rbengine](https://github.com/TechnicallyComputers/retcomm-rbengine) | MIT | [`LICENSE`](https://github.com/TechnicallyComputers/retcomm-rbengine/blob/main/LICENSE) | |
| [TechnicallyComputers/retcomm-catalog](https://github.com/TechnicallyComputers/retcomm-catalog) | **None** | no license file | No README license section either |
| [mstan/m68k-recomp-core](https://github.com/mstan/m68k-recomp-core) | PolyForm Noncommercial 1.0.0 | [`LICENSE`](https://github.com/mstan/m68k-recomp-core/blob/main/LICENSE) | Holder `Copyright (c) 2026 Matthew Stan`. Appended paragraph |
| [mstan/z80-recomp-core](https://github.com/mstan/z80-recomp-core) | PolyForm Noncommercial 1.0.0 | [`LICENSE`](https://github.com/mstan/z80-recomp-core/blob/main/LICENSE) | Appended paragraph. Also carries `LICENSES/SUPERZAZU-MIT.txt` for the Z80 core it derives from |
| [mstan/recomp-ui](https://github.com/mstan/recomp-ui) | MIT | [`LICENSE`](https://github.com/mstan/recomp-ui/blob/master/LICENSE) | Holder `Copyright (c) 2026 Matthew Stanley` |

## Game repositories that carry a license file

| Repository | License | Source file | Notes |
|---|---|---|---|
| [mstan/TombaRecomp](https://github.com/mstan/TombaRecomp) | PolyForm Noncommercial 1.0.0 | `LICENSE` | Appended paragraph |
| [mstan/Tomba2Recomp](https://github.com/mstan/Tomba2Recomp) | PolyForm Noncommercial 1.0.0 | `LICENSE` | Appended paragraph |
| [mstan/ApeEscapeRecomp](https://github.com/mstan/ApeEscapeRecomp) | PolyForm Noncommercial 1.0.0 | `LICENSE` | Appended paragraph |
| [mstan/MegaManX4Recomp](https://github.com/mstan/MegaManX4Recomp) | PolyForm Noncommercial 1.0.0 | `LICENSE` | Appended paragraph |
| [mstan/MegaManX5Recomp](https://github.com/mstan/MegaManX5Recomp) | PolyForm Noncommercial 1.0.0 | `LICENSE` | Appended paragraph |
| [mstan/MegaManX6Recomp](https://github.com/mstan/MegaManX6Recomp) | PolyForm Noncommercial 1.0.0 | `LICENSE` | Plus a `THIRD-PARTY-LICENSES/` directory |
| [mstan/TsumuLightRecomp](https://github.com/mstan/TsumuLightRecomp) | PolyForm Noncommercial 1.0.0 | `LICENSE` | Appended paragraph |
| [mstan/MinishCapRecomp](https://github.com/mstan/MinishCapRecomp) | PolyForm Noncommercial 1.0.0 | `LICENSE` | Appended paragraph |
| [mstan/DragonBallZBuusFuryRecomp](https://github.com/mstan/DragonBallZBuusFuryRecomp) | PolyForm Noncommercial 1.0.0 | `LICENSE` | Appended paragraph |
| [mstan/SonicTheHedgehogRecomp](https://github.com/mstan/SonicTheHedgehogRecomp) | PolyForm Noncommercial 1.0.0 | `LICENSE.md` | No copyright holder line anywhere in the file |
| [Shy/BoktaiRecomp](https://github.com/Shy/BoktaiRecomp) | PolyForm Noncommercial 1.0.0 | `LICENSE` | `Copyright (c) 2026 Shy (github.com/Shy)` |
| [OpokXeno/xenogears-recomp](https://github.com/OpokXeno/xenogears-recomp) | PolyForm Noncommercial 1.0.0 | `LICENSE` | `Copyright (c) 2026 OpokXeno`. 98 lines, no appended paragraph |
| [Alexbeav/syphon-filter-2-recompiled](https://github.com/Alexbeav/syphon-filter-2-recompiled) | PolyForm Noncommercial 1.0.0 | `LICENSE` | `Copyright (c) 2026 Matthew Stan`, not the repository owner. See below |
| [mstan/DKC2Recomp](https://github.com/mstan/DKC2Recomp) | MIT | `LICENSE` | `Copyright (c) 2026 DKC2 Port contributors`. An MIT game repo built on a PolyForm-NC framework |
| [mstan/MetroidPrimeHuntersRecomp](https://github.com/mstan/MetroidPrimeHuntersRecomp) | MIT | `LICENSE` | Built on the MIT `ndsrecomp`, whose runner binary is GPL-3.0-or-later |
| [mstan/MarioTennisVirtualBoyRecomp](https://github.com/mstan/MarioTennisVirtualBoyRecomp) | MIT | `LICENSE.md` | The grant is explicitly scoped. See below |

One more repository in the fleet carries a proprietary all rights reserved
notice. That same file says the repository is meant to stay private, so this
site does not name, link or describe it until its owner has been asked.

## Repositories with no license file

This site does not state or imply a license for repositories that carry no license file.

**mstan, Game Boy Advance (11).** `DragonBallZLegacyOfGokuRecomp`,
`DragonBallZLegacyofGokuIIRecomp`, `EmeraldRecomp`, `FireRedLeafGreenRecomp`,
`RubySapphireRecomp`, `MarioKartSuperCircuitRecomp`, `MegaManZeroRecomp`,
`ShrekGBAVideoRecomp`, `SuperMarioAdvance2Recomp`, `SuperMarioAdvance4Recomp`,
`WarioWareTwistedRecomp`.

**mstan, NES (10).** `DrMarioNesRecomp`, `DuckHuntNESRecomp`, `FaxanaduRecomp`,
`GumshoeNESRecomp`, `LegendOfZeldaNESRecomp`, `Megaman3NESRecomp`,
`MetroidNESRecomp`, `SuperMarioBrosNESRecomp`, `YoshiNESRecomp`,
`YoshisCookieRecomp`.

**mstan, SNES (5).** `MegaManXSNESRecomp`, `StarFoxSNESRecomp`,
`SuperMarioWorldRecomp`, `SuperMetroidRecomp`, `ZeldaAlttPSNESRecomp`.

**mstan, Game Gear, Master System, Genesis (5).** `SonicBlastGGRecomp`,
`SonicTheHedgehogSMSRecomp`, `smsggrecomp`, `Sonic3AndKnucklesRecomp`,
`SonicTheHedgehog2Recomp`.

**TechnicallyComputers (11).** `Bomberman-Fantasy-Race-Recomp`,
`Bomberman-World-Recomp`, `BombermanPartyEditionRecomp`,
`Klonoa-Door-to-Phantomile`,
`Marvel-vs.-Capcom-Clash-of-Super-Heroes-Recomp`, `MastersOfTerasKasiRecomp`,
`Metal-Slug-X-Recomp`, `Rampage---Through-Time-Recomp`,
`Street-Fighter-Alpha-3-Recomp`, `TwistedMetal4Recomp`, `retcomm-catalog`.

**Others (2).** `PeriBluGaming/ToyStory2Recomp`, `Team-Resurgent/MegaManX-X`.

### Repositories that state the position themselves

Several of them say so in the README. Where a project says it, the project is
quoted.

From [`README.md`](https://github.com/mstan/SonicBlastGGRecomp/blob/main/README.md):

```text title="README.md"
## License

Not yet declared. Code in this repo is original. The *Sonic Blast* ROM and any
data derived from it are **not** in this repo and are not licensed for
redistribution.
```

From [`README.md`](https://github.com/mstan/StarFoxSNESRecomp/blob/main/README.md):

```text title="README.md"
## License

Not yet declared. Original project code and vendored dependencies retain their
respective ownership and licensing status. The *Star Fox* ROM and all data
extracted from it are not part of this repository and are not licensed for
redistribution.
```

[Team-Resurgent/MegaManX-X](https://github.com/Team-Resurgent/MegaManX-X) and
[mstan/MegaManXSNESRecomp](https://github.com/mstan/MegaManXSNESRecomp) carry an
identical third wording, adding that vendored dependencies under `third_party/`
retain their own licenses.

One repository uses a different phrase.
[MetroidNESRecomp](https://github.com/mstan/MetroidNESRecomp)'s `README.md`
calls the nesrecomp framework and its own game code "provided as-is for
educational and research purposes". That sentence is MetroidNESRecomp's. The
nesrecomp framework it names is PolyForm Noncommercial 1.0.0, so the phrase is
not the framework's license text and does not apply to the rest of the fleet.

## Where a headline license is narrower than it looks

Three repositories say directly that their headline license does not cover the
whole tree or the shipped binary.

**ndsrecomp.** From [`THIRD_PARTY_ATTRIBUTION.md`](https://github.com/mstan/ndsrecomp/blob/main/THIRD_PARTY_ATTRIBUTION.md):

```text title="THIRD_PARTY_ATTRIBUTION.md"
The MIT grant covers this project's own source. It does not and cannot relicense
the third-party code described below, and it does not make every build artifact
redistributable under MIT terms. In particular, the native runner links vendored
melonDS sources, so the `nds_runner` **executable** is a combined work whose
distribution must comply with GPL-3.0-or-later — see
[melonDS vendored GPU3D (runner)](#melonds-vendored-gpu3d-runner) below. The
recompiler, the generated banks, and all `ndsref`-independent tooling stay
outside that boundary and are distributable under MIT alone.
```

**MarioTennisVirtualBoyRecomp.** From [`LICENSE.md`](https://github.com/mstan/MarioTennisVirtualBoyRecomp/blob/master/LICENSE.md):

```text title="LICENSE.md"
This licence covers ONLY the build glue + per-game CMake wiring + this
repo's documentation. It does NOT cover:

  - The Mario's Tennis ROM and any data derived from it (e.g.,
    `generated/marios_tennis_*.c`, screenshots of the running cart).
    Those are © Nintendo. Do not redistribute. You must dump the cart
    you own.

  - The vbrecomp framework (separate repo at github.com/mstan/vbrecomp,
    MIT-licensed under its own `LICENSE` file).

  - The Beetle VB libretro core (cloned separately under `beetle-vb/`,
    GPL-licensed by its respective contributors).
```

**DKC2Recomp.** From [`README.md`](https://github.com/mstan/DKC2Recomp/blob/main/README.md):

```text title="README.md"
## License

Project-owned source is available under the [MIT License](LICENSE). Vendored
dependencies and submodules retain their own licenses. In particular, the
PSXRecomp-derived screen-color component is PolyForm Noncommercial 1.0.0 with
an MIT/Apache-2.0 color-science lineage; the complete notices are in
`third_party/psxrecomp_color_lut/` and it is not relicensed by the root MIT
license. Nintendo and Rare
own their respective game content and trademarks; no license in this
repository grants rights to that content.
```

That `third_party/psxrecomp_color_lut/` directory carries all three texts:
`LICENSE-APACHE-2.0.txt`, `LICENSE-MIT.txt`, and
`LICENSE-POLYFORM-NONCOMMERCIAL-1.0.0.txt`.

## Third-party licenses the toolchains bundle or link

Five canonical attribution files exist, at
[psxrecomp](https://github.com/mstan/psxrecomp/blob/master/THIRD_PARTY_ATTRIBUTION.md),
[snesrecomp](https://github.com/mstan/snesrecomp/blob/main/THIRD_PARTY_ATTRIBUTION.md),
[gbarecomp](https://github.com/mstan/gbarecomp/blob/main/THIRD_PARTY_ATTRIBUTION.md),
[ndsrecomp](https://github.com/mstan/ndsrecomp/blob/main/THIRD_PARTY_ATTRIBUTION.md)
and [vbrecomp](https://github.com/mstan/vbrecomp/blob/master/THIRD_PARTY_ATTRIBUTION.md).
Four more carry variant filenames: cdirecomp's `THIRD-PARTY-NOTICES.md`,
DKC2Recomp's `THIRD_PARTY_NOTICES.md`, and segagenesisrecomp's
`THIRD-PARTY-LICENSES.md`. Two repositories use a directory instead,
`MegaManX6Recomp/THIRD-PARTY-LICENSES/` and
`SuperMarioBrosNESRecomp/THIRD-PARTY-LICENSES/`. These files are the authority
for what a build contains, not the README.

### psxrecomp

| Component | Role | License stated |
|---|---|---|
| OpenBIOS, from [PCSX-Redux](https://github.com/grumpycoders/pcsx-redux) `src/mips/openbios` | Bundled free PS1 BIOS image, statically recompiled | MIT |
| [uC-sdk](https://github.com/grumpycoders/uC-sdk) | Linked into the OpenBIOS binary | "a mixture of permissive (non-reciprocal) licenses that require this mention" |
| TinyCC (TCC) | Overlay compiler shipped to players, invoked as a subprocess | LGPL-2.1 |
| JRickey/gba-recomp | ShadowVerifier and colour-science core, re-implemented in C | MIT OR Apache-2.0, "used with permission" |
| SDL2 | Windowing, input, audio, via game repos | zlib |

psxrecomp calls TinyCC aggregation rather than linkage, and says why. TinyCC is
not vendored in the repository. `tools/compile_overlays.py` runs it as a
separate program to build overlay shards into a DLL. In the attribution file's
words, "Nothing in the runtime links against libtcc, so this is aggregation with
a separate program rather than LGPL linkage." The same file notes that no script
in the repository fills the end-user overlay toolchain bundle, so if release
packaging supplies it, the TinyCC notice has to travel with it there.

### snesrecomp

| Component | Role | License stated |
|---|---|---|
| libretro API header (`tools/snesref/libretro.h`) | Developer-only frontend | MIT, full text reproduced |
| SDL2 | snesref frontend, not vendored | zlib |
| bsnes libretro core | Developer oracle, not vendored | GPLv3 |
| Snes9x libretro core | Developer oracle, not vendored | "Snes9x non-commercial license" |
| psxrecomp colour LUT (`runner/src/snes/color_lut.{c,h}`) | Screen colour | PolyForm Noncommercial 1.0.0 over an MIT OR Apache-2.0 lineage |
| ares | Cx4 / Hitachi HG51B S169 coprocessor | ISC, full text reproduced |
| ares | DSP-1 / NEC uPD7725 coprocessor | ISC |
| ares | SA-1 coprocessor | ISC |
| [LakeSnes](https://github.com/angelo-wf/lakesnes) | 65816 interpreter core `interp816` | MIT, full text reproduced |
| perplexes/snesrecomp | Rust native-analyzer foundation | "License declared by the upstream crate: MIT" |
| DerrickGold/ar-recomp | Named as performance inspiration only, no code taken | not applicable |

The file also states that the developer-only label is not a waiver.

From [`THIRD_PARTY_ATTRIBUTION.md`](https://github.com/mstan/snesrecomp/blob/main/THIRD_PARTY_ATTRIBUTION.md):

```text title="THIRD_PARTY_ATTRIBUTION.md"
The `tools/snesref/.gitignore` rules exclude SDL packages and binaries,
`snesref.exe`, and `*_libretro.dll`. A developer-only label does not waive a
dependency's terms if someone distributes it; downstream packages must either
comply with the selected dependency's license or continue to require developers
to supply it separately.
```

### gbarecomp

| Component | Role | License stated |
|---|---|---|
| JRickey/gba-recomp | MP2K driver detection, colour LUT, cartridge RTC, audio shadow, MP2K shadow mixer | MIT OR Apache-2.0, "used with the author's permission" |
| mGBA, vendored at `third_party/mgba` | BIOS SWI high level emulation routines | MPL-2.0 |

gbarecomp records that portions of `src/runtime/bios_hle.cpp` are derived from
mGBA and remain subject to MPL-2.0, and that the upstream source is vendored at
`third_party/mgba/src/gba/bios.c` to satisfy the license's source-availability
requirement.

### ndsrecomp

The largest attribution file in the fleet, at 252 lines.

| Component | Role | License stated |
|---|---|---|
| gbarecomp | ARMv4T core, recompiler driver, function finder | Upstream PolyForm Noncommercial 1.0.0; ported portions offered here under MIT because the copyright owner is the same |
| melonDS (oracle, cloned into an ignored directory) | Reference implementation | GPL-3.0-or-later |
| melonDS GPU3D, vendored | 3D geometry engine and software rasterizer in the runner | GPL-3.0-or-later |
| melonDS Wifi and net glue, vendored | Wi-Fi device model and network backend | GPL-3.0-or-later |
| libpcap public headers, vendored inside the melonDS net tree | Networking | BSD |
| libslirp 4.8.0, vendored inside the melonDS net tree | Networking | BSD-3-Clause |
| melonPrimeDS | Control-scheme reference | GPL-3.0-or-later, inherited |
| Hyllian xBR-lv2 | Optional texture upscaler rules | MIT |
| mGBA | Behavioural and ARM7 timing reference, not vendored | MPL-2.0 |
| [FreeBIOS](https://github.com/mstan/freebios), the DraStic BIOS replacement by Gilead Kutnick | Opt-in no-dump boot images | BSD-2-Clause |

### vbrecomp

| Component | Role | License stated |
|---|---|---|
| JRickey/gba-recomp | Audio shadow differential verifier, re-implemented in C | MIT OR Apache-2.0, "used with the author's permission" |
| Mednafen Beetle VB | Oracle backend | GPL. "vbrecomp does not redistribute it" |

### segagenesisrecomp

| Component | Role | License stated |
|---|---|---|
| ymfm | YM2612 FM synthesis | BSD-3-Clause |
| superzazu/z80 | Z80 sound-CPU core | MIT |
| clowncommon | Integer types and C helpers | ISC |
| SDL2 | Windowing, input, rendering, audio | zlib |
| tomlc99 | TOML parsing | MIT |
| ShadowVerifier and colour science | Opt-in audio and video enhancements | MIT OR Apache-2.0 |
| Dear ImGui | Launcher UI, added at build time by game repos | MIT |
| stb_image, stb_truetype, stb_image_write | Image and font helpers | "Public domain or MIT" |
| tinyfiledialogs | Native ROM file picker | zlib |
| Lato | Launcher typeface | SIL Open Font License 1.1 |

Its compliance notes set out the whole model in four lines.

From [`THIRD-PARTY-LICENSES.md`](https://github.com/mstan/segagenesisrecomp/blob/master/THIRD-PARTY-LICENSES.md):

```text title="THIRD-PARTY-LICENSES.md"
## Compliance notes

- Native release binaries contain no AGPL code. Release packaging must still
  follow [RELEASING.md](RELEASING.md) and include every applicable notice.
- The shipped binary must not contain a game ROM. Users supply their own ROM;
  `*.bin` is ignored and the runtime loads it separately.
- Generated C compiled into a game executable is a machine translation of ROM
  code. The project's own license cannot grant rights to third-party game code.
- This inventory is informational, not legal advice.
```

The same file records a dependency that was dropped. No clownmdemu, clown68000
or clownz80 remains in the current source, the recompiler or the native release
paths. Those retired oracle components exist only in git history.

### Per-game attribution files

| Repository | What it records |
|---|---|
| [mstan/DKC2Recomp](https://github.com/mstan/DKC2Recomp/blob/main/THIRD_PARTY_NOTICES.md) | Launcher notices: Dear ImGui MIT, SDL2 zlib, GCC runtime with the Runtime Library Exception, Lato under OFL 1.1, LakeSnes-derived APU and S-DSP MIT. Plus the cover art notice below |
| [mstan/MegaManX6Recomp](https://github.com/mstan/MegaManX6Recomp) `THIRD-PARTY-LICENSES/` | xdelta3 3.0.11 relicensed Apache-2.0 by its original author, so no GPL obligation. `error_recalc` is GPLv3-or-later and invoked as a separate process |
| [mstan/SuperMarioBrosNESRecomp](https://github.com/mstan/SuperMarioBrosNESRecomp) `THIRD-PARTY-LICENSES/` | An unlicensed upstream, handled as an explicit publication assumption rather than a license grant |

DKC2Recomp records why an image ships at all. The North American retail cover is
there "only to identify the supported game and region", the art and trademarks
stay copyright Nintendo and Rare, and the project claims no ownership.

MegaManX6Recomp states what its one GPL tool means for packaging.

From [`THIRD-PARTY-LICENSES/README.md`](https://github.com/mstan/MegaManX6Recomp/blob/master/THIRD-PARTY-LICENSES/README.md):

```text title="THIRD-PARTY-LICENSES/README.md"
- Because it is a **separate process**, its GPL terms do **not** extend to this
  project's PolyForm-NC code. If a release ships the error_recalc binary before
  the replacement below lands, that release must also make the error_recalc
  source available per GPLv3 (§6).
```

## Where a project's tooling is not uniformly under one license

| Repository | The split |
|---|---|
| mstan/ndsrecomp | MIT project source; the `nds_runner` binary is a GPL-3.0-or-later combined work; the recompiler, generated banks and `ndsref`-independent tooling stay MIT |
| mstan/psxrecomp | PolyForm-NC framework; MIT OpenBIOS image bundled with it; LGPL-2.1 TinyCC invoked as a separate process at release time |
| mstan/MegaManX6Recomp | PolyForm-NC project code; one GPLv3-or-later tool invoked as a separate process; one Apache-2.0 tool |
| mstan/DKC2Recomp | MIT root; a vendored PolyForm-NC colour component with an MIT OR Apache-2.0 lineage, not relicensed by the root |
| mstan/MarioTennisVirtualBoyRecomp | MIT scoped to build glue, CMake wiring and documentation; the vbrecomp framework and the GPL Beetle VB core are outside it |
| mstan/segagenesisrecomp | Two license files in one repository whose text differs |
| mstan/snesrecomp | PolyForm-NC framework; ISC and MIT vendored cores; GPLv3 and non-commercial oracle cores that are not vendored |

## Deviations and open questions

**The appended PolyForm paragraph.** Twenty-two license files in the fleet
append this to the end of the stock PolyForm Noncommercial 1.0.0 text, two of
them in the shared CPU cores added to the census above.

From [`LICENSE`](https://github.com/mstan/psxrecomp/blob/master/LICENSE):

```text title="LICENSE"
For the avoidance of doubt, the licensor's intent is to restrict uses where
profit is derived from this software. Non-profit personal, educational,
or community use is welcome regardless of organizational context.

For commercial licensing inquiries, contact: https://1379.tech
```

Three PolyForm files in the fleet do not carry it: `OpokXeno/xenogears-recomp`,
`mstan/SonicTheHedgehogRecomp`, and `mstan/segagenesisrecomp`'s `LICENSE.md`.

**PolyForm text with no copyright holder.** `mstan/SonicTheHedgehogRecomp`'s
`LICENSE.md` and `mstan/segagenesisrecomp`'s `LICENSE.md` are byte identical and
name no licensor. The only copyright string in either file is PolyForm's own
worked example. The license file does not say who the licensor is.

**Two license files in one repository.** `mstan/segagenesisrecomp` has both
`LICENSE-recompiler`, 100 lines with a named holder and the appended paragraph,
and `LICENSE.md`, 73 lines with neither. A consumer repository's README,
`Sonic3AndKnucklesRecomp`, points at `LICENSE.md`.

**A community repository carrying the framework author's copyright.**
`Alexbeav/syphon-filter-2-recompiled`'s `LICENSE` names
`Copyright (c) 2026 Matthew Stan` although the repository owner is Alexbeav.
Nothing says whether that is intended. `Shy/BoktaiRecomp` and
`OpokXeno/xenogears-recomp` both name their own owners, so the fleet is not
uniform here.

**Do not read a framework's license from a vendored copy.**
`PeriBluGaming/ToyStory2Recomp` and `Team-Resurgent/MegaManX-X` each hold a
partial snapshot of a framework, including an older attribution file that says
different things. The ToyStory2 copy documents an sljit overlay backend and has
no OpenBIOS or TinyCC section at all. `OpokXeno/xenogears-recomp` carries
psxrecomp as a submodule pointing at that owner's own fork. For any framework
fact, read `mstan/psxrecomp` and `mstan/snesrecomp` directly.

**Not established from the files.** The license of
`TechnicallyComputers/retcomm-catalog`. And whether release archives really ship
the notices their repositories require, because this census read repositories,
not built packages.

---

# Provenance

> How cdirecomp records where every line of its device code came from, quoted step by step, and what each toolchain in the fleet says about BIOS and firmware it does or does not ship.

- Canonical URL: https://retroportingtoolkit.com/docs/fleet/provenance
- Markdown: https://retroportingtoolkit.com/docs/fleet/provenance.md
- Section: The fleet
- Page type: concept
- Tags: Provenance, Attribution, BIOS, Engineering practice
- Last updated: 2026-08-25
- Source repositories:
  - https://github.com/mstan/cdirecomp
  - https://github.com/mstan/psxrecomp
  - https://github.com/mstan/ndsrecomp
  - https://github.com/mstan/gbarecomp
  - https://github.com/mstan/snesrecomp

---

Nobody has documented these consoles completely. So the people writing a
recompiler read hardware specifications, run other people's emulators, and reuse
code from their own earlier projects. Provenance is the record of which of those
a given line of code came from.
[cdirecomp](https://github.com/mstan/cdirecomp) keeps that record in a 57 line
file, and it is the only project here that writes the practice down as a rule.

## The line the record draws

The file opens by drawing one line.

From [`PROVENANCE.md`](https://github.com/mstan/cdirecomp/blob/master/PROVENANCE.md):

```text title="PROVENANCE.md"
# Source provenance

This record covers the source that builds `CdiRuntime` and the author-owned
`CdiRecomp` frontend. It distinguishes implementation inputs from optional
black-box validation tools.
```

An implementation input is something you write code from. A validation tool is
something you only compare against. Once they have separate names, every
component has to be filed under one of them.

## The practice, step by step

### A basis and a test per device

The body is a table: the component, the independent basis it was written from,
and the project's own evidence that the result is right. Three rows of it:

From [`PROVENANCE.md`](https://github.com/mstan/cdirecomp/blob/master/PROVENANCE.md):

```text title="PROVENANCE.md"
| Component | Independent implementation basis | Project evidence |
|---|---|---|
| 68000 decode, code generation, and interpreter | Author-owned `segagenesisrecomp` frontend ancestry; Motorola 68000 architecture and SCC68070 timing/exception documentation | `recompiler/PROVENANCE.txt`, `runner/tests/m68k_arith_test.c`, generated-code differential tests |
| SCC68070 exception frames, timers, interrupt controller, and UART | SCC68070 User Manual, especially exception processing and sections 2.13.1–2.13.12 | `runner/tests/periph_test.c`, BIOS boot and co-simulation gates |
| DS1216 phantom clock/NVRAM | Analog Devices DS1216 data sheet: serial key, register layout, oscillator, BCD calendar, and SRAM pass-through | `runner/tests/cdi_nvram_test.c` |
```

The middle column says where the code came from. The right column names the test
that pins it. No row cites another emulator as a basis.

### Publish the specification sources

A basis is only checkable if you can open it, so the file gives URLs.

From [`PROVENANCE.md`](https://github.com/mstan/cdirecomp/blob/master/PROVENANCE.md):

```text title="PROVENANCE.md"
Specification locations used during the rewrite:

- SCC68070 User Manual: <https://d-nb.info/880525312/04>
- Analog Devices DS1216 product page/data sheet: <https://www.analog.com/en/products/ds1216.html>
- ICDIA CD-i technical-document catalog: <https://www.icdia.co.uk/techdocs/>
```

### What an emulator is for

Three sentences carry the whole document.

From [`PROVENANCE.md`](https://github.com/mstan/cdirecomp/blob/master/PROVENANCE.md):

```text title="PROVENANCE.md"
The device implementations above were rewritten without copying third-party
emulator source. Optional emulators may be run as black-box behavioral
comparators; their output is test evidence, not implementation authority.
```

"Test evidence, not implementation authority" is the line to keep. An emulator
can tell you that you are wrong. It cannot tell you what to write.

### Measure, then print the number

The project does not assert independence. It measures and reports.

From [`PROVENANCE.md`](https://github.com/mstan/cdirecomp/blob/master/PROVENANCE.md):

```text title="PROVENANCE.md"
The 2026-07-14 final audit found no exact sequence of 24 or more code tokens
shared between project source and either local third-party checkout. Validation
aligned 659,998 near-full-boot instruction transitions with zero skips,
resynchronizations, timing mismatches, or cumulative cycle drift; all focused
unit tests and Release shell/media/navigation smokes passed.
```

### Keep the oracle out of the build

The comparator is named, and the file says where it is not.

From [`PROVENANCE.md`](https://github.com/mstan/cdirecomp/blob/master/PROVENANCE.md):

```text title="PROVENANCE.md"
## Excluded third-party tools

CeDImu is an optional, git-ignored local oracle checkout. Its source, local
patches, and resulting `CdiOracle` binary are not part of this repository's
player or recompiler targets and are never packaged.
```

A release contains the runtime only. The recompiler, the oracle, development
tools, user-supplied ROM and disc images, traces and build outputs are all
excluded.

### Remove it from history too

Deleting a vendored tree leaves it in every earlier commit. This project says
what it did.

From [`PROVENANCE.md`](https://github.com/mstan/cdirecomp/blob/master/PROVENANCE.md):

```text title="PROVENANCE.md"
The formerly vendored AGPL clown68000/clowncommon trees and their cycle-probe
adapter were removed on 2026-07-14. Neither `CdiRuntime` nor `CdiRecomp` now
includes, links, or requires them. Local historical checkouts remain ignored.
Ahead of this repository's public release the entire `external/clown68000` and
`external/clowncommon` history was stripped with `git filter-repo`, so no
vendored third-party emulator source remains in any commit.
```

The recompiler subtree carries a matching note: CD-i cycle timing now comes from
the project's own SCC68070 model, transcribed from the user manual, and no
third-party CPU core is compiled or linked.

### Record inherited code with a commit

Code from the author's own earlier project is recorded as precisely as code
written from a specification: repository, branch, commit, what was copied, and
the date.

From [`recompiler/PROVENANCE.txt`](https://github.com/mstan/cdirecomp/blob/master/recompiler/PROVENANCE.txt):

```text title="recompiler/PROVENANCE.txt"
Ancestor: F:\Projects\segagenesisrecomp\SonicTheHedgehogRecomp\segagenesisrecomp
Branch:   dev
Commit:   5aa0c4f (sonic3: add Sonic 3 (USA) standalone mode)
Copied:   author-owned recompiler/src 68000 frontend
Date:     2026-05-28

The frontend came from another repository by the same author and has since
diverged for CD-i. GenesisRom naming remains pending shared-module extraction.
```

### Write the rule down

The file ends by turning the record into policy.

From [`PROVENANCE.md`](https://github.com/mstan/cdirecomp/blob/master/PROVENANCE.md):

```text title="PROVENANCE.md"
## Audit rule

Any future production implementation must cite a hardware specification,
author-owned ancestor, or project-owned experiment/test. Third-party source may
be isolated as a separately licensed development tool, but it must not be used
as source text for the player implementation or enter a player/recompiler build.
```

## Why keep a record like this?

Each piece is cheap to write and answers a question that cannot be answered
later. Where the DS1216 clock came from has a row, a data sheet URL and a test
file, not somebody's memory. The audit gives a threshold and a result, so the
claim is bounded. The oracle is git-ignored and named as excluded, so a
development tool cannot ship by accident.

[ndsrecomp](https://github.com/mstan/ndsrecomp) applies the same reasoning to a
choice made before any code was written. A dependency was rejected, and the
reason was recorded next to the one picked instead.

From [`THIRD_PARTY_ATTRIBUTION.md`](https://github.com/mstan/ndsrecomp/blob/main/THIRD_PARTY_ATTRIBUTION.md):

```text title="THIRD_PARTY_ATTRIBUTION.md"
**xBRZ was rejected on licensing grounds.** DeSmuME's texture upscaling
vendors Zenju's xBRZ (`desmume/src/filter/xbrz.cpp`), which carries
`GNU General Public License: http://www.gnu.org/licenses/gpl-3.0` with no
"or later" clause, plus a MAME-specific linking exception that does not
apply here. Combining GPL-3.0-only code into this runner would force the
whole executable to be conveyed as GPL-3.0 exactly, stripping the "or
later" option from every downstream recipient. xBRZ is "xBR, Zenju
enhanced", so xBR-lv2 is the same algorithm family without that cost. No
DeSmuME source is used.
```

## What the projects have not proved

ndsrecomp ran the same kind of audit and said at once what it does not establish.

From [`THIRD_PARTY_ATTRIBUTION.md`](https://github.com/mstan/ndsrecomp/blob/main/THIRD_PARTY_ATTRIBUTION.md):

```text title="THIRD_PARTY_ATTRIBUTION.md"
The native implementation uses melonDS as a behavioral and timing reference.
An audit before the first public release found no exact normalized six-line
code block shared between the tracked native recompiler/runtime sources and
the pinned melonDS source tree. That mechanical check cannot prove independent
authorship; provenance comments and the repository history remain the primary
record.
```

The same file carries a dated correction naming a notice that was missing.

From [`THIRD_PARTY_ATTRIBUTION.md`](https://github.com/mstan/ndsrecomp/blob/main/THIRD_PARTY_ATTRIBUTION.md):

```text title="THIRD_PARTY_ATTRIBUTION.md"
  Correction, 2026-08-16: this section previously listed all seven of
  those files as byte-identical to upstream. They were not — the adaptive
  widescreen work modified them without recording a change notice. The
  patches and this list are the correction; no upstream behaviour claim
  was affected, but the GPLv3 §5(a) notice was missing and is now present.
```

cdirecomp's [`BIOS-CLOSEOUT.md`](https://github.com/mstan/cdirecomp/blob/master/BIOS-CLOSEOUT.md)
closed a milestone on 2026-07-14: the non-launching CD-RTOS player shell running
on a user-supplied CD-i 490 system ROM. Then it says what it did not prove.

From [`BIOS-CLOSEOUT.md`](https://github.com/mstan/cdirecomp/blob/master/BIOS-CLOSEOUT.md):

```text title="BIOS-CLOSEOUT.md"
## What moves to the next chapter

The closeout does not claim that every SCC68070 facility or every possible ROM
path has executed. I2C, DMA, MMU translation, additional exception variants,
CIAP application-sector delivery, audio, and dynamically loaded OS-9 code stay
on the platform/game backlog. They are no longer speculative blockers for a
BIOS shell that does not use them; the Hotel Mario loader path will drive their
implementation and add focused regressions when it reaches them.
```

The regression that proves the milestone is `tools/bios_options_smoke.py`. It
creates a fresh battery image, lets the real BIOS set it up, reboots from that
image, clicks through Options, Storage and Exit, and confirms that a headless run
neither loads nor rewrites player NVRAM.

## The same discipline elsewhere in the fleet

Other repositories apply pieces of it without writing a `PROVENANCE.md`.

**Only metadata crosses from a decompilation.**
[MinishCapRecomp](https://github.com/mstan/MinishCapRecomp) states what enters
its repository from an open decompilation project.

From [`README.md`](https://github.com/mstan/MinishCapRecomp/blob/main/README.md):

```text title="README.md"
Only **symbol metadata** (function names, addresses, sizes) from the
[`zeldaret/tmc`](https://github.com/zeldaret/tmc) decompilation enters this repo —
never its C source, PC-port runner, or toolchain. **The ROM is never
redistributed**; you supply your own legally-dumped copy.
```

**An unlicensed upstream is an assumption, not a grant.**
[SuperMarioBrosNESRecomp](https://github.com/mstan/SuperMarioBrosNESRecomp)
claims no more than it knows about a repository that publishes no license.

From [`THIRD-PARTY-LICENSES/README.md`](https://github.com/mstan/SuperMarioBrosNESRecomp/blob/master/THIRD-PARTY-LICENSES/README.md):

```text title="THIRD-PARTY-LICENSES/README.md"
**That repository publishes no license.** Verified 2026-08-07 via the GitHub
API (`license: null`); the repository root carries no license file. For the
initial Captain Falcon release, the project owner has directed this project to
treat the community/decomp-derived controller as permissively reusable. That
is a project publication assumption, not a verified upstream license grant or
a legal conclusion about the upstream repository.
```

The same file explains why a submodule is not redistribution. It records a URL
and a commit, and the ingest script copies only names and addresses: no ROM
bytes, no instruction text, no commentary.

**A vendoring with a reproducible transform.**
[snesrecomp](https://github.com/mstan/snesrecomp)'s attribution file gives the
steps to regenerate its vendored 65816 core from upstream, and names the opcode
harness that checks the result.

## The BIOS question, per project

A console BIOS is the sharpest case: a file the project neither wrote nor owns.
The answers differ by console, in each repository's own words.

### PlayStation: one image is bundled

[psxrecomp](https://github.com/mstan/psxrecomp) is the only project here that
ships a console image, and it is a from-scratch replacement, not a dump.

From [`docs/BIOS_SELECTION.md`](https://github.com/mstan/psxrecomp/blob/master/docs/BIOS_SELECTION.md):

```text title="docs/BIOS_SELECTION.md"
A PlayStation game needs a BIOS. PSXRecomp can supply one — **OpenBIOS**, an
MIT-licensed, from-scratch PS1 BIOS from the PCSX-Redux project that we are
allowed to redistribute — so a player can be handed a build and a disc image and
just play. A player who prefers their own dumped retail BIOS can use that
instead.

Both recompiled BIOS backends are linked into every normal build. The OpenBIOS
image itself and its MIT notice are staged in `bios/` beside the executable;
the retail image is never shipped and comes from the player. Which backend runs
is decided when the game launches, not when it is built.
```

The `bios/` directory holds four files. What is missing matters too.

| File | What it is |
|---|---|
| `openbios.bin` | The bundled OpenBIOS image, 524,288 bytes |
| `OpenBIOS.LICENSE` | Its MIT notice |
| `OpenBIOS.toml` | Build profile, upstream pins, image identity |
| `SCPH1001.toml` | Build profile for the retail backend. No retail image is present |

The image's identity and redistributable status live in the config, not in prose.

From [`bios/OpenBIOS.toml`](https://github.com/mstan/psxrecomp/blob/master/bios/OpenBIOS.toml):

```toml title="bios/OpenBIOS.toml"
[program.image]
sha256          = "fabe498fbf224e4721f12f31b6f5fe0659205e341dc4e5c5f91b9bd1a1011c57"
license         = "MIT"
redistributable = true
```

No BIOS chosen means OpenBIOS. A BIOS the player chose means that BIOS. OpenBIOS
can also be switched off per title, and then the player must supply a retail
dump.

From [`docs/BIOS_SELECTION.md`](https://github.com/mstan/psxrecomp/blob/master/docs/BIOS_SELECTION.md):

```text title="docs/BIOS_SELECTION.md"
Set `openbios = false` only for a title with a **verified** OpenBIOS
incompatibility. Per-title compatibility is not implied by the framework
supporting OpenBIOS — verify a title before shipping it that way.
```

The document closes with one packaging rule: the notice and the image travel
together.

From [`docs/BIOS_SELECTION.md`](https://github.com/mstan/psxrecomp/blob/master/docs/BIOS_SELECTION.md):

```text title="docs/BIOS_SELECTION.md"
## Attribution

OpenBIOS is MIT-licensed. Its notice is vendored at `bios/OpenBIOS.LICENSE`,
with the upstream source pin and build recipe in `bios/OpenBIOS.toml` and
attribution in `THIRD_PARTY_ATTRIBUTION.md`. Builds that ship it credit the
PCSX-Redux authors in the launcher, whether or not the licence compels it.

Native runtime builds automatically stage both `bios/openbios.bin` and
`bios/OpenBIOS.LICENSE`. Release packaging must copy that directory as a unit;
shipping the image without its notice violates the distribution contract.

Retail BIOS images are **not** redistributable and are never shipped. A player
using one supplies their own dump.
```

The notice also credits [uC-sdk](https://github.com/grumpycoders/uC-sdk), whose
permissively licensed code is linked into the OpenBIOS binary and whose own terms
require the mention.

### CD-i: nothing is bundled

cdirecomp ships no BIOS at all. Its `README.md` says it ships no copyrighted
material, no BIOS ROM, no disc images and no game-derived generated code. The
player system ROM comes from the user. See [CD-i](https://retroportingtoolkit.com/docs/platforms/cd-i.md).

### Game Boy Advance: required, never bundled

gbarecomp needs the console BIOS and does not ship it. It runs the real BIOS
instruction by instruction rather than stubbing it.

From [`bios/README.md`](https://github.com/mstan/gbarecomp/blob/main/bios/README.md):

```text title="bios/README.md"
Drop your own dump of the GBA BIOS here as `gba_bios.bin`. The binary
**is not in git** (it's copyrighted Nintendo code) but the `.toml` /
`.md` / `.sym` files in this folder ARE tracked, so the path layout
matches between developer machines.
```

That is also why it does not high level emulate the SWIs, stub the intro, or
fast-forward through boot: the BIOS is part of what it recompiles through. See
[High level and low level](https://retroportingtoolkit.com/docs/concepts/hle-and-lle.md).

### Nintendo DS: retail dumps by default

ndsrecomp offers both and says which one is authoritative.

From [`README.md`](https://github.com/mstan/ndsrecomp/blob/main/README.md):

```text title="README.md"
An opt-in no-dump path also exists (`--freebios --generated-firmware
--boot direct`): the recompiled [FreeBIOS](https://github.com/mstan/freebios)
(the DraStic BIOS replacement, BSD-2-Clause, vendored as the
`third_party/freebios` submodule) plus a synthesized firmware image with a
persisted per-install identity. The retail dumps remain the default and the
oracle-diffed source of truth.
```

The vendored notice states the limit of that path.

From [`vendor/freebios/README.md`](https://github.com/mstan/ndsrecomp/blob/main/vendor/freebios/README.md):

```text title="vendor/freebios/README.md"
FreeBIOS can only pair with `--boot direct` (it cannot boot the firmware
menu), and the retail-dump path remains the default and the oracle-diffed
source of truth.
```

### SNES: coprocessor firmware is not shipped

Some SNES cartridges carry a coprocessor with its own data ROM, separate from the
game ROM. snesrecomp does not redistribute the Cx4 data ROM, `.gitignore` refuses
it, and the loader reports loudly when it is missing instead of computing on
zeros. The requirement is measured: on Mega Man X2's boot self-test the Cx4 program
reads all 1024 data-ROM entries. Where no firmware exists, the DSP-1 high level
model answers only the commands it has verified.
