78 lines
2.9 KiB
Markdown
78 lines
2.9 KiB
Markdown
|
|
# **Turn Lifecycle Specification: Activation & Reset**
|
||
|
|
|
||
|
|
This document defines the exact state changes that occur when a unit becomes active (Start Turn) and when they finish (End Turn).
|
||
|
|
|
||
|
|
## **1. Start of Turn (Activation Phase)**
|
||
|
|
|
||
|
|
This logic runs immediately when TurnSystem identifies a unit as the new active actor.
|
||
|
|
|
||
|
|
### **A. Action Point (AP) Regeneration**
|
||
|
|
|
||
|
|
The unit must be given their budget for the turn.
|
||
|
|
|
||
|
|
- **Formula:** Base AP (3) + Math.floor(Speed / 5).
|
||
|
|
- **Constraint:** AP does _not_ roll over. It resets to this max value every turn. This encourages players to use their actions rather than hoard them.
|
||
|
|
|
||
|
|
### **B. Cooldown Reduction**
|
||
|
|
|
||
|
|
- Iterate through all skills in unit.skills.
|
||
|
|
- If cooldown > 0, decrement by 1.
|
||
|
|
- _Note:_ This ensures a skill used on Turn 1 with a 1-turn cooldown is ready again on Turn 2.
|
||
|
|
|
||
|
|
### **C. Status Effect Tick (The "Upkeep" Step)**
|
||
|
|
|
||
|
|
- Iterate through unit.statusEffects.
|
||
|
|
- **Apply Effect:** If the effect is a "DoT" (Damage over Time) or "HoT" (Heal over Time), apply the value now.
|
||
|
|
- **Decrement Duration:** Reduce the effect's duration by 1.
|
||
|
|
- **Expire:** If duration reaches 0, remove the effect immediately (unless it is "Permanent").
|
||
|
|
- **Stun Check:** If a STUN status is active, skip the Action Phase and immediately trigger **End Turn**.
|
||
|
|
|
||
|
|
## **2. End of Turn (Resolution Phase)**
|
||
|
|
|
||
|
|
This logic runs when the player clicks "End Turn" or the AI finishes its logic.
|
||
|
|
|
||
|
|
### **A. Charge Meter Consumption**
|
||
|
|
|
||
|
|
- **Logic:** We do _not_ set Charge to 0. We subtract 100.
|
||
|
|
- **Why?** If a unit has 115 Charge (because they are very fast), setting it to 0 deletes that extra 15 speed advantage. Subtracting 100 lets them keep the 15 head-start on the next race.
|
||
|
|
- **Formula:** unit.chargeMeter = Math.max(0, unit.chargeMeter - 100).
|
||
|
|
|
||
|
|
### **B. Action Slot Reset**
|
||
|
|
|
||
|
|
- Reset flags like hasMoved, hasAttacked, or standardActionUsed to false so the UI is clean for the next time they act.
|
||
|
|
|
||
|
|
## **3. The Tick Loop (The "Race")**
|
||
|
|
|
||
|
|
This runs whenever no unit is currently active.
|
||
|
|
|
||
|
|
```js
|
||
|
|
while (no_unit_has_100_charge) {
|
||
|
|
globalTick++;
|
||
|
|
for (all_units as unit) {
|
||
|
|
// Gain Charge
|
||
|
|
unit.chargeMeter += unit.stats.speed;
|
||
|
|
|
||
|
|
// Cap?
|
||
|
|
// No cap, but we check for >= 100 break condition
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
// Sort by Charge (Descending) -> Highest Charge wins
|
||
|
|
```
|
||
|
|
|
||
|
|
## **4. Prompt for Coding Agent**
|
||
|
|
|
||
|
|
"Update src/systems/TurnSystem.js to implement the full Lifecycle.
|
||
|
|
|
||
|
|
1. **startTurn(unit)**:
|
||
|
|
- Calculate Max AP (3 + floor(speed/5)). Set currentAP to this.
|
||
|
|
- Loop unit skills: cooldown--.
|
||
|
|
- Loop unit statuses: Apply DoT/HoT logic via EffectProcessor, decrement duration, remove if 0.
|
||
|
|
- Check for Stun. If stunned, skip to endTurn.
|
||
|
|
2. **endTurn(unit)**:
|
||
|
|
- unit.chargeMeter -= 100.
|
||
|
|
- Triggers advanceToNextTurn().
|
||
|
|
3. **advanceToNextTurn()**:
|
||
|
|
- While no unit has >= 100 charge: loop all units, add speed to chargeMeter.
|
||
|
|
- Once threshold met: Sort candidates by Charge. Pick winner. Call startTurn(winner)."
|