Files
Sylpheed/docs/port/splash-animation-fixed.md
Sylpheed port agent 6263686841 port: the developer splash declares TWO shapes -- and the port draws both, per element
The publisher shape check covered one element on one screen, which I flagged: a
port applying one screen-wide ramp to everything would have passed it.

developer_logos declares gamearts/seta flat across 15..30 and anima decaying 17%
over the same interval. Same screen, same frames, same clock -- the two flat
elements are the control for the third, and any phase or rate error hits all
three alike.

Pre-registered, then filmed. Flat ones flat to five decimals (+0.00000), anima
decays. Fitted scale-free against declared curves: each element matches its own
at 0.49/0.50/2.18% max error and the OTHER shape at 8.1-8.8% -- 4-17x, both
directions.

Establishes the ramp is per-element, not just correctly shaped.
2026-09-02 16:20:27 +00:00

161 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# The splash: frozen, then fixed, and now checked for SHAPE as well as motion
**Status:** ✅ **animates, and the ramp matches the declared curve.** Written
2026-09-02 by the Port; HANDOFF on this branch answers `9ca1eb5`.
The 2026-09-02 play-test found the splash frozen. The cause and the fix are in
the commit history; this page is the part that comes after — **is the animation
now the right animation?** `motion-census` says explicitly that it cannot answer
that: *"a wrong ramp that moves every frame passes here."*
## Pre-registered (R2)
`palogo_sqex_eff` declares `0:a=0 → 15:a=255 → 30:a=212 → 45:a=0` — three
segments, three gradients:
| segment | declared |
|---|---|
| 0 → 15 | **+17.0** per unit |
| 15 → 30 | **−2.87** per unit |
| 30 → 45 | **−14.13** per unit |
> So a film should show three straight runs with breakpoints at **15** and
> **30**, the middle slope about **1/5** the magnitude of the last, and the rise
> about **1.2×** the last.
## Measured, from a film of a real boot
Region: `686x11+299+319` — the companion's top strip, which **no other element
overlaps**, so the number is that element's own alpha and not a composite.
| view units | strip mean | slope/unit |
|---|---|---|
| 5.58 | 0.02809 | |
| 10.00 | 0.05086 | **+0.00515** |
| 13.04 | 0.06611 | **+0.00503** |
| 16.12 | 0.07530 | +0.00298 ← crossing the breakpoint |
| 19.21 | 0.07260 | **−0.00087** |
| 25.38 | 0.06695 | **−0.00092** |
| 28.39 | 0.06482 | −0.00071 |
| 31.39 | 0.05719 | −0.00254 ← crossing the breakpoint |
| 34.39 | 0.04471 | **−0.00416** |
| 40.39 | 0.01910 | **−0.00428** |
| 43.39 | 0.00655 | −0.00418 |
| 46.39 | 0.00000 | gone |
**Breakpoints land where declared**: the rise stops between 13.0 and 16.1, the
gentle fall steepens between 28.4 and 31.4.
| ratio | declared | measured |
|---|---|---|
| middle : last | 0.203 | **0.213** |
| rise : last | 1.20 | **1.20** |
Within 5 % and exact respectively. **The port interpolates piecewise-linearly
across the declared segments** — which is what the Decoder independently measured
the game doing (28 distinct alphas over 28 consecutive presents, modal steps −3
and −14 against predicted −2.87 and −14.13).
⚠️ **Ratios, not absolutes, and deliberately.** The strip mean is an alpha
scaled by whatever the sprite's own pixels are; its absolute value carries the
texture. A ratio between segments divides that out, which is why the shape is
checkable from a composite at all. Anyone quoting 0.00515 as an alpha is
misreading it.
## What this still does not establish
* That it **looks** right. Three instruments have now agreed with a picture a
human called wrong, and the fourth agreeing does not change the standing of
the fifth. A play-test is the check.
* ~~Anything about the **developer** splash's three logo/companion pairs. One
element, one screen.~~ ✅ **Closed below, and the developer splash turned out to
be the far better test.**
* The **absolute** alpha. The shape matches; whether the port's alpha equals the
game's at a given unit is `verify-capture`'s question, and it answers 0.01 %
at the settled pose only.
---
# ✅ The developer splash: three elements, TWO declared shapes, on one screen
The publisher check above had a structural weakness I named at the time: one
element, one screen, one shape. If the port applied *some* single ramp to
everything, that check would pass.
**The developer splash cannot be fooled that way, because it declares two
different shapes at once:**
| element | declared alpha | middle segment |
|---|---|---|
| `palogo_gamearts_eff` | `0:0 15:255 30:255 45:0` | **flat** |
| `palogo_seta_eff` | `0:0 15:255 30:255 45:0` | **flat** |
| `palogo_anima_eff` | `0:0 15:255 30:212 45:0` | **decays 17 %** |
Same screen, same frames, same clock, same code path. The two flat elements are
the control for the one that is not — no second run, no second renderer, and
nothing for a phase or rate error to hide behind, because any such error hits all
three identically.
## Pre-registered, before the film was read
> In units 15→30, `gamearts` and `seta` hold flat while `anima` falls gently.
> All three fall steeply 30→45.
## Measured, off a real filmed boot
Companion-only strips (each companion's rectangle minus the logo sitting inside
it), mean luma, `--film-interval=0.03`:
```
segment units 16-29 units 31-44
gamearts +0.00000 -0.00101
seta +0.00000 -0.00151
anima -0.00001 -0.00003
```
**The two flat ones are flat to five decimals. The decaying one decays.** And all
three fall over 31–44, so the flatness is not a dead element.
## The quantitative version, and the falsification arm
Each trace normalised by a **single solved gain** — one scalar per element, not a
per-point fit — against the declared curve, over the whole `t=0..45` ramp:
| element | fitted against | max err | rms err |
|---|---|---|---|
| `gamearts` | **its own (flat)** | **0.49 %** | 0.23 % |
| `seta` | **its own (flat)** | **0.50 %** | 0.27 % |
| `anima` | **its own (decay)** | **2.18 %** | 1.19 % |
| `gamearts` | anima's decay | 8.32 % | 4.80 % |
| `seta` | anima's decay | 8.08 % | 4.86 % |
| `anima` | flat | 8.82 % | 4.94 % |
**Both directions.** Every element fits its own declared shape 4–17× better than
it fits the other one available on the same screen. A port that drew one ramp for
all three would sit at ~8 % on at least one row; none does.
`anima`'s 2.18 % is the loosest row and the reason is its signal: its
companion-only strip means ~0.0005 against gamearts's ~0.015, thirty times
dimmer, so its noise floor is thirty times higher in these units. It still
separates from the wrong curve by 4×.
## What this adds over the publisher check
The publisher check established that the ramp has the declared *breakpoints and
slope ratios*. This establishes that the ramp is **per-element** — that the port
reads each element's own keyframes rather than applying a screen-wide curve. That
is a different failure mode, and it is the one that would have survived the
publisher check unnoticed.
## What it still does not establish
* That it **looks** right. This is instrument five. The standing of a human's
eyes is unchanged by it.
* The **absolute** alpha, for the same reason as above — a solved gain is
deliberately scale-free, so this is a shape result and says nothing about
whether the port's alpha equals the game's at a given unit.
* Anything about the **logo** elements. Both checks measure the pre-blurred
*companions*, because those are the strips that can be isolated from the sharp
logo underneath them.