formats: a third measured paint order — the main menu, with two primitives

Read off the running game with screen_children.py and identified by pivot
signature as GP_TITLE.pak ratc-index 8, the NEW GAME / LOAD GAME / TUTORIAL /
OPTIONS / EXTRAS screen:

  paint order: 1 3 4 2 5 8 9 6 7 15 10 11 12 13 14 0

It is the first measured screen carrying TWO primitives, and they land in
different places, which is the point. pteff02.prm (the 25% dim) paints 4th,
beneath the whole UI; pteff00.prm (the transition fade, resting transparent)
paints last. Both match their positions on the title screen exactly. So a
primitive's place is per-element and stable by role - backdrop first, dim at
slot 4, fade last - and there are now three permutations to test a derivation
against rather than two.

Wired into measured_paint_order, keyed by element names so both language builds
get it. The English build composited with --primitives edge-correlates at 0.9591
at shift (0,0) against a framebuffer capture taken in the same session - a third
screen confirming paint order, resting pose, fade alpha and primitives at once,
against a capture this project had not seen before.

13 disc tests green.
This commit is contained in:
Sylpheed RE agent
2026-08-19 08:56:21 +00:00
parent 20b0edc2c2
commit 23565ec5ec
4 changed files with 75 additions and 0 deletions

View File

@@ -728,6 +728,22 @@ fn measured_paint_order(build: &UiBuild) -> Option<Vec<usize>> {
// the full-screen .prm, then all three glows, then the three logos.
return Some(vec![0, 2, 4, 6, 1, 3, 5]);
}
// GP_TITLE.pak ratc-index 8 — the MAIN MENU (NEW GAME / LOAD GAME /
// TUTORIAL / OPTIONS / EXTRAS). Read off the running game 2026-08-19; it is
// the third measured permutation and the first that contains TWO
// primitives, which is why it matters — see `ui-prm-primitives.md`.
const MENU: [&str; 16] = [
"pteff00.prm", "ptbase.t32", "pteff05.t32", "ptloop01.rat",
"ptloop02.rat", "pteff02.prm", "ptframe1.t32", "ptframe2.t32",
"pteff10.t32", "pteff12.t32", "ptbtn01.rat", "ptbtn02.rat",
"ptbtn03.rat", "ptbtn04.rat", "ptbtn05.rat", "ptmsg.t32",
];
if names == MENU {
// background, the two loops, the full-screen effect, the DIM quad,
// the glows, the frames, the message, the five buttons, and the
// screen-transition FADE quad last.
return Some(vec![1, 3, 4, 2, 5, 8, 9, 6, 7, 15, 10, 11, 12, 13, 14, 0]);
}
None
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 649 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 KiB

View File

@@ -133,3 +133,62 @@ measured screens would be the entire evidence base; instead a third of the disc'
screens now composite in an order no capture has checked. The test asserts the
share stays above a quarter, so a future change that quietly collapses the rule
back to declaration order fails here instead of passing silently.
## A third measured permutation — the main menu (2026-08-19)
Read off the running game with `tools/re-capture/screen_children.py`, and
identified in the file by its pivot signature: **`GP_TITLE.pak` ratc-index 8**,
the NEW GAME / LOAD GAME / TUTORIAL / OPTIONS / EXTRAS screen, 16 elements.
```
paint order (child slots): 1 3 4 2 5 8 9 6 7 15 10 11 12 13 14 0
```
| slot | element | | slot | element |
|---|---|---|---|---|
| 0 | 1 `ptbase.t32` | | 8 | 7 `ptframe2` |
| 1 | 3 `ptloop01` | | 9 | 15 `ptmsg` |
| 2 | 4 `ptloop02` | | 1014 | 1014 `ptbtn01``ptbtn05` |
| 3 | 2 `pteff05` | | 15 | **0 `pteff00.prm`** |
| 4 | **5 `pteff02.prm`** | | | |
| 57 | 8 `pteff10`, 9 `pteff12`, 6 `ptframe1` | | | |
**This is the first measured screen with TWO primitives**, and they land in
different places — which is the point. `pteff02.prm` (the 25 % black dim) paints
4th, beneath the whole UI; `pteff00.prm` (the screen-transition fade, resting
transparent) paints **last**. Both match their positions on the title screen
exactly, where `pteff02.prm` is also slot 4 and `pteff00.prm` is also last.
So a primitive's place is **per-element and stable by role** across screens:
| primitive | role | measured position |
|---|---|---|
| `palogo_eff0.prm` | opaque black backdrop | **first** (splash) |
| `pteff02.prm` | 25 % dim under the UI | **slot 4** (title *and* menu) |
| `pteff00.prm` | screen-transition fade | **last** (title *and* menu) |
It is still not *derived* — a primitive has no `T8aD` header and so no layer key
— but there are now three permutations to test a candidate against instead of
two, and the candidate has to live in the 60-byte declaration entry.
### Verified against the live capture
The order is wired into `measured_paint_order` (keyed by element names, so both
language builds get it). Composited with `--primitives` and edge-correlated
against a framebuffer capture taken in the same session
([capture](../captures/main-menu-oracle.png),
[composite](../captures/ui-layout/main-menu-composited.png)):
> **0.9591 at shift (0, 0)**
That is a *third* screen confirming the whole stack at once — paint order,
resting pose, `fade` alpha and primitives — on a capture this project had not
seen before.
### Not settled
*`ptframe1`/`ptframe2` rest at `0x00ffffff` (alpha 0) and are therefore not
drawn, but the capture shows the menu frame plainly. Either the resting rule
picks the wrong plateau for them or the frame is drawn by something else.
* ❔ The derivation for primitives. Three permutations now, still no rule.