Initialise native Rust port of Ratchet & Clank: Going Commando
Sets up the foundation for reimplementing the PS2 game in Rust rather than emulating it. Nothing is implemented yet; this is the scaffold, the verified target and the working agreements that keep a long project coherent. Target disc, verified against a real image: SCUS_972.68 v1.01, USA Black Label, NTSC 60 Hz boot ELF 2,618,684 bytes, SHA-1 bacda860...d098a77, entry 0x00131AE8 The entry point independently matches the value recorded by the rac2-gc-decomp community reference, which cross-confirms the identification. This is the exact build the upstream research pins; Greatest Hits v2.00 is a different binary and is not the target. NTSC matters beyond label compatibility: PAL discs run 50 Hz, which would make chargeboots and other speed-sensitive movement run at 5/6 speed. Verifying the disc before writing movement code avoids discovering that in Phase 5. Contents: - Five-crate workspace (formats, extract, game, video, engine) on Bevy 0.19.1, matching the version ReRAC uses so its Graphics Synthesizer and VU work stays portable. `cargo check --workspace` is clean. - tools/identify-disc.py, which reproduces the identification against any disc image and distinguishes a truncated dump from a non-PS2 image. - .githooks/pre-commit, refusing game data from entering git history: disc image extensions, asset directories, container signatures at offset 0, and files over 50 MiB. Verified against seven cases including a disc image renamed to look like source. Now that this pushes to a remote, this matters more than it would have locally. - AGENTS.md, the operating agreements: no game data ever, reproduce the PS2 float model rather than approximating it, bound every read, verify against the real disc. - PROVENANCE.md, recording that this follows ReRAC (ISC) and learns from rac2-gc-decomp (MIT). Wrench is used as a written specification only and no GPLv3 code is copied, since that would relicense everything derived from it. RAC2Decomp is explicitly not used: its provenance is disputed in the upstream community reference, and it targets the wrong region. - docs/roadmap.md, phased so the riskiest unknowns are retired early. The two that matter: overlay relocation transfers from ReRAC and makes 27 level overlays tractable, while VU1 microcode is binary and is the hardest single item. Phase 5 is a deliberately scoped Veldin vertical slice as the go/no-go.
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
# AGENTS.md — working agreements for this repository
|
||||
|
||||
Guidance for coding agents and for anyone picking this up cold. Read this
|
||||
before changing anything.
|
||||
|
||||
## What this project is
|
||||
|
||||
A from-scratch native PC reimplementation of **Ratchet & Clank: Going Commando**
|
||||
(PlayStation 2, 2003), written in Rust. The game is **reimplemented**, not
|
||||
emulated and not translated: there is no MIPS interpreter and no CPU
|
||||
emulator anywhere in this repository.
|
||||
|
||||
The goal is a build that plays the game the way the original does. "Close
|
||||
enough" is not the bar — the point is that it feels like the game you remember.
|
||||
|
||||
## Hard rules
|
||||
|
||||
### 1. No game data in this repository. Ever.
|
||||
|
||||
Not the ISO, not extracted assets, not textures, not models, not audio, not
|
||||
BIOS dumps, not SDK binaries. Not in a branch, not in a stash, not "just for a
|
||||
test".
|
||||
|
||||
- Everything is covered by `.gitignore`.
|
||||
- `.githooks/pre-commit` blocks disc images, asset directories, container
|
||||
signatures and files over 50 MiB. It is activated via
|
||||
`git config core.hooksPath .githooks` — **check that this is still set** in a
|
||||
fresh clone, or run `git config core.hooksPath .githooks`.
|
||||
- To undo the hook for a legitimate source change: `git commit --no-verify`.
|
||||
Legitimate source changes should not need it.
|
||||
- Game data is an **input**, supplied by the user from their own legally
|
||||
obtained disc. Repositories that need the disc state its serial and hashes.
|
||||
|
||||
### 2. Reproduce the PS2 float model.
|
||||
|
||||
The Emotion Engine's FPU is not IEEE-754. It has **no denormals**, and rounding
|
||||
and exception behaviour differ from x86 in ways that are visible in gameplay.
|
||||
|
||||
Gameplay and animation maths must model this deliberately rather than using
|
||||
Rust's native `f32` and hoping. When porting a routine, find out how the
|
||||
original computes it and reproduce that, including the odd cases — ReRAC's
|
||||
reference implementation deliberately reproduces a "post-scale list bug" in the
|
||||
moby animation evaluator because doing so is what makes the result match.
|
||||
|
||||
Do not "fix" something that looks like a bug until you have confirmed the
|
||||
original does the same thing. Fidelity beats correctness.
|
||||
|
||||
### 3. Verify against the real disc, not against a guess.
|
||||
|
||||
A parser is correct when it round-trips your own disc's bytes, checked by hash.
|
||||
Commit size-and-hash tables (never content) so a test can assert "this matches
|
||||
retail" rather than "this matches whatever was on my disk".
|
||||
|
||||
### 4. Bound every read.
|
||||
|
||||
Asset data is untrusted input from a 2003 disc format. Parsers return typed
|
||||
errors; they never panic and never read past the end of a buffer.
|
||||
|
||||
## Orientation
|
||||
|
||||
Read these before working in an unfamiliar area:
|
||||
|
||||
| Path | What it is |
|
||||
|---|---|
|
||||
| `docs/disc-identification.md` | Which disc we build against, verified |
|
||||
| `docs/roadmap.md` | Phases, gates, and what is done |
|
||||
| `docs/plan/` | One file per subsystem, written **as work proceeds** |
|
||||
| `docs/formats/` | Format specs, written **as formats are reversed** |
|
||||
| `PROVENANCE.md` | Upstream projects we build on, and their licences |
|
||||
| `vendor/reRAC/` | Pinned reference checkout (not tracked) |
|
||||
|
||||
## Crates
|
||||
|
||||
| Crate | Responsibility |
|
||||
|---|---|
|
||||
| `gc-formats` | Parse asset formats into plain Rust values. No I/O beyond the caller's buffer. |
|
||||
| `gc-extract` | Disc pipeline: identify, unpack, verify. |
|
||||
| `gc-game` | Game logic: hero, weapons, classes, progression, saves. |
|
||||
| `gc-video` | IPU/MPEG-2 decode. |
|
||||
| `gc-engine` | Bevy app: GS, VU0/VU1, renderer, frame loop. |
|
||||
|
||||
The dependency direction is `gc-formats` ← `gc-extract`; `gc-formats` ←
|
||||
`gc-game` ← `gc-engine`; `gc-video` ← `gc-game` ← `gc-engine`. `gc-formats`
|
||||
depends on nothing of ours. Do not invert these — a format parser that can
|
||||
reach into the engine cannot be tested in isolation.
|
||||
|
||||
## Conventions
|
||||
|
||||
- Rust 2021 edition, workspace inheritance for all shared config. Do not
|
||||
hardcode a version in a member crate.
|
||||
- `rustfmt` defaults. Clippy warnings are errors in spirit; do not silence them
|
||||
without a comment explaining why.
|
||||
- Error types: `thiserror` for library errors in `gc-formats` and `gc-game`,
|
||||
`anyhow` at the binary/`xtask` boundary.
|
||||
- Comments explain **why**, especially for anything that looks like a bug. The
|
||||
`.githooks` and crate docs deliberately have few inline comments; match the
|
||||
surrounding density rather than adding noise.
|
||||
- Tests live beside the code (`#[cfg(test)] mod tests`) for unit-level checks,
|
||||
and in `tests/` for golden-file checks against real disc data.
|
||||
|
||||
## Working rhythm
|
||||
|
||||
This is a long project. Keep it navigable:
|
||||
|
||||
1. Work in small, coherent commits with a substantive body explaining what was
|
||||
non-obvious. Match the existing style in `git log`.
|
||||
2. **Update `docs/roadmap.md`** when a phase advances or a gate is met.
|
||||
3. **Write the `docs/plan/*.md` file for a subsystem when you start it**, and
|
||||
update it as you learn. The reasoning is more valuable than the code; the
|
||||
code is in git.
|
||||
4. **Update this file** if you change a convention.
|
||||
|
||||
## When you get stuck
|
||||
|
||||
Reverse engineering means long stretches of not knowing. That is normal, not a
|
||||
failure. Write down what you tried and what it ruled out in the relevant
|
||||
`docs/plan/` file before moving on — the next attempt (which may be you, in
|
||||
three months) needs the negative results as much as the positive ones.
|
||||
|
||||
If something is genuinely blocked, say so plainly and say what would unblock
|
||||
it. Do not paper over a gap with an approximation that looks like it works.
|
||||
|
||||
## Legal
|
||||
|
||||
Ratchet & Clank is a trademark of Sony Interactive Entertainment, developed by
|
||||
Insomniac Games. This is an unofficial fan project, not affiliated with or
|
||||
endorsed by either. We redistribute no game content. Upstream projects we learn
|
||||
from keep their own licences — see `PROVENANCE.md`, and keep those notices
|
||||
intact when porting their code.
|
||||
Reference in New Issue
Block a user