# Godot Turn System

> Expert blueprint for turn-based combat with turn order, action points, phase management, and timeline systems for strategy/RPG games. Covers speed-based initiative, interrupts, and simultaneous turns. Use when implementing turn-based combat OR tactical systems. Keywords turn-based, initiative, action points, phase, round, turn order, combat.

- Skill: `gabrielmoreira/godot-turn-system` (Agent Skill, multi-file: 8 files)
- Install (CLI): `npx skillmds@latest add gabrielmoreira/godot-turn-system`
- Raw SKILL.md: https://api.skillmd.com/api/skills/gabrielmoreira/godot-turn-system/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: gabrielmoreira (https://skillmd.com/u/gabrielmoreira)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/gabrielmoreira/godot-turn-system

---


## 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 use **`call_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 applying `current_ap -= cost` to 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 `>=` or `is_equal_approx()` for robust comparisons.

### Tactical Grid & UI
- NEVER use generic `AStar2D` for tile grids; strictly use **`AStarGrid2D`** for 10x faster pathfinding and native diagonal handling.
- NEVER forget to call **`update()`** on `AStarGrid2D` after changing obstacle states; if you toggle `set_point_solid()`, the grid MUST refresh before the next query.
- NEVER lock the main thread with `while` loops for input; strictly use the **await keyword** or signals to yield execution back to the Tree.
- NEVER handle turn decisions with `is_action_pressed()`; strictly use `is_action_just_pressed()` for discrete, frame-locked menu input.
- NEVER skip turn timeouts in networked games; strictly implement a **server-side timer** with a default "pass" action to prevent griefing. See **Networked Turn Timeout** golden path below.

---

## Decision Tree — Pick a Turn Model

| Need | Choose | **MANDATORY** script |
|------|--------|----------------------|
| Discrete rounds (chess / tactics / card phases) | Round + initiative queue + AP phases | [turn_system_patterns.gd](scripts/turn_system_patterns.gd) |
| Continuous gauges (FF-style ATB) | Per-actor gauge fill in `_process` | [active_time_battle.gd](scripts/active_time_battle.gd) |
| Timeline / CTB with interrupts & prediction | Event timeline + predictive UI | [timeline_turn_manager.gd](scripts/timeline_turn_manager.gd) |

> **Do NOT** invent a fourth model inline. Read the matching script before coding.

## Expert Components (scripts/)

- [turn_system_patterns.gd](scripts/turn_system_patterns.gd) — Match-based phase machines, UndoRedo, `AStarGrid2D` board helpers.
- [active_time_battle.gd](scripts/active_time_battle.gd) — ATB gauges, pause-on-ready, async action handoff.
- [timeline_turn_manager.gd](scripts/timeline_turn_manager.gd) — Timeline / CTB with interrupts and pre-visualization.
- [turn_predictor.gd](scripts/turn_predictor.gd) — Simulate ATB gauges for timeline UI preview.
- [combat_stats_resource.gd](scripts/combat_stats_resource.gd) — Deterministic damage preview Resource for hover UI.

## TurnManager Autoload — Interface Contract Only

Keep the Autoload thin. **Do not** paste full queue math here — implement in the script chosen above.

```gdscript
# turn_manager.gd (AutoLoad) — contract only
extends Node
signal turn_started(combatant: Node)
signal turn_ended(combatant: Node)
signal round_ended
signal turn_timed_out(combatant: Node)  # multiplayer: server default-pass

func start_combat(participants: Array[Node]) -> void: pass
func end_turn() -> void: pass
func request_pass(combatant: Node) -> void: pass  # default action on timeout
```

## Networked Turn Timeout (Golden Path)

Referenced from NEVER: server owns the clock; clients never decide "pass."

1. On `turn_started`, server starts a one-shot `Timer` / `SceneTreeTimer` (authoritative).
2. On timeout: server calls `request_pass(current)` (or auto-end-turn), then emits `turn_timed_out`.
3. Clients only render the countdown; never mutate the turn queue locally.
4. Pair with [godot-multiplayer-networking](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-multiplayer-networking/SKILL.md) for host-auth RPC.

## Action Points (Contract)

```gdscript
func can_perform_action(cost: int) -> bool:
    return current_action_points >= cost

func perform_action(cost: int) -> bool:
    if not can_perform_action(cost):
        return false
    current_action_points -= cost
    return true
```

Phases: prefer `enum Phase { DRAW, MAIN, END }` + `match`, or route to [godot-state-machine-advanced](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-state-machine-advanced/SKILL.md). Full ATB / timeline math lives in the MANDATORY scripts — do not duplicate Elite snippets here.

## Deep recipes (on demand)

> LLM-ignorance rule: if a general agent would not know it before reading, it lives here or in `scripts/` — never delete, only move.

| Topic | Reference |
|-------|-----------|
| ATB / prediction / previews | [elite-turn-patterns.md](references/elite-turn-patterns.md) |

## Reference

> Progressive disclosure: open Official Documentation links only when researching a specific API;
> load Related Skills when routing work to a peer domain — do not preload the whole lattice.

### Official Documentation
- [Idle and Physics Processing](https://docs.godotengine.org/en/stable/tutorials/scripting/idle_and_physics_processing.html) — When turn ticks belong in `_process` vs `_physics_process` vs pure event steps.
- [Using signals](https://docs.godotengine.org/en/stable/getting_started/step_by_step/signals.html) — Turn-start / turn-end / unit-acted events without polling gauges.
- [Resources](https://docs.godotengine.org/en/stable/tutorials/scripting/resources.html) — Initiative/speed stats as Resources for sim and UI prediction.
- [Singletons (Autoload)](https://docs.godotengine.org/en/stable/tutorials/scripting/singletons_autoload.html) — TurnManager ownership boundaries.
- [GDScript basics](https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_basics.html) — `await` sequencing for multi-phase turns.
- [Object](https://docs.godotengine.org/en/stable/classes/class_object.html) — Signal connect flags for turn bus listeners.
- [SceneTree](https://docs.godotengine.org/en/stable/classes/class_scenetree.html) — Pausing gameplay while menus resolve turn choices.
- [Timer](https://docs.godotengine.org/en/stable/classes/class_timer.html) — Optional realtime turn clocks without busy loops.
- [Tween](https://docs.godotengine.org/en/stable/classes/class_tween.html) — Animating ATB gauges and turn handoff juice.
- [AnimationPlayer](https://docs.godotengine.org/en/stable/classes/class_animationplayer.html) — Action animations that must finish before the next turn.
- [MultiplayerAPI](https://docs.godotengine.org/en/stable/classes/class_multiplayerapi.html) — Authoritative turn order in networked matches.
- [JSON](https://docs.godotengine.org/en/stable/classes/class_json.html) — Deterministic turn replay / seed logs for balance labs.

### Related Skills

#### Prerequisites
- [godot-project-foundations](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-project-foundations/SKILL.md) — Scene and Autoload placement for TurnManager.
- [godot-signal-architecture](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-signal-architecture/SKILL.md) — Turn bus contracts (signals up, commands down).
- [godot-resource-data-patterns](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-resource-data-patterns/SKILL.md) — Speed/initiative Resources shared with combat/UI.
- [godot-autoload-architecture](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-autoload-architecture/SKILL.md) — Lifecycle of a global turn orchestrator.

#### Complements
- [godot-state-machine-advanced](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-state-machine-advanced/SKILL.md) — Per-unit states nested under turn phases.
- [godot-combat-system](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-combat-system/SKILL.md) — Actions resolved inside a granted turn.
- [godot-rpg-stats](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-rpg-stats/SKILL.md) — Speed/AGI feeding ATB gauges.
- [godot-ability-system](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-ability-system/SKILL.md) — Cooldowns measured in turns, not wall-clock only.
- [godot-tweening](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-tweening/SKILL.md) — Gauge fill and handoff presentation.
- [godot-multiplayer-networking](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-multiplayer-networking/SKILL.md) — Host-auth turn order and lockstep.

#### Downstream / consumers
- [godot-genre-action-rpg](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-genre-action-rpg/SKILL.md) — ATB/turn hybrids in ARPG/JRPG-adjacent combat.
- [godot-genre-card-game](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-genre-card-game/SKILL.md) — Card turns and priority windows.
- [godot-genre-rts](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-genre-rts/SKILL.md) — Discrete orders in strategy loops.
- [godot-monte-carlo-balancer](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-monte-carlo-balancer/SKILL.md) — Simulate turn matrices for speed/action fairness.

#### Master
- [godot-master](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-master/SKILL.md) — Library router and mirrored module entry for turn systems.

