# **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 ```