Add a project.
Yours or someone else’s, a new row, a correction or a claim. Both routes end in the
same place: a validated row on the board, written by a bot within a few minutes. No human
queue, nothing waiting on anyone’s attention.
Route A · Your own repository, no account needed
Commit a file
Put .recomp.json at the root of your repository. Your row says what
the file says, and editing the file edits the row. Whoever can commit there decides,
which is proof enough, and it is the way for a repository owned by an organisation.
Any coding assistant can write the file for you.
How to write the file
Route B · Anyone with a GitHub account
Fill in a form
For your project or someone else’s, a correction, or claiming your row. Guided
fields, no JSON. The bot checks the repository, writes the row and answers in the issue.
For someone else’s repository only the facts are kept; its owner writes the rest.
Open the forms
Claiming a row someone else added
Commit a .recomp.json to your repository, or send the form from the
GitHub account that owns it. The row loses its unclaimed mark, only you can edit it from
then on, and the periodic scan stops touching it. A form records the status and notes as
they are the day you send it, and changing them means sending it again; the file is read
every day, so editing it keeps the row current on its own, which makes it the better way
for a project that moves. The claim is for the repository: if it
has a decomp row and a recomp or source port row, one form claims both, and choosing
“both” as the kind of work adds the one that is missing. Deleting the file, or ticking
“Release my claim” in the form, hands them back whenever you want.
Games from consoles still on sale
Projects for games from the Switch, Switch 2, PS5 and Xbox Series are not shown on the
board, out of respect for games their makers still sell. A project that
brings an older game to one of them is shown like any other.
If your project is a decomp
A decomp that publishes an objdiff progress report needs no file and no form to show its
progress: the board reads the report every day. Upload build/report.json as a
GitHub Actions artifact named VERSION_report (for example
SLUS_203.88_report), from a workflow that runs on your default branch. The game page
then shows the share of matched code, and the status In progress until it reaches 100%,
then Complete once the report also matches all the data, unless you have set a status
yourself. When the repository publishes
several versions of the game, a figure appears only if one of them is the release your row
works from (the original field of the file) or if they agree within half a point.
A file or the form still adds what a report cannot say: who maintains the project, whether it
is paused or only exploring, notes, the help you want and the release you work from.
If you don’t use GitHub
The repo can live on GitLab, Codeberg, sourcehut or your own server. Any public
HTTPS repository is accepted, and for the hosts with a public API the commit date and
release tag are pulled from there too. Self-hosted repos keep the same row; the daily check
confirms the URL still answers, and the commit date is whatever your repo feed reports.
Route A needs no account anywhere: the file is read from your own host. Only the first
listing of a repository outside GitHub goes through the one-field
manifest form,
which needs a free GitHub account, or through the periodic sweep. What’s not accepted
is a row with no public code behind it anywhere; that’s rule 01, and it’s the
only thing keeping the table honest.
Route A in detail
.recomp.json, the file that owns your row
Commit it at the root of your repository. The format is open and
described on its own page, so other lists and tools can read the
same file: you write it once. On GitHub the daily job finds it on its own, even
for a repository that isn’t listed yet; to be listed right away, or on another host,
give its address with the
manifest form.
Every field is optional on a row that exists; a new row needs game,
system and type. Leave a field out and the row stays empty there.
Remove the file and the row goes back to unclaimed: it keeps the status, the platforms
the build runs on, the method and the toolchain the file last named, and the rest of what
the file said is cleared.
{
"$schema": "https://recomp.fyi/schema/v1.json",
"game": "Wave Race 64",
"wikidata": "Q3142278",
"system": "N64",
"type": "recomp",
"original": { "region": "USA", "revision": "1.0" },
"project": "Wave Race 64 Recompiled",
"status": "playable",
"targets": ["Windows", "Linux", "Steam Deck"],
"toolchain": "N64recomp",
"approach": "Static recompilation, RT64 renderer",
"maintainers": [{ "name": "yourhandle", "link": "https://your-profile" }],
"links": [{ "label": "Discord", "url": "https://discord.gg/..." }],
"help": ["Audio timing", "Controller mapping on Linux"],
"notes": "What works, what's next, what hurts."
}
Works on GitHub, GitLab, Codeberg and any Gitea or Forgejo instance. The board never
writes to your repository, it only reads that one file. A file committed under its first
name, .recomp-board.json, keeps working. A repository that is both a
decomp and a recomp writes "type": ["decomp", "recomp"] and gets one row
of each; a decomp with its source port writes ["decomp", "port"]. A
repository that holds several games keeps .recomp.json for the first and adds
one file per other game, .recomp-2.json up to .recomp-9.json, each
with the same fields: every file gets its own row.
Every field and the values it takes
Built from the code that reads the file, so it is always the list the board applies.
Anything longer than the limit is cut, and a value the board can’t use is dropped.
type | "recomp": the original binary translated by a recompiler. "port": a source port, the game built natively from decompiled, disassembled or rewritten source, an engine rewritten from the game's file formats included. "decomp": source that rebuilds the original binary. A repository that does two of them writes a list, ["decomp", "recomp"] or ["decomp", "port"], and gets one row of each. |
|---|
status | "unknown" Not declared: Nobody has said. The maintainer sets it when they claim the row."exploring" Exploring: Feasibility, tooling, no promises yet."in-progress" In progress: Actively being worked on."playable" Playable: Runs start to finish, rough edges remain."released" Released: Public build, still maintained."complete" Complete: Finished: a decomp whose source fully rebuilds the original, or a recomp or source port with no further work planned. The activity clock stops."paused" Paused: On hold. Say so rather than going quiet.
|
|---|
system | The platform of the original binary you work from, whether you recompile it, decompile it or port the game from its decompiled source. One name, or a list of up to 8: "Xbox Series" "Xbox 360" "Xbox One" "Xbox" "PS5" "PS4" "PS3" "PS2" "PSP" "PS Vita" "PS1" "Wii U" "Wii" "GameCube" "N64" "Switch 2" "Switch" "SNES" "GBA" "GBC" "GB" "NDS" "3DS" "Virtual Boy" "NES" "Master System" "Game Gear" "Sega CD" "3DO" "Atari Lynx" "Atari Jaguar" "N-Gage" "CD-i" "32X" "Saturn" "Dreamcast" "Genesis" "Neo Geo Pocket Color" "Neo Geo" "Arcade" "PC (DOS)" "PC (Windows)" "Mac" "Amiga" "Atari ST" "Commodore 64" "ZX Spectrum" "Amstrad CPC" "MSX" "MSX2" "PC-98". A usual other spelling of these ("PlayStation", "Nintendo 64") is read as the name here; a platform that is not listed is kept as written. For a port of source code its authors released, the platform that source was written for. |
|---|
targets | Where your build runs, a list of up to 8: "Windows" "Linux" "macOS" "Steam Deck" "Android" "iOS" "Switch" "Browser". A console is written with its system name, "PC (Windows)" as Windows, and a processor is dropped ("Linux (ARM64)" is Linux). Anything else is kept as written when it reads as a platform name; an address or a sentence is left out. |
|---|
toolchain | "N64recomp" "Xenonrecomp" "Rexglue" "Xboxrecomp" "Ps3recomp" "Ps2recomp" "Psxrecomp" "Psxport" "Recompone" "Snesrecomp" "Nesrecomp" "Gbarecomp" "Gb-recompiled" "Segagenesisrecomp" "Wiicompiled" "Dolrecomp" "Neogeorecomp" "3dsrecomp" "Shiftglue" "Xboxxberecomp" "Pcrecomp" "Bbport" "Arcade-decomp" "Decomp-toolkit" "Splat". Another name is kept, capital first letter, up to 32 characters. One name, or a list of up to 4 when the project is built on several; two names typed as one ("A / B") are read as a list. The decompilation a source port is built from is not a toolchain and is left out, and so is a word that names no tool ("Unspecified"). |
|---|
game | The title as it shipped, up to 120 characters. |
|---|
wikidata | The game's Wikidata item, "Q…" with digits. Shown on the row as a link. |
|---|
original | The release you work from: { "region": "…", "revision": "…", "serial": "…", "sha1": "…" }, each part optional and up to 40 characters, sha1 as 40 hex digits. A list of up to 6 when you support several. Shown on the row. |
|---|
project | Your project's name, up to 120 characters. |
|---|
approach | The method in one line, up to 200 characters. |
|---|
started | Optional. When the work began, "YYYY-MM-DD", for a repository younger than the project (moved, or cut from a private history). Shown as Started instead of the repository's creation date. |
|---|
notes | Up to 600 characters. |
|---|
help | What you'd take a hand with: up to 8 short phrases of 120 characters. |
|---|
tags | Up to 8 words of 24 characters. |
|---|
maintainers | Up to 6: { "name": "…", "link": "https://…" }, name up to 60 characters, link optional and https only. |
|---|
links | Up to 6: { "label": "…", "url": "https://…" }, label up to 32 characters. Never a game file. |
|---|
mirrors | Up to 4 addresses of other copies of the same code ("https://codeberg.org/…", GitLab, Forgejo, a server of your own). Shown next to the repository. |
|---|
moved | When the project leaves this repository: the new address. Put a .recomp.json there too and the row follows, claim and history included. Can be the only field of the file left in an archived repository. |
|---|
previously | In the new repository, when the old one was deleted: the old address. The old row joins the new one when the old repository is gone or archived and nobody else holds that row. |
|---|
The whole file stays under 8 KB and never mentions a ROM, an ISO or where to get one: a file that does is refused whole. version, builds and lastCommit are read from the repository every day, so leave them out. $schema and x- fields are ignored.