Skip to content

demo-dnd: Product Brief

Status: approved (W-003).

Target app: apps/demo-dnd. Refs: concept §8.

1. Vision

Player leads a fixed party (Fighter, Rogue, Wizard) through one turn-based, D&D-style skirmish on a grid against a pack of monsters, moving and acting with each hero and watching initiative, dice, crits, and poison play out in a 2–5 minute fight.

2. Audience and purpose

  • Audience: developers learning ECS / flecs concepts on koota. The demo must still be a fun 2–5 minute fight on its own.
  • Teaches: traits and tags, pairs with data (HasEffect(Poisoned) with a duration), observers, Added/Removed change detection, systems ordered in turn phases (ecs-schedule), monster templates as prefabs (ecs-prefab), and live world inspection (ecs-devtools).

3. Core loop

  1. User sees the grid, the initiative order, and whose turn it is.
  2. On a hero's turn, player moves the hero on the grid, then picks an action and a target in reach.
  3. The action resolves with visible dice (advantage, crits); damage and Poisoned apply.
  4. Monsters take their turns automatically, closing in on the weakest hero.
  5. Poisoned ticks down at turn boundaries; defeated combatants leave the order.
  6. Repeat until one side is defeated, then restart.

4. ECS showcase

flecs concept Shown by Package
Entities, components, tags Combatants with Health, ArmorClass, Initiative, Position; Hero / Monster / Defeated tags (DND-F01, DND-F02) koota
Queries Monster AI finds the living hero with the lowest HP (DND-F04) koota
Pipeline phases, ordered systems, manual stepping Turn pipeline: start of turn → move → act → resolve → end of turn, stepped per turn (DND-F02, DND-F05) ecs-schedule
Prefabs and IsA Monsters spawned from templates (DND-F01); template variants (DND-F09) ecs-prefab
Pairs with data HasEffect(Poisoned) with remaining duration (DND-F05) koota
Observers Combat log entries and defeat handling on trait add/remove (DND-F02, DND-F03) koota
Added / Removed queries UI highlights new effects and newly defeated combatants (DND-F02, DND-F05) koota
Explorer-style inspection Live entity/trait panel (DND-F10) ecs-devtools
Serialization Save and resume a fight (DND-F08) ecs-serialize

5. Backlog

ID Feature Milestone Work
DND-F01 User sees Fighter, Rogue, and Wizard vs. 3–4 template monsters (e.g. Goblin, Orc) on a grid, and player can move the active hero up to its speed M1
DND-F02 User sees the initiative order and the active combatant; turns advance round after round, defeated combatants drop out, and the user sees victory or defeat and can restart M1
DND-F03 Player can make the active hero attack a monster in reach (melee: adjacent; Wizard: ranged) and sees the d20 + bonus vs. AC roll, advantage, crits, and damage in a combat log; attacks against a Poisoned target roll with advantage M1
DND-F04 Monsters take their turn automatically: move toward and attack the living hero with the lowest HP M1
DND-F05 Player can use the Rogue's poison ability to apply Poisoned (damage per turn for N turns) and sees it tick and expire; while Poisoned, attacks against the target have advantage M1
DND-F06 Defeated combatants drop out of the order; user sees victory or defeat and can restart the encounter Merged into DND-F02 to keep M1 at 6 features. –
DND-F07 Player can control the whole fight from the keyboard with on-screen key hints M2
DND-F08 Player can save a fight in progress and resume it after reload M2
DND-F09 User meets monster variants that build on a base template (e.g. Goblin Boss from Goblin) M2
DND-F10 User can open a devtools panel listing entities, traits, and effects live M1
DND-F11 Player can pick the party and the encounter from a list in content data M2
DND-F12 Player can move combatants on a grid, with range and adjacency rules Moved to M1 and merged into DND-F01 (movement) and DND-F03 (reach). –
DND-F13 Player can cast spells with multiple effects and areas later
DND-F14 Player can fight with terrain, cover, and opportunity attacks on the grid later

M1 order: DND-F01, DND-F02, DND-F03, DND-F04, DND-F05, DND-F10.

Notes: - Every core-loop action in M1, including grid movement, must already be keyboard-reachable (demo rule); DND-F07 adds hints and polish. - Dependency/risk (DND-F10): needs an ecs-devtools v0 implementation. Only its spec (W-006) is on the board, and concept §6 has ecs-devtools build on ecs-serialize. DND-F10 is last in M1 so the core loop is playable without it; the v0 scope should be an entity/trait list that does not need ecs-serialize.

6. Non-functional targets

  • Performance: under 50 combatant entities on a grid of at most 12×12; UI stays at 60 FPS with the devtools panel open; a full turn resolves in under one frame of logic.
  • Accessibility: all actions, including grid movement and targeting, keyboard-reachable; WCAG AA contrast; status, dice, advantage, and crit results shown as text, not color alone; grid cells have text labels for occupants.
  • Persistence: M1 none. M2 saves the full encounter (combatants, HP, effects with remaining duration, initiative position, round) via ecs-serialize.

7. Path to a real app

  • Rules data (stats, speed, reach, abilities, effects, monster templates, map size) lives in src/content/ and can be swapped for SRD-style data files.
  • Dice and RNG behind one seam, so fights can be seeded and replayed.
  • Turn pipeline as ecs-schedule phases, so new phases (reactions, movement) slot in without rewriting systems.
  • Monster AI behind one decision function per monster (M1: lowest-HP hero), replaceable later.
  • World state serializable, leaving room for networked or async multiplayer.

8. Out of scope

  • Terrain, cover, line of sight, and opportunity attacks in M1 (see DND-F14).
  • Party selection and character creation, leveling, inventory, and campaigns. The M1 party is fixed.
  • Status effects other than Poisoned in M1.
  • Full D&D 5e rules fidelity; only d20 + bonus vs. armor class, with advantage and crits (natural 20 hits and doubles damage dice; natural 1 misses).
  • 3D rendering (R3F); plain 2D UI only.
  • Multiplayer and networking.