Architecture
Architecture
Module Dependency Graph
main.rs
├── game.rs ──→ world.rs
│ ├→ player.rs
│ ├→ encounter.rs
│ └→ audio.rs
└── ui.rs ───→ game.rs (reads state)
├→ world.rs (reads map)
└→ player.rs (reads stats)
Design Principles
- Renderer isolation
-
ui.rsonly reads game state via&Game. Game logic never calls rendering functions. This separation enables swapping the terminal renderer for a graphical one (Bevy, wgpu) without touching game logic. - Event-driven audio
-
Sound effects are triggered by
SoundEventenum variants. TheAudioEngineis optional (Option<AudioEngine>) — the game runs silently if no audio hardware is available. - Content separation
-
All educational content lives in
encounter.rsas data. The challenge format is extensible — add aChallengestruct to a floor function to add content. Future: load from YAML/JSON for hot-reload. - Procedural generation
-
BSP (Binary Space Partitioning) produces unique dungeon layouts every run. Features (terminals, traps, chests, locked doors) are placed probabilistically per floor.
File Sizes
| File | Lines | Responsibility |
|---|---|---|
main.rs |
47 |
Terminal setup, game loop |
game.rs |
497 |
State machine, input, game logic |
world.rs |
500 |
BSP dungeon gen, tiles, FOV |
player.rs |
112 |
Player state, inventory, items |
encounter.rs |
2,813 |
107 challenges, answer checking |
audio.rs |
218 |
Synthesized sound via rodio |
ui.rs |
1,305 |
ratatui rendering, minimap, animations |
Scale Path
| Layer | Current | Future |
|---|---|---|
Renderer |
ratatui (terminal) |
Bevy 2D/3D or wgpu |
Input |
crossterm keys |
Gamepad, mouse, touch |
Audio |
Sine wave synthesis |
Asset pipeline (OGG/WAV) |
Content |
Hardcoded Rust |
YAML/JSON hot-load |
World |
Single-player local |
Networked multiplayer |
State |
In-memory only |
Save/load (serde + JSON) |