godot-turn-system
Turn System
Turn order calculation, action points, phase management, and timeline systems define turn-based combat.
NEVER Do (Expert Anti-Patterns)
Order & Determinism
-
NEVER recalculate turn order every action; strictly sort once per round or ONLY when a speed-relevant stat changes to prevent O(n log n) lag.
-
NEVER use random tie-breaking for initiative; strictly use a secondary static attribute (Agility, ID, or persistent "luck") for deterministic replays.
-
NEVER modify an active turn-order queue while iterating it; strictly iterate over a
duplicate()or apply queue modifications after the loop. -
NEVER broadcast global turn state changes using immediate
call_group(); strictly usecall_group_flags(SceneTree.GROUP_CALL_DEFERRED, ...)to prevent frame spikes when notifying hundreds of units. -
NEVER rely on the Node hierarchy as the source of truth; strictly use a Dictionary board state for logical grid coordinates.
Logic & Action Economy
- NEVER deduct Action Points (AP) before validation; strictly call
can_perform_action(cost)before applyingcurrent_ap -= costto prevent exploits. - NEVER hardcode phase transitions (
if phase == 0); strictly use an enum + match or a dedicated State Machine for Draw/Main/End phases. - NEVER emit "Turn Ended" before internal cleanup; strictly reset AP and tick status effects BEFORE signaling the next turn.
- NEVER use exact floating-point equality (
==) for AP checks; strictly use>=oris_equal_approx()for robust comparisons.