sylpheed-port asked which of my figures predate the keyframe record-layout fix,
noting the sharper form of the hazard: a fix that changes WHICH ROWS EXIST is
harder to sweep for than one that changes values, because the recomputation looks
like a correction rather than a different question.
Located the fix (5744f37, 2026-08-29 14:01) and enumerated docs quoting
keyframe-derived numbers that have not been touched since. One real hit:
structures/ui-group-start-time.md, a page about group START TIMES, written -- in
its own words -- "under the shifted time reading" and referring to the glows'
"untimed first keyframe".
Durations survive. The glow is visible ~0..45 (45 units) and the logo ~15..210
(195 units), exactly what its table already used; the "~0" it hedged with is now
a real timed 0.
The argument did not. It read "every glow declares the same times 15, 30, 45 ...
both families start at 15". Post-fix both start at 0, with times 0,15,30,45 and
0,15,30,190,194,206,210. Corrected in place with the original sentence quoted so
the change is visible.
The conclusion is unchanged and slightly stronger: on one clock the glow is
visible over 0..45 and the logo over 15..210, an overlap of 30 of the glow's 45
units, where the capture shows no overlap at all (glows frames 94-115, logos
116-211). A shared clock origin was contradicted before and is contradicted by a
wider margin now, because both groups demonstrably begin at the same declared
instant.
Of the three figures the port reports having quoted from me, the splash dwell
spans were already corrected today and the black-gap and cold-boot intervals are
capture-derived, so the fix does not reach them.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
239 lines
11 KiB
Markdown
239 lines
11 KiB
Markdown
# ❔ A group's DURATION is in the data; its START TIME is not
|
||
|
||
**Status:** ✅ the durations are measured and match; ❔ the start offset is
|
||
**undecodable from the placement data**, with the obvious candidate refuted.
|
||
|
||
Found while testing whether the splash timeline, *played*, reproduces the
|
||
capture sequence — the last gap in the animation model.
|
||
|
||
## The durations are right
|
||
|
||
From the 235-frame draw capture of the developer splash, at the settled
|
||
2 units/frame, under the shifted time reading:
|
||
|
||
| element | drawn on frames | = units | declared visible span | match |
|
||
|---|---|---|---|---|
|
||
| `palogo_gamearts_eff`, `palogo_seta_eff` | 94–115 (22) | 44 | ~0 … 45 = **45** | **97.8 %** |
|
||
| `palogo_gamearts`, `palogo_seta` | 116–211 (96) | 192 | 15 … 210 = **195** | **98.5 %** |
|
||
|
||
(The logos are `a = 0` until t=15, so they are *drawn* for 15…210; the glows fade
|
||
in from their untimed first keyframe.) **Each element is on screen for its
|
||
declared span, to within 2 %.**
|
||
|
||
## ⚠️ Re-checked against the corrected reader, 2026-08-30 — durations survive, the argument needed fixing
|
||
|
||
This page was written **"under the shifted time reading"** — its own words — and
|
||
refers to the glows' *"untimed first keyframe"*. Both are pre-fix artifacts: the
|
||
[record-layout fix](../ui-keyframe-record-layout.md) (`a975517`, 2026-08-29 14:01)
|
||
times a group's final pose, and this page has not been touched since. Swept after
|
||
`sylpheed-port` asked which of my figures were computed before it. Post-fix:
|
||
|
||
```
|
||
palogo_gamearts.t32 0:a=0 15:a=0 30:a=255 190:a=255 194:a=232 206:a=32 210:a=0
|
||
palogo_gamearts_eff.t32 0:a=0 15:a=255 30:a=255 45:a=0
|
||
```
|
||
|
||
✅ **The durations above are unaffected** — the glow is visible ≈0…45 (45 units)
|
||
and the logo ≈15…210 (195 units), which is exactly what the table already used.
|
||
The `~0` it hedged with is now a real, timed `0`.
|
||
|
||
## 🔴 But they do not share a clock origin
|
||
|
||
⚠️ **The original sentence here was pre-fix and is corrected.** It read: *"Every
|
||
glow declares the same times — `15, 30, 45` — and every logo the same `15, 30,
|
||
190, 194, 206, 210`. On one clock they would overlap almost entirely: both
|
||
families start at 15."* Post-fix **both families start at `0`**, and the times are
|
||
`0, 15, 30, 45` and `0, 15, 30, 190, 194, 206, 210`.
|
||
|
||
📌 **The conclusion is unchanged and slightly stronger.** On one clock the glow is
|
||
visible over units 0…45 and the logo over 15…210 — an overlap of 30 of the glow's
|
||
45 units. Measured, they overlap **not at all**: glows on frames 94–115, logos
|
||
116–211, the logos starting the frame after the glows end. A shared origin was
|
||
contradicted before and is contradicted by a wider margin now, because both groups
|
||
demonstrably begin at the same declared instant.
|
||
|
||
**They do not overlap at all.** The glows run frames **94–115** and the logos
|
||
**116–211** — strictly sequential, the logos starting the frame after the glows
|
||
end. Fitting a single origin bears this out: `gamearts_eff` needs f₀ ≈ 93.5 and
|
||
`gamearts` needs f₀ ≈ 103, about **19 units apart**, and the same edit that
|
||
aligns one throws the other off by ~9 frames at both ends.
|
||
|
||
## 🔴 The obvious candidate is refuted
|
||
|
||
`parse_placements` reads each group header as `(element index, keyframe count)`
|
||
followed by **one undecoded lead-in word**. That is exactly where a per-group
|
||
start offset would live. It is **`0x00000000` for all seven elements** of the
|
||
developer splash — glows and logos alike. It carries no offset.
|
||
|
||
## ❔ So where does the start come from?
|
||
|
||
Not from the keyframe times (identical across each family), not from the group
|
||
header's spare word (zero), and not from declaration order (`eff0.prm`, gamearts,
|
||
gamearts_eff, seta, seta_eff, anima, anima_eff — which interleaves logos and
|
||
glows, while the observed sequencing groups them). The RATC child order does not
|
||
match the observed order either.
|
||
|
||
Reach: three places looked, all negative. What remains is that the sequencing is
|
||
**driven by code**, consistent with what
|
||
[boot-config-and-gamepart-registry](../boot-config-and-gamepart-registry.md)
|
||
already concluded for the boot order — *the driver is code, not data*.
|
||
|
||
## ⚠️ What a port needs to know
|
||
|
||
A group tells you **how long** an element's animation runs and what it does; it
|
||
does **not** tell you **when** that animation starts relative to other elements
|
||
on the same screen. On the developer splash the observed order is: both glows
|
||
together, then both logos together. That is a **measured** sequence for one
|
||
screen, not a decoded rule — a port animating a screen has to author the
|
||
sequencing, and should know it is authoring.
|
||
|
||
---
|
||
|
||
## ✅ Verified against its own refutation — and it goes further than start times
|
||
|
||
**2026-08-29.** Two checks on the "sequential, not simultaneous" reading.
|
||
|
||
### The phases really are disjoint
|
||
|
||
If the glows and logos ever shared a frame, the sequencing claim would be wrong.
|
||
Across all 235 captured frames, the number of frames containing **both** a glow
|
||
and a logo is **zero**. The switch is a single clean boundary:
|
||
|
||
```
|
||
f110–115 1280x720 + 262x108 + 525x90 ← both glows
|
||
f116–122 1280x720 + 243x86 + 499x72 ← both logos
|
||
```
|
||
|
||
Two sprites either side, no overlap, no transition frame.
|
||
|
||
### A third of the bundle is never drawn at all
|
||
|
||
Entry 11 declares **three** logo/glow pairs. Only two are ever drawn:
|
||
|
||
| sprite | declared | drawn |
|
||
|---|---|---|
|
||
| `palogo_gamearts` / `_eff` | 500×71 / 521×91 | **95 / 22 frames** |
|
||
| `palogo_seta` / `_eff` | 240×89 / 261×110 | **95 / 22 frames** |
|
||
| `palogo_anima` / `_eff` | 388×136 / 407×156 | **never** |
|
||
|
||
…and `palogo_anima` declares the *same* keyframe times as `palogo_gamearts`.
|
||
⚠️ Reach: the capture covers frames 1–214, so this is "never **within the
|
||
window**", not "never". The pair may follow after it.
|
||
|
||
### What that means for a consumer
|
||
|
||
**A bundle is a palette, not a script.** Its elements carry what to draw and for
|
||
how long; which of them run, and when each starts, is decided outside the
|
||
placement data — selectively enough that two elements with byte-identical
|
||
keyframe times get 95 frames and 0 frames in the same run.
|
||
|
||
That is the same conclusion the boot-order work reached from the other end
|
||
(*the driver is code, not data*), now with a per-element measurement behind it.
|
||
|
||
⚠️ Concretely: **compositing every element of a bundle does not reproduce what
|
||
the game shows over time.** It is the right thing for a static screen that
|
||
settles, and it is not a timeline.
|
||
|
||
---
|
||
|
||
## 🔴 Narrowing "a bundle is a palette" — the mechanism is NOT established
|
||
|
||
**2026-08-29.** The glow phase and the logo phase are disjoint, but there are two
|
||
explanations and I asserted one of them:
|
||
|
||
1. **one bundle, selective activation** — the game runs some of entry 11's
|
||
elements, then others;
|
||
2. **two bundle-loads in sequence** — the game shows one composition, then
|
||
another (entries 11 and 14 are twins declaring identical sprites).
|
||
|
||
The draw log records each draw's **texture base**, which looked like it would
|
||
separate them. It does not:
|
||
|
||
| phase | frames | texture bases |
|
||
|---|---|---|
|
||
| publisher splash | 1–90 | `0x11C30000`, `0x10000000` |
|
||
| glows | 94–115 | `0x11C30000`, `0x10000000` |
|
||
| logos | 116–211 | `0x11C30000`, `0x10000000` |
|
||
|
||
**The test fails its own control.** The publisher splash is certainly a different
|
||
bundle from the developer splash — different entry, different artwork — and it
|
||
uses the *same* base. So `0x11C30000` is a reused upload address, not a bundle
|
||
identity, and it cannot distinguish hypothesis 1 from hypothesis 2.
|
||
|
||
### What survives, and what I withdraw
|
||
|
||
✅ **Survives:** a bundle's declared elements are not what gets drawn.
|
||
`palogo_anima` and `palogo_gamearts` carry byte-identical keyframe times, and in
|
||
the same run one is drawn for 95 frames and the other for none — whichever of the
|
||
twins was active declares *both*. The phases are also strictly disjoint (0 frames
|
||
of overlap in 235).
|
||
|
||
🔴 **Withdrawn:** the mechanism. "One bundle, elements activated selectively" was
|
||
my reading, and the evidence does not choose it over "two compositions shown in
|
||
sequence". The practical consequence is the same either way — compositing every
|
||
element of a bundle does not reproduce what the game shows over time — but the
|
||
*why* is not established and should not have been stated as though it were.
|
||
|
||
❔ What would separate them: a per-draw capture recording the **bundle** each draw
|
||
came from, or a kernel/file-IO log showing whether a second RATC entry is read
|
||
between frames 115 and 116.
|
||
|
||
---
|
||
|
||
## ✅ Re-established, by elimination — selective activation is happening
|
||
|
||
**2026-08-29.** The alternative can be killed statically, which I had not tried.
|
||
Hypothesis 2 needs a bundle that declares the **glows without the logos**. There
|
||
is none. Enumerating every entry in `GP_TITLE` that contains `palogo` elements:
|
||
|
||
| entry | elements |
|
||
|---|---|
|
||
| 10, 13 (publisher twins) | `palogo_eff0.prm`, `palogo_sqex`, `palogo_sqex_eff` |
|
||
| 11, 14 (developer twins) | `palogo_eff0.prm`, **all three logos and all three glows** |
|
||
|
||
Four entries, and each developer entry declares the **complete set of six**. So
|
||
whichever bundle was active across frames 94–211 — entry 11, entry 14, or both in
|
||
turn — it declared the logos *and* the glows, while the game drew two sprites at
|
||
a time in disjoint phases.
|
||
|
||
**⇒ Only a subset of a bundle's elements is drawn at any moment, whatever the
|
||
bundle-loading story is.** The conclusion does not depend on resolving how many
|
||
bundles are involved, which is why the texture-base test's failure no longer
|
||
matters.
|
||
|
||
✅ So "a bundle is a palette, not a script" is **reinstated** — this time by
|
||
eliminating the alternative rather than by assuming it away. The route that
|
||
worked was not a better capture but asking what the competing hypothesis would
|
||
*require on the disc*, and finding it absent.
|
||
|
||
---
|
||
|
||
## ✅ The measured splash sequence — what a port has to author
|
||
|
||
Since the sequencing is not in the placement data, here is the measurement, so a
|
||
port authors from evidence rather than from taste. Frames are VdSwap counts;
|
||
**1 frame = 1/30 s** (2 units/frame × 1 unit = 1/60 s, both settled in
|
||
[Q1](../ui-keyframe-time-unit.md)). Data:
|
||
[`data/splash-phase-timeline.txt`](../data/splash-phase-timeline.txt).
|
||
|
||
| phase | frames | n | seconds | starts at |
|
||
|---|---|---|---|---|
|
||
| publisher — `palogo_sqex` | 1–90 | 90 | **3.00+** | 0.00 |
|
||
| *(gap — nothing drawn)* | 91–93 | 3 | 0.10 | 3.00 |
|
||
| developer — **both glows** | 94–115 | 22 | **0.73** | 3.10 |
|
||
| developer — **both logos** | 116–211 | 96 | **3.20** | 3.83 |
|
||
|
||
⚠️ **Three limits on these numbers.**
|
||
|
||
* The capture opens at frame 1 with `palogo_sqex` **already at `a=255`**, so the
|
||
publisher phase began before the window. **3.00 s is a floor**, and every
|
||
"starts at" is relative to the capture, not to boot.
|
||
* `palogo_anima` and `palogo_anima_eff` get **0 draws** in all 214 frames, so the
|
||
third logo pair's phase — if there is one — is not in this measurement.
|
||
* One capture, one run. The glow→logo switch is a single frame boundary with no
|
||
overlap, which is a strong shape, but the *durations* are one sample each.
|
||
|
||
✅ What is solid: the **0.73 s glow phase** and the **3.20 s logo phase** are
|
||
each within 2 % of their element's declared span, so the durations are the
|
||
bundle's own and only the sequencing is authored.
|