Files
Sylpheed/docs/re/boot-order-and-splash-dwell.md
sylph-decoder a1af583725 re: verify the splash's opaque-black backdrop, and the noun amendment
sylpheed-port found the fifth member of our error family on their own side: their
"visible" test counted any element with alpha > 0, which includes palogo_eff0.
Verified from the disc rather than accepted --

  entry 10  [0] palogo_eff0.prm  1 kf  t=0  fade=0xff000000  scale=100x100  pos=(0,0)
  entry 11  same

Alpha 255 over RGB 000000: full-screen opaque black, drawn from t=0 and showing
nothing. So "any element drawn" reports these screens visible from t=0 while the
frame is black -- "visible" read as "drawn".

Worth having on its own: this verifies from the disc the premise behind
`screen render --black`, which its own help states as "what the game composites
over on a screen carrying its own background". On the splash builds that
background is DECLARED, not assumed.

METHOD gains their amendment, which is the sharpest formulation either of us
reached this week: all five instances are a failure of a NOUN, not of a number.
Extent, bounding box, duration, span, visible. The number was always correct FOR
SOMETHING; what went missing was which thing. Every other check in that file
tests whether a number is right, and not one tests whether it is a number of the
thing you think.

Also teaches fade_quads.py to address a PAK ENTRY directly (`e10`) rather than
only a build ordinal. The splashes are entries 10/11 and are not screen builds,
so no ordinal addresses them -- and writing `e10` states which index space is
meant, which is the standing lesson of build-ordinal-vs-entry.md.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
2026-08-30 17:30:37 +00:00

217 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# The boot's first ten seconds: publisher, then developer — and the movie has a logo card too
**Status:**`CONFIRMED`. The **order** is measured in three independent cold
boots and confirmed **by eye**, not only by a correlation. The **dwells** are
**decoded** — they are on the disc, and the running game reproduces them to
within the emulator's own frame pacing.
Raised by the port agent against `data/boot-timeline-2026-08-29.tsv`, whose
`label` column runs `splash_dev` *before* `splash_pub` — the opposite of what
`authored/flow.json` carries. If that ordering were real it would be a boot-order
bug in the port. **It is not real, and this page says why.**
## The order: publisher first
![the two splashes and the movie's logo card](captures/boot-order/splash-order-two-runs.png)
*Brightened ×6 — these frames have a surface mean of ≈5/255. Top-left and
top-right are the two splashes; the bottom row is what comes next and is NOT a
splash.*
| run | `SQUARE ENIX` (publisher) | `GAME ARTS`/`SETA`/`studio anima` (developer) |
|---|---|---|
| 1 | 3.046 → 7.343 s | 7.683 → 11.191 s |
| 2 | 1.180 → 5.784 s | 6.051 → 9.554 s |
| 3 | 1.192 → 5.562 s | 5.929 → 9.295 s |
Three cold boots, `t = 0` at process launch, a ~0.20.3 s black hold between
them. **Publisher first, every time**, and the top row of the contact sheet is
what the two segments actually show. `docs/game/navigation.md` §1 and
[`ui-title-build-map.md`](ui-title-build-map.md) stand.
## Why the committed TSV says otherwise — the probe attached late
`data/boot-timeline-2026-08-29.tsv` opens at `t = 0.692` with twelve
**byte-identical** rows: mean `5.642`, `splash_dev` `+0.8707`, `splash_pub`
`+0.0294`, to four decimals. Twelve identical samples over 1.27 s are one
observation of a held screen, not twelve.
Those exact numbers appear in my run 1 at **8.42 10.94 s** — same mean, same
two correlations, same four decimals. So that capture's `t = 0` is roughly
**7.7 s into the guest's boot**: the publisher splash had already been and gone
before the stream opened, and the developer splash was simply the first thing the
probe ever saw.
**The label column is right about what each frame is. It is wrong about what came
before the file starts.** Nothing in the TSV is retracted; its *reach* is.
## The trap that makes this worse: `ADV.wmv` opens with a SQUARE ENIX card
After the developer splash there is a black hold and then a screen that scores
**0.59 0.75** against `live-splash-publisher.png` — above the classifier's
threshold, so it is labelled `splash_pub` a second time. In all three runs:
| run | second "splash_pub" |
|---|---|
| 1 | 17.793 → 20.301 s |
| 2 | 16.930 → 20.664 s |
| 3 | 14.669 → 17.308 s |
The bottom row of the contact sheet is that screen. It is a **blurred, bloomed
SQUARE ENIX wordmark, lower in the frame** — the intro movie's own opening title
card, i.e. `ADV.wmv` ([`movie-binding.md`](movie-binding.md)) already playing.
The real splash's wordmark is sharp and centred; the movie's is soft and sits
below centre.
⚠️ **So `splash_pub` is not a safe label once the movie has started.** A boot
classifier keyed on `live-splash-publisher.png` will fire twice per boot. The
discriminators that do work: the real splash holds *perfectly still* (identical
frame statistics to four decimals for seconds at a time) and scores **0.930.94**;
the movie card drifts continuously and never exceeds **0.76**.
## The dwells are on the disc — do not author them
Both splash bundles declare their whole life. Read with the corrected keyframe
record layout ([`ui-keyframe-record-layout.md`](ui-keyframe-record-layout.md))
and Q1's `1 unit = 1/60 s`:
| | declared | visible span | measured (run 1 / 2 / 3) |
|---|---|---|---|
| publisher, `palogo_sqex.t32` | α `0@15 → 255@30 → 255@235 → 232@239 → 32@251 → 0@255` | `15 → 255` = 240 u = **4.000 s** | 4.297 / 4.604 / 4.370 s |
| developer, `palogo_gamearts.t32` (`seta`, `anima` identical) | α `0@15 → 255@30 → 255@190 → 232@194 → 32@206 → 0@210` | `15 → 210` = 195 u = **3.250 s** | 3.508 / 3.503 / 3.366 s |
Measured ÷ declared, over all six spans: **1.074, 1.151, 1.093, 1.079, 1.078,
1.036** — mean **1.085**. A 30 Hz timeline stretched by 8.5 % is the game
presenting at **27.6 fps**, which is the rate this corpus has measured
independently three times (27.6 on the boot splash, 28.3 and 28.8 on the idle
title — [`ui-keyframe-time-unit.md`](ui-keyframe-time-unit.md)).
**Classified decoded.** The port reads **240 units** for the publisher and
**195 units** for the developer and authors nothing.
## 🔴 WITHDRAWN — "the game runs them ~8.5 % long". I measured one element's span and called it the screen's.
**Retracted the same day.** `sylpheed-port` said the port plays the **full group**
— 255 and 210 units — not my 240/195, and they are right for a reason sharper than
either of us first had. The `_eff` elements ramp **α 0 → 255 over t=0..15**, while
the main logo is still fully transparent there:
```
palogo_sqex.t32 0:a=0 15:a=0 30:a=255 235:a=255 239:a=232 251:a=32 255:a=0
palogo_sqex_eff.t32 0:a=0 15:a=255 30:a=212 45:a=0
```
So **the screen is visible from within t=0..15**, and its visible span is 0→255
and 0→210 — the full group. My "240 units visible" was **one element's** visible
span, computed while another element of the same build was already on screen.
Recomputed against the screen:
| | ratios | |
|---|---|---|
| publisher (255 u = 4.250 s) | 1.011, 1.083, 1.028 | |
| developer (210 u = 3.500 s) | 1.002, 1.001, **0.962** | one **below** unity |
| **mean** | **1.0145** | against 1.085 before |
A 1.5 % mean with a measurement below unity is not a clock running at 54 u/s.
**The systematic is gone and Q1 stands unqualified.**
⚠️ **And the consequence I drew was wrong too.** "A port playing 240 units at 60
shows the publisher splash 0.42 s less" — it plays 255, so the gap is 0.174 s, and
on the developer splash the port runs *longer* than my mean. There is no direction
to correct in, and nothing here supports moving `keyframe_units_per_second`.
🟡 **What survives, weakly:** against the full group the publisher still runs long
in all three boots (1.011, 1.083, 1.028) while the developer sits at unity. Three
boots per screen is thin and it is not a systematic.
### ✅ And the splash builds carry their own OPAQUE BLACK backdrop — verified
`sylpheed-port` found the fifth family member on their own side while confirming
the above: their "visible" test counted **any element with alpha > 0**, which
includes `palogo_eff0.prm`. Checked against the disc
(`tools/re-capture/fade_quads.py e10 e11`):
```
entry 10 [0] palogo_eff0.prm 1 kf t=0 fade=0xff000000 (alpha 255) scale=100x100 pos=(0,0)
entry 11 [0] palogo_eff0.prm 1 kf t=0 fade=0xff000000 (alpha 255) scale=100x100 pos=(0,0)
```
Alpha 255 over RGB `000000`: **full-screen opaque black, drawn from t=0 and
showing nothing.** So "any element drawn" reports these screens visible from t=0
while the frame is black — **"visible" read as "drawn"**, the fifth member.
📌 **Worth having on its own:** this verifies, from the disc, the premise behind
`screen render --black` — *"what the game composites over on a screen carrying its
own background, and so what a framebuffer capture must be compared against"*. On
the splash builds that background is **declared**, not assumed.
📌 **This is the fourth instance of one family** — pivot anchor read as drawn
extent, centre track as bounding box, cycle length as motion duration, and now
**one element's visible span read as the screen's**. Every one is a number used as
though it described the thing beside it.
`sylpheed-port` reported their `verify-dwell` at 4.28 s / 3.58 s and called it
agreement with these boots. Checking the arithmetic rather than the impression:
| | declared | at Q1's 60 u/s | measured (3 cold boots) | ratio |
|---|---|---|---|---|
| publisher | 240 u | **4.000 s** | 4.297 / 4.604 / 4.370, mean **4.424** | **1.106** |
| developer | 195 u | **3.250 s** | 3.508 / 3.503 / 3.366, mean **3.459** | **1.064** |
**All six ratios exceed 1** — 1.074, 1.151, 1.093, 1.079, 1.078, 1.036 — mean
**1.085**. The implied unit rate is **54.3** and **56.4 units/s**, and the port's
own two numbers imply **56.1** and **54.5**. Four estimates, none at 60.
⚠️ **The obvious explanation does not work.** A detector triggering early and
late would lengthen the interval — but the declared span *is* `15 → 255`, and
outside it the alpha is **0**, so there is nothing on screen to trigger on. An
8.5 % overshoot is 20 units, ten rendered frames, which a threshold cannot
manufacture from a blank screen.
🟡 **So this is a real systematic and its cause is not established.** Either the
title's timeline advances at ~55 units/s rather than Q1's 60, or the boot inserts
something between the declared span and what a capture sees. ⚠️ It is **not** the
same discrepancy as the sweep leaf's (which runs ~50 % slow, not 8.5 %), and I am
recording it as an open qualification on Q1 rather than a correction to it — three
boots per screen is thin, and Q1 was measured on a different quantity.
📌 **For the port:** these dwells are still *decoded* and still should not be
authored — but a port that plays 240 units at exactly 60 u/s will show the
publisher splash for **0.42 s less** than the game does.
⚠️ **Reach of the ±:** a correlation crossing a threshold during a fade is not a
sharp edge, so an individual span is good to roughly ±0.2 s. The developer's
first two runs agree to **5 ms**, which is the instrument at its best; run 2's
publisher span (4.604 s) is the outlier and its onset at 1.180 s is early enough
to be a stream still filling. The *order* does not depend on any of this.
## Method
`tools/re-capture/boot_timeline_probe.py`, whose `--control` was run first and
passed **11/11** on the content classifier and **4/4** on the plate detector,
including `live-splash-publisher.png → splash_pub` and
`live-splash-developer.png → splash_dev` with each rejecting the other at
**0.035**. So a 0.87 reading against the developer reference is a real match and
not an artefact of two dark images: the two references are both dark and they do
not correlate with each other.
Both splash references are themselves committed captures whose identity is
independent of any correlation — `live-splash-publisher.png` was matched to
`GP_TITLE` entry 10, whose elements are literally named `palogo_sqex`, and
`live-splash-developer.png` to entry 11, `palogo_gamearts` / `palogo_seta` /
`palogo_anima`.
Boots were cold: `/dev/shm/xenia_*` cleared, no pad input at any point.
## What this does not say
* Nothing here is about the **movie's** length or the attract loop; the runs were
cut at 2645 s. That half is in `data/boot-timeline-2026-08-29.tsv`, whose
*intervals* are unaffected by the attach offset even though its absolute `t` is.
* The 0.20.3 s black hold between the two splashes was not separately timed
against the declared `palogo_eff0.prm` backdrop; it is consistent with the
0.140.30 s black hold already measured between screens
([`title-plate-delay-measured.md`](title-plate-delay-measured.md)) but that is
a consistency note, not a measurement of this particular gap.