# Reusable UE5 Modular Game Framework
### A Complete Blueprint Architecture for First-Person Narrative Horror (and Beyond)

> **C++ Status (2026-05-22):** 27 C++ classes implemented in `Source/PG_Framework/` — 15 full implementations (GI_GameFramework, GM_CoreGameMode, GS_CoreGameState, DA_GameTagRegistry, FL_GameUtilities, I_InterfaceLibrary, BPC_InventorySystem, SS_SaveManager, BPC_DamageReceptionSystem, SS_EnhancedInputManager, BPC_StateManager, DA_ItemData, UBPC_PlanarCapture, ABP_PlanarCaptureActor, USS_PlanarCaptureManager) + 2 utility (UPlanarCaptureCameraUtils, PlanarCaptureCommon) + 10 stubs (BPC_HealthSystem, BPC_StaminaSystem, BPC_StressSystem, BPC_MovementStateSystem, PC_CoreController, PS_CorePlayerState, BPC_HitReactionSystem, BPC_ShieldDefenseSystem, DA_EquipmentConfig, DA_StateGatingTable). See [`docs/checklists/cpp-blueprint-status.md`](docs/checklists/cpp-blueprint-status.md) for the full grid. All 147 Blueprint spec files exist in [`docs/blueprints/`](docs/blueprints/INDEX.md) with Manual Implementation Guides.

---

## Naming Conventions

| Prefix | Class Type | Example |
|--------|-----------|---------|
| `BP_` | Blueprint Actor | `BP_Door`, `BP_Pickup` |
| `BPC_` | Blueprint Component | `BPC_HealthSystem`, `BPC_InteractionSystem` |
| `WBP_` | Widget Blueprint | `WBP_HUDController`, `WBP_PauseMenu` |
| `GI_` | Game Instance | `GI_GameFramework` |
| `GM_` | Game Mode | `GM_CoreGameMode` |
| `GS_` | Game State | `GS_CoreGameState` |
| `PC_` | Player Controller | `PC_CoreController` |
| `PS_` | Player State | `PS_CorePlayerState` |
| `DA_` | Data Asset | `DA_ItemData`, `DA_AchievementData` |
| `E_` | Enum | `E_InteractionType`, `E_GamePhase` |
| `S_` | Struct | `S_ItemData`, `S_NarrativeFlag` |
| `I_` | Interface | `I_Interactable`, `I_Damageable` |
| `FL_` | Function Library | `FL_GameUtilities`, `FL_MathHelpers` |
| `SS_` | Game Instance Subsystem | `SS_SaveManager`, `SS_AchievementSystem` |
| `AI_` | AI Blueprint | `AI_PatrolAgent`, `AI_EncounterDirector` |
| `BTT_` | Behaviour Tree Task | `BTT_Investigate`, `BTT_Chase` |
| `BTS_` | Behaviour Tree Service | `BTS_PerceptionUpdate` |
| `BTD_` | Behaviour Tree Decorator | `BTD_CanSeePlayer` |
| `BB_` | Blackboard | `BB_AgentBoard` |
| `T_` | Texture | `T_WatchFace_D` |
| `M_` | Material | `M_DiegeticHUD_Glass` |
| `ABP_` | Animation Blueprint | `ABP_PlayerBody` |
| `M_` | Master Material | `M_CaptureSurface_Master` |
| `MI_` | Material Instance | `MI_Mirror_Clean` |
| `MPC` | Material Parameter Collection | `MPC_CaptureSurface` |

**Asset Folder Structure:**
```
Content/
  Framework/
    Core/
    Player/
    Interaction/
    Inventory/
    Weapons/
    UI/
    Narrative/
    Save/
    Adaptive/
    AI/
    Achievements/
    Settings/
  Data/
    Items/
    Objectives/
    Achievements/
    Encounters/
    Narrative/
  Game/          ← game-specific overrides and extensions
```

---

## Architectural Principles

1. **Single Responsibility** — Every component owns exactly one concern. If you cannot describe it in one sentence, split it.
2. **Interface-First Communication** — Systems talk to each other through interfaces (`I_`) or event dispatchers. Direct object references are the exception, not the rule.
3. **Data Owns Itself** — Interactable objects carry their own interaction data (via Data Asset or struct). The Interaction System reads it; it does not define it.
4. **UI Reads, Never Writes** — Widget Blueprints consume data from systems. They never own game logic or write game state directly.
5. **No Hardcoded Names** — All game-specific configuration lives in Data Assets, Gameplay Tags, or config structs. Nothing is hardcoded in Blueprint logic.
6. **Save-System Aware** — Any component that needs to persist state must implement the `I_Persistable` interface and register with `SS_SaveManager`.
7. **Tag-Driven Filtering** — Use Gameplay Tags for categorisation, filtering, and condition checks everywhere. Never use string comparisons or hardcoded booleans for state.
8. **Manager vs Worker Split** — Managers (subsystems, game instance) coordinate. Workers (components on actors) execute. Managers do not tick actors. Workers do not manage global state.
9. **GASP Is Sacred** — Do not touch GASP locomotion internals. Layer all new systems around GASP via its extension points, Smart Object hooks, and animation notify support.
10. **Fail Gracefully** — All interface calls check validity before execution. Missing components should log a warning, not crash.
11. **Central State Authority** — `BPC_StateManager` (130) is the single source of truth for "what can the player do right now?" Systems call `IsActionPermitted(Tag)` instead of checking other systems' states directly.
12. **State Gating via Data Asset** — All gating rules in `DA_StateGatingTable` (131). Designers modify rules without touching Blueprints.
13. **Force Stack Pattern** — Death, cutscenes, void space push state onto a force stack; `RestorePreviousState()` pops back.
14. **Animation Notify Contract** — 14 named notifies required in montages for framework synchronization (see [`animation-catalog.md`](docs/architecture/animation-catalog.md)).
15. **Server-Authoritative Replication** — All state mutations gated by `HasAuthority()`. Clients request via `Server_` RPCs; servers validate and replicate via `RepNotify`. See [`multiplayer-networking.md`](docs/architecture/multiplayer-networking.md).
16. **Capture Is Local-Only** — Scene capture rendering (mirrors, portals, monitors) is always local to each client. Each client renders their own camera view. The World Subsystem evaluates surface priorities independently per client. Only surface active state replicates — never render targets.

---

## Core Dependency Rules

```
GI_GameFramework
  └─ owns ─► SS_SaveManager
  └─ owns ─► SS_AchievementSystem
  └─ owns ─► SS_SettingsSystem
  └─ owns ─► SS_EnhancedInputManager
  └─ owns ─► SS_AudioManager
  └─ owns ─► SS_UIManager

GM_CoreGameMode
  └─ spawns ─► PC_CoreController
  └─ manages ─► GS_CoreGameState
  └─ routes ─► narrative phase changes

PC_CoreController
  └─ reads ─► SS_EnhancedInputManager (input contexts)
  └─ reads ─► BPC_HealthSystem (on Pawn)
  └─ reads ─► BPC_StaminaSystem (on Pawn)
  └─ reads ─► BPC_StressSystem (on Pawn)

PlayerPawn (GASP base)
  └─ BPC_StateManager          ← CENTRAL STATE AUTHORITY
  └─ BPC_HealthSystem
  └─ BPC_StaminaSystem
  └─ BPC_StressSystem
  └─ BPC_MovementStateSystem
  └─ BPC_EmbodimentSystem
  └─ BPC_CameraStateLayer
  └─ BPC_PlayerMetricsTracker
  └─ BPC_InventorySystem
  └─ BPC_DamageReceptionSystem
  └─ BPC_ShieldDefenseSystem
  └─ BPC_HitReactionSystem
  └─ BPC_HidingSystem
  └─ BPC_InteractionDetector
  └─ BPC_ActiveItemSystem
  └─ BPC_EquipmentSlotSystem
  └─ BPC_ConsumableSystem
  └─ BPC_KeyItemSystem

World Actors
  └─ implement I_Interactable (define their own data)
  └─ implement I_Damageable (if destructible)
  └─ implement I_Persistable (if world-state must save)
  └─ BP_RoomAudioZone (acoustic zones)
  └─ BP_PlanarCaptureActor → Mirror/Portal/Monitor/Horror/FakeWindow surfaces
  └─ SS_PlanarCaptureManager (World Subsystem — auto-created per world)
```

**Communication Priority:**
1. Gameplay Tags + Subsystem lookup (global, decoupled)
2. Interface calls (local, type-safe)
3. Event Dispatchers (one-to-many, fire-and-forget)
4. Direct reference (only within a tightly-coupled actor-component pair that is always co-located)

---

## Full System Map

| # | Category | Systems Count |
|---|----------|--------------|
| 0 | Project Setup & Starter | 1 |
| 1 | Core Framework Systems | 7 |
| 2 | Player State & Embodiment | 8 (+2 controller/state stubs) |
| 3 | Interaction & World Manipulation | 8 |
| 4 | Inventory, Items & Collectibles | 11 |
| 5 | Save, Load, Persistence & Death Loop | 9 |
| 6 | UI, Menus & Diegetic Presentation | 14 |
| 7 | Narrative, Dialogue, Objective & Choice | 11 |
| 8 | Weapons, Equipment & Damage | 11 |
| 9 | AI, Perception & Encounters | 9 |
| 10 | Adaptive Environment, Atmosphere & Scare | 13 + 2 Audio = 15 |
| 11 | Achievements, Progression & Meta | 2 |
| 12 | Settings, Accessibility & Platform | 2 |
| 13 | Polish & Support Systems | 9 |
| 14 | Data Assets (content definitions) | 16 |
| 15 | Enhanced Input System | 1 |
| 16 | State Management | 2 |
| 17 | Planar Capture System | 12 |
| **Total** | | **147 numbered + 1 starter = 148 specs** |

> **Note:** The full spec index lives in [`docs/blueprints/INDEX.md`](docs/blueprints/INDEX.md). Each of the 147 numbered systems has a detailed blueprint specification with a Manual Implementation Guide. The design document below describes the *architecture and intent* of each system; the spec files define the *exact enum values, structs, variables, functions, and node-by-node implementation logic*.

---

# 1. Core Framework Systems

*These systems form the skeleton of every project. They handle global state, service access, utility functions, event routing, and data architecture. Nothing in the game should bypass this layer.*

---

### GI_GameFramework — GameInstance

**Purpose:**
The single persistent object that lives for the entire application session. It owns global subsystems, manages save slot ownership, and provides the canonical entry point for service resolution.

**Responsibilities:**
- Initialize and hold all GameInstance Subsystems on startup
- Manage which save slot is currently active
- Provide a static-style accessor pattern so any Blueprint can request a subsystem without needing a direct reference
- Store transient cross-level flags (e.g. which cutscene just played, current chapter)
- Route platform-specific init (Steam, PlayStation, Xbox)

**Does NOT Handle:**
- Game logic, AI, combat, narrative content
- Level streaming decisions
- UI construction

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `ActiveSaveSlotIndex` | Integer | Which save slot is loaded (0–N) |
| `SessionFlags` | Map (GameplayTag → Bool) | Transient flags that do not persist to disk |
| `CurrentGamePhase` | E_GamePhase | Enum tracking broad phase (MainMenu, InGame, Paused, Loading, DeathLoop, Credits) |
| `PlatformType` | E_PlatformType | Steam / PlayStation / Xbox / Generic |
| `bFirstLaunch` | Bool | True on first-ever boot; triggers intro flow |

**Enums:**

| Enum | Values | Description |
|------|--------|-------------|
| `E_GamePhase` | MainMenu, Loading, InGame, Paused, Cutscene, DeathLoop, AltDeathSpace, Credits, PostGame | Top-level game phase |
| `E_PlatformType` | Steam, PlayStation, Xbox, Switch, Generic | Platform identity for service abstraction |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `GetSubsystem` | Tag: GameplayTag | Object Reference | Returns the requested subsystem by tag lookup |
| `SetSessionFlag` | Tag, Value: Bool | — | Sets a transient session flag |
| `GetSessionFlag` | Tag | Bool | Reads a transient session flag |
| `SetActiveSlot` | SlotIndex: Int | — | Designates the active save slot |
| `SetGamePhase` | Phase: E_GamePhase | — | Updates CurrentGamePhase and broadcasts dispatcher |
| `InitPlatformServices` | — | — | Called on Init; routes to Steam/PS/Xbox wrappers |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnGamePhaseChanged` | NewPhase: E_GamePhase | Any phase transition |
| `OnPlatformReady` | PlatformType: E_PlatformType | Platform services confirm ready |

**Communicates With:**

| Target System | Method | Why |
|---------------|--------|-----|
| All SS_ Subsystems | Direct reference (owns them) | Lifecycle management |
| GM_CoreGameMode | Dispatcher (phase changes) | Sync game mode to phase |
| WBP_HUDController | Dispatcher | HUD reacts to phase changes |

**Blueprint Flow:**
```
[BeginPlay / Init]
  └─► InitPlatformServices()
  └─► Create all SS_ Subsystems
  └─► Load persistent settings (SS_SettingsSystem)
  └─► Check for existing save data (SS_SaveManager)
  └─► SetGamePhase(MainMenu)
  └─► Broadcast OnGamePhaseChanged
```

**Reuse Notes:**
Replace `E_PlatformType` routing with new platform entries. Add new subsystems to the init list. The `SessionFlags` map lets you add per-project transient state without touching this class.

---

### SS_SaveManager — GameInstance Subsystem (35)

**C++ Status:** ✅ Full implementation — `Source/PG_Framework/Public/Save/SS_SaveManager.h`

**Purpose:**
Handles all serialisation and deserialisation of game state to disk. Supports multiple save slots, checkpoint saves, hard saves, and world object persistence. C++ uses `FArchive` for direct binary serialization — far more powerful than Blueprint `SaveGame`/`LoadGame` nodes.

**Responsibilities:**
- Write and read `USaveGame`-derived objects per slot
- Maintain a manifest of available save slots (timestamp, chapter, thumbnail data)
- Coordinate with `BPC_PersistableWorldState` for world object delta saves
- Notify all `I_Persistable` implementors to collect/restore their state on save/load
- Handle save versioning and migration stubs

**Does NOT Handle:**
- Deciding when to save (that is `BPC_CheckpointSystem`'s job)
- UI display of save slots (that is `WBP_SaveSlotList`)
- Death loop logic

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `SaveSlotManifest` | Array of S_SaveSlotInfo | Metadata for all available slots |
| `ActiveSaveObject` | SaveGame Object Ref | The currently loaded save data object |
| `bIsSaving` | Bool | Prevents concurrent save operations |
| `SaveVersion` | Integer | Schema version for migration |
| `WorldStateDelta` | Map (Name → S_WorldObjectState) | Persisted changes to world objects |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_SaveSlotInfo` | SlotIndex, DisplayName, Timestamp, ChapterTag, ThumbnailBytes | Save slot manifest entry |
| `S_WorldObjectState` | ObjectTag, bDestroyed, CustomData (Map) | Per-object world delta record |
| `S_PlayerSnapshot` | Health, Stress, Stamina, Position, Rotation, InventoryData, NarrativeFlags | Full player state capture |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `SaveToSlot` | SlotIndex, SaveType: E_SaveType | Bool (success) | Orchestrates full save: collects state, writes to disk |
| `LoadFromSlot` | SlotIndex | Bool (success) | Reads disk, distributes state to I_Persistable actors |
| `DeleteSlot` | SlotIndex | — | Removes save file and manifest entry |
| `GetSlotManifest` | — | Array S_SaveSlotInfo | Returns all slot metadata for UI |
| `CollectWorldState` | — | — | Iterates all I_Persistable actors and calls CollectState() |
| `DistributeWorldState` | — | — | Iterates all I_Persistable actors and calls RestoreState() |
| `MigrateSaveVersion` | OldVersion, Data | MigratedData | Upgrades old save schema |
| `SaveCheckpoint` | CheckpointTag | — | Saves checkpoint data to active slot (no slot prompt) |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnSaveComplete` | SlotIndex, SaveType | Save operation finishes |
| `OnLoadComplete` | SlotIndex | Load operation finishes |
| `OnSaveFailed` | ErrorCode | Save fails (disk full, etc.) |

**Enums:**

| Enum | Values | Description |
|------|--------|-------------|
| `E_SaveType` | Checkpoint, HardSave, AutoSave, DeathStateSave | Categorizes save triggers |

**Communicates With:**

| Target System | Method | Why |
|---------------|--------|-----|
| All I_Persistable actors | Interface | Collect/restore world state |
| BPC_CheckpointSystem | Dispatcher (receives trigger) | Checkpoint saves routed here |
| WBP_SaveLoadMenu | Dispatcher | UI updates after save/load |
| GI_GameFramework | Direct (owned by) | Access active slot index |

**Blueprint Flow:**
```
[SaveToSlot called]
  └─► Set bIsSaving = true
  └─► Collect player snapshot (via PC_CoreController)
  └─► CollectWorldState() → iterate I_Persistable actors
  └─► Write SaveGame object to disk
  └─► Update SaveSlotManifest
  └─► Set bIsSaving = false
  └─► Broadcast OnSaveComplete

[LoadFromSlot called]
  └─► Read SaveGame from disk
  └─► MigrateSaveVersion() if needed
  └─► Restore player snapshot
  └─► DistributeWorldState() → iterate I_Persistable actors
  └─► Broadcast OnLoadComplete
```

**Reuse Notes:**
Add new fields to `S_PlayerSnapshot` per project. The `WorldStateDelta` map handles any actor without refactoring. Swap `USaveGame` subclass per project.

---

### SS_AchievementSystem — GameInstance Subsystem

**Purpose:**
Platform-agnostic achievement and trophy tracking system. Handles unlock logic, progress tracking, and platform service submission.

*(Full detail in Section 11)*

---

### SS_SettingsSystem — GameInstance Subsystem

**Purpose:**
Persists and distributes audio, graphics, controls, and accessibility settings across sessions.

*(Full detail in Section 12)*

---

### DA_GameTagRegistry — Primary Data Asset (01)

**C++ Status:** ✅ Full implementation — `Source/PG_Framework/Public/Core/DA_GameTagRegistry.h`

**Purpose:**
Centralises all Gameplay Tag definitions used across the framework. Wraps `UGameplayTagsManager` APIs directly in C++, bypassing the Data Table proxy workaround required in Blueprint. The Data Table array (`TagDataTables` — 11 entries) is maintained for Blueprint implementations.

**Responsibilities:**
- Define all framework-level tags (Player.State.*, Interaction.Type.*, Narrative.Flag.*, etc.)
- Provide the canonical tag namespace so no system uses raw FName comparisons
- Document each tag's meaning inline via comments in the ini
- Provide `GetAllRegisteredTags()`, `ValidateTag()`, `RequestTag()`, `ExportTagNamespace()` in C++ (BlueprintCallable)

**Tag Namespace Structure:**
```
Player.State.Alive
Player.State.Dead
Player.State.Hidden
Player.State.Interacting
Player.Stress.Low / Mid / High / Critical
Player.Posture.Standing / Crouching / Prone / Vaulting

Interaction.Type.Pickup / Door / Drawer / Container / Inspect / Climb / Hide / Use / Combine
Interaction.Context.Requires.Key / Requires.Item / Locked / Disabled

Item.Type.Weapon / Consumable / KeyItem / Document / Collectible / Ammo / Tool
Item.Slot.PrimaryWeapon / SecondaryWeapon / Flashlight / Shield / Active

Narrative.Flag.*          ← game-specific flags live here
Narrative.Phase.*         ← story chapters / acts
Narrative.Choice.*        ← choice consequence tags
Narrative.Ending.*        ← ending conditions

Objective.Status.Active / Complete / Failed / Hidden
AI.Alert.None / Suspicious / Alerted / Engaged
AI.Archetype.Patrol / Ambush / Stalker / Passive

Save.Type.Checkpoint / HardSave / AutoSave
Achievement.*             ← per-achievement tags

Environment.Atmosphere.*  ← current atmosphere state tags
Environment.Scare.*       ← scare event tags

DeathSpace.Active         ← triggers alt death space layer
```

**Reuse Notes:**
The `Narrative.Flag.*` and `Narrative.Phase.*` namespaces are blank by default — fill them per project. All other namespaces are reusable as-is.

---

### FL_GameUtilities — Function Library

**Purpose:**
A static Blueprint Function Library providing common utility functions available everywhere without needing an object reference.

**Responsibilities:**
- Math helpers (remapping, lerp clamped, vector utilities)
- Actor utility (find component by class, find nearest actor with tag)
- Gameplay Tag utilities (tag container checks, add/remove helpers)
- String/text formatting (time display, pluralisation, ordinal numbers)
- Screen utilities (world to screen, clamp to viewport)
- Debug helpers (coloured screen log, toggleable via build config)

**Key Functions:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `GetSubsystemSafe` | WorldContext, SubsystemClass | Subsystem Reference | Null-safe subsystem retrieval |
| `FindComponentByInterface` | Actor, InterfaceClass | Component | Returns first component implementing an interface |
| `RemapFloat` | Value, InMin, InMax, OutMin, OutMax | Float | Linear remap |
| `FormatTime` | Seconds: Float | FText | "00:00" formatted display |
| `HasGameplayTag` | Actor, Tag | Bool | Safe gameplay tag container check |
| `AddTagToActor` | Actor, Tag | — | Adds gameplay tag to actor's tag container |
| `LogDebug` | Category, Message, Colour | — | Conditional screen/log output (editor-only) |
| `GetGameFramework` | WorldContext | GI_GameFramework | Typed GameInstance cast helper |
| `GetPlayerController` | WorldContext | PC_CoreController | Typed controller cast helper |

**Reuse Notes:**
This library ships verbatim to every project. Add project-specific helpers in a separate `FL_ProjectUtilities` child library.

---

### I_InterfaceLibrary — Interface Collection

*This is a conceptual grouping of all framework interfaces. Each is its own `BlueprintInterface` asset.*

**Core Interfaces:**

| Interface | Key Functions | Implemented By |
|-----------|--------------|----------------|
| `I_Interactable` | `GetInteractionData()`, `OnInteract(Instigator)`, `CanInteract(Instigator) → Bool` | All world-interactive actors |
| `I_Damageable` | `ReceiveDamage(Amount, Type, Instigator)`, `GetCurrentHealth() → Float`, `IsDead() → Bool` | Player, enemies, destructibles |
| `I_Persistable` | `CollectState() → S_WorldObjectState`, `RestoreState(Data: S_WorldObjectState)` | Any actor that saves world state |
| `I_Holdable` | `OnPickUp(Holder)`, `OnDrop(Location)`, `GetHoldOffset() → Transform` | Pickupable / draggable objects |
| `I_Equippable` | `OnEquip(Holder)`, `OnUnequip()`, `GetEquipmentData() → S_EquipmentData` | Weapons, tools, equipment |
| `I_HidingSpot` | `OnPlayerEnter()`, `OnPlayerExit()`, `GetHideCapacity() → Int` | Closets, under-bed actors |
| `I_NarrativeActor` | `OnNarrativeFlagChanged(Tag, Value)` | Actors that react to story state |
| `I_DiegeticDisplay` | `SetDiegeticValue(Tag, Value)`, `RefreshDisplay()` | Diegetic HUD display elements |
| `I_ScareTarget` | `OnScareEventFired(ScareTag)` | Actors that respond to scare events |

**Reuse Notes:**
All interfaces are project-agnostic. Add project-specific interfaces in a `I_Project*` namespace. All 9 interfaces are defined in C++ (`Source/PG_Framework/Public/Core/I_InterfaceLibrary.h`) with `BlueprintNativeEvent` — implement them in Blueprint actors.

---

### SS_EnhancedInputManager — GameInstance Subsystem (128)

**C++ Status:** ✅ Full implementation — `Source/PG_Framework/Public/Input/SS_EnhancedInputManager.h`

**Purpose:**
Sole authority for Push/Pop input context, key rebinding, and input mode changes. All gameplay systems query input state through this manager — never through raw Enhanced Input calls.

**Responsibilities:**
- Manage a priority-ordered context stack (Default(0) < Hiding(5) < WristwatchUI(10) < Inspection(20) < UI(100))
- Push/Pop `UInputMappingContext` assets with duplicate protection
- Coordinate input mode (Game/UI) with `SS_UIManager` — cursor visibility, input blocking
- Handle key rebinding requests and persist via `SS_SettingsSystem`
- Provide `IsActionPressed()`, `GetActionValue()` queries for gameplay systems

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `ContextStack` | Array of FInputContextEntry | Ordered by priority, highest at top |
| `DefaultContexts` | Array of UInputMappingContext | Loaded on Initialize |
| `bCurrentUIMode` | Bool | UI mode active |

**Input Assets to Create (in UE5 editor):**
- 22 `IA_*` Input Action assets (IA_Move, IA_Look, IA_Jump, IA_Sprint, IA_Interact, IA_Fire, IA_Aim, IA_Reload, IA_Melee, IA_Block, IA_UseItem, IA_Hotkey1-8, IA_NextItem, IA_PreviousItem, IA_Pause, IA_Inventory, IA_Journal, IA_Map, IA_SkipCutscene, IA_SkipDialogue, IA_Grab)
- 5 `IMC_*` Input Mapping Contexts (IMC_Default, IMC_Hiding, IMC_WristwatchUI, IMC_Inspection, IMC_UI)
- `DA_InputMappingProfile` (129) — per-platform binding Data Asset

**Full Spec:** [`docs/architecture/enhanced-input-system.md`](docs/architecture/enhanced-input-system.md)

---

### GM_CoreGameMode — GameMode

**Purpose:**
Sets the rules of the game session: which pawn, controller, player state, HUD, and game state classes to use. Manages level-phase transitions.

**Responsibilities:**
- Define default classes (pawn, controller, HUD, player state, game state)
- Manage game phase transitions (via GI_GameFramework)
- Handle win/loss routing
- Trigger chapter/level transitions
- Enforce rules (e.g. pause disabled during certain narrative moments)

**Does NOT Handle:**
- Gameplay logic (that's components on actors)
- UI construction
- Save/load (that's SS_SaveManager)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `DefaultPawnClass` | Class | GASP-based player pawn |
| `DefaultControllerClass` | Class | PC_CoreController |
| `DefaultPlayerStateClass` | Class | PS_CorePlayerState |
| `DefaultGameStateClass` | Class | GS_CoreGameState |
| `bPauseAllowed` | Bool | Runtime flag disabling pause during scripted moments |
| `CurrentChapterTag` | GameplayTag | Active chapter/level tag |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `TransitionToChapter` | ChapterTag | — | Loads next level, sets chapter tag |
| `TriggerGameOver` | Cause: E_DeathCause | — | Routes to death handler or alt death space |
| `TriggerEnding` | EndingTag | — | Passes ending tag to ending accumulator |
| `SetPauseAllowed` | bAllowed | — | Enables/disables pause permission |
| `HandlePlayerDead` | — | — | Called by death system; routes respawn or game-over |

**Communicates With:**

| Target System | Method | Why |
|---------------|--------|-----|
| GI_GameFramework | Direct | Phase transitions |
| BPC_DeathHandlingSystem | Dispatcher | Receives death event |
| SS_SaveManager | Direct | Load checkpoint on respawn |
| BPC_NarrativeSystem | Interface | Chapter start/end hooks |

**Blueprint Flow:**
```
[Player Dies]
  └─► BPC_DeathHandlingSystem fires OnPlayerDied dispatcher
  └─► GM_CoreGameMode receives → HandlePlayerDead()
      ├─► Has alt death space? → SetGamePhase(AltDeathSpace)
      └─► No → SetGamePhase(Loading) → SS_SaveManager.LoadCheckpoint
```

**Reuse Notes:**
Override default class references per project. `TransitionToChapter` can use level streaming or full level load. `TriggerEnding` is the only project-specific hook.

---

### GS_CoreGameState — GameState

**Purpose:**
Replicable (for potential co-op future) game state visible to all players. Tracks session-level progression state.

**Responsibilities:**
- Track elapsed play time
- Store current chapter tag
- Track active narrative phase
- Store encounter director state (is an encounter active?)
- Broadcast state changes for UI sync

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `ElapsedPlayTime` | Float | Session seconds (accumulates across chapters) |
| `ActiveChapterTag` | GameplayTag | Current story chapter |
| `ActiveNarrativePhase` | GameplayTag | Sub-chapter narrative phase |
| `bEncounterActive` | Bool | Is an AI encounter currently running |
| `ActiveObjectiveTags` | Array of GameplayTag | Currently active objective identifiers |

**Reuse Notes:**
Add multiplayer replication markings if the game adds co-op. Otherwise treat as a lightweight singleton.

---

# 2. Player State & Embodiment Systems

*These systems define everything about the player character's internal state: physical, psychological, and positional. They live as Actor Components on the Player Pawn and communicate upward to the Controller and outward to the UI via dispatchers.*

---

### BPC_HealthSystem — Actor Component

**Purpose:**
Manages the player's hit points, death thresholds, and damage event routing. Decoupled from damage sources — it only cares about receiving health deltas.

**Responsibilities:**
- Track current and maximum health
- Apply damage and healing with type filtering
- Detect and broadcast death threshold crossing
- Support optional health regen (with delay)
- Expose health as a normalised 0–1 float for UI

**Does NOT Handle:**
- How damage is dealt (that's weapons/hazards)
- Death screen or respawn (that's BPC_DeathHandlingSystem)
- UI display (reads from this via dispatcher)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `CurrentHealth` | Float | Current HP |
| `MaxHealth` | Float | Maximum HP |
| `bIsInvincible` | Bool | Ignore damage flag (cutscenes, etc.) |
| `bRegenEnabled` | Bool | Auto-regen on |
| `RegenDelay` | Float | Seconds after last damage before regen starts |
| `RegenRate` | Float | HP per second during regen |
| `DamageResistances` | Map (E_DamageType → Float) | Per-type damage multiplier |
| `DeathThreshold` | Float | HP value at which death fires (default 0) |

**Enums:**

| Enum | Values | Description |
|------|--------|-------------|
| `E_DamageType` | Physical, Fire, Psychic, Environmental, InstantKill, Scripted | Damage categorisation |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_DamageEvent` | Amount, Type: E_DamageType, Instigator, HitLocation, HitNormal | Full damage context |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `ApplyDamage` | DamageEvent: S_DamageEvent | — | Applies resistance, subtracts HP, broadcasts |
| `ApplyHealing` | Amount: Float | — | Adds HP clamped to max |
| `GetHealthNormalised` | — | Float | Returns CurrentHealth / MaxHealth |
| `SetMaxHealth` | NewMax | — | Updates max, clamps current |
| `SetInvincible` | bInvincible | — | Toggle invincibility |
| `KillInstant` | — | — | Forces death regardless of current HP |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnHealthChanged` | NewHealth, Delta, DamageType | Any HP change |
| `OnDeath` | DamageCause: S_DamageEvent | HP reaches DeathThreshold |
| `OnHealthCritical` | CurrentHealth | HP drops below 20% |

**Communicates With:**

| Target System | Method | Why |
|---------------|--------|-----|
| BPC_DeathHandlingSystem | Dispatcher (OnDeath) | Trigger death sequence |
| BPC_StressSystem | Dispatcher (OnHealthCritical) | Low HP raises stress |
| WBP_HUDController | Dispatcher (OnHealthChanged) | UI health display |
| BPC_PlayerMetricsTracker | Dispatcher | Track damage received |

**Blueprint Flow:**
```
[ApplyDamage called]
  └─► bIsInvincible? → return
  └─► Apply DamageResistances multiplier
  └─► CurrentHealth -= DamageAmount
  └─► Clamp to (DeathThreshold, MaxHealth)
  └─► Broadcast OnHealthChanged
  └─► CurrentHealth <= DeathThreshold? → Broadcast OnDeath
  └─► CurrentHealth < 20%? → Broadcast OnHealthCritical
```

**Reuse Notes:**
Add new `E_DamageType` values per project. DamageResistances map makes this work for any genre. Disable regen for hardcore modes.

---

### BPC_StressSystem — Actor Component

**Purpose:**
Tracks the player's psychological stress / sanity level. Drives hallucination triggers, audio distortion, and adaptive atmosphere responses.

**Responsibilities:**
- Accumulate stress from events (nearby monster, health critical, dark exposure, scripted triggers)
- Decay stress over time in safe conditions
- Broadcast stress tier changes (Low/Mid/High/Critical)
- Expose normalised stress value for UI and adaptive systems
- Gate stress via gameplay tags (bStressImmune for cutscenes)

**Does NOT Handle:**
- What happens when stress is high (that's BPC_AdaptiveAtmosphereController, scare system)
- Hallucination visuals (that's screen effect system)
- Audio distortion (that's audio atmosphere controller)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `CurrentStress` | Float | 0.0–100.0 |
| `StressDecayRate` | Float | Units per second decay in safe state |
| `bIsSafe` | Bool | Is player in a designated safe zone |
| `StressThresholds` | S_StressThresholds | Breakpoints for Low/Mid/High/Critical |
| `ActiveStressSources` | Array of GameplayTag | Tags of active ongoing stress sources |
| `CurrentTier` | E_StressTier | Current stress tier |

**Enums:**

| Enum | Values | Description |
|------|--------|-------------|
| `E_StressTier` | Calm, Low, Mid, High, Critical | Quantised stress state |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_StressThresholds` | LowMin, MidMin, HighMin, CriticalMin: Float | Tier breakpoints |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `AddStress` | Amount, SourceTag | — | Increases stress, adds source tag |
| `RemoveStress` | Amount, SourceTag | — | Decreases stress, removes source tag |
| `AddStressSource` | SourceTag, Rate: Float | — | Registers ongoing stress source (ticks per second) |
| `RemoveStressSource` | SourceTag | — | Deregisters ongoing source |
| `SetSafe` | bSafe | — | Enters/exits safe state |
| `GetStressNormalised` | — | Float | 0–1 value for UI/shaders |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnStressTierChanged` | OldTier, NewTier: E_StressTier | Tier boundary crossed |
| `OnStressChanged` | CurrentStress: Float | Any stress delta |
| `OnStressCritical` | — | Critical tier entered |

**Reuse Notes:**
Rename "Stress" to "Sanity", "Corruption", "Fear" or any thematic label per project by replacing display text in UI only. The numeric logic is identical.

---

### BPC_StaminaSystem — Actor Component

**Purpose:**
Manages the player's stamina pool used for sprinting, actions, and physical exertion.

**Responsibilities:**
- Track current and maximum stamina
- Drain stamina during active consumption (sprint, melee, climb)
- Regen stamina when not consuming
- Gate actions that require minimum stamina thresholds
- Broadcast depletion and recovery events

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `CurrentStamina` | Float | 0–MaxStamina |
| `MaxStamina` | Float | Upper cap |
| `DrainRates` | Map (GameplayTag → Float) | Per-action drain rates (Sprint.Drain, Melee.Drain) |
| `RegenRate` | Float | Units per second recovery |
| `RegenDelay` | Float | Delay after last drain |
| `MinActionThresholds` | Map (GameplayTag → Float) | Minimum stamina to start an action |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnStaminaChanged` | NewStamina: Float | Any change |
| `OnStaminaDepleted` | — | Reaches 0 |
| `OnStaminaRecovered` | — | Returns to full |

**Reuse Notes:**
The `DrainRates` map handles any future action type without modifying this component.

---

### BPC_MovementStateSystem — Actor Component

**Purpose:**
Tracks and communicates the player's movement and posture state. Acts as the authoritative source for "what is the player's body doing" so all other systems query here instead of reading raw velocity.

**Responsibilities:**
- Track posture (Standing, Crouching, Prone, Vaulting, Climbing, Hanging)
- Track movement mode (Idle, Walking, Jogging, Sprinting)
- React to GASP locomotion state changes via Animation Notify
- Broadcast state changes to stamina, audio foley, and adaptive systems
- Provide helpers: `IsMoving()`, `IsCrouching()`, `IsGrounded()`

**Enums:**

| Enum | Values | Description |
|------|--------|-------------|
| `E_PostureState` | Standing, Crouching, Prone, Vaulting, Climbing, Hanging, Ragdoll | Body posture |
| `E_MovementMode` | Idle, Walking, Jogging, Sprinting, Sneaking | Locomotion speed tier |

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `CurrentPosture` | E_PostureState | Current body posture |
| `CurrentMovementMode` | E_MovementMode | Current speed mode |
| `bIsGrounded` | Bool | True when on ground |
| `bIsMoving` | Bool | True when velocity > threshold |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnPostureChanged` | OldPosture, NewPosture | Any posture transition |
| `OnMovementModeChanged` | OldMode, NewMode | Any speed mode change |

**Reuse Notes:**
GASP already drives locomotion. This component is a read-only state mirror. Wire it to GASP's output events on init.

---

### BPC_HidingSystem — Actor Component

**Purpose:**
Manages the player entering and exiting hiding spots. Coordinates with the `I_HidingSpot` interface on world actors.

**Responsibilities:**
- Detect nearby valid hiding spots (line trace / overlap)
- Handle enter/exit transition (play animation, suppress movement, apply gameplay tag)
- Add/remove `Player.State.Hidden` gameplay tag
- Communicate hidden state to AI perception system
- Support optional peek-out mechanic

**Does NOT Handle:**
- AI vision (that's BPC_PerceptionSystem on AI)
- Scare events while hiding
- Movement control (that's GASP)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `CurrentHidingSpot` | Actor Reference | Active hiding spot actor |
| `bIsHiding` | Bool | Currently hidden |
| `HideDetectionRadius` | Float | Radius to detect nearby spots |
| `HideTransitionTime` | Float | Animation blend time |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnHideEntered` | HidingSpot: Actor | Player enters hiding |
| `OnHideExited` | HidingSpot: Actor | Player leaves hiding |

**Communicates With:**

| Target System | Method | Why |
|---------------|--------|-----|
| I_HidingSpot implementors | Interface | Enter/exit calls |
| BPC_AdaptiveEnvironmentReactor | Dispatcher | Track hiding frequency |
| AI_PerceptionSystem | Gameplay Tag | Hidden tag suppresses AI detection |

---

### BPC_EmbodimentSystem — Actor Component

**Purpose:**
Manages first-person body awareness: hand/arm visibility, body-tilt IK, head-bob, breath effects, and contextual pose overrides.

**Responsibilities:**
- Drive first-person arm IK offsets based on posture and stress
- Play breath animations during high stress
- Apply head-bob to camera based on movement speed
- Expose hooks for GASP's motion matching to layer diegetic body poses
- Trigger "look down to see feet" trace

**Does NOT Handle:**
- Camera FOV (that's BPC_CameraStateLayer)
- Stress values (reads from BPC_StressSystem)
- Actual animation blueprint logic (drives variables; ABP reads them)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `BreathIntensity` | Float | 0–1 driven by stress |
| `ArmSwayIntensity` | Float | Lateral sway based on stress |
| `HeadBobScale` | Float | Bob intensity multiplier |
| `bShowBody` | Bool | Visibility of first-person body mesh |
| `LookDownHitDistance` | Float | Trace distance for foot visibility |

**Communicates With:**

| Target System | Method | Why |
|---------------|--------|-----|
| BPC_StressSystem | Dispatcher | Read stress to drive breath/sway |
| BPC_MovementStateSystem | Direct | Read speed for head-bob |
| ABP_PlayerBody | Direct (anim var write) | Push IK parameters |
| BPC_CameraStateLayer | Event | Coordinate camera effects |

---

### BPC_CameraStateLayer — Actor Component

**Purpose:**
Manages camera state modifiers layered on top of GASP's camera manager. Handles FOV, camera shake, effect triggers, and transition blending.

**Responsibilities:**
- Apply FOV changes (sprint widening, ADS narrowing, stress distortion)
- Trigger camera shakes (footsteps, impacts, explosions, jump scare)
- Manage transitions between camera states (normal → ADS → inspect → cinematic)
- Protect GASP's base camera values from being stomped

**Does NOT Handle:**
- Camera physics/spring arm (GASP owns this)
- Rendering effects (BPC_ScreenEffectController)
- Cutscene cameras (sequencer owns those)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `BaseFOV` | Float | Default FOV (read from settings) |
| `CurrentFOVModifier` | Float | Additive FOV delta |
| `ActiveCameraState` | E_CameraState | Current camera mode |
| `ShakeQueue` | Array of S_CameraShakeRequest | Pending shakes |

**Enums:**

| Enum | Values | Description |
|------|--------|-------------|
| `E_CameraState` | Normal, ADS, Inspect, Cinematic, DeathCam, HideCam | Camera mode |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `SetCameraState` | NewState: E_CameraState | — | Transitions camera mode |
| `ApplyFOVModifier` | Delta, BlendTime | — | Temporarily modifies FOV |
| `TriggerShake` | ShakeClass, Intensity | — | Plays a camera shake |
| `ResetFOV` | BlendTime | — | Returns to BaseFOV |

---

### BPC_PlayerMetricsTracker — Actor Component

**Purpose:**
Silently records player behaviour data throughout the session to drive adaptive systems and run summaries.

**Responsibilities:**
- Count kills, deaths, items found, hiding frequency, exploration completeness
- Track playstyle tags (aggressive, cautious, explorer, speedrunner)
- Record time spent in each area/chapter
- Provide data to the Playstyle Classifier and Run Summary systems
- Never directly affect gameplay — read-only output

**Does NOT Handle:**
- Achievements (SS_AchievementSystem reads from this)
- Adaptive decisions (BPC_PlaystyleClassifier reads from this)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `DeathCount` | Integer | Session deaths |
| `HideCount` | Integer | Times hidden from AI |
| `ItemsCollected` | Integer | Total items picked up |
| `DistanceTravelled` | Float | World units walked/run |
| `AggressionScore` | Float | Weighted aggression metric |
| `CautionScore` | Float | Weighted caution metric |
| `ExplorationScore` | Float | % of optional areas visited |
| `BehaviourEventLog` | Array of S_BehaviourEvent | Timestamped event log |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_BehaviourEvent` | EventTag, Timestamp, Context | Single logged player action |

**Communicates With:**

| Target System | Method | Why |
|---------------|--------|-----|
| BPC_PlaystyleClassifier | Direct (read) | Drives adaptive classification |
| SS_AchievementSystem | Direct (read) | Achievement progress data |
| BPC_RunSummarySystem | Direct (read) | Post-game summary |

---

# 2.5. State Management — Central State Authority

*These two systems form the central nervous system of the framework. Every gameplay system queries `BPC_StateManager.IsActionPermitted(Tag)` instead of checking other systems' states directly. This decouples all 135 systems from each other.*

---

### BPC_StateManager — Actor Component (130) — on Player Pawn

**C++ Status:** ✅ Full implementation — `Source/PG_Framework/Public/Player/BPC_StateManager.h`

**Purpose:**
The single source of truth for "what can the player do right now?" Manages exclusive action states (42), upper-body overlay states (18), action gating, vital signs (heart rate), and the force-stack pattern for nested overrides (death, cutscenes, void space).

**Responsibilities:**
- Accept state change requests from any system via `RequestStateChange(NewState, Requester)`
- Evaluate gating rules from `DA_StateGatingTable` (37 rules) to permit or deny actions
- Maintain a force stack — death/cutscenes push a forced state, `RestorePreviousState()` pops
- Track and smooth heart rate BPM based on stress tier + stamina exhaustion + combat
- Broadcast `OnActionStateChanged`, `OnOverlayStateChanged`, `OnVitalSignChanged`, `OnForceStackPushed/Popped`

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `CurrentActionState` | GameplayTag | Currently active exclusive action (only one) |
| `CurrentOverlayState` | GameplayTag | Upper-body overlay (aiming, reloading, etc.) |
| `GatingTable` | DA_StateGatingTable | 37 gating rules |
| `HeartRateBPM` | Float | Smoothed heart rate (60–180+) |
| `HeartRateTier` | EHeartRateTier | Resting/Elevated/Stressed/Panic/Critical |
| `ForceStack` | Array of (State, Reason) | Nested force override history |

**Core Query (Hot Path):**
```
IsActionPermitted(ActionTag) → Bool
  └─ Check force stack → blocked?
  └─ Evaluate gating rules → blocked?
  └─ Return true/false
```

**Communicates With:**

| Target System | Method | Why |
|---------------|--------|-----|
| ALL gameplay systems (10+) | `IsActionPermitted()` query | Per-frame action validation |
| BPC_HealthSystem | Direct bind | Death triggers force state |
| BPC_StaminaSystem | Direct bind | Exhaustion affects heart rate |
| BPC_StressSystem | Direct bind | Stress tier drives heart rate |
| BPC_MovementStateSystem | Direct bind | Movement mode affects state |
| DA_StateGatingTable | Direct reference | Reads gating rules |

---

### DA_StateGatingTable — Primary Data Asset (131)

**C++ Status:** 🟡 Stub — `Source/PG_Framework/Public/State/DA_StateGatingTable.h` (struct + query method)

**Purpose:**
Defines all state gating rules in one Data Asset. Designers modify rules here without touching Blueprints or C++.

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `GatingRules` | Array of FStateGatingRule | 37 rules: ActionTag, BlockedByState, bIsBlocked |

**Examples:**
- `Framework.Action.FireWeapon` blocked by `Framework.State.Action.Dead` → true
- `Framework.Action.Sprint` blocked by `Framework.State.Action.Hiding` → true
- `Framework.Action.Jump` blocked by `Framework.State.Action.Dead` → true

**Required Enums (create in UE5 editor):**
- `E_PlayerActionState` — 42 exclusive action states (Idle, Sprinting, Hiding, Dead, InCutscene, etc.)
- `E_OverlayState` — 18 upper-body overlay states (AimingDownSights, Reloading, Inspecting, etc.)
- `E_ActionRequestResult` — 8 result codes (Granted, Denied, BlockedByForce, AlreadyActive, etc.)
- `E_PlayerVitalSignals` — 5 vital tiers (Resting, Elevated, Stressed, Panic, Critical)

**Full Spec:** [`docs/architecture/bpc-statemanager.md`](docs/architecture/bpc-statemanager.md) — enum values, gating table, force stack pattern, Chooser Table audit.

---

# 2.6. Planar Capture System — Mirrors, Portals, Monitors & Horror Surfaces

*Systems 136-147 form a unified rendering pipeline for reflective and transmissive surfaces. A global World Subsystem manages quality budgets across all captures, while a single master material with 9 parameter-driven layers handles all visual effects from clean mirrors to horror wrong-reflections.*

---

### BPC_PlanarCapture — Actor Component (136) — on capture surface actors

**C++ Status:** ✅ Full implementation — `Source/PG_Framework/Public/Capture/BPC_PlanarCapture.h`

**Purpose:**
Core capture component managing `USceneCaptureComponent2D` lifecycle. Performs camera math per mode (mirror reflection, portal relative, fixed monitor), manages render target allocation, show/hide actor lists, and horror-feature actuation.

**Responsibilities:**
- Own `USceneCaptureComponent2D` — create, configure, destroy
- Compute capture camera transform per mode (mirror/portal/monitor/fake window)
- Apply quality tier profiles (render target size, capture interval, show flags)
- Manage ShowOnly/Hidden actor lists for selective rendering
- Actuate horror features: wrong-reflection swap, delayed frame ring buffer
- Push MPC parameters each frame (steam, dirt, darkness, etc.)
- Accept scripted priority overrides from gameplay systems

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `CaptureMode` | EPlanarCaptureMode | Mirror / Portal / Monitor / HorrorMirror / HorrorPortal / FakeWindow |
| `QualityProfiles` | Array of FPlanarCaptureQualityProfile | 4 entries [Low, Medium, High, Hero] — RT size, FPS, feature toggles |
| `CaptureFOV` | Float | Capture camera FOV (default 90) |
| `CurrentQualityTier` | EPlanarCaptureQualityTier | Assigned by SS_PlanarCaptureManager |
| `ShowOnlyActors` | Array of TSoftObjectPtr | Captured exclusively (for horror swaps) |
| `WrongReflectionActor` | TSoftObjectPtr〈AActor〉 | Swapped into ShowOnly on horror trigger |
| `LinkedTargetSurface` | TSoftObjectPtr〈ABP_PlanarCaptureActor〉 | Portal destination |
| `FixedCameraActor` | TSoftObjectPtr〈AActor〉 | Monitor fixed camera reference |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `InitializeCapture` | — | EPlanarCaptureInitResult | Creates SceneCapture2D, allocates RT from pool |
| `ApplyQualityTier` | Tier: EPlanarCaptureQualityTier | — | Applies quality profile: resize RT, update interval, toggle features |
| `CaptureNow` | — | — | Bypasses tick interval for event-driven capture |
| `ActivateHorrorReflection` | — | — | Saves ShowOnly list, swaps to WrongReflectionActor |
| `DeactivateHorrorReflection` | — | — | Restores original ShowOnly list |
| `SetScriptedPriority` | Priority: Float (0–1) | — | Forces higher quality tier for scare moments |
| `ComputeCaptureCameraTransform` | ViewerTransform: FTransform | FTransform | Mode-specific camera placement |

**Communicates With:**

| Target System | Method | Why |
|---------------|--------|-----|
| SS_PlanarCaptureManager | Direct | Receives quality tier assignment |
| UPlanarCaptureCameraUtils | Static calls | Mirror/portal/oblique math |
| MPC_CaptureSurface | Direct | Pushes 10 scalar params per frame |

---

### BP_PlanarCaptureActor — Actor (137) — base for all capture surfaces

**C++ Status:** ✅ Full implementation — `Source/PG_Framework/Public/Capture/BP_PlanarCaptureActor.h`

**Purpose:**
Placeable actor wrapping the BPC_PlanarCapture component. Owns the surface mesh, dynamic material instance, proximity trigger for quality scoring, and registers with the global manager.

**Responsibilities:**
- Own and configure the surface mesh (plane/quad) and material
- Create dynamic material instance from M_CaptureSurface_Master
- Handle proximity overlap events for quality scoring boost
- Register/unregister with SS_PlanarCaptureManager on BeginPlay/EndPlay
- Expose Enable/Disable surface, SetCaptureMode, SetSurfaceMaterial APIs
- Support surface destruction (shatter mirror, break monitor)

**Blueprint Children (139-143):**
- `BP_Mirror` — Standard mirror with dirt/steam/aging layers
- `BP_Portal` — Linked portal with teleport-on-overlap
- `BP_Monitor` — Security screen with fixed camera, scanlines, static noise
- `BP_HorrorMirror` — Horror mirror extending BP_Mirror with wrong-reflection, delayed frame, steam text reveal, scare events
- `BP_FakeWindow` — Architectural fake window with parallax, sublevel streaming, weather overlay

---

### SS_PlanarCaptureManager — World Subsystem (138)

**C++ Status:** ✅ Full implementation — `Source/PG_Framework/Public/Capture/SS_PlanarCaptureManager.h`

**Purpose:**
Global budget manager — one instance per World. Scores every registered capture surface by distance, screen coverage, facing angle, and scripted priority. Assigns quality tiers within budget limits. Owns the shared render target pool.

**Responsibilities:**
- Maintain registry of all active capture surfaces
- Each frame evaluation cycle (0.5s interval): score and assign quality tiers
- Enforce budget limits: MaxHeroSurfaces(1), MaxHighSurfaces(3), MaxMediumSurfaces(6)
- Manage render target pool — allocate, reuse, resize to minimize memory churn
- Support force-tier overrides for cutscenes/scare moments
- Expose global quality cap for lower-end hardware targets

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `GlobalQualityCap` | EPlanarCaptureQualityTier (default: High) | Maximum tier for any surface |
| `MaxHeroSurfaces` | int32 (1) | Max simultaneous Hero captures |
| `MaxHighSurfaces` | int32 (3) | Max simultaneous High captures |
| `MaxMediumSurfaces` | int32 (6) | Max simultaneous Medium captures |
| `MaxTotalRenderTargetMemoryMB` | float (128) | Total RT memory budget |
| `MaxCaptureDistance` | float (10000) | Distance at which surface goes Off |

**Quality Tier Summary:**

| Tier | RT Size | FPS | Shadows | Lumen | Post | Memory |
|------|---------|-----|---------|-------|------|--------|
| Off | — | 0 | — | — | — | 0 |
| Low | 256 | 4 | No | No | No | 256 KB |
| Medium | 512 | 15 | Dynamic | Optional | No | 1 MB |
| High | 1024 | 30 | Full | Yes | Minimal | 4 MB |
| Hero | 2048 | 60 | Full | Yes | Full | 16 MB |

**Communicates With:**

| Target System | Method | Why |
|---------------|--------|-----|
| All capture surface actors | Direct (registry) | Quality tier assignment |
| BPC_PlanarCapture | Direct (ApplyQualityTier) | Per-surface tier application |
| UTextureRenderTarget2D | Direct (create/release) | RT pool management |

---

### PlanarCaptureCameraUtils — Static Math Library

**C++ Status:** ✅ Full implementation — utility class

**Purpose:**
Static BlueprintFunctionLibrary providing mirror reflection math, portal relative transform, oblique near-plane projection, screen coverage estimation, and visibility frustum checks. All pure functions, callable from Blueprint.

**Key Functions:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `ComputeMirroredTransform` | ViewerTransform, MirrorPlaneTransform | FTransform | Reflects camera across mirror plane |
| `ComputePortalTransform` | ViewerTransform, SourceSurface, TargetSurface | FTransform | Maps viewer position to portal exit |
| `ComputeObliqueProjectionMatrix` | FOV, Aspect, Near, Far, ClipPlane, SurfaceTransform | FMatrix | Oblique near-plane for flush portal geometry |
| `ComputeScreenCoverage` | SurfaceBounds, ViewerTransform, FOV, Width, Height | Float (0–1) | Estimates screen-space coverage |
| `IsSurfaceVisibleToViewer` | SurfaceBounds, ViewerTransform, FOV, Aspect, Near, Far | Bool | Frustum visibility check |
| `ComputeCompositeScore` | ScreenCoverage, FacingAngle, Distance, MaxDistance, Priority | Float (0–1) | Quality scoring |

---

### Content Assets (144-147)

| # | System | Type | Purpose |
|---|--------|------|---------|
| 144 | `M_CaptureSurface_Master` | Master Material (Unlit) | 9-layer stack: RT sample, condensation UV distort, fresnel fade, dirt/scratch multiply, steam/fog lerp, steam emissive glow, text reveal mask, mirror darkness, wrong reflection crossfade |
| 145 | `MPC_CaptureSurface` | Material Parameter Collection | 10 global scalar params: SteamIntensity, DirtOpacity, CondensationFlow, DistortionAmplitude, MirrorDarkness, WrongReflectionBlend, TextRevealProgress, SteamEmissiveIntensity, DelayedReflectionBlend, SurfaceAge |
| 146 | `DA_PlanarCaptureProfile` | Data Asset | Per-surface config: default mode, quality overrides, actor lists, material |
| 147 | `MI_Mirror_Clean/Dirty/Steam/Horror` | Material Instances | 7 pre-configured MICs for common surface states |

**Full Architecture Spec:** [`docs/architecture/planar-capture-system.md`](docs/architecture/planar-capture-system.md)

**Game Examples:** [`docs/game/planar-capture-examples.md`](docs/game/planar-capture-examples.md) — 8 capture surfaces placed across Project Void levels

---

# 3. Interaction & World Manipulation Systems

---

### BPC_InteractionDetector — Actor Component (on Player Controller)

**Purpose:**
Performs the line trace and proximity detection to find valid interactable objects in front of the player. Broadcasts the "focused" interactable so the execution system and UI can act.

**Responsibilities:**
- Run a configurable line trace / sphere trace each tick (or on tick-throttle)
- Check if hit actor implements `I_Interactable`
- Call `CanInteract()` on candidate to validate
- Track enter/exit focus events (new target detected, target lost)
- Broadcast focused target for UI interaction prompt

**Does NOT Handle:**
- Executing the interaction (that's BPC_InteractionExecutor)
- What happens during interaction (that's the interactable object itself)
- UI prompt display (that's WBP_InteractionPromptDisplay)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `TraceRange` | Float | Max interaction distance |
| `TraceChannel` | ETraceTypeQuery | Trace collision channel |
| `FocusedActor` | Actor Reference | Currently highlighted interactable |
| `bDetectionEnabled` | Bool | Pause detection during cutscenes |
| `TraceTickRate` | Float | How often to trace (e.g. 0.05s = 20/sec) |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `RunDetectionTrace` | — | Actor (hit) | Performs trace, returns first valid interactable |
| `SetFocusedActor` | NewActor | — | Updates focused actor, fires events |
| `ClearFocus` | — | — | Clears focus, fires OnFocusLost |
| `SetDetectionEnabled` | bEnabled | — | Enable/disable detection |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnFocusGained` | TargetActor, InteractionData: S_InteractionData | New interactable focused |
| `OnFocusLost` | PreviousActor | Player looks away |
| `OnInteractableChanged` | NewActor | Focus changes to different actor |

**Blueprint Flow:**
```
[Tick / Throttled Timer]
  └─► LineTrace from Camera
  └─► Hit something?
      ├─► Implements I_Interactable?
      │     └─► CanInteract(Player)? → SetFocusedActor
      └─► No → ClearFocus()
```

---

### BPC_InteractionExecutor — Actor Component (on Player Controller)

**Purpose:**
Listens for the player's interaction input and executes the focused interactable's logic. Manages interaction state (is an interaction in progress?).

**Responsibilities:**
- Bind to player input action (Interact button)
- Call `OnInteract()` on the currently focused actor via `I_Interactable`
- Handle hold-to-interact timing
- Lock input during interaction animations
- Route to specialised handlers (inspect, hide, drag) based on interaction type

**Does NOT Handle:**
- What happens during the interaction (owned by the interactable)
- Finding which actor to interact with (that's BPC_InteractionDetector)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `bInteractionInProgress` | Bool | Prevents re-triggering |
| `HoldThreshold` | Float | Seconds to hold for hold-type interactions |
| `CurrentInteractionType` | E_InteractionType | From focused actor's data |

**Enums:**

| Enum | Values | Description |
|------|--------|-------------|
| `E_InteractionType` | Tap, Hold, Proximity, Automatic, Continuous | How the interaction is triggered |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `OnInteractPressed` | — | — | Player presses interact |
| `OnInteractReleased` | — | — | Player releases (for hold interactions) |
| `ExecuteInteraction` | TargetActor | — | Calls I_Interactable.OnInteract |
| `BeginHoldInteraction` | TargetActor | — | Starts hold timer |
| `CancelInteraction` | — | — | Aborts in-progress interaction |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnInteractionStarted` | TargetActor, Type | Interaction begins |
| `OnInteractionCompleted` | TargetActor | Interaction finishes |
| `OnInteractionCancelled` | TargetActor | Interrupted |

---

### BPC_InspectItemSystem — Actor Component (on Player Controller)

**Purpose:**
Manages the "pick up and examine" mode where the player rotates and inspects an item in 3D. Supports note/text discovery on inspection.

**Responsibilities:**
- Enter inspect mode: freeze movement, show item in inspect space
- Handle rotation input (mouse/thumbstick spin the item)
- Trigger discovery events when item is rotated to hidden angle
- Exit inspect mode cleanly
- Support diegetic inspection (item floats in world) and UI inspection (render target)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `InspectAnchorTransform` | Transform | Where item appears during inspection |
| `CurrentInspectedItem` | Actor/StaticMesh | What is being inspected |
| `bInInspectMode` | Bool | Inspection active |
| `DiscoveryAngles` | Array of S_InspectDiscovery | Hidden secrets at specific rotations |
| `RotationSensitivity` | Float | Input-to-rotation mapping |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_InspectDiscovery` | AngleRange, DiscoveryTag, DisplayText | A secret discovered at a certain rotation |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnInspectEntered` | ItemActor | Inspect mode starts |
| `OnInspectExited` | — | Inspect mode ends |
| `OnDiscoveryUnlocked` | DiscoveryTag | Hidden angle reached |

---

### BPC_PhysicsDragSystem — Actor Component (on Player Controller)

**Purpose:**
Handles physics-based grab, drag, push, and pull of world objects. Wraps UE5's physics handle with game-ready controls.

**Responsibilities:**
- Grab physics-simulating actors on interaction
- Apply constraint forces to drag grabbed object with player view
- Handle throw / release
- Respect mass limits (can't pick up heavy objects unless scripted)
- Play haptic feedback on grab/release

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `GrabRange` | Float | Max distance to initiate grab |
| `HoldDistance` | Float | Distance item is held from camera |
| `MaxGrabMass` | Float | Mass limit in kg |
| `PhysicsHandle` | UPhysicsHandleComponent | UE physics handle component |
| `GrabbedActor` | Actor Reference | Currently held actor |
| `ThrowForce` | Float | Force applied on throw |

---

### BP_DoorActor — Actor (Blueprint)

**Purpose:**
A complete reusable door actor implementing `I_Interactable` and `I_Persistable`. Handles locked, unlocked, key-required, and one-way states.

**Responsibilities:**
- Self-contained open/close animation via Timeline or Root Motion
- Lock state management (locked by key tag, locked by objective tag, destructible lock)
- Creak/knock audio feedback
- Save/load open state via `I_Persistable`
- Support both manual push (physics) and scripted open

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `bIsOpen` | Bool | Current open state |
| `bIsLocked` | Bool | Lock state |
| `RequiredKeyTag` | GameplayTag | Key item needed to unlock |
| `LockConditionTag` | GameplayTag | Objective flag that unlocks |
| `OpenAngle` | Float | Degrees to rotate on open |
| `OpenDuration` | Float | Animation time |
| `InteractionData` | S_InteractionData | Data returned to interaction system |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_InteractionData` | InteractionType, PromptText, RequiredTag, InteractionTag, HoldDuration | Defines interaction appearance and requirements |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `OpenDoor` | bForced: Bool | — | Plays open animation |
| `CloseDoor` | — | — | Plays close animation |
| `TryUnlock` | Instigator | Bool (success) | Checks key item in inventory |
| `LockDoor` | — | — | Sets locked state |
| `SetLockByTag` | ConditionTag | — | Ties lock to narrative flag |

**Blueprint Flow:**
```
[Player Interacts → OnInteract called]
  └─► bIsLocked?
      ├─► Yes → Check Inventory for RequiredKeyTag
      │         ├─► Has key? → TryUnlock → OpenDoor
      │         └─► No key → Broadcast locked feedback (audio + UI)
      └─► No → bIsOpen ? CloseDoor : OpenDoor
```

---

### BP_ContainerActor — Actor (Blueprint)

**Purpose:**
Reusable drawer/cabinet/chest actor. Implements `I_Interactable` and `I_Persistable`. Contains an inventory that the player can search.

**Responsibilities:**
- Open/close animation
- Expose internal item list to inventory system on search
- Track whether player has already searched (looted flag)
- Support locked state (same pattern as BP_DoorActor)
- Persist loot state

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `ContainedItems` | Array of S_ItemData | Items inside on spawn |
| `bIsLooted` | Bool | Has player searched |
| `bIsLocked` | Bool | Lock state |
| `bIsOpen` | Bool | Visual open state |

**Communicates With:**

| Target System | Method | Why |
|---------------|--------|-----|
| BPC_InventorySystem | Direct | Transfer items to player inventory |
| WBP_ContainerSearchUI | Dispatcher | Open search UI |

---

### BP_HidingSpotActor — Actor (Blueprint)

**Purpose:**
A world actor that implements `I_HidingSpot`. Defines a safe hiding location (closet, under bed, barrel) the player can enter.

**Responsibilities:**
- Define entry/exit points and animation montage
- Support peeking (partial exit without fully leaving)
- Handle AI reaching the hiding spot (tension event)
- Notify BPC_HidingSystem on enter/exit

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `EntryTransform` | Transform | Where player's camera moves to |
| `PeekTransforms` | Array of Transform | Peek directions |
| `HideCapacity` | Integer | Max players (co-op future) |
| `bAICanInvestigate` | Bool | AI will check this spot |

---

### BPC_ContextualTraversalSystem — Actor Component (on Player Controller)

**Purpose:**
Manages contextual climb, vault, ledge grab, and step-up interactions. Acts as a gateway layer between player input and GASP's motion warping system.

**Responsibilities:**
- Detect climbable ledges, vaultable objects, and step-up surfaces via trace
- Queue a warp request to GASP's motion warping component
- Lock player input during traversal montage
- Fire completion event to resume normal control

**Does NOT Handle:**
- Animation state (GASP + ABP handle this)
- Camera (GASP camera manager handles this)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `ClimbTraceHeight` | Float | Vertical trace range for ledge detection |
| `VaultTraceDepth` | Float | Horizontal depth for vault detection |
| `bTraversalEnabled` | Bool | Master enable flag |
| `ActiveTraversalTag` | GameplayTag | What traversal is in progress |

---

### BP_PuzzleDeviceActor — Actor (Blueprint)

**Purpose:**
A generic puzzle device that receives input states and emits a solved/failed event. Specific puzzles (keypad, pressure plate, dial, fuse box) extend this.

**Responsibilities:**
- Define input requirements (correct sequence, correct combination, time limit)
- Track current input state
- Broadcast `OnSolved` / `OnFailed` dispatchers
- Implement `I_Interactable` to start the puzzle
- Support narrative lock (disabled until objective reached)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `SolutionData` | DA_PuzzleData | Data asset defining correct solution |
| `CurrentInputState` | Array of Integer/String/Tag | Player's current attempt |
| `bIsSolved` | Bool | Permanent solved state |
| `bIsActive` | Bool | Puzzle interactable right now |
| `FailPenaltyTag` | GameplayTag | Effect to apply on failure |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnPuzzleSolved` | PuzzleTag | Player solves correctly |
| `OnPuzzleFailed` | AttemptCount | Player fails |
| `OnPuzzleActivated` | — | Player starts the puzzle |

---

### BPC_UsableWorldObjectSystem — Actor Component (on usable actors)

**Purpose:**
Generic component for world objects that have a simple use state (on/off, activated/deactivated): light switches, generators, levers, valves.

**Responsibilities:**
- Toggle active state on interact
- Fire state change dispatchers for other systems to react
- Support one-time or repeated use
- Implement `I_Interactable` and optionally `I_Persistable`

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `bIsActive` | Bool | Current state |
| `bRepeatable` | Bool | Can be toggled multiple times |
| `UseTag` | GameplayTag | Tag broadcast on activation |
| `InteractionData` | S_InteractionData | Interaction prompt data |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnActivated` | Instigator | Switched on |
| `OnDeactivated` | Instigator | Switched off |

---

# 4. Inventory, Items & Collectibles Systems

*The inventory is a data-only system. It does not own UI. UI reads from it. Items are defined by Data Assets and carry all their own logic metadata.*

---

### BPC_InventorySystem — Actor Component (on Player Pawn)

**Purpose:**
The authoritative container for all items the player is carrying. Pure data management — no UI, no visual representation.

**Responsibilities:**
- Add, remove, and stack items by their `S_ItemData` struct
- Enforce capacity limits (slot count and/or weight)
- Validate add/remove operations (item exists, space available)
- Persist inventory state via `I_Persistable`
- Notify equipment and active item systems on change

**Does NOT Handle:**
- Visuals or animation
- UI display (WBP_InventoryMenu reads via dispatcher)
- Item effects (BPC_ConsumableSystem handles)
- Equipment assignment (BPC_EquipmentSlotSystem handles)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `InventorySlots` | Array of S_InventorySlot | All held items |
| `MaxSlotCount` | Integer | Total inventory capacity |
| `MaxCarryWeight` | Float | Optional weight limit (0 = disabled) |
| `CurrentWeight` | Float | Sum of held item weights |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_InventorySlot` | ItemData: S_ItemData, Quantity: Int, UniqueID: Name | One inventory entry |
| `S_ItemData` | ItemTag, DisplayName, Description, Icon, Mesh, Weight, StackLimit, ItemType: E_ItemType, bIsKeyItem, CustomData: Map | Complete item definition |

**Enums:**

| Enum | Values | Description |
|------|--------|-------------|
| `E_ItemType` | Weapon, Ammo, Consumable, KeyItem, Document, Collectible, Tool, Resource, Misc | Item classification |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `AddItem` | ItemData, Quantity | Bool (success) | Adds item if capacity allows |
| `RemoveItem` | ItemTag, Quantity | Bool (success) | Removes item by tag |
| `HasItem` | ItemTag | Bool | Checks item presence |
| `GetItemQuantity` | ItemTag | Integer | Returns stack count |
| `GetAllItems` | — | Array S_InventorySlot | Full inventory snapshot |
| `TransferTo` | TargetInventory, ItemTag, Qty | Bool | Move item to another inventory |
| `ClearInventory` | — | — | Empty all slots (death/new game) |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnItemAdded` | ItemData, Quantity | Item added |
| `OnItemRemoved` | ItemTag, Quantity | Item removed |
| `OnInventoryFull` | — | Capacity reached |
| `OnInventoryChanged` | — | Any change (for UI refresh) |

**Communicates With:**

| Target System | Method | Why |
|---------------|--------|-----|
| WBP_InventoryMenu | Dispatcher | UI refresh |
| BPC_EquipmentSlotSystem | Direct | Equip item from inventory |
| BPC_ActiveItemSystem | Direct | Set active hand item |
| SS_AchievementSystem | Dispatcher | Item collection achievements |
| BP_ContainerActor | Direct | Receive items from containers |

---

### BPC_EquipmentSlotSystem — Actor Component (on Player Pawn)

**Purpose:**
Manages the player's named equipment slots (PrimaryWeapon, SecondaryWeapon, Flashlight, Shield, ActiveTool). Separate from the bag inventory.

**Responsibilities:**
- Maintain up to N named equipment slots (driven by DA_EquipmentConfig)
- Equip and unequip items to/from slots
- Enforce slot type restrictions (only weapons in weapon slots)
- Spawn/despawn visible equipment actors on the player mesh
- Communicate to BPC_ActiveItemSystem which item is "in hand"

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `EquipmentSlots` | Map (GameplayTag → S_EquipmentSlot) | Named slots and their contents |
| `EquipmentConfig` | DA_EquipmentConfig | Which slots exist for this character |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_EquipmentSlot` | SlotTag, AllowedItemTypes, EquippedItem: S_ItemData, VisibleActor: Actor | Single slot definition |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `EquipToSlot` | SlotTag, ItemData | Bool | Assigns item to slot, spawns actor |
| `UnequipFromSlot` | SlotTag | S_ItemData | Removes item, despawns actor |
| `SwapSlots` | SlotTagA, SlotTagB | — | Swaps two slot contents |
| `GetEquippedItem` | SlotTag | S_ItemData | Returns item in slot |
| `GetActiveSlotActor` | SlotTag | Actor | Returns visible equipment actor |

---

### BPC_ActiveItemSystem — Actor Component (on Player Controller)

**Purpose:**
Manages what is currently in the player's active hand. Routes to weapon, tool, or consumable systems based on item type. Handles raise/lower animations.

**Responsibilities:**
- Track left-hand and right-hand active items independently
- Trigger raise/lower montages via GASP hooks
- Route use input to the correct system (melee, firearm, consumable, tool)
- Handle quick-switch (toggle between last two items)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `RightHandItem` | S_ItemData | Currently raised right-hand item |
| `LeftHandItem` | S_ItemData | Currently raised left-hand item |
| `PreviousRightHandItem` | S_ItemData | Last item for quick-switch |
| `bIsRaised` | Bool | Item is in ready position |

**Enums:**

| Enum | Values | Description |
|------|--------|-------------|
| `E_HandSide` | Left, Right, Both | Which hand(s) |

---

### DA_ItemDatabase — Data Asset Collection

**Purpose:**
Each item in the game is a `DA_ItemData` Data Asset. These assets are the single source of truth for item properties. No item data lives in Blueprint logic.

**Structure of DA_ItemData:**
```
DA_ItemData extends UPrimaryDataAsset
  └─ ItemTag: GameplayTag           (unique identifier)
  └─ DisplayName: FText
  └─ Description: FText
  └─ Icon: Texture2D
  └─ WorldMesh: StaticMesh
  └─ Weight: Float
  └─ StackLimit: Integer
  └─ ItemType: E_ItemType
  └─ bIsKeyItem: Bool
  └─ CombinesWith: Array GameplayTag (items this can combine with)
  └─ CombineResult: GameplayTag (resulting item tag)
  └─ EquipmentData: S_EquipmentData (if equippable)
  └─ ConsumableData: S_ConsumableData (if consumable)
  └─ InspectData: S_InspectData (if inspectable 3D model)
  └─ AmmoData: S_AmmoData (if ammo type)
  └─ CustomProperties: Map (Name → String)
```

**Reuse Notes:**
Create one DA_ItemData per item. Use Asset Manager with primary asset labels for async loading. The `CustomProperties` map future-proofs any per-project additions.

---

### BPC_ItemCombineSystem — Actor Component (on Player Controller)

**Purpose:**
Enables combining two items from inventory to create a new item. Validates combinations against item data assets.

**Responsibilities:**
- Accept two item tags as combine candidates
- Look up `CombinesWith` and `CombineResult` in item data assets
- Remove source items from inventory, add result item
- Play combine animation and feedback
- Support failed combine feedback (visual/audio)

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `TryCombine` | ItemTagA, ItemTagB | Bool (success) | Validates and executes combination |
| `CanCombine` | ItemTagA, ItemTagB | Bool | Preview check without executing |
| `GetCombineResult` | ItemTagA, ItemTagB | GameplayTag | Returns result tag or None |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnCombineSuccess` | ResultItemTag | Successful combine |
| `OnCombineFailed` | ItemTagA, ItemTagB | Invalid combination |

---

### BPC_DocumentArchiveSystem — Actor Component (on Player Pawn)

**Purpose:**
Stores all found documents, notes, files, and messages. Separate from regular inventory for clean UI organisation.

**Responsibilities:**
- Accept document items (tag-matched from BPC_InventorySystem)
- Store ordered document list with read/unread status
- Provide sorted/filtered views (by chapter, type, location)
- Unlock lore entries on document discovery

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `FoundDocuments` | Array of S_DocumentEntry | All collected documents |
| `UnreadCount` | Integer | Documents not yet viewed |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_DocumentEntry` | DocumentTag, Title, BodyText, AuthorTag, bIsRead, DiscoveryChapter | One document record |

---

### BPC_JournalSystem — Actor Component (on Player Pawn)

**Purpose:**
Manages the player's journal: auto-filled objective summaries, player-authored notes (if applicable), and narrative observation entries.

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `JournalEntries` | Array of S_JournalEntry | All journal entries |
| `bAllowPlayerNotes` | Bool | Enable freeform player writing |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_JournalEntry` | EntryTag, Heading, Body, Timestamp, ChapterTag, bIsHighlighted | Journal record |

---

### BPC_CollectibleTracker — Actor Component (on Player Pawn)

**Purpose:**
Tracks all collectible items (hidden items, secret discoveries, lore objects) separately from general inventory.

**Responsibilities:**
- Record found collectible tags
- Track completion percentage per collectible set
- Trigger achievement checks on set completion
- Persist collectible state

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `FoundCollectibles` | Set of GameplayTag | All discovered collectible tags |
| `CollectibleSets` | Map (GameplayTag → S_CollectibleSet) | Named collectible sets |

---

### BPC_ConsumableSystem — Actor Component (on Player Pawn)

**Purpose:**
Handles the use and effect application of consumable items (health kits, stress reducers, stamina boosters).

**Responsibilities:**
- Receive use request from BPC_ActiveItemSystem
- Look up consumable effect data in item data asset
- Apply effects to target systems (BPC_HealthSystem, BPC_StressSystem, etc.)
- Remove consumed item from inventory
- Play use animation and audio

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `UseAnimMontage` | AnimMontage | Default consume animation |
| `bIsConsuming` | Bool | Use in progress lock |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_ConsumableData` | HealthRestore, StressReduce, StaminaRestore, UseDuration, EffectTag | Consumable effect definition |

---

### BPC_AmmoResourceSystem — Actor Component (on Player Pawn)

**Purpose:**
Manages all ammunition and resource pools for weapons and tools.

**Responsibilities:**
- Track ammo counts per ammo type (tag-based)
- Validate ammo availability before weapon fires
- Handle ammo pickup (add to pool)
- Handle reload requests (transfer from pool to weapon)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `AmmoPool` | Map (GameplayTag → Integer) | AmmoType → Count |
| `MaxAmmoLimits` | Map (GameplayTag → Integer) | Per-type carry limits |

---

### BPC_KeyItemSystem — Actor Component (on Player Pawn)

**Purpose:**
Specialised tracking for key items that gate progression. Ensures key items cannot be dropped, consumed, or lost.

**Responsibilities:**
- Mirror BPC_InventorySystem's key item subset
- Validate key item requirements on door/lock interactions
- Fire events when key items are acquired/used
- Protect key items from bulk inventory operations (ClearInventory excludes them by default)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `HeldKeyItems` | Array of GameplayTag | Tags of all held key items |
| `UsedKeyItems` | Array of GameplayTag | Tags of consumed/used key items |
| `bKeyItemsDestructible` | Bool | Whether key items disappear after use |

---

# 5. Weapon, Equipment & Damage Systems

---

### BPC_MeleeSystem — Actor Component (on Player Pawn)

**Purpose:**
Handles all melee attack logic: swings, hit detection, damage application, and combo state.

**Responsibilities:**
- Process melee attack input
- Perform sweep traces on attack frames (driven by Animation Notify)
- Apply damage to hit actors via `I_Damageable`
- Manage combo window timing
- Track stamina cost per swing
- Handle melee destruction of objects (doors, barricades)

**Does NOT Handle:**
- Ranged attacks (BPC_FirearmSystem)
- Animation (ABP handles; receives notify events)
- Camera shake on hit (BPC_CameraStateLayer)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `EquippedWeaponData` | DA_WeaponData | Current melee weapon config |
| `bIsAttacking` | Bool | Attack in progress lock |
| `ComboCount` | Integer | Current combo step |
| `ComboWindowTime` | Float | Window to chain next attack |
| `AttackTraceRadius` | Float | Swing sweep sphere radius |
| `AttackRange` | Float | Forward sweep distance |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `RequestAttack` | — | — | Player presses attack |
| `PerformAttackTrace` | — | Array of Hit Results | Sweep during attack frame |
| `ApplyMeleeDamage` | HitResult, WeaponData | — | Applies damage event to hit actor |
| `OnComboWindowOpen` | — | — | Called by Anim Notify |
| `OnComboWindowClose` | — | — | Resets combo |
| `OnAttackAnimFinished` | — | — | Clears attack lock |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnMeleeHit` | HitActor, DamageEvent | Successfully hit something |
| `OnMeleeMiss` | — | Swing hit nothing |
| `OnComboComplete` | MaxCombo | Full combo executed |

---

### BPC_FirearmSystem — Actor Component (on Player Pawn)

**Purpose:**
Handles all ranged firearm logic: fire modes, projectile/hitscan, spread, and firing rate.

**Responsibilities:**
- Process fire input with fire rate throttling
- Support hitscan (line trace) and projectile (spawn actor) modes
- Apply spread and recoil requests
- Validate ammo with BPC_AmmoResourceSystem
- Trigger reload via BPC_ReloadSystem
- Play muzzle flash and audio effects

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `EquippedFirearmData` | DA_WeaponData | Current firearm config |
| `FireMode` | E_FireMode | Single, Burst, Auto |
| `bIsFiring` | Bool | Fire in progress |
| `CurrentMagazineCount` | Integer | Rounds in current magazine |
| `MaxMagazineSize` | Integer | From weapon data |
| `bIsADS` | Bool | Aiming down sights |
| `FireRate` | Float | Rounds per second |

**Enums:**

| Enum | Values | Description |
|------|--------|-------------|
| `E_FireMode` | Single, Burst, Automatic, Charge | Fire mode |
| `E_ProjectileMode` | Hitscan, Projectile | Bullet type |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `RequestFire` | — | — | Player presses fire |
| `PerformHitscan` | — | HitResult | Line trace from muzzle |
| `SpawnProjectile` | — | — | Spawn projectile actor from muzzle |
| `SetADS` | bAiming | — | Enter/exit aim-down-sights |
| `ApplyRecoilRequest` | — | — | Sends recoil request to BPC_RecoilSystem |
| `EmptyMagazine` | — | — | Force empty (jam, etc.) |

---

### BPC_RecoilSystem — Actor Component (on Player Controller)

**Purpose:**
Handles procedural recoil: camera kick, recovery curve, and ADS recoil reduction.

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `RecoilPattern` | CurveVector | Per-weapon kick pattern |
| `RecoverySpeed` | Float | How fast camera returns |
| `ADSRecoilMultiplier` | Float | Recoil reduction while ADS |
| `CurrentRecoilOffset` | Vector2D | Accumulated offset |

---

### BPC_ReloadSystem — Actor Component (on Player Pawn)

**Purpose:**
Manages reload animations, timing, and ammo transfer from pool to weapon magazine.

**Responsibilities:**
- Play reload animation montage
- Lock fire input during reload
- Transfer correct ammo type from pool to magazine
- Support interrupted reload (partial reload)
- Handle tactical reload (reload before empty)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `bIsReloading` | Bool | Reload in progress |
| `ReloadMontage` | AnimMontage | Per-weapon reload animation |
| `AmmoTypeTag` | GameplayTag | Which ammo pool to draw from |
| `bPartialReload` | Bool | Whether partial reload is supported |

---

### BPC_ShieldDefenseSystem — Actor Component (on Player Pawn)

**Purpose:**
Manages defensive tools: shields, blocking, parrying. Works in both melee and ranged defense contexts.

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `bIsBlocking` | Bool | Block active |
| `BlockDamageReduction` | Float | % reduction while blocking |
| `ParryWindow` | Float | Perfect parry timing window |
| `ShieldDurability` | Float | If shield can break |

---

### BPC_DamageReceptionSystem — Actor Component (on Player Pawn)

**Purpose:**
The central damage intake point for the player. Validates damage events, applies hit reactions, and routes to BPC_HealthSystem.

**Responsibilities:**
- Implement `I_Damageable` interface
- Apply damage direction to drive hit reaction animations
- Filter friendly-fire, scripted immunity
- Route to BPC_HealthSystem with processed DamageEvent
- Apply screen damage effect via BPC_ScreenEffectController

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `bInvincibilityActive` | Bool | Master immune flag |
| `LastDamageDirection` | Vector | For hit reaction anim |
| `HitReactionMontages` | Map (E_DamageType → AnimMontage) | Directional hit reactions |

---

### BPC_HitReactionSystem — Actor Component (on Player Pawn)

**Purpose:**
Drives physical hit reaction behaviour: flinch animations, ragdoll blends, camera trauma.

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `FlinchThreshold` | Float | Min damage to trigger flinch |
| `RagdollThreshold` | Float | Damage to trigger ragdoll blend |
| `TraumaDecayRate` | Float | Camera trauma recovery |

---

### BPC_DeathCauseTracker — Actor Component (on Player Pawn)

**Purpose:**
Records the cause and context of the player's death for use by the death handling system, adaptive systems, and run summary.

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `LastDeathCause` | E_DeathCause | How the player died |
| `LastDeathLocation` | Vector | World position of death |
| `LastDeathInstigator` | Actor | What killed them |
| `DeathHistory` | Array of S_DeathRecord | Full session death log |

**Enums:**

| Enum | Values | Description |
|------|--------|-------------|
| `E_DeathCause` | Melee, Projectile, Environmental, Scripted, Psychic, InstantKill, Unknown | Death cause |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_DeathRecord` | Cause, Location, Instigator, Timestamp, ChapterTag | One death event |

---

### DA_WeaponData — Data Asset

**Purpose:**
Complete definition of a weapon's properties. Referenced by melee and firearm systems.

**Fields:**
```
DA_WeaponData extends UPrimaryDataAsset
  └─ WeaponTag: GameplayTag
  └─ DisplayName: FText
  └─ WeaponType: E_WeaponType (Melee, Firearm, Throwable, Tool)
  └─ DamageBase: Float
  └─ DamageType: E_DamageType
  └─ Range: Float
  └─ FireRate: Float (firearms)
  └─ MagazineSize: Integer
  └─ AmmoTypeTag: GameplayTag
  └─ FireMode: E_FireMode
  └─ RecoilPattern: CurveVector
  └─ WeaponMesh: SkeletalMesh
  └─ MuzzleSocketName: Name
  └─ HitParticles: Map (Surface → ParticleSystem)
  └─ FireSound: SoundBase
  └─ ReloadMontage: AnimMontage
  └─ AttackMontages: Array AnimMontage
  └─ AimOffset: AimOffsetBlendSpace
```

---

# 6. UI, Menus & Diegetic Presentation Systems

*The entire UI layer is decoupled from game logic. Widgets subscribe to dispatchers and read from systems. They never own game state.*

---

### WBP_HUDController — Widget (Root HUD)

**Purpose:**
The master HUD container. Owns all in-world HUD sub-widgets and manages their visibility based on game phase and player state.

**Responsibilities:**
- Create and manage all HUD sub-widgets (diegetic display, interaction prompt, subtitles, notifications)
- React to `E_GamePhase` changes (hide HUD during cutscenes, show during play)
- Route visibility of individual HUD elements via gameplay tags
- Never display raw data — always delegates to child widgets

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `DiegeticHUDWidget` | WBP_DiegeticHUDFrame | The diegetic UI element |
| `InteractionPromptWidget` | WBP_InteractionPromptDisplay | Interaction cues |
| `SubtitleWidget` | WBP_SubtitleDisplay | Dialogue/event subtitles |
| `NotificationWidget` | WBP_NotificationToast | Toast messages |
| `ObjectiveWidget` | WBP_ObjectiveDisplay | Objective overlay |
| `ScreenEffectWidget` | WBP_ScreenEffectController | Full-screen effects |
| `bHUDVisible` | Bool | Master visibility flag |

**Communicates With:**

| Target System | Method | Why |
|---------------|--------|-----|
| GI_GameFramework | Dispatcher | Phase-based visibility |
| BPC_InteractionDetector | Dispatcher | Show/hide interaction prompt |
| BPC_DialogueSystem | Dispatcher | Show/hide subtitles |
| BPC_ObjectiveSystem | Dispatcher | Update objective display |

---

### WBP_DiegeticHUDFrame — Widget (Diegetic HUD)

**Purpose:**
The swappable container for the game's diegetic HUD presentation. This is the "skin" that changes per project — wristwatch, visor, bracelet, handheld device, etc.

**Responsibilities:**
- Implement `I_DiegeticDisplay` interface
- Expose display zones: health indicator, stress indicator, stamina indicator, time, compass, objectives
- All data displayed here comes from system dispatchers — it contains zero game logic
- Be swappable: a child widget class overrides this for each project's art direction

**Does NOT Handle:**
- Game state (reads only)
- Input
- Anything outside visual presentation

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `HealthIndicator` | Widget | Child widget showing health |
| `StressIndicator` | Widget | Child widget showing stress |
| `StaminaBar` | Widget | Optional stamina display |
| `CompassWidget` | Widget | Optional directional compass |
| `ActiveItemWidget` | Widget | Currently held item icon |
| `bAnimatedEntries` | Bool | Whether values animate in/out |

**Reuse Notes:**
For a sci-fi game, create `WBP_DiegeticHUD_VisorSkin`. For a period horror game, create `WBP_DiegeticHUD_WatchSkin`. Only the art/layout changes — all data bindings use the same `I_DiegeticDisplay` interface.

---

### WBP_InteractionPromptDisplay — Widget

**Purpose:**
Displays interaction prompts when the player focuses an interactable. Reacts to `BPC_InteractionDetector.OnFocusGained` and `OnFocusLost`.

**Responsibilities:**
- Show prompt text (from `S_InteractionData.PromptText`)
- Show interaction type indicator (tap vs hold)
- Animate in/out on focus change
- Show hold progress bar for hold-type interactions
- Support icon-based prompts (controller button glyphs)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `PromptText` | FText | Current interaction label |
| `HoldProgress` | Float | 0–1 for hold interactions |
| `bIsHoldType` | Bool | Shows progress bar |
| `ButtonGlyph` | Texture2D | Platform-appropriate button icon |

---

### WBP_InventoryMenu — Widget (Inventory UI)

**Purpose:**
Full inventory screen. Can be presented as a diegetic bag/pocket UI or a traditional menu. The same widget supports both via a `PresentationMode` enum.

**Responsibilities:**
- Display all items from BPC_InventorySystem
- Support item selection, examination, equip, drop, combine
- Open item inspection via BPC_InspectItemSystem
- Open combine UI when two items are selected
- Show equipment slots from BPC_EquipmentSlotSystem
- Support both Diegetic and Menu presentation modes

**Enums:**

| Enum | Values | Description |
|------|--------|-------------|
| `E_InventoryPresentationMode` | Diegetic, MenuOverlay, RadialQuick | Visual style |

---

### WBP_JournalDocumentViewer — Widget

**Purpose:**
Displays collected documents, notes, and the player journal. Supports text scrolling, page turns, and image plates.

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `ActiveDocument` | S_DocumentEntry | Currently displayed document |
| `bShowPageTurnAnim` | Bool | Enable page turn animation |
| `FontStyle` | E_DocumentFontStyle | Handwritten, Typewritten, Digital |

---

### WBP_ObjectiveDisplay — Widget

**Purpose:**
Shows active objectives on the HUD. Supports diegetic fade-in, traditional list, or map-marker modes.

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `ActiveObjectives` | Array of S_ObjectiveDisplayData | What to show |
| `DisplayMode` | E_ObjectiveDisplayMode | HUDFade, List, Hidden |
| `FadeOutDelay` | Float | Seconds before objective fades |

---

### WBP_SubtitleDisplay — Widget

**Purpose:**
Renders dialogue subtitles and ambient sound captions. Supports styling, speaker labels, and accessibility size scaling.

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `CurrentLine` | FText | Active subtitle text |
| `SpeakerName` | FText | Optional speaker label |
| `SubtitleStyle` | E_SubtitleStyle | Dialogue, Caption, Thought, System |
| `FontScale` | Float | Accessibility size multiplier |

---

### WBP_MainMenu — Widget

**Purpose:**
The primary entry point for new/continue/settings/quit. Manages animated backgrounds and menu section routing.

---

### WBP_PauseMenu — Widget

**Purpose:**
Pause screen with resume, save (if allowed), settings, and quit options. Respects `GM_CoreGameMode.bPauseAllowed`.

---

### WBP_SettingsMenu — Widget

**Purpose:**
Hosts audio, graphics, controls, and accessibility settings. Reads from and writes to `SS_SettingsSystem`.

---

### WBP_NotificationToast — Widget

**Purpose:**
Displays transient notification messages: item acquired, objective updated, achievement unlocked. Auto-dismisses after duration.

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `NotificationQueue` | Array of S_NotificationData | Pending notifications |
| `DisplayDuration` | Float | Default on-screen time |
| `MaxSimultaneous` | Integer | Stack limit |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_NotificationData` | Icon, Title, Body, NotificationType: E_NotificationType, Duration | Toast content |

---

### WBP_ScreenEffectController — Widget

**Purpose:**
Full-screen post-process and material-based effects: damage vignette, stress distortion, blackout/fade, static, jump-scare flash.

**Responsibilities:**
- Drive material parameter collections for screen effects
- Manage fade to/from black with configurable curves
- Handle jump-scare whiteness flash
- Apply static/noise overlay driven by stress
- Support custom effect injection per project

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `FadeToBlack` | Duration | — | Lerp opacity to black |
| `FadeFromBlack` | Duration | — | Lerp from black |
| `TriggerDamageFlash` | Intensity | — | Red vignette pulse |
| `TriggerJumpScareFlash` | — | — | White flash |
| `SetStaticIntensity` | 0–1 | — | Drives stress noise |
| `SetDistortionIntensity` | 0–1 | — | Drives stress warp |

---

### WBP_MenuFlowController — Widget (Menu Shell)

**Purpose:**
Manages transitions between all full-screen menu widgets: MainMenu → Settings → LoadGame → Credits. Owns the menu navigation stack.

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `MenuStack` | Array of Widget | Navigation history |
| `CurrentMenu` | Widget | Active menu widget |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `PushMenu` | MenuClass | — | Navigate to new menu |
| `PopMenu` | — | — | Go back |
| `ReplaceMenu` | MenuClass | — | Replace without history |
| `ClearAndShow` | MenuClass | — | Reset stack |

---

# 7. Narrative, Dialogue, Objective & Choice Systems

*These systems handle all story-driven content: what the player is told, what choices they make, what consequences follow, and how the game ends.*

---

### BPC_NarrativeStateSystem — Actor Component (on Player Pawn)

**Purpose:**
The authoritative store of all narrative flags. Every story decision, discovered secret, and consequence tag is registered here.

**Responsibilities:**
- Store narrative flags as GameplayTag → Value map
- Provide add/check/remove flag API
- Persist flags via `I_Persistable`
- Broadcast flag changes so reactive systems (doors, dialogue, environment) update

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `NarrativeFlags` | Map (GameplayTag → Bool) | Binary story flags |
| `NarrativeValues` | Map (GameplayTag → Float) | Numeric story values (reputation, etc.) |
| `NarrativeHistory` | Array of GameplayTag | Ordered flag acquisition log |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `SetFlag` | Tag, Value: Bool | — | Sets narrative flag |
| `GetFlag` | Tag | Bool | Reads flag (missing = false) |
| `SetValue` | Tag, Value: Float | — | Sets numeric narrative value |
| `GetValue` | Tag | Float | Reads numeric value |
| `HasAllFlags` | Array of Tag | Bool | AND check |
| `HasAnyFlag` | Array of Tag | Bool | OR check |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnFlagChanged` | Tag, NewValue: Bool | Any flag change |
| `OnValueChanged` | Tag, NewValue: Float | Any value change |

**Communicates With:**

| Target System | Method | Why |
|---------------|--------|-----|
| BP_DoorActor / all I_NarrativeActor | Dispatcher + Interface | World reacts to flag changes |
| BPC_ObjectiveSystem | Dispatcher | Objectives unlock/complete |
| BPC_EndingAccumulator | Direct | Ending condition evaluation |
| BPC_DialogueSystem | Direct | Dialogue condition checks |
| SS_SaveManager | I_Persistable | Flags persist |

---

### BPC_ObjectiveSystem — Actor Component (on Player Pawn)

**Purpose:**
Tracks active, completed, and failed objectives. Supports main objectives, sub-objectives, hidden objectives, and optional objectives.

**Responsibilities:**
- Activate objectives by tag
- Complete/fail objectives by tag or narrative flag trigger
- Track objective dependency chains
- Notify UI and journal on changes
- Support objectives hidden until discovery condition met

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `AllObjectives` | Map (GameplayTag → S_ObjectiveState) | Full objective register |
| `ActiveObjectiveTags` | Array of GameplayTag | Currently active |
| `CompletedObjectiveTags` | Array of GameplayTag | Done |
| `FailedObjectiveTags` | Array of GameplayTag | Failed |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_ObjectiveState` | ObjectiveTag, Status: E_ObjectiveStatus, DisplayText, SubObjectives, Dependencies, bIsHidden | Runtime objective state |

**Enums:**

| Enum | Values | Description |
|------|--------|-------------|
| `E_ObjectiveStatus` | Inactive, Active, Complete, Failed, Hidden | Objective lifecycle |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `ActivateObjective` | ObjectiveTag | — | Sets objective Active |
| `CompleteObjective` | ObjectiveTag | — | Marks complete, fires dispatcher |
| `FailObjective` | ObjectiveTag | — | Marks failed |
| `GetActiveObjectives` | — | Array S_ObjectiveState | For UI |
| `IsObjectiveComplete` | ObjectiveTag | Bool | Status check |
| `RevealHiddenObjective` | ObjectiveTag | — | Shows previously hidden |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnObjectiveActivated` | ObjectiveTag, Data | New objective added |
| `OnObjectiveCompleted` | ObjectiveTag | Completed |
| `OnObjectiveFailed` | ObjectiveTag | Failed |

---

### BPC_DialoguePlaybackSystem — Actor Component (on Player Controller)

**Purpose:**
Manages the playback of dialogue sequences: line queuing, timing, subtitle routing, audio playback, and lip-sync.

**Responsibilities:**
- Receive dialogue sequence data (from DA_DialogueSequence)
- Queue lines and play in order with timing
- Trigger subtitle display via dispatcher
- Play voiceover audio
- Fire narrative flags on line completion (if configured)
- Pause/interrupt dialogue on player action

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `ActiveSequence` | DA_DialogueSequence | Currently playing sequence |
| `LineQueue` | Array of S_DialogueLine | Remaining lines |
| `bIsPlaying` | Bool | Dialogue active |
| `LineTimer` | TimerHandle | Auto-advance timer |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_DialogueLine` | SpeakerTag, LineText, VoiceAudio, Duration, LipSyncData, FlagToSetOnComplete, AnimTag | One dialogue line |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnLineStarted` | Line: S_DialogueLine | New line begins |
| `OnLineComplete` | Line: S_DialogueLine | Line ends |
| `OnSequenceComplete` | SequenceTag | Full sequence done |

---

### BPC_DialogueChoiceSystem — Actor Component (on Player Controller)

**Purpose:**
Presents branching dialogue choices to the player and routes the selected response back to the narrative system.

**Responsibilities:**
- Receive choice set from dialogue flow
- Display choices via `WBP_DialogueChoiceDisplay`
- Apply time limit if configured
- Route selected choice tag to `BPC_NarrativeStateSystem`
- Trigger consequence dialogue branches

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `CurrentChoices` | Array of S_DialogueChoice | Available options |
| `ChoiceTimeLimit` | Float | 0 = no limit |
| `DefaultChoiceIndex` | Integer | Auto-selected if timer expires |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_DialogueChoice` | ChoiceText, ResultFlagTag, NextSequenceTag, RequiredFlagTag, bIsHidden | One choice option |

---

### BPC_BranchingConsequenceSystem — Actor Component (on Player Pawn)

**Purpose:**
Evaluates narrative flag states and triggers world/story consequences. The "if this flag, then that event" engine.

**Responsibilities:**
- Register consequence rules (DA_ConsequenceRule assets)
- Monitor BPC_NarrativeStateSystem flag changes
- Evaluate conditions when flags change
- Execute consequences (spawn actors, trigger events, update objectives, lock/unlock areas)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `ActiveConsequenceRules` | Array of DA_ConsequenceRule | Loaded rules |
| `FiredConsequences` | Set of GameplayTag | Already fired (prevent repeat) |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_ConsequenceRule` | ConditionFlags: Array Tag, ConditionValues: Map, ConsequenceTag, bOneShot | Rule definition |

---

### BPC_TrialScenarioSystem — Actor Component (can be on GameMode or dedicated Actor)

**Purpose:**
A generic event-driven trial / scenario / challenge system. Supports any game section that has start conditions, rules, win/fail states, and callbacks.

**Responsibilities:**
- Start a scenario by tag (from DA_ScenarioData)
- Track scenario state (NotStarted, Active, Success, Failed)
- Apply success/failure consequences to narrative state
- Support time-limited, kill-count, stealth, collection, or survival scenario types
- Fire hooks for adaptive systems and achievements

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `ActiveScenario` | DA_ScenarioData | Running scenario |
| `ScenarioState` | E_ScenarioState | Current state |
| `ElapsedTime` | Float | Timer |
| `ProgressValue` | Float | Generic progress (0–1) |

**Enums:**

| Enum | Values | Description |
|------|--------|-------------|
| `E_ScenarioState` | NotStarted, Active, Paused, Success, Failed | Scenario lifecycle |

---

### BPC_CutsceneBridge — Actor Component (on Player Controller)

**Purpose:**
Handles the interface between Blueprints and Sequencer-driven cutscenes. Manages control surrender, camera handoff, and narrative flag firing on cutscene events.

**Responsibilities:**
- Disable player input and camera for cutscene duration
- Trigger the correct Level Sequence via tag lookup
- Listen to Sequencer completion and restore control
- Fire narrative flags at specific timecodes via Sequencer event tracks
- Support skippable and unskippable cutscenes

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `CutsceneMap` | Map (GameplayTag → LevelSequence) | Tag → Sequence lookup |
| `bSkippable` | Bool | Current cutscene allow skip |
| `bCutsceneActive` | Bool | Control surrendered |

---

### BPC_EndingAccumulatorSystem — Actor Component (on Player Pawn)

**Purpose:**
Evaluates ending conditions throughout the game session. Determines which ending fires at the climax.

**Responsibilities:**
- Register ending conditions (from DA_EndingData assets)
- Evaluate conditions against BPC_NarrativeStateSystem flags
- Rank valid endings by priority / specificity
- Output the highest-scoring valid ending tag at trigger point
- Support multiple ending tiers (good/bad/neutral/secret)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `EndingConditions` | Array of DA_EndingData | All possible endings |
| `FulfilledEndingTags` | Array of GameplayTag | Conditions currently met |
| `ResolvedEndingTag` | GameplayTag | Final selected ending |

---

### BPC_LoreUnlockSystem — Actor Component (on Player Pawn)

**Purpose:**
Tracks world lore discovery: environmental storytelling, hidden messages, and lore object scans. Feeds journal and achievement systems.

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `DiscoveredLoreTags` | Set of GameplayTag | Found lore entries |
| `LoreDatabase` | Map (GameplayTag → S_LoreEntry) | All lore content |
| `TotalLoreCount` | Integer | Max possible lore |

---

### DA_NarrativeDataAssets — Data Asset Collection

**DA_DialogueSequence:**
```
└─ SequenceTag: GameplayTag
└─ Lines: Array S_DialogueLine
└─ RequiredFlags: Array GameplayTag (conditions to play)
└─ SpeakerActorTag: GameplayTag (which world actor is speaking)
└─ bBlockInput: Bool
└─ OnCompleteFlag: GameplayTag
```

**DA_ConsequenceRule:**
```
└─ RuleTag: GameplayTag
└─ ConditionType: E_ConditionType (AllFlags, AnyFlag, ValueThreshold)
└─ ConditionFlags: Array GameplayTag
└─ ConsequenceEvents: Array S_ConsequenceEvent
└─ bOneShot: Bool
```

**DA_EndingData:**
```
└─ EndingTag: GameplayTag
└─ DisplayTitle: FText
└─ RequiredFlags: Array GameplayTag
└─ ForbiddenFlags: Array GameplayTag
└─ Priority: Integer
└─ EndingSequenceTag: GameplayTag (links to DA_DialogueSequence)
└─ EndingType: E_EndingType (Good, Bad, Neutral, Secret, TrueEnding)
```

---

# 8. Save, Load, Persistence & Death Loop Systems

---

### BPC_CheckpointSystem — Actor Component (on GameMode or dedicated Manager Actor)

**Purpose:**
Defines and manages checkpoint triggers in the level. Determines when auto-saves and checkpoint saves fire.

**Responsibilities:**
- Register checkpoint volumes/triggers in the level
- Detect player crossing checkpoint boundary
- Trigger SS_SaveManager.SaveCheckpoint with the checkpoint tag
- Respect "no save zone" flag for tension segments
- Update the "last valid respawn point" for death handling

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `LastCheckpointTag` | GameplayTag | Most recently hit checkpoint |
| `LastCheckpointTransform` | Transform | Respawn location |
| `bNoSaveZoneActive` | Bool | Suppress auto-checkpoint saves |
| `RegisteredCheckpoints` | Array of S_CheckpointData | All level checkpoints |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_CheckpointData` | CheckpointTag, TriggerVolume, RespawnTransform, bAutoSave | Checkpoint definition |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnCheckpointReached` | CheckpointTag | Player crosses checkpoint |

---

### BPC_PersistentWorldStateRecorder — Actor Component (on Game State or dedicated Actor)

**Purpose:**
Tracks all world-object state changes throughout a session so they can be serialised on save and restored on load.

**Responsibilities:**
- Maintain a delta map of changed world objects
- Provide register/deregister for `I_Persistable` actors
- On save: call `CollectState()` on all registered actors
- On load: call `RestoreState()` on all registered actors
- Handle actors spawned mid-session (dynamic world changes)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `PersistableActors` | Array of Actor | All I_Persistable registered actors |
| `WorldStateDelta` | Map (Name → S_WorldObjectState) | Changed state records |

---

### BPC_PersistentCorpseSystem — Actor Component (on Game State)

**Purpose:**
Manages persistent death traces: player corpse markers, blood trails, and contextual echoes from previous deaths.

**Responsibilities:**
- Record death location and cause on player death
- Spawn a persistent corpse/echo actor at the death location
- Persist death trace data via SS_SaveManager
- Optionally allow interacting with death echoes (narrative hook)
- Limit total persistent corpses (oldest removed when limit reached)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `DeathTraces` | Array of S_DeathTrace | All recorded death locations |
| `MaxDeathTraces` | Integer | Maximum persisted traces |
| `DeathTraceActorClass` | Class | What actor to spawn at death location |
| `bDeathTracesEnabled` | Bool | Toggle feature |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_DeathTrace` | Location, Rotation, Cause: E_DeathCause, DeathTag, SessionIndex | One death record |

---

### BPC_DeathHandlingSystem — Actor Component (on Player Controller)

**Purpose:**
The central orchestrator for all death outcomes. Routes the death event to the correct outcome: standard respawn, death screen, or alternate death space.

**Responsibilities:**
- Receive `OnDeath` from BPC_HealthSystem
- Determine death outcome type (respawn, game over, alt death space)
- Trigger death animation and camera
- Invoke persistent corpse system
- Route to SS_SaveManager for checkpoint load OR to alt death space
- Update death counter in metrics

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `bAltDeathSpaceEnabled` | Bool | Feature flag for alternate death space |
| `AltDeathSpaceThreshold` | Integer | Deaths before alt space activates (or always, etc.) |
| `DeathOutcomeMode` | E_DeathOutcome | Default behaviour |
| `bDeathInProgress` | Bool | Prevent re-trigger |
| `DeathCamClass` | Class | Camera actor spawned on death |

**Enums:**

| Enum | Values | Description |
|------|--------|-------------|
| `E_DeathOutcome` | StandardRespawn, GameOver, AltDeathSpace, CustomScripted | How death resolves |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `HandleDeath` | DamageEvent: S_DamageEvent | — | Main death handler |
| `TriggerStandardRespawn` | — | — | Load last checkpoint |
| `TriggerGameOver` | — | — | Show game over screen |
| `TriggerAltDeathSpace` | — | — | Enter alternate death space layer |
| `CompleteDeathSequence` | — | — | After death anim, route to outcome |

**Blueprint Flow:**
```
[OnDeath received from BPC_HealthSystem]
  └─► bDeathInProgress = true
  └─► Play death animation / ragdoll
  └─► BPC_PersistentCorpseSystem.RecordDeath()
  └─► BPC_PlayerMetricsTracker.IncrementDeaths()
  └─► SS_AchievementSystem.CheckDeathAchievements()
  └─► Determine DeathOutcome:
      ├─► StandardRespawn → SS_SaveManager.LoadCheckpoint
      ├─► GameOver → WBP_GameOverScreen
      └─► AltDeathSpace → GI_GameFramework.SetGamePhase(AltDeathSpace)
                           → Stream in death-space level layer
```

---

### BPC_AltDeathSpaceSystem — Actor Component (on Player Controller)

**Purpose:**
A generic "between-death" alternate space system. When active, the player inhabits a separate liminal/void/purgatory space before respawning. Fully game-agnostic — the art and narrative context are project-specific.

**Responsibilities:**
- Activate when death handling routes here
- Stream in the alternate space level layer
- Manage a mini-objective or escape sequence within the space
- Track how many times the player has entered this space
- Handle exit: either respawn with penalty/bonus or trigger special consequences
- Expose all narrative hooks for project customisation

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `bIsActive` | Bool | Space currently inhabited |
| `EnterCount` | Integer | Times entered this session |
| `AltSpaceLevelTag` | GameplayTag | Which sub-level to stream |
| `EscapeConditionTag` | GameplayTag | Narrative flag to escape |
| `MaxEntriesBeforeConsequence` | Integer | Threshold for escalating consequence |
| `ConsequenceEscalationFlags` | Array of GameplayTag | Flags set on repeated entry |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `EnterAltSpace` | — | — | Stream level, surrender control |
| `ExitAltSpace` | EscapeTag | — | Return to main world |
| `SetEscapeCondition` | ConditionTag | — | Configure what lets player leave |
| `OnEscapeConditionMet` | — | — | Called when player can exit |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnAltSpaceEntered` | EnterCount | Space activated |
| `OnAltSpaceExited` | EscapeTag | Player escapes |
| `OnAltSpaceConsequence` | ConsequenceTag | Escalation threshold hit |

**Reuse Notes:**
This system is named generically. For THE BLISS it represents the Void/Death Loop. For another game it could be a dream realm, a mirror world, or a time-rewind sequence. The art, audio, and narrative content are entirely project-defined. Only the activation/deactivation/tracking logic is in this system.

---

### BPC_PlayerRespawnSystem — Actor Component (on Player Controller)

**Purpose:**
Restores the player after checkpoint load: repositions pawn, restores snapshot values, fades in camera.

**Responsibilities:**
- Receive respawn trigger from BPC_DeathHandlingSystem
- Wait for SS_SaveManager load to complete
- Teleport player to checkpoint respawn transform
- Restore health, stress, stamina from snapshot
- Fade camera in
- Re-enable input and HUD

---

### BPC_RunHistoryTracker — Actor Component (on Game Instance or Player State)

**Purpose:**
Records full run data across the session for post-game summary and meta progression.

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `RunStartTime` | DateTime | Session start |
| `TotalDeaths` | Integer | Session death total |
| `ChaptersCompleted` | Array of GameplayTag | Completed chapter tags |
| `EndingAchieved` | GameplayTag | Which ending fired |
| `ItemsFound` | Integer | Total items collected |
| `SecretCount` | Integer | Optional areas found |

---

# 9. Adaptive Environment, Atmosphere & Scare Systems

*These systems react to player behaviour patterns and dynamically adjust the world's atmosphere, pacing, and scare events.*

---

### BPC_PlaystyleClassifier — Actor Component (on Player Pawn or Game State)

**Purpose:**
Analyses player behaviour metrics and classifies their playstyle in real time. Feeds into the adaptive director.

**Responsibilities:**
- Read from BPC_PlayerMetricsTracker at regular intervals
- Calculate weighted playstyle scores
- Output current dominant playstyle tag
- Update when playstyle shifts significantly

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `AggressionWeight` | Float | Weight for combat actions |
| `CautionWeight` | Float | Weight for hiding/sneaking |
| `ExplorationWeight` | Float | Weight for off-path exploration |
| `CurrentPlaystyleTag` | GameplayTag | Dominant style |
| `ClassificationInterval` | Float | Seconds between re-evaluation |

**Enums:**

| Enum | Values | Description |
|------|--------|-------------|
| `E_PlaystyleTag` | Aggressive, Cautious, Explorer, Passive, Speedrunner, Completionist | Style categories (use as Gameplay Tags) |

**Blueprint Flow:**
```
[Timer fires every ClassificationInterval seconds]
  └─► Read BPC_PlayerMetricsTracker values
  └─► Calculate weighted scores
  └─► Determine dominant style tag
  └─► CurrentPlaystyleTag changed? → Broadcast OnPlaystyleChanged
```

---

### BPC_AdaptiveEnvironmentDirector — Actor Component (on GameMode or dedicated Actor)

**Purpose:**
The master controller of all adaptive systems. Receives playstyle classification and orchestrates world responses.

**Responsibilities:**
- Subscribe to BPC_PlaystyleClassifier.OnPlaystyleChanged
- Route playstyle to appropriate atmosphere adjustments
- Control pacing (when to trigger events vs. let player breathe)
- Coordinate between scare system, atmosphere controller, and AI director
- Enforce cooldowns between major adaptive changes

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `AdaptationRules` | Array of DA_AdaptationRule | Rule set for this level |
| `LastAdaptationTime` | Float | Timestamp of last major change |
| `AdaptationCooldown` | Float | Minimum seconds between changes |
| `ActiveAtmosphereTag` | GameplayTag | Current atmosphere state |

---

### BPC_MemoryDriftSystem — Actor Component (on Level Blueprint or dedicated Actor)

**Purpose:**
Manages the "room swap" or "memory drift" effect — subtle changes to rooms the player has already visited. Supports both gradual and sudden environment mutations.

**Responsibilities:**
- Track which rooms the player has visited and in what order
- Trigger subtle room mutations (moved objects, changed lighting, new notes appearing)
- Coordinate with BPC_AdaptiveEnvironmentDirector for timing
- Track mutation history for narrative significance
- Support "hard drift" (dramatic change) and "soft drift" (subtle)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `VisitedRooms` | Map (RoomTag → S_RoomVisitData) | Room visit history |
| `MutationRegistry` | Array of DA_RoomMutation | Available mutations for each room |
| `ActiveMutations` | Set of GameplayTag | Currently active mutations |
| `DriftIntensity` | Float | 0–1 global drift severity |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_RoomVisitData` | RoomTag, VisitCount, LastVisitTime, ActiveMutationTag | Per-room tracking |

---

### BPC_AtmosphereStateController — Actor Component (on Level Blueprint)

**Purpose:**
Manages the current atmospheric state of the level. Controls ambient lighting colour, fog density, wind audio, and ambient sound layers.

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `CurrentAtmosphereTag` | GameplayTag | Active atmosphere state |
| `AtmosphereProfiles` | Map (GameplayTag → DA_AtmosphereProfile) | State → profile lookup |
| `TransitionDuration` | Float | Blend time between states |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `SetAtmosphere` | AtmosphereTag, BlendTime | — | Transition to new state |
| `PushAtmosphereOverride` | Tag, Duration | — | Temporary override |
| `PopAtmosphereOverride` | — | — | Restore previous state |

---

### BPC_ScareEventSystem — Actor Component (on Game State or dedicated Director Actor)

**Purpose:**
Manages the scheduling and firing of scare events: jump scares, ambient scares, audio stingers, and environmental anomalies.

**Responsibilities:**
- Maintain a scare event queue (from DA_ScareEvent assets)
- Enforce scare cooldowns (prevent scare saturation)
- Select appropriate scare tier based on current stress level
- Broadcast `I_ScareTarget.OnScareEventFired()` to affected actors
- Track scare history to avoid repetition

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `ScareEventPool` | Array of DA_ScareEvent | Available scare events |
| `LastScareTime` | Float | Timestamp of last scare |
| `ScareCooldownMin` | Float | Minimum gap between scares |
| `ActiveScareTier` | E_ScareTier | Matched to stress tier |
| `ScareHistory` | Array of GameplayTag | Recently fired scares |

**Enums:**

| Enum | Values | Description |
|------|--------|-------------|
| `E_ScareTier` | Ambient, Minor, Moderate, Major, JumpScare, Cinematic | Scare intensity |

**Blueprint Flow:**
```
[Director decides scare is appropriate]
  └─► Check ScareCooldown passed?
  └─► Get valid scares for ActiveScareTier
  └─► Filter out recently fired scares
  └─► Select scare event
  └─► Execute scare:
      ├─► Audio → BPC_AudioAtmosphereController
      ├─► Visual → BPC_LightEventController / WBP_ScreenEffectController
      └─► Actor → Broadcast I_ScareTarget to tagged actors
  └─► Add to ScareHistory
  └─► Reset ScareCooldown timer
```

---

### BPC_LightEventController — Actor Component (on Level Blueprint)

**Purpose:**
Controls scripted and adaptive light events: flickers, fade-outs, colour shifts, power failures.

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `ManagedLights` | Array of Light Component | Lights under this system's control |
| `LightEventProfiles` | Map (GameplayTag → DA_LightEvent) | Event definitions |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `TriggerLightEvent` | EventTag | — | Plays the named light event |
| `FlickerLight` | LightRef, Duration, Rate | — | Flickers a specific light |
| `SetLightColour` | LightRef, Colour, BlendTime | — | Smooth colour transition |
| `PowerFailure` | Duration | — | All managed lights off |

---

### BPC_AudioAtmosphereController — Actor Component (on Game State)

**⚠️ DEPRECATED** — Replaced by `SS_AudioManager` (132) GameInstance Subsystem and `BP_RoomAudioZone` (133) trigger volumes. The MetaSounds audio architecture (`docs/architecture/metasounds-audio-system.md`) replaces the component-based approach with bus management, room presets, and gameplay parameter injection. Migrate any audio atmosphere logic to `SS_AudioManager.SetRoomPreset()` and `BP_RoomAudioZone` triggers.

**Key Variables (legacy reference only):**

| Name | Type | Description |
|------|------|-------------|
| `MusicState` | GameplayTag | Active music layer |
| `AmbientLayers` | Map (GameplayTag → AudioComponent) | Active ambient components |
| `StingerQueue` | Array of SoundBase | One-shot stinger queue |
| `MasterMoodLevel` | Float | 0–1 tension level |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `SetMusicState` | StateTag, BlendTime | — | Crossfade to new music |
| `TriggerStinger` | StingerAsset | — | Fire one-shot audio event |
| `SetAmbientLayer` | LayerTag, Volume | — | Adjust ambient mix |
| `SetMoodLevel` | 0–1 | — | Drives RTPC / MetaSound parameter |

---

### BPC_PacingDirector — Actor Component (on GameMode)

**Purpose:**
Monitors overall session pacing: tension curves, quiet beats, and escalation patterns. Prevents scare fatigue by enforcing structured ups and downs.

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `TensionCurve` | CurveFloat | Ideal tension over session time |
| `CurrentTension` | Float | Actual measured tension |
| `TensionSources` | Map (GameplayTag → Float) | Contributing tension sources |
| `LastQuietBeatTime` | Float | Ensures periodic relief |
| `QuietBeatMinInterval` | Float | Minimum time between quiet beats |

---

---

### BPC_RareEventSystem — Actor Component (on GameMode)

**Purpose:**
Controls ultra-rare, randomised world events that can occur once per session or with very low probability: hidden messages, brief hallucinations, entity sightings.

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `RareEventPool` | Array of DA_RareEvent | Available rare events |
| `FiredRareEvents` | Set of GameplayTag | Already triggered this session |
| `EligibilityConditions` | Map (GameplayTag → S_RareEventCondition) | When each event can fire |

---

### MetaSounds Audio Subsystem (132-135)

*The framework uses UE5 MetaSounds for all audio. These systems replace the deprecated `BPC_AudioAtmosphereController` with a modern bus-based architecture.*

---

### SS_AudioManager — GameInstance Subsystem (132)

**C++ Status:** 🔵 BP-only (planned C++ stub)

**Purpose:**
Single entry point for all audio playback. Routes through `MS_MasterBus` → 4 category buses (SFX, Ambience, Music, Dialogue). Never call `UGameplayStatics::PlaySound*` directly — always use this subsystem.

**Responsibilities:**
- Manage 4 MetaSound mix buses with volume/effect controls
- Accept `SetBusVolume(Category, Volume)` calls from settings menu
- Push gameplay float parameters (heart rate, stress, fear, music intensity) to MetaSound patches
- Switch room acoustic presets when `BP_RoomAudioZone` triggers overlap
- Play 150+ sound triggers from the sound catalog (`docs/architecture/sound-catalog.md`)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `MasterBus` | MetaSound Patch | Final output bus |
| `SFXBus` | MetaSound Patch | Weapon, impact, interaction sounds |
| `AmbientBus` | MetaSound Patch | Environmental ambience |
| `MusicBus` | MetaSound Patch | Adaptive music layers |
| `DialogueBus` | MetaSound Patch | Voice-over and subtitles |
| `CurrentRoomPreset` | DA_RoomAcousticPreset | Active reverb/occlusion profile |
| `GameplayParameters` | Map (FName → Float) | HeartRate, Stress, Fear, MusicIntensity |

**Full Spec:** [`docs/architecture/metasounds-audio-system.md`](docs/architecture/metasounds-audio-system.md)

---

### BP_RoomAudioZone — Actor (133)

**Purpose:**
Trigger volume that automatically switches reverb/occlusion settings when the player enters/leaves a room. Communicates with `SS_AudioManager.SetRoomPreset()`.

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `RoomPreset` | DA_RoomAcousticPreset | The acoustic profile for this zone |
| `BlendDuration` | Float | Crossfade time between presets |
| `Priority` | Integer | For overlapping zones |

---

### Audio Data Assets (134-135)

- **DA_AudioSettings** (134) — Global audio config: bus volumes, default presets, subtitle settings
- **DA_RoomAcousticPreset** (135) — Per-zone profile: reverb params, occlusion curves, EQ settings. Pre-built presets: SmallRoom, LargeHall, Outdoor, Cave, Corridor, Basement, VentilationShaft

### MetaSounds Audio Conventions (Summary)
- **Single Entry Point:** All playback via `SS_AudioManager` — never raw `PlaySound*`
- **Mix Buses:** 4 categories → Master Bus, each with own MetaSound patch
- **Room Zones:** `BP_RoomAudioZone` trigger volumes handle reverb/occlusion switching
- **Settings Integration:** Volume sliders in `WBP_SettingsMenu` call `SS_AudioManager.SetBusVolume()`
- **Gameplay Parameters:** Heart rate, stress, fear pushed as MetaSound float parameters from gameplay systems
- **Deprecated:** `BPC_AudioAtmosphereController` (95) → migrate to `SS_AudioManager`

---

# 10. AI, Perception & Encounter Systems

---

### AI_BaseAgentController — AI Controller (Blueprint)

**Purpose:**
Base AI controller for all enemy archetypes. Provides common perception integration, blackboard setup, and behaviour tree launch.

**Responsibilities:**
- Initialise perception component (sight, hearing, damage)
- Setup blackboard with standard keys
- Launch the archetype's behaviour tree
- Route perception events to BB keys
- Implement AI_Memory system hooks

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `PerceptionComponent` | AIPerceptionComponent | Sight + hearing config |
| `BehaviourTree` | BehaviourTree | Agent's BT asset |
| `Blackboard` | BlackboardComponent | Standard BB (BB_AgentBoard) |
| `MemoryComponent` | BPC_AIMemorySystem | Memory tracking |

---

### BB_AgentBoard — Blackboard Asset

**Standard Keys:**

| Key | Type | Description |
|-----|------|-------------|
| `TargetActor` | Object | Current pursuit target |
| `LastKnownTargetLocation` | Vector | Last seen location |
| `AlertState` | Enum (E_AIAlertState) | Current alert level |
| `PatrolTargetIndex` | Integer | Current patrol point |
| `bIsInvestigating` | Bool | Investigating state active |
| `InvestigateLocation` | Vector | Where to investigate |
| `bTargetLost` | Bool | Lost sight of target |
| `PlayerPlaystyleTag` | GameplayTag | Adaptive behaviour hook |
| `LastHeardLocation` | Vector | Most recent sound location |

---

### BPC_AIPerceptionSystem — Actor Component (on AI Agent)

**Purpose:**
Manages how an AI agent perceives the world: vision cone, hearing radius, and damage alerts.

**Responsibilities:**
- Configure UE5 AIPerception component at runtime from DA_PerceptionConfig
- Process perception events and update blackboard keys
- Respect player's `Player.State.Hidden` gameplay tag
- Apply stress-based noise detection (stressed player breathes louder)
- Broadcast alert state changes

**Enums:**

| Enum | Values | Description |
|------|--------|-------------|
| `E_AIAlertState` | Unaware, Curious, Suspicious, Alerted, Engaged, Searching | Alert escalation |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `OnSightPerceptionUpdate` | Stimuli | — | Handle sight event |
| `OnHearingPerceptionUpdate` | Stimuli | — | Handle noise event |
| `OnDamagePerceptionUpdate` | Stimuli | — | Handle being hit |
| `EscalateAlertState` | NewState | — | Update BB + broadcast |
| `GetAlertState` | — | E_AIAlertState | Current state query |

---

### BPC_AIMemorySystem — Actor Component (on AI Agent)

**Purpose:**
Gives AI agents persistent short-term memory: where they last saw the player, what sounds they heard, which areas they've searched.

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `MemoryEntries` | Array of S_AIMemoryEntry | Timestamped memory records |
| `MemoryDecayTime` | Float | How long memories last |
| `SearchedLocations` | Array of Vector | Already investigated points |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_AIMemoryEntry` | Location, MemoryType: E_MemoryType, Timestamp, Confidence | One memory record |

**Enums:**

| Enum | Values | Description |
|------|--------|-------------|
| `E_MemoryType` | Sighting, Sound, Damage, Smell, ScriptedHint | Memory source type |

---

### BPC_BehaviourVariantSelector — Actor Component (on AI Agent)

**Purpose:**
Selects which behaviour variant the AI uses based on player playstyle tag. Adapts difficulty and aggression to match the player's approach.

**Responsibilities:**
- Subscribe to BPC_PlaystyleClassifier.OnPlaystyleChanged
- Map playstyle tags to behaviour variant tags
- Update BB key `PlayerPlaystyleTag` on change
- Swap patrol patterns, reaction times, search radius based on variant

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `VariantMap` | Map (PlaystyleTag → DA_BehaviourVariant) | Playstyle → variant lookup |
| `DefaultVariant` | DA_BehaviourVariant | Fallback variant |

---

### BPC_EncounterDirector — Actor Component (on GameMode or dedicated Actor)

**Purpose:**
Controls the spawning, despawning, and escalation of AI encounters. Manages encounter pools and prevents encounter stacking.

**Responsibilities:**
- Register encounter definitions from DA_EncounterData
- Determine when to activate encounters based on pacing director
- Spawn/despawn AI agents respecting budget limits
- Track active encounters in GS_CoreGameState
- Support scripted (always-on) and dynamic (adaptive) encounters

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `ActiveEncounters` | Array of S_ActiveEncounter | Running encounters |
| `EncounterPool` | Array of DA_EncounterData | Available encounters |
| `MaxActiveEncounters` | Integer | Concurrent encounter limit |
| `bEncountersEnabled` | Bool | Master toggle |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_ActiveEncounter` | EncounterTag, SpawnedAgents, StartTime, EncounterState | Running encounter record |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnEncounterStarted` | EncounterTag | Encounter activates |
| `OnEncounterEnded` | EncounterTag, Outcome | Encounter resolves |

---

### DA_EncounterData — Data Asset

**Fields:**
```
└─ EncounterTag: GameplayTag
└─ AgentArchetypeTag: GameplayTag
└─ SpawnPoints: Array FName (socket names or actor tags)
└─ MaxAgents: Integer
└─ TriggerCondition: S_EncounterCondition
└─ EndCondition: S_EncounterCondition
└─ bIsPersistent: Bool (despawns on leave or persists)
└─ BehaviourVariantTag: GameplayTag
└─ EncounterMusicTag: GameplayTag
```

---

# 11. Achievements, Progression & Meta Systems

---

### SS_AchievementSystem — GameInstance Subsystem

**Purpose:**
Platform-agnostic achievement and trophy system. Handles unlock logic, progress tracking, hidden achievements, and platform API submission.

**Responsibilities:**
- Load achievement definitions from DA_AchievementData assets
- Track progress for incremental achievements
- Evaluate unlock conditions against game state
- Submit to platform APIs (Steam, PlayStation, Xbox) via platform abstraction
- Display unlock notification via WBP_NotificationToast
- Support hidden achievements (concealed name/description until unlocked)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `AchievementRegistry` | Map (GameplayTag → S_AchievementState) | All achievements + current state |
| `UnlockedAchievements` | Set of GameplayTag | Already unlocked tags |
| `PendingSubmissions` | Array of GameplayTag | Unlocked but not yet sent to platform |
| `bOfflineMode` | Bool | Platform submission deferred |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_AchievementState` | AchievementTag, CurrentProgress, TargetProgress, bIsUnlocked, UnlockTimestamp | Runtime achievement state |

**Enums:**

| Enum | Values | Description |
|------|--------|-------------|
| `E_AchievementType` | Narrative, Collection, Survival, Exploration, Combat, Secret, Progress, Meta | Achievement category |
| `E_AchievementCondition` | FlagSet, ValueThreshold, CountReached, EndingAchieved, CollectionComplete | How it unlocks |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `NotifyEvent` | EventTag, Value: Float | — | Called by game systems; checks all relevant achievements |
| `UnlockAchievement` | AchievementTag | — | Marks unlocked, submits to platform |
| `UpdateProgress` | AchievementTag, Delta | — | Increments progress tracker |
| `GetAchievementState` | AchievementTag | S_AchievementState | Returns current state |
| `GetAllAchievements` | — | Array S_AchievementState | For achievements menu |
| `SubmitPendingToplatform` | — | — | Flush pending on reconnect |
| `IsUnlocked` | AchievementTag | Bool | Quick check |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnAchievementUnlocked` | AchievementTag, Data | Achievement fires |
| `OnProgressUpdated` | AchievementTag, NewProgress | Progress changes |

**Blueprint Flow:**
```
[Game system calls NotifyEvent(Tag, Value)]
  └─► Iterate AchievementRegistry
  └─► Find achievements with matching EventTag
  └─► For each:
      ├─► Already unlocked? → skip
      ├─► Update progress if incremental
      ├─► Evaluate condition:
      │   ├─► FlagSet → check BPC_NarrativeStateSystem
      │   ├─► ValueThreshold → check value
      │   └─► CountReached → check progress
      └─► Condition met? → UnlockAchievement()
                           → Platform submit
                           → Broadcast OnAchievementUnlocked
                           → WBP_NotificationToast.ShowAchievement
```

---

### DA_AchievementData — Data Asset

**Fields:**
```
DA_AchievementData extends UPrimaryDataAsset
  └─ AchievementTag: GameplayTag        (unique identifier)
  └─ DisplayName: FText                 (shown when unlocked or visible)
  └─ HiddenName: FText                  (shown before unlock if secret)
  └─ Description: FText
  └─ HiddenDescription: FText           (shown if secret and locked)
  └─ Icon: Texture2D
  └─ LockedIcon: Texture2D              (greyed-out version)
  └─ AchievementType: E_AchievementType
  └─ bIsSecret: Bool                    (hidden until unlocked)
  └─ bIsHidden: Bool                    (not shown at all until unlocked)
  └─ ConditionType: E_AchievementCondition
  └─ TriggerEventTags: Array GameplayTag (which NotifyEvent calls trigger check)
  └─ TargetFlag: GameplayTag            (for FlagSet condition)
  └─ TargetValue: Float                 (for ValueThreshold/CountReached)
  └─ SteamAPIName: String               (platform achievement ID)
  └─ PlatformAchievementID: String      (PSN/Xbox equivalent)
  └─ XPReward: Integer                  (optional meta progression)
  └─ bUnlocksContent: Bool              (triggers post-game unlock)
  └─ UnlockedContentTag: GameplayTag    (what content unlocks)
```

---

### BPC_ProgressStatTracker — Actor Component (on Player Pawn)

**Purpose:**
Central statistics hub. Accumulates all session and lifetime stats that feed achievements, run summaries, and meta progression.

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `SessionStats` | Map (GameplayTag → Float) | Current session stats |
| `LifetimeStats` | Map (GameplayTag → Float) | Accumulated across saves |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `IncrementStat` | StatTag, Amount | — | Adds to both session and lifetime |
| `SetStat` | StatTag, Value | — | Absolute set |
| `GetStat` | StatTag, bLifetime | Float | Read session or lifetime value |

---

### BPC_EndingCompletionTracker — Actor Component (on Game Instance)

**Purpose:**
Tracks across saves which endings the player has achieved. Enables meta progression (NG+ unlocks, secret content).

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `AchievedEndings` | Set of GameplayTag | All achieved ending tags |
| `TotalEndingCount` | Integer | Total possible endings |
| `CompletionPercentage` | Float | % of endings seen |

---

### BPC_MetaProgressionSystem — Actor Component (on Game Instance)

**Purpose:**
Manages content that unlocks across multiple playthroughs: bonus modes, alternate costumes, developer commentary, speedrun mode.

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `UnlockedContentTags` | Set of GameplayTag | Globally unlocked content |
| `MetaFlags` | Map (GameplayTag → Bool) | Meta-level flags (NG+ active, etc.) |

---

### BPC_RunSummarySystem — Actor Component (on Game State)

**Purpose:**
Assembles the end-of-run summary screen data: stats, ending, deaths, achievements, and time.

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `SummaryData` | S_RunSummary | Assembled summary struct |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_RunSummary` | TotalTime, Deaths, EndingTag, AchievementsUnlocked, ItemsFound, SecretsFound, PlaystyleTag, ChaptersCompleted | Full run record |

---

# 12. Settings, Accessibility & Platform Systems

---

### SS_SettingsSystem — GameInstance Subsystem

**Purpose:**
Persists and distributes all player settings (audio, graphics, controls, accessibility). Single source of truth for all preference data.

**Responsibilities:**
- Load settings from `USaveGame` on startup
- Distribute settings to relevant systems (console commands for graphics, audio mix for audio, etc.)
- Apply settings immediately on change
- Save settings on change (auto-save, not manual)
- Expose typed getters for each setting category

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `AudioSettings` | S_AudioSettings | Volume, music, SFX, voice, subtitles |
| `GraphicsSettings` | S_GraphicsSettings | Resolution, quality, FOV, brightness |
| `ControlSettings` | S_ControlSettings | Sensitivity, invert, button remaps |
| `AccessibilitySettings` | S_AccessibilitySettings | Subtitle size, contrast, colour blind, motion |

**Structs:**

| Struct | Fields | Description |
|--------|--------|-------------|
| `S_AudioSettings` | MasterVolume, MusicVolume, SFXVolume, VoiceVolume, bSubtitlesEnabled, SubtitleLanguage | Audio preferences |
| `S_GraphicsSettings` | ResolutionScale, QualityPreset, TargetFPS, bVSync, FOV, Brightness, Gamma, bHDREnabled, bMotionBlur, bFilmGrain | Graphics preferences |
| `S_ControlSettings` | MouseSensitivityX, MouseSensitivityY, bInvertY, GamepadSensitivity, bVibrationEnabled, KeyRemaps | Control preferences |
| `S_AccessibilitySettings` | SubtitleSize, bHighContrast, ColourBlindMode: E_ColourBlindMode, bReduceMotion, bScreenShakeReduction, UIScale | Accessibility preferences |

**Enums:**

| Enum | Values | Description |
|------|--------|-------------|
| `E_ColourBlindMode` | None, Protanopia, Deuteranopia, Tritanopia | Colour blindness support |
| `E_QualityPreset` | Low, Medium, High, Ultra, Custom | Graphics quality presets |

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `ApplyAudioSettings` | S_AudioSettings | — | Sets audio mix parameters |
| `ApplyGraphicsSettings` | S_GraphicsSettings | — | Executes console commands |
| `ApplyControlSettings` | S_ControlSettings | — | Updates input mappings |
| `ApplyAccessibilitySettings` | S_AccessibilitySettings | — | Updates UI scale, subtitle size, etc. |
| `ResetToDefaults` | Category: E_SettingsCategory | — | Reset one category |
| `SaveSettings` | — | — | Persist all settings |

**Event Dispatchers:**

| Name | Parameters | Fired when |
|------|-----------|-----------|
| `OnSettingsChanged` | Category: E_SettingsCategory | Any setting changes |
| `OnSettingsApplied` | — | After full apply pass |

---

### BPC_HapticsController — Actor Component (on Player Controller)

**Purpose:**
Abstraction layer for haptic feedback: DualSense adaptive triggers, rumble, and speaker audio on controller.

**Responsibilities:**
- Trigger haptics for game events (damage, impact, footstep, heartbeat)
- Support DualSense-specific features (trigger resistance, trigger vibration)
- Fallback gracefully on non-PS5 platforms (standard rumble)
- Respect accessibility settings (haptics on/off)

**Key Variables:**

| Name | Type | Description |
|------|------|-------------|
| `bHapticsEnabled` | Bool | Master haptics toggle |
| `HapticProfiles` | Map (GameplayTag → DA_HapticProfile) | Event → haptic data |

---

### BPC_PlatformServiceAbstraction — Actor Component (on Game Instance)

**Purpose:**
Wraps all platform-specific APIs (Steam, PlayStation, Xbox) behind a common interface. The rest of the framework never calls platform APIs directly.

**Responsibilities:**
- Achievement submission (routes to Steam API / PSN Trophies / Xbox Achievements)
- Cloud save sync
- Platform overlay (Screenshot, Share, Trophy notification)
- Online status and invite handling hooks
- Return stub implementations on unsupported platforms

**Functions / Events:**

| Name | Inputs | Outputs | What it does |
|------|--------|---------|--------------|
| `SubmitAchievement` | PlatformID: String | Bool | Platform-specific achievement unlock |
| `SyncCloudSave` | SlotIndex | Bool | Upload save to cloud |
| `ShowPlatformOverlay` | OverlayType | — | Open platform UI |

---

# 13. Editor / Data / Content Authoring Support Systems

*These are not runtime systems but conventions, data structures, and tools that ensure the team can build content consistently.*

---

## Data Asset Architecture

Every major content type has its own Primary Data Asset class registered with the Asset Manager for async streaming.

| Asset Class | Content It Defines | Used By |
|-------------|-------------------|---------|
| `DA_ItemData` | All item properties | BPC_InventorySystem, DA_ItemDatabase |
| `DA_WeaponData` | Weapon properties and stats | BPC_MeleeSystem, BPC_FirearmSystem |
| `DA_InteractionData` | Interaction prompt, type, requirements | I_Interactable objects |
| `DA_DialogueSequence` | Ordered dialogue lines | BPC_DialoguePlaybackSystem |
| `DA_ConsequenceRule` | Narrative flag → world consequence | BPC_BranchingConsequenceSystem |
| `DA_EndingData` | Ending conditions and content | BPC_EndingAccumulatorSystem |
| `DA_ObjectiveData` | Objective text, conditions | BPC_ObjectiveSystem |
| `DA_AchievementData` | Achievement definition | SS_AchievementSystem |
| `DA_EncounterData` | Enemy encounter configuration | BPC_EncounterDirector |
| `DA_ScenarioData` | Trial/scenario rules | BPC_TrialScenarioSystem |
| `DA_AtmosphereProfile` | Lighting/audio/fog state | BPC_AtmosphereStateController |
| `DA_ScareEvent` | Scare trigger definition | BPC_ScareEventSystem |
| `DA_RoomMutation` | Environmental mutation content | BPC_MemoryDriftSystem |
| `DA_BehaviourVariant` | AI variant stats and patterns | BPC_BehaviourVariantSelector |
| `DA_HapticProfile` | DualSense haptic pattern | BPC_HapticsController |
| `DA_AdaptationRule` | Adaptive director rule | BPC_AdaptiveEnvironmentDirector |
| `DA_EquipmentConfig` | Which equipment slots exist | BPC_EquipmentSlotSystem |
| `DA_PuzzleData` | Puzzle solution definition | BP_PuzzleDeviceActor |
| `DA_LoreEntry` | Lore content | BPC_LoreUnlockSystem |
| `DA_RareEvent` | Rare world event definition | BPC_RareEventSystem |

---

## Naming Conventions for Content (Assets/Folders)

```
Items/
  DA_Item_MedKit
  DA_Item_Flashlight
  DA_Item_KeyCard_Omega

Weapons/
  DA_Weapon_Crowbar
  DA_Weapon_Pistol_9mm

Dialogue/
  DA_Dialogue_Intro_Scene01
  DA_Dialogue_Choice_Basement_A

Objectives/
  DA_Obj_MainQuest_FindExit
  DA_Obj_Optional_SecretRoom

Achievements/
  DA_Ach_FirstDeath
  DA_Ach_NoKills
  DA_Ach_AllEndings

Encounters/
  DA_Enc_Library_Patrol
  DA_Enc_Corridor_Chase

Atmosphere/
  DA_Atmo_SafeRoom
  DA_Atmo_Tension_High
  DA_Atmo_AltDeathSpace

ScareEvents/
  DA_Scare_Jumpscare_Window
  DA_Scare_Ambient_Breathing

RoomMutations/
  DA_Mutation_Library_Books
  DA_Mutation_Hallway_Mirror
```

---

## Save Versioning Convention

```
SaveVersion = Integer incremented on every schema change.

MigrationTable:
  Version 0 → 1: Added S_StressSnapshot field (default 0.0)
  Version 1 → 2: Added AltDeathSpaceEnterCount field (default 0)
  Version 2 → 3: Renamed NarrativeFlags map key format

All migration handled in SS_SaveManager.MigrateSaveVersion().
Never remove save fields — mark as deprecated with bLEGACY_ prefix.
```

---

## Recommended Dependency Rules for Teams

```
RULE 1: Data Assets never reference Blueprints.
RULE 2: Systems never reference UI Widgets directly — use dispatchers.
RULE 3: Components never import other components by class — use interfaces.
RULE 4: Narrative flags are the ONLY cross-system currency — never pass actor references across narrative boundaries.
RULE 5: All player metrics funnel through BPC_PlayerMetricsTracker — no system self-reports to achievements.
RULE 6: SS_SaveManager is the ONLY system that touches disk — nothing else reads/writes save files.
RULE 7: GASP internals are read-only — extend via notify events and Smart Object hooks only.
RULE 8: Platform APIs only through BPC_PlatformServiceAbstraction — never call Steam/PS/Xbox SDK directly.
```

---

# Build Order & Implementation Roadmap

> **Note:** The definitive prioritized build list with C++ status per system lives in [`docs/checklists/remaining-blueprint-build-order.md`](docs/checklists/remaining-blueprint-build-order.md). Below is the architectural build order showing the major phases. All 22 C++ classes are already implemented and compile-ready.

---

## Recommended Build Order (Dependency-Safe)

### Phase 0 — Foundation + Input (Week 1–2)
Build these first. Everything else depends on them.

```
 1. 11 Data Tables (import CSVs, register in Project Settings)
 2. DA_GameTagRegistry           ← Data Asset instance with 11 table refs
 3. FL_GameUtilities             ← Static library, no build needed
 4. I_InterfaceLibrary           ← 9 interfaces, implement on actors as needed
 5. GI_GameFramework             ← BP child → set as Default GameInstance
 6. GM_CoreGameMode              ← BP child → set as Default GameMode
 7. GS_CoreGameState             ← BP child
 8. PC_CoreController + PS_CorePlayerState  ← BP children
 9. SS_EnhancedInputManager      ← Auto-created subsystem (C++)
10. 22 IA_* + 5 IMC_* assets     ← Create in editor
11. DA_InputMappingProfile       ← Per-platform instances
```

### Phase 1 — State Management (Week 2)
```
12. E_PlayerActionState enum (42 values)
13. E_OverlayState enum (18 values)
14. E_ActionRequestResult enum (8 values)
15. DA_StateGatingTable          ← Data Asset with 37 gating rules
16. BPC_StateManager             ← Attach to player pawn (C++)
```

### Phase 2 — Player Core (Week 3–4)
```
17. BPC_HealthSystem             ← C++ stub — BP child adds logic
18. BPC_StaminaSystem            ← C++ stub — BP child adds logic
19. BPC_StressSystem             ← C++ stub — BP child adds logic
20. BPC_MovementStateSystem      ← C++ stub — BP child adds logic
21. BPC_DamageReceptionSystem    ← Attach to pawn (C++)
22. BPC_InventorySystem          ← Attach to pawn (C++)
23. BPC_ShieldDefenseSystem      ← C++ stub — BP child adds logic
24. BPC_HitReactionSystem        ← C++ stub — BP child adds logic
25. BPC_PlayerMetricsTracker
26. BPC_HidingSystem
27. BPC_EmbodimentSystem
28. BPC_CameraStateLayer
```

### Phase 3 — Interaction (Week 5–6)
```
29. BPC_InteractionDetector
30. BP_DoorActor
31. BPC_ContextualTraversalSystem
32. BPC_PhysicsDragSystem
33. WBP_InteractionPromptDisplay
```

### Phase 4 — Inventory (Week 7–8)
```
34. BPC_EquipmentSlotSystem
35. BPC_ActiveItemSystem
36. BPC_KeyItemSystem
37. BPC_ConsumableSystem
38. BPC_DocumentArchiveSystem
39. BPC_JournalSystem
40. BPC_CollectibleTracker
41. BPC_ItemCombineSystem
42. BP_ItemPickup
43. BPC_ContainerInventory
44. DA_ItemData instances
```

### Phase 5 — Save/Load (Week 9–10)
```
45. SS_SaveManager              ← Auto-created subsystem (C++)
46. I_Persistable               ← Implement on actors
47. BP_Checkpoint
48. BPC_DeathHandlingSystem
49. BPC_PlayerRespawnSystem
50. BPC_PersistentWorldStateRecorder
51. BPC_PersistentCorpseSystem
52. BPC_RunHistoryTracker
53. BPC_AltDeathSpaceSystem
```

### Phase 6 — UI (Week 11–12)
```
54. SS_UIManager
55. WBP_HUDController
56. WBP_DiegeticHUDFrame
57. WBP_InteractionPromptDisplay
58. WBP_InventoryMenu
59. WBP_ScreenEffectController
60. WBP_NotificationToast
61. WBP_PauseMenu
62. WBP_MainMenu
63. WBP_SettingsMenu
64. WBP_MenuFlowController
65. WBP_ObjectiveDisplay
66. WBP_JournalDocumentViewer
67. WBP_AccessibilityUI
```

### Phase 7 — Narrative (Week 13–15)
```
68. BPC_NarrativeStateSystem
69. BPC_ObjectiveSystem
70. BPC_DialoguePlaybackSystem
71. BPC_DialogueChoiceSystem
72. BPC_BranchingConsequenceSystem
73. BPC_EndingAccumulator
74. BPC_CutsceneBridge
75. BPC_LoreUnlockSystem
76. BPC_TrialScenarioSystem
77. BP_NarrativeTriggerVolume
78. DA_NarrativeDataAssets instances
```

### Phase 8 — Weapons (Week 16–17)
```
79. BP_WeaponBase
80. BPC_MeleeSystem
81. BPC_FirearmSystem
82. BPC_ReloadSystem
83. BPC_RecoilSystem
84. BPC_AmmoComponent
85. BPC_CombatFeedbackComponent
86. BPC_DeathCauseTracker
87. DA_EquipmentConfig instances
```

### Phase 9 — AI (Week 18–20)
```
88. BB_AgentBoard
89. AI_BaseAgentController
90. BP_EnemyBase
91. BPC_AIPerceptionSystem
92. BPC_AIMemorySystem
93. BPC_AlertSystem
94. BPC_AIStateMachine
95. BP_PatrolPath
96. BPC_BehaviourVariantSelector
```

### Phase 10 — Adaptive + Audio (Week 21–23)
```
 97. BPC_PlaystyleClassifier
 98. BPC_AdaptiveEnvironmentDirector
 99. BPC_AtmosphereStateController
100. BPC_ScareEventSystem
101. BPC_LightEventController
102. BPC_PacingDirector
103. BPC_MemoryDriftSystem
104. BPC_RareEventSystem
105. BPC_DifficultyManager
106. BPC_FearSystem
107. BPC_PerformanceScaler
108. BPC_ProceduralEncounter
109. SS_AudioManager              ← MetaSounds subsystem
110. BP_RoomAudioZone             ← Acoustic trigger volumes
111. DA_AudioSettings + DA_RoomAcousticPreset instances
```

### Phase 11 — Meta + Settings + Polish (Week 24–26)
```
112. BPC_ProgressStatTracker
113. SS_AchievementSystem
114. SS_SettingsSystem
115. BPC_AccessibilitySettings
116. BPC_TutorialSystem
117. BPC_LoadingScreen
118. BPC_AnalyticsTracker
119. BPC_DevCheatManager
120. BPC_ErrorHandler
121. BPC_FPSCounter
122. WBP_CreditsScreen
123. WBP_DebugMenu
124. WBP_SplashScreen
125. All remaining DA_* Data Asset instances
```

---

## Smallest Playable Prototype

*The absolute minimum to have a functional first-person character. All C++ classes marked with ✅ are ready to use:*

```
✓ 11 Data Tables (import CSVs)
✓ DA_GameTagRegistry (Data Asset + 11 table refs)
✓ FL_GameUtilities (static library)
✓ I_Interactable, I_Damageable, I_Persistable (C++ interfaces)
✓ GI_GameFramework (BP child → GameInstance)
✓ GM_CoreGameMode (BP child → GameMode)
✓ GS_CoreGameState (BP child)
✓ PC_CoreController + PS_CorePlayerState (BP children from C++ stubs)
✓ SS_EnhancedInputManager (auto-created C++ subsystem)
✓ 8 IA_* + 1 IMC_Default (input assets)
✓ BPC_StateManager (C++ component → attach to pawn)
✓ DA_StateGatingTable (Data Asset with 8 min rules)
✓ BPC_HealthSystem (C++ stub → BP child adds logic)
✓ BPC_StaminaSystem (C++ stub → BP child adds logic)
✓ BPC_MovementStateSystem (C++ stub → BP child adds logic)
✓ BPC_DamageReceptionSystem (C++ component → attach to pawn)
✓ BPC_InventorySystem (C++ component → attach to pawn)
✓ SS_SaveManager (auto-created C++ subsystem)
✓ BPC_InteractionDetector (BP child from spec)
✓ WBP_HUDController (minimal widget)
✓ WBP_InteractionPromptDisplay (minimal widget)
✓ Player Pawn BP (Character parent → 10+ components attached)
```

*Estimated: ~22 systems. Enough to walk, take damage, manage inventory, save/load, and query state permissions. Expand with weapons, AI, narrative, and UI as needed.*

**Step-by-step guide:** [`docs/developer/project-prototype-guide.md`](docs/developer/project-prototype-guide.md)

---

## Full Production Framework

*All 135 numbered systems + 1 starter GameInstance. Supports:*

```
✓ Complete narrative with branching choices and multiple endings
✓ Full inventory (grid, equipment, key items, consumables, ammo, documents)
✓ Melee + firearms + reload + recoil + shield defense
✓ State Management — 42 action states, 18 overlay states, 37 gating rules
✓ Adaptive AI that responds to player playstyle
✓ Diegetic HUD (swappable skin)
✓ Full save system (auto, checkpoint, hard save, slot manifest, backups)
✓ Persistent corpse/death traces
✓ Alternate death space (limbo mechanic)
✓ Scare system with pacing director and cooldowns
✓ Memory drift / room mutation
✓ Rare events
✓ Achievements/trophies (Steam + PS + Xbox platform abstraction)
✓ Full accessibility settings
✓ Enhanced Input — priority context stack, key rebinding
✓ MetaSounds Audio — 4 bus categories, room zones, gameplay parameters
✓ DualSense haptics + adaptive triggers (BPC_HapticsController 148)
✓ Post-game meta progression and ending tracker
✓ Run history and summary
✓ Document archive + journal + lore system
✓ Collectible tracking
✓ Full item combine system
✓ Puzzle device framework
✓ Contextual traversal (vault, climb, ledge, slide, squeeze)
✓ Physics drag/throw
✓ Subtitles + localisation hooks
✓ Hiding spots
✓ 16 Data Asset types (item, equipment, encounter, atmosphere, scare, haptic, render pipeline, etc.)
✓ Server-authoritative multiplayer networking (HasAuthority gates, Server_ RPCs, RepNotify)
✓ Central state authority — systems never check each other directly
✓ Per-platform render pipeline (Lumen/Baked, Nanite/LOD, DLSS/FSR/TSR/PSSR upscaling)
✓ Quality preset system (Low→Cinematic) with platform-aware profiles
```

---

*End of Reusable UE5 Modular Game Framework v2.0*
*Framework designed for generic use. All system names are project-agnostic.*
*Override in /Game/ folder. Never modify /Framework/ core assets.*
*C++ source: 22 classes in Source/PG_Framework/ | BP specs: 150 numbered files + 2 supplementary in docs/blueprints/*
*Companion docs: docs/checklists/ (build order, status), docs/developer/ (per-category references), docs/architecture/ (state management, audio, networking, animation, sound)*
