- Introduce the MissionDebrief component to display after-action reports, including XP, rewards, and squad status. - Implement the MissionGenerator class to create procedural side missions, enhancing replayability and resource management. - Update mission schema to include mission objects for INTERACT objectives, improving mission complexity. - Enhance GameLoop and MissionManager to support new mission features and interactions. - Add tests for MissionDebrief and MissionGenerator to ensure functionality and integration within the game architecture.
3 KiB
3 KiB
| description | globs | alwaysApply |
|---|---|---|
| Turn resolution specification - the tick system for transitioning between unit turns | src/systems/TurnSystem.js, src/systems/TurnSystem.ts, src/types/TurnSystem.ts | false |
Turn Resolution Rule
This rule defines the logic that occurs the moment a unit presses "End Turn". It transitions the game from one actor to the next using a time-based simulation.
1. The Logic Flow
When endTurn() is called:
- Resolution (Old Unit):
- Cooldowns: Decrement cooldowns on all skills by 1
- Status Effects: Tick durations of active effects (Buffs/Debuffs). Remove expired ones
- Charge Reset: The unit's
chargeMeteris reset to 0 (or reduced by action cost)
- Time Advancement (The "Tick"):
- The system enters a
while(no_active_unit)loop - Tick: Every unit gains
Charge += Speed - Check: Does anyone have
Charge >= 100?- Yes: Stop looping. The unit with the highest Charge is the New Active Unit
- No: Continue looping
- The system enters a
- Activation (New Unit):
- AP Refill: Set
currentAPtomaxAP - Start Triggers: Fire
ON_TURN_STARTevents (e.g., "Take Poison Damage") - Input Unlock: If Player, unlock UI. If Enemy, trigger AI
- AP Refill: Set
2. TypeScript Interfaces
// src/types/TurnSystem.ts
export interface TurnState {
/** The ID of the unit currently acting */
activeUnitId: string | null;
/** How many "Ticks" have passed in total (Time) */
globalTime: number;
/** Ordered list of who acts next (predicted) for the UI */
projectedQueue: string[];
}
export interface TurnEvent {
type: 'TURN_CHANGE';
previousUnitId: string;
nextUnitId: string;
/** Did we wrap around a "virtual round"? */
isNewRound: boolean;
}
3. Conditions of Acceptance (CoA)
CoA 1: Speed determines frequency
- If Unit A has Speed 20 and Unit B has Speed 10:
- Unit A should act roughly twice as often as Unit B over 10 turns
CoA 2: Queue Prediction
- The system must expose a
getPredictedQueue(depth)method that "simulates" future ticks without applying them, so the UI can show the "Next 5 Units" list correctly
CoA 3: Status Duration
- A Status Effect with
duration: 1applied on Turn X must expire exactly at the start of the unit's next turn (Turn X+1), ensuring it affects them for one full action phase
4. Implementation Requirements
Create src/systems/TurnSystem.js:
- State: Maintain a
globalTickcounter and reference to UnitManager - End Turn Logic: Implement
endTurn(unit). Reset the unit's charge to 0. Tick their cooldowns/statuses - Time Loop: Implement
advanceToNextTurn(). Loop through all alive units, adding Speed to Charge. Stop as soon as one or more units reach 100 - Tie Breaking: If multiple units pass 100 in the same tick, the one with the highest total charge goes first. If equal, Player beats Enemy
- Prediction: Implement
simulateQueue(depth)which clones the current charge state and runs the loop virtually to return an array of the next depth Unit IDs