2.6 KiB
2.6 KiB
Data Model: Set Initiative
Entity Changes
Combatant (modified)
| Field | Type | Required | Description |
|---|---|---|---|
| id | CombatantId (branded string) | Yes | Unique identifier |
| name | string | Yes | Display name (non-empty, trimmed) |
| initiative | integer | No | Initiative value for turn ordering. Unset means "not yet rolled." |
Validation rules:
initiativemust be an integer when set (no floats, NaN, or Infinity)- Zero and negative integers are valid
- Unset (
undefined) is valid — combatant has not rolled initiative yet
Encounter (unchanged structure, new ordering behavior)
| Field | Type | Required | Description |
|---|---|---|---|
| combatants | readonly Combatant[] | Yes | Ordered list. Now sorted by initiative descending (unset last, stable sort for ties). |
| activeIndex | number | Yes | Index of the active combatant. Adjusted to follow the active combatant's identity through reorders. |
| roundNumber | number | Yes | Current round (≥ 1). Unchanged by initiative operations. |
Ordering invariant: After any setInitiative call, combatants is sorted such that:
- Combatants with initiative come first, ordered highest to lowest
- Combatants without initiative come last
- Ties within each group preserve relative insertion order (stable sort)
New Domain Event
InitiativeSet
Emitted when a combatant's initiative value is set, changed, or cleared.
| Field | Type | Description |
|---|---|---|
| type | "InitiativeSet" | Event discriminant |
| combatantId | CombatantId | The combatant whose initiative changed |
| previousValue | integer or undefined | The initiative value before the change |
| newValue | integer or undefined | The initiative value after the change |
State Transitions
setInitiative(encounter, combatantId, value)
Input: Current encounter, target combatant id, new initiative value (integer or undefined to clear)
Output: Updated encounter with reordered combatants and adjusted activeIndex, plus events
Error conditions:
combatant-not-found: No combatant with the given id exists in the encounterinvalid-initiative: Value is not an integer (when defined)
Transition logic:
- Find target combatant by id → error if not found
- Validate value is integer (when defined) → error if invalid
- Record the active combatant's id (for preservation)
- Update the target combatant's initiative value
- Stable-sort combatants: initiative descending, unset last
- Find the active combatant's new index in the sorted array
- Return new encounter +
InitiativeSetevent