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) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014voBspJ6kFncNErZJuZcLw
This commit is contained in:
sylph-decoder
2026-08-29 12:43:41 +00:00
parent c1f3608b07
commit 5b0a6e6666
4 changed files with 131 additions and 21 deletions

View File

@@ -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)

View File

@@ -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 10011023, 11011105), **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.140.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.140.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 ~810 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 |

View File

@@ -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

View File

@@ -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