- Created ui-overrides.md detailing game-specific Widget Blueprint overrides, including purpose, widget index, visual styling, and accessibility requirements. - Established weapons-index.md outlining all held weapon actors, including their components, logic, and comparisons for gameplay mechanics.
14 KiB
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<Vector> | 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 ofBP_EnemyBase - Add alert, AI state machine, perception, memory, behavior variant, damage reception, hit reaction components
- Create
AI_PatientController— child ofAI_BaseAgentController - Create
BT_PatientBehavior— Patrol/Search/Combat branches - Create
BB_PatientData— all blackboard keys - Create
DA_BehaviourVariant_Patientwith 3 variants + weights - Set max health = 100, walk speed = 250, damage = 20
Orderly Enemy
- Create
BP_Enemy_Orderly— child ofBP_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 ofBP_EnemyBase - Add Teleport, VoidGlow, PhaseShift components
- Add
BPC_FearSystem(fear aura) - Create
AI_ShadeControllerwith 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 ofCharacter - 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 for full game structure. See 80_BP_EnemyBase.md for base enemy spec.