Files
initiative/specs/026-roll-initiative/data-model.md

69 lines
2.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Data Model: Roll Initiative
## Existing Entities (no changes)
### Combatant
| Field | Type | Notes |
|-------|------|-------|
| id | CombatantId | Branded string identifier |
| name | string | Display name |
| initiative | number \| undefined | The initiative value (set by manual input OR roll) |
| creatureId | CreatureId \| undefined | Link to bestiary creature — presence determines roll eligibility |
| maxHp | number \| undefined | From bestiary or manual |
| currentHp | number \| undefined | Current hit points |
| ac | number \| undefined | Armor class |
| conditions | ConditionId[] | Active conditions |
| isConcentrating | boolean | Concentration flag |
### Creature (from bestiary)
| Field | Type | Notes |
|-------|------|-------|
| id | CreatureId | Branded string identifier |
| dexScore | number | Dexterity ability score (used for initiative modifier) |
| cr | string | Challenge rating (determines proficiency bonus) |
| initiativeProficiency | number | 0 = none, 1 = proficiency, 2 = expertise |
### Initiative Modifier (derived, not stored)
Calculated on demand via `calculateInitiative(creature)`:
- `modifier = Math.floor((dexScore - 10) / 2) + (initiativeProficiency × proficiencyBonus(cr))`
- `passive = 10 + modifier`
## New Concepts (no new stored entities)
### Roll Result (transient)
Not persisted — computed at the adapter boundary and immediately applied:
- `diceRoll`: integer 120 (generated via Math.random at adapter layer)
- `initiativeValue = diceRoll + modifier` (computed by domain function, stored as combatant's `initiative`)
## State Transitions
### Single Roll
```
Combatant(initiative: any | undefined)
→ rollInitiative(diceRoll, modifier)
→ Combatant(initiative: diceRoll + modifier)
→ encounter re-sorted by initiative descending
```
### Batch Roll
```
Encounter(combatants: [...])
→ for each combatant with creatureId:
→ rollInitiative(diceRoll_i, modifier_i)
→ setInitiative(encounter, id, value)
→ single save with final sorted state
```
## Validation Rules
- `diceRoll` must be an integer in range [1, 20]
- `modifier` is any integer (can be negative)
- Final `initiative` value is any integer (can be negative, e.g., 1 + (3) = 2)
- Only combatants with a non-undefined `creatureId` are eligible for rolling