diff --git a/authored/rendering.json b/authored/rendering.json index dc8774db..6633144d 100644 --- a/authored/rendering.json +++ b/authored/rendering.json @@ -154,7 +154,11 @@ "pteff23", "ptloop01", "ptloop02" - ] + ], + "press_start": [ + "ptbtn00f" + ], + "title": [] }, "additive_elements_why": [ "TRANSCRIBED, not authored, and the distinction is the whole entry. The port", diff --git a/docs/port/BLOCKED.md b/docs/port/BLOCKED.md index e5382529..4369a145 100644 --- a/docs/port/BLOCKED.md +++ b/docs/port/BLOCKED.md @@ -155,6 +155,26 @@ quads and the batch holds six, so four were dropped **with a well-formed log lin Adopted — EXTRAS whole-screen residual **1.97 → 0.63**, `ptframe4` 31.90 → 1.14. See `DECISIONS.md` for the `pteff10` metric split and why I took it anyway. +## New ask, 2026-08-31 — a capture of the title plate at a NON-ZERO loop phase, port `HEAD` `9a8b43e` + +**Every title-plate capture we hold is at the plate's blind phase**, so nothing in +this repository can tell whether the port now draws the plate's pulse correctly. + +`ptbtn00f` — the plate's highlight, measured **additive** (entry 2 of +`docs/re/data/blend-bit-vs-oracle.txt`) — contributes **0 px at loop phase 0** and +22 000–29 000 px at phases 20–100. `verify-capture` poses `title_plate` at +`--loop-phase=0`, matching `live-title-press-a.png`. So the row agrees to 0.09 % +and is **blind to the pulse by construction**, and switching the element to its +measured blend moved 26 319 px at phase 20 while reporting exactly zero here. + +📌 **The blend itself is not in question** — it is theirs and measured off the GPU. +What is unverifiable on my side is whether *my renderer* now reproduces it. One +capture of the title with the plate at a visibly mid-pulse instant closes it. + +⚠️ Cheap alternative if a fresh capture is expensive: the plate's alpha at a known +phase, from the existing `plate-pulse-measured.md` run, would let me check the +level rather than the picture. + ## New ask, 2026-08-31 — three, derived from today's completed blend delivery, port `HEAD` `49a6333` **1. Is `pteff10` additive on the MAIN MENU too?** It is measured additive on diff --git a/docs/port/DECISIONS.md b/docs/port/DECISIONS.md index e1db720a..b8dd7789 100644 --- a/docs/port/DECISIONS.md +++ b/docs/port/DECISIONS.md @@ -9,7 +9,7 @@ dies, which is what this file is for. -337 sections. Search this before re-deriving anything. +338 sections. Search this before re-deriving anything. * [P0 — the exporter, 2026-08-28](#p0--the-exporter-2026-08-28) * [P1 — Godot draws the screen, 2026-08-28](#p1--godot-draws-the-screen-2026-08-28) @@ -348,6 +348,7 @@ dies, which is what this file is for. * [EXTRAS is complete: 1.97 → 0.63, and the two metrics disagree about it](#extras-is-complete-197--063-and-the-two-metrics-disagree-about-it) * [🔴 Refuted: my kind census was a two-screen generalisation, one message after I criticised theirs](#refuted-my-kind-census-was-a-two-screen-generalisation-one-message-after-i-criticised-theirs) * [🔴 Refuted: the sweeps DO run on the menu, and my instrument was measuring my own renderer](#refuted-the-sweeps-do-run-on-the-menu-and-my-instrument-was-measuring-my-own-renderer) +* [The plate's highlight is additive — and my harness poses it at the one phase where it is invisible](#the-plates-highlight-is-additive--and-my-harness-poses-it-at-the-one-phase-where-it-is-invisible) ## P0 — the exporter, 2026-08-28 @@ -16386,3 +16387,48 @@ path, so enabling the loop today would make the port more correct in behaviour a visibly worse against the capture. That trade needs the ramp first, and it is filed. What has changed today is the *claim*: **the port is wrong here, and says so.** + +## The plate's highlight is additive — and my harness poses it at the one phase where it is invisible + +`blend-bit-vs-oracle.txt` entry 2: `ptbtn00` `0x0110` **alpha-over**, `ptbtn00f` +`0x0112` **ADDITIVE** — the PRESS Ⓐ plate and its own highlight, same screen, same +draw order, one bit apart. Entry 4, the whole title, is **alpha-over throughout**, +including `ptlogo_back2`/`ptlogo_back2eff` — which independently kills the +*"frame-shaped and mostly transparent ⇒ additive"* rule I declined to adopt. + +Bands are now per **draw op** rather than per paint-order entry, because one band +per element cannot express *base alpha-over, its own focus record additive*. + +### 🔴 It reported ZERO three times, and each zero had a different cause + +**R2 says a change with a predicted magnitude that delivers nothing is a failed +run, not a negative result.** This one delivered nothing three times. + +1. **The mapping never reached the overlay.** `additive_elements` was assigned to + `view` in three places and to `overlay` in **none** — and the plate *is* an + overlay. Every other decoded rule on that page is assigned to both. +2. **I then "proved" the element is never drawn** — suppressed its sprite at six + times across the cycle, 0 px every time. ⚠️ **That sweep was invalid.** I varied + `--time` while passing **`--loop-phase=0` in every run**, and `--loop-phase` + pins exactly the clock a looping record runs on. Six samples of one phase. I + was one commit from filing *"the port never draws the plate highlight"* as a + defect. +3. **The real reason the harness saw nothing.** Swept properly: + +| loop phase | `ptbtn00f` contributes | +|---|---| +| **0** | **0 px** | +| 20 / 40 / 60 | 28 197 / 28 830 / 28 821 px | +| 80 / 100 | 27 334 / 21 885 px | + +**`verify-capture`'s `title_plate` row poses at `--loop-phase=0`** — the single +phase where the highlight contributes nothing. The change is live and worth +**26 319 px** at phase 20, and the row correctly reports 13.03 / 0.09 % unchanged, +because it is blind to it by construction. + +📌 That is a defect in my instrument, not in the fix: **the row that validates the +plate cannot see the plate's pulse.** Now stated in the tool, next to the pose. + +⚠️ **Not verified against the oracle.** The blend is theirs and measured; that the +*port* now draws it correctly is not something any capture I hold can confirm, +because every title-plate capture is at the blind phase. Filed. diff --git a/port/scripts/boot.gd b/port/scripts/boot.gd index 13534df4..0030e527 100644 --- a/port/scripts/boot.gd +++ b/port/scripts/boot.gd @@ -1396,6 +1396,14 @@ func _raise_overlay(name: String) -> void: # the announcement to cover the overlay -- the guard's first use. overlay.leaf_time_units = view.leaf_time_units overlay.draw_leaf_for = _draw_leaf_for + # 🔴 THE OVERLAY IS A SECOND ScreenView AND IT WAS NOT GETTING THIS. Every + # other decoded rule on this page is assigned to `view` AND to `overlay`, and + # `additive_elements` was assigned to `view` in three places and to `overlay` + # in none -- so the PRESS (A) plate, which is an overlay, kept drawing its + # focus record alpha-over after the blend was wired in. The change reported + # EXACTLY ZERO against the capture, which is what a change that never reached + # the renderer looks like. + overlay.additive_elements = _additive_elements overlay.loop_leaf = _loop_leaf_screens.has(name) overlay.holding = true overlay.time_units = 0.0 diff --git a/port/scripts/screen_view.gd b/port/scripts/screen_view.gd index ab252406..b3077933 100644 --- a/port/scripts/screen_view.gd +++ b/port/scripts/screen_view.gd @@ -782,15 +782,29 @@ func _draw() -> void: var additive_here: Array = additive_elements.get( String(screen.get("name", "")), []) var order: Array = screen.get("paint_order", []) + # 🔴 BANDS ARE PER DRAW OP, NOT PER ELEMENT, and the plate is why. `ptbtn00` is + # drawn alpha-over and its own focus record `ptbtn00f` ADDITIVE -- same screen, + # same element, adjacent draws, measured off the GPU. One band per paint-order + # entry cannot express that, and the first version of this file could not draw + # the PRESS (A) plate's pulse at all: both halves went through the base's band. var band_of := {} var band_additive: Array[bool] = [] var prev := -1 for index: int in order: - var add_it: bool = additive_here.has(String(elements[index].get("id", ""))) - if prev == -1 or add_it != band_additive[prev]: - band_additive.append(add_it) - prev += 1 - band_of[index] = prev + var el: Dictionary = elements[index] + var eid := String(el.get("id", "")) + var parts: Array = [[index, "base"], [index, "focus"]] if el.has("focus") \ + else [[index, "base"]] + for part: Array in parts: + var pid := eid + if part[1] == "focus": + var fes: Array = el.get("focus", {}).get("elements", []) + pid = String(fes[0].get("id", eid)) if not fes.is_empty() else eid + var add_it: bool = additive_here.has(pid) + if prev == -1 or add_it != band_additive[prev]: + band_additive.append(add_it) + prev += 1 + band_of[[index, part[1]]] = prev for i in band_additive.size(): _band(i, band_additive[i]) # Runs left over from a screen with more of them would still hold last @@ -800,7 +814,7 @@ func _draw() -> void: for index: int in order: var element: Dictionary = elements[index] var id: String = element.get("id", "") - _target = _bands[band_of[index]] + _target = _bands[band_of[[index, "base"]]] if ghosts.has(index): skipped.append("%s (template instance)" % id) continue @@ -838,6 +852,7 @@ func _draw() -> void: # A FOCUSED button draws its record INSTEAD of its base sprite -- measured, # the focused sprite covers the base at 100.0 % of base-visible pixels. if focused_id == id and element.has("focus"): + _target = _bands[band_of[[index, "focus"]]] _draw_focus(element) continue # 🔴 A LOOPING record draws IN ADDITION to the base, not instead of it. @@ -869,6 +884,7 @@ func _draw() -> void: _draw_quad(tex, placement(pose, pivot, tex.get_size()), colour, pivot, pos, rot) drawn.append(id) if loops_focus: + _target = _bands[band_of[[index, "focus"]]] _draw_focus(element) elif element.get("role", "") == "primitive" and element.has("size"): # A primitive has no texture; the quad is its declared size and its diff --git a/tools/port/verify-capture b/tools/port/verify-capture index 8075e156..f5db9d72 100755 --- a/tools/port/verify-capture +++ b/tools/port/verify-capture @@ -129,6 +129,17 @@ MAP=( # independent captures fit at two DIFFERENT phases -- this one at 237, the # no-plate one at ~400 -- and both to 0.01 % or better. A geometry error in how # the sweeps are drawn would leave a floor in both. Neither has one. + # 🔴 THIS ROW IS POSED AT THE PLATE'S BLIND PHASE, and it cannot see the plate's + # highlight at all. `--loop-phase=0` pins the looping-focus clock, and + # `ptbtn00f` -- the plate's own highlight, which the GAME draws ADDITIVE + # (docs/re/data/blend-bit-vs-oracle.txt, entry 2) -- contributes EXACTLY 0 px at + # phase 0 and 22 000-29 000 px at phases 20..100. Measured 2026-08-31 by + # shadowing its sprite and diffing. + # + # So switching that element to its measured additive blend moved 26 319 px at + # phase 20 and reported ZERO here. This row's 0.09 % is real and unaffected; it + # simply says nothing about the pulse. A capture at a NON-ZERO loop phase is + # what would let this row see it, and none exists -- filed in BLOCKED.md. "title_plate:$CAPS/live-title-press-a.png:plate" # A BANDED row -- the capture is 1279x120, not a full frame, and the harness # could not compare one until now. That was the only reason this capture sat