Introduce detailed specifications for combat skill usage, including interaction flow, state machine updates, and the skill targeting system. Implement the SkillTargetingSystem to handle targeting validation and area of effect calculations. Enhance the CombatHUD specification to define the UI overlay for combat phases. Integrate these systems into the GameLoop for improved combat mechanics and user experience.
68 lines
2.9 KiB
Markdown
68 lines
2.9 KiB
Markdown
# **Turn Resolution Specification: The Tick System**
|
|
|
|
This document 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:
|
|
|
|
1. **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 chargeMeter is reset to 0 (or reduced by action cost).
|
|
2. **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.
|
|
3. **Activation (New Unit):**
|
|
- **AP Refill:** Set currentAP to maxAP.
|
|
- **Start Triggers:** Fire ON_TURN_START events (e.g., "Take Poison Damage").
|
|
- **Input Unlock:** If Player, unlock UI. If Enemy, trigger AI.
|
|
|
|
## **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: 1 applied 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. Prompt for Coding Agent**
|
|
|
|
"Create src/systems/TurnSystem.js.
|
|
|
|
1. **State:** Maintain a globalTick counter and reference to UnitManager.
|
|
2. **End Turn Logic:** Implement endTurn(unit). Reset the unit's charge to 0. Tick their cooldowns/statuses.
|
|
3. **Time Loop:** Implement advanceToNextTurn(). Loop through all alive units, adding Speed to Charge. Stop as soon as one or more units reach 100.
|
|
4. **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.
|
|
5. **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."
|