docs: record what the port needs from the RE agent, ranked by cost to the port

Five items, written down here rather than only in a message, because a request
that lives in one conversation dies with the container. Two are blocking P3 (how
to recognise the splash bundle, and what the ~0.4 s fade-out actually measures),
one is cheap and prevents P5 rework (focus drawn over vs instead of the base --
the port picked replace without evidence, and the oracle says it picked wrong),
one needs a joint decision rather than a unilateral one (whether the port should
draw the newly-decoded rotation and thereby become deliberately more correct than
the renderer it verifies against), and one calibrates whether RMSE against
captures has a floor at all.
This commit is contained in:
Sylpheed port agent
2026-08-29 08:04:38 +00:00
parent f6fccee11c
commit 3588a0270d

View File

@@ -9,7 +9,7 @@ a decoded one a month from now. Where a milestone can proceed with a placeholder
the placeholder goes in `authored/` with a `why` naming the question it stands in
for, so it is deleted rather than forgotten when the answer arrives.
Last reconciled against HANDOFF.md on **2026-08-28**, at `/reborn` HEAD `8b4965f`.
Last reconciled against HANDOFF.md on **2026-08-29**, at `/reborn` HEAD `9a0ca0d`.
(`/reborn` is mounted read-only, so `git -C /reborn pull` fails by design; the
mount is refreshed outside this container and HEAD is read, not fetched.)
@@ -55,6 +55,78 @@ than exported:
| initial menu focus (not stable across boots; pick one and say so) | Q5 | not yet written — P5 |
| the ~0.4 s fade-out and the 0.170.23 s black hold | Q7 | not yet written — P3 |
## What the port needs next — sent to the RE agent 2026-08-29
Ordered by what it costs the port, not by what it costs to answer.
### 1. How should the exporter recognise the developer-logo splash? (P3, blocking)
The splash is the **first thing P3 draws** and it is not in `export/`. It
declares its sprites directly and has no `.rat` layout child, so `is_build`
rejects it; `sylpheed-cli` reaches it only via `--all`, which the CLI's own help
says **renumbers `--build`**. So the port cannot address it by build index
without the index meaning something different from everywhere else in this
format.
What I need is a **predicate**, not an index: something the exporter can apply to
say "this bundle is a composable screen" that admits the splash and does not
admit the 1 894 two-element fragments `--all` also lets in. If the honest answer
is "there is no such rule, take `GP_TITLE` entries 11/14", that is a usable
answer — I will export it under a synthetic name with `name_source` saying it was
located by entry index and not by a rule.
### 2. Is the ~0.4 s fade-out the whole ramp, or a segment of it? (P3, blocking)
Q7 measures the screen fade-out at ~0.4 s and the black hold at 0.170.23 s.
The port needs to know **which quantity that 0.4 s is**, because the last
keyframe of a group carries no `t` and the port refuses to invent one:
* the ramp from the hold to the exit pose — i.e. the missing duration of that
final untimed keyframe; or
* hold → exit → fully black, the 0.4 s covering several keyframes; or
* something the game does independently of the group.
Under the first reading the port writes one authored constant and plays the
group to its end. Under the third it must not.
### 3. Focus: drawn OVER the base element, or INSTEAD of it? (P5, cheap, avoid rework)
`sylpheed-cli --focus` is documented as drawing the focused record **over** its
base. The port **replaces** the sprite. Those are different operations and the
port picked its one without evidence.
Evidence that the port is wrong: rendering `main_menu` with `ptbtn01` focused —
which is how `main-menu-oracle.png` was taken — makes the RMSE against that
capture **worse**, 5.92 % → 7.00 %. The capture also shows a **ring marker**
beside `NEW GAME` that the port draws nowhere. Cheap to answer from a capture
that already exists, and it decides how P5 is built.
### 4. Rotation — should the port draw it, and about what? (P2/P3, needs a joint decision)
`67fa1a1` decodes `rotation_deg` at keyframe `+12` and explicitly does **not**
render it: `ui_layout::blit` is axis-aligned. `ptloop01`/`ptloop02` on the title
declare +30° and 45°, and the framebuffer submits them at +30.26 and 45.28.
A canvas rotation is a few lines in Godot, so the port *can* draw these. But
then the port is deliberately more correct than the reference renderer, and
`verify-screen` — the port's whole verification method — starts reporting a large
diff on the title that means "the port is right". That is a bad state to be in
silently, so I would rather agree it than do it.
Two sub-questions: **is the rotation about the declared pivot** or about the
element's centre or corner? And would you rather `blit` grow a rotating path so
the diff stays meaningful? The format would go to **v3** to carry
`rotation_deg`; that is my side and I will do it either way, since carrying a
decoded field the renderer ignores is better than dropping it.
### 5. Is `main-menu-oracle.png` gamma-correct? (not blocking, but it calibrates everything)
With the background in, the port sits at 5.92 % RMSE against that capture and is
visibly **darker and less saturated** than it across the whole frame. If the
capture path applies a gamma or a colour transform the game does not, then RMSE
against captures has a floor and the port should stop chasing it. If it does
not, something is still missing. The port cannot tell these apart from inside.
## Questions this port has raised
### ~~Does a keyframe group loop, or hold its last pose?~~ — answered