re: the forced-backdrop span -- 256 vs 211 is a bundle mismatch, and the hold

decides 55% of verdicts

The port implemented the forced-backdrop rule and reported a discrepancy:
palogo_eff0.prm at 256 opaque instants against this corpus's 211.

There is no discrepancy. palogo_eff0.prm appears on BOTH splashes -- the
publisher (entries 10, 13) runs to t=255, giving 256 instants; the developer
(11, 14) runs to t=210, giving 211. Same definition, different bundle. The page
now names the entries so it cannot recur.

The definition, stated: the span is 0..=max keyframe time over every element in
the build, and an element HOLDS its final pose past its own last keyframe --
which is what pose_at does, and which is decoded rather than assumed (a group
holds at its last keyframe rather than looping; the declared +0x08 never falls
short of the last keyframe, the slack being that hold).

The port's instinct that the hold was load-bearing was right. Over the 130
keyless full-screen primitives with an opaque interval:

  * span = the header's declared +0x08          ->  0 verdicts change
  * span = the primitive's own last keyframe    -> 72 change
  * elements GONE after their last keyframe     -> 72 change

So the hold decides 55% of verdicts -- and dropping it is REFUTED by a measured
order. palogo_eff0.prm is a single keyframe at t=0: without the hold it is
opaque for one instant, no other element is up yet, and the rule calls it free,
against a game measured painting it first. Pinned by a new test that spells out
the counterfactual rather than importing it.

The verdicts that matter are convention-independent: pgloading_eff00.prm is
FIRST under all four conventions and pteff00.prm FREE under all four. And the
header length is interchangeable with the elements' maximum -- zero
disagreements disc-wide.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsEPXWVaEpyfudtR6re1Pd
This commit is contained in:
sylph-decoder
2026-08-29 21:14:58 +00:00
parent cfcda5501c
commit cf91ad1dcc
5 changed files with 221 additions and 1 deletions

View File

@@ -37,7 +37,8 @@ instances.
| primitive | measured in the game | opaque instants | forced below | rule says |
|---|---|---|---|---|
| `palogo_eff0.prm` | **paints FIRST** | 211 | **6 of 6** | ✅ forced first |
| `palogo_eff0.prm` (entry 11, developer) | **paints FIRST** | 211 | **6 of 6** | ✅ forced first |
| `palogo_eff0.prm` (entry 10/13, publisher) | **paints FIRST** | 256 | 2 of 2 | ✅ forced first |
| `pteff00.prm` (title) | **paints LAST** | 2 | 3 of 23 | ✅ permitted on top |
| `pteff00.prm` (menu) | **paints LAST** | 2 | 7 of 15 | ✅ permitted on top |
@@ -47,6 +48,50 @@ order. Occlusion gets it right. `pteff00.prm` is opaque only for two instants, a
its screen's entry and exit, so the constraint never binds it: it is the fade
cover, and it belongs on top.
## The span, and what it costs to get wrong
The rule quantifies over "every instant the primitive is opaque" and "every
element visible then", so it depends on where a screen's timeline ends and on what
an element does after its own last keyframe. The port asked, having got **256**
opaque instants for `palogo_eff0.prm` where this page said 211.
⚠️ **That pair was a bundle mismatch, not a definitional one**`palogo_eff0.prm`
appears on both splashes, and the publisher (entries 10, 13) runs to t=255 while
the developer (11, 14) runs to t=210. 256 and 211 are both right, for their own
screen. The definitions already agreed.
**The definition:** the span is `0 ..= max keyframe time over every element in the
build`, and an element **holds its final pose** past its own last keyframe — which
is what `pose_at` does, and it is decoded rather than assumed: a group holds at its
last keyframe rather than looping
([`ui-keyframe-time-unit.md`](../ui-keyframe-time-unit.md)), and
[`ui-record-loop-length.md`](ui-record-loop-length.md) shows the declared length
never falls short of the last keyframe, the slack being exactly that hold.
**How much rests on it — 130 keyless full-screen primitives with an opaque
interval, and how many verdicts change:**
| alternative convention | verdicts changed |
|---|---|
| span = the bundle header's declared `+0x08` | **0** |
| span = the primitive's **own** last keyframe | 72 |
| elements counted **gone** after their last keyframe (no hold) | **72** |
🔴 **The hold decides 55 % of the verdicts, and dropping it is refuted by a
measured order.** `palogo_eff0.prm` is a *single* keyframe at t=0. Without the
hold it would be opaque for one instant, no other element would be up yet, and the
rule would call it **free** — against the order measured in the running game,
which paints it first. Pinned by
`the_hold_after_a_final_keyframe_is_required_by_a_measured_order`.
**And the header length is interchangeable with the elements' maximum**: zero
disagreements disc-wide. Either may be used.
**The verdicts that matter are convention-independent.**
`pgloading_eff00.prm` comes out **first** under all four conventions;
`pteff00.prm` comes out **free** under all four. Only `palogo_eff0.prm` moves, and
only under the convention its own measured order rules out.
## Disc-wide
Keyless **full-screen** primitives with an opaque interval: