Introduce the HubScreen as the main interface for managing resources, units, and mission selection, integrating with the GameStateManager for dynamic data binding. Implement the MissionBoard component to display and select available missions, enhancing user interaction with mission details and selection logic. Update the GameStateManager to handle transitions between game states, ensuring a seamless experience for players. Add tests for HubScreen and MissionBoard to validate functionality and integration with the overall game architecture.
4.9 KiB
| description | globs | alwaysApply |
|---|---|---|
| Combat integration - wiring TurnSystem and MovementSystem into the GameLoop | src/core/GameLoop.js, src/core/GameLoop.ts | 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:
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()
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()
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)
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
_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, bothturnSystemandmovementSystemmust 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