diff --git a/docs/re/units-per-frame-is-not-a-constant.md b/docs/re/units-per-frame-is-not-a-constant.md new file mode 100644 index 00000000..0d0842fa --- /dev/null +++ b/docs/re/units-per-frame-is-not-a-constant.md @@ -0,0 +1,113 @@ +# 🔴 `units per frame` is NOT a constant — the UI clock is TIME-based, and 60 units/s is right + +**Status: ✅ measured, and it withdraws my own 120 units/s.** 2026-09-01. +Instrument: ⟨capture⟩ — vertex alpha per present, two captures at different +presentation rates. + +**This is my fourth position on this number in one day and it returns to the +port's. Read the mechanism, not my confidence.** + +--- + +## The observation that settles it + +Splash B's logo quads, this capture, **14 consecutive gap-free steps**, four +independent quads agreeing exactly: + +``` +alphas 17 34 51 68 85 102 119 136 153 170 187 204 221 238 255 +steps 17 17 17 17 17 17 17 17 17 17 17 17 17 17 +``` + +The corpus's committed `h3-units-per-frame-measured.md` measured the **same +elements** at **+34 per frame** and concluded *2 units per frame*, pre-registered +and gap-free. + +**Both are right.** `Δα/present = 255 × (units/present) / T`, and with the declared +`T = 15`: + +| capture | presents/s | Δα/present | ⇒ units/present | **⇒ units/second** | +|---|---|---|---|---| +| `h3` | 27.2 | **34** | 2.0 | **54.4** | +| this one | 51.4 | **17** | 1.0 | **51.4** | + +**Units per present halved when the presentation rate doubled. Units per second +did not move.** + +> **So the UI clock advances by ELAPSED TIME, not by frame count.** "2 units per +> frame" was never a property of the game — it was a property of a capture that +> happened to run at 27 fps. + +## What this withdraws + +🔴 **My 120 units/s is wrong and is withdrawn.** It was `2 units/present × 60 +presents/s`. The first factor is not a constant, so the product is not a rate. + +🔴 **And the movie result is re-explained rather than refuted.** 2 presents per +decoded movie frame at 51.4 presents/s is a movie decoding at **25.7 fps** — a +30 fps movie running at 86 % under a slow emulator. Correct as a measurement; my +inference from it assumed the movie decoded at 30/s in *real* time, which it does +not when the emulator is slow. **Same shape as the first withdrawal: the +measurement held, the inference did not.** + +⚠️ **`h3-units-per-frame-measured.md`'s ✅ needs demoting too, and it is not mine.** +Its measurement stands; its *conclusion* — that 2 units/frame is the law — is a +single-capture artefact. That page is the origin of the constant this whole +question has been thrashing on. + +## Why 60 units/s is positively supported, not merely surviving + +A time-based clock is **immune to dropped frames**: dropping presents makes an +animation choppier, not slower. That predicts the *dwell in seconds* should be +stable across runs at different frame rates — and it is, across **four**: + +| | declared | measured dwell | +|---|---|---| +| publisher splash | 255 units | **4.263** (mine) · 4.297 · 4.604 · 4.370 s | +| developer splash | 210 units | **3.457** (mine) · 3.508 · 3.503 · 3.366 s | + +`255 / 4.27 = 59.7 units/s`. `210 / 3.46 = 60.7 units/s`. + +**Both land on 60 within ~1 %**, from runs whose present rates differ by 1.9×. +That agreement is only possible if the clock is time-based *and* the rate is 60 — +which is also the natural authoring choice, one unit per 1/60 s. + +**The port's 60 was right the whole time.** I moved off it twice on inferences +built over a constant that is not constant. + +## Consequences + +* ✅ **`units/s = 60`.** The plate's `t = 236` is **3.93 s**. The port changes + nothing, and this time the value is supported rather than merely undefended. +* 🔴 **Finding 3 is open again.** Units-per-second is eliminated as its cause, and + every other named candidate was eliminated earlier. It has **no surviving named + cause**, and the honest state is that we do not know. +* 📌 **Anything in the corpus that converts units to seconds via "2 units per + frame" is wrong at any frame rate but 30.** Convert via **units/60**. +* 📌 **The port's splash hold question is answered on the measurement, and the + numbers are below** — but note it now sits against 60, not 120. + +## The split the port asked for, measured rather than inferred + +Screen presents vs animation presents, this capture +([`data/splash-dwell-presents-vs-hostclock.txt`](data/splash-dwell-presents-vs-hostclock.txt)): + +| | screen | animating | holding | +|---|---|---|---| +| publisher | 219 | 54 (25 %) | **163 (74 %)** | +| developer | 186 | 58 (31 %) | **127 (68 %)** | + +⚠️ **These are presents, and presents are not units** — that is the whole point of +this page. In *units*, the declared timeline already carries the hold: the +publisher ramps `15→30`, holds `30→235` (**205 units**, 80 %), and fades `239→255`. +**The port does not need to author a hold at all; it needs to play the declared +timeline at 60 units/s**, which already contains one. The port's report that its +screen time equals its animation time suggests it is compressing the declared hold, +and that is a different bug from the constant. + +## Reach + +⟨capture⟩ ×2 for the rate-dependence (mine and `h3`'s, at 27.2 and 51.4 +presents/s), ⟨capture⟩ ×4 for the dwell stability. The rate-dependence is the load +bearing part and rests on two captures; a third at a deliberately different frame +rate would nail it, and `--framerate_limit` makes that cheap.