From f24304248c8aca2e9cbd9f3b7465eee4205d0b05 Mon Sep 17 00:00:00 2001 From: sylph-decoder Date: Sat, 29 Aug 2026 12:43:41 +0000 Subject: [PATCH] re: the plate delay was on the disc all along -- my instruction is refuted The port caught this with arithmetic off the disc, and it was right: build 2 has a keyframe group of its own, so "when build 4 has settled, wait 2.13 s, then composite build 2" puts the plate at settle + 2.13 + 3.97 s. Confirmed build 2's group here independently of their message: `ptbtn00.t32` reaches a=255 at t=238. The reconciliation needs no free parameter. Both builds run on ONE clock, started together, and the premise that fails is `rest.t`: rest.t is NOT when a screen settles. It is the last HOLD keyframe before the exit. ptlogo1 rests at t=251 and stops moving at t=42. The title's visible build-in ends at t=118, where pteff01, pteff02.prm and ptlogoall_eff end their ramps together. 238 - 118 = 120 units = 2.000 s, against a measured 2.138 and 2.132. So the interval the two runs agreed on to 6 ms was a DECLARED one and I handed over a wall-clock reading of it. That reading is 6.7% long, and the corpus already knew why: 120 units in 2.135 s is the game presenting at 28.06 / 28.14 fps against a nominal 30, and the idle title was independently measured at 28.5 fps before these runs. Corroborated from inside the same two runs -- first pixels -> settle is 1.643 s and 2.131 s, a 30% spread, while settle -> plate is 2.138 and 2.132. Frames are dropped during the build-in, not during the hold, which a change in the game's own timing could not do. So the port authors nothing here. What is unchanged: ScreenView still has to draw two builds at once and the boot's end state is still not plate-free. Not settled, and said so on the page: which reading of the keyframe times is right (it moves the plate by 2 units and I cannot separate them from these traces), and my settle landmark to better than +/-5 units. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_014voBspJ6kFncNErZJuZcLw --- docs/port/HANDOFF.md | 38 ++++++++---- docs/re/INDEX.md | 2 +- docs/re/REFUTED.md | 23 +++++++ docs/re/title-plate-delay-measured.md | 89 ++++++++++++++++++++++++--- 4 files changed, 131 insertions(+), 21 deletions(-) diff --git a/docs/port/HANDOFF.md b/docs/port/HANDOFF.md index 32c646b1..434c6928 100644 --- a/docs/port/HANDOFF.md +++ b/docs/port/HANDOFF.md @@ -139,18 +139,32 @@ items MISSION parks as emulator-blocked. boot title went **154 → 781**, and 154 is the same reading the committed `live-title-build4-no-plate.png` gives (159) while plate titles give 753/977/1493. - ✅ **AND THE DELAY IS NOW MEASURED — 2.13 s, replicated to 6 ms.** Two - independent boots: the plate arrives **2.138 s** and **2.132 s** after build 4 - settles (the frame where the glyph counter first reads its no-plate 154 and - motion goes to zero). **So `ScreenView` does have to draw two builds at once, - and your `--boot` end state is NOT plate-free** — that is the structural answer - you said this question decides. - ⚠️ Measure from **settled**, not from first pixels: "first drawn → plate" is - 3.78 s in one run and 4.26 s in the other, because the build-in animation - itself ran 1.64 s and 2.13 s. That spread is the emulator's frame pacing, not - the game's clock. - Then pulse the plate at ≈ **2.24 s** (four intervals: 2.12 / 2.19 / 2.34 / - 2.31), which replicates the corpus's ≈2.3 s rather than replacing it. + ✅ **So `ScreenView` does have to draw two builds at once, and your `--boot` + end state is NOT plate-free** — that is the structural answer you said this + question decides, and it is unchanged. + 🔴 **But my INSTRUCTION was wrong and you refuted it — do not author a delay at + all.** I said "when build 4 has settled, wait 2.13 s, composite build 2". Build + 2 has a group of its own, and starting that group at settle puts the plate at + settle + 2.13 + 3.97 s. **Correct instruction: run build 4 and build 2 on ONE + clock, started together, and play both groups from their own keyframes.** The + plate then arrives at its declared `t=238` with nothing authored. + 🔴 **The premise that broke it is yours and it will bite again: `rest.t` is NOT + when a screen settles.** It is the last *hold* keyframe before the exit. + `ptlogo1` has `rest.t = 251` and stops moving at **`t=42`**. The title's visible + build-in is over at **`t≈118`**, where `pteff01`, `pteff02.prm` and + `ptlogoall_eff` all end their ramps together — and `238 − 118 = 120 units = + **2.000 s**`, which is the 2.13 s I measured. The number was on the disc. + ⚠️ **If you author a gap anyway, author 120 units, not my 2.13 s.** 120 units in + 2.135 s is the game presenting at **28.06 / 28.14 fps** against a nominal 30 — + and the corpus had already measured the idle title at **28.5 fps**, + independently and before these runs. My wall-clock was this emulator's frame + rate baked into a game constant; a port at a true 30 Hz would be visibly late. + ✅ That it is presentation rate and not the game is checkable in the same two + runs: *first pixels → settle* is 1.643 s and 2.131 s (a 30 % spread) while + *settle → plate* is 2.138 s and 2.132 s. Frames are dropped during the + build-in, not during the hold. + Pulse the plate at ≈ **2.24 s** (four intervals: 2.12 / 2.19 / 2.34 / 2.31), + which replicates the corpus's ≈2.3 s rather than replacing it. [`title-plate-delay-measured.md`](../re/title-plate-delay-measured.md) · [figure](../re/captures/ui-timing/plate-onset-two-runs.png) · [run 1](../re/data/plate-timing-run1.tsv) · [run 2](../re/data/plate-timing-run2.tsv) diff --git a/docs/re/INDEX.md b/docs/re/INDEX.md index 9f2db95f..913dcb47 100644 --- a/docs/re/INDEX.md +++ b/docs/re/INDEX.md @@ -164,5 +164,5 @@ files, which is how the same ground got covered twice. | [`xpr2-colour-check.md`](xpr2-colour-check.md) | XPR2 colours: channel order ✅ confirmed against the running game | — | | [`focus-ring-spin-measured.md`](focus-ring-spin-measured.md) | The main menu's focus ring spins continuously — and how fast | ✅ **measured**: period **2.177 s** over 9 revolutions (8 evenly spaced autocorrelation peaks) = 120 units = 60 frames = 2.00 s at 30 Hz. A pulse is excluded — annulus total conserved to 0.4 % while per-bin brightness swings by 24. ✅ the ring is the **only** moving thing on the settled main menu (std exactly 0.000 elsewhere). 🔴 no angle is quoted: the angular estimator FAILED its own control (30° → 0°) | | [`structures/slb-bank-header-not-a-wave.md`](structures/slb-bank-header-not-a-wave.md) | Why a music bank read as THREE sub-waves when the census says two | ✅ **decoded**: the third is the **bank header**, emitted by our own reader. `to_xma_riffs`'s hybrid branch derives a leading packet stream's start as `first_riff % 2048`, which is right only for a header shorter than one packet; a music bank's header is exactly **5 packets (10 240 B)**, so the modulus gave 0 and the whole header came back as sub-wave 0. The header states its own length at `+0x24` in blocks. Disc-wide over 9 519 `sound.pak` entries: **28** match the header signature at offset 0 (ids 1001–1023, 1101–1105), **28/28** end exactly at the first `RIFF`, **0** have a gap, **0** false positives — so a header at offset 0 and a leading packet stream never coexist. Decode control, same chain, same bank: the emitted region gives **0.009 s** against **87.744 s** for the real wave 0. Corroborated by the runtime XMA probe, which saw exactly two streams at the main menu. Fixed + 2 regression tests; the `VOICE_D_453` recovery is untouched (10/10 green) | -| [`title-plate-delay-measured.md`](title-plate-delay-measured.md) | How long the boot title shows build 4 before the `PRESS Ⓐ` plate | ✅ **measured**, two independent boots: **2.138 s** and **2.132 s** from the frame build 4 settles (glyph = its no-plate 154, motion → 0). Agreeing to **6 ms**. So the boot title's end state is **not** plate-free and a compositor must draw **two builds at once**. ⚠️ Measure from *settled*, not from first pixels — "first drawn → plate" is 3.78 s vs 4.26 s across the same two runs, because the build-in animation's own duration varies with emulator frame pacing. Plate pulse re-measured at 2.12/2.19/2.34/2.31 s (mean 2.24), replicating the corpus's ≈2.3 s. ✅ black hold between screens bracketed at **0.14–0.30 s**, consistent with the declared 12 units. 🔴 the Ⓐ→menu latency is still **not** available: both runs freeze one frame for ~1.4 s at surface mean **26.626** — agreeing between runs to 1e-6, and reproduced with stream restarts disabled — which is a guest **load stall**, not the capture path. Probe: 8.7 ms/frame, 7.97/7.98 fps against a requested 8, controls 9/9 + 4/4 | +| [`title-plate-delay-measured.md`](title-plate-delay-measured.md) | How long the boot title shows build 4 before the `PRESS Ⓐ` plate | ✅ **decoded after a refutation**: build 2 and build 4 run on **one clock started together**, and the plate's own `ptbtn00` reaches `a=255` at `t=238`; the last build-in ramp ends at `t=118`, so the interval is a declared **120 units = 2.000 s**. 🔴 The instruction that shipped first — "wait 2.13 s after build 4 settles" — was **refuted by the port** with disc arithmetic and is corrected in place; 🔴 `rest.t` is **not** when a screen settles (it is the last hold keyframe before the exit: `ptlogo1` rests at `t=251` and stops moving at `t=42`). ⚠️ The wall-clock 2.13 s is 6.7 % long because Canary presents at **28.06 / 28.14 fps** against a nominal 30, matching the corpus's independent **28.5 fps**; author the 120 units. ✅ **measured**, two independent boots: **2.138 s** and **2.132 s** from the frame build 4 settles (glyph = its no-plate 154, motion → 0). Agreeing to **6 ms**. So the boot title's end state is **not** plate-free and a compositor must draw **two builds at once**. ⚠️ Measure from *settled*, not from first pixels — "first drawn → plate" is 3.78 s vs 4.26 s across the same two runs, because the build-in animation's own duration varies with emulator frame pacing. Plate pulse re-measured at 2.12/2.19/2.34/2.31 s (mean 2.24), replicating the corpus's ≈2.3 s. ✅ black hold between screens bracketed at **0.14–0.30 s**, consistent with the declared 12 units. 🔴 the Ⓐ→menu latency is still **not** available: both runs freeze one frame for ~1.4 s at surface mean **26.626** — agreeing between runs to 1e-6, and reproduced with stream restarts disabled — which is a guest **load stall**, not the capture path. Probe: 8.7 ms/frame, 7.97/7.98 fps against a requested 8, controls 9/9 + 4/4 | | [`menu-idle-and-b-2026-08-29.md`](menu-idle-and-b-2026-08-29.md) | The main menu does not idle back to the title — and four durations that were a pipeline | ✅ **refuted**: no self-return in **≥ 60 s** untouched; the ~8–10 s idle belongs to the **title**. 🟡 Ⓑ→title ordering measured, latency not. 🔴 `classify_array` at **1503 ms/frame** drained an 8 fps stream at 0.64 fps and manufactured four latencies (24.66 s / 15.58 s / 25.60 s / 20.26 s) — all withdrawn; a backlog preserves ordering and destroys durations | diff --git a/docs/re/REFUTED.md b/docs/re/REFUTED.md index 9aa46663..c26d0761 100644 --- a/docs/re/REFUTED.md +++ b/docs/re/REFUTED.md @@ -618,6 +618,29 @@ neighbourhood, not just the line. the `GP_STAGE_CLEAR` child the same scan named `8AX`. With the name decoded the count is **10 148 of 10 148**. [`ratc-child-names.md`](structures/ratc-child-names.md) +## UI timing (2026-08-29) + +* "a screen has SETTLED at its `rest.t`" → **refuted.** `rest.t` is the last + *hold* keyframe before the exit, not the end of motion. Build 4's `ptlogo1` + rests at `t=251` and stops moving at **`t=42`**; the title's visible build-in + ends at `t≈118`, where `pteff01`, `pteff02.prm` and `ptlogoall_eff` end their + ramps together. Believing `rest.t` put a port's plate 3.97 s late — + [`title-plate-delay-measured.md`](title-plate-delay-measured.md). +* "the `PRESS Ⓐ` plate is composited a measured 2.13 s after the title settles, + and the port should author that" → **the measurement stands, the instruction + was refuted by the port.** Build 2 has a keyframe group of its own; both builds + run on **one clock started together** and the plate's declared `t=238` supplies + the timing, so nothing is authored. `238 − 118 = 120 units = 2.000 s`, of which + 2.13 s was a wall-clock reading stretched by Canary presenting at ~28.1 fps. + ⚠️ General lesson: **a wall-clock duration off this emulator is ~6 % long**, so + a measured interval that lands near a round number of units probably *is* that + number of units. +* "a music bank has three sub-waves" → **refuted; it was our reader.** The third + is the bank header, emitted because `to_xma_riffs` derived a leading packet + stream's start as `first_riff % 2048` — valid only for a header shorter than + one packet. 28/28 disc-wide — + [`structures/slb-bank-header-not-a-wave.md`](structures/slb-bank-header-not-a-wave.md). + ## The oracle harness and the container (2026-08-29) * "the decoder container has no disc" → **refuted the same day.** The container diff --git a/docs/re/title-plate-delay-measured.md b/docs/re/title-plate-delay-measured.md index 6599b904..b31eb80e 100644 --- a/docs/re/title-plate-delay-measured.md +++ b/docs/re/title-plate-delay-measured.md @@ -53,17 +53,90 @@ independent observables: then rises. A pulsing overlay moves the frame mean; the frame mean does not move until onset. -## What the port should author +## 🔴 The instruction below was WRONG, and the port refuted it — corrected 2026-08-29 -1. draw build 4, play its own keyframes; -2. when build 4 has settled, wait **2.13 s**; -3. composite build **2** over it and start its pulse — period measured here at - **2.12 / 2.19 / 2.34 / 2.31 s** across four peak- and trough-to-peak - intervals in the two runs, mean **2.24 s**, which replicates the corpus's - ≈ 2.3 s rather than replacing it. +**What stands:** every measurement on this page. **What was wrong:** what I told +the port to do with it. + +The instruction was *"when build 4 has settled, wait 2.13 s, composite build 2"*. +The port implemented it literally, then pointed out with arithmetic off the disc +that it cannot be right: build 2 has a **group of its own**, and playing that +group from a start at "settle" puts the plate at settle + 2.13 + 3.97 s. The +3.97 s is real — `ptbtn00.rat` reaches `a=255` at `t=238`, confirmed here +independently of their message: + +``` +$ sylpheed-cli screen info --build 2 --geometry $SYLPHEED_DISC/dat/GP_TITLE.pak +build [2] 1280x720 1 elements +0 ptbtn00.t32 214: 383,560 a=0 236: 383,550 a=0 + 238: 383,550 a=255 244: 383,550 a=255 -: a=0 +``` + +### The reconciliation: one clock, and my landmark is `t≈118`, not `t=261` + +**Build 2's group runs on the same clock as build 4's, starting together.** Then +the plate's own keyframes say when it arrives and nothing needs authoring. + +The port's premise that *"build 4 settles at `t=261` = 4.35 s"* is the part that +fails, and it is worth stating plainly because it will bite elsewhere: +🔴 **`rest.t` is not when a screen settles.** It is the last *hold* keyframe +before the exit. `ptlogo1` has `rest.t = 251` and stops moving at **`t=42`** — +after which it creeps 5 px over the next 209 units. The title's visible build-in +is over at **`t≈118`**, where three elements' ramps end together (`pteff01`, +`pteff02.prm`, `ptlogoall_eff`); the only later change is the copyright line and +the ™. + +That closes the gap exactly, with no free parameter: + +| | units | +|---|---| +| last build-in ramp ends (`pteff01` / `pteff02.prm` / `ptlogoall_eff`) | `t = 118` | +| `ptbtn00` reaches `a = 255` | `t = 238` | +| **difference** | **120 units = 2.000 s** at 1 unit = 1/60 s | + +against a measured **2.138 s** and **2.132 s**. So the interval the two runs agree +on to 6 ms is a **declared** 120 units — the number was on the disc, and I handed +over a wall-clock reading of it. + +### ⚠️ And the wall-clock reading is 6.7 % long, for a reason the corpus already knew + +120 units in 2.135 s is **56.2 units/s**, i.e. the game presenting at **28.06 / +28.14 fps** against its nominal 30. The corpus independently measured the idle +title at **28.5 fps** ([`ui-keyframe-time-unit.md`](ui-keyframe-time-unit.md)) — +1.3 % from these two runs, established before and separately from them. + +✅ Corroborating that it is presentation rate and not the game: within these runs +*first pixels → settle* is **1.643 s** and **2.131 s** — a 30 % spread — while +*settle → plate* is **2.138 s** and **2.132 s**. The build-in is where frames are +dropped; the static hold is not. A model in which the game's own timing varied +would have to move both. + +## What the port should author — nothing + +1. draw build 4 and build **2** on **one clock, started together**, and play both + groups from their own keyframes; +2. the plate then appears at its declared `t = 238` with no authored constant; +3. its pulse is the focus record `ptbtn00f`, measured here at **2.12 / 2.19 / + 2.34 / 2.31 s** over four intervals, mean **2.24 s** — replicating the + corpus's ≈ 2.3 s rather than replacing it. + +⚠️ **If you do author a gap anyway, author 120 units (2.00 s at 30 Hz), not my +2.13 s.** The 2.13 s is this emulator's presentation rate baked into a game +constant, and a port running at a true 30 Hz would be visibly late. So yes: `ScreenView` needs two builds at once, and the boot's end state is -**not** plate-free. +**not** plate-free. That part of the answer is unchanged. + +### ❔ What this does not settle + +* **Which reading of the keyframe times** — the current one or Q1's replicated + shift — is right. It barely matters here (the plate's `a=255` is `t=238` + unshifted and `t=236` shifted, 0.03 s apart), but the two make different + predictions for `ptcopyright`'s fade, and my traces contain **both** a 0.4 s + rise and a 1.1 s creep before the plate. Not separated; Q1's 🟡 stands. +* **My settle landmark to better than ±5 units.** At 56 units/s, 8 units is + 0.14 s — about one sample. `t=118` is identified from the file (three ramps + ending together) and is *consistent with* the measurement, not pinned by it. ## What is NOT measured here — the press latencies, again