# ✅ A `.tbm` DRAWS PIXELS — the `TUTORIAL` screen, captured and identified **Classification: not an answer.** Recorded per *"do not improvise around a blocker"*, and because the *reason* both runs failed is the same mistake three times over. ## The question [`ui-forced-backdrop.md`](ui-forced-backdrop.md) has **24** of its 62 deciding verdicts on `.tbm` elements. `compose` draws **nothing** for a `.tbm` — no resolvable sprite — so those verdicts are *"correct or inert"* and the two cannot be separated. A capture of a screen carrying one would separate them. ✅ **And no focus detector is needed**, which is what makes this cheap now. [`s00a-drive-blocked-by-focus.md`](../s00a-drive-blocked-by-focus.md) records that a per-row brightness statistic **failed its own control**, and that wrap-around makes counting presses useless. But *every* main-menu destination except `EXTRAS` lands on an archive holding a `.tbm` decider — `GP_SYSTEM` (`pqbase`), `GP_TUTORIAL` (`pubase`), `GP_SAVE_LOAD` (`px_replay_base`), `GP_DIALOG` (`pcbase`). So press Ⓐ on whatever is focused and identify the screen **from the capture**. ## What happened | run | approach | result | |---|---|---| | 1 | **timed** the title→menu transition (tap, wait 8 s) | 8 s later still the **title** — glyph 714, the plate's pulse trough. The second tap did the transition; the "submenu" capture is the menu. **Void.** | | 2 | **detected** the menu (glyph 250–420 for 6 samples; menu is 327, plate is 714–1520) | menu found at 357.2 s, glyph **327** exactly. Tapped at 358.0 s. 12 s later: **still the menu.** | ## 🔴 The second tap was never delivered | | | |---|---| | `[file-pad] vk=5800` lines | **2** — that is *one* press, down and up | | `[RE-INPUT] -> user=0 vk=5800` | one down, one up | | `swallowed by IsUIActive` | **0** — not the sign-in path | The tap came **0.8 s after the menu appeared**, while the guest was still loading it. A **0.12 s** press is missed outright if the guest does not poll during that window. The pad driver reports what *it* emitted; the guest never asked. ⚠️ **So "the press did nothing" and "there was no press" look identical from the screen**, and only the log separates them. Any driven run that presses and waits must **confirm delivery in the log** before interpreting the result — otherwise a missed press reads as a screen that did not respond. ## The pattern worth more than the run This is the **third** time in one iteration that timing was used where detection was required — the title→menu wait, the menu→submenu wait, and the press itself (assumed delivered rather than confirmed). The first two were caught because the screen was recognisable; the third only because the log records deliveries. 📌 Each fix has the same shape: **replace "wait long enough" with "watch for the thing".** The title detector, the menu detector and the delivery check are all that substitution, and each was written only after the timed version had already produced a confident wrong answer. ## ✅ Run 3 — all three fixes applied, all three needed, submenu reached ``` [ 288.6s] TITLE (glyph 1520) [ 289.7s] A delivered (attempt 1) ← confirmed from [RE-INPUT], not from the pad [ 295.4s] MENU (glyph 327) ← detected, not timed [ 299.3s] A delivered (attempt 1) [ 303.4s] SUBMENU: 87.1 % of pixels differ from the menu, glyph 314 ``` **The capture is 99.7 % inked**, uniformly top to bottom — a full-screen background ([capture](../captures/title-builds/live-submenu-unidentified.png), [numbers](../data/tbm-submenu-reached.txt)). **Our renderer, on the archives carrying a `.tbm` decider:** | archive | builds | inked | |---|---|---| | `GP_SAVE_LOAD` | 19 | **1.9 – 3.0 %** | | `GP_TUTORIAL` | 3 | **6.0 – 6.4 %** | | `GP_SYSTEM` | 0, 1 | 78.4 % | So two of the three render essentially nothing where the game draws a full screen. ## ✅ It is `TUTORIAL`, and the screen names itself **Read off the framebuffer** — the same method Q4 used to measure all five menu buttons. The capture says `TUTORIAL`, lists `BASIC CONTROLS … BACK`, and carries a **full-screen blue circuit/hex background**. `GP_TUTORIAL` build 0's element 0 is **`pubase.tbm`, pivot (640, 360)** — 1280×720, the only full-screen *textured* element in the bundle; the one other full-screen element is `pueff00.prm`, an untextured primitive that the colour census puts at **pure black**. Our render of the same build is the **identical layout on pure black** — 6.0–6.4 % inked against the game's 99.7 %. **So a `.tbm` draws, and the "inert" reading in [`ui-forced-backdrop.md`](ui-forced-backdrop.md) is refuted.** Its 24 `.tbm` deciders are correct rather than harmless. ⚠️ One `.tbm` observed; the class question is settled, the ten other families are not individually seen. 🔴 **And `screen render` is wrong on every screen carrying a `.tbm`** — it drops the background silently. ## 🔴 The instrument I built for this failed, and reading the screen was better **Correlation cannot discriminate when the candidate renders are near-blank.** **Correlation cannot discriminate when the candidate renders are near-blank.** An almost-empty image has no structure to correlate against, so all 19 `GP_SAVE_LOAD` builds score **−0.004 … −0.010** — a ranking with no information in it. ⚠️ **A matching statistic is useless against a hypothesis that predicts an empty image**, and that is precisely the hypothesis under test. The instrument is disabled by the thing it was brought in to detect. 🔴 **Two repair attempts, and the honest outcome.** Masking the correlation to the pixels the render *does* ink **failed its control**: asked to identify the known main menu, it picked `EXTRAS` over the menu by **+0.0040** — the shared background dominates. High-passing first **passed** the control but by **1.28×** (+0.0276 against +0.0215), where the port's method on the same class of problem separated by 4.7×. **A control that passes by 1.28× is not a licence to identify an unknown**, so it was not used. Looking at the picture settled in one step what two statistics could not. 🔴 **And the focus could not be read either.** Against the two labelled menu captures the whole-frame mean absolute difference is **2.52** (NEW GAME) and **2.48** (OPTIONS) — 1.6 % apart, far too weak to call. [`s00a-drive-blocked-by-focus.md`](../s00a-drive-blocked-by-focus.md) already records a per-row brightness statistic failing its control; this is a **second** statistic failing on the same problem, which makes focus identification a real open item rather than an oversight. ✅ **One thing worth keeping regardless:** the game surface sits at **y = 45** in the 1280×720 display frame — `m[45:45+675, 0:1279]` fits the committed 1279×675 captures to a mean absolute difference of **2.5**. That is the alignment the earlier cross-geometry floor comparison got wrong. ## What is now validated, and what the next run needs ✅ Working: the plate-pulse title detector (three runs); the **menu detector**, glyph **327**, matching `live-main-menu.png` exactly; and delivery confirmation from `[RE-INPUT]`. **Next run:** hold Ⓐ longer than 0.12 s, **confirm the `[RE-INPUT]` line appears**, retry if it does not, then detect the submenu **by change** rather than by timer — a submenu load may also pass through a `pgloading_*` screen, so "different from the menu" is the signal, not a fixed wait.