Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Quiet-Wolfe/Rustic-Engine/llms.txt
Use this file to discover all available pages before exploring further.
Prerequisites
You need the Rust toolchain installed before you can build anything.Install Rust
Install Rustic Engine does not require a nightly toolchain — stable is sufficient.
rustup from rustup.rs, then verify:Build commands
Crate structure
The project is a Cargo workspace. Each crate has one responsibility and one only.| Crate | Responsibility |
|---|---|
rustic-core | Data types and parsing. Charts, characters, stages, scoring math, asset paths. Zero rendering or audio dependencies. |
rustic-audio | Audio playback via kira. Instrumental + vocal sync, conductor BPM tracking, sound effects. |
rustic-render | All drawing. Sparrow atlas parsing, sprite animation, camera, HUD, health bar, stage. |
rustic-gameplay | Game logic. Input, hit/miss detection, hold notes, health, score. Emits events — no direct rendering. |
rustic-scripting | Lua VM integration. Full Psych Engine Lua API surface with matching function signatures. |
rustic-app | Binary entry point and state machine. Wires crates together. Each screen is its own module. |
References directory
references/ contains source material used for behavior matching. These files are not compiled into the engine.
FNF-PsychEngine/
FNF-PsychEngine/
Full Psych Engine Haxe source code and assets. This is the primary reference for matching behavior exactly — when you’re unsure how something should work, read the Haxe source here first.
funkin/
funkin/
Base Friday Night Funkin’ source (pre-Psych Engine). Useful for understanding the original chart and asset formats before Psych Engine extended them.
RusticV1/
RusticV1/
The failed first attempt at this project. The parsing code (atlas, charts) is worth reusing. The architectural decisions are not — V1 is here as a cautionary reference, not a model.
VS-RetroSpecter-PART-2-Compiled/
VS-RetroSpecter-PART-2-Compiled/
A compiled mod with custom events, modcharts, and Lua scripts. This is the integration test target for Phase 5. When this mod runs correctly end-to-end, the engine is feature-complete.
Architecture rules
No crate should become a dumping ground
If a module grows beyond ~500 lines, split it into smaller focused files. This is a hard rule — not a suggestion. The V1 engine failed because a singlemain.rs grew to over 2,000 lines. Adding a freeplay menu caused breakage that cascaded across the entire file. Every change became risky because everything was coupled to everything else. V2 exists specifically to avoid repeating that mistake.
Each screen in rustic-app is its own module
The state machine in rustic-app manages transitions between screens. Title screen, main menu, freeplay, story mode, loading, playing, and results are each isolated modules — not branches inside a single function.
rustic-gameplay emits events; it does not render
rustic-gameplay has no dependency on rustic-render. It produces events (note hit, miss, health change) that the render layer consumes. Keep this boundary clean.
rustic-core has no rendering or audio dependencies
rustic-core holds data types and parsing logic only. It must remain importable by any other crate without pulling in wgpu, kira, or winit.
Commit discipline
Commit after every meaningful unit of work — a new parser, a working subsystem, a confirmed bug fix. Keep commits small and frequent. If something breaks, revert. Do not spend hours debugging a broken state. Revert to the last working commit and approach the problem differently. A clean history of small working steps is far more valuable than a single large commit that “eventually got it working.”Small commits also make blame and bisect useful. When a regression appears in Phase 3, you want to be able to identify the exact commit that introduced it — not search through 800 lines of mixed changes.
Code style
- Run
cargo clippybefore every commit. Fix all warnings — do not suppress them with#[allow(...)]unless there is a documented reason. - Run
cargo testbefore every commit. A commit that breaks the test suite should not exist in the history. - Format with
cargo fmtto keep diffs clean.