# ✅ The guest presents at **60 fps** — **120 units/s**, and that is the plate-late cause **Status: ✅ measured**, against [`movie-decode-vs-rotate-preregistration.md`](movie-decode-vs-rotate-preregistration.md), committed **before** the capture. Instrument: ⟨capture⟩ — the real game in Canary with a texture **content hash** added to the draw logger for this question. Data: [`data/movie-decode-vs-rotate.txt`](data/movie-decode-vs-rotate.txt). ⚠️ **This is my third position on this number today.** The first (60 units/s) was withdrawn by me; this reverses it. What is different is not confidence — it is that the instrument now tests the thing that was assumed before, and the control that would expose the failure passed. Read the controls before the verdict. --- ## The result | | predicted | measured | |---|---|---| | **D** decode per present ⇒ 30 fps ⇒ 60 units/s | ≥ 0.90 | — | | **R** rotate per present ⇒ 60 fps ⇒ **120 units/s** | 0.40–0.60 | **0.5739** | ``` movie luma draws 177 (presents 422..599) distinct BASES 3 59 uses each <- rotation distinct CONTENT HASHES 102 <- decodes consecutive presents, content changed 101/176 = 0.5739 run lengths (presents showing the SAME content): 1 present : 29 2 presents: 72 <-- the mode 4 presents: 1 ``` **The buffer rotates three times faster than the content changes.** 177 presents carry only 102 distinct frames, and the modal run is **exactly 2 presents per decoded frame**. That is `R`. 📌 **And this is precisely the failure that invalidated my first answer.** The base address changed every present — which is what I measured and read as "one decode per present". The content did not. A base-keyed census cannot see the difference; a content hash can, and it says the guest presents **twice per decoded movie frame**. `ADV.wmv` is authored at 30.000 fps ⟨disc⟩, so 2 presents per movie frame is **60 presents per second ⇒ 2 units/present × 60 = 120 units/s.** ## The controls, both of which had to pass **Control 1 — a static texture must hash constant.** The splash sprite atlas (1280×768) is uploaded once per splash and sampled throughout. If its hash moved between presents, the hash would be racing the writer and nothing else could be read. ``` h=54D8DB4A2249A978 frames 1..219 n=218 h=478C1E9F56EE5485 frames 224..409 n=186 hash changes between consecutive samples: 1 of 403 ranges disjoint: True ``` **PASS**, and in the informative way: it changes **once**, at an era boundary — a genuine re-upload between the two splashes — and never within an era. ⚠️ I first wrote this control as *"must be constant"* and it read as FAIL. Stated that way it was wrong: a re-upload is real content change and the control has to distinguish *temporal* change from *alternating* change. Recorded because a control that is too strong gets waved away, which is its own failure mode. **Control 2 — the movie luma hash must NOT be constant**, or I am hashing the wrong bytes and would manufacture `R`. **PASS**: 102 distinct hashes. **These are the controls the withdrawn version lacked.** Both of its guards tested how I *read* the buffer; neither tested whether a buffer change meant a decode. ## 🔴 What this means for the play-test > **The plate's `t = 236` is 1.97 s, not 3.93 s. The port shows it ~1.96 s late.** That is finding 3, and *"about two seconds"* is the size a human reported. Two of the play-test's four named candidates were eliminated earlier (the ramp is drawn; the onset is a completion) — **the survivor is the unit→seconds constant**, which is where the play-test put it first. Everything downstream of `units/s` moves with it: every declared duration on every screen is **half** what the corpus has been quoting in seconds. Unit *counts* are untouched, and so is `2 units per present`. ## Reconciling the third route — and this part is POST-HOC, labelled as such `title-plate-delay-measured.md` measured 120 declared units at **2.13 s**, twice, agreeing to 6 ms ⇒ ~56 units/s. At 120 units/s that interval is **1.00 s** true, so that run's emulator was at ~47 % speed. Plausible — its own harness documents `screenshot` costing **10.8 s while xenia is running** — and this capture independently measured only **44.5 presents per host-second** against a 60 fps guest, i.e. 74 % speed with a far lighter harness. ⚠️ **But I fitted a speed factor to close a gap, which is what this corpus keeps losing claims to.** It is an *explanation*, not evidence, and it is not offered as support for 120. The support for 120 is the hash ratio and its two controls. ## Reach, and what is still not settled ⟨capture⟩, **one boot**, one movie region, this emulator. The ratio is inside its band and both controls pass, but this number has now moved twice and **a second independent boot is the obvious next step before the port rewrites a timeline.** * ❔ **Whether Canary's cadence equals a real console's.** The vblank interval (one vblank 71.7 %, two 24.6 %) is consistent with a 60 fps guest, but it is host time. A 360 vblanks at 60 Hz and the game presents every vblank here; that it would do the same on hardware is an inference. * ❔ **The clock origin** — untouched, and still the other half of finding 3. A common offset survives everything measured here, because every quantity above is a ratio or a count.