aether-shards/specs/TurnLifecycle.spec.md
Matthew Mone 56aa6d79df Add Combat Skill Usage and Targeting System Specifications
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.
2025-12-23 21:01:54 -08:00

77 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)."