---
description: Combat integration - wiring TurnSystem and MovementSystem into the GameLoop
globs: src/core/GameLoop.js, src/core/GameLoop.ts
alwaysApply: false
---

# **Combat Integration Rule**

This rule defines how the TurnSystem and MovementSystem integrate into the existing GameLoop.

## **1. System Ownership**

The GameLoop is the central owner of these systems. It ensures they share the same source of truth (VoxelGrid and UnitManager).

**GameLoop Structure Update:**

```js
class GameLoop {
  constructor() {
    // ... existing systems ...
    this.grid = null;
    this.unitManager = null;

    // NEW: Combat Logic Systems
    this.turnSystem = null; // Manages Initiative & Round state
    this.movementSystem = null; // Manages Pathfinding & Position updates
  }

  init(container) {
    // ... existing init ...
    // Instantiate logic systems (they are stateless until startLevel)
    this.turnSystem = new TurnSystem();
    this.movementSystem = new MovementSystem();
  }
}
```

## **2. Integration Point: Level Initialization**

When `startLevel()` runs, the new Grid and UnitManager must be injected into the combat systems so they act on the current map.

**Location:** `src/core/GameLoop.js` -> `startLevel()`

```js
async startLevel(runData) {
  // ... generate grid and units ...

  // WIRING: Connect Systems to Data
  this.movementSystem.setContext(this.grid, this.unitManager);
  this.turnSystem.setContext(this.unitManager);

  // WIRING: Listen for Turn Changes (to update UI/Input state)
  this.turnSystem.addEventListener('turn-start', (e) => this._onTurnStart(e.detail));
}
```

## **3. Integration Point: Transition to Combat**

The transition from "Placing Units" to "Fighting" happens in `finalizeDeployment`. This is where the Turn System takes control.

**Location:** `src/core/GameLoop.js` -> `finalizeDeployment()`

```js
finalizeDeployment() {
  // ... spawn enemies ...

  this.setPhase('COMBAT');

  // WIRING: Hand control to TurnSystem
  const allUnits = this.unitManager.getAllUnits();
  this.turnSystem.startCombat(allUnits);

  // UI Update: Show Combat HUD
  // (Handled via event listeners in index.html)
}
```

## **4. Integration Point: Input Routing (The "Game Loop")**

When the game is in COMBAT phase, inputs must be routed to the active system based on context (Moving vs Targeting).

**Location:** `src/core/GameLoop.js` -> `triggerSelection()` (called by InputManager)

```js
triggerSelection() {
  const cursor = this.inputManager.getCursorPosition();

  // PHASE: DEPLOYMENT (Existing Logic)
  if (this.phase === 'DEPLOYMENT') {
    // ... deploy logic ...
  }

  // PHASE: COMBAT (New Logic)
  else if (this.phase === 'COMBAT') {
    const activeUnit = this.turnSystem.getActiveUnit();

    // Security Check: Is it actually the player's turn?
    if (activeUnit.team !== 'PLAYER') return;

    // Context A: Unit is trying to MOVE
    if (this.combatState === 'SELECTING_MOVE') {
      // DELEGATE to MovementSystem
      if (this.movementSystem.isValidMove(activeUnit, cursor)) {
        this.movementSystem.executeMove(activeUnit, cursor);
        // Updating AP is handled internally or via event
      }
    }

    // Context B: Unit is targeting a SKILL
    else if (this.combatState === 'TARGETING_SKILL') {
      // Delegate to SkillSystem (Future)
    }
  }
}
```

## **5. Visualizing Range (The "Update Loop")**

The blue movement grid needs to update whenever the active unit changes or moves.

**Location:** `src/core/GameLoop.js` -> `animate()` or Event Handler

```js
_onTurnStart(unit) {
  if (unit.team === 'PLAYER') {
    // Ask MovementSystem for reachable tiles
    const tiles = this.movementSystem.getReachableTiles(unit);
    // Ask VoxelManager to highlight them
    this.voxelManager.highlightTiles(tiles, 'BLUE');
  } else {
    this.voxelManager.clearHighlights();
    // Trigger AI processing
  }
}
```

## **6. Conditions of Acceptance (CoA)**

**CoA 1: System Initialization**

- When `startLevel()` is called, both `turnSystem` and `movementSystem` must receive valid references to the current grid and unit manager

**CoA 2: Phase Transitions**

- Calling `finalizeDeployment()` must transition the game to COMBAT phase and initialize the turn queue

**CoA 3: Input Routing**

- During COMBAT phase, player inputs must be routed to the appropriate system (MovementSystem for moves, SkillTargetingSystem for skills)

**CoA 4: Visual Feedback**

- When a player unit's turn starts, the movement range must be highlighted on the grid
- When an enemy unit's turn starts, highlights must be cleared

## **7. Implementation Requirements**

- **Responsibility:** The GameLoop is the "God Object" responsible for tying systems together. It owns the Scene, Renderer, Grid, and Managers
- **Phases:** The loop must respect the current phase: INIT, DEPLOYMENT, COMBAT, RESOLUTION
- **Input Routing:** The loop routes raw inputs from InputManager to the appropriate system (e.g., MovementSystem vs SkillTargeting) based on the current Phase

