Commit Graph

5 Commits

Author SHA1 Message Date
Sylpheed RE agent
5414db34bf re: the rest() fix gets its disc-wide check, and one question back to the
port agent

Closing the two things I flagged as unconfirmed when I committed the fix.

The unit gate is green: cargo test -p sylpheed-formats with SYLPHEED_DISC
set gives 131 passed, 0 failed across six binaries including the
disc-gated ones. The earlier background run that produced an empty log
had died with SIGTERM, which is why it looked like nothing happened.

And the disc-wide check the classification requires. Reimplementing both
rules over every RATC bundle on the disc -- 2859 bundles, 13991 elements
with at least two keyframes -- the fix moves rest for 30 elements, which
is 0.21 percent. Four go invisible to visible. Zero go visible to
invisible, which is the safety property I wanted and did not have when I
committed. The four are ptframe1 and ptframe2 in GP_TITLE entries 5 and
8, the same pair once per language.

That surfaces a discrepancy worth handing back rather than smoothing
over. On the English main menu exactly TWO elements satisfy the port
agent's pose-equality condition, not six, so their six must span the
whole twelve-screen export. That fits their own observation that the
timeline and rest differ in exactly one region, the bounding box of
ptframe1 and ptframe2 and nothing else. But if any of their other four
have a TRANSPARENT trailing run, my alpha rule leaves them alone
deliberately -- that exclusion is what protects PAUSE -- so I have asked
which screens they are on and whether a capture shows any of them drawn.
If one is, the alpha rule is incomplete and needs a third discriminator.
2026-08-28 21:24:42 +00:00
Sylpheed RE agent
4bc970688f re: rest() fixed -- a trailing keyframe run is the hold when it is
VISIBLE, not when its pose repeats

The port agent's report was right about the defect and about which
elements it hits, and its proposed condition does not survive the case
the exclusion was written for.

Their test -- the final untimed keyframe has the same pose as the last
timed one -- is also true of pgptitle.rat, whose trailing run is two
identical transparent frames. Adopting it would erase the word PAUSE
again, which a committed capture disproves. What separates the two is
alpha: an exit fades the element out so its last keyframe is transparent,
while an element with no exit ends on the pose you can see. So
rest_plateau now accepts a trailing run exactly when it is visible.

Verified against a capture rather than against another renderer, which is
the point their own report made: ptframe1's rest moves from (620,108)
t=16 to (440,108) t=62; the changed pixels are 10082 in a bounding box of
x 440-839, y 108-577, which is exactly the 400x470 at (440,108) they
predicted; and correlation against main-menu-oracle.png over that region
improves from 0.9596 to 0.9748. The PAUSE wordmark is unchanged across
all three pause builds.

This also closes a question ui-paint-order-key.md has carried for a
while, that ptframe1 and ptframe2 rest at alpha 0 while the capture shows
the menu frame plainly.

One trap cost most of this iteration and goes in METHOD: CARGO_TARGET_DIR
is redirected in this container, so ./target/debug/sylpheed-cli is hours
stale and every render I made against it was old code. Byte-identical
before and after reads as "no effect" when it actually means "you ran the
old binary".

The full disc-gated test suite was still executing when this was
committed; the verification above is artifact-based.
2026-08-28 21:19:00 +00:00
Sylpheed RE agent
ed4e5c7b37 re: build 4 captured without the plate, and keyframe groups hold rather
than loop

The port agent ranked a plate-free capture of build 4 above any further
static RE, so that came first.

B from the main menu returns to the title and the plate fades in a beat
later, which opens a clean window. Recorded at 20 fps from the press: the
art appears at 1.10 s, builds in to 3.70 s, sits settled and unobstructed
until 5.00 s, and the plate arrives at 5.10 s -- the band jumps from 282
to 3755 bright pixels. Committed the frame at 4.0 s as the reference for
the cyan glow slab they report drawing and the game not having.

Their other sub-question -- whether a keyframe group loops or holds --
falls out of the decoded sweeps plus a measurement I already had, and the
two agree. ptloop01's final keyframe parks pteff03.t32 at x=1521 and
ptloop02's parks pteff03a.t32 at x=-839, both off-screen on a 1280-wide
design; and over 18 s of settled title the centre tiles sit at sd <= 0.01
when a looping group would recross the screen every 7.5 s. So groups HOLD
at the last keyframe. The loop*.rat name is misleading.

Also recorded, in the corpus rather than only in their report: the
rest_plateau bug, with their exact identifying condition -- the final
untimed keyframe has the same pose as the last timed one -- the six
elements it misses on main_menu, and the bracket it drops. That closes an
open question ui-paint-order-key.md has carried for a while about
ptframe1 and ptframe2 resting at alpha 0 while the capture shows the
frame plainly. Same two elements, same cause. Not fixed yet; the change
is in ui_layout's rest().

And a METHOD line I would not have written myself: two renderers agreeing
is not evidence the field is right. Their composite and screen render
matched to 3/255 on main_menu and both omitted two elements the game
draws, because both read one field through one decoder.
2026-08-28 21:05:35 +00:00
Sylpheed RE agent
7fbdcc078c formats: apply the keyframe fade alpha, and fix the resting rule it exposed
blit modulated by tint only, which is 0xffffffff on essentially every keyframe,
so the fade word was decoded, stored and then discarded. Applying it as an ARGB
modulate takes the title composite's edge correlation against the framebuffer
capture of the running game from 0.4597 to 0.9538, both at zero shift. The white
wordmark with its blue outline, the trademark, the copyright and the orange
exploding planet all appear -- the planet because a full-screen blue effect that
rests at alpha 0 had been painting over it at full opacity.

ARGB is measured: across a fade-in the high byte walks 0x00 -> 0x80 -> 0xc0 ->
0xe0 -> 0xff while the low three stay ffffff, and the low 24 bits are 0xffffff on
5276 of the disc's 5453 resting keyframes.

A modulate can only remove pixels, so the risk is a blank screen. Measured: no-op
on 4060 of 5200 sprite elements, partial on 453, hides 687 -- transient HUD
indicators that should not be lit at rest -- and NO build is left with nothing
visible. A disc test asserts that, and that the no-op share stays high, which
also guards the resting rule against drifting onto ramp frames.

Both changes are in one commit because the second is invisible without the first.
Applying fade erased the word PAUSE, which the running-game capture plainly
shows: pgptitle.rat has three runs of two identical keyframes -- pre-roll, hold,
exit -- and the 'later run wins' tie-break grabbed the exit. A group carries the
screen's entry animation AND its exit, so a run ending on the last keyframe is
now excluded unless it is the only one. The title correlation is unchanged.
2026-08-19 06:56:38 +00:00
Sylpheed RE agent
b5c44b7c2a formats: the resting pose is the hold, not the longest dwell
Element::rest() picked the keyframe with the largest gap to the next keyframe's
time. That reads a keyframe as a value held until the next one; it is the start
of a ramp toward it. A long gap after keyframe k means the screen spends that
time arriving at k+1, so the settled pose is at the far end of the gap.

The title wordmark zooms in over five frames and holds at (184,193) at 100% from
t=251 to t=264. The old rule picked the frame before the long gap: (179,186) at
101%, still mid-zoom.

Measured against the framebuffer capture of the running title screen, which is a
1:1 crop so frame coordinates map directly (confirmed: the copyright line lands
on row 669 in the capture and in both composites). Edge-correlated over the
wordmark box:

    plateau (landed)      best 0.4597 at shift (0,0)
    longest dwell (old)   best 0.1511 at shift (+3,+8), 0.1268 at (0,0)

The old composite scores 3x lower and only peaks after being moved, by about the
(-5,-7) that picking kf4 instead of kf5 predicts.

It also fixes six title elements the old rule rested at alpha 0x00 where the
capture plainly shows them, and pteff00.prm - the full-screen fade quad painted
last - which rested at opaque black. That was the blocker on .prm compositing.

Adds tools/re-capture/align_to_capture.py, which is how this was scored, and
turns the .prm test that deliberately asserted the old defect into a guard on
the fix.

Not settled and now the next item: compose ignores the keyframe fade alpha
entirely (blit modulates by tint only), which is why choosing the wrong keyframe
was invisible until now.
2026-08-19 06:41:24 +00:00