handoff: say which index space a build number is in -- 10/11 meant two different screens
The port challenged HANDOFF's loading-screen row and was right. The Q2 row said "0/1 and 10/11 are the LOADING screen"; the dated section above it says "entries 0, 1, 12, 15". Both are true, in different index spaces, and the page did not say which. Verified against the bytes rather than the table: screen list GP_TITLE.pak -> 12 builds, ordinals 0..11 screen list --all GP_TITLE.pak -> 16 builds, ordinals 0..15 Only under --all does the ordinal equal the pak entry. Without it ordinal 10 is entry 12 and ordinal 11 is entry 15. `screen info --all --build 10` shows palogo_sqex; --build 11 shows palogo_gamearts / seta / anima; 12 and 15 show pgloading_*. So in ENTRY space 10/11 are the publisher and developer splashes, which is exactly the screen the wrong reading would have renamed. It would have validated silently: the port's screen_names.json is keyed by entry. Q2 row corrected to entry space and marked; the trap is in METHOD under "Mechanics that have bitten", with the rule that a number leaving this repository says "entry N", never "build N". Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsEPXWVaEpyfudtR6re1Pd
This commit is contained in:
@@ -306,13 +306,48 @@ items MISSION parks as emulator-blocked.
|
||||
at **7.97 / 7.98 fps against a requested 8**, so there was no backlog to
|
||||
destroy them.
|
||||
|
||||
## ✅ 2026-08-29 — the paint-order tie-break costs your screens ZERO pixels (Q3 closed for you)
|
||||
|
||||
You challenged the advertised blast radius of the unknown tie-break and were
|
||||
right; the census that came back said **24 overlapping tied pairs** and admitted
|
||||
nobody had measured how many of them *change a pixel*. Measured now.
|
||||
|
||||
**Overlap was an upper bound and it was loose.** Each bundle was rendered twice,
|
||||
once in the derived order and once with one tied pair swapped, and diffed —
|
||||
elements sharing a layer key are contiguous in the derived order, so a swap
|
||||
paints nothing else in between. Every entry ran a **control** first: a swap of an
|
||||
overlapping pair with *different* keys, which must move pixels (it moved 36 305
|
||||
to 771 479 px, max Δ 254). Where no control was available the page says so.
|
||||
|
||||
* ✅ **On `EXTRAS` (entries 6/9) and the main menu (5/8): 0 px.** The tied
|
||||
`ptframe` pairs each ink ~3 600 px and **share 0**. The bounding-box overlap
|
||||
was an artefact of approximating an element's rect as pivot × 2. Layers that
|
||||
never touch the same pixel cannot be mis-ordered under *any* blend, so this
|
||||
does not depend on our compositor being right.
|
||||
* ✅ **The splashes have no ties; the title and developer splash use a measured
|
||||
order.** So across all five screens the tie-break's cost is **zero**, not "one
|
||||
drawable pair, consistent with a capture".
|
||||
* 🔴 **A claim of ours is withdrawn.** This page's source said a wrong tie-break
|
||||
"can be wrong by a whole layer", from the geometry that `ptlogo_back2eff5`
|
||||
*fully contains* two other glows. Rendered, that swap moves 6 390 px by a
|
||||
maximum of **Δ2 out of 255**. The glows are near-transparent; containment is
|
||||
not occlusion. Nobody had rendered it before asserting it.
|
||||
* 🟡 **Outside your set**, the worst tie-break cost anywhere in `GP_TITLE` is
|
||||
**Δ3/255** (the Japanese title, entry 7). ⚠️ Those Δ figures *do* assume our
|
||||
alpha blend — what they rule out is a structural error, a layer appearing or
|
||||
vanishing, not a shading one.
|
||||
|
||||
[`ui-paint-order-derived-check.md`](../re/structures/ui-paint-order-derived-check.md#-what-the-tie-break-actually-costs-in-pixels-2026-08-29) ·
|
||||
[data](../re/data/paint-order-tie-pixel-cost.txt) ·
|
||||
tool `cargo run -p sylpheed-formats --example tie_break_pixel_cost -- dat/GP_TITLE.pak`
|
||||
|
||||
## Status
|
||||
|
||||
| | Question | State | Answer / link |
|
||||
|---|---|---|---|
|
||||
| Q1 | keyframe time unit + ramp shape | ✅ answered | ramp is **linear**; **2 units per rendered frame**; **`1 unit = 1/60 s` — measured**, the idle title presents at 28.5 fps so the game is 30 Hz — [`ui-keyframe-time-unit.md`](../re/ui-keyframe-time-unit.md). ✅ **The group timeline is now DECODED too (2026-08-29) and the gap is closed**: a placement group is `frames` records of `{u32 time; 36-byte pose}` after an 8-byte header, so a pose's time is the word **before** it, pose 0's time is the group's lead-in word, and **every** pose is timed — including the last, which nothing could time before. Disc-wide over 13 991 groups with controls; the old reading makes **0 of 1 042** multi-segment alpha ramps constant-rate against 857 of 1 540. `SYLPHEED_KF_TIME_SHIFT` is retired (it had the association right but left pose 0 untimed, which is the whole reason it appeared to cost 13.1 % of build 7). Static renders are byte-identical — [`ui-keyframe-record-layout.md`](../re/ui-keyframe-record-layout.md) |
|
||||
| Q2 | which build is which screen state | ✅ answered | `GP_TITLE` is **8 screens shipped twice, EN/JP**: 4/7 title art, 2/3 the `PRESS Ⓐ` plate, 5/8 main menu, 6/9 `EXTRAS`, and ✅ **0/1 and 10/11 are the LOADING screen** — two variants, plain and dressed, decoded from their `pgloading_*` element names (2026-08-29). 🟡 which of the two is `LOADING` vs `LOADING2` is undecided; 🟡 the English member of a pair is the one in the first half of the data segment — [`ui-title-build-map.md`](../re/ui-title-build-map.md) |
|
||||
| Q3 | paint order for the six screens | ✅ answered, ❔ tie-break | **decoded**: a `u16` layer key at `+0x0A` of each `T8aD` sprite header, stable-sorted with declaration index; unkeyed elements get an implied key. Confirmed on 5 measured orders + `EXTRAS` vs a capture. One residual: the **tie-break** is unknown and bites on one element of the title — [`structures/ui-paint-order-key.md`](../re/structures/ui-paint-order-key.md). ⚠️ **The key does not fully order a screen**: elements sharing a key are tied, and the tie-break is ❔ **undecodable from the bundle** — declaration table, `T8aD` header (exhaustive: every offset 0x00–0x7f at u8/u16/u32, both directions, **0** fields match the measured order against **64** for the control) and the RATC child order all give the same order the game does *not* use. Your exposure is **2 overlapping tied pairs on `EXTRAS`** — [`structures/ui-paint-order-derived-check.md`](../re/structures/ui-paint-order-derived-check.md) |
|
||||
| Q2 | which build is which screen state | ✅ answered | `GP_TITLE` is **8 screens shipped twice, EN/JP**: 4/7 title art, 2/3 the `PRESS Ⓐ` plate, 5/8 main menu, 6/9 `EXTRAS`, and ✅ **pak entries 0/1 and 12/15 are the LOADING screen** — two variants, plain and dressed, decoded from their `pgloading_*` element names (2026-08-29). ⚠️ **Read that in ENTRY space.** This row said "0/1 and 10/11" until 2026-08-29; that is true only of `screen list`'s ordinals, where 10→entry 12 and 11→entry 15. In entry space 10/11 are the **publisher and developer splashes** (`palogo_sqex`, `palogo_gamearts`). The port caught it; see [METHOD](../re/METHOD.md#mechanics-that-have-bitten). 🟡 which of the two is `LOADING` vs `LOADING2` is undecided; 🟡 the English member of a pair is the one in the first half of the data segment — [`ui-title-build-map.md`](../re/ui-title-build-map.md) |
|
||||
| Q3 | paint order for the six screens | ✅ answered, ❔ tie-break | **decoded**: a `u16` layer key at `+0x0A` of each `T8aD` sprite header, stable-sorted with declaration index; unkeyed elements get an implied key. Confirmed on 5 measured orders + `EXTRAS` vs a capture. One residual: the **tie-break** is unknown and bites on one element of the title — [`structures/ui-paint-order-key.md`](../re/structures/ui-paint-order-key.md). ⚠️ **The key does not fully order a screen**: elements sharing a key are tied, and the tie-break is ❔ **undecodable from the bundle** — declaration table, `T8aD` header (exhaustive: every offset 0x00–0x7f at u8/u16/u32, both directions, **0** fields match the measured order against **64** for the control) and the RATC child order all give the same order the game does *not* use. ✅ **Your exposure is now measured at ZERO PIXELS (2026-08-29).** The 2 overlapping tied pairs on `EXTRAS` are `ptframe3`×`ptframe4` (the other is a `loop*` you never draw), and rendering the screen with that pair swapped changes **0 px** — because the two sprites put ink on ~3 600 pixels each and **share none of them**; the 102×132 "overlap" was a bounding-box artefact. Same on the main menu's `ptframe1`×`ptframe2`. This is blend-independent: layers that never touch the same pixel cannot be ordered wrongly. **Nothing about the tie-break can change a pixel on any of your five screens** — [`structures/ui-paint-order-derived-check.md`](../re/structures/ui-paint-order-derived-check.md) |
|
||||
| Q4 | button → GamePart | ✅ answered | **measured** which screen all **5** buttons open — `NEW GAME` → `DIFFICULTY` → `SELECT DATA`, not a hang. The **GamePart id is still a name match**, not a measurement — [`menu-navigation-semantics.md`](../re/menu-navigation-semantics.md) |
|
||||
| Q5 | navigation semantics | ✅ answered | **measured**: initial focus varies boot to boot (2× `TUTORIAL`, 2× `NEW GAME`); ⬆⬇ one step, **wraps both ends**; ⬅➡ do nothing; Ⓑ returns to the parent **with focus restored**; Ⓑ on the main menu → title; Ⓑ on the title → nothing — [`menu-navigation-semantics.md`](../re/menu-navigation-semantics.md) |
|
||||
| Q6 | boot sequence + what drives it | ✅ answered | sequence **measured** end to end; the driver is **code, not data** — four search spaces closed, so the port **authors** the sequence — [`boot-config-and-gamepart-registry.md`](../re/boot-config-and-gamepart-registry.md) |
|
||||
@@ -1180,7 +1215,7 @@ here until 2026-08-28 and is now settled.)
|
||||
|---|---|---|
|
||||
| 🟡 | **cue NAME → event binding** (Q8) | event→**wave** is measured for move/confirm/back; that the cursor's wave is the cue *named* `SE_UI_CURSOR` is still read off the authors' identifiers |
|
||||
| ❔ | **the other ~319 SE cues** (Q8) | located one at a time by triggering them; only the three the menu needs have been done |
|
||||
| 🟡 | **the paint-order tie-break** (Q3) | eight candidates refuted. 🔴 **The cost was understated and is corrected 2026-08-29** — the port challenged it and was right. Over all 16 `GP_TITLE` entries: 5 use a **measured** order and carry no tie risk; the other 11 fall back to the derived order and **7 of them have overlapping ties, 24 pairs in total** — 16 of those on the **Japanese title** (entry 7) alone, 2 each on `EXTRAS` EN/JP, 1 each on the four loading bundles. ⚠️ Overlap bounds *where* a wrong tie-break could show; nobody has measured how many actually change a pixel — [`ui-paint-order-derived-check.md`](../re/structures/ui-paint-order-derived-check.md) · [census](../re/data/paint-order-ties-gp_title.txt) |
|
||||
| ✅→🟡 | **the paint-order tie-break** (Q3) | ✅ **Its COST is now measured and it is zero on all five port screens** (2026-08-29) — the tied `ptframe` pairs share no ink, and the worst tie-break effect anywhere in `GP_TITLE` is Δ3/255. What stays open is only *why* the game orders ties as it does. Eight candidates refuted. 🔴 **The cost was understated and is corrected 2026-08-29** — the port challenged it and was right. Over all 16 `GP_TITLE` entries: 5 use a **measured** order and carry no tie risk; the other 11 fall back to the derived order and **7 of them have overlapping ties, 24 pairs in total** — 16 of those on the **Japanese title** (entry 7) alone, 2 each on `EXTRAS` EN/JP, 1 each on the four loading bundles. ⚠️ Overlap bounds *where* a wrong tie-break could show; nobody has measured how many actually change a pixel — [`ui-paint-order-derived-check.md`](../re/structures/ui-paint-order-derived-check.md) · [census](../re/data/paint-order-ties-gp_title.txt) |
|
||||
| 🟡 | **GamePart ids behind the buttons** (Q4) | the *screens* are measured; the ids are a name match onto the executable's class names |
|
||||
| 🟡 | **the boot transitions in code** (Q6) | both levels decoded — phase at `this+132` (`entry→2`, `2→0`, `2→3`, `3→4`, `4→2`) and state at `this+136` inside phase 4. Phase 0 = splash (`LOGO`), phase 2 = title + `PRESS Ⓐ`, phase 4 = menu. Unknown: what the event *numbers* mean |
|
||||
| 🟡 | **Ⓑ leaving the main menu** (Q5) | **upgraded 2026-08-29 (later).** The idle half of this objection is **refuted**: the main menu does not self-return for **≥ 60 s** untouched, and the ~8–10 s idle belongs to the **title**. Ⓑ is delivered (Canary logs `vk=5801`) and is the only input in ≥ 100 s before the return, so the **ordering is measured**; the latency is not (a backlogged probe void). The footer point stands — the main menu is still the only screen not advertising Ⓑ — [`menu-navigation-semantics.md`](../re/menu-navigation-semantics.md#-refutation-attempt-2026-08-29--the-main-menus-own-footer-does-not-advertise-ⓑ) |
|
||||
|
||||
@@ -89,6 +89,18 @@ agent's loop prompt, i.e. nowhere durable. See [`README.md`](README.md) for the
|
||||
* **Raw grep cannot see inside compressed pak entries.**
|
||||
* **Commit messages go in a file** (`git commit -F`); a literal `|` in a table
|
||||
cell needs escaping; `git log --all -- <path>` can hang.
|
||||
* **"Build 10" of a pak is ambiguous — always say which index space.**
|
||||
`sylpheed-cli screen list GP_TITLE.pak` reports **12** builds and numbers them
|
||||
0–11; `screen list --all` reports **16** and numbers them 0–15. Only under
|
||||
`--all` does the ordinal equal the pak entry. Without it, ordinal 10 is pak
|
||||
entry **12** and ordinal 11 is entry **15** — so "builds 10/11 are the loading
|
||||
screen" and "entries 12/15 are the loading screen" are the same true statement,
|
||||
while "**entries** 10/11 are the loading screen" is false: those are the
|
||||
publisher (`palogo_sqex`) and developer (`palogo_gamearts`/`seta`/`anima`)
|
||||
splashes. This cost a wrong line in HANDOFF that the port caught, and it would
|
||||
have validated silently because the port's `screen_names.json` is keyed by
|
||||
entry. **Write `entry N`, not `build N`, whenever the number leaves this
|
||||
repository.**
|
||||
|
||||
## Runtime / emulator
|
||||
|
||||
|
||||
Reference in New Issue
Block a user