port: build the correctness harness verify-screen has pointed at since P1
`tools/port/verify-screen` line 20 has said "use `tools/verify-capture` for the
correctness question" since P1, and there was no such file. The port has had a
harness comparing itself to sylpheed-cli -- two renderers sharing its assumptions
-- and none comparing it to the game, while its own docs said otherwise. That gap
is what ORACLE-CAPTURES.md warns about: this corpus has been bitten three times
by two renderers agreeing, and every one was obvious against a capture.
Five screens against framebuffer captures of the real game:
main_menu RMSE 14.79 0.25% differing focus state may differ
extras RMSE 15.29 0.46% focus state may differ
title RMSE 21.07 1.82% ptloop sweeps never stop
publisher_logo RMSE 10.77 1.00%
developer_logos RMSE 9.37 0.39%
NO SCREEN SHOWS A LARGE CONNECTED BLOB -- the shape a missing element makes, and
the shape all three historical failures made.
And 74.1% of main_menu's differing pixels fall inside the ORACLE'S OWN focus
signature (live-main-menu vs live-main-menu-options-focused, the same screen with
a different button lit). So the bulk of that disagreement is a state mismatch,
not a defect.
REFUTATION ATTEMPT, on ui-render-tone-curve.md's `capture = 255*(render/255)^g`.
It survives where it was measured and not past it. Binning every structurally
matched pixel by render level gives the relationship directly, and the implied
exponent is NOT constant: 1.26 at render 16, 1.10 at 32, crossing 1.0 near 44,
down to 0.69 at 96. Above ~44 the capture is BRIGHTER than the render, which one
exponent cannot express -- and that is exactly why my whole-frame fits kept
returning 1.00, the two halves cancelling. The page's own stated reach ("nothing
constrains midtones or highlights") was not a hedge, it was the finding. Its 1.49
for this screen measures 1.18-1.26 in my darks; recorded as a disagreement rather
than resolved, since they fit selected flat patches and I binned everything.
Two earlier versions of this tool reported a best-fit gamma and were wrong both
times -- once fitting across a 74% structural mismatch, once extrapolating past
the measurement's stated reach. The fix was not a better fit but a different
instrument: it prints the curve, which somebody can argue with.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF
This commit is contained in:
@@ -3667,3 +3667,84 @@ artefact would look like it worked.
|
||||
|
||||
Its output is **byte-identical** to the control's own stripping, so the tool and
|
||||
the experiment are the same operation rather than two implementations that agree.
|
||||
|
||||
## The correctness harness the docs promised for eight milestones did not exist
|
||||
|
||||
`tools/port/verify-screen`, line 20, since P1: *"Use `tools/verify-capture` for
|
||||
the correctness question."* **There was no such file.** The port has had a harness
|
||||
comparing itself to `sylpheed-cli` — two renderers sharing its assumptions — and
|
||||
none comparing it to the game, while its own documentation said otherwise.
|
||||
|
||||
`docs/re/captures/ORACLE-CAPTURES.md` is blunt about why that matters: two
|
||||
renderers agreeing proves nothing, and this corpus has been bitten three times —
|
||||
the dropped `pteff05` background, the scale-0 rect, `rest()` — each invisible to a
|
||||
render-vs-render diff and obvious against a capture.
|
||||
|
||||
`tools/port/verify-capture` now exists. **Five screens, against framebuffer
|
||||
captures of the real game:**
|
||||
|
||||
| screen | RMSE | differing | note |
|
||||
|---|---|---|---|
|
||||
| `main_menu` | 14.79 | **0.25 %** | focus state may differ |
|
||||
| `extras` | 15.29 | 0.46 % | focus state may differ |
|
||||
| `title` | 21.07 | 1.82 % | `ptloop` sweeps never stop |
|
||||
| `publisher_logo` | 10.77 | 1.00 % | |
|
||||
| `developer_logos` | 9.37 | 0.39 % | |
|
||||
|
||||
**No screen shows a large connected blob** — the shape a missing or misplaced
|
||||
element makes, and the shape all three historical failures made. The differences
|
||||
are scattered, and the two largest have stated causes.
|
||||
|
||||
### 74 % of `main_menu`'s difference is the oracle's own focus signature
|
||||
|
||||
The corpus ships `live-main-menu.png` and `live-main-menu-options-focused.png` —
|
||||
the same screen with a different button lit. Their difference *is* what focus
|
||||
changes, measured by the oracle against itself. Of the port's 2 159 differing
|
||||
pixels, **1 599 — 74.1 % — fall inside that signature.** So the bulk of the
|
||||
disagreement is a state mismatch (the port focuses `NEW GAME`, authored, because
|
||||
HANDOFF Q5 measured initial focus as unstable), not a rendering defect.
|
||||
|
||||
## Refutation attempt — the tone curve survives in its stated reach and not past it
|
||||
|
||||
`ui-render-tone-curve.md` models the relationship as
|
||||
`capture = 255·(render/255)^γ`, γ ≈ 1.34–1.49, **measured on dark flat patches
|
||||
(render ~0–60), with "nothing constrains midtones or highlights"** written into
|
||||
its own reach.
|
||||
|
||||
**I tried to fit that γ and got contradictory answers three times, and the
|
||||
contradictions were mine.** Binning every structurally matched pixel of
|
||||
`main_menu` by render level gives the relationship directly:
|
||||
|
||||
| render | capture | implied γ | pixels |
|
||||
|---|---|---|---|
|
||||
| 8 | 4.04 | 1.20 | 183 026 |
|
||||
| 16 | 7.89 | **1.26** | 227 630 |
|
||||
| 24 | 15.57 | 1.18 | 100 945 |
|
||||
| 32 | 26.15 | 1.10 | 87 474 |
|
||||
| 40 | 38.07 | 1.03 | 86 094 |
|
||||
| 48 | 53.96 | **0.93** | 85 255 |
|
||||
| 64 | 78.52 | 0.85 | 6 509 |
|
||||
| 96 | 130.44 | **0.69** | 1 682 |
|
||||
|
||||
✅ **The claim survives where it was measured.** In the darks the capture really
|
||||
is darker than the render and γ > 1.
|
||||
|
||||
🔴 **It is not a single power law.** The implied exponent falls monotonically and
|
||||
**crosses 1.0 near render ≈ 44** — above that the capture is *brighter*. One
|
||||
exponent cannot express a curve that crosses unity, which is precisely why my
|
||||
whole-frame fits kept returning γ = 1.00: the darks want more than 1 and the
|
||||
midtones want less, and they cancel.
|
||||
|
||||
**So the corpus's stated reach was not a hedge, it was the finding.** ⚠️ And the
|
||||
exponent in the darks measures **1.18–1.26 here against the page's 1.49 for this
|
||||
screen** — a disagreement I am recording rather than resolving, since they fit
|
||||
selected flat patches and I binned every matched pixel.
|
||||
|
||||
### The tool reports the curve, not a best exponent
|
||||
|
||||
Two earlier versions of `verify-capture` reported a best-fit γ and were wrong
|
||||
both times — once by fitting across a 74 % structural mismatch, once by
|
||||
extrapolating past a reach the measurement's own authors had written down.
|
||||
**Extrapolating a measurement past its stated reach is how this tool got it wrong
|
||||
twice**, and the answer was not a better fit but a different instrument: a table
|
||||
somebody can argue with.
|
||||
|
||||
Reference in New Issue
Block a user