Clearing my own debt: I withdrew navigation.md's "boot title accepts a single A" counter-example as confounded by three concurrent emulators and never re-ran it, which left the claim unsupported rather than settled. Clean trial: exactly one emulator verified by count, gated on the plate pulse (glyph in [500,2500] held 12 samples) so the press lands on the BOOT title rather than the attract loop's, delivery confirmed at [file-pad] keystroke vk=5800 down/up. Glyph after the press is 0 at +2 s and +4 s -- the transition -- then 327 steady from +6 s through +39 s. 327 is a proxy and reading a proxy is the habit this corpus keeps cataloguing, so the screen was checked with which_title_screen.py instead: main_menu at RMSE 19.91 and 20.08 with margin ~10, inside the 9.9-11.7 band its control establishes on four known captures. The before frame gives the "neither" signature at margin 0.10, correctly, since the title is neither main_menu nor extras. So the count is 3 of 3, the latency is 4-6 s -- which is why a script that presses and looks 0.5 s later concludes the press was dropped -- and the two earlier failures were the confound, not the game. Refutation attempted: sylpheed-port's leaf segment rates. Derived independently from the disc and they SURVIVE exactly -- pteff03 +4.0000 then +4.0000 then a hold, pteff03a -4.0667 then -4.0625 then a hold. So their inversion stands: my linearity gate fails on the leaf whose declared track is perfectly straight. And records the third structural consequence of main being stale, which they raised: HANDOFF.md is the delivery contract and it lives on an unmerged branch, so their checkout contains none of this week's entries. Findings written into the contract reach them only through messages -- the channel the protocol says does not count as delivery. Writing it in the contract is necessary and not sufficient when the contract lives where the other party cannot see it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
373 lines
20 KiB
Markdown
373 lines
20 KiB
Markdown
# Playing the game: every screen, and how you move through it
|
||
|
||
**Written from the player's chair.** What is on screen, what you press, what
|
||
happens. This is the document you would hand someone who has never seen the game
|
||
and wants to reach a mission — or who needs to script that journey.
|
||
|
||
Internal names (`ptbtn03`, `GP_LOAD`, build numbers) appear only as footnotes,
|
||
because they are how *we* find things, not what the game shows anyone.
|
||
|
||
**Status:** filling in. §1–§4 now carry what the committed oracle frames actually
|
||
show; what is still ❔ is what no capture answers. This page exists to be filled
|
||
in by playing, not to look finished.
|
||
|
||
> ## ⚠️ Fill this in from the real game
|
||
>
|
||
> The oracle is **Xenia Canary running the actual title**, captured. Not
|
||
> `sylpheed-cli`, not the Explorer, not any renderer of ours — those are tools
|
||
> for verifying our decoding, they are hypotheses under test, and they have been
|
||
> wrong. A row here with no capture behind it is a guess wearing a table cell.
|
||
>
|
||
> Describe what you *saw*. "The cursor starts on the second item" is worth more
|
||
> than any amount of reasoning about the layout data.
|
||
|
||
Confidence: ✅ seen in a capture · 🟡 inferred · ❔ unknown.
|
||
|
||
---
|
||
|
||
## 1. From power-on to the main menu
|
||
|
||
| # | What you see | What you do | What happens |
|
||
|---|---|---|---|
|
||
| 1 | **SQUARE ENIX** in white on black, the two dots in red, `™` after it ✅ | nothing | fades on to the next logo |
|
||
| 2 | **GAME ARTS**, **SETA** and **studio anima** stacked on black ✅ | nothing | fades on into the cinematic |
|
||
| 3 | The opening cinematic | **Ⓐ** skips it ✅ | ends into the title |
|
||
| 4 | **Title screen** — the wordmark appears **first, with no prompt**; `PRESS Ⓐ BUTTON` fades in **2.13 s** later, above the 2006/2007 Square Enix copyright line, and then pulses about every 2.2 s ✅ | press **Ⓐ** | goes to the main menu ✅ |
|
||
| 5 | **Main menu** | — | see §2 |
|
||
|
||
✅ **The order is publisher then developer, confirmed in three cold boots
|
||
(2026-08-29)** — `SQUARE ENIX` for ~4.3 s, a ~0.25 s black hold, then
|
||
`GAME ARTS` / `SETA` / `studio anima` for ~3.5 s, and both dwells are declared on
|
||
the disc (240 and 195 keyframe units). ⚠️ There is a **third** SQUARE ENIX
|
||
wordmark about ten seconds in — bloomed, below centre — and it is the opening
|
||
card of the intro movie, not a splash.
|
||
[the three frames side by side](../re/captures/boot-order/splash-order-two-runs.png) ·
|
||
[`boot-order-and-splash-dwell.md`](../re/boot-order-and-splash-dwell.md)
|
||
|
||
Both logo screens are **still pictures the game draws**, not video — neither is a
|
||
`.wmv` on the disc. Captures:
|
||
[publisher](../re/captures/title-builds/live-splash-publisher.png) ·
|
||
[developer](../re/captures/title-builds/live-splash-developer.png) ·
|
||
[title](../re/captures/title-builds/live-title-press-a.png).
|
||
|
||
⚠️ **One Ⓐ skips the cinematic**, and it is worth a lot of time: the title
|
||
arrived at **57 s** with the skip against **193 s** without it ✅.
|
||
|
||
⚠️ **The title screen has two states that look identical.** The one that ends
|
||
the boot accepts Ⓐ. The one the attract loop returns to, after the game has sat
|
||
untouched and looped back, **accepts nothing** — Ⓐ, START, B, BACK, X, Y, dozens
|
||
of presses, no response. Nothing on screen distinguishes them ✅. If you are
|
||
scripting: use the *first* title after boot, and do not press anything during the
|
||
boot.
|
||
|
||
⚠️ **The title is not input-ready for about ten seconds** after it appears ✅.
|
||
And even then Ⓐ registers roughly half the time, with nothing yet found that
|
||
predicts which ✅ — budget retries.
|
||
🔴 **Refutation attempt, 2026-08-29 — both halves of that came out wrong on the
|
||
runs I could test.** Two boots, Ⓐ pressed **7.29 s** and **7.28 s** after the
|
||
title art settled (5.15 s and 5.15 s after the prompt appeared): **accepted both
|
||
times, first press, no retry**, and each went straight on to the main menu. Ⓑ on
|
||
the menu was then also accepted first press, both runs.
|
||
⚠️ Reach: **n = 2**, so "half the time" is only made unlikely (2/2 has p ≈ 0.25
|
||
under it), not excluded — but *"not input-ready for about ten seconds"* is
|
||
contradicted outright, because 7.3 s worked twice. Keep the retry budget; drop
|
||
the ten-second wait. Evidence:
|
||
[run 1](../re/data/plate-timing-run1.tsv) · [run 2](../re/data/plate-timing-run2.tsv) ·
|
||
[`title-plate-delay-measured.md`](../re/title-plate-delay-measured.md).
|
||
|
||
⚠️ **The prompt takes 2.13 s to arrive, measured twice (2.138 s / 2.132 s).**
|
||
Timed from the moment the wordmark stops animating, not from the moment it first
|
||
appears — the build-in itself varies by half a second between runs.
|
||
|
||
---
|
||
|
||
## 2. Main menu
|
||
|
||
Five options in a vertical stack, roughly centred, with a highlighted state on
|
||
the focused one.
|
||
|
||
> ✅ **The focused option carries a small ring to the left of its label, and the
|
||
> ring turns — continuously, about once every 2.2 s.** It has a bright head, so
|
||
> you can see it go round. It is the **only** thing moving on this screen once it
|
||
> has settled: the labels, the bracket and the footer are all completely still
|
||
> (temporal std exactly 0.000 over 20 s). Ⓑ
|
||
> [five frames, 4 s apart](../re/captures/focus-ring/ring-single-frames-4s-apart.png) ·
|
||
> [the measurement](../re/focus-ring-spin-measured.md)
|
||
|
||
| position | label | what it opens |
|
||
|---|---|---|
|
||
| 1 | **NEW GAME** | a **DIFFICULTY** prompt, then **SELECT DATA** ✅ |
|
||
| 2 | **LOAD GAME** | the save-slot list ✅ |
|
||
| 3 | **TUTORIAL** | the lesson list ✅ |
|
||
| 4 | **OPTIONS** | the settings menu ✅ |
|
||
| 5 | **EXTRAS** | a three-item submenu ✅ |
|
||
|
||
Read off [`live-main-menu.png`](../re/captures/title-builds/live-main-menu.png);
|
||
destinations off
|
||
[`q4-destinations.png`](../re/captures/menu-nav/q4-destinations.png) and
|
||
[`newgame-difficulty.png`](../re/captures/newgame-path/newgame-difficulty.png).
|
||
|
||
The screen is the title art gone dim, with the wordmark ghosted behind the list
|
||
and a bracket of glowing rule-lines drawn around it. The focused item is bright
|
||
white with a **spinning ring** to its left; the others are dim blue. Every item
|
||
carries a small dot-in-circle at the left end of its underline — that is on all
|
||
five all the time and is *not* the cursor.
|
||
|
||
**Moving around ✅**
|
||
|
||
| you press | what happens |
|
||
|---|---|
|
||
| ⬆ / ⬇ | one item, and it **wraps** at both ends |
|
||
| ⬅ / ➡ | nothing |
|
||
| Ⓐ | opens the focused item |
|
||
| Ⓑ | 🟡 back to the title — see the warning below |
|
||
|
||
❔ **Which item is focused when the menu opens is not fixed.** Four boots of the
|
||
same harness opened on `TUTORIAL`, `TUTORIAL`, `NEW GAME`, `NEW GAME`. Do not
|
||
assume the top item, and do not assume the middle one either.
|
||
|
||
> ⚠️ **The main menu is the one screen whose footer does not offer Ⓑ.** It reads
|
||
> `⊙ : Select Ⓐ : OK` — every submenu adds `Ⓑ : Back`. Measured: **zero**
|
||
> red-Ⓑ glyph pixels anywhere in the frame, on two captures, with the same
|
||
> detector finding the glyph on `EXTRAS` and `DIFFICULTY` ✅.
|
||
> ✅ **But Ⓑ does leave it, and the objection that stood here is refuted
|
||
> (2026-08-29).** This page used to say the title "returns on its own after
|
||
> ~8–10 s idle", so an observer could not tell Ⓑ from the timer. That timer
|
||
> belongs to the **title**, not to this screen: the main menu was held untouched
|
||
> for **≥ 60 s** and never moved. Ⓑ is delivered and is the only input in ≥ 100 s
|
||
> before the return, so the ordering is measured — the *latency* is not
|
||
> ([the measurement](../re/menu-idle-and-b-2026-08-29.md)).
|
||
|
||
*Internals: `GP_TITLE.pak` build 5; buttons `ptbtn01`–`ptbtn05` top to bottom.*
|
||
|
||
---
|
||
|
||
## 3. The rest of the menus
|
||
|
||
One section each, in the shape of §2: what is on screen, what the cursor does,
|
||
what each choice leads to, and what a wrong choice shows you.
|
||
|
||
### New game ✅
|
||
Ⓐ on `NEW GAME` does **not** start a mission. It opens **DIFFICULTY** —
|
||
`EASY` / `NORMAL` / `HARD` / `BACK`, opening focused on **NORMAL** ✅ — and Ⓐ
|
||
there opens **SELECT DATA**, a save-slot picker headed
|
||
`Current Storage: Dummy HDD` that asks you to choose a file for the auto-save.
|
||
Pick one and a movie plays ✅.
|
||
[DIFFICULTY](../re/captures/difficulty-screen.png)
|
||
|
||
### Load game ✅
|
||
A vertical list of numbered slots, **8 rows visible**, scrolling as a carousel —
|
||
one capture shows the order `19, 20, 01, 02, 03, 04` with `01` focused, so the
|
||
list runs past the end and back round to the start ✅. Each row shows
|
||
`Difficulty`, `Flight Time` and `Clear Ratio`; a **Details** panel to the right
|
||
gives `STAGE`, `Game Status`, `Points` and `Times Cleared`, and an empty slot
|
||
leaves every one of those blank ✅. `Current Storage: Dummy HDD` sits along the
|
||
top.
|
||
|
||
Its footer offers more than the other menus:
|
||
`⊙ : Select Ⓐ : OK Ⓑ : Back Ⓧ : Delete Ⓨ : Select Storage` ✅.
|
||
[capture](../re/captures/menu-nav/q4-destinations.png) (left panel)
|
||
|
||
❔ Still open: the overwrite / delete confirmation, and where its cursor starts.
|
||
|
||
Known: `title → LOAD GAME → slot 01 → YES → READY ROOM → TAKE OFF` reaches
|
||
flight ✅.
|
||
|
||
### Tutorial ✅
|
||
A list of lessons in two headed groups, with a one-line description shown on the
|
||
left for whichever is focused ✅ — e.g. `BASIC CONTROLS` reads
|
||
*"Learn how to move and attack"*. Opens focused on the first entry.
|
||
|
||
| group | lessons |
|
||
|---|---|
|
||
| **Level 1** | `BASIC CONTROLS`, `HEADS-UP DISPLAY`, `RADAR` |
|
||
| **Level 2** | `SUPPLY AND SPECIAL MOVES`, `RADIO ORDERS`, `ADVANCED CONTROLS` |
|
||
| — | `BACK` |
|
||
|
||
[capture](../re/captures/menu-nav/q4-destinations.png) (middle panel)
|
||
|
||
### Options ✅ (one level in)
|
||
`GAME SETTINGS` · `CONTROL SETTINGS` · `SOUND SETTINGS` · `SCREEN SETTINGS` ·
|
||
`BACK`, opening focused on the first ✅.
|
||
[capture](../re/captures/menu-nav/q4-destinations.png) (right panel)
|
||
|
||
❔ Still open: what is inside each of the four, what each setting ranges over, and
|
||
whether a change needs confirming.
|
||
|
||
### Extras ✅
|
||
Three items: `MISSION SELECT` · `MOVIE THEATER` · `BACK`, opening focused on
|
||
`MISSION SELECT` ✅. The cursor wraps here too — it is a menu rule, not a
|
||
per-screen one ✅.
|
||
[capture](../re/captures/title-builds/live-extras.png)
|
||
|
||
❔ `MOVIE THEATER` has never been opened.
|
||
|
||
### Mission select ✅ — and the "stuck cursor" is explained
|
||
The stage list on the left (**8 rows visible of 16**, with a scrollbar), a detail
|
||
panel showing the stage's name, a picture, `High Score` and `Best Time`, and a
|
||
**Wide Area Space Map** on the right with the named systems on it. The chosen
|
||
difficulty is printed top-right. Footer:
|
||
`⊙ : Select Ⓐ : OK Ⓑ : Back Ⓨ : Difficulty` ✅.
|
||
|
||
⚠️ **"Stage select would not move" — sixteen d-pad presses never left Stage 01 —
|
||
is now explained: the other fifteen stages were LOCKED** ✅. A locked row is
|
||
drawn *dimmer than an unfocused one*: measured, the labels sit at three distinct
|
||
brightnesses — focused **254**, unlocked **183**, locked **104** — and on a save
|
||
with the story unlocked the same rows read 183, with the cursor able to reach
|
||
**Stage16** at the bottom of the scrolled list.
|
||
[the measurement](../re/menu-navigation-semantics.md#-mission-select-the-cursor-was-stuck-because-the-stages-were-locked) ·
|
||
[locked](../re/captures/mission-select-stage01-only.png) ·
|
||
[unlocked](../re/captures/mission-select-all-story-unlocked.png) ·
|
||
[at Stage16](../re/captures/mission-select-ends-at-stage16.png)
|
||
|
||
So: if you are scripting a run, **check what the save has unlocked** before
|
||
concluding the list is broken. ❔ Whether the list wraps past Stage16, and
|
||
whether a locked row is skipped or simply unreachable, is not settled.
|
||
|
||
### Briefing and Ready Room ❔
|
||
❔ What you read, what you choose, and what finally launches the mission.
|
||
|
||
### Hangar / Arsenal ❔
|
||
❔ How a weapon is fitted, how one is bought, what a purchase prompt says.
|
||
|
||
---
|
||
|
||
## 4. Prompts, confirmations and alerts
|
||
|
||
The interrupting layer — and the thing most likely to break a scripted run,
|
||
because it looks like a menu and does not behave like one.
|
||
|
||
| prompt | when | where the cursor starts | notes |
|
||
|---|---|---|---|
|
||
| `Save game?` | after a mission | **YES** ✅ | |
|
||
| `Do you want to develop this weapon?` | Arsenal, on purchase | ❔ | |
|
||
| overwrite / delete confirmation | saving, loading | ❔ | |
|
||
| "not enough points" or similar refusal | Arsenal | ❔ | ❔ does it need dismissing |
|
||
|
||
⚠️ **A short d-pad tap is ignored inside a prompt.** Sixty milliseconds moves the
|
||
cursor on a menu and does *nothing* in a dialog ✅. So a script that works
|
||
through the menus will silently accept the default in every prompt it meets —
|
||
which is how you end up overwriting a save you meant to keep. **Confirm which
|
||
side the cursor is on before pressing Ⓐ.**
|
||
|
||
---
|
||
|
||
## 4b. What a screen change looks like ✅ measured, three of them
|
||
|
||
Every screen carries a full-screen black quad (`pteff00.prm`) that paints last.
|
||
A screen change is that quad ramping to opaque on the way out, and the **incoming**
|
||
screen's own copy of it starting opaque and clearing on the way in — so a
|
||
transition is two screens' quads, not one shared effect. The outgoing ramp's length
|
||
is on the disc and matches the game **three for three**; the black between them
|
||
does not, and is not a constant.
|
||
|
||
| you press | going | outgoing ramp | black between | incoming clears over |
|
||
|---|---|---|---|---|
|
||
| Ⓑ | main menu → title | 5 frames | **none — they cross-fade** | 8 frames |
|
||
| Ⓐ | title → main menu | 4 frames | ~3 frames | 5 frames |
|
||
| Ⓑ | EXTRAS → main menu | 5 frames | **2 frames, fully blank** | 5 frames |
|
||
|
||
⚠️ **Ⓑ is not "the cancel animation".** Ⓑ out of the main menu cross-fades — the
|
||
title is already drawing while the menu is still fading — while Ⓑ out of EXTRAS
|
||
goes properly black first. Same button, two different-looking moves, and if you are
|
||
scripting against "the screen goes black" one of them will not do it.
|
||
|
||
⚠️ **Ⓐ off the title is slow to start.** About 25 rendered frames (~0.8 s) pass
|
||
between a delivered press and anything changing on screen; the other two start
|
||
immediately. A script that presses and then looks 0.5 s later sees the title still
|
||
up and can conclude the press was dropped.
|
||
|
||
Timings are in *rendered frames* at ~30 Hz, from the emulator's own draw stream, so
|
||
they do not stretch when the emulator runs slow —
|
||
[`screen-transitions.md`](../re/screen-transitions.md) ·
|
||
[`data/fade-three-transitions.txt`](../re/data/fade-three-transitions.txt).
|
||
|
||
## 5. Flying
|
||
|
||
Not started, and the game teaches it better than we could: **play the in-game
|
||
tutorials and write down what they say.** They are the game's own explanation of
|
||
its controls, which is exactly the document we want.
|
||
|
||
To fill in: the control map, and whether there is more than one scheme · throttle
|
||
and boost · targeting — ⚠️ target select is Ⓐ pressed **twice**; a sweep that
|
||
only ever tapped once concluded targeting was automatic, and was wrong ✅ ·
|
||
switching weapons · the pause menu and what it offers · what the HUD tells you,
|
||
element by element · how a mission ends, win or lose, and what you see next.
|
||
|
||
---
|
||
|
||
## 6. If you are scripting this
|
||
|
||
Traps that read as bugs but are not, all measured ✅:
|
||
|
||
* **F10 opens Xenia's own menu bar**, and while any emulator UI is up the game
|
||
is handed an empty keystroke before any pad driver is asked. The controller
|
||
looks dead and is not.
|
||
* **A signed-in profile is required** — `--create_profile_if_none`.
|
||
* **A trace consumer that exits stalls the emulator**, which also reads as a dead
|
||
pad.
|
||
* Cold boot is slow; ~25 s once the shader and code caches are warm.
|
||
* **`pkill -f xenia_canary` kills the shell that ran it**, because `-f` matches
|
||
the whole command line and your own `bash -c` contains the pattern. The script
|
||
dies before the emulator does, silently, with no output at all. Kill by process
|
||
**name**: `ps -o pid= -C xenia_canary | xargs -r kill -9`. (The same trap is in
|
||
`METHOD.md` for `pgrep` wait-loops; it cost another launch on 2026-08-30.)
|
||
* **`kill -9` on xenia ORPHANS `/tmp/xenia-canary.lock`**, and the next
|
||
`run-canary` refuses with *"an emulator is already running"* — to **stderr**,
|
||
where a polling script never looks. A probe of mine then sampled a dead display
|
||
for **484 s**, reporting `other` every 4 s, because `screen_id.py` on an empty
|
||
screen returns `other` and *"not the title yet"* is indistinguishable from
|
||
*"there is no emulator"*. Kill with a plain `kill` so it can clear its own lock;
|
||
if you must use `-9`, `rm -f /tmp/xenia-canary.lock` after. **And assert the
|
||
emulator is alive before entering any wait loop** — `ps -C xenia_canary` — so
|
||
the loop cannot spend its whole deadline on nothing.
|
||
* ✅ **Ⓐ on a settled boot title DOES reach the main menu — re-run clean,
|
||
2026-08-30, and the withdrawn counter-example below is now explained.** One
|
||
trial, **exactly one emulator verified by count**, gated on the plate pulse
|
||
(glyph in [500, 2500] held 12 samples) so the press lands on the boot title
|
||
rather than the attract loop's. Delivery confirmed (`[file-pad] keystroke
|
||
vk=5800 down`/`up`). Glyph after the press: `0, 0` at +2 s and +4 s — the
|
||
transition — then **327 steady from +6 s to +39 s**. ⚠️ 327 is a proxy, so the
|
||
screen was checked with [`which_title_screen.py`](../../tools/re-capture/which_title_screen.py)
|
||
instead: **`main_menu` at RMSE 19.91 and 20.08, margin ~10**, inside the 9.9–11.7
|
||
band its control establishes on four known captures. The `before` frame gives
|
||
the "neither" signature (margin 0.10), correctly, since the title is neither.
|
||
📌 **Latency 4–6 s**, which is why a script that presses and looks 0.5 s later
|
||
concludes the press was dropped. So the count is now **3 of 3**, and the two
|
||
earlier failures were the three-emulator confound, not the game.
|
||
|
||
* ~~🔴🔴 **THE ENTRY BELOW IS WITHDRAWN — the experiment was confounded.**~~ When it
|
||
ran, **three emulators were live at once** (started 15:39, 15:44 and 16:12 on
|
||
2026-08-30), all reading the same `/tmp/xenia_pad.txt` and sharing display `:98`.
|
||
A press written to that file is delivered to **every** instance, and `screenshot`
|
||
grabs whichever window is topmost — which need not be the one that acted on it.
|
||
So "Ⓐ was delivered and the screen did not change" may simply be *two different
|
||
emulators*, and the keystroke-level confirmation proves only that **some**
|
||
instance received it. ⚠️ The cause was mine: `run-canary`'s lockfile is the
|
||
implementation of the "one emulator at a time" rule, and I had been clearing it
|
||
with `rm -f` to get past a stale one — which disables the guard for the next
|
||
launch too. **Clear a stale lock only after confirming zero live instances**
|
||
(`ps -C xenia_canary --no-headers | wc -l`). The claim below is unsupported and
|
||
needs a clean re-run before anyone relies on it.
|
||
|
||
* ~~🔴 **Ⓐ on a settled boot title does NOT reliably reach the menu.**~~ This page's
|
||
§1 and `canary-scripted-input-traps.md` record "the boot title accepts a single
|
||
Ⓐ (2 of 2 runs)". A run on 2026-08-30 gated on the **plate pulse** (glyph in
|
||
[500, 2500] held 12 consecutive samples), fired at t=484.5 s with glyph 1723 —
|
||
a verified settled boot title, not the attract one — pressed Ⓐ, and **the press
|
||
was delivered** (`[file-pad] keystroke vk=5800 down` / `up`, 8 `[RE-INPUT]`
|
||
lines). Twenty seconds later every captured frame still classified as the title.
|
||
So the sample is no longer 2 of 2, and a script that presses once and proceeds
|
||
can be left on the title with nothing in its log to say so. **Confirm the screen
|
||
changed; do not infer it from a delivered press.**
|
||
* **`screen_id.py` reports `menu` during the attract loop.** Two boots on
|
||
2026-08-30 logged `menu` at t=106 s and t=418 s while the game was still in the
|
||
intro movie. A wait-loop that breaks on `menu` will act on the wrong screen; the
|
||
loops here break on `title` for that reason.
|
||
* **`screen_id.py` cannot tell EXTRAS from the main menu** — both are dark blue
|
||
`GP_TITLE` screens and it answers `menu` for either. Use
|
||
[`which_title_screen.py`](../../tools/re-capture/which_title_screen.py), which
|
||
separates them by ~11 RMSE against ~18 within-class, and read the **margin**: a
|
||
margin under ~1 means "neither", which is what you get on a screen outside
|
||
`GP_TITLE` entirely.
|