formats: check the derived paint order against the screens already verified

The layer-key order was adopted from two measured screens and then applied to
every build on the disc, so it owed a regression check against the screens the
corpus had already validated against the running game.

Rendered the tutorial PAUSE menu and the title main menu both ways and diffed:
3.8 % and 1.1 % of pixels differ, max delta 45/255 and 34/255, and the two
renders are indistinguishable in layout — the change is confined to blends where
translucent sprites overlap. No regression, but which order is more faithful on
those two screens is unsettled and recorded as such.

Adds a corpus-wide test asserting every composite's draw list is strictly
increasing in (layer key, declaration index), streaming one pak at a time so it
does not OOM alongside the other whole-disc tests. It reports the rule's reach:
341 of 965 builds are reordered, and it fails if that share collapses.
This commit is contained in:
Sylpheed RE agent
2026-08-19 05:43:08 +00:00
parent d9ae42dd55
commit deff5a4d6d
3 changed files with 143 additions and 4 deletions

View File

@@ -88,3 +88,48 @@ has no `.rat` child, so `ui_layout::is_build` rejects it and the compositor neve
sees it. Its measured order is therefore inert in practice, and the splash cannot
be rendered by `screen render` at all. That is a separate gap in what counts as a
"build", not a paint-order question.
## What the change did to the screens that were already verified (2026-08-19)
The derived order is applied to **every** build on the disc on the strength of
two measured screens, so the first thing owed to it is a check of what it did to
the screens the corpus had already validated against the running game. Two exist:
the tutorial PAUSE menu and the title main menu
(`../captures/ui-layout/pause-tutorial-real-vs-rebuilt.png`).
Rendered both ways — `compose` as committed, then with `compose` temporarily
reverted to declaration order — and diffed:
| screen | pixels differing | RMSE | max per-channel delta |
|---|---|---|---|
| tutorial PAUSE | 35 162 / 921 600 (3.8 %) | 0.52 % | 45 / 255 |
| title main menu | 9 911 / 921 600 (1.1 %) | 0.36 % | 34 / 255 |
**No layout regression.** Side by side the two renders are indistinguishable:
every panel, label and glyph is in the same place at the same size. What moved is
confined to pixels where translucent sprites overlap — the glows around PAUSE,
the OBJECTIVE / DEFEAT CONDITION / HINT header bars, the menu underlines — i.e.
the order the blends compose in, which is exactly what a paint-order change is
supposed to touch and nothing else.
🟡 **Which of the two is more faithful on these two screens is NOT settled.** A
difference of ≤45/255 on a few per cent of pixels is not decidable against the
committed side-by-side oracle, and there is no fresh framebuffer capture of
either screen to diff at that magnitude. The derived order is kept because it is
the rule measured off the game on the two screens where the order *is* known, not
because it was shown to be better here. If a capture of the PAUSE menu is ever
taken, this is the first thing to check it against.
### Corpus-wide, and not a no-op
A disc-gated test (`every_composite_paints_in_layer_key_order`) composes every
build on the disc and asserts the draw list is strictly increasing in
`(layer key, declaration index)`. It also counts how far the rule reaches:
> **341 of 965 builds (35 %) are reordered** by it.
That matters for how much credit the rule gets. Had it been a near-no-op, the two
measured screens would be the entire evidence base; instead a third of the disc's
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.