69 lines
2.9 KiB
Markdown
69 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."
|