aether-shards/specs/EffectProcessor.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

132 lines
4.7 KiB
Markdown

# **Effect Processor Specification: The Game Logic Engine**
This document defines the architecture for the **Effect Processor**, the central system responsible for executing all changes to the game state (Damage, Healing, Movement, Spawning).
## **1. System Overview**
The EffectProcessor is a stateless logic engine. It takes a **Definition** (What to do) and a **Context** (Who is doing it to whom), and applies the necessary mutations to the UnitManager or VoxelGrid.
### **Architectural Role**
- **Input:** EffectDefinition (JSON), Source (Unit), Target (Unit/Tile).
- **Output:** State Mutation (HP changed, Unit moved) + EffectResult (Log data).
- **Pattern:** Strategy Pattern. Each effect_type maps to a specific Handler Function.
## **2. Integration Points**
### **A. Calling the Processor**
The Processor is never called directly by the UI. It is invoked by:
1. **SkillManager:** When an Active Skill is executed.
2. **EventSystem:** When a Passive Item triggers (e.g., "On Hit -> Apply Burn").
3. **Environmental Hazard:** When a unit starts their turn on Fire/Acid.
### **B. Dependencies**
The Processor requires injection of:
- VoxelGrid: To check collision, modify terrain, or move units.
- UnitManager: To find neighbors (Chain Lightning) or spawn tokens (Turrets).
- RNG: A seeded random number generator for damage variance and status chances.
## **3. Data Structure (JSON Schema)**
Every effect in the game must adhere to this structure.
```typescript
interface EffectDefinition {
type: EffectType;
// -- Magnitude --
power?: number; // Base amount (Damage/Heal)
attribute?: string; // Stat to scale off (e.g., "strength", "magic")
scaling?: number; // Multiplier for attribute (Default: 1.0)
// -- Flavour --
element?: "PHYSICAL" | "FIRE" | "ICE" | "SHOCK" | "VOID" | "TECH";
// -- Status/Buffs --
status_id?: string; // For APPLY_STATUS
duration?: number; // Turns
chance?: number; // 0.0 to 1.0
// -- Movement/Physics --
force?: number; // Distance for Push/Pull
destination?: "TARGET" | "BEHIND_TARGET"; // For Teleport
// -- Conditionals --
condition?: {
target_tag?: string; // e.g. "MECHANICAL"
target_status?: string; // e.g. "WET"
hp_threshold?: number; // e.g. 0.3 (30%)
};
}
type EffectType =
| "DAMAGE"
| "HEAL"
| "APPLY_STATUS"
| "REMOVE_STATUS"
| "TELEPORT"
| "PUSH"
| "PULL"
| "SPAWN_UNIT"
| "MODIFY_TERRAIN" // Destroy walls, create hazards
| "CHAIN_DAMAGE"; // Bouncing projectiles
```
## 4. Handler Specifications
### Handler: `DAMAGE`
- **Logic:** `FinalDamage = (BasePower + (Source[Attribute] * Scaling)) - Target.Defense`.
- **Element Check:** If Target has Resistance/Weakness to `element`, modify FinalDamage.
- **Result:** `Target.currentHP -= FinalDamage`.
### Handler: `CHAIN_DAMAGE`
- **Logic:** Apply `DAMAGE` to primary target. Then, scan for N nearest enemies within Range R. Apply `DAMAGE * Decay` to them.
- **Synergy:** If `condition.target_status` is present on a target, the chain may branch or deal double damage.
### Handler: `TELEPORT`
- **Logic:** Validate destination tile (must be Air and Unoccupied). Update `Unit.position` and `VoxelGrid.unitMap`.
- **Visuals:** Trigger "Vanish" VFX at old pos, "Appear" VFX at new pos.
### Handler: `MODIFY_TERRAIN`
- **Logic:** Update `VoxelGrid` ID at Target coordinates.
- **Use Case:** Sapper's "Breach Charge" turns `ID_WALL` into `ID_AIR`.
- **Safety:** Check `VoxelGrid.isDestructible()`. Do not destroy bedrock.
---
## 5. Conditions of Acceptance (CoA)
**CoA 1: Attribute Scaling**
- Given a Damage Effect with `power: 10` and `attribute: "magic"`, if Source has `magic: 5`, the output damage must be 15.
**CoA 2: Conditional Logic**
- Given an Effect with `condition: { target_status: "WET" }`, if the target does _not_ have the "WET" status, the effect must **not** execute (return early).
**CoA 3: State Mutation**
- When `APPLY_STATUS` is executed, the Target unit's `statusEffects` array must contain the new ID with the correct duration.
**CoA 4: Physics Safety**
- When `PUSH` is executed, the system must check `VoxelGrid.isSolid()` behind the target. If a wall exists, the unit must **not** move into the wall (optionally take "Smash" damage instead).
---
## 6. Prompt for Coding Agent
> "Create `src/systems/EffectProcessor.js`.
>
> 1. **Constructor:** Accept `VoxelGrid` and `UnitManager`. Initialize a map of `handlers`.
> 2. **Process Method:** `process(effectDef, source, target)`. Look up handler by `effectDef.type`. Verify `checkConditions()`. Execute handler. Return `ResultObject`.
> 3. **Handlers:** Implement `handleDamage`, `handleHeal`, `handleStatus`, `handleMove`.
> 4. **Helper:** Implement `calculatePower(def, source)` to handle attribute scaling logic centrally."