# Initiative Ordering — Design ## Core Principle **Slot, never sort.** Initiative order = a single list. Participants occupy slots determined by initiative value. The list is mutated by insert/move operations — never re-sorted wholesale. ## Single Source of Truth One list: `participants[]`. - Display order = `participants[]` order (both Player view + DM view). - Turn order = `participants[]` order. - No derived/re-sorted copy. `turnOrderIds`, if present, is always an exact mirror (`participants.map(p => p.id)`) — never an independent ordering. ## When Ordering Changes | Action | Effect on order | |--------|-----------------| | **Add** (roll or manual) | Insert participant into slot by initiative | | **Edit initiative** | Move participant to new slot | | **Drag** | Reorder within a tie (same initiative) only | | **Remove** | Splice out; others keep position | | **Start encounter** | Freeze current list. No re-sort. | | **Round wrap** | No rebuild. Continue rotation through existing list. | | **Damage/heal/death/save** | No order change. | | **Toggle active** | No position change. Does **not** advance current turn. Skip on next explicit turn advance only. | ## Slotting Rules - Insert/move positions participants so the list stays initiative-descending. - **Tie-break = original add order.** Later additions slot *after* existing same-init participants. Stable insertion. - Tie order is only changed by explicit DM drag. Never auto-changed. ## Drag (DM Tie-Break Override) - Only participants with the **same initiative** are draggable onto each other. - Cross-initiative drag is **not allowed**. (Use edit-initiative field instead.) - Drag persists in `participants[]`. Survives all subsequent operations. - **Re-slotting on add/edit must preserve drag-established tie order.** ## Toggle Active Semantics Toggle active is a roster/status edit, not a turn action. - Deactivating the current participant leaves `currentTurnParticipantId` unchanged. - Deactivating the current participant does **not** increment `round`. - DM must click Next Turn to pass turn after deactivating current. - Next Turn skips inactive participants during rotation. - Reactivating a participant restores them to rotation at their existing slot. - Toggle active never changes participant position or tie order. Reason: auto-advancing from toggle active makes a status edit count like a turn pass, can wrap the round accidentally, and causes double-act/skip drift. ## Explicitly Forbidden - `sort()` on every mutation. Overwrites drag order. Root cause of past drift. - Separate display order vs turn order. Causes player/DM divergence. - Re-sort on round wrap. Replays rounds, introduces skips. - Cross-initiative drag. Contradicts initiative as the primary key. - Auto-changing tie order on add/edit. Silently loses DM intent. ## Why Sorting is destructive to manual ordering. A stable slot list with drag for ties gives deterministic, DM-controllable order that never drifts between display surfaces or combat rounds.