You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Defines a D&D-style combat loop including initiative, turn order, attack resolution, damage calculation, and combat end conditions. Integrates with the Enemy/Encounter system (spec #19) and Dice Engine (spec #16), while preserving Human DM authority to pause combat, adjust HP, skip turns, or end encounters early.
Why it's needed
Combat is a core pillar of gameplay. This spec provides deterministic, testable combat mechanics that can be executed by the bot while keeping DM control and auditability.
Out of scope
Spellcasting rules and spell slot mechanics (future spec)
Advanced action economy (bonus actions, reactions) beyond a single action per turn
Test Scenarios (Danny)⚠️ COMPLETE BEFORE IMPLEMENTATION
Happy path
Given an active encounter with two PCs and two enemies When/combat start executes Then initiative is rolled, turn order is persisted, and combat status is Active
Given a player’s turn When they execute /combat attack Then a d20 roll determines hit/miss and damage is applied
Edge cases
Given two combatants tie on initiative When combat starts Then ties are resolved deterministically (higher Dexterity, then stable ordering)
Given a combatant is stunned When their turn begins Then the system skips their action and advances the turn
Error / failure cases
Given a player tries to attack out of turn When/combat attack runs Then the bot rejects the action with an error message
Given the encounter already ended When/combat start runs Then the API returns 409 Conflict
Acceptance Criteria
Functional
Initiative order is rolled using IDiceEngine and persisted
Combat turn order advances deterministically and enforces active turn rules
Attack rolls apply d20 + modifiers and determine hit/miss
Damage rolls reduce HP and mark defeated combatants
Status effects apply and expire by duration
Human DM can pause, skip turns, adjust HP, and end combat early
Feature Spec: Battle System (Initiative, Combat, Resolution)
Overview
What it does
Defines a D&D-style combat loop including initiative, turn order, attack resolution, damage calculation, and combat end conditions. Integrates with the Enemy/Encounter system (spec #19) and Dice Engine (spec #16), while preserving Human DM authority to pause combat, adjust HP, skip turns, or end encounters early.
Why it's needed
Combat is a core pillar of gameplay. This spec provides deterministic, testable combat mechanics that can be executed by the bot while keeping DM control and auditability.
Out of scope
Architecture Notes (The Doctor)
Projects / layers touched
DungeonMaster.Core— combat entities, services, status effectsDungeonMaster.Infrastructure— EF Core mappings, repositoriesDungeonMaster.Api— combat endpointsDungeonMaster.Bot—/combatcommand suiteDungeonMaster.Shared— DTOs for combat stateNew interfaces in
DungeonMaster.CoreICombatService— combat lifecycle, turn execution, damage applicationIInitiativeService— initiative rolls usingIDiceEngineIStatusEffectService— apply/expire status effectsData flow
Integration points with existing systems
Domain Model
Entities
CombatStateEncounterId(Guid FK)Status(CombatStatus enum)RoundNumber(int, starts at 1)ActiveTurnIndex(int)StartedAt(DateTimeOffset)EndedAt(DateTimeOffset?)InitiativeOrder(ICollection)InitiativeEntryCombatStateId(Guid FK)CombatantId(Guid) — PlayerCharacterId or EncounterEnemyIdCombatantType(CombatantType enum)InitiativeRoll(int)OrderIndex(int)CombatantStateCombatStateId(Guid FK)CombatantId(Guid)CombatantType(CombatantType enum)CurrentHitPoints(int)ArmorClass(int)IsDefeated(bool)StatusEffectCombatantStateId(Guid FK)Type(StatusEffectType enum)AppliedAtRound(int)DurationRounds(int)Enums
CombatStatusActivePausedCompletedFledCombatantTypePlayerCharacterEnemyCompanionStatusEffectTypeStunnedPoisonedProneBleedingCharmedRecords
Service Interfaces (CQRS)
API Contract (Rory)
Endpoints
POST /api/encounters/{id}/combat/start— start combat, returnsCombatStateGET /api/encounters/{id}/combat— get current combat statePOST /api/encounters/{id}/combat/player-attack— resolve a player attackPOST /api/encounters/{id}/combat/enemy-attack— resolve an enemy attackPOST /api/encounters/{id}/combat/advance— advance turn (DM only)POST /api/encounters/{id}/combat/adjust-hp— DM override HP changesPOST /api/encounters/{id}/combat/end— end combat (Completed/Fled)Notes
CombatStateper encounter.Discord Commands (Rory — Bot Layer)
/combat start— starts combat for the active encounter/combat status— shows turn order and active combatant/combat attack {target}— player attack command (requires active turn)/combat skip-turn— DM-only command/combat set-hp {target} {delta}— DM-only override/combat end— DM-only end combatTest Scenarios (Danny)⚠️ COMPLETE BEFORE IMPLEMENTATION
Happy path
Given an active encounter with two PCs and two enemies
When
/combat startexecutesThen initiative is rolled, turn order is persisted, and combat status is Active
Given a player’s turn
When they execute
/combat attackThen a d20 roll determines hit/miss and damage is applied
Edge cases
Given two combatants tie on initiative
When combat starts
Then ties are resolved deterministically (higher Dexterity, then stable ordering)
Given a combatant is stunned
When their turn begins
Then the system skips their action and advances the turn
Error / failure cases
Given a player tries to attack out of turn
When
/combat attackrunsThen the bot rejects the action with an error message
Given the encounter already ended
When
/combat startrunsThen the API returns
409 ConflictAcceptance Criteria
Functional
IDiceEngineand persistedNon-functional
Dependencies
Agent Work Breakdown
Definition of Done