This repository has been archived on 2026-09-16. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Sylpheed RE agent 7ba415fbae re: the last 9 effects are genuinely unshipped; wep_85 accounts for two
EF_IDX_ proved that prefixes exist, so the residual deserved the same treatment
across every package rather than one. Censusing prefixes over all 36
effect-carrying .xpr gives seven in use:

  EF_IDX_       223 names
  mdl_           45
  EF_IDX_mdl_    45
  VolumeLine_    10
  GN_            10
  GN__            6
  bare           the rest

Testing all nine unlocated names against all seven prefixes: 0 of 9 resolve.

That zero has force where the earlier disc-wide zero did not, and for the stated
reason - the control shows each prefix genuinely carries names the same search
reads (223, 45, 45, 10, 10, 6), so the instrument demonstrably works on the
population it is being asked about. The nine are bound by a datasheet field and
shipped in no package.

Two of them turn out to belong to one cut asset. eff_m010_wep_85 and
eff_m011_wep_85 name a weapon, and the weapon is real in the data:
Weapon_DSaber_P_wep_85_Beam with 24 uses, its Shell_, WeaponCannonName_ and
WeaponShellName_ siblings, and GameModel_eff_m010_wep_85 / _m011_ declaring the
two effects. But the weapon packages stop at 84 - hidden/resource3d/ holds 59
rou_f001_wep_NN.xpr files numbering 00 to 84 with gaps, and no wep_85. So wep_85
is a declared-but-unshipped weapon and its two effects go missing with it.

This does not contradict "every weapon is placed - 131 = 105+22+0+4". That
partition is declared x MOUNTED IN A LOADOUT, which is a different question from
whether a package ships.

Seven remain with no account: eff_e0044, eff_f0002, eff_f0002_barn, eff_h308,
eff_j002_e01, eff_j002_e02, eff_n0071. The .xpr route is now exhausted for them
under every prefix the disc uses; a different container or a runtime generator is
what is left.

All seventeen artefacts byte-identical.
2026-08-28 10:17:20 +00:00

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 AssetLoader for .xpr textures
  • 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)

  1. Mesh format — fingerprint with sniff-unknown, implement mesh.rs
  2. Audio — parse XWB headers, batch-convert XMA to WAV via ffmpeg
  3. Mission data — format unknown; starts after mesh/texture loading works
  4. Flight model — document by playing the original; implement as Bevy system

Constraints

  1. Never copy decompiled or disassembled game code — reimplement behavior through observation only.
  2. Assets stay gitignoredassets/ and *.iso are excluded. Never commit game files.
  3. Keep sylpheed-formats Bevy-free — parsers must be testable without a GPU.
  4. WASM must always compile — CI enforces cargo check --target wasm32-unknown-unknown.
  5. justfile is 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

Description
No description provided
Readme 103 MiB
Languages
Rust 97.6%
Python 1.1%
HTML 0.8%
Just 0.5%