# Running the port **P5's gate is *"a human clicks through it"*, and until now there was no page telling a human how.** The commands existed — in `boot.gd`'s header comment and scattered through a twelve-thousand-line `DECISIONS.md`. A capability that lives only in the record is, to the person who needs it, absent. Everything below has been run. Where a number is quoted it was measured in this container, and where the container distorts it that is said rather than left for the reader to discover. ## 1. Build the asset tree The Godot project reads `export/`, never the disc. ```bash cargo run --release -p sylpheed-export -- export --disc /disc --out export ``` Roughly four minutes, most of it transcoding two movies. It **rewrites `export/` wholesale** — never hand-edit anything in there; hand-written decisions live in `authored/` beside it, and survive a re-export. ## 2. The P5 walk, from a cold start ```bash godot --path port -- --boot --play ``` This is the one a human should judge. It boots the way the game does — two splashes, the `ADV` intro, the title — hands over to the menu on Ⓐ, and then **stays live and waits for input**. | you press | what should happen | |---|---| | Ⓐ on the title | the main menu opens on **NEW GAME** | | ⬆ / ⬇ | one item, wrapping at both ends | | ⬅ / ➡ | **nothing** — measured, and implemented as an explicit no-op | | Ⓐ on **EXTRAS** | the EXTRAS submenu, opening on **MISSION SELECT** | | Ⓑ in EXTRAS | back to the main menu, **on the item you left** | | Ⓑ on the main menu | back to the title | | Ⓐ on the title again | the menu, **still on the item you left** | That last row is the one worth checking deliberately: the main menu **remembers its cursor**, and every submenu **resets** to its own opening item. Both are measured, and they disagree on purpose. ⏱ **The intro is ~157 s.** To skip straight to the menu: ```bash godot --path port -- --menu=main_menu ``` and to drive it unattended: ```bash godot --path port -- --menu=main_menu --script=down,down,down,down,accept,cancel ``` 🔴 **This example used to say `down,down,accept,cancel`, and it walked the wrong path.** Two ⬇ from the opening item lands on **`TUTORIAL`**, whose destination this export does not carry — so the example exercised a *not-carried* message and returned, never opening a submenu at all. **`EXTRAS` is the fifth item**, so it takes four. The one submenu P5's gate rests on was the one the runbook's own command did not reach. Verified 2026-08-31 by running both. 🔴 `--script` **without** `--play` or `--menu` refuses and says so. It used to parse, be stored, and do nothing. ## 3. What is knowingly missing — not bugs Four of the five main-menu destinations are **measured but not in this export**: they live in other archives (`GP_SAVE_LOAD`, `GP_OPTIONS`, …). Pressing Ⓐ on them prints what it would have opened and why it cannot: ``` (LOAD GAME) opens a screen this export does not carry: The save-slot list is GP_SAVE_LOAD, not in this export. Destination MEASURED. ``` **EXTRAS is the only Ⓐ-into-a-submenu this milestone can walk**, which is why the P5 gate rests on it. `NEW GAME` is a deliberate gap of a different kind: the real chain is NEW GAME → DIFFICULTY → SELECT DATA → the `S00A` movie, and the port **jumps to the movie**, printing the two screens it skipped. That is a gap, stated out loud; nobody should read the port's behaviour there as the game's. ## 4. What this container distorts * **No GPU.** 720p Theora decodes **+6.7 % … +6.9 % slower than real time** here (5 runs, both movies, on a quiet box). The boot's printed seconds carry that deficit. It is a property of the machine, not of the port. * **No sound card.** Godot falls back to a dummy driver, so **you will hear nothing**. The audio is present and measurable — `docs/port/AUDIO-VERIFICATION.md` answers every audio question without a device, and `tools/port/verify-menu-audio` asserts it — but *"I heard it"* is not available in here. * **A leaked-object warning at exit** is engine-side, not the port's. Measured: releasing every reference the port owns moves the count from 8 to 8. ## 5. Modding `data/mods/` shadows `export/` by path. Each override is announced as it is read, and at the end of a run any file that **can never apply** is listed: ``` mod: sprites/title/main_menu/ptbase.png <- data/mods/... mods: 1 file(s) in data/mods can shadow NOTHING -- no such path in the export: inert: sprites/title/TYPO_menu/pteff05.png ``` A file whose path exists in the export but was simply not read this run is **not** listed. See `docs/port/MODDING.md` for the five rules the asset tree keeps. ## 6. Where the work is, and what P5's gate is waiting on **P5's gate is the only one that needs a person, and it is not waiting on code.** Everything above runs from `auto/port-p6-audio`. 🔴 **This section used to quote counts — "256 commits ahead, 58 files" — and they were stale the moment they were committed, because committing them incremented the count.** By the time anyone read it, it said 256 and the answer was 258. A number written into a document meant to inform a decision **decays with every commit either agent makes**, and the Decoder hit the same thing in their own merge-state page one message after recording the class. **So what follows are the invariants, which do not move, and the commands to re-derive anything that does.** | invariant | check | **passes when** | |---|---|---| | `main` is an **ancestor** of this branch — a fast-forward, nothing to resolve | `git merge-base --is-ancestor origin/main HEAD; echo $?` | prints **`0`**. ⚠️ The command itself prints **nothing** on success — without the `echo` a reader cannot tell success from failure | | `main` is an ancestor of the Decoder's branch too | `git merge-base --is-ancestor origin/main origin/auto/build-ordinal-audit; echo $?` | prints **`0`**, same caveat | | the two change sets touch **zero files in common** | `comm -12 <(git diff --name-only origin/main...HEAD \| sort) <(git diff --name-only origin/main...origin/auto/build-ordinal-audit \| sort) \| wc -l` | prints **`0`** | | merging both produces **no conflicts** | `git merge-tree --write-tree HEAD origin/auto/build-ordinal-audit \| wc -l` | prints **`1`** — one line is the tree id; conflicts would follow it. **Read-only: this merges nothing** | **Last run here: `0`, `0`, `0`, `1`.** A command published without a pass condition is half a check — the reader gets a number and no way to know whether it is the right one — so each row states what the right one is. 📌 **So the sentence is not "N commits behind", which sounds like something to schedule. It is: two fast-forwards over disjoint file sets, mergeable in either order with zero conflicts.** Counts if you want them: `git rev-list --count origin/main..HEAD`. ### What a person is actually being asked to do 1. `godot --path port -- --boot --play`, then walk §2's table. 2. Say whether it behaves as described. **Not whether it matches the game** — that comparison is the oracle's job and is already asserted by `tools/port/check-all`. 3. If it does, P5's gate is met and nothing else is blocking P6, which asserts its own audio and has no human step. ⚠️ **You will hear nothing** (§4), and the intro takes ~157 s. `--menu=main_menu` skips straight to the part being judged.