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>
111 lines
5.5 KiB
Markdown
111 lines
5.5 KiB
Markdown
Build the Godot menu port of Project Sylpheed, one milestone at a time.
|
|
|
|
## Your objective
|
|
|
|
`Syplheed-Reborn/docs/port/MISSION.md` — read it every iteration. It defines the
|
|
milestones (P0…P7 plus a gated S1), the gate each one must pass, and the two
|
|
decisions already made. Work the **lowest unfinished milestone**; do not skip
|
|
ahead because a later one looks more interesting.
|
|
|
|
Reverse engineering has not stopped, but it is no longer the goal. An RE item
|
|
earns attention when the port is blocked on it, and the write-up still goes in
|
|
`docs/re/` under the usual convention.
|
|
|
|
## Read these first, every iteration
|
|
|
|
Short on purpose, and the reason this prompt is short:
|
|
|
|
1. `docs/port/MISSION.md` — the objective, the milestones, what is out of scope.
|
|
2. `docs/port/FORMAT.md` — the export schema. It is **versioned**; changing it is
|
|
a deliberate act with a version bump, not a silent edit.
|
|
3. `docs/re/REFUTED.md` — claims already tested and dead. Grep it for your nouns
|
|
before designing anything.
|
|
4. `docs/re/METHOD.md` — the traps this corpus has already paid for.
|
|
5. `docs/re/INDEX.md` — what is already decoded. Re-deriving a ✅ row is not a
|
|
finding.
|
|
6. `docker/agent/AGENT.md` — the container's tooling.
|
|
|
|
`docs/re/disc-atlas.html` is the map of how the assets reference each other —
|
|
useful when you need to find what feeds what.
|
|
|
|
**These files are the memory.** A finding that lives only in your context is lost
|
|
when the container dies.
|
|
|
|
## Each iteration
|
|
|
|
1. **Pick the lowest unfinished milestone** from MISSION.md. If you are mid-item,
|
|
continue it rather than starting another.
|
|
2. **Build the smallest thing that reaches its gate.** The gate is an *artifact* —
|
|
a validating JSON file, a screenshot, a human-clickable build — never "it
|
|
compiles".
|
|
3. **Keep derived and authored apart.** `export/` is regenerated wholesale and is
|
|
never hand-edited; `authored/` is hand-written and survives a re-export. If you
|
|
are tempted to hand-fix a file under `export/`, the fix belongs in the exporter
|
|
or in `authored/`. Every `authored/` entry carries a `why`.
|
|
4. **Write down what you learned** — in `docs/port/` for port decisions, in
|
|
`docs/re/` for anything about the disc.
|
|
* Refuted something → a line in `REFUTED.md`.
|
|
* Bitten by a general trap → a line in `METHOD.md`.
|
|
* Closed a format → update its `INDEX.md` row.
|
|
5. **Commit** to `auto/<topic>`, one logical change per commit.
|
|
6. **Publish**: `push-work`. Every iteration that produced a commit.
|
|
7. **Say plainly what you did not settle**, and stop.
|
|
|
|
## Hard rules
|
|
|
|
* **Never commit game assets.** `export/` is generated from the user's own disc
|
|
and is gitignored. Code, schemas, authored mappings and docs only. If you are
|
|
about to commit a sprite PNG or a transcoded video, stop.
|
|
* **No Rust in the Godot project, no GDExtension.** If Godot cannot read
|
|
something, the exporter emits it differently. The wall between the two halves is
|
|
the design, not an inconvenience.
|
|
* **Do not touch `crates/sylpheed-viewer`.** The Explorer is the human's
|
|
verification tool, it is independent of the port, and it keeps its
|
|
static-data-only rule. Do not refactor it to share code with the exporter.
|
|
* **Never commit to `main`**, never rebase a shared branch, never delete a branch,
|
|
never rewrite history.
|
|
* **Do not touch another agent's worktree.** `git worktree list` first; branches
|
|
marked `+` are checked out elsewhere.
|
|
* **One emulator at a time** — `run-canary` enforces it with a lockfile.
|
|
* **Measure the oracle; never infer it.** If you need to know what the real game
|
|
does, run it. This applies with full force to the keyframe time unit and to any
|
|
transition timing.
|
|
* **Do not improvise around a blocker.** If a milestone needs a decision only the
|
|
user can make — a new dependency, a scope change, the Ready Room go/no-go —
|
|
write what you found, note it in MISSION.md, and move to the next thing you can
|
|
actually finish.
|
|
|
|
## Verifying
|
|
|
|
* `build-reborn test` wires up `SYLPHEED_DISC`; without it the disc tests
|
|
self-skip and a green run means almost nothing.
|
|
* `sylpheed-cli screen render` is the reference renderer. When Godot draws a
|
|
screen, diff it against the CLI's composite of the same build — they should
|
|
agree, and where they do not, one of them is wrong and you must say which.
|
|
* Godot runs headless in this container (`godot --headless`), and
|
|
`screenshot` captures the windowed one under Xvfb.
|
|
* A regenerated artifact that comes out byte-identical is strong evidence a
|
|
change was additive. When it does change, check that every diff line pairs.
|
|
|
|
## Publishing
|
|
|
|
`push-work` pushes the current branch to origin. It refuses anything that is not
|
|
`auto/*` and never force-pushes, so the consolidated line stays a human's
|
|
decision. Run it **every iteration that produced a commit** — not at the end of
|
|
some longer arc, which is exactly when a container dies.
|
|
|
|
If it reports no credentials, say so in your reply and continue working. Do not
|
|
improvise another route out: no remote rewrite, no credential helper of your own,
|
|
no alternate transport. A push that is blocked is a blocked push.
|
|
|
|
## Pacing
|
|
|
|
One milestone step plus its write-up is a good iteration; a marathon is not. Stop
|
|
with a clean commit, a push, and an honest list of what is still open.
|
|
|
|
An emulator session must fit inside ONE turn — a Stop hook kills xenia when the
|
|
turn ends — but sequential tool calls within a turn are fine.
|
|
|
|
The loop runs on a fixed interval set by the harness, so you do **not** need to
|
|
arm the next wakeup yourself. Spend that attention on the write-up instead.
|