Closes the open half of Q3. `ui-paint-order-derived-check.md` bounded WHERE a wrong tie-break could show -- overlapping same-key pairs -- and said outright that nobody had measured how many change a pixel. At the instant the player sees, the answer is: at most 1 px at max channel difference 1, on the JAPANESE title only (`ptlogo2` x `ptlogo_tm`, 5 px of shared ink). Exactly 0 px on all five port screens. The earlier 24-pair bound was counted at `rest()`, and 10 of the title's 11 overlapping tied pairs are between `ptlogo_back2eff1`..`eff5` -- the five transient flashes from the settle-time finding, transparent on the settled screen. A tie between two invisible elements cannot cost a pixel. Not a knife-edge. Sweeping every keyframe time and every midpoint between keyframe times, the live-pair count is flat across the ENTIRE settle window: 1 on the EN title, 2 on the JP title, 0 on all four loading bundles -- whose tie is live only at t17..t33, during the build-in, which matters because their settle windows are narrow enough to deserve little trust otherwise. Controls: every entry reporting zero also swaps an overlapping DIFFERENT-key pair, which must and does move pixels (25 310 / 268 698 / ~765 000 px). Zeros are explained by shared-ink counts rather than asserted -- the `ptframe` pairs overlap by bounding box and share 0 px of ink. Entries 0/1/12/15 have NO live control and their zeros rest on keyframe data rather than a render; recorded as the weaker claim it is. Refutation attempt on the corpus's "24 overlapping pairs": it SURVIVES as a rest-pose count -- an independent recount reproduces entry 7's 16 exactly. What is overturned is its interpretation as the risk surface. `tie_break_pixel_cost` gains a settle-time case and an alpha/scale filter on its rect test; `tie_cost_over_time` is new. Also strips 611 bytes of captured cargo warnings from the head of the committed tie census. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsEPXWVaEpyfudtR6re1Pd
5.6 KiB
What the paint-order tie-break actually costs: one pixel, on one screen
Classification: decoded. Both terms come from the disc — the pairs from the keyframe table, the pixels from rendering the same bundle twice with two elements swapped. No capture is involved, and none is needed: this measures how much a wrong answer could cost, not which answer is right.
The question this closes
ui-paint-order-derived-check.md bounds
where a wrong tie-break could show — same-layer-key pairs whose rects overlap —
and says outright that nobody has measured how many of them change a pixel.
That was the last open half of Q3.
The answer
At the instant the player actually sees, the tie-break costs at most one pixel, at a maximum channel difference of 1, and only on the Japanese title. On all five port screens it is exactly zero.
| entry | screen | live tied pairs at settle | measured cost |
|---|---|---|---|
| 4 | title (EN) | 1 | 0 px — the pair is ptloop01×ptloop02, not both drawn |
| 5 | main menu | 2 | 0 px — ptframe1×ptframe2 share no ink; the other is undrawn |
| 6 | submenu | 2 | 0 px — same shape |
| 8 | submenu | 2 | 0 px — same shape |
| 9 | submenu | 2 | 0 px — same shape |
| 7 | title (JP) | 2 | 1 px, max Δ 1 — ptlogo2×ptlogo_tm, 5 px of shared ink |
| 0, 1, 12, 15 | loading | 0 | no pair is live at all |
Full run: tie-break-pixel-cost-gp_title.txt.
Why the number moved: rest() was counting elements that are not there
The census that produced the earlier bound posed every element at rest(), its
own last hold keyframe. That draws transients at their peak
(ui-settle-time.md), and the title's ties are almost
entirely between transients: ptlogo_back2eff1…eff5 are five staggered
two-frame flashes, all extinguished by t110, and they account for 10 of the
title's 11 overlapping tied pairs.
A tie between two elements that are transparent cannot cost a pixel however much their rects overlap. Posing at the settle time instead:
| entry 4 | entry 7 | entries 0/1/12/15 | |
|---|---|---|---|
overlapping tied pairs at rest() |
11 | 13 | 1 each |
| still live at the settle time | 1 | 2 | 0 |
It is not a knife-edge
The obvious objection is that "at the settle time" picks one instant, and a
different instant might give a different count. Sweeping every keyframe time and
every midpoint between keyframe times
(tie-break-live-over-time-gp_title.txt):
| entry | peak live pairs over the whole timeline | max anywhere in the settle window |
|---|---|---|
| 4 | 6 | 1 |
| 7 | 6 | 2 |
| 5 / 6 / 8 / 9 | 2 | 2 |
| 0 / 1 / 12 / 15 | 1 | 0 |
The count is flat across the entire window, not just at its midpoint. The four loading bundles are the sharpest case: their tie is live only at t17–t33 — during the build-in — and dead everywhere else, which matters because their settle windows are narrow (4 and 8 units) and would otherwise deserve little trust.
Controls
- ✅ A live control on every entry that reports a zero. Each run also swaps an overlapping pair with different keys — an order the game demonstrably does care about — and requires it to move pixels. It moves 25 310 px on the title, 268 698 px on the JP title, and ~765 000 px on the four menu screens.
- ⚠️ Entries 0, 1, 12, 15 have no live control ("no overlapping different-key pair is drawn"). Their zeros rest on the keyframe data — no tied pair has both elements opaque at any instant in the window — not on a render, so a dead control does not undermine them. But nothing here demonstrates the renderer would notice a swap on those bundles.
- ✅ Shared-ink accounting. A zero is only meaningful with an explanation. The
ptframepairs overlap by bounding box and share 0 px of actual ink; the JP title's 1 px comes from 5 px of shared ink betweenptlogo2andptlogo_tm.
🟡 Refutation attempt: the corpus's "24 overlapping pairs" — it survives
Recounted independently. Without the alpha/scale filter this document adds, the
per-entry counts are e0:1 e1:1 e4:13 e5:2 e6:2 e7:16 e8:2 e9:2 e12:1 e15:1,
total 41 — and entry 7's 16 reproduces the corpus's figure exactly. The 24 is
that population scoped to the entries without a measured order. Adding the filter
takes the total to 36.
So the count stands as a rest-pose upper bound. What this document overturns is its interpretation: 24 was being read as the surface on which a wrong tie-break could show, and at the instant the player sees, that surface is one pixel.
Reach and what is still open
❔ Why the game orders ties as it does is still unknown, and this does not
touch it — eight candidate rules remain refuted in
ui-paint-order-derived-check.md. What changes
is that the question is no longer worth much: getting it wrong costs one pixel on
a screen the port does not ship.
⚠️ GP_TITLE only. Other paks were not swept. The method is bundle-agnostic
but the numbers are not.
⚠️ Rect overlap is still an approximation (pivot doubled, placed at the pose). It is used only to choose candidate pairs; every reported cost is a real render diff, so the approximation can add candidates but cannot invent a cost.
Reproducing
cargo run -p sylpheed-formats --example tie_break_pixel_cost -- "$SYLPHEED_DISC/dat/GP_TITLE.pak"
cargo run -p sylpheed-formats --example tie_cost_over_time -- "$SYLPHEED_DISC/dat/GP_TITLE.pak"