port: the rest() flash defect reaches all four splashes I ship; the port survives it
The Decoder censused rest()'s dwell fallback from the file side: 2305 elements have no plateau, 1697 of those get a visible pose, and in GP_TITLE all four visible fires are on the splash screens this port ships. Confirmed in my export. Refinement to their description: they named the [0:a0 15:a255 30:a212 45:a0] shape, but palogo_gamearts_eff and palogo_seta_eff hold 255 through t=30, so their fallback lands on the flash PEAK rather than its decay. Same defect, worse pose. The port ships the right frame and there is now a number for it. Publisher splash against the committed oracle capture: timeline (shipped) RMSE 2.17 / 0.01% differing; --pose=rest 9.05 / 0.75% -- 75x the differing area on a screen I ship. So the rule added to verify-screen's header after the title_jp mistake generalises, and is demonstrated against an oracle rather than argued. What did need fixing: ScreenView logged '(transparent at rest)' for every skipped element whatever instant it posed, so it said that about palogo_sqex_eff, whose resting alpha is 212. That is the same rest-versus-posed-instant confusion that cost a wrong conclusion, pre-printed in the log. It now names the instant. Controlled both ways: timeline says 'at t=6' and skips the flash, --pose=rest still says 'at rest' and draws it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF
This commit is contained in:
@@ -9,7 +9,7 @@ dies, which is what this file is for.
|
||||
|
||||
<!-- INDEX: generated by tools/port/index-decisions -- do not hand-edit -->
|
||||
|
||||
149 sections. Search this before re-deriving anything.
|
||||
150 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)
|
||||
@@ -160,6 +160,7 @@ dies, which is what this file is for.
|
||||
* [🔴 `verify-screen` was nondeterministic, and it looked fine most of the time](#verify-screen-was-nondeterministic-and-it-looked-fine-most-of-the-time)
|
||||
* [The JP title capture adjudicates `title_jp` — and it goes against the port](#the-jp-title-capture-adjudicates-title_jp--and-it-goes-against-the-port)
|
||||
* [🔴 CORRECTION: the port did not move away from the game — I scored the wrong frame](#correction-the-port-did-not-move-away-from-the-game--i-scored-the-wrong-frame)
|
||||
* [The `rest()` flash defect reaches four screens I ship — and the port already survives it](#the-rest-flash-defect-reaches-four-screens-i-ship--and-the-port-already-survives-it)
|
||||
|
||||
<!-- /INDEX -->
|
||||
## P0 — the exporter, 2026-08-28
|
||||
@@ -8695,3 +8696,60 @@ would score the port against a 45 px shift. With it, `title_jp` reads **RMSE
|
||||
|
||||
⚠️ The row prints `no capture` until the Decoder's branch merges. Their capture is
|
||||
theirs to commit; it was staged locally to test the row and removed.
|
||||
|
||||
## The `rest()` flash defect reaches four screens I ship — and the port already survives it
|
||||
|
||||
The Decoder censused it from the file side while I was looking at one instance:
|
||||
of 13 991 elements with ≥2 keyframes, **2 305** have no plateau so the dwell
|
||||
fallback decides, and **1 697 (74 %)** of those get a *visible* pose. In
|
||||
`GP_TITLE`, 5 fires and 4 are visible — **all four on the splash screens this
|
||||
port ships**.
|
||||
|
||||
✅ Confirmed in my own export, and it is exactly the JP-title shape on different
|
||||
screens:
|
||||
|
||||
| element | keyframes | `rest` |
|
||||
|---|---|---|
|
||||
| `palogo_sqex_eff` | `0:a0 15:a255 30:a212 45:a0` | t=30, **a=212** |
|
||||
| `palogo_anima_eff` | `0:a0 15:a255 30:a212 45:a0` | t=30, **a=212** |
|
||||
| `palogo_gamearts_eff` | `0:a0 15:a255 **30:a255** 45:a0` | **t=15, a=255** |
|
||||
| `palogo_seta_eff` | `0:a0 15:a255 **30:a255** 45:a0` | **t=15, a=255** |
|
||||
|
||||
📌 **A refinement to their description**, which named the `212` shape: two of the
|
||||
four hold **255 through t=30**, so their fallback lands on the flash's *peak*
|
||||
rather than its decay. Same defect, worse pose — full brightness, not
|
||||
four-fifths. The logos themselves (`palogo_sqex` holds 255 from t=30 to t=235)
|
||||
have a real plateau and are unaffected.
|
||||
|
||||
### The port ships the right frame, and now there is a number for it
|
||||
|
||||
Both poses of the publisher splash against the **committed oracle capture**:
|
||||
|
||||
| pose | RMSE | differing |
|
||||
|---|---|---|
|
||||
| **timeline — what the port ships** | **2.17** | **0.01 %** |
|
||||
| `--pose=rest` — the harness frame | 9.05 | 0.75 % |
|
||||
|
||||
🔴 **75× the differing area on a screen this port ships.** So the rule I wrote
|
||||
into `verify-screen`'s header after getting it wrong on `title_jp` is not a
|
||||
special case — it generalises, and here it is demonstrated against an oracle
|
||||
rather than argued.
|
||||
|
||||
✅ The port's settled pose evaluates `pose_at(hold)`, not `rest`, so it skips the
|
||||
flashes and agrees with the capture at 0.01 %. The defect is confined to the
|
||||
harness pose. **Nothing shipped is wrong; nothing needed fixing in the render.**
|
||||
|
||||
### What did need fixing: the port said "at rest" about a pose it never looked at
|
||||
|
||||
`ScreenView` logged `"%s (transparent at rest)"` for every skipped element,
|
||||
whatever instant it had posed. On the timeline path the pose is
|
||||
`pose_at(time_units)` — so it reported `palogo_sqex_eff (transparent at rest)`
|
||||
about an element whose **resting alpha is 212**.
|
||||
|
||||
⚠️ That is not cosmetic. The rest-versus-posed-instant confusion is precisely what
|
||||
made me score a `--pose=rest` frame against a capture and write up a drift that
|
||||
did not exist. A log line that erases the distinction is that error pre-printed,
|
||||
waiting to be believed. It now names the instant: `transparent at t=6`.
|
||||
|
||||
Controlled both ways on one screen: timeline → `transparent at t=6` and the flash
|
||||
skipped; `--pose=rest` → still `at rest`, and the flash **drawn**.
|
||||
|
||||
@@ -640,7 +640,22 @@ func _draw() -> void:
|
||||
else pose_at(element, time_units)
|
||||
var colour := modulate_of(pose)
|
||||
if colour.a <= 0.0:
|
||||
skipped.append("%s (transparent at rest)" % id)
|
||||
# 🔴 THIS LINE USED TO SAY "at rest" WHATEVER INSTANT IT HAD POSED.
|
||||
#
|
||||
# On the timeline path the pose is `pose_at(time_units)`, not
|
||||
# `rest`, and on the screens where those differ the message named a
|
||||
# pose it had not looked at. `palogo_sqex_eff` on the publisher
|
||||
# splash is `[0:a0 15:a255 30:a212 45:a0]` -- a flash whose `rest`
|
||||
# alpha is **212**. The port skips it correctly at the settled
|
||||
# instant and then reported "transparent at rest" about a resting
|
||||
# pose that is four-fifths opaque.
|
||||
#
|
||||
# ⚠️ That is not cosmetic. The rest-versus-posed-instant confusion is
|
||||
# exactly what made me score a `--pose=rest` frame against a capture
|
||||
# and write up a drift that did not exist (DECISIONS.md). A log line
|
||||
# that erases the distinction is the same error, pre-printed.
|
||||
skipped.append("%s (transparent %s)" % [id,
|
||||
"at rest" if pose_mode == Pose.REST else "at t=%.0f" % time_units])
|
||||
continue
|
||||
var pivot := _vec(element.get("pivot", [0, 0]))
|
||||
var pos := _vec(pose.get("pos", [0, 0]))
|
||||
|
||||
Reference in New Issue
Block a user