# Enemies Index — All Enemy Types **Game:** Project Void | **Build Phase:** 12 **Framework Systems:** 80_BP_EnemyBase, 82_BPC_AlertSystem, 83_BPC_AIStateMachine, 84_AI_BaseAgentController, 85_BB_AgentBoard, 86_BPC_AIMemorySystem, 87_BPC_AIPerceptionSystem, 88_BPC_BehaviourVariantSelector --- ## Purpose Defines the 3 enemy types, their AI controllers, behavior trees, blackboards, and integration with the horror framework systems. Plus the friendly NPC survivor. --- ## Enemy Catalog | # | Enemy | Threat Level | Speed | Damage | Killable? | Vulnerability | Spawn Areas | |---|-------|:---:|:---:|:---:|:---:|------|-------------| | 1 | Patient | Medium | Slow (250) | 20 melee | YES | Light distracts briefly | Entry, WardA, WardB, Basement | | 2 | Orderly | High | Fast (500) | 15 melee | YES | Flashlight blinds (slows 50%) | WardB, WardensOffice | | 3 | Shade | Extreme | Teleport | 100 (1-hit) | NO | Light delays approach | WardB², Basement, VoidSpace | ² Shade appears once in WardB (scripted courtyard) + randomly in morgue --- ## 1. BP_Enemy_Patient — "The Lost" **Parent:** `BP_EnemyBase` (80) **Description:** Former asylum patients, twisted by the void. Slow but persistent. Walk with jerky, unnatural gait. Moan occasionally. Attack by grabbing and slashing. ### Components | Component | Purpose | |-----------|---------| | `BP_EnemyBase` components (inherited) | Health (100), movement, skeletal mesh | | `BPC_AlertSystem` (82) | Suspicious→Alerted→Combat | | `BPC_AIStateMachine` (83) | Patrol/Search/Combat/Flee | | `BPC_AIPerceptionSystem` (87) | Sight (120° cone, 2000u), Hearing (1500u) | | `BPC_AIMemorySystem` (86) | Last known player location | | `BPC_BehaviourVariantSelector` (88) | Aggressive/Curious/Erratic variants | | `BPC_DamageReceptionSystem` (72) | Receive damage, hit reaction | | `BPC_HitReactionSystem` (75) | Flinch/stagger on hit | | `BPC_DeathCauseTracker` (73) | Log killing blow | ### AI Controller: AI_PatientController **Parent:** `AI_BaseAgentController` (84) ``` Behavior Tree: BT_PatientBehavior ├─ Root → Selector │ ├─ [Combat] Sequence │ │ ├─ MoveTo (player last known location) │ │ ├─ Wait (0.5s — "searching" animation) │ │ ├─ MoveTo (player current location) │ │ └─ Melee Attack → BPC_MeleeSystem.Swing │ │ │ ├─ [Search] Sequence (unseen player, heard sound) │ │ ├─ MoveTo (suspected location from BPC_AIMemorySystem) │ │ ├─ Wait (2.0s — "sniffing" animation) │ │ └─ Return to Patrol │ │ │ └─ [Patrol] Sequence (default) │ ├─ MoveTo (next waypoint on BP_PatrolPath_Asylum) │ ├─ Wait (3-5s at each waypoint — random) │ └─ Loop ``` ### Blackboard: BB_PatientData **Parent:** `BB_AgentBoard` (85) | Key | Type | Purpose | |-----|------|---------| | `TargetActor` | Actor | Current target (player) | | `LastKnownLocation` | Vector | From BPC_AIMemorySystem | | `AlertState` | Enum | Calm/Suspicious/Alerted/Combat | | `PatrolIndex` | Int | Current patrol waypoint | | `bHasSeenPlayer` | Bool | Player was sighted | | `bHeardSound` | Bool | Sound stimulus received | | `SoundLocation` | Vector | Where sound came from | ### Perception | Sense | Range | Angle | Notes | |-------|:---:|:---:|-------| | **Sight** | 2000u | 120° | Player flashlight increases detection range 50% | | **Hearing** | 1500u | 360° | Running: detected at full range. Walking: 50%. Crouching: 25% | | **Damage** | 3000u | 360° | Being shot alerts to player location instantly | | **Touch** | 100u | 360° | Physical contact = immediate combat | ### Behaviour Variants (via DA_BehaviourVariant_Patient) | Variant | Weight | Behavior | |---------|:---:|----------| | **Aggressive** | 40% | Charges directly, ignores hiding spots, attacks on sight | | **Curious** | 35% | Approaches slowly, tilts head, investigates sounds first | | **Erratic** | 25% | Randomly changes patrol path, sometimes stands still for 10s | ### Stress Impact on Player - Patient visible: +3 stress/second - Patient in combat: +5 stress/second - Patient killed nearby: +10 stress (one-time spike) --- ## 2. BP_Enemy_Orderly — "The Wardens" **Parent:** `BP_EnemyBase` (80) **Description:** Former asylum staff. Fast, aggressive, but vulnerable to bright light. Walk with purposeful stride. Carry rusted medical tools as weapons. ### Key Differences from Patient | Aspect | Patient | Orderly | |--------|---------|---------| | Speed | 250 (walk) | 500 (jog) | | Health | 100 | 75 (weaker but faster) | | Damage | 20 | 15 (faster attacks) | | Attack Speed | 2.0s | 1.0s (rapid slashes) | | Flashlight Effect | Distracts (looks away 2s) | Blinds (slows to 125 speed, misses attacks) | | Hiding Detection | Can't detect hidden player | Can find hidden player if searched recently | | Audio Cues | Moans, footsteps | Heavy breathing, keys jangling | ### Flashlight Vulnerability ``` Orderly enters player flashlight beam: ├─ BPC_AlertSystem.State == Combat? │ ├─ True: │ │ ├─ Set movement speed multiplier = 0.25 (slowed) │ │ ├─ Set attack accuracy multiplier = 0.3 (misses often) │ │ ├─ Play pained hiss sound │ │ └─ After 5 seconds in light: Flee state (runs away) │ │ │ └─ False: │ ├─ Set AlertState = Suspicious │ └─ Shield eyes animation, back away slowly │ └─ Flashlight battery drains 2x faster when blinding an Orderly ``` ### AI Controller: AI_OrderlyController Same structure as Patient but with: - Faster patrol (jog between waypoints) - Hiding spot investigation behavior (checks lockers) - Flashlight avoidance task (path around light beams) --- ## 3. BP_Enemy_Shade — "The Void" **Parent:** `BP_EnemyBase` (80) **Description:** The primary antagonist. A shifting, semi-corporeal entity from the void. Cannot be killed, only delayed. Teleports between dark areas. One-hit kills the player. ### Components Same as Patient/Orderly PLUS: | Component | Purpose | |-----------|---------| | `BPC_FearSystem` (90) | Generates fear aura (player stress +8/sec within 800u) | | `Timeline "PhaseShift"` | Visual: model fades in/out when teleporting | | `PointLightComponent "VoidGlow"` | Purple-black light aura (grows brighter when close) | ### Special Rules | Rule | Behavior | |------|----------| | **Immortal** | Cannot be killed. Damage only delays (stuns for 3-5 seconds) | | **Teleport** | Moves between dark areas (illuminance < 0.1). Cannot enter lit rooms | | **Light Delayed** | Flashlight aimed at Shade slows approach speed 60% | | **Sound Tracking** | FULL hearing range (5000u). Any sound = instant investigation | | **One-Hit Kill** | Contact causes instant death → Void Space | | **Void Aura** | Radius 800u: player stress +8/sec, screen vignette darkens | | **Persistence** | Remembers player across runs (session flag: "ShadeEncountered") | | **Walls Don't Stop It** | Can phase through doors, walls (not during combat) | ### AI Controller: AI_ShadeController ``` Behavior Tree: BT_ShadeBehavior ├─ Root → Selector │ ├─ [Void Hunt] Sequence (player detected by sound/sight) │ │ ├─ Calculate "dark path" to player (avoid lit areas) │ │ ├─ Teleport to next dark node (max 3000u per teleport) │ │ ├─ Wait (1-3s — appears, stands still, watches) │ │ ├─ MoveTo (player — floating, no walk animation) │ │ ├─ On contact: KillPlayer → trigger void death │ │ └─ If flashlight hits: Stun 3s, teleport away │ │ │ └─ [Stalk] Sequence (default) │ ├─ Teleport to dark location near player (800-1500u) │ ├─ Wait (5-10s — watching) │ ├─ SFX: whisper, breathing, or distant scream │ └─ If player stays still > 10s: teleport closer ``` ### Blackboard: BB_ShadeData | Key | Type | Purpose | |-----|------|---------| | `TargetPlayer` | Actor | Player reference | | `DarkNodes` | Array\ | All dark locations in level (pre-calculated) | | `CurrentDarkNode` | Vector | Current teleport position | | `bIsStunned` | Bool | Recently hit by flashlight | | `StunTimer` | Float | Remaining stun duration | | `bHasKilledPlayer` | Bool | Killed player this encounter | ### Shade Encounter Design | Location | Type | Trigger | Duration | |----------|------|---------|----------| | WardB Courtyard | **Scripted Teaser** | Player enters courtyard | 10s (watches then vanishes) | | WardB Morgue | **Void Shift Guardian** | Void shift event | 30s (pursues during shift) | | Basement | **Persistent Hunter** | Always active in basement | Entire level | | Void Space | **Final Chase** | Enter void | Until exit or caught | --- ## 4. BP_NPC_Survivor (Friendly) **Parent:** `Character` **Description:** A surviving asylum patient. Optional rescue NPC. If saved, appears in endings and grants lore. ### Interaction ``` BP_NPC_Survivor Implements: I_Interactable Event Interact: │ ├─ [Dialogue Choice] │ ├─ BPC_DialogueChoiceSystem.PresentChoices() │ ├─ Options: │ │ ├─ "Who are you? What happened here?" → Lore dump │ │ ├─ "Follow me. I'll get you out." → NPC follows player │ │ └─ "Stay here. It's safer." → NPC stays, gives item │ │ │ ├─ Choice → BPC_BranchingConsequenceSystem.ExecuteConsequence() │ │ ├─ Follow: NPC becomes follower, can carry items │ │ └─ Stay: NPC gives Keycard Alpha (if not found yet) │ │ │ └─ BPC_EndingAccumulator.RecordEvent("SurvivorSaved") │ └─ Return True ``` ### Survivor States | State | Behavior | |-------|----------| | Idle | Sits in room, waits for player | | Following | Walks behind player, stops when player stops | | Hiding | If enemies near, finds hiding spot | | Dead | If attacked by enemies during escort | | Saved | Reaches safe room — ending flag set | --- ## Enemy Spawning & Difficulty ### BPC_ProceduralEncounter (92) Configuration | Encounter | DA_EncounterData | Difficulty Scalar | |-----------|-----------------|:---:| | WardA Patrol | `DA_Encounter_WardA_Patrol` | ×1.0 | | WardB Mixed | `DA_Encounter_WardB_Mixed` | ×1.2 | | Basement Shade | `DA_Encounter_ShadeAmbush` | ×1.5 | ### BPC_DifficultyManager (89) Scaling ``` Player deaths in current chapter: 0 deaths → Difficulty × 1.0 (normal) 1 death → Difficulty × 0.9 (slightly easier) 2 deaths → Difficulty × 0.8 (noticeably easier) 3+ deaths→ Difficulty × 0.7 (easier + extra checkpoints) Difficulty affects: ├─ Enemy count: × Difficulty (rounded down) ├─ Enemy health: × Difficulty ├─ Enemy damage: × Difficulty ├─ Ammo spawn count: × (2.0 - Difficulty) [more ammo when easier] ├─ Stress accumulation rate: × Difficulty └─ Scare event frequency: × Difficulty ``` --- ## Enemy Death & Persistence When an enemy is killed: ``` Enemy Health = 0 │ ├─ [Death Animation] Montage plays (GASP death state) ├─ [Ragdoll] Enable physics on skeletal mesh ├─ [Corpse Persistence] │ ├─ BPC_PersistentCorpseSystem.SaveCorpse() │ └─ Corpse remains in world until: │ ├─ Player leaves level (transition) │ ├─ Save/Load cycle (corpse ID saved) │ └─ Manual "clear corpses" via Void shift │ ├─ [Loot Drop] (30% chance) │ └─ Spawn random item at corpse location: │ ├─ Patient: Battery (40%), MedKit (30%), Ammo (20%), Nothing (10%) │ └─ Orderly: Ammo (40%), Key item hint (30%), Battery (20%), Nothing (10%) │ ├─ [Metrics] │ ├─ BPC_PlayerMetricsTracker.RecordKill(EnemyType, WeaponUsed) │ └─ BPC_ProgressStatTracker.IncrementEnemiesKilled() │ ├─ [Stress Effect] │ └─ Player BPC_StressSystem.AddStress(10) — "killing a former human" │ └─ [Achievement Check] └─ SS_AchievementSystem.Check("FirstKill", "Pacifist", "Exterminator") ``` --- ## Blueprint Wiring Checklist ### Patient Enemy - [ ] Create `BP_Enemy_Patient` — child of `BP_EnemyBase` - [ ] Add alert, AI state machine, perception, memory, behavior variant, damage reception, hit reaction components - [ ] Create `AI_PatientController` — child of `AI_BaseAgentController` - [ ] Create `BT_PatientBehavior` — Patrol/Search/Combat branches - [ ] Create `BB_PatientData` — all blackboard keys - [ ] Create `DA_BehaviourVariant_Patient` with 3 variants + weights - [ ] Set max health = 100, walk speed = 250, damage = 20 ### Orderly Enemy - [ ] Create `BP_Enemy_Orderly` — child of `BP_EnemyBase` - [ ] Same components as Patient - [ ] Add flashlight vulnerability logic in AI controller (OnPerceptionUpdated → check light) - [ ] Create `AI_OrderlyController`, `BT_OrderlyBehavior`, `BB_OrderlyData` - [ ] Set max health = 75, walk speed = 500, damage = 15 ### Shade Enemy - [ ] Create `BP_Enemy_Shade` — child of `BP_EnemyBase` - [ ] Add Teleport, VoidGlow, PhaseShift components - [ ] Add `BPC_FearSystem` (fear aura) - [ ] Create `AI_ShadeController` with dark-node pathfinding - [ ] Create `BT_ShadeBehavior` — VoidHunt/Stalk branches - [ ] Create `BB_ShadeData` — DarkNodes array, stunned state - [ ] Set health = invulnerable, damage = 100 (one-hit) ### NPC Survivor - [ ] Create `BP_NPC_Survivor` — child of `Character` - [ ] Implement `I_Interactable` - [ ] Wire dialogue choices via `BPC_DialogueChoiceSystem` - [ ] Wire follow/hide behaviors --- ## Notes for Expansion - Add **boss encounters**: Void Entity manifestation (multi-phase boss fight) - Add **stealth kill mechanic**: sneak behind Patient → silent takedown (no stress penalty) - Add **enemy variants**: "Blind Patient" (hearing-only), "Crawler" (ceiling enemy) - Add **dynamic music**: combat music intensity scales with number of alert enemies - Add **enemy faction system**: Patients flee from Shade, Orderlies protect Shade - Multiplayer: server-authoritative AI, perception events replicated to all clients - Consider **Procedural placement**: spawn points randomized each new game for replayability --- *Enemies Index for Project Void. See [GAMEINDEX.md](GAMEINDEX.md) for full game structure. See [80_BP_EnemyBase.md](../blueprints/09-ai/80_BP_EnemyBase.md) for base enemy spec.*