Skip to content

Tutorial Overlays

johnjohto edited this page Jul 25, 2026 · 2 revisions

Tutorial: Overlays (Modernization Recipes)

An overlay is a versioned recipe that transforms a project you already have into a derived one — the mechanism behind Project Vermilion, and the reason we can ship a "modernized Kanto" without shipping any Kanto: you apply the recipe to your own extraction, on your machine.

Applying one

python tools/apply_overlay.py --overlay overlays/vermilion --base game/project --out build/vermilion
  • The base is read-only by construction — the derived project lands beside it, fully self-contained.
  • Re-running the same apply is byte-stable (the double-apply is a release gate).
  • The derived project's identity hashes are recomputed honestly, so link play between differently-derived projects refuses at the handshake instead of desyncing.

Writing one

An overlay is a folder with an overlay.json and its payload files:

{
 "id": "myoverlay",
 "name": "My Overlay",
 "format": 1,
 "base": {"id": "kanto", "format": 2},
 "ops": [
  {"op": "merge",   "target": "presentation/version.json", "with": "merge/version.json"},
  {"op": "copy",    "target": "assets/backdrops/myscene.png", "from": "files/myscene.png"},
  {"op": "replace", "target": "presentation/backdrops.json", "from": "files/backdrops.json"},
  {"op": "delete",  "target": "data/scripts/old.json"}
 ]
}
  • base pins the project id and format the recipe expects; a mismatched base refuses before any byte moves.
  • Four ops, applied in order: merge (JSON merge-patch: objects merge deep, null deletes a key, arrays replace whole), copy (new file), replace (existing file), delete.
  • Every payload file under the overlay folder must be referenced exactly once — an unused or doubly-used payload refuses.
  • JSON results re-emit in canonical bytes, so derived projects diff and hash cleanly.

The shipped overlays/vermilion/ is the living example — its ops turn on widescreen, palettes, the glow shader, backdrops, and the QoL pair, one small file each.

Clone this wiki locally