The activation decision is code, and MISSION already says the port authors the sequence -- so the useful move is to hand over the sequence measured rather than chase the code. From the 235-frame draw capture, at 1 frame = 1/30 s (2 units/frame, 1 unit = 1/60 s, both settled in Q1): publisher: SQUARE ENIX logo f1-90 90 frames 3.00 s+ at 0.00 (gap, nothing drawn) f91-93 3 frames 0.10 s at 3.00 developer: both glows f94-115 22 frames 0.73 s at 3.10 developer: both logos f116-211 96 frames 3.20 s at 3.83 Three limits, stated with the numbers rather than after them. The capture opens with palogo_sqex already at a=255, so the publisher phase began before the window and 3.00 s is a FLOOR -- 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 a third pair's phase is not in this measurement. And it is one capture, one run: the glow->logo switch being a single frame boundary with no overlap is a strong shape, but each duration is one sample. What is solid is the part that matters: the 0.73 s and 3.20 s phases are each within 2% of their element's declared span, so the durations are the bundle's own and only the ordering is authored. That is the difference between a port transcribing timing and inventing it.
213 lines
9.7 KiB
Markdown
213 lines
9.7 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 %.**
|
||
|
||
## 🔴 But they do not share a clock origin
|
||
|
||
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.
|
||
|
||
**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.
|