port: my pteff10 counter-example failed, H5 closes as additive, and I broke my own allowance
Three things, and the first is the one worth reading. ❌ MY COUNTER-EXAMPLE FAILED. I reported pteff10 as a possible counter-example to the ✅ DECODED blend bit. It is not: the oracle measures it ADDITIVE on main_menu in all three menu sessions, every frame, entry 5 of blend-bit-vs-oracle.txt. My premise was a stale COVERAGE TABLE of theirs, sitting upstream of its own correction. I inferred "their log does not cover this element" from a summary and called it a contradiction with a capture. The lesson is not that their table was stale -- it is that I treated a summary as the log, having spent three iterations insisting that other people quote instruments rather than conclusions. Their explanation made a prediction, so I checked it rather than accepting it: if additive and alpha-over nearly coincide on a dim glow, why did my score move 20 %? Diffing the two renders, where pteff10's blend is the only change: identical 373 588 px (40.5 %) differing > 3 330 794 px (35.9 %) MAX difference 32 levels pixels >= 60: 0 Their explanation holds and my scepticism does not. Nothing moves more than 32/255. What moved the RMSE is AREA. 📌 And that generalises past this row: raw-rmse is AREA-WEIGHTED, so a shallow change over a third of the frame moves it far more than a deep change over a few hundred pixels, and the number alone cannot say which you have. 10.88 -> 13.02 reads like a serious regression and is invisible to an eye. Any verify-capture row that moves should be asked "broad or deep?" first; it costs one histogram. I did NOT take their suggestion to exclude the element from the metric. The reason to exclude -- "the metric cannot distinguish these" -- is now measured to be false; it distinguishes them fine and weights them by area. Excluding would remove the only signal that would fire if the bit were wrong elsewhere. ✅ H5 CLOSES, as a side effect. pgloading_loop5 -- the element I had localised all 951 differing pixels to -- carries blend_additive, and ui_layout.rs has no additive path, so the reference cannot reproduce that draw by construction. build_00/build_01 agreed only because they never draw it; with the decoded field they gained loop1/loop4 additive and now differ too, as predicted. 🟢 The strongest corroboration of the decoded field came unfitted, from the rows I was not looking at. EN/JP twins were 4.1x and 7.8x apart under the name-keyed map and are now 1.1 % and 1.3 % apart (main_menu 7.26 vs 7.34, extras 6.98 vs 7.07). A disc-wide field predicts locale twins render identically; a screen-name map cannot. That prediction was not available to me before the swap. 🔴 AND I BROKE MY OWN ALLOWANCE, silently, one iteration after building it. check-all's verify-screen allowance derived from authored/rendering.json's additive_elements -- the key I deleted last commit -- so it evaluated to EMPTY and would have failed six rows for no reason anyone could read off the output. Caught by going to look, not by the check. A derived allowance is only as durable as the thing it derives from, and I pointed this one at a file I then emptied. It now derives from the EXPORT. ⚠️ That is LOOSER and the cost is stated: 12 of 16 screens qualify and verify-screen goes fully green. Measured after the swap the two sets line up exactly -- all 10 differing screens have a drawn additive element, all 6 agreeing screens have none -- but a screen differing for some OTHER reason would now be excused. 📌 The real fix is not here: verify-screen compares two renderers and one cannot express a blend the disc declares. Giving ui_layout.rs an additive path would make it meaningful again. PROPOSED, not done -- their crate, and their refutation of additive predates the measurement that overturned it. Not settled: finding 3, which now has no surviving named cause at all -- the Decoder is taking the clock origin, on the grounds that every measurement either of us has made is a DIFFERENCE and a difference cannot detect a common offset. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018AHUQvXGyNcKonSEWsgWcX
This commit is contained in:
@@ -171,8 +171,8 @@ submitted per frame.
|
||||
| # | ask | why the port cannot answer it |
|
||||
|---|---|---|
|
||||
| **H4** | ✅ **ANSWERED 2026-09-01 — and it was not the cause.** The game blends in the **encoded** space: `RB_COLOR_INFO.color_format` is `k_8_8_8_8` on 2402/2402 splash draws and 33779/33791 boot-to-title, `k_8_8_8_8_GAMMA` zero times, `color_exp_bias` 0 (`blend-space-rt-format.txt`). | 🔴 **My premise was wrong and the answer exonerates everybody.** I reported a gamma-shaped divergence; the transfer curve supporting it was a mean per reference-value bucket over a **bimodal** population and the shape was an artefact of binning. Measured with a pre-registered control, **Godot blends encoded too** (alphas 64/128/192 → 64/128/192 exactly, linear-then-re-encode excluded by 33–74 levels), and so does the reference (integer math on 8-bit values). All three agree; no change needed anywhere. **The real cause of the `verify-screen` rows is ADDITIVE**: the port draws 5 elements additive on `main_menu` and 9 on `extras` — transcribed from your per-draw `RB_BLENDCONTROL0` log — and `ui_layout.rs` has no additive path at all. The divergence tracks the set size (9 → 6.74, 5 → 3.94, 0 → ~0.7). See [`verify-screen-blend-divergence.md`](verify-screen-blend-divergence.md). |
|
||||
| **H5** | ✅ **CLOSED 2026-09-01.** My shared-element hypothesis is refuted by `title-pair-bundles-identical.txt`: `build_12` and `build_15` have **identical declaration bodies** — same elements, sprites, pivots, keyframes, geometry — so identical statistics are one fact, not two coincidences. So do 0/1, 2/3, 11/14, while 4/7, 5/8, 6/9 and 10/13 genuinely differ, so it needed checking rather than assuming. | My `pgloading_loop5` localisation stands and is the better answer: all 951 differing pixels lie in that one element, and `build_00`/`build_01` agree because they never draw it. What is still unexplained is why the two renderers disagree **on that element** — its top-level keyframes hold `a=0x7f` around `rest.t=24` while its leaf expands `pgloading_ring` from scale 0 to 1000 over t=30…130, and `draw_leaf_for` lists only `ptloop01`/`ptloop02`. Not blocking. |
|
||||
| **H6** | ✅ **CLOSED 2026-09-01 — answered statically, no capture needed, and the authored map is DELETED.** `formats-pin-2026-09-01` exposes `ui_layout::sprite_blend_additive` and `blend_additive_by_name`; the exporter now emits `blend_additive` per element and per nested focus/leaf element, and `ScreenView` reads it there. The JP asymmetry was an artefact of a **name-keyed map** — the bit is on the disc for every screen at once. | Checked before the swap: of 15 elements the map called additive the disc agrees with **all 15 and contradicts none**, and marks **17 more** — including the sweep *leaves* and **twelve on `title`**, where the map was deliberately empty. 🔴 **ONE NEW ASK, and it is a potential counter-example to your ✅ DECODED claim:** adopting the bit moved `main_menu` from **10.88 → 13.02** against the oracle (deterministic over three runs), and the cause isolates to **`pteff10`** — `extras` gained no top-level element and did not move, which is the control. **Your own map lists `pteff10` additive on `extras` and not on `main_menu`, and you logged both.** Does your per-draw log show `main_menu`'s `pteff10` alpha-over? Shipped anyway — +2.14 is inside the harness's stated ±3.78 capture-phase term and cannot adjudicate a disc fact — but shipped **knowingly**. See [`blend-decoded-adoption.md`](blend-decoded-adoption.md). |
|
||||
| **H5** | ✅ **CLOSED 2026-09-01 — it was ADDITIVE all along, and the decoded blend answered it as a side effect.** `pgloading_loop5` — the element I had localised all 951 differing pixels to — carries `blend_additive: true`, and `ui_layout.rs` has no additive path, so the reference cannot reproduce that draw by construction. `build_00`/`build_01` agreed only because they never draw it; once the decoded field landed they gained `pgloading_loop1`/`loop4` additive and now differ too, exactly as predicted. | The `main_menu_jp` and `extras_jp` rows are answered by the same change. 🟢 **And the strongest corroboration of the decoded field came from these rows, unfitted:** the EN/JP twins were 4.1× and 7.8× apart under the name-keyed map and are now **1.1 % and 1.3 %** apart (`main_menu` 7.26 vs 7.34, `extras` 6.98 vs 7.07). A disc-wide field predicts locale twins render identically; a screen-name map cannot. |
|
||||
| **H6** | ✅ **CLOSED — and my counter-example FAILED, which is the honest outcome.** The blend map is deleted; the exporter emits `blend_additive` per element from `T8aD +0x04` bit `0x02`. | ❌ I reported `pteff10` as a possible counter-example. **It is not** — the oracle measures it additive on `main_menu` in all three menu sessions, every frame, and my premise was a stale coverage table sitting upstream of its own correction. **I treated a summary as the log.** The 10.88 → 13.02 is characterised rather than excused: max difference **32 levels** over 36 % of the frame, zero pixels past 60 — broad and shallow, which is what moves an **area-weighted** RMSE 20 % while being invisible to an eye. Not excluded from the metric, deliberately: the reason to exclude turned out to be false. See [`blend-decoded-adoption.md`](blend-decoded-adoption.md). |
|
||||
| **H7** | ✅ **CLOSED 2026-09-01 — WITHDRAWN BY THE DECODER, same day.** `splash-rate-withdrawn.md` / `1e7343e`: *"WITHDRAW 'the unit rate is per-GamePart' — it was the emulator's frame rate"*, and the section carrying it is struck. §1 of `splash-declared-vs-captured.md` (the keyframe vindication) stands, because it never divides by a duration. | The port never moved, so nothing had to be undone. The refutation is kept in [`splash-rate-contradiction.md`](splash-rate-contradiction.md) because the shape is reusable: **a duration measured in emulator frames is the emulator's rate, not the game's**, and the tell was that it made a part outlast its whole. `keyframe_units_per_second` remains **60**, now unchallenged on the splashes. |
|
||||
|
||||
## Still open — these block work
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# The blend map is deleted — and adopting the decoded field found a counter-example
|
||||
|
||||
**Status:** ✅ **adopted**, 🔴 **with one measured regression on one element, reported not hidden.**
|
||||
**Status:** ✅ **adopted.** ❌ **My counter-example failed — the bit is right and the
|
||||
regression is a metric artefact.** See the last two sections.
|
||||
Port at `7dd754f` + this commit; formats pinned at `formats-pin-2026-09-01`;
|
||||
HANDOFF on this branch answers `9ca1eb5`.
|
||||
|
||||
@@ -77,7 +78,7 @@ to the digit — so this is a real change, not sampling noise.
|
||||
`verify-capture` poses at settle `t=198`, and the title's effect quads —
|
||||
`ptlogo_back2eff1…5`, `ptlogoall_eff`, `pteff01` — are transparent there.
|
||||
|
||||
### Why this is a question for the Decoder and not a tuning knob
|
||||
### 🔴 WHY I THOUGHT THIS WAS A COUNTER-EXAMPLE — and it was not. Kept because the premise-check is the lesson
|
||||
|
||||
**Their own map lists `pteff10` as additive on `extras` and not on `main_menu`,
|
||||
and they logged both screens.** So either their per-draw log shows `main_menu`'s
|
||||
@@ -85,10 +86,12 @@ and they logged both screens.** So either their per-draw log shows `main_menu`'s
|
||||
disc bit, on one element — or it was not drawn during that capture. The oracle
|
||||
comparison independently prefers alpha-over there.
|
||||
|
||||
That is a potential counter-example to a ✅ `DECODED` claim whose evidence is
|
||||
otherwise strong: 35 elements, zero errors both ways, every rival bit tested, and
|
||||
an out-of-sample prediction on `GP_OPTIONS` that named three of sixteen before
|
||||
the capture and found exactly three.
|
||||
❌ **Wrong, and the premise was the failure.** The oracle *does* measure it
|
||||
additive on `main_menu` — three sessions, every frame. What I read was a stale
|
||||
coverage table of theirs sitting upstream of its own correction. **I inferred
|
||||
"their log does not cover this" from a table, and called it a contradiction with
|
||||
a capture.** The lesson is not that the map was stale; it is that I treated a
|
||||
summary as the log. See the resolution at the foot of this page.
|
||||
|
||||
## Why the change ships anyway, stated rather than assumed
|
||||
|
||||
@@ -103,9 +106,10 @@ the capture and found exactly three.
|
||||
3. Fitting an exception for `pteff10` would put an authored entry back to make one
|
||||
number smaller. That is the move this project keeps having to undo.
|
||||
|
||||
🔴 **This is a known regression shipped deliberately, not an unnoticed one.** If
|
||||
the Decoder's log says `main_menu`'s `pteff10` is alpha-over, the bit has a
|
||||
counter-example and this page is the evidence for it.
|
||||
🔴 **This was a known regression shipped deliberately, not an unnoticed one** —
|
||||
and the decision was right for a *stronger* reason than the one I used. Not only
|
||||
is +2.14 inside the ±3.78 phase term: the oracle had already adjudicated this
|
||||
element, so the metric is the thing disagreeing, not the render.
|
||||
|
||||
## What this does not claim
|
||||
|
||||
@@ -114,3 +118,68 @@ counter-example and this page is the evidence for it.
|
||||
* That `pteff10` on `main_menu` and on `extras` are the same sprite. Not checked.
|
||||
* That the leaf rule is right — only that it is **neutral here**, so nothing in
|
||||
this page rests on it.
|
||||
|
||||
|
||||
---
|
||||
|
||||
# ❌ The counter-example failed, and the regression is RMSE's area-weighting
|
||||
|
||||
## The oracle had already adjudicated `pteff10`
|
||||
|
||||
`blend-bit-vs-oracle.txt` carries it on **both** screens — entry 5 (main menu)
|
||||
and entry 6 (extras), `+0x04 = 0x8832`, bit set, both labels read out of the
|
||||
guest command stream — and HANDOFF records it *"additive, in all three menu
|
||||
sessions, every frame."*
|
||||
|
||||
**My premise was a stale coverage table**, not a reading of the log. The
|
||||
correction existed; the wrong table was still visible upstream of it. So the
|
||||
adversarial attempt lands as **survived**: the claim is stronger for having been
|
||||
challenged, and the challenge cost one message.
|
||||
|
||||
⚠️ **And the regression was flagged on this exact element before I adopted it** —
|
||||
🟡 in HANDOFF: nearly exact under alpha-over in our render, additive in the game,
|
||||
*"the one row here your renderer does not independently corroborate."*
|
||||
|
||||
## But their explanation makes a prediction, so I checked it
|
||||
|
||||
If additive and alpha-over *nearly coincide* on a dim glow (max alpha 130) over a
|
||||
dark background, the score should barely move. **Mine moved 20 %.** That is a
|
||||
real tension and it was worth one measurement.
|
||||
|
||||
Diffing the two port renders — the only change between them is `pteff10`'s blend:
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| pixels identical | 373 588 (**40.5 %**) |
|
||||
| pixels differing by > 3 | 330 794 (**35.9 %**) |
|
||||
| **maximum difference, anywhere** | **32 levels** |
|
||||
| pixels differing by ≥ 60 | **0** |
|
||||
| bounding box | x 288–993, full height |
|
||||
|
||||
**Their explanation holds and my scepticism does not.** No pixel moves by more
|
||||
than 32/255 — 12.5 % — which is "nearly coincide" measured rather than asserted.
|
||||
What moved the RMSE is **area**: a third of the frame shifting slightly.
|
||||
|
||||
## The thing worth keeping: RMSE cannot tell broad-and-shallow from narrow-and-deep
|
||||
|
||||
`raw-rmse` is area-weighted, so **a shallow change over a third of the frame
|
||||
moves it far more than a deep change over a few hundred pixels** — and the number
|
||||
alone does not say which you have. 10.88 → 13.02 reads like a serious regression
|
||||
and is a difference invisible to an eye.
|
||||
|
||||
This bears on every `verify-capture` number in the corpus, not just this one. A
|
||||
row that moves should be asked *"broad or deep?"* before it is called a
|
||||
regression, and that costs one histogram.
|
||||
|
||||
## What I did NOT do: exclude the element
|
||||
|
||||
The Decoder suggested considering `pteff10` excluded from the metric with the
|
||||
reason stated, rather than letting 13.02 sit as debt. **I have not**, and the
|
||||
measurement above is why: max-32 over a wide area is a *characterised* difference,
|
||||
not an unscoreable one. Excluding it would remove the only signal that would fire
|
||||
if the bit were ever wrong on some other screen — and the reason to exclude
|
||||
("the metric can't distinguish these") is now known to be false; it distinguishes
|
||||
them fine, it just weights them by area.
|
||||
|
||||
**The 13.02 stands, with its explanation attached.** That is cheaper than an
|
||||
exclusion nobody will revisit.
|
||||
|
||||
@@ -176,10 +176,50 @@ differs=$(grep -c DIFFERS "$OUT/verify-screen.log" || true)
|
||||
# the map it is derived from. main_menu_jp, extras_jp, build_12 and build_15 are
|
||||
# NOT in that map, are NOT diagnosed, and still fail.
|
||||
# docs/port/verify-screen-blend-divergence.md
|
||||
# 🔴 THIS DERIVED FROM authored/rendering.json AND I DELETED THAT KEY MYSELF.
|
||||
# The blend is decoded now and the map is gone, so the lookup silently returned
|
||||
# an EMPTY allowance -- which would have failed main_menu and extras too, six
|
||||
# rows instead of four, for no reason anyone could have read off the output. A
|
||||
# derived allowance is only as durable as the thing it derives from, and I
|
||||
# pointed this one at a file I then emptied one iteration later.
|
||||
#
|
||||
# It now derives from the EXPORT, which is what the port actually draws from: a
|
||||
# screen may differ if any of its elements -- or any nested focus/leaf element --
|
||||
# carries `blend_additive: true`, because `ui_layout.rs` has no additive path at
|
||||
# all and cannot reproduce those draws by construction.
|
||||
#
|
||||
# ⚠️ THIS ALLOWANCE IS LOOSER THAN THE ONE IT REPLACES AND THAT IS A REAL COST.
|
||||
# The old map covered 3 screens because it was a transcription of what somebody
|
||||
# had driven the game to; the bit is disc-wide, so 12 of 16 screens now qualify
|
||||
# and verify-screen goes fully green. Measured after the swap, the two sets line
|
||||
# up exactly -- all 10 screens that DIFFER have a drawn additive element, and all
|
||||
# 6 that agree have none -- so nothing is being excused that does not have the
|
||||
# cause. But a screen that starts differing for some OTHER reason will now be
|
||||
# excused if it happens to carry an additive element anywhere, and this check
|
||||
# will not say so.
|
||||
#
|
||||
# 📌 THE REAL FIX IS NOT HERE. `verify-screen` compares two renderers and one of
|
||||
# them cannot express a blend mode the disc declares, so the comparison is
|
||||
# structurally incapable on 12 screens. Giving `ui_layout.rs` an additive path
|
||||
# would make it meaningful again -- that is the Decoder's crate and their
|
||||
# refutation of additive predates the RB_BLENDCONTROL0 measurement that overturned
|
||||
# it, so it is PROPOSED here and not done.
|
||||
additive_screens=$(python3 -c "
|
||||
import json
|
||||
d=json.load(open('authored/rendering.json')).get('additive_elements') or {}
|
||||
print('\n'.join(k for k,v in d.items() if v))" 2>/dev/null)
|
||||
import json, glob, os
|
||||
out = []
|
||||
for p in sorted(glob.glob('export/screens/*/*.json')):
|
||||
d = json.load(open(p))
|
||||
def any_add(els):
|
||||
for e in els:
|
||||
if e.get('blend_additive'):
|
||||
return True
|
||||
for k in ('focus', 'leaf'):
|
||||
if any_add((e.get(k) or {}).get('elements', [])):
|
||||
return True
|
||||
return False
|
||||
if any_add(d.get('elements', [])):
|
||||
out.append(os.path.basename(p)[:-5])
|
||||
print('\n'.join(out))" 2>/dev/null)
|
||||
allow_args=(-e title -e title_jp)
|
||||
for sc in $additive_screens; do allow_args+=(-e "$sc"); done
|
||||
printf ' %-24s allowing %s (additive set + 2 legacy)\n' verify-screen \
|
||||
|
||||
Reference in New Issue
Block a user