port: pose a settled screen at ONE instant -- title 1.81% -> 0.26%, splashes to 0.01%

The Decoder's finding, applied. `rest()` returns each element's last hold
keyframe chosen independently of every other element: right for anything that
ends the screen settled, exactly wrong for a transient. The title's
ptlogo_back2eff1 is a two-frame flash (0 until t52, 255 at t54-56, 0 by t58), so
its last hold IS the flash peak and rest() left it burning -- five of them, drawn
at once.

The settled instant is the longest interval containing no keyframe time, over a
bundle's TOP-LEVEL elements. Reproduced here before adopting: title [160, 236],
midpoint 198, the Decoder's number to the unit. The top-level restriction is what
makes it match -- including the ptloop leaves gives [269, 540].

AGAINST THE ORACLE:

  title            20.92 RMSE  1.81%  ->  14.61 RMSE  0.26%
  publisher_logo    9.05       0.75%  ->   2.17       0.01%
  developer_logos   8.86       0.33%  ->   3.05       0.01%
  main_menu                    0.08%  ->              0.08%   window too narrow
  extras                       0.19%  ->              0.19%   window too narrow

Seven times fewer differing pixels on the title, seventy-five times fewer on the
publisher splash, whose differing region is now a 13x18 box. The largest
correctness gain this port has had, and none of it is mine -- it is a decode
computed from the keyframe table with no reference to any capture.

APPLIED ONLY WHERE THE WINDOW IS WIDE, and the bar is not invented. This export's
widths split with nothing in between: 214, 190, 145, 76, then 12, 12, 8, 4. The
bar is 30 units -- the Decoder's disc-wide census puts the knee there (30% of
bundles >= 30, 42% under 10, the latter mostly loop* fragments meant to be in
motion) and this export's screens sit 4x either side with nothing between 12 and
46. Two independent populations agreeing on where to cut.

Checked unbroken: boot pacing unmoved, scripted walk runs end to end with focus
restored.

Also recorded: my "34 focus-record elements, only 2 varying" is right for
GP_TITLE and reads as a fact about the format -- disc-wide it is 210 varying, 202
with rest() at the peak, concentrated in the paks a wider port reaches next. And
their sharper framing, which I have adopted: a pulsing element has no resting
pose at all, so rest() is MALFORMED rather than mis-answered on one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF
This commit is contained in:
Sylpheed port agent
2026-08-29 19:52:00 +00:00
parent 761071520a
commit 4226505222
3 changed files with 158 additions and 1 deletions

View File

@@ -56,6 +56,27 @@ var exit_ramp_units: float = 24.0
## copyright notice pulse. Narrowed to focus records it matches exactly one
## distinct element, and a rule justified by n=1 is a special case wearing a
## rule's clothes.
## The one instant a settled screen is posed at, in keyframe units, or -1.
##
## 🔴 Replaces per-element `rest()` while `holding`, where the export gives a
## wide enough window. `rest()` returns each element's last HOLD keyframe chosen
## independently of every other element -- right for anything that ends the
## screen settled, and exactly wrong for a **transient**. The title's
## `ptlogo_back2eff1` is a two-frame flash (0 until t52, 255 at t54-56, 0 by
## t58), so its last hold IS the flash peak and `rest()` leaves it burning. There
## are five of them, and `rest()` draws all five at once.
##
## ⚠️ **Only where the window is wide.** Across this export the widths split with
## nothing in between: `press_start` 214, `publisher_logo` 190,
## `developer_logos` 145, `title` 76 -- then `main_menu` 12, `extras` 12, the
## loading screens 8 and 4. A 12-unit "settle" on a menu that builds in until
## t=70 is a gap between staggered ramps, not a settled pose. The bar is 30
## units: the Decoder's disc-wide census puts the knee there (30 % of bundles
## have a window >= 30, 42 % have one under 10), and this export's own screens
## sit 4x either side of it with nothing between 12 and 46.
var settle_instant: float = -1.0
const SETTLE_WINDOW_MIN := 30.0
var looping_focus: Dictionary = {}
## Element ids whose nested `.rat` leaf the runtime actually draws.
@@ -99,6 +120,10 @@ func load_screen(t: ExportTree, name: String) -> bool:
ProjectSettings.get_setting("display/window/size/viewport_height"))
if Vector2i(int(design[0]), int(design[1])) != viewport:
push_warning("screen %s is authored at %sx%s, viewport is %s" % [name, design[0], design[1], viewport])
var w: Array = screen.get("settle_window", [])
settle_instant = -1.0
if w.size() == 3 and float(w[1]) - float(w[0]) >= SETTLE_WINDOW_MIN:
settle_instant = float(w[2])
_load_textures()
queue_redraw()
return true
@@ -185,7 +210,10 @@ func pose_at(element: Dictionary, t: float) -> Dictionary:
# While holding, stop at the hold: past it the group is ramping out, and a
# screen that has arrived and is sitting there is not leaving.
if holding:
t = minf(t, settle_units(element))
# One instant for the whole screen where the disc gives a wide enough
# window; otherwise each element's own hold, which is what this port did
# everywhere until 2026-08-29.
t = settle_instant if settle_instant >= 0.0 else minf(t, settle_units(element))
# The exit. The final keyframe carries no `t` -- the disc has no slot for one
# -- so it is given a synthetic time `exit_ramp_units` after the last timed
# frame and then interpolated like any other. That keeps one code path: the