From d071898cde56bbdcfbbffe400120c02627ba858b Mon Sep 17 00:00:00 2001 From: sylph-decoder Date: Tue, 1 Sep 2026 16:49:08 +0000 Subject: [PATCH] re: H3 answered -- 2 units per guest frame, and the settle anchor is t~160 The Port asked which of two of my measurements to believe, 55 units/s vs ~150, a factor of 2.7 off one game. Measured on the plate's own declared ramp, against a pre-registration committed first. PREDICTED 11 frames at 2 units/frame, 4.4 at the Port's inferred 5, +/-1. MEASURED 10 labels, and three consecutive gap-free steps of EXACTLY 23, which is 255*2/22 on the nose. 5 units/frame is excluded by >2x. Why the splash read as 5: an alpha step is not a clock rate. For a linear segment d(alpha)/frame = 255*(units/frame)/T. Splash B's quads step 34 with a declared T=15; the plate steps 23 with a declared T=22; ONE clock, two steps 1.5x apart. And the Port's intervals start at each quad's first submission, which on splash A is already alpha=85 -- not the element's t where alpha=0, and biased by a different amount per element because T differs. My own splash-quad-timeline.txt published alpha against frame with no T beside it, which is the column that makes the conversion possible; it now carries the warning. The other half: the 'title settled' anchor is ptcopyright reaching full alpha -- the last build-in element and the ONLY glyph one, which is what a glyph counter settling means. Calibrated on the plate's own ramp it lands at t~168 (t~176 at a flat 2.0/label). The Port's candidates are 118 and 160, 42 units apart: this is 8-16 units from 160 and 50-58 from 118. It is 160. Instrument fact that bounds all of it: labels with zero draws exist, ~1 in 5, and the clock does NOT advance a fixed amount across them -- across label 5376 the plate moved +82 where three adjacent labels each moved +23. So an empty label is a real advance, not a logger artefact, and spans that cross one are approximate. The conclusion rests on the gap-free steps. Also recorded: the sweep leaves never settle. They translate monotonically through every label examined and are still moving when the plate arrives, so 'settled' can only mean the build-in elements are done. NOT answered, and it is what the port actually needs: units per SECOND. units/s = (units/frame) x (guest fps); this pins the first at 2 and says nothing about the second, and 2x30 vs 2x60 differ by exactly the ~2 s the human reported. My own title-plate-delay-measured.md's 2.13 s does not reconcile with this capture's 20 labels for the same two anchors -- a real ~2.9x disagreement, now localised to frames->seconds rather than units->frames. Settling it needs the guest's own frame counter, which neither capture read. --- docs/re/data/splash-quad-timeline.txt | 14 ++ docs/re/data/title-plate-ramp.txt | 91 +++++++++++++ docs/re/h3-units-per-frame-measured.md | 177 +++++++++++++++++++++++++ 3 files changed, 282 insertions(+) create mode 100644 docs/re/data/title-plate-ramp.txt create mode 100644 docs/re/h3-units-per-frame-measured.md diff --git a/docs/re/data/splash-quad-timeline.txt b/docs/re/data/splash-quad-timeline.txt index 24918d81..3c8b19ee 100644 --- a/docs/re/data/splash-quad-timeline.txt +++ b/docs/re/data/splash-quad-timeline.txt @@ -11,6 +11,20 @@ # Q6 x[-0.320,+0.310] y[-0.650,-0.220] submitted in 21 draws # Q7 x[-0.530,+0.540] y[-0.130,+0.120] submitted in 8 draws # +# +# WARNING added 2026-09-01, after this file was read as a clock rate and was not. +# The alpha column is NOT a clock rate and cannot be converted into one without +# each element's DECLARED ramp length T, which this file does not carry: +# d(alpha)/frame = 255 * (units per frame) / T +# Splash B's six quads step 34/frame with T=15; the title's plate steps 23/frame +# with T=22; both are the SAME clock at 2 units/frame. Reading a step as a rate +# gave a factor of 2.7 between two captures of one game -- see +# ../h3-units-per-frame-measured.md. +# Also: a quad's FIRST appearance here is its first submission, not its t where +# alpha=0. Q7 and Q0 are both already at alpha=85 when first submitted, so an +# interval between two first-appearances is not an interval between two declared +# times, and the bias differs per element. +# frame slot quad x0 y0 x1 y1 alpha rgb uniform_colour 4 0 Q7 -0.53 -0.13 0.54 0.12 85 FFFFFF True 6 0 Q7 -0.53 -0.13 0.54 0.12 204 FFFFFF True diff --git a/docs/re/data/title-plate-ramp.txt b/docs/re/data/title-plate-ramp.txt new file mode 100644 index 00000000..09fd6f43 --- /dev/null +++ b/docs/re/data/title-plate-ramp.txt @@ -0,0 +1,91 @@ +# The title's build-in and the PRESS (A) plate, off the guest's vertex stream. +# Capture 2026-09-01: ui_draw_capture.sh GRACE=1 NOTAP=1 ARM=early FRAMES=20000 +# MAXDRAWS=400000, augmented draw logger (canary sylpheed-re d90d14e02). +# 30466 draws over 6565 frame labels; the title occupies labels ~5250..6456. +# 'label' is the logger's swap counter: one VdSwap = one label. Labels with NO +# draw at all exist and are listed; the animation clock does NOT advance a fixed +# amount across them, which is why counts across a gap are approximate. + +## empty labels (zero draws) in 5340..5390 + [5346, 5351, 5360, 5367, 5371, 5376, 5379, 5383, 5388] + +## ptbtn00 -- the PRESS (A) plate NDC x+-0.40 y -0.67..-0.53 = 513x50 px at (383,550). Declared t=214 a=0 -> t=236 a=255. + label alpha step + 5372 46 + 5373 69 23 + 5374 92 23 + 5375 115 23 + 5377 197 82 + 5378 220 23 + 5380 255 35 + 5381 255 0 + 5382 255 0 + 5384 255 0 + 5385 255 0 + 5386 255 0 + 5387 255 0 + 5389 255 0 + 5390 255 0 + 5392 255 0 + 5393 255 0 + 5394 255 0 + 5395 255 0 + 5396 255 0 + 5397 255 0 + 5398 255 0 + 5399 255 0 + 5400 255 0 + +## ptcopyright -- the last build-in element, and the only glyph one NDC x+-0.54 y -0.87..-0.82 = 691x36 px at the screen foot. + label alpha step + 5341 23 + 5342 57 34 + 5343 81 24 + 5344 104 23 + 5345 139 35 + 5347 208 69 + 5348 231 23 + 5349 243 12 + 5350 255 12 + 5352 255 0 + 5353 255 0 + 5354 255 0 + 5355 255 0 + 5356 255 0 + 5357 255 0 + 5358 255 0 + 5359 255 0 + 5361 255 0 + 5362 255 0 + 5363 255 0 + 5364 255 0 + 5365 255 0 + 5366 255 0 + 5368 255 0 + 5369 255 0 + 5370 255 0 + 5372 255 0 + 5373 255 0 + 5374 255 0 + 5375 255 0 + 5377 255 0 + 5378 255 0 + 5380 255 0 + 5381 255 0 + 5382 255 0 + 5384 255 0 + 5385 255 0 + 5386 255 0 + 5387 255 0 + 5389 255 0 + 5390 255 0 + 5392 255 0 + 5393 255 0 + 5394 255 0 + 5395 255 0 + 5396 255 0 + 5397 255 0 + 5398 255 0 + 5399 255 0 + 5400 255 0 + diff --git a/docs/re/h3-units-per-frame-measured.md b/docs/re/h3-units-per-frame-measured.md new file mode 100644 index 00000000..8ce782cb --- /dev/null +++ b/docs/re/h3-units-per-frame-measured.md @@ -0,0 +1,177 @@ +# H3 — the answer: **2 declared units per guest frame.** The 5 was an artefact + +**Status: ✅ measured**, against the [pre-registration](h3-units-per-frame-preregistration.md) +committed before the capture was read. Instrument: ⟨capture⟩ — the real game in +Canary, per-draw. 2026-09-01. + +Answers the Port's `BLOCKED.md` H3 (`auto/port-p6-audio` at `6eccfa8`), both +halves. Neither answer rests on a renderer of ours. + +--- + +## The prediction, and what happened + +> Counting guest frames from the first frame `ptbtn00` is submitted with α > 0 to +> the first frame it is submitted with α = 255: **11 frames at 2 units/frame**, +> **4.4 at the Port's inferred 5**. Accept ±1. + +| | | +|---|---| +| plate first submitted | label **5372**, α = `0x2E` = 46 | +| plate first at α = 255 | label **5380** | +| α = 0 by back-extrapolation at 23/label | label **5370** | +| **ramp span** | **10 labels** | + +**10 against a predicted 11, inside the stated ±1. The prediction held, and 4.4 is +excluded by more than a factor of two.** + +And the local steps are not merely close — they are exact: + +``` +label 5372 5373 5374 5375 [5376] 5377 5378 [5379] 5380 +alpha 46 69 92 115 — 197 220 — 255 +step +23 +23 +23 (+82) +23 (+35, clamped) +``` + +`255 × 2 / 22 = 23.18`. **Three consecutive steps of exactly 23** is 2.0 declared +units per frame on the nose, on the element the play-test complains about, on a +screen that is not a splash. `ui-keyframe-time-unit.md`'s ✅ law reproduces. + +## Why the splash read as 5, and why that reading cannot work + +The Port derived 5 units/frame from three intervals of my splash timeline. The +derivation is sound arithmetic on an unsound premise, and the premise is one I +handed them: + +**An alpha step is not a clock rate.** For a linear segment, + +``` +Δα per frame = 255 × (units per frame) / T T = the segment's declared length +``` + +so two elements with different `T` show different `Δα` at an *identical* clock. +The disc says exactly that, and all three numbers now agree at one clock: + +| element | `Δα` per frame, measured | implied `T` at 2 units/frame | declared `T` | +|---|---|---|---| +| splash B's six quads | **34** | 15.0 | **15** — the value `ui-keyframe-time-unit.md` already records | +| `ptbtn00`, the plate | **23** | 22.2 | **22** (`t=214 → 236`) | + +Two screens, two step sizes 1.5× apart, **one clock**. Reading either step as a +rate gives a different answer, which is the whole of the factor of 2.7. + +The second defect is the anchor. The Port's intervals start at a quad's *first +submission*, and on splash A the first submission of `Q7` is already **α = 85** +and of `Q0` **α = 85** — neither is that element's `t` for α = 0. An interval +between two biased onsets is not the interval between two declared times, and the +bias is not equal because the two elements have different `T`. + +⚠️ **This is mine to have caused.** `splash-quad-timeline.txt` published alpha +against frame with no `T` beside it, which is precisely the column that makes the +conversion possible. It now says so. + +## The other half — the "title settled" anchor is **t ≈ 160**, not t = 118 + +The Port asks which of two declared times my operational anchor — *glyph counter +first reads its no-plate value 154* — corresponds to. The same capture answers it, +because the draw stream names which element is which. + +**`ptcopyright` is the last element to finish building in, and it is the only +glyph element on the screen.** A glyph counter settling *is* that element +reaching full alpha: + +``` +label 5341 5342 5343 5344 5345 [5346] 5347 5348 5349 5350 → 255 thereafter +alpha 23 57 81 104 139 — 208 231 243 255 +``` + +Calibrating on the plate's own declared ramp (α=46 ↔ t=217.97, α=255 ↔ t=236, so +2.25 units/label over that stretch): + +| anchor | label | implied declared t | +|---|---|---| +| `ptcopyright` reaches α = 255 | 5350 | **t ≈ 168** (t ≈ 176 at a flat 2.0/label) | +| the Port's candidate A | | t = 118 — **50 to 58 units away** | +| the Port's candidate B | | t = 160 — **8 to 16 units away** | + +**It is candidate B.** The margin is not marginal: the two candidates are 42 units +apart and the measurement sits within a third of one gap of B and more than a +whole gap from A. + +⚠️ **And the Port's own note says this is the reading under which `clock: +"shared"` collapses.** I am reporting what the game does; what that costs the +port's model is theirs. It is not evidence against the measurement. + +📌 Also from this stream, for whoever defines "settled" next: **the sweep leaves +never settle.** The two off-screen-wide quads translate monotonically through +every one of the 100 labels examined and are still moving when the plate arrives. +"The title has settled" can only ever mean *the build-in elements have finished*, +never *the screen has stopped changing*. + +## The instrument fact that bounds all of this + +**Labels with zero draws exist, and the animation clock does not advance a fixed +amount across them.** In `5340…5390` the empty labels are +`5346, 5351, 5360, 5367, 5371, 5376, 5379, 5383, 5388` — about one in five. + +Across the empty label `5376` the plate's alpha moved **+82**, where three +adjacent occupied labels each moved **+23**. That is ~3.5 nominal steps for one +missing label, not one and not two. So: + +* an empty label is **not** a logger artefact — the clock really did advance + across it, by more than a step; and +* frame counts that span a gap are **approximate**, and every count on this page + that does so is quoted as such. + +This is why the ramp span is quoted as *10 labels* and the conclusion rests on the +three **gap-free** steps of exactly 23 rather than on the span alone. + +## 🔴 What is still NOT answered, and it is the part the port actually needs + +**Units per *second* is not settled by this, and my own two captures disagree +about it by roughly the factor that started this.** + +`units/second = (units/frame) × (guest frames/second)`. This page pins the first +factor at **2**. It says nothing about the second, and the second is where the +disagreement now lives: + +* the port uses **60 units/s**, i.e. 2 × 30 fps; +* 2 × 60 fps would be **120 units/s**, which would put the plate at 1.97 s instead + of 3.93 s — and *"about two seconds early"* is the size of the thing the human + reported; +* this capture produced **6 565 labels in ~241 s ≈ 27.2 labels/s**, which is + Canary's presentation rate, **not** the guest's nominal rate, and cannot + distinguish a 30 Hz guest running at full speed from a 60 Hz guest running at + half. + +⚠️ And `title-plate-delay-measured.md`'s 2.13 s does not reconcile with this +capture: settled → plate onset is **20 labels ≈ 0.73 s** here against **2.13 s** +there. The two anchors are the same events, so that is a real ~2.9× disagreement +between two of my own captures, and it is now localised — **not** in units→frames, +which this page settles, but in **frames→seconds**. That page's number is a +wall-clock duration read off a screenshot stream, which +[`../agents/TEMPORAL-VERIFICATION.md`](../agents/TEMPORAL-VERIFICATION.md) says +not to trust; this page's is a count. I am not withdrawing it on that ground +alone, and I am not reconciling them by argument. + +**The experiment that settles it** is to read the guest's own frame counter or +vblank rate directly rather than any wall clock — guest memory and CPU state are +available and neither of these two captures used them. That is the next +iteration's first item. + +## Reach + +One capture, one boot, one title. The 2 units/frame figure now has two +independent screens behind it (the splashes' 34-with-T=15 and the plate's +23-with-T=22) and reproduces a law the corpus already held ✅ on a third route, +so I would expect it to be general. The **anchor** result is about `GP_TITLE` +build 4 specifically and does not generalise anywhere. + +## Reproduce + +```bash +GRACE=1 NOTAP=1 ARM=early FRAMES=20000 MAXDRAWS=400000 \ + tools/re-capture/ui_draw_capture.sh 780 /sylph-home/re/titleplate +# the title arrives ~243 s in; leave the emulator up ~75 s more, then kill it +``` +Series: [`data/title-plate-ramp.txt`](data/title-plate-ramp.txt).