78 lines
3 KiB
Markdown
78 lines
3 KiB
Markdown
---
|
|
description: Turn resolution specification - the tick system for transitioning between unit turns
|
|
globs: src/systems/TurnSystem.js, src/systems/TurnSystem.ts, src/types/TurnSystem.ts
|
|
alwaysApply: 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:
|
|
|
|
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**
|
|
|
|
```typescript
|
|
// 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. Implementation Requirements**
|
|
|
|
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
|
|
|
|
|