The Port's arithmetic was right: a 160-unit sub-interval cannot outlast the 210-unit group containing it, and my hold (4.514 s) outlasted three cold-boot measurements of the whole group (3.37/3.50/3.51 s). My own capture says why, once asked the right question. The three numbers I quoted came from three regions of ONE run, and I never asked how fast the emulator was going in each: splash B (the hold) 3.39 labels/guest-second -> I reported 35.4 splash A (publisher) 15.33 -> I reported 40.0 the title (the plate) 23.20 -> I reported 56.8 Monotonic. The 'per-GamePart rate' is the pacing of the region it was measured in. Splash B was captured at 3.4 fps, an eighth of the title region. And the corpus already had this. boot-splash-dwells-are-declared.md says in its own words that the wall-clock dwell is an emulator-pacing artefact that varies run to run, with a no-input boot 15-20% long on the same declared timeline. I re-derived a documented artefact as a discovery and drew a false conclusion from it. The instrument lesson, which is the part worth keeping: I believed the guest timebase removed the artefact. It does not. The game's animation clock is not the guest timebase -- it is frame-coupled -- so a slow run advances less animation per guest second and no clock can see that from inside. My control asked 'does this timebase track real time', which is capability. The question that mattered was 'is the quantity I divide by coupled to the frame rate', and nothing I ran asked it. That is PROTOCOL's own warning, which I quoted at the other agent two iterations ago and then walked into. Restated: the clock is neither purely frame-counted (21 vs 33 labels for one animation) nor purely time-integrated (rate scales with frame rate). Consistent with a clamped per-frame delta, untested, and now the real open question. Consequence: no rate measured on this emulator is the console's; all are biased low. Best estimate stays the declared timeline against the fastest runs -- 60 units/s, 1.1% on the developer splash. The port keeps 60 for every screen and nothing needs averaging. Untouched: section 1 of splash-declared-vs-captured.md. It compares a disc table against vertex alphas at integer t and never divides by a duration, so the pacing artefact cannot reach it.
139 lines
6.8 KiB
Markdown
139 lines
6.8 KiB
Markdown
# The declared timeline **does** reproduce the captured splash — and the unit rate is **per-GamePart**
|
||
|
||
**Status: ✅ two results, one of which corrects me.** 2026-09-01.
|
||
Instrument: ⟨disc⟩ for the declared side, ⟨capture⟩ for the observed side.
|
||
**No renderer is anywhere in this comparison** — it is a keyframe table against a
|
||
vertex stream.
|
||
|
||
Settles the R1-re-opened entry *"the declared keyframe timeline reproduces the
|
||
captured splash"*, 🟡 `⟨our-reader⟩`, whose stated condition was *"re-derive the
|
||
declared timeline under the fixed record layout and re-compare against the same
|
||
frames."*
|
||
|
||
---
|
||
|
||
## 1 ✅ The declared timeline reproduces the capture to **one alpha level**
|
||
|
||
Declared, off the disc ([`data/splash-declared-timeline.txt`](data/splash-declared-timeline.txt)),
|
||
`GP_TITLE` build 11:
|
||
|
||
| family | declared keyframes |
|
||
|---|---|
|
||
| logos (`palogo_gamearts`, `_seta`, `_anima`) | `0:a=0 15:a=0 30:a=255 190:a=255 194:a=232 206:a=32 210:a=0` |
|
||
| glows (`_gamearts_eff`, `_seta_eff`) | `0:a=0 15:a=255 30:a=255 45:a=0` |
|
||
| `palogo_anima_eff` | `0:a=0 15:a=255 **30:a=212** 45:a=0` |
|
||
|
||
Captured: the per-quad vertex alphas from the draw stream
|
||
([`data/splash-quad-timeline.txt`](data/splash-quad-timeline.txt)).
|
||
|
||
**Test — deliberately calibration-free.** No fitting, no clock, no lag search:
|
||
*is each captured alpha an exact member of the declared value set*, i.e. equal to
|
||
the declared piecewise-linear α(t) at some integer t?
|
||
|
||
| | |
|
||
|---|---|
|
||
| samples | **50** |
|
||
| exact members under **truncation** | **39 / 50** |
|
||
| exact members under **rounding** | 30 / 50 |
|
||
| **worst error under either rule** | **1 alpha level out of 255 — 0.39 %** |
|
||
| samples off by more than one level | **0** |
|
||
|
||
**Every one of the 11 non-exact samples is low by exactly 1**, and every one of
|
||
them is on a *falling* segment. Truncation fits better than rounding by 9
|
||
samples, which is what an integer interpolator that floors rather than rounds
|
||
looks like.
|
||
|
||
📌 **So the entry resolves in favour of the declared timeline.** The old ❌ rested
|
||
on *"`palogo_gamearts` is still at `a=255` nine frames after its declared
|
||
`a=32`"* — under the fixed record layout `a=32` is at **t=206**, four units from
|
||
the end of a 210-unit timeline, not early. That was the off-by-one association,
|
||
exactly as the R1 note suspected.
|
||
|
||
🟡 **What is not settled:** *why* 11 samples floor one low while 39 do not. The
|
||
residual is one level and is named, not hidden. A candidate is that the clock is
|
||
fractional and α is floored, so a sample lands one low whenever the fraction is
|
||
small — untested.
|
||
|
||
## 2 ❌ WITHDRAWN — "the unit→seconds rate is per-GamePart"
|
||
|
||
> 🔴 **This section is REFUTED and is kept only for the record.** See
|
||
> [`splash-rate-withdrawn.md`](splash-rate-withdrawn.md). The three "rates" below
|
||
> came from three regions of one run at **3.39 / 15.33 / 23.20 labels per guest
|
||
> second**, and the reported rates order the same way — 35 / 40 / 57. It is the
|
||
> emulator's pacing, not the `GamePart`. The corpus already documented the effect
|
||
> in `boot-splash-dwells-are-declared.md`; I re-derived it as a discovery and drew
|
||
> a false conclusion from it. **The rate is 60 units/s for every screen, and §1
|
||
> above is untouched.**
|
||
|
||
### the withdrawn text follows
|
||
|
||
#### (withdrawn) The unit→seconds rate is **per-GamePart**, and I told the port otherwise
|
||
|
||
This is the correction, and it matters more than the first result.
|
||
|
||
An hour ago I reported **56.8 units per guest second** off the plate and wrote
|
||
that the reach was the title. The splash now has its own measurement, from the
|
||
disc-declared `T` rather than a borrowed one, and **it is a different number.**
|
||
|
||
| screen | element | declared | measured | **units / guest second** |
|
||
|---|---|---|---|---|
|
||
| title | `ptbtn00` ramp | `T = 22` (`t=214→236`, ⟨disc⟩) | 657.9 α/s | **56.8** |
|
||
| title | `ptcopyright` ramp | implied `T = 22.25` | 650.4 α/s | 56.8 (control, 1.15 %) |
|
||
| splash | `palogo_gamearts` ramp | `T = 15` (`t=15→30`, ⟨disc⟩) | 664.8 α/s | **39.1** |
|
||
| splash | publisher logo ramp | `T = 15` ⟨disc⟩ | 679.4 α/s | **40.0** |
|
||
| **splash** | **`palogo_gamearts` HOLD** | **160 units (`t=30→190`) ⟨disc⟩** | 4.514 guest s | **35.4** |
|
||
|
||
### The hold is what makes this safe to say
|
||
|
||
A ramp rate is `(Δα/Δt) × T/255` and therefore depends on `T`. **The hold does
|
||
not.** It is a declared *duration* — 160 units of plateau — measured directly in
|
||
guest seconds, with no alpha slope, no interpolation and no `T` in the
|
||
arithmetic. It gives **35.4 units/s** against the same screen's ramp at 39.1, and
|
||
the two share none of their algebra.
|
||
|
||
⚠️ The hold figure is a **lower bound on the rate**: it is measured between the
|
||
first and last labels at α=255, and the true plateau extends slightly past both.
|
||
So the splash sits at **~35–40 units/s** and the title at **~57**.
|
||
|
||
### Why I nearly missed it — recorded because it is a good trap
|
||
|
||
All four elements give **650–679 α/s**, agreeing to ±2 %, which reads exactly
|
||
like one clock. It is a coincidence: `T` differs 22 vs 15 (ratio 1.47) and the
|
||
rates differ 57 vs 37 (ratio 1.54), and those two ratios nearly cancel in
|
||
`Δα/Δt`. **A quantity that looks constant across screens is not evidence of one
|
||
clock when the thing that would vary is inside it.** The hold breaks the tie
|
||
because `T` is not in it.
|
||
|
||
### And my "borrowed `T=15` does not apply" was wrong
|
||
|
||
[`units-per-second-measured.md`](units-per-second-measured.md) says the splash
|
||
elements' implied `T` is 23–34, *"none of them 15"*, derived by assuming one
|
||
rate. **The disc says `T = 15`, plainly.** The premise was the single rate, not
|
||
the `T`. Both halves of that page's arithmetic were right and its conclusion
|
||
about which term was unknown was wrong.
|
||
|
||
## What this means for the port
|
||
|
||
🔴 **A single `keyframe_units_per_second` cannot be right.** The two splashes and
|
||
the title run their timelines at rates ~1.5× apart, and the splashes are exactly
|
||
the screens the play-test called *"close but not right"*.
|
||
|
||
* title: **~57 units/s** — the port's 60 is 5 % away and stands.
|
||
* splashes: **~35–40 units/s** — a port running them at 60 plays them **1.5–1.7×
|
||
too fast**, which would make every splash fade look shorter and sharper than
|
||
the game's. That is the direction of *"the fade is more pronounced in the
|
||
game"*.
|
||
|
||
**Classified: measured**, not decoded. Nothing on the disc has been found that
|
||
*states* a rate; these are two numbers off the running game. The port authors
|
||
them and must know it is authoring.
|
||
|
||
## Reach
|
||
|
||
Two `GamePart`s, one boot each. It establishes that the rate is **not global**,
|
||
which is a negative with wide reach — one counter-example is enough. It does
|
||
**not** establish the rate for the main menu, `EXTRAS`, or any submenu, and those
|
||
must not inherit either number. ❔ Where the rate comes from — a per-`GamePart`
|
||
field, a constant in the driver, or a frame-rate target — is **not decoded**, and
|
||
that is the next question.
|