Sets a new mission: boot the real disc through developer splash -> intro video -> title -> main menu -> submenus in Godot 4, interactively, with no gameplay, no 3D and no emulator. docs/port/MISSION.md defines it -- eight gated milestones, each finished by an ARTIFACT rather than by compiling, plus the Ready Room as an explicitly gated stretch goal with a one-iteration probe that decides go/no-go. GP_READY_ROOM is 1106 entries with 6 recoverable names and is ISL-scripted, so it is either a week or a quarter, and the agent must not start it on its own authority. Architecture, per the user's decision: the Godot project is INDEPENDENT of the Rust viewer and never reads a disc format. An offline Rust exporter converts the disc into open formats; Godot reads only those. No GDExtension, no Rust in the Godot project, and sylpheed-viewer is off limits -- it stays the human's verification tool with its static-data rule intact. docs/port/FORMAT.md specifies the open format, versioned, because modding is the port's second goal and that makes the layout a deliverable rather than a temp directory: JSON over XML (Godot parses JSON natively; its XMLParser is SAX), names never hashes, provenance in every generated file, and unknowns listed rather than guessed. The discipline the whole thing rests on is the derived/authored split. `export/` is regenerated wholesale and never hand-edited; `authored/` is hand-written and survives a re-export. Three things this milestone needs are NOT on the disc in any decoded form -- which button does what, paint order, and menu sound cues -- so they live in `authored/` with a stated `why`. Deleting an authored entry because the exporter can now emit it IS the measure of progress. `export/` is gitignored: it is generated from the user's own disc and this stays a clean-room repo. Container: adds a pinned Godot 4 (windowed under Xvfb for screenshots, plus a headless wrapper). ffmpeg already carries libtheora, which is the video target -- Godot 4 plays only Ogg Theora natively and the disc's ADV.wmv is WMV3/WMA Pro. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
4.2 KiB
4.2 KiB
Notes for an agent working inside this container
Read this before starting a dynamic-RE run. Everything here is something that already went wrong once.
The container fixes three old traps for you
- The display outlives the turn. Xvfb and openbox are children of PID 1, not of your shell. The old "Xvfb dies on its own every few minutes" note is gone — you no longer have to wrap a whole session in one blocking foreground call to keep it alive.
- The toolchain is real.
tools/re-capture/rebuild_canary.shexists because the old box had no cmake/ninja/clang and only runtime sonames, so it hand- relinked object files. Do not use it here. Usebuild-canary. - numpy and Pillow are installed.
entities2.py,flight_probe.pyand the image oracles work. Their absence used to look like a logic bug.
Method (the part that matters more than the tooling)
- Measure the oracle; never infer it. A session with zero Canary runs is a red flag.
- Trace upstream to where data first goes wrong, rather than patching the symptom you can see.
- Try to refute before believing. Record demotions rather than editing them
away —
docs/re/README.mdhas the ✅/🟡/❔ convention, and a withdrawn result is more useful than a quietly deleted one. - A probe that never performs the action will "prove" the action does not exist. The "targeting is automatic" conclusion came from a sweep that only ever tapped once; target select is Ⓐ pressed twice.
- Do not poll faster than the guest updates — it manufactures a clean curve
out of noise.
rate-curve-aliased-BAD.csvis committed as the bad example.
Running the emulator
run-canary # correct audio/pad/display flags baked in
pad.py tap A ; pad.py dpad down # scripted input (--hid=file, no uinput)
screenshot ~/shots/now.png # cropped to the GAME surface, not the window
python3 tools/re-capture/gmem.py find hex:820af844 400
- One emulator at a time.
run-canaryenforces it with a lockfile. - Boot is slow cold, ~25 s once the shader/code caches are warm — so a launch-and-dump fits in a single call.
- Screens: classify by whole-image statistics (
screen_id.py), not named pixels. Named-pixel oracles are only valid while the game image sits at a known place, and nothing errors when it moves.
Verifying your own work
- Reborn's disc-gated tests self-skip without
SYLPHEED_DISC. A green run with it unset means almost nothing.build-reborn testwires it up for you. - Prefer a headless self-verify over "it compiles":
sylpheed-cli mesh render,screen render,save infoall produce checkable artifacts. - A Bevy system-parameter conflict is invisible to the type checker and panics at startup. If you touch viewer systems, run the binary, don't just build it.
The Godot port
The primary objective — see docs/port/MISSION.md. Two binaries are installed:
godot-headless --path port/ --script res://tools/check.gd # no display needed
DISPLAY=:99 godot --path port/ # windowed, under Xvfb
screenshot ~/shots/godot.png # then capture it
- Godot is pinned to one version in the Dockerfile. An engine bump changes rendering, and this project diffs Godot's output against a reference renderer — so do not upgrade it to fix a bug without saying that is what you did.
sylpheed-cli screen renderis the reference. When Godot draws a screen, render the same build with the CLI and compare. Where they disagree, one of them is wrong; say which, and why, rather than tuning until they match.- ffmpeg has libtheora, which is the transcode target for video. Keep the exact command in the exporter config — a modder who dislikes the quality should be able to re-run it, not reverse-engineer what you did.
- Never commit anything under
export/. It is generated from the user's own disc and gitignored. Code, schemas,authored/mappings and docs only.
Reporting
State what you measured, what you assumed, and what you could not settle. If a result is withdrawn, say so and keep the reasoning — that is the corpus's whole convention, and the reason its numbers can be trusted.