# Modding is a requirement, not a later feature The port has two goals, and the second one constrains the first: **the exported asset tree is a product**, not a build artefact. Someone who has never read this repository should be able to open the tree, understand what they are looking at, change something, and see it in the game. That is a design constraint on the **exporter**, today — not a milestone to add later. Custom *behaviour* (scripting) is a later milestone, but nothing built now may make it harder. ## The five rules **1. One logical asset, one file. Never split.** A sprite is one PNG. A track is one OGG. A screen is one JSON. This is a real constraint and not a platitude, because **the disc does the opposite everywhere**: a `.pak` entry spans segment files, a bank holds several sub-waves, and a cutscene voice is a byte region of a continuous stream chunked across entries whose boundaries do not match the cues. All of that is the *exporter's* problem to resolve. If a modder has to reassemble anything, the export is unfinished. **2. Names a person recognises.** `screens/title/main_menu.json`, not `0x90822a39.json`. Where the disc's own name was never recovered — the six `*2D` archives, `GP_READY_ROOM` — emit a stable synthetic name **and say in the file that the real one is unknown**, so a modder can tell a recovered name from an invented one. **3. Modern, editable formats only.** | kind | format | why | |---|---|---| | data, layout, config | **JSON** | Godot parses it natively (`JSON.parse_string`); every tool speaks it | | images | **PNG** | RGBA8, lossless, opens anywhere | | audio | **Ogg Vorbis** | Godot-native, no licence trap | | video | **Ogg Theora** | the only format Godot 4 plays natively | | text | **UTF-8** | never UTF-16BE, whatever the disc did | Not XML: Godot's `XMLParser` is a SAX-style API needing a hand-written binding per schema, where JSON is one call. Not a custom binary container, ever — that would rebuild the exact wall this port exists to remove. **4. Base and overrides, never one merged pile.** ``` data/ base/ generated from your disc by the exporter. Gitignored. Rewritten wholesale -- never hand-edit it, your changes will vanish. mods/ drop-in overrides. Yours. The exporter never touches this. ``` A mod replaces a file by shadowing its path. A modder edits nothing under `base/`, so re-exporting is always safe, and "did I break it?" is answered by disabling a mod rather than by re-extracting the disc. **5. Provenance in every generated file.** Source archive, entry index, exporter version. It is what lets someone check a file against the disc instead of trusting it — and what stops the export drifting into an unverifiable fork of the original. ## Not blocking scripted mods later Behaviour modding is a later milestone. Two decisions now keep the door open: * **The loader is data-driven and screen-agnostic.** No screen name is hardcoded in GDScript. A screen is *whatever the JSON describes*, so a mod that adds a new screen needs no engine change. * **No GDExtension, no native code in `port/`.** [Godot Mod Loader][gml] — the established option, Godot 4.1–4.3, used by Brotato and Dome Keeper — works by substituting **GDScript** at load time. A port whose logic lives in GDScript stays moddable by it; one that hides logic in native code does not. Adopting a mod loader is a decision for that milestone. Making it *possible* is a constraint on this one. [gml]: https://github.com/GodotModding/godot-mod-loader ## What this rules out, explicitly * Atlases or packed archives of sprites — one file per sprite. * Any format needing our code to read it. * Hash-named files. * Hand-edited files under `data/base/`. * Splitting one playable thing across files to mirror how the disc stored it.