Looked in four places. The bundle has no field: a primitive has no RATC child at all and the declaration words are constant across every element of three measured screens -- the two grounds ui-prm-primitives.md already used to refute a bundle-side LAYER key, and they apply identically to blend. The colour census: every full-screen *eff00* primitive on the disc carries pure black at its various alphas, and the only non-black primitive anywhere is pbafc.prm, RGB 00e8e0 cyan. The occlusion constraint cannot reach that one. pbafc.prm looked alarming at a declared 844x600 and alpha ff; it is a small moving glint. It strobes between alpha 255 and 124 every 2 units, travels from x=178 to x=291, and is scaled 2%x3%, so it draws about 17x18 pixels. At that size it occludes essentially nothing. The oracle is unavailable: GP_READY_ROOM is a recorded no-go and gameplay needs the A press that faults the guest in this container. But the consequence closes even though the question does not. For a BLACK quad -- which is every primitive forced_backdrop touches -- the hypotheses differ only in whether it hides what is beneath. Drawn first it is correct under both; drawn last it is correct only under additive. So the rule's verdict is robust to the open question, and the port's original "layerless sorts last" was wrong under alpha-over and merely pointless under additive. This is explicitly NOT evidence for alpha-over. The investigation also found forced_backdrop judging coverage from the pivot alone, ignoring scale -- pbafc.prm is the disc's own proof that a nominally 844x600 element can draw at 2%. Checked before changing anything: all 80 forced instances are at scale 100% on every opaque instant, so no verdict moved. The guard now requires scale >= 100 at the instants it counts as opaque. Defensive, not a fix. 4 + 13 disc tests green either side. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsEPXWVaEpyfudtR6re1Pd
86 lines
4.2 KiB
Markdown
86 lines
4.2 KiB
Markdown
# Primitive blend mode — narrowed to one element, and it does not matter
|
||
|
||
**Classification: undecodable, with reach.** Looked in the bundle, in the colour
|
||
census, in the occlusion constraint, and at the oracle. The question survives; its
|
||
*consequences* do not.
|
||
|
||
## The question
|
||
|
||
[`ui-prm-primitives.md`](ui-prm-primitives.md) leaves blend mode open: "a dim quad
|
||
at `0x7f000000` is presumably straight alpha over what is beneath, but the flash
|
||
(`0xf0ffffff`) and the coloured ones (`0x60ff0000`) may well be additive. Nothing
|
||
measured." [`ui-forced-backdrop.md`](ui-forced-backdrop.md) then assumed
|
||
alpha-over, so the assumption became load-bearing.
|
||
|
||
## Where I looked
|
||
|
||
**1. The bundle — nothing.** `ui-prm-primitives.md` already refuted a bundle-side
|
||
key for a primitive's *layer*, on two grounds that apply identically to blend: the
|
||
declaration entry's unread words are constant across every element of three
|
||
measured screens, and the bundle carries **no RATC child at all** for a primitive.
|
||
There is no field to read.
|
||
|
||
**2. The colour census — the population is overwhelmingly black.** Every
|
||
full-screen `*eff00*` primitive on the disc carries **pure black** at its various
|
||
alphas: `ff000000`, `7f000000`, `40000000`, `b2000000`, `cc000000`, `d4000000`,
|
||
`00000000`. The `*base*` elements are `ffffffff`. **The only non-black primitive on
|
||
the disc is `pbafc.prm`**, RGB `00e8e0` — cyan.
|
||
|
||
**3. The occlusion constraint — inapplicable to the one candidate.** `pbafc.prm`
|
||
looked alarming at a declared 844×600 and alpha `ff`. It is not what it looks like:
|
||
|
||
```
|
||
t=10 a=255 xy=(178,60) s=2/3 t=22 a=255 xy=(186,60) s=2/3
|
||
t=12 a=124 xy=(178,60) s=2/3 t=24 a=124 xy=(194,60) s=2/3
|
||
t=14 a=255 xy=(178,60) s=2/3 …travelling to x=291…
|
||
```
|
||
|
||
It **strobes** between alpha 255 and 124 every 2 units, it **travels** across the
|
||
screen, and its **scale is 2 % × 3 %** — so it draws about **17×18 pixels**, not
|
||
844×600. It is a small moving glint. At that size it occludes essentially nothing,
|
||
so the constraint that settles the backdrops cannot reach it.
|
||
|
||
**4. The oracle — not reachable.** `pbafc.prm` lives in `GP_READY_ROOM`, which
|
||
[`ready-room-probe.md`](../ready-room-probe.md) recorded as a no-go, and reaching
|
||
gameplay needs button input, which
|
||
[`ui-clock-freezes-at-settle.md`](ui-clock-freezes-at-settle.md) records as
|
||
faulting the guest in this container.
|
||
|
||
## ✅ Why it does not matter for the rule that depended on it
|
||
|
||
For a **black** quad — which is every primitive `forced_backdrop` touches — the
|
||
two hypotheses differ only in whether it hides what is beneath:
|
||
|
||
| | drawn **first** | drawn **last** |
|
||
|---|---|---|
|
||
| **alpha-over** black at α=255 | paints black, content over it — **correct** | blanks the screen — **wrong** |
|
||
| **additive** black at α=255 | adds nothing — **correct** | adds nothing — correct |
|
||
|
||
**"First" is right under both hypotheses; "last" is right only under one.** So the
|
||
forced-backdrop rule's *verdict* is robust to the blend question even though the
|
||
question is open — and the port's original "layerless sorts last", which produced
|
||
solid black on `build_12`/`build_15`, is wrong under alpha-over and merely
|
||
pointless under additive.
|
||
|
||
⚠️ **This is not evidence that the blend is alpha-over.** It is the reason the
|
||
open question stops being a risk. `pbafc.prm` remains genuinely unknown, and it is
|
||
the only element on the disc where the answer could change a pixel.
|
||
|
||
## 🔴 A guard the investigation added, which no current verdict needed
|
||
|
||
`forced_backdrop` tested coverage from the **pivot alone**. `pbafc.prm` is the
|
||
disc's own proof that scale can shrink a nominally full-screen element to 2 %.
|
||
|
||
Checked before changing anything: **all 80 forced instances are at scale 100 % on
|
||
every opaque instant**, so no verdict moved. The guard now requires
|
||
`scale_x >= 100 && scale_y >= 100` at the instants it counts as opaque — a guard
|
||
against data not yet met, not a fix. 4 + 13 disc tests green either side.
|
||
|
||
## Reach
|
||
|
||
⚠️ The colour census covers keyless elements. A **sprite**'s blend is a separate
|
||
question, and `T8aD +0x04` bit `0x02` was already refuted as an additive flag.
|
||
|
||
❔ `pbafc.prm` is unsettled and would need either a `GP_READY_ROOM` capture or a
|
||
blend-state read from Canary, neither of which is available here.
|