DungeonSpire is a terminal-based, single-player dungeon crawler implemented in C++. The game features an endless tower structure with procedurally generated floors, turn-based combat, and modular gameplay extensions (dynamic weather + side-quest engine).
- Endless Tower Progression — procedural rooms, potions, enemies and loot per floor.
- Race-Based Playstyles — pick a race with unique base stats and passive effects.
- Turn-Based Mechanics — deterministic per-command state updates.
- Potion System — hidden effects until first use; some races see special interactions.
- Combat Engine — dynamic enemy AI, factional hostility, damage calculation.
- Gold & Loot System — diverse treasure types, faction-specific gold modifiers.
- Dynamic Weather (optional) — environmental effects on visibility and movement.
- Quest System (optional) — side quests with rewards and objective tracking.
- A C++20-capable compiler (
g++≥ 10 orclang++≥ 12) - GNU
make
Two equivalent options — pick whichever fits your workflow:
# Option A: classic Makefile
git clone https://github.com/faketut/DungeonSpire.git
cd DungeonSpire/src && make
# Option B: CMake (out-of-tree; required for sanitizers + coverage)
git clone https://github.com/faketut/DungeonSpire.git
cd DungeonSpire
cmake -S . -B build && cmake --build build -j
# Optional toggles: -DENABLE_ASAN=ON -DENABLE_UBSAN=ON -DENABLE_COVERAGE=ON./cc3k [--enableWeather] [--enableQuest] [--file <path>] [--seed <n>]
[--save <path>] [--load <path>]| Flag | Description |
|---|---|
--enableWeather |
Enable the dynamic weather system |
--enableQuest |
Enable the side-quest system |
--file <path> |
Load a specific floor layout from file |
--seed <n> |
Seed the PRNG for reproducible runs |
--save <path> |
Write a JSON save file on clean quit (q) |
--load <path> |
Resume from a JSON save file at startup; loaded settings (seed, file, weather, quest) override the corresponding CLI flags |
Unit tests use doctest (vendored, single header).
cd tests
make runCI runs seven jobs on every push: build-and-test under both g++ and clang++, a CMake build, an ASan+UBSan sanitizer run, clang-tidy, cppcheck, and a coverage upload — see .github/workflows/ci.yml.
src/ Game source (Board.cc split into Board{Combat,Enemies,Load,Player}.cc + Game, Player, Enemy, Item, AnsiRenderer, ...)
src/third_party/ Vendored single-header libraries (nlohmann/json)
tests/ doctest-based unit tests
tests/third_party/ Vendored doctest single header
data/ Data-driven configs (enemies.json, items.json, races.json, floor.json)
files/ Hand-authored floor layouts
design/ Original design docs, UML, plans (historical)
Key modules:
- src/Board.h +
src/Board*.cc— map, enemies, combat dispatch - src/Game.h / src/Game.cc — main loop, command parsing, save/load orchestration
- src/Player.h, src/Enemy.h, src/Item.h — entity hierarchy
- src/EffectManager.h, src/QuestManager.h — Meyers singleton managers
- src/EventBus.h — header-only type-erased pub/sub; publishers wired for
FloorChanged,EnemyDied,ItemPickedUp - src/Renderer.h / src/AnsiRenderer.h —
IRendererabstraction + default ANSI terminal renderer - src/EnemyStats.h, src/ItemStats.h, src/RaceStats.h, src/FloorStats.h — stat registries overridable via the matching JSON in data/
- src/SaveGame.h / src/SaveGame.cc — JSON v1 save format
- src/PRNG.h — seedable
std::mt19937wrapper
- Builds under
-Wall -Wextra -Wsuggest-override -Werror=vlaand is clean under ASan + UBSan. - Code style: see .clang-format. Run
clang-format -i src/*.{h,cc}before submitting changes. - Editor settings: see .editorconfig.
MIT — see LICENSE.
@faketut. PRs welcome.

