Brought in with a subtree merge rather than a copy, so the port's 31 commits survive as history rather than arriving as one anonymous import. Landed under godot-import/ and moved into the final layout in the next commit, which keeps git's rename detection able to follow each file across the move.
76 lines
3.1 KiB
Markdown
76 lines
3.1 KiB
Markdown
# Sylpheed Godot
|
|
|
|
A clean-room Godot 4 port of *Project Sylpheed: Arc of Deception*, starting with
|
|
the menu shell: developer splash → intro video → title → main menu → submenus.
|
|
|
|
**You need your own copy of the game.** Nothing in this repository is game
|
|
content. An offline exporter reads the disc you supply and writes an open,
|
|
moddable asset tree; the Godot project reads only that tree and never touches a
|
|
disc format.
|
|
|
|
```
|
|
your disc ──▶ crates/sylpheed-export ──▶ export/ ──▶ port/ (Godot 4)
|
|
(Rust; decoders come from JSON + PNG reads ONLY
|
|
sylpheed-formats) + OGG + OGV open formats
|
|
```
|
|
|
|
## Why the wall
|
|
|
|
Two reasons, and the second is the interesting one:
|
|
|
|
1. Godot cannot read IPFB archives, RATC bundles, T8aD textures, XMA banks or
|
|
WMV video, and it should not learn to.
|
|
2. **Modding is a goal of this port.** If the runtime reads the original formats,
|
|
modding means reverse engineering. If it reads JSON and PNG, modding means
|
|
opening a file.
|
|
|
|
## Where the knowledge comes from
|
|
|
|
The decoders live in [`sylpheed-formats`][formats], pinned by revision — a
|
|
separate project, where the reverse engineering happens. Its
|
|
`docs/port/HANDOFF.md` is the contract: what has been decoded, what was measured
|
|
off the running game, and what is known to be undecodable. Read it before
|
|
assuming a value is on the disc.
|
|
|
|
[formats]: https://git.mc02.dev/fabi/Syplheed-Reborn
|
|
|
|
## Layout
|
|
|
|
| | |
|
|
|---|---|
|
|
| `crates/sylpheed-export/` | disc → open formats. Regenerates `export/` wholesale |
|
|
| `port/` | the Godot 4 project |
|
|
| `authored/` | decisions that are **not** on the disc, each with its reason |
|
|
| `export/` | generated, gitignored, never hand-edited |
|
|
| `tools/` | verification harnesses that hold the port to the reference renderer |
|
|
| `docs/` | the mission, the format spec, the agent's loop prompt |
|
|
|
|
## Verifying
|
|
|
|
**The oracle is the Xenia Canary capture and the game**, not either renderer.
|
|
`sylpheed-cli screen render` is an explorer and extraction CLI for verifying
|
|
decodes, and it can be wrong -- three times both it and the port agreed and both
|
|
were wrong, each caught only by a capture.
|
|
|
|
So `tools/verify-screen` is a **consistency check and a regression detector**,
|
|
not a grade. It draws every exported screen both ways -- built from the same
|
|
`sylpheed-formats` revision the exporter is pinned to -- and reports the largest
|
|
per-channel difference in the frame:
|
|
|
|
```
|
|
tools/verify-screen # every screen in the manifest
|
|
tools/verify-screen main_menu # one of them
|
|
```
|
|
|
|
A difference means the two moved apart; `docs/DECISIONS.md` says which one moved
|
|
and why, rather than tuning the port until the number goes down. Correctness is
|
|
checked against the captures indexed at `docs/re/captures/ORACLE-CAPTURES.md` --
|
|
mind that they are not gamma-neutral, so RMSE against them has a floor.
|
|
|
|
## Status
|
|
|
|
**P1.** The exporter writes `GP_TITLE`'s twelve screen builds and their sprites,
|
|
and the Godot project draws any of them statically at 1280x720 from that tree
|
|
alone. `main_menu` matches the reference renderer to within 3/255 on every
|
|
channel of every pixel. Next: P2, keyframe animation.
|