Checked first: no docs/re file mentions ArmsStatus, RangeFinder, Radar, Sight, Wing, NamePlate or ResourceTable. Only HudResource had been opened; the other fifteen records had not. The six IDXD entries of GP_MAIN_GAME_E2D.pak: two carry the 16-record HUD config, two the 13-record ObjectiveMarker_*/TutorialMarker_* set, one Face (52 portrait sprites), one ResourceTable. Between them they name 419 distinct asset paths -- the whole flight HUD -- with new subdirectory prefixes throughout (ArmsSt, ActvArm, RangeF, Marker, Manuva, Map, Speed, Radar, Sight, Wing, Hitmark, Lockon, Info). The decisive control uses the config's own exact path strings, so no guessing is left in the loop: 419 distinct .prt/.t32/.tbl values, ZERO resolve as a pak entry under 10 prefixes, and the four config filenames resolve to nothing either. The .t32 sprites certainly exist -- 574 T8aD in that pak. So the 2D pak is not addressed by name_hash of the name its config uses. This supersedes the earlier framing: the 28 'dangling' .prt names were never a missing-asset story; they are 28 of a set where none of the 419 resolves. ResourceTable is 58 positional fields = 29 pairs, alternating HudResource.tbl / HudMarkerResource.tbl, identical in all six language paks, with exactly one override at pair index 25 -- HudResource_S26.tbl. Reading: indexed by stage number minus 1, so index 25 is S26, the one stage with its own HUD config. Arithmetic exact, indexing unproven, not adopted. New structure doc, artefact and regenerator; the other seven regenerate byte-identical.
Project Sylpheed: Arc of Deception — Reborn
A clean-room, open-source reimplementation of Project Sylpheed: Arc of Deception (Xbox 360, 2006).
Built with Rust and the Bevy game engine. Runs natively on Windows, macOS, and Linux, and in the browser via WebAssembly.
Legal note: This project contains no original game code or assets. You must own a legitimate copy of Project Sylpheed to use this engine. Assets remain the intellectual property of SETA Corporation / Square Enix.
Current Status: Milestone 1 — Asset Explorer
- XISO disc image reading via
xdvdfs - Xbox 360 texture de-tiling (Morton / Z-order)
- XPR2 texture container parsing
- Bevy custom
AssetLoaderfor.xprtextures - Orbit camera viewer
- CLI tools: extract, list, sniff, texture info, texture export
- GitHub Actions CI (Windows + macOS + Linux + WASM)
- WASM / web build target
- Mesh format (reverse engineering in progress)
- Audio format (XMA → PCM pipeline)
- Mission data format
Repository Structure
sylpheed-reborn/
└── sylpheed-viewer/ ← Milestone 1: asset explorer (Rust/Bevy workspace)
├── Cargo.toml ← Workspace root
├── crates/
│ ├── sylpheed-formats/ # Format parsers — no Bevy dependency
│ │ ├── xiso.rs # XISO / XDVDFS disc image reader
│ │ ├── texture.rs # XPR2 container + DXT de-tiling (Morton)
│ │ ├── vfs.rs # Virtual filesystem + magic-byte sniffer
│ │ ├── mesh.rs # Mesh parser (stub — RE in progress)
│ │ └── audio.rs # Audio parser (stub — XMA TODO)
│ │
│ ├── sylpheed-viewer/ # Bevy application
│ │ ├── lib.rs # App setup + WASM entry point
│ │ ├── main.rs # Native binary entry point
│ │ ├── asset_loader.rs # Custom Bevy AssetLoaders
│ │ ├── camera.rs # Orbit camera (LMB orbit, RMB pan, scroll zoom)
│ │ └── ui.rs # egui file browser + RE notes panel
│ │
│ └── sylpheed-cli/ # Command-line tools
│ └── main.rs # extract / list / sniff / texture info commands
│
├── assets/ ← Extracted game files (gitignored)
├── .github/workflows/
│ └── ci.yml # CI: Windows + macOS + Linux + WASM
├── Trunk.toml # WASM build configuration
└── justfile # All build recipes
Getting Started
Prerequisites
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install just (task runner)
cargo install just
# For web builds only
cargo install trunk
rustup target add wasm32-unknown-unknown
Linux — Bevy system dependencies
sudo apt-get install -y \
libasound2-dev libudev-dev libwayland-dev \
libxkbcommon-dev libx11-dev libxi-dev pkg-config
Step 1 — Extract your disc
cd sylpheed-viewer
# Extract using the CLI tool
just extract /path/to/project_sylpheed.iso
# Or manually with xdvdfs
cargo install xdvdfs-cli
xdvdfs unpack project_sylpheed.iso ./assets/
Step 2 — Run the viewer
cd sylpheed-viewer
just run # Native viewer
just web # WASM dev server → http://localhost:8080
The asset viewer opens an orbit camera scene. Use the left panel to browse extracted game files. Click a .xpr file to preview it as a texture.
Build Commands
All commands run from the sylpheed-viewer/ directory.
just run # Run the native viewer (debug)
just run-dev # Run with hot-reloading
just build-native # Build native release binary
just web # WASM dev server at localhost:8080
just build-web # WASM release build → ./dist/
just extract game.iso # Extract an ISO to ./assets/
just sniff # Identify file formats in ./assets/
just sniff-unknown # Show only unrecognised formats (RE focus)
just test # Run all tests
just ci # Full CI: fmt + lint + test + WASM check
Technology Stack
| Layer | Choice | Reason |
|---|---|---|
| Language | Rust | Memory safety, performance, cross-platform |
| Game engine | Bevy 0.15 | ECS-first, WASM-native, data-driven |
| XISO reading | xdvdfs | Pure Rust, reads Xbox 360 disc images |
| Binary parsing | binrw | Derive-macro based, ideal for RE work |
| Web bundler | Trunk | Bevy's standard WASM build tool |
| CLI | clap | Asset extraction and inspection tools |
| Debug UI | bevy_egui | In-viewer asset browser and RE notes panel |
Key Architectural Decisions
sylpheed-formats has zero Bevy dependency. All binary format parsers live here and are testable with plain cargo test. Bevy integration is a thin layer on top in sylpheed-viewer.
WASM is a first-class target. XISO reading is gated behind #[cfg(not(target_arch = "wasm32"))] since the browser can't read local files. On the web, assets must be pre-extracted and served over HTTP.
Modding is designed in from the start. The virtual filesystem (vfs.rs) is the single choke point for all asset reads — a mod loader only needs to intercept that one layer to override any file.
Reverse Engineering Notes
Known file formats
| Path pattern | Format | Status | Notes |
|---|---|---|---|
*.XPR, *.XPR2 |
XPR2 texture | ✅ Parsing | DXT1/3/5, DXN, Morton de-tiling done |
DEFAULT.XEX |
Xbox EXE 2 | 🔬 Study | Main executable — load in Ghidra (PPC BE) |
*.XWB, *.XSB |
XACT audio | ⏳ TODO | Wave/sound banks; audio is XMA codec |
*.pak, *.p00 |
SETA archive | ⏳ Unknown | Paired header/data format |
| mesh files | Unknown | ⏳ TODO | Run just sniff-unknown to find candidates |
RE workflow
# 1. Extract and map the disc
just extract game.iso
just sniff-unknown # shows hex magic bytes of unknown files
# 2. Hex-inspect candidates
# Groups of 12 bytes at offsets: likely f32 XYZ vertices
# Groups of 6 bytes: likely u16 triangle indices
# 3. Cross-reference in Ghidra
# Load DEFAULT.XEX with PowerPC Big-Endian processor
# Search string refs to file extensions → find load functions
# 4. Implement parser
# Add binrw #[derive(BinRead)] struct in sylpheed-formats/src/mesh.rs
# cargo test -p sylpheed-formats
Next steps (Milestone 2)
- Mesh format — fingerprint with
sniff-unknown, implementmesh.rs - Audio — parse XWB headers, batch-convert XMA to WAV via
ffmpeg - Mission data — format unknown; starts after mesh/texture loading works
- Flight model — document by playing the original; implement as Bevy system
Constraints
- Never copy decompiled or disassembled game code — reimplement behavior through observation only.
- Assets stay gitignored —
assets/and*.isoare excluded. Never commit game files. - Keep
sylpheed-formatsBevy-free — parsers must be testable without a GPU. - WASM must always compile — CI enforces
cargo check --target wasm32-unknown-unknown. justfileis the source of truth for build commands — add new recipes there.
Milestone Roadmap
| Milestone | Goal | Status |
|---|---|---|
| 1 | Asset Explorer | 🚧 In Progress |
| 2 | Flying Tech Demo | ⏳ Planned |
| 3 | Combat Prototype | ⏳ Planned |
| 4 | Mission 1 Playable | ⏳ Planned |
| 5 | Full Game (all 16 missions) | ⏳ Planned |
| 6 | Mod SDK | ⏳ Planned |
Useful References
- xdvdfs — XISO disc image reader (used in this project)
- Xenia emulator — GPU/API reference (cloned at
../../xenia-canary/) - xboxdevwiki — Xbox 360 hardware documentation
- binrw docs — binary format parsing framework
- Free60 Project — open Xbox 360 hardware docs