Files
Sylpheed/docs/re/structures/boot-splash-dwells-are-declared.md
sylph-decoder d8d834709f re: withdraw the splash frame boundaries -- count the batch, not the logged quads
The port refuted the boundaries in boot-splash-dwells-are-declared.md by
arithmetic: the two splash spans gave 2.237 and 2.414 units/frame, 7.9% apart on
one boot of one guest, which must be one number. They proposed the spans were
anchored on different elements.

The log says the cause is worse. The developer splash batches SIX quads into one
draw (indices=24) and the log dumps only the first two. While the three glows are
alive they occupy that prefix, so the three wordmarks are invisible to the log
until the glows stop being submitted at t=45. "Developer wordmarks first drawn at
frame 140" was the logging prefix shifting, not the game -- and the same defect
explains why palogo_anima never appeared at all.

The fix costs nothing: indices/4 is how many quads the draw actually holds, and
the 8-vertex cap cannot touch it. Its transitions land exactly where the declared
count of elements with alpha>0 changes, giving free calibration points:

  publisher   1->2 quads at frame 5.5 (t=15), 2->1 at 22.5 (t=45), ends 119.5 (t=255)
  developer   3->6 quads at frame 126.5 (t=15), 6->3 at 139.5 (t=45), ends 209.5 (t=210)

That yields 1.765 and 2.165 units/frame on the publisher, 2.308 and 2.357 on the
developer -- the developer's two independent segments agreeing to 2%, and the rate
rising 33% across the run. One cause for both the port's 7.9% inconsistency and
this page's open 4.1% publisher error, exactly as they predicted: the publisher
splash runs during the first seconds, where the rate is furthest from its later
value. It also means no single units-per-frame figure describes a run here, which
is the dwell-is-emulator-paced conclusion from a third direction.

The declared dwells (255 and 210 units) and the corpus's three-cold-boot
confirmation are untouched -- neither uses this draw log.

METHOD.md gains the general form: when an instrument truncates, the surviving
sample is not random, it is the first N, and what falls in the first N is itself a
moving function of the thing being measured. A truncated view looks like a
complete view of a smaller set.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsEPXWVaEpyfudtR6re1Pd
2026-08-29 21:34:51 +00:00

5.4 KiB
Raw Blame History

The boot splash dwells are declared on the disc — wall clock is the wrong unit

Classification: decoded, with an independent wall-clock check. The port asked for two timestamps; the right answer is that timestamps are not the invariant.

The answer

splash bundle declared timeline at 60 units/s corpus wall clock, 3 cold boots error
publisher GP_TITLE entries 10, 13 t = 0 … 255 4.250 s 4.30 / 4.60 / 4.37 4.1 %
developer entries 11, 14 t = 0 … 210 3.500 s 3.51 / 3.50 / 3.37 1.1 %

The developer splash is the sharp one: 3.500 s declared against 3.51 and 3.50 measured on two of three boots. Author the units.

Why not seconds — this run is the argument

A fresh no-input boot with a frame→wall-clock map (below) puts the same two dwells at 5.10 – 5.61 s and 3.83 – 4.30 s — 15–20 % longer than both the declared values and the corpus's three runs, on the same disc and the same declared timeline.

So the wall-clock dwell is an emulator-pacing artefact that varies run to run. Three separate measurements of this container's rate — 13.1 fps, ~28 fps, and this one — say the same thing from another direction. A port that authors seconds is authoring one run's pacing.

🔴 The boundaries — corrected, after the port refuted them

An earlier version of this page read element visibility off which quads appear in the log. That is wrong, and the port caught it by arithmetic: the two splash spans came out at 2.237 and 2.414 units/frame, 7.9 % apart on one boot of one guest, which should be one number.

Their diagnosis was that the spans were anchored on different elements — the publisher's on its wordmark, the developer's on its glows. The log says the cause is worse: the developer splash batches SIX quads into one draw and the log dumps only the first two. While the glows are alive they occupy that prefix, so the three wordmarks are invisible to the log until the glows stop being submitted. "Developer wordmarks first drawn at frame 140" was the logging prefix shifting, not the game.

✅ The fix is to count the batch, not the logged quads. indices / 4 is the number of quads the game is submitting, and the 8-vertex cap cannot touch it. The count changes exactly where the declared set of elements with alpha > 0 changes:

splash transition frame t
publisher 1 → 2 quads, the wordmark joins the glow 5.5 15
2 → 1, the glow ends 22.5 45
last drawn 119.5 255
developer 3 → 6 quads, three wordmarks join three glows 126.5 15
6 → 3, the glows end 139.5 45
last drawn 209.5 210

✅ And that explains the 4.1 %: the rate drifts through the run

segment units frames units/frame
publisher, t = 15 → 45 30 17 1.765
publisher, t = 45 → 255 210 97 2.165
developer, t = 15 → 45 30 13 2.308
developer, t = 45 → 210 165 70 2.357

Within the developer splash the two independent segments agree to 2 %. Across the run the rate rises from ~1.76 in the first seconds to ~2.36 — a 33 % drift.

That is one cause for both the port's 7.9 % inconsistency and this page's open 4.1 % publisher error, which is what they predicted: "I'd expect one problem behind a 7.9 % inconsistency and a 4.1 % error on the same screen before I'd expect two."

⚠️ It also means no single units-per-frame figure describes a run here, which is the same conclusion as the dwell being emulator-paced, arriving from a third direction.

🔴 The instrument's resolution is one buffer flush, not one frame

tools/re-capture/frame_clock.sh polls the growing draw log for its last frame number. The capture writes through a C++ ofstream, so tail sees the file in flush-sized bursts:

  • 69 of 125 samples showed no advance at all; the rest jumped 7–15 frames at once.
  • Interpolating a frame's time inside a burst invents precision. Done naively it made the apparent rate swing between 0.0164 and 0.0316 s/frame — 61 fps to 31 fps — which is the flush, not the guest.
  • Frames 119 and 123 fall in the same burst, so the black gap between the splashes is not separable by this instrument at all. Its duration here comes from frame counting, not from this clock.

So the table above is quoted as brackets: a frame's true time lies between the last sample that had not reached it and the first that had. Sub-flush point estimates are not available and were withdrawn before being reported.

What is still open

✅ The publisher's 4.1 % error against the developer's 1.1 % is explained by the units/frame drift above — the publisher splash runs during the first seconds, where the rate is furthest from its later value.

⚠️ The intro-video boundary (frame 216) is 7 frames after the developer splash's last draw, but those 7 frames span 1.77 s by the naive map — deep inside the flush artefact, and the movie is loading there. The developer→intro gap is not measured, only bounded at 5.70 – 6.21 s end to end.

Reproducing

GRACE=1 NOTAP=1 FRAMES=9000 ARM=early tools/re-capture/ui_draw_capture.sh 200 /tmp/cap &
tools/re-capture/frame_clock.sh /tmp/cap/xenia_re_ui_draws_01.log /tmp/cap/frameclock.tsv \
    150 0.2 /tmp/cap/canary.stdout 400