diff --git a/docs/port/BLOCKED.md b/docs/port/BLOCKED.md index 1e8ee6f0..26dd084d 100644 --- a/docs/port/BLOCKED.md +++ b/docs/port/BLOCKED.md @@ -171,7 +171,7 @@ 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 β€” 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. | +| **H5** | βœ… **CLOSED, and now confirmed from the other side too.** `pgloading_loop5` is additive, which is why `build_12`/`build_15` differed and `build_00`/`build_01` did not β€” the latter never draw it. With the reference taught the additive blend (`formats-pin-2026-09-01b`) **`build_00`/`build_01` go DIFFERS β†’ OK** (`over3` 3422 β†’ 0) and `build_12`/`build_15` fall 0.0772 β†’ 0.0463. | ⚠️ They do **not** return to their pre-change 0.0368, so `pgloading_loop5` carries a small residual of its own beyond the blend β€” recorded, not chased. πŸ“Œ The Decoder nearly reported my H5 claim as a contradiction because `loop5` is not a sprite: it is an **element**, `pgloading_loop5.rat`, resolving to sprite `pgloading_ring.t32`. **The element/sprite name split is a trap for any census keyed by sprite name** β€” worth knowing before writing one. | | **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. | diff --git a/docs/port/verify-screen-blend-divergence.md b/docs/port/verify-screen-blend-divergence.md index 8b15134e..cdb6a0b5 100644 --- a/docs/port/verify-screen-blend-divergence.md +++ b/docs/port/verify-screen-blend-divergence.md @@ -1,7 +1,8 @@ # `verify-screen` DIFFERS on six more screens β€” it is ADDITIVE, and the port is ahead of the reference -**Status:** βœ… **diagnosed for `main_menu` and `extras`**, 🟑 **open for four -others.** `check-all` stays **red**, on the four. Port `HEAD` `da7864e` + this +**Status:** βœ… **RESOLVED.** The reference gained an additive path +(`formats-pin-2026-09-01b`) and the divergence this page is about collapses **6Γ—**. +Everything below stands; the last section is the measurement that closes it. Port `HEAD` `da7864e` + this commit; HANDOFF at `9ca1eb5`. > πŸ”΄ **This page said, in its first version, that the cause was a blend-SPACE @@ -324,3 +325,77 @@ in this corpus recorded which one produced a diff, and for eight months there wa only one so it never mattered. Any diff quoted from here on should say what drew it β€” the same discipline `TEMPORAL-VERIFICATION.md` already demands for capture rate, applied to the thing that rasterises rather than the thing that clocks. + + +--- + +# βœ… Closed: the reference can draw additive now, and the divergence collapses 6Γ— + +The Decoder taught `ui_layout::blit` the additive blend at +`formats-pin-2026-09-01b`, on the argument this page made β€” that the comparison +was **structurally incapable**, and that the refutation which had kept additive +out was `⟨render-vs-capture⟩`, i.e. that renderer disagreeing with itself while +it had a stale keyframe association, no leaf geometry and no rotation. + +**Measured without pulling their branch into mine**: a detached worktree at the +tag, `sylpheed-cli` built there, and `verify-screen` pointed at it through +`SYLPHEED_CLI`. My branch is untouched and the reference on `main` is unchanged. + +## Pre-registered (R2) + +> With the reference finally able to draw additive, the diffs caused by that gap +> should collapse. `main_menu`/`extras` and their JP twins should fall sharply +> from ~7, and whatever remains is a *different* cause. + +| screen | alpha-over reference | **additive reference** | factor | +|---|---|---|---| +| `main_menu` | 7.2580, max 105 | **1.2068, max 28** | **6.0Γ—** | +| `main_menu_jp` | 7.3440, max 108 | **1.2111, max 31** | **6.1Γ—** | +| `extras` | 6.9757, max 113 | **1.0229, max 28** | **6.8Γ—** | +| `extras_jp` | 7.0734, max 115 | **1.0255, max 30** | **6.9Γ—** | +| `title` | 1.0335, max 88 | **0.5685, max 41** | 1.8Γ— | +| `title_jp` | 4.4944, max 233 | **2.8225, max 233** | 1.6Γ— | +| `build_12` / `build_15` | 0.0772, max 60 | **0.0463, max 17** | 1.7Γ— | +| `build_00` / `build_01` | 0.0676, max 60 | **0.0366, max 4** | **DIFFERS β†’ OK** | + +**`build_00` and `build_01` stop differing entirely** β€” `over3` 3 422 β†’ **0**. + +## And the twins agree to a third of a percent + +| | | +|---|---| +| `main_menu` 1.2068 vs `main_menu_jp` 1.2111 | **0.36 % apart** | +| `extras` 1.0229 vs `extras_jp` 1.0255 | **0.25 % apart** | + +Under the name-keyed map these pairs were 4.1Γ— and 7.8Γ— apart. Nothing was fitted +to make that happen β€” the locale twins converged first when the *port* took the +decoded field, and again now that the *reference* draws the same blend. + +## The residual is smaller and its causes are the documented ones + +* `title_jp` 2.82 at max 233 remains the largest, and its named reason β€” + `--pose=rest` sparkle handling β€” is untouched by any of this. +* `title` 0.57 at max 41 is the `ptloop` sweep-phase residual, also untouched. +* `main_menu`/`extras` and twins now sit at ~1.0–1.2, max ~28–31. **New, small, + and undiagnosed** β€” additive was the dominant cause and not the only one. +* `build_12`/`build_15` do **not** return to their pre-change 0.0368: they land at + 0.0463 with both renderers drawing `pgloading_loop5` additive. So that element + carries a small residual of its own beyond the blend. + +## πŸ”΄ What must happen to `check-all`, and why it has NOT happened yet + +The allowance widened when the reference could not draw additive. **That +justification is gone**, so the allowance should be narrowed back and the check +should regain its teeth. + +**It is not narrowed in this commit, deliberately.** `check-all` builds the +reference from the **workspace** `crates/sylpheed-formats`, and the additive path +is at a tag that has not landed on `main`. Tightening now would turn `check-all` +red against a reference that still cannot draw additive β€” a wall of failures +meaning one thing, which is the exact defect the display guard was added for. + +**The trigger is mechanical**: when the additive path is on `main`, drop the +export-derived clause and leave the two named legacy rows. The set that should +then differ is measured above and is `title`, `title_jp`, `main_menu`, `extras`, +`main_menu_jp`, `extras_jp`, `build_12`, `build_15` β€” with `build_00`/`build_01` +expected to pass. diff --git a/tools/port/check-all b/tools/port/check-all index 913a4e38..15801f0f 100755 --- a/tools/port/check-all +++ b/tools/port/check-all @@ -198,12 +198,26 @@ differs=$(grep -c DIFFERS "$OUT/verify-screen.log" || true) # 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. +# βœ… THE REAL FIX HAS LANDED -- AT A TAG, NOT YET ON `main`, WHICH IS WHY THIS +# CLAUSE IS STILL HERE. `ui_layout::blit` draws additive as of +# formats-pin-2026-09-01b, so the comparison is capable again and this widening +# has lost its justification. +# +# Measured at that tag, in a detached worktree, with SYLPHEED_CLI pointed at it: +# main_menu 7.26 -> 1.21, extras 6.98 -> 1.02, both JP twins likewise, and +# build_00/build_01 go DIFFERS -> OK (over3 3422 -> 0). A 6x collapse. +# +# πŸ”΄ NOT NARROWED YET, AND ON PURPOSE. This script builds the reference from the +# WORKSPACE crate, and the additive path is not on `main`. Narrowing now would +# turn check-all red against a reference that still cannot draw additive -- a +# wall of failures meaning one thing, which is the defect the display guard above +# exists to prevent. +# +# TRIGGER, so this does not rot: when `grep -q additive crates/sylpheed-formats/src/ui_layout.rs` +# succeeds, delete the export-derived clause and keep only `-e title -e title_jp`. +# The set that should then differ is measured in +# docs/port/verify-screen-blend-divergence.md: title, title_jp, main_menu, extras, +# main_menu_jp, extras_jp, build_12, build_15 -- and build_00/build_01 pass. additive_screens=$(python3 -c " import json, glob, os out = []