-
-
Notifications
You must be signed in to change notification settings - Fork 4
Architecture
Developer onboarding guide for the Firestaff codebase.
Firestaff is a pure C application (no C++) that reimplements five Dungeon Master game engines with source-level fidelity to the originals. It builds with CMake and Ninja, renders via SDL3, and runs on macOS, Windows, Linux, and Steam Deck.
Codebase scale: 1,190,000+ lines of C across 2,425 source files, 2,379 headers, and 2,919 test files containing 3,673 tests.
Firestaff is organized into three major layers:
M10 owns all game state and mechanics. It is the engine core shared across presentation modes:
- Party state (champions, inventory, stats, position).
- Dungeon state (maps, things, doors, actuators, sensors).
- Combat resolution and damage calculation.
- Creature AI and movement.
- Projectile tracking.
- Item interactions and thing-list management.
- Save/load serialization.
M10 is game-specific: DM1/CSB share one M10 path (from ReDMCSB), DM2 has its own (from skproject), and Nexus/Theron have independent M10 implementations.
M11 is the Original (faithful) rendering path. It reproduces the exact visual output of the original game:
-
m11_game_view.c(~50,000 lines): the monolithic game view that drives viewport rendering, HUD drawing, menu display, and input dispatch. -
M11_GameViewState: the central state struct (~1,570 lines ininclude/m11_game_view.h) containing world state, party, dungeon, audio, viewport, HUD, DM2, and presentation state. - Viewport rendering follows the original draw order and clipping rules.
- Wall ornaments, floor ornaments, creatures, and items are drawn at original pixel positions.
M12 adds modern rendering features on top of the proven M11/M10 engine:
- Camera system with smooth movement and rotation.
- Resolution-independent scaling.
- Fullscreen and windowed modes.
- Enhanced lighting (DM2).
- Controller and touch input mapping.
M12 consumes M10 state but does not modify game logic. The Original engine must be proven correct before Custom features are built on top.
src/
engine/ M11 game view (m11_game_view.c and supporting modules)
csb/ CSB-specific: viewport, boot, runtime, DSA
dm1/ DM1-specific: viewport 3D, music, movement, ornaments
dm1v2/ DM1 Custom presentation (camera, modern rendering)
dm2/ DM2 runtime (boot, CCM, combat, GDAT, champions)
shared/ Cross-game: audio (SDL3), rendering, main entry point
memory/ Dungeon data decoding, save/load, combat serialization
frontend/ UI frontend, dialog, text rendering
audio/ Audio decoding (SND, SONG.DAT, HMP)
include/ All public headers (~2,379 files)
tests/ Test sources (~2,919 files)
parity-evidence/ Source-lock evidence documents (960+ files)
Firestaff uses CMake with Ninja as the preferred generator:
cmake -S . -B build -DCMAKE_C_COMPILER=cc -G Ninja
ninja -C buildKey build system details:
- Single
CMakeLists.txtwith the project version at line ~3505. - Pure C with
LANGUAGES Cenforced -- no C++ compilation. - Compiler: system
cc(Clang on macOS, GCC on Linux). Do not usegcc. - SDL3 is the only external dependency.
- Tests are registered with CTest and can be run in parallel.
-
Create a test source file in
tests/:tests/test_{module_name}.c -
Write the test using the project's test patterns. Tests are standalone C programs that return 0 on success and nonzero on failure.
-
Register the test in
CMakeLists.txtusingadd_test(). Follow the existing patterns near where similar tests are registered. -
Build and run:
ninja -C build ctest --test-dir build -R "test_{module_name}" --output-on-failure
Probes are targeted test programs that verify specific engine behaviors against known-good outputs. They are registered as CTest tests with descriptive names:
# Run all probes for a specific game
ctest --test-dir build -R "dm1" -j4 --output-on-failure
# Run a specific probe
ctest --test-dir build -R "viewport_wall_ornament" --output-on-failureSome probes require original game data files to be present under
~/.firestaff/data/. Probes that need game data will fail or time out
without it.
Parity evidence is the project's verification system. Each piece of evidence documents that a specific Firestaff behavior matches the original game:
- Evidence files live in
parity-evidence/with names likepass{NNN}_{description}.md. - Each document records what was tested, how it was verified, and what the expected behavior is.
- There are 960+ parity-evidence documents covering DM1, CSB, DM2, Nexus, and Theron's Quest.
- Evidence is cumulative: once a behavior is source-locked, it stays locked and regression tests prevent it from breaking.
A feature is considered "source-locked" when it has both:
- A passing test that verifies the behavior.
- A parity-evidence document that records the verification.
| Pattern | Example | Use |
|---|---|---|
dm1_v1_{feature}_pc34_compat.h |
dm1_v1_random_ornament_pc34_compat.h |
DM1 PC 3.4 headers |
dm1_v1_{feature}_pc34_compat.c |
dm1_v1_random_ornament_pc34_compat.c |
DM1 PC 3.4 sources |
csb_v1_{feature}_pc34_compat.{h,c} |
csb_v1_viewport_pc34_compat.c |
CSB modules |
dm2_v1_{feature}.c |
dm2_v1_boot.c |
DM2 modules |
F0NNN_Name_Compat() |
F0170_Random_Ornament_Compat() |
ReDMCSB function names |
test_{module}.c |
test_dm1_viewport.c |
Test files |
pass{NNN}_{desc}.md |
pass216_nexus_saturn_hardware_evidence.md |
Evidence docs |
| Game | Reference | Identifier style |
|---|---|---|
| DM1 | ReDMCSB |
F0NNN_Name, ReDMCSB FILENAME.C:LINE
|
| CSB | ReDMCSB | Same as DM1 |
| DM2 | skproject | skproject function/variable names |
| Nexus | None | Firestaff-native identifiers |
| Theron | None | Firestaff-native identifiers |