recomp.board

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.
systemThe 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.
targetsWhere 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").
gameThe title as it shipped, up to 120 characters.
wikidataThe game's Wikidata item, "Q…" with digits. Shown on the row as a link.
originalThe 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.
projectYour project's name, up to 120 characters.
approachThe method in one line, up to 200 characters.
startedOptional. 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.
notesUp to 600 characters.
helpWhat you'd take a hand with: up to 8 short phrases of 120 characters.
tagsUp to 8 words of 24 characters.
maintainersUp to 6: { "name": "…", "link": "https://…" }, name up to 60 characters, link optional and https only.
linksUp to 6: { "label": "…", "url": "https://…" }, label up to 32 characters. Never a game file.
mirrorsUp 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.
movedWhen 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.
previouslyIn 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.