From b2b6e1e7c78989bac2a9c1589066c7920a9ca8ea Mon Sep 17 00:00:00 2001 From: Lefteris Notas Date: Tue, 19 May 2026 14:13:51 +0300 Subject: [PATCH] Add developer documentation for systems 11-16, including architecture overview and implementation patterns - Created detailed documentation for systems 102-135 covering achievements, settings, polish, data assets, input management, and state management. - Added INDEX.md for easy navigation of developer reference materials. - Introduced architecture-overview.md to provide a high-level understanding of the framework's structure and communication methods. - Compiled implementation-patterns.md to outline common UE5 Blueprint patterns for consistent development practices. --- .kilo/kilo.json | 6 + CONTEXT.md | 29 +- docs/blueprints/INDEX.md | 16 + docs/developer/01-core-foundation.md | 380 ++++++++++++++++++ docs/developer/02-player-systems.md | 456 ++++++++++++++++++++++ docs/developer/03-interaction-systems.md | 244 ++++++++++++ docs/developer/04-inventory-systems.md | 243 ++++++++++++ docs/developer/05-saveload-systems.md | 186 +++++++++ docs/developer/06-ui-systems.md | 157 ++++++++ docs/developer/07-narrative-systems.md | 133 +++++++ docs/developer/08-weapons-systems.md | 139 +++++++ docs/developer/09-ai-systems.md | 118 ++++++ docs/developer/10-adaptive-systems.md | 149 +++++++ docs/developer/11-16-systems.md | 111 ++++++ docs/developer/INDEX.md | 193 +++++++++ docs/developer/architecture-overview.md | 156 ++++++++ docs/developer/implementation-patterns.md | 295 ++++++++++++++ 17 files changed, 3005 insertions(+), 6 deletions(-) create mode 100644 .kilo/kilo.json create mode 100644 docs/developer/01-core-foundation.md create mode 100644 docs/developer/02-player-systems.md create mode 100644 docs/developer/03-interaction-systems.md create mode 100644 docs/developer/04-inventory-systems.md create mode 100644 docs/developer/05-saveload-systems.md create mode 100644 docs/developer/06-ui-systems.md create mode 100644 docs/developer/07-narrative-systems.md create mode 100644 docs/developer/08-weapons-systems.md create mode 100644 docs/developer/09-ai-systems.md create mode 100644 docs/developer/10-adaptive-systems.md create mode 100644 docs/developer/11-16-systems.md create mode 100644 docs/developer/INDEX.md create mode 100644 docs/developer/architecture-overview.md create mode 100644 docs/developer/implementation-patterns.md diff --git a/.kilo/kilo.json b/.kilo/kilo.json new file mode 100644 index 0000000..9a85742 --- /dev/null +++ b/.kilo/kilo.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://app.kilo.ai/config.json", + "indexing": { + "enabled": true + } +} \ No newline at end of file diff --git a/CONTEXT.md b/CONTEXT.md index 474a466..bf9f9ce 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -76,7 +76,22 @@ docs/ 14-data-assets/ # Data Asset definitions (16 files, 115-127, 129, 134-135) 15-input/ # Enhanced Input System (1 file, 128) 16-state/ # State Management (2 files, 130-131) - architecture/ # Architecture & Design Documents (6 files) + developer/ # Developer Reference Docs (NEW) + INDEX.md # Master developer docs index (11 docs) + architecture-overview.md # Framework-wide architecture walkthrough + implementation-patterns.md # Common UE5 Blueprint patterns used + 01-core-foundation.md # Foundation systems explained + 02-player-systems.md # Player state & embodiment explained + 03-interaction-systems.md # Interaction & world manipulation explained + 04-inventory-systems.md # Inventory, items & collectibles explained + 05-saveload-systems.md # Save/load, persistence, death loop explained + 06-ui-systems.md # UI, menus & diegetic presentation explained + 07-narrative-systems.md # Narrative, dialogue, objectives explained + 08-weapons-systems.md # Weapons, equipment & damage explained + 09-ai-systems.md # AI, perception & encounters explained + 10-adaptive-systems.md # Adaptive environment & atmosphere explained + 11-16-systems.md # Meta, Settings, Polish, Data Assets, Input, State explained + architecture/ # Architecture & Design Documents (6 files) bpc-statemanager.md # BPC_StateManager full spec + Chooser Table Audit metasounds-audio-system.md # MetaSounds audio architecture (mix buses, room zones, settings) animation-catalog.md # Animation requirements for all 135 systems @@ -91,7 +106,7 @@ docs/ enhanced-input-system.md bpc-statemanager.md # NEW — State Manager implementation checklist ``` -**Total: 135 numbered Blueprint files + 5 enums + 5 Data Assets + TEMPLATE.md + AUDIT_REPORT.md + INDEX.md + 6 architecture docs + 1 audit report = 153 files in 17 directory groups** +**Total: 135 numbered Blueprint files + 5 enums + 5 Data Assets + TEMPLATE.md + AUDIT_REPORT.md + INDEX.md + 11 developer docs + 6 architecture docs + 1 audit report = 164 files in 18 directory groups** ## Naming Conventions | Prefix | Type | @@ -166,12 +181,14 @@ docs/ Each file in `docs/blueprints/` follows the template defined in `docs/blueprints/TEMPLATE.md`. Files define: Enums, Structs, Variables, Functions, Event Dispatchers, Flow Diagram, Communication Matrix, and Reuse Notes. ## Documentation Update Protocol (CRITICAL RULE) -**Any change to the framework MUST also update these 3 files in the same commit:** +**Any change to the framework MUST also update these files in the same commit:** 1. [`docs/blueprints/INDEX.md`](docs/blueprints/INDEX.md) — add/update the file entry in the master index -2. [`docs/architecture/animation-catalog.md`](docs/architecture/animation-catalog.md) — if the change adds/modifies animation requirements -3. [`docs/architecture/sound-catalog.md`](docs/architecture/sound-catalog.md) — if the change adds/modifies audio triggers or surfaces +2. [`docs/developer/INDEX.md`](docs/developer/INDEX.md) — if the change affects how a system works internally (data flow, state machines, integration points) +3. The relevant [`docs/developer/`](docs/developer/) category document — if the change modifies a system's behavior, dependencies, or implementation pattern +4. [`docs/architecture/animation-catalog.md`](docs/architecture/animation-catalog.md) — if the change adds/modifies animation requirements +5. [`docs/architecture/sound-catalog.md`](docs/architecture/sound-catalog.md) — if the change adds/modifies audio triggers or surfaces -No PR is accepted without these 3 files being current. This ensures the animator, sound designer, and all team members always have an up-to-date reference. +No PR is accepted without these files being current. This ensures the animator, sound designer, developers, and all team members always have an up-to-date reference. ## MetaSounds Audio Conventions - **Single Entry Point:** All audio playback routes through [`SS_AudioManager`](docs/architecture/metasounds-audio-system.md) Game Instance Subsystem. Never call `UGameplayStatics::PlaySound*` directly. diff --git a/docs/blueprints/INDEX.md b/docs/blueprints/INDEX.md index 78a8d58..93dd7f6 100644 --- a/docs/blueprints/INDEX.md +++ b/docs/blueprints/INDEX.md @@ -30,6 +30,22 @@ docs/blueprints/ ├── 14-data-assets/ ← Data Asset definitions (16 files) ├── 15-input/ ← Enhanced Input System (1 file) └── 16-state/ ← State Management (2 files) + +docs/developer/ ← Developer Reference Docs +├── INDEX.md ← Developer docs master index +├── architecture-overview.md ← Framework-wide architecture +├── implementation-patterns.md ← Common Blueprint patterns +├── 01-core-foundation.md ← Foundation systems explained +├── 02-player-systems.md ← Player systems explained +├── 03-interaction-systems.md ← Interaction systems explained +├── 04-inventory-systems.md ← Inventory systems explained +├── 05-saveload-systems.md ← Save/load systems explained +├── 06-ui-systems.md ← UI systems explained +├── 07-narrative-systems.md ← Narrative systems explained +├── 08-weapons-systems.md ← Weapons systems explained +├── 09-ai-systems.md ← AI systems explained +├── 10-adaptive-systems.md ← Adaptive systems explained +└── 11-16-systems.md ← Meta, Settings, Polish, Data, Input, State ``` --- diff --git a/docs/developer/01-core-foundation.md b/docs/developer/01-core-foundation.md new file mode 100644 index 0000000..74f0c8d --- /dev/null +++ b/docs/developer/01-core-foundation.md @@ -0,0 +1,380 @@ +# 01 — Core Foundation Systems (Systems 01-07) + +**Category Purpose:** The foundation layer provides the application kernel, service resolution, shared utilities, interfaces, game rules, session state, and the base data asset from which all items inherit. Everything else in the framework depends on this layer. + +--- + +## System Index + +| # | System | Asset Type | Role | +|---|--------|-----------|------| +| 01 | `GI_GameTagRegistry` | Data Asset | Central GameplayTag namespace registry & validation | +| 02 | `FL_GameUtilities` | Function Library | Static utility functions (safe casts, math, tags, debug) | +| 03 | `I_InterfaceLibrary` | Interface Collection | All 9 framework interfaces for decoupled communication | +| 04 | `GI_GameFramework` | Game Instance | Application kernel; owns subsystems, manages game phases | +| 05 | `GM_CoreGameMode` | Game Mode | Session rules, player spawn, chapter transitions, death routing | +| 06 | `GS_CoreGameState` | Game State | Shared session state: chapter, objectives, play time | +| 07 | `DA_ItemData` | Data Asset | Base item data asset — all items derive from this template | + +--- + +## Category Data Flow + +``` +┌──────────────────────────────────────────────────────────────────┐ +│ APPLICATION BOOT SEQUENCE │ +│ │ +│ GI_GameFramework.Init() │ +│ ├─► InitPlatformServices() │ +│ ├─► SS_ Subsystems auto-initialize (UE GameInstanceSubsystem) │ +│ ├─► SS_SettingsSystem.PopulateDefaults() │ +│ ├─► SS_SaveSystem.GetSlotManifest() │ +│ └─► SetGamePhase(MainMenu) → Broadcast OnGamePhaseChanged │ +│ │ +│ GM_CoreGameMode (spawned by engine) │ +│ ├─► Reads default class references │ +│ ├─► Spawns PC_CoreController, PS_CorePlayerState │ +│ ├─► Creates GS_CoreGameState │ +│ └─► If save data: LoadFromSlot → SetGamePhase(InGame) │ +│ └─► If new game: TransitionToChapter(first chapter) │ +│ │ +│ GS_CoreGameState.BeginPlay() │ +│ ├─► Bind to GI_GameFramework.OnGamePhaseChanged │ +│ └─► Tick: accumulate ElapsedPlayTime when InGame │ +│ │ +│ ALL SYSTEMS query GameplayTags via GI_GameTagRegistry │ +│ ALL SYSTEMS use FL_GameUtilities for safe casts & logging │ +│ ALL SYSTEMS communicate via I_InterfaceLibrary interfaces │ +│ ALL ITEMS are defined as DA_ItemData Data Assets │ +└──────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 01 — GI_GameTagRegistry: Central GameplayTag Registry + +**What It Does:** This is a **documentation anchor** Data Asset, not a runtime tag database. The actual GameplayTag definitions live in `DefaultGameplayTags.ini`, but this asset serves as the single place where all framework tag namespaces are documented and validated. Every system that uses GameplayTags references them from this registry's documented namespaces. + +**How It Works Internally:** +- At `OnAssetLoaded`, it calls `GetAllRegisteredTags()` to verify the project has tags registered +- If zero tags exist, it logs a warning — this catches misconfigured projects early +- `ValidateTag(Tag)` checks if a given tag exists in the engine's tag table using `RequestGameplayTag()` +- `ExportTagNamespace(Prefix)` iterates registered tags matching a namespace prefix for tooling/docs +- The documented namespaces cover: `Player.State.*`, `Interaction.*`, `Item.*`, `Narrative.*`, `Objective.*`, `AI.*`, `Save.*`, `Achievement.*`, `Environment.*`, `DeathSpace.*` + +**Implementation Patterns:** +- Create as `UPrimaryDataAsset` → Blueprint Data Asset +- Functions are BlueprintCallable / Pure — no tick, no events, no state +- `LogAllTags()` and `ExportTagNamespace()` are Editor-only via `#if WITH_EDITOR` +- Framework tags use `Framework.` prefix; project tags use `Game.` prefix to avoid collisions + +**Integration Points:** +- **Read by:** Every system that does `HasTag()` / `MatchesTag()` comparisons +- **No outgoing calls** — this is purely passive + +**Edge Cases:** +- If the tag table is empty at load, a warning fires but the game still runs (tags can be added later) +- Duplicate tags across namespaces cause `RequestGameplayTag()` to return the first match — validate in editor +- Raw string comparisons are forbidden — always use `HasTag()` or `MatchesTag()` + +--- + +## 02 — FL_GameUtilities: Shared Function Library + +**What It Does:** A static Blueprint Function Library providing safe, reusable utility functions available from any Blueprint without needing an object reference. Handles subsystem lookups, math, tag operations, text formatting, screen projection, and debug logging. + +**How It Works Internally:** +- **Pure static class** — no variables, no tick, no event dispatchers, no state +- **Null-safe subsystem retrieval:** `GetSubsystemSafe()` wraps `GetSubsystem()` in a validity check and returns `None` instead of crashing +- **Typed casts:** `GetGameFramework()` and `GetPlayerController()` cast to framework-specific types and log errors on failure +- **Actor utilities:** `FindComponentByInterface()` iterates components checking `DoesImplementInterface()`; `FindNearestActorWithTag()` sphere-overlaps actors and filters by GameplayTag +- **Math:** `RemapFloat()`, `LerpClamped()`, `VectorToAngle2D()`, `AngleDifference()` — standard blueprint-safe math +- **Tag utilities:** `HasGameplayTag()` checks actor's tag container safely (returns false if no container); `MakeTagFromString()` converts strings with validation +- **Text:** `FormatTime()` converts seconds to `HH:MM:SS`; `Pluralise()` handles singular/plural; `TruncateText()` clips with ellipsis +- **Screen:** `WorldToScreenSafe()` projects world position to screen and returns `bIsOnScreen` (false if behind camera) +- **Debug:** All debug functions are wrapped in `#if !UE_BUILD_SHIPPING` — automatically stripped from shipping builds + +**Implementation Patterns:** +- All functions are `BlueprintCallable` or `BlueprintPure` +- Functions requiring world context take `WorldContextObject` as first parameter (UE convention for static libraries) +- Debug functions use `DO_CHECK` preprocessor — no manual removal needed + +**Integration Points:** +- **Called by:** Every Blueprint in the project (context menu → category name) +- **No outgoing calls** except to `GI_GameFramework` and `PC_CoreController` via typed cast functions + +**Edge Cases:** +- `GetSubsystemSafe()` returning null must be handled by callers — no default fallback +- `MakeTagFromString()` returns invalid tag if string isn't registered — caller must validate +- Math functions assume float inputs — NaN protection uses `FMath::IsNaN()` internally + +--- + +## 03 — I_InterfaceLibrary: All Framework Interfaces + +**What It Does:** Defines all 9 Blueprint Interfaces that form the backbone of cross-system communication. Rather than dozens of scattered interface files, all interfaces are documented in one collection. Interfaces are the **preferred communication method** — they decouple caller from callee's concrete class. + +**How It Works Internally — The 9 Interfaces:** + +| Interface | Functions | Implemented By | +|-----------|-----------|---------------| +| `I_Interactable` | `OnInteract`, `OnFocusBegin/End`, `GetInteractionPrompt`, `CanInteract`, `GetInteractionType` | Doors, pickups, devices, NPCs | +| `I_Inspectable` | `StartInspect/EndInspect`, `RotateInspect`, `GetInspectData`, `HasInspectInfo` | Items with 3D examine mode | +| `I_Damageable` | `TakeDamage`, `Heal`, `IsAlive`, `GetMaxHealth/GetCurrentHealth`, `OnDeath`, `GetDamageModifier` | Player, enemies, destructibles | +| `I_Holdable` | `OnPickup/OnDrop`, `GetHoldTransform`, `IsHeld`, `OnReleasedFromHold` | Physics objects, puzzle items | +| `I_Lockable` | `TryLock/TryUnlock`, `IsLocked`, `GetRequiredKeyTag`, `OnLockStateChanged` | Doors, containers, safes | +| `I_UsableItem` | `UseItem`, `CanUseItem`, `GetUseDuration`, `OnItemUsed` | Consumables, tools, key items | +| `I_Persistable` | `OnSave/OnLoad`, `GetSaveTag`, `NeedsSave` | Any actor that saves state | +| `I_Toggleable` | `Toggle`, `SetState`, `GetCurrentState`, `GetStateLabel`, `OnStateChanged` | Lights, switches, machines | +| `I_Adjustable` | `Adjust`, `SetValue`, `GetCurrentValue`, `GetMinValue/GetMaxValue`, `OnValueChanged` | Dials, valves, sliders | + +**Communication Pattern:** +1. Caller uses `DoesImplementInterface` or `Cast to Interface` to check +2. If interface exists, calls the interface function +3. Implementor handles the logic internally — caller never knows the concrete class +4. Interface default return values (typically `false` or `0.0f`) handle missing implementations gracefully + +**Implementation Patterns:** +- Each interface function has a single clear responsibility +- Implementors should NEVER call interface functions on themselves (use internal functions instead) +- New interfaces extend the collection; child interfaces keep base interfaces stable +- Multiple interfaces can be implemented by one actor (e.g., a door implements `I_Interactable`, `I_Toggleable`, `I_Lockable`, `I_Persistable`) + +**Edge Cases:** +- Calling an interface function on an actor that doesn't implement it returns the default value (no crash) +- `OnInteract` returning false triggers a "blocked" feedback sound — caller handles this +- `CanInteract` provides `BlockReason` text for UI — always provide a reason, not just `false` + +--- + +## 04 — GI_GameFramework: Application Kernel + +**What It Does:** The single persistent object that lives for the entire application session. It owns all `SS_` GameInstanceSubsystems, manages save slot ownership, provides the canonical service resolver (`GetSubsystem()`), and tracks the top-level game phase (MainMenu → Loading → InGame → Paused → Cutscene → DeathLoop → AltDeathSpace → Credits → PostGame). + +**How It Works Internally:** + +**State Machine — Game Phases:** +``` +MainMenu → Loading → InGame ⇄ Paused + ↓ + Cutscene + ↓ + DeathLoop → AltDeathSpace + ↓ + Credits → PostGame +``` +- `SetGamePhase(Phase)` updates `CurrentGamePhase` and broadcasts `OnGamePhaseChanged` +- Phase transitions are the single point of authority — all systems react to dispatcher, not direct checks +- `SessionFlags` (Map of GameplayTag → Boolean) stores transient flags that don't persist to disk + +**Boot Sequence (Init):** +1. Call parent `Init()` +2. `InitPlatformServices()` — routes to platform-specific stubs based on `PlatformType` (Steam/PS/Xbox/Switch/Generic) +3. All `SS_` Subsystems are auto-initialized by UE's `GameInstanceSubsystem` system +4. `SS_SettingsSystem.PopulateDefaults()` loads persistent settings +5. `SS_SaveSystem.GetSlotManifest()` checks existing saves +6. `SetGamePhase(MainMenu)` — game starts at main menu +7. Broadcast `OnPlatformReady` + +**Service Resolution:** +- `GetSubsystem(Tag)` maps a GameplayTag to a subsystem class, then calls `GetSubsystem()` +- This is the canonical entry point for any system needing a global service +- Returns null and logs warning if tag isn't mapped — caller must handle null + +**Implementation Patterns:** +- `SetActiveSlot(SlotIndex)` designates save slot without triggering load — slot is just an integer +- `bFirstLaunch` stays true until onboarding flow clears it — controls intro sequence +- `PlatformType` can be overridden via command-line: `-Platform=Steam` +- Add new subsystems to the init list — they auto-initialize via UE's native system + +**Integration Points:** +- **Owns:** All `SS_` Subsystems +- **Broadcasts:** `OnGamePhaseChanged` → `GM_CoreGameMode`, `WBP_HUDController`, `WBP_MenuFlowController` +- **Broadcasts:** `OnPlatformReady` → all platform-dependent systems +- **Called by:** Any Blueprint via `GetSubsystem()` + +**Edge Cases:** +- Calling `SetGamePhase()` with the same value should not fire dispatcher (prevents infinite loops) +- `GetSubsystem()` during `PreInit()` returns null — systems must handle early-access gracefully +- For multi-world / split-screen: this is a single-instance singleton per application session + +--- + +## 05 — GM_CoreGameMode: Session Rules & Player Spawning + +**What It Does:** Sets the rules of the game session: which pawn, controller, player state, HUD, and game state classes to use. Manages chapter transitions, win/loss/death routing, and coordinates with the narrative system for story progression. + +**How It Works Internally:** + +**Default Class Setup:** +- `DefaultPawnClass` — the GASP-based player pawn +- `DefaultControllerClass` — `PC_CoreController` +- `DefaultPlayerStateClass` — `PS_CorePlayerState` +- `DefaultGameStateClass` — `GS_CoreGameState` +- `DefaultHUDClass` — `WBP_HUDController` + +**Chapter Transition Flow:** +1. `TransitionToChapter(ChapterTag)` is called (by narrative trigger or menu) +2. Sets `CurrentChapterTag` on GM +3. Calls `GI_GameFramework.SetGamePhase(Loading)` +4. Opens/streams the level associated with `ChapterTag` +5. On level loaded: syncs chapter to `GS_CoreGameState`, fires `BPC_NarrativeSystem.OnChapterStart` +6. Calls `SetGamePhase(InGame)` + +**Death Handling Flow:** +1. `BPC_DeathHandlingSystem` dispatches player death +2. `HandlePlayerDead()` is called +3. Disables pause (`bPauseAllowed = false`) +4. Sets phase to `DeathLoop` +5. Decision: if Alt Death Space is configured → `TriggerEnding(AltDeathSpace)`, else → load checkpoint via `SS_SaveSystem`, respawn player + +**Implementation Patterns:** +- All default class references are exposed as instance-editable variables — no hardcoded classes +- `bPauseAllowed` is a runtime flag that menu widgets check before pausing (false during cutscenes/death) +- `CurrentChapterTag` is a GameplayTag — chapters are data-driven, not hardcoded strings +- `TriggerEnding(EndingTag)` passes the ending condition to `BPC_EndingAccumulator` + +**Integration Points:** +- **Owns/Spawns:** Player Controller, Player State, Game State, HUD +- **Listens to:** `BPC_DeathHandlingSystem` (death events), `BPC_NarrativeSystem` (chapter triggers) +- **Calls:** `GI_GameFramework.SetGamePhase()`, `SS_SaveSystem.LoadCheckpoint()` +- **Broadcasts:** `OnChapterTransition`, `OnGameOverTriggered` + +**Edge Cases:** +- `TransitionToChapter` during loading should be ignored (check phase before transitioning) +- `HandlePlayerDead` must be idempotent — calling it twice shouldn't double-stack death states +- For multiplayer: extend to derive from replicated GameMode base class + +--- + +## 06 — GS_CoreGameState: Shared Session State + +**What It Does:** A replicated game state singleton visible to all players. Tracks session-level data: elapsed play time, active chapter, narrative phase, encounter status, and active objectives. UI widgets and narrative systems read from here rather than querying individual systems. + +**How It Works Internally:** + +**Tracked State:** +- `ElapsedPlayTime` — accumulates in Tick only when GamePhase is `InGame` +- `ActiveChapterTag` — current story chapter (set by GM_CoreGameMode) +- `ActiveNarrativePhase` — sub-chapter phase (set by NarrativeStateSystem) +- `bEncounterActive` — whether an AI encounter is running (set by EncounterDirector) +- `ActiveObjectiveTags` — array of active objective tags (set by ObjectiveSystem) + +**State Change Pattern (all variables follow this):** +1. Setter function updates internal variable +2. Broadcasts corresponding event dispatcher +3. UI/replication `OnRep` functions mirror the broadcast for network clients + +**Dispatcher Protocol:** +- `OnElapsedPlayTimeUpdated` — fires every ~1 second tick (throttled for performance) +- `OnChapterChanged` — UI updates chapter display, narrative systems react +- `OnNarrativePhaseChanged` — sub-chapter transitions +- `OnEncounterActiveStateChanged` — HUD shows encounter status, atmosphere shifts +- `OnObjectiveTagsChanged` — `WBP_ObjectiveDisplay` refreshes + +**Implementation Patterns:** +- Intentional lightweight — a singleton data holder, not a logic processor +- All modification happens through dedicated setter functions (never direct variable write) +- Objective tags array: add/remove check for duplicates before modifying +- Time accumulation is gated by GamePhase check — stops during pause/loading/cutscenes +- For multiplayer: all variables are `Replicated Using` with `OnRep` notification + +**Integration Points:** +- **Written by:** `GM_CoreGameMode`, `BPC_ObjectiveSystem`, `BPC_EncounterDirector` +- **Read by:** `WBP_HUDController`, `WBP_ObjectiveDisplay`, `BPC_RunHistoryTracker` +- **Listens to:** `GI_GameFramework.OnGamePhaseChanged` (to gate time accumulation) + +**Edge Cases:** +- Rapid chapter changes in same tick must fire dispatcher for each — use queue if necessary +- Empty objective list removal from empty list should not crash +- Time accumulation stops correctly on phase change to Paused/Loading/Cutscene + +--- + +## 07 — DA_ItemData: Base Item Data Asset + +**What It Does:** The single source of truth for every item in the game. Each item is one `DA_ItemData` Primary Data Asset — no item data lives in Blueprint logic. This is the base class; all items inherit this template and fill in their specific values. + +**How It Works Internally:** + +**Core Properties (every item has these):** +- `ItemTag` (GameplayTag) — unique identifier, must be registered in `GI_GameTagRegistry` +- `DisplayName`, `Description` (FText) — player-facing text +- `Icon` (Texture2D soft reference) — UI icon +- `WorldMesh` (StaticMesh soft reference) — 3D mesh when dropped in world +- `Weight` (Float) — carry weight units +- `StackLimit` (Integer) — max per-slot stack count +- `ItemType` (E_ItemType) — classification: Weapon, Ammo, Consumable, KeyItem, Document, Collectible, Tool, Resource, Misc + +**Conditional Sub-Data (shown based on ItemType via EditCondition):** +- `EquipmentData` — shown when ItemType is Weapon or Tool (slot type, stats) +- `ConsumableData` — shown when ItemType is Consumable (health restore, stress reduce) +- `InspectData` — shown when `bHasInspectMode` is true (3D rotation anchors) +- `AmmoData` — shown when ItemType is Ammo (ammo type tag, per-pickup count) + +**Combination Logic:** +- `CombinesWith` — array of ItemTags this can combine with +- `CombineResult` — the ItemTag produced on successful combination +- Both fields are read by `BPC_ItemCombineSystem` to validate and execute combinations + +**Data-Driven Design:** +- This is a pure data container — no runtime functions, no tick, no events +- `ValidateItemData()` exists as an Editor-only function for content team validation +- `CustomProperties` map (Name → String) provides per-project extensibility without modifying the base class + +**Implementation Patterns:** +- Create one asset per item: name convention `DA_Item_[ShortName]` +- All `ItemTag` values must be registered in tag table before use +- `bIsKeyItem` forces `bCanBeDropped = false` — key items can't be discarded +- `StackLimit = 1` for weapons, tools, key items; larger for ammo, consumables, resources +- Assets registered with Primary Asset Manager (label: `Item`) for async loading + +**Integration Points:** +- **Read by:** `BPC_InventorySystem` (every property), `BPC_ConsumableSystem` (ConsumableData), `BPC_EquipmentSlotSystem` (EquipmentData), `BPC_AmmoResourceSystem` (AmmoData), `BPC_ItemCombineSystem` (CombinesWith/CombineResult), `BPC_InspectItemSystem` (InspectData) +- **Displayed by:** `WBP_InventoryMenu` (via InventorySystem), `WBP_InteractionPromptDisplay` (DisplayName for pickup prompt) + +**Edge Cases:** +- Two items with same ItemTag causes confusion — editor validation must enforce uniqueness +- Key items with `bCanBeDropped = true` is prevented by `ValidateItemData()` forcing it false +- Empty DisplayName/Description should be caught by validation — not crash, just warn +- Consumable items with all effect values = 0 are technically valid but useless — validation should warn + +--- + +## Initialization Order (BeginPlay Sequence) + +``` +1. GI_GameFramework.Init() ← Engine creates GameInstance +2. ├─ InitPlatformServices() +3. ├─ SS_ Subsystems init ← UE auto-initializes GameInstanceSubsystems +4. ├─ SS_SettingsSystem loads +5. └─ SetGamePhase(MainMenu) + +6. GM_CoreGameMode.InitGame() ← Engine creates GameMode when level loads +7. ├─ Sets default classes +8. ├─ Spawns GS_CoreGameState +9. └─ Spawns Player Controller + Pawn + +10. GS_CoreGameState.BeginPlay() +11. ├─ Binds to OnGamePhaseChanged +12. └─ Starts time tick + +13. DA_ItemData assets are loaded on demand ← Asset Manager async loads +14. FL_GameUtilities calls available immediately ← Static library +15. GI_GameTagRegistry.OnAssetLoaded() ← Fires when data asset loads +``` + +--- + +## Common Implementation Patterns in This Category + +1. **Tag-Driven Everything:** No booleans for state, no string comparisons. Everything is a GameplayTag compared via `HasTag()` / `MatchesTag()`. +2. **Dispatcher-Based Phase Changes:** Systems don't poll `CurrentGamePhase` — they bind to `OnGamePhaseChanged` and react. +3. **Data Assets for Content:** All item definitions, platform configs, and settings live in Data Assets, never hardcoded in Blueprints. +4. **Interface-First Communication:** Systems query for interface implementation before calling — no direct class casting. +5. **Null-Safe Subsystem Lookup:** Always use `FL_GameUtilities.GetSubsystemSafe()` — never call engine `GetSubsystem()` directly. +6. **Session Flags vs Saved Data:** `GI_GameFramework.SessionFlags` for transient state; `I_Persistable` for data that survives sessions. + +--- + +*Developer Reference v1.0 — 01 Core Foundation Systems. Companion to docs/blueprints/01-core/ specs.* diff --git a/docs/developer/02-player-systems.md b/docs/developer/02-player-systems.md new file mode 100644 index 0000000..e33b80f --- /dev/null +++ b/docs/developer/02-player-systems.md @@ -0,0 +1,456 @@ +# 02 — Player State & Embodiment Systems (Systems 08-15) + +**Category Purpose:** These 8 systems form the player character's core simulation layer — health, stamina, stress, movement, hiding, first-person body, camera, and metrics tracking. They cascade: health affects stress, stress affects movement, movement affects camera. All feed into the animation system (ABP_GASP) via event dispatchers. + +--- + +## System Index + +| # | System | Asset Type | Role | +|---|--------|-----------|------| +| 08 | `BPC_HealthSystem` | Component | Health pool, damage resistance, death trigger, healing | +| 09 | `BPC_StaminaSystem` | Component | Stamina pool, sprint/action drain, exhaustion states | +| 10 | `BPC_StressSystem` | Component | Psychological stress, tiers (Calm→Catatonic), hallucinations | +| 11 | `BPC_MovementStateSystem` | Component | Movement mode + posture tracking; GASP liaison; footsteps | +| 12 | `BPC_HidingSystem` | Component | Hide/peek/breath-hold; LOS checks; stress decay while hidden | +| 13 | `BPC_EmbodimentSystem` | Component | First-person body mesh, arm IK, visibility modes, overlays | +| 14 | `BPC_CameraStateLayer` | Component | Camera FOV/offset/rotation layers for all states; shake system | +| 15 | `BPC_PlayerMetricsTracker` | Component | Player metrics: accuracy, deaths, playstyle ratios | + +--- + +## Category Data Flow — The Cascade + +``` +┌──────────────────────────────────────────────────────────────────────┐ +│ PLAYER SIMULATION CASCADE │ +│ │ +│ Combat Damage │ +│ ↓ │ +│ BPC_HealthSystem │ +│ ↓ dispatchers: OnDamageTaken → │ +│ BPC_StressSystem ←── also fed by: enemy proximity, environment, │ +│ ↓ dispatchers: OnStressTierChanged → narrative events │ +│ BPC_CameraStateLayer (FOV pulse, chromatic aberration) │ +│ BPC_MovementStateSystem (movement penalties at high stress) │ +│ ↓ dispatchers: OnMovementModeChanged → │ +│ BPC_StaminaSystem (regen blocked while sprinting) │ +│ ABP_GASP (animation selection) │ +│ ↓ dispatchers: OnSprintStateChanged → │ +│ BPC_StaminaSystem (continuous drain during sprint) │ +│ │ +│ BPC_HidingSystem ←── interacts with both: │ +│ ↓ stress decay while hidden │ +│ ↓ camera constrained while hiding │ +│ ↓ movement disabled while inside spot │ +│ │ +│ BPC_EmbodimentSystem ←── visual overlays from damage/water │ +│ BPC_PlayerMetricsTracker ←── records everything for analytics │ +└──────────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 08 — BPC_HealthSystem: Health, Damage & Death + +**What It Does:** The central survivability component. Manages a health pool (MaxHealth → CurrentHealth), applies damage with type-based resistance calculation, handles healing, tracks death state (Alive → Dying → Dead → PermaDeath), and fires dispatchers that cascade to stress, UI, and death handling systems. + +**How It Works Internally:** + +**Damage Application Flow:** +1. `ApplyDamage(DamageEvent)` called by weapon, trap, or environment +2. Early-out checks: Is DeathState == Dead? Is bIsInvincible? → return 0 +3. Calculate resistance: look up `S_DamageResistance` for `DamageType`, multiply `BaseAmount` by `Multiplier` +4. `CurrentHealth -= EffectiveDamage` +5. Reset `RegenDelay` timer (regen starts after delay from last damage) +6. Fire `OnDamageTaken` → `BPC_StressSystem` reacts, HUD updates +7. Check thresholds: if `CurrentHealth <= 0` → `HandleDeath()`; if `CurrentHealth <= CriticalHealthPercent * MaxHealth` → fire `OnHealthCritical` +8. If DamageType is `Fear` → stress multiplier on `BPC_StressSystem` + +**Resistance System:** +- Default resistances stored as array of `S_DamageResistance` (type → multiplier) +- 7 damage types: Physical, Arcane, Fire, Poison, Fear, Environmental, True (bypasses all) +- `AddResistance()` / `RemoveResistance()` at runtime for buffs/debuffs + +**Death States:** +- `Alive` → normal; `Dying` → downed, waiting for recovery/final death; `Dead` → no actions; `PermaDeath` → save-scrubbing locked +- On death: clear all timers (regen, DoT, invincibility), fire `OnDeath`, notify `GM_CoreGameMode.HandlePlayerDead()` + +**Health Regeneration:** +- `RegenDelay` seconds after last damage before regen starts +- Timer ticks `RegenRate` HP per second until `CurrentHealth >= MaxHealth` +- Blocked by death state + +**Implementation Patterns:** +- `GetHealthNormalised()` returns 0.0-1.0 for UI bars — smooth interpolation, never raw polling +- `KillInstant()` bypasses everything for scripted deaths +- `ApplyDamageOverTime()` creates a looping timer with unique SourceName to prevent stacking +- `SetMaxHealth(NewMax, bMaintainRatio)` scales CurrentHealth proportionally or clamps +- All dispatchers fire on authority; UI binds and reacts + +**Integration Points:** +- **Listens to:** Nothing directly (called by damagers) +- **Broadcasts:** `OnHealthChanged`, `OnDamageTaken`, `OnHealthCritical`, `OnDeath`, `OnDeathStateChanged`, `OnInvincibilityChanged` +- **Key consumers:** `BPC_StressSystem` (damage → stress), `WBP_HUD` (health bar), `GM_CoreGameMode` (death), `BPC_HitReactionSystem` (stagger) + +**Edge Cases:** +- Invincibility blocks all damage for its duration (used after respawn/dodge) +- DoT with same SourceName replaces existing (no stacking) +- ApplyHealing on dead character returns 0, no dispatchers +- Negative damage treated as 0 + +--- + +## 09 — BPC_StaminaSystem: Stamina Pool & Exhaustion + +**What It Does:** Manages a stamina resource that drains during sprinting, jumping, climbing, dodging, and special attacks. Enforces minimum stamina thresholds per action, applies exhaustion penalties (Normal → Low → Exhausted), and coordinates with MovementState for regen blocking while moving. + +**How It Works Internally:** + +**Drain System:** +- Each `E_StaminaActionType` (Sprint, Jump, Climb, SpecialAttack, Dodge, Environment) has a `S_StaminaDrainRate` config: `DrainPerSecond` (continuous), `DrainFlat` (one-shot), `MinStamina` (threshold to perform), `CooldownAfterUse` +- `DrainStamina(ActionType)` checks: cooldown active? sufficient stamina? → deduct, update exhaustion, start regen delay +- `StartContinuousDrain(ActionType)` for sprint/climb — timer runs at 0.1s intervals +- `StopContinuousDrain(ActionType)` stops when action ends + +**Exhaustion States:** +- `Normal` (full operation) → `Low` (below LowThreshold, heavy breathing) → `Exhausted` (below ExhaustedThreshold, cannot sprint, slow regen) +- `UpdateExhaustionState()` checks `CurrentStamina / MaxStamina` against configured thresholds +- Transition downward is instant; recovery is gradual +- `OnExhausted` dispatcher → player controller shows feedback, sprint blocked + +**Regeneration:** +- `RegenSettings` configures: `RegenRate`, `RegenDelay`, `ExhaustedRegenRate`, `ExhaustedRegenDelay`, `RegenBlockedWhileMoving` +- If `RegenBlockedWhileMoving`: listens to `BPC_MovementStateSystem.OnMovementModeChanged`, pauses regen when speed > walk +- `BlockRegen(Duration)` for external debuffs + +**Implementation Patterns:** +- `CanAffordAction(ActionType)` checks both stamina level and cooldown before allowing +- Per-action cooldowns prevent dodge/jump spamming +- `RestoreStamina(Amount, Tags)` for potions/resting +- `SetMaxStamina(NewMax, bMaintainRatio)` scales current proportionally + +**Integration Points:** +- **Called by:** `PC_PlayerController` (sprint, jump, dodge input) +- **Broadcasts:** `OnStaminaChanged` → `WBP_HUD`, `OnExhausted` → movement/audio, `OnExhaustionStateChanged` → `ABP_GASP` (breathing anim) +- **Listens to:** `BPC_MovementStateSystem.OnMovementModeChanged` (regen blocking) +- **Key consumers:** `BPC_MovementStateSystem` (exhausted blocks sprint), `BPC_CameraStateLayer` (exhaustion effects) + +**Edge Cases:** +- Multiple continuous drains stack independently +- DrainStamina during cooldown returns false without side effects +- MaxStamina change with bMaintainRatio preserves current percentage +- All timers cleaned on component destroy + +--- + +## 10 — BPC_StressSystem: Psychological Stress & Sanity + +**What It Does:** Simulates the player's psychological state via an accumulating stress meter. Multiple stress sources contribute simultaneously (enemy proximity, environmental horror, health deficit, narrative events, supernatural, isolation). Stress tiers (Calm→Uneasy→Distressed→Panicked→Terrified→Catatonic) drive visual distortion, audio hallucinations, movement penalties, and narrative branching. + +**How It Works Internally:** + +**Multi-Source Architecture:** +- `ActiveSources` map (FName identifier → `S_StressSourceData`) tracks all contributing sources +- Each source has: `CurrentIntensity`, `MaxIntensity`, `DecayRate`, `SourceTags` +- `AddStressSource()` adds or updates a source; `RemoveStressSource()` removes it +- `RecalculateFromSources()` sums all source intensities and updates total + +**Stress Events:** +- `AddStress(Event)` can be instant (`bIsInstant`) or gradual (adds to source system) +- `HealthDeficitMultiplier` amplifies incoming stress when health < 50% — creates death spiral feel +- `OnDamageTakenHandler` converts damage amount to stress (Fear damage type gets 2x multiplier) +- `ForcePanic(Duration)` temporarily forces Panicked tier for narrative use + +**Tier System:** +- 6 tiers with configurable thresholds: `Uneasy` (subtle audio), `Distressed` (visual noise, heartbeat), `Panicked` (heavy distortion, movement penalty), `Terrified` (hallucinations, input inversion), `Catatonic` (freeze/stumble) +- `UpdateTier()` compares `CurrentStress` against threshold values +- Tier transitions fire `OnStressTierChanged` — systems react to tier, not raw stress value +- `TierEntryTimes` map records when each tier was entered for duration tracking + +**Hallucination System:** +- At `Terrified` tier: `HandleHallucinationCheck()` rolls random chance each tick +- Triggers random hallucination events (visual, audio, dialogue) +- Stops when tier drops below `Distressed` + +**Safe Zones & Recovery:** +- `SetSafeZone(bSafe)` toggles passive decay +- `PassiveDecayTick()` slowly reduces stress when in safe area or below Distressed +- `OnSafeZoneChanged` dispatcher → atmosphere system adjusts + +**Implementation Patterns:** +- Sources with identifiers enable precise tracking (e.g., "Enemy_Guard_12", "Area_Basement") +- `GetTierDuration(Tier)` for narrative systems to query how long player has been panicked +- At Catatonic, further stress accumulation is blocked (immune at max) +- All effects driven by tier dispatchers, never by polling + +**Integration Points:** +- **Called by:** Enemies (proximity), environment triggers, `BPC_HealthSystem` (damage handler) +- **Broadcasts:** `OnStressTierChanged` → `BPC_CameraStateLayer` (post-process), `ABP_GASP` (anim), `WBP_HUD` (vignette), `OnHallucinationTriggered` → hallucination/audio managers, `OnCatatonicStateEntered` → input lockdown +- **Listens to:** `BPC_HealthSystem.OnDamageTaken` + +**Edge Cases:** +- Catatonic blocks all non-instant stress additions +- Stress clamping prevents overflow past MaxStress +- Source with matching identifier updates existing entry (no duplicate sources) +- ForcePanic temporarily locks tier and restores gradually after duration + +--- + +## 11 — BPC_MovementStateSystem: Movement Mode & Posture + +**What It Does:** The "movement oracle" — tracks the player's current state (movement mode + posture), reports changes via dispatchers, and applies movement settings to the CharacterMovementComponent. Other systems query here instead of polling the movement component directly. Bridges gameplay state to GASP animation. + +**How It Works Internally:** + +**Dual State Tracking:** +- `CurrentMovementMode` (Idle, Walking, Jogging, Sprinting, CrouchWalk, Sneaking) — speed tier +- `CurrentPosture` (Standing, Crouching, Prone, Sliding, Climbing, Vaulting) — body position +- These are independent — you can be Sprinting while Standing, or CrouchWalk while Crouching +- `PreviousMovementMode` and `PreviousPosture` stored for transition detection + +**Movement Settings Application:** +- `MovementSettings` map (Mode → `S_MovementSettings`) defines: `MaxWalkSpeed`, `Acceleration`, `Deceleration`, `GroundFriction`, `bCanSprint`, `bCanCrouch`, `StaminaDrainMultiplier` +- `SetMovementMode(NewMode)` applies the corresponding settings to `CharacterMovementComponent` +- `SetPosture(NewPosture)` adjusts CapsuleComponent half-height (Standing=96, Crouch=60, Prone=30) +- Prone requires going through Crouching first (enforced) + +**Movement Penalties:** +- `ApplyMovementPenalty(Multiplier, Duration, PenaltyTag)` temporarily multiplies MaxWalkSpeed +- Timer restores original value after Duration +- Used by stress system (movement penalty at high stress), injury system, debuffs +- Each penalty tagged for tracking — multiple penalties stack multiplicatively? + +**Footstep System:** +- `CalculateFootstep()`: line trace downward from foot → get surface physical material → look up `S_FootstepProfile` matching surface and mode +- `DefaultFootstepProfile` as fallback +- Fires `OnFootstep` dispatcher with mode and surface type for audio system +- Velocity threshold determines soft vs hard footstep sound + +**GASP Integration:** +- On every mode/posture change: notify ABP_GASP via direct reference or interface +- Sets GASP-specific animation variables (bStrafing, bSprinting, gait, stance) +- This is the ONLY component that talks directly to ABP_GASP for movement state + +**Implementation Patterns:** +- Does NOT handle input — input remains in `PC_PlayerController` +- `CanTransitionToPosture(TargetPosture)` traces for ceiling clearance +- `SetSprinting(bSprinting)` wraps SetMovementMode with stamina awareness +- `OnMovementUpdated(Tick)` checks velocity, detects start/stop, tracks ground state +- `GetCurrentSpeedNormalised()` for smooth animation blend values + +**Integration Points:** +- **Called by:** `PC_PlayerController` (input → mode changes) +- **Broadcasts:** `OnMovementModeChanged`, `OnPostureChanged`, `OnMovementStart/Stop`, `OnSprintStateChanged`, `OnJumped/Landed`, `OnFootstep` +- **Key consumers:** `ABP_GASP` (animation), `BPC_StaminaSystem` (drain/regen), `BPC_CameraStateLayer` (FOV), `BP_AudioManager` (footsteps), `BPC_InteractionDetector` (range scaling) + +**Edge Cases:** +- Forced transitions (knockdown) apply impulse regardless of current state +- Cannot transition to upright if ceiling is too low (traced by CanTransitionToPosture) +- Rapid mode switching is protected by TransitionBlendTime +- Sprinting auto-stops when stamina hits 0 (external listener) + +--- + +## 12 — BPC_HidingSystem: Stealth & Concealment + +**What It Does:** Manages the player entering, occupying, peeking from, and exiting environmental hiding spots. Handles line-of-sight checks against enemies, breath-holding mechanics, and stress reduction while concealed. The central hub for all stealth gameplay. + +**How It Works Internally:** + +**Hide State Machine:** +``` +Exposed → Entering → Hidden ⇄ Peeking → Exiting → Exposed +``` +- `Entering/Exiting`: transient animation states +- `Hidden`: fully concealed, LOS blocked, stress decaying +- `Peeking`: partial exposure, camera offset, timed max duration +- Each transition broadcasts `OnHideStateChanged` + +**Hide Spot Types:** +- `Locker`: fully enclosed (wardrobe, locker) — complete concealment +- `BehindCover`: behind low wall/crate — peeking possible +- `Under`: under bed/table — prone entry +- `InShadow`: standing in shadow volume — dynamic, proximity-based +- `TallGrass`: crouch-moving through vegetation — partial concealment +- Each type stored in `S_HideSpotInfo` from the hiding spot actor + +**Entry Protocol:** +1. Player presses interact near a hide spot +2. `EnterHideSpot(HideSpotActor)` → validate I_HidingSpot interface, check slot availability +3. Set `CurrentHideState = Entering`, disable movement input +4. Play entering animation → animation notify triggers `OnAnimationHideEnterComplete` +5. Set `CurrentHideState = Hidden`, start stress decay timer, start periodic LOS check + +**Line of Sight (LOS) System:** +- `IsPlayerDetectable(EnemyLocation, DetectionRange)` called by AI perception +- If not hidden: always detectable +- If hidden: line trace from enemy to player → if trace hits hide spot actor before player: concealed +- Peeking state increases detection radius +- `PerformLOSCheck()` runs on timer: iterates all enemies in range, checks each +- If any enemy has LOS: fire `OnHideSpotCompromised` → stress spike, forced exit warning + +**Peek System:** +- `StartPeek(Direction)` — Left/Right/Over from behind cover +- Camera moves to peek socket location on hide spot actor +- `MaxPeekDuration` timer forces return to Hidden +- `PeekCooldown` prevents rapid toggling + +**Stress Interaction:** +- `StressDecayWhileHidden` applied per second while in Hidden state +- `bBlocksStress` on hide spot prevents new stress sources from affecting player +- Hide spots double as psychological safe rooms + +**Implementation Patterns:** +- `ForceKickFromHide()` for enemy discovery — bForceExit skips animation +- `TryBreathHold()` reduces noise for 8 seconds near enemies +- `OnDamageWhileHiding` handler: penetrating damage forces exit; non-penetrating converts to stress +- Destroying a hide spot while player is inside force-exits them + +**Integration Points:** +- **Called by:** `PC_PlayerController` (interact input), AI (IsPlayerDetectable queries) +- **Broadcasts:** `OnHideStateChanged`, `OnEntered/ExitedHidingSpot`, `OnPeekStarted/Ended`, `OnHideSpotCompromised`, `OnForcedExitWarning`, `OnBreathHoldChanged` +- **Key consumers:** `BPC_CameraStateLayer` (peek/hide offsets), `BPC_StressSystem` (decay), `ABP_GASP` (hide anims), `AI_EnemyController` (awareness), `WBP_HUD` (hide indicators) + +**Edge Cases:** +- EnterHideSpot while already hiding returns false +- ExitHideSpot while Exposed does nothing +- Multiple players can't occupy limited-slot spots +- Peek max duration and cooldown enforced +- Shutting down the hide spot actor force-exits the player + +--- + +## 13 — BPC_EmbodimentSystem: First-Person Body + +**What It Does:** Creates first-person body awareness — the player sees their arms, shadow, and optionally legs/torso in context-appropriate situations. Manages mesh visibility modes, environmental body overlays (blood, water, mud), wall proximity detection for arm IK, and shadow casting. + +**How It Works Internally:** + +**Visibility Modes:** +- `FullBody` (third-person, mirrors, death) → `ArmsOnly` (default first-person) → `ArmsAndShadow` → `Minimal` (only hands, high stress) → `Hidden` (cutscenes, UI) +- `SetVisibilityMode(NewMode, bInstant)` toggles mesh components: ArmsMesh, BodyShadowComponent, optional TorsoMesh +- `S_BodyPartVisibility` struct derived from mode controls individual part visibility + +**Overlay System:** +- `E_BodyOverlayState`: Clean, BloodSpatter, WaterDroplets, Mud, Toxic +- `ApplyOverlay(Overlay)` with blend: sets MaterialParameter on ArmsMesh toward `TargetValue` at `BlendSpeed` +- Auto-fades after `Duration` seconds +- `ClearOverlay(Type)` removes single or all overlays +- Multiple overlays stack: blood + water = combined effect on material +- `ApplyOverlayBlendTick()` runs each frame for smooth transitions + +**Wall Proximity / Arm IK:** +- `CheckWallProximity()`: line trace from camera forward by `BrushTraceDistance` +- If wall detected: apply IK offset to arms (avoids clipping), set `bIsNearWall = true` +- Fires `OnWallProximityChanged` → ABP_Arms for IK adjustment + +**Damage/Environment Integration:** +- `OnDamageTakenBloodHandler`: blood overlay intensity scales with damage amount +- `OnEnterWaterHandler`: water droplets overlay with fast blend, auto-dries +- Bound to `BPC_HealthSystem.OnDamageTaken` and water volume triggers + +**Implementation Patterns:** +- Mesh references cached at BeginPlay from owner (first-person skeletal mesh) +- Shadow uses separate component with shadow-only material — not full character mesh +- All overlay blending uses Material Parameter Collections for real-time updates +- Wall proximity is simple line trace; advanced IK requires arms animation blueprint + +**Integration Points:** +- **Listens to:** `BPC_HealthSystem.OnDamageTaken` (blood), water volume triggers +- **Broadcasts:** `OnVisibilityModeChanged` → `BPC_CameraStateLayer` (FOV adjust), `OnOverlayChanged` → `WBP_HUD` (screen effects), `OnWallProximityChanged` → ABP_Arms + +**Edge Cases:** +- Rapid visibility changes don't cause rendering glitches due to fade transitions +- Overlays stack: intensity values combined via material logic +- Hidden mode overrides all — hides everything regardless of other settings + +--- + +## 14 — BPC_CameraStateLayer: Dynamic Camera Controller + +**What It Does:** Centralizes all camera-modifying logic: field-of-view changes per state, camera shake system with priority queuing, post-process overrides (vignette, chromatic aberration, color grading), head bob, and location/rotation offsets per game state. Other systems request camera changes here instead of directly manipulating the camera. + +**How It Works Internally:** + +**Camera State System:** +- 10 states: Default, Aiming, Sprinting, Crouching, Peeking, Hiding, Stressed, Injured, Death, Cutscene +- Each has `S_CameraStateConfig`: TargetFOV, BlendSpeed, HeadOffset, HeadRotation, pitch constraints, head bob settings +- `RequestCameraState(NewState, bImmediate)` sets targets and starts blending +- `BlendToTargetFOV()` runs per tick: smooth interpolation to target FOV +- `BlendCameraOffset()` interpolates head position/rotation offsets + +**Camera Shake System:** +- `S_CameraShakeRequest`: ShakeClass, Scale, Priority (Low/Medium/High/Cinematic), Duration, bIsLooping, Tag +- Priority system: higher priority shakes override lower; same tag replaces existing +- `PlayCameraShake(ShakeRequest)` adds to ActiveShakeRequests map and starts playback +- If Duration > 0: timer auto-stops shake +- `StopCameraShake(ShakeTag)` removes specific shake + +**Post-Process Overrides:** +- `S_PostProcessOverride`: vignette, chromatic aberration, color grading LUT +- `ApplyPostProcessOverride(Override, bInstant)` blends Material Parameter Collection values +- `ClearPostProcessOverride(BlendTime)` returns to defaults +- Used by stress system (CA at high stress), injury (vignette), death (fade to black) + +**Dynamic Effects:** +- **Sprint:** FOV widens by SprintFOVMultiplier +- **Stress:** `UpdateStressPulse()` applies sine-wave FOV oscillation for "unease" feel +- **Crouch:** slight downward offset +- **Peek:** camera moves to hide spot peek socket +- **Hiding:** constricted FOV, darkness effect + +**Reactivity:** +- Binds to `BPC_MovementStateSystem.OnMovementModeChanged` → Sprint/Crouch/Default FOV +- Binds to `BPC_StressSystem.OnStressTierChanged` → stress effects at Panicked+ +- Binds to `BPC_HealthSystem.OnDamageTaken` → injury shake, vignette +- Called directly by `BPC_HidingSystem` for peek/hide camera states + +**Implementation Patterns:** +- Uses Material Parameter Collection (MPC_CameraEffects) for post-process parameters +- Camera shakes authored as Blueprint Camera Shake classes +- Pitch constraints enforced during hiding/peeking states +- All blending is frame-rate independent via DeltaTime + +**Integration Points:** +- **Broadcasts:** `OnCameraStateChanged`, `OnFOVChanged`, `OnShakeStarted/Ended`, `OnPostProcessChanged` +- **Called by:** Any system needing camera change +- **Key consumers:** PlayerCameraManager (direct application), `WBP_HUD` (post-process materials) + +**Edge Cases:** +- Shake with same tag and lower priority is ignored (not stacked) +- Rapid FOV switching blends smoothly — no snap transitions +- Stress pulse uses sine wave to prevent jitter +- All active shakes stopped on component destroy or pawn unpossess + +--- + +## 15 — BPC_PlayerMetricsTracker: Analytics & Playstyle + +**What It Does:** Records player behavior metrics throughout a session: accuracy (shots fired vs hit), deaths count, damage dealt/received, items used, hiding time, sprint time, objectives completed. Used by `BPC_PlaystyleClassifier` to categorize player as Aggressive/Stealthy/Explorer/Balanced, and by `BPC_DifficultyManager` for adaptive tuning. + +**How It Works Internally:** +- Listens to relevant dispatchers from HealthSystem (deaths), WeaponBase (shots/hits), InventorySystem (items used), HidingSystem (hide time), MovementState (sprint time) +- Accumulates counters and ratios internally +- Provides query functions for other adaptive systems +- Persists across sessions via `I_Persistable` for long-term playstyle tracking + +**Implementation Patterns:** +- Pure listener — never calls into other systems, only receives events +- All metrics are gameplay-tag keyed for extensibility +- Ratios computed on demand, not continuously + +--- + +## Common Implementation Patterns in This Category + +1. **Cascade Architecture:** Systems don't poll each other — they bind to dispatchers. Health change → stress reaction → camera effect → movement penalty. Each system reacts independently. +2. **Normalized Values for UI:** `GetHealthNormalised()`, `GetStaminaNormalised()`, `GetStressNormalised()` all return 0.0-1.0 — UI widgets interpolate smoothly. +3. **Timer-Based Ticks:** Regen, drain, stress decay all use 0.1s interval timers — not event tick. Better performance. +4. **State Not Polling:** Camera doesn't ask "am I sprinting?" — it binds to `OnMovementModeChanged` and reacts. +5. **Threshold Not Continuous:** Stress/hiding systems use tier/state thresholds — other systems react to tier changes, not raw values. +6. **Data Config Everything:** Damage resistances, movement speeds, stamina drain rates, stress thresholds — all in exposed variables or Data Assets, never hardcoded. + +--- + +*Developer Reference v1.0 — 02 Player Systems. Companion to docs/blueprints/02-player/ specs.* diff --git a/docs/developer/03-interaction-systems.md b/docs/developer/03-interaction-systems.md new file mode 100644 index 0000000..8de802b --- /dev/null +++ b/docs/developer/03-interaction-systems.md @@ -0,0 +1,244 @@ +# 03 — Interaction & World Manipulation Systems (Systems 16-23) + +**Category Purpose:** These 8 systems handle everything the player can do with the world — detecting interactable objects, opening doors, solving puzzles, traversing obstacles, dragging physics objects, using world devices (levers, buttons), viewing diegetic displays, and finding hiding spots. The `BPC_InteractionDetector` is the central hub; all other systems respond to its dispatchers or interface calls. + +--- + +## System Index + +| # | System | Asset Type | Role | +|---|--------|-----------|------| +| 16 | `BPC_InteractionDetector` | Component | Raycast interaction detection hub; holds/press/double-tap | +| 17 | `I_HidingSpot` | Interface | Interface for hideable world objects | +| 18 | `BPC_DiegeticDisplay` | Component | In-world screens (wristwatch, monitors, holograms) | +| 19 | `BP_DoorActor` | Actor | Physical door: 6-state machine, lock/barricade/key | +| 20 | `BP_PuzzleDeviceActor` | Actor | Puzzle device base: state machine, solution checking | +| 21 | `BPC_ContextualTraversalSystem` | Component | Vault/mantle/slide/squeeze via Motion Warping | +| 22 | `BPC_PhysicsDragSystem` | Component | Grab/drag/release physics objects | +| 23 | `BPC_UsableWorldObjectSystem` | Component | Generic world objects: levers, valves, buttons, panels | + +--- + +## Category Data Flow + +``` +┌────────────────────────────────────────────────────────────────────┐ +│ INTERACTION FLOW │ +│ │ +│ BPC_InteractionDetector (runs on player) │ +│ │ Timer-based sphere trace every 0.1s │ +│ │ Filters by: I_Interactable interface │ +│ │ Sorts by: Priority (Emergency > High > Normal > Low) │ +│ │ then Distance (closest wins) │ +│ ├─► OnTargetFound → WBP_InteractionPromptDisplay (show prompt) │ +│ │ │ +│ │ On player input: │ +│ ├─► Press: immediate interaction │ +│ ├─► Hold: radial progress fill → interaction on complete │ +│ └─► DoubleTap: two rapid presses │ +│ │ +│ Target types are routed: │ +│ ├─► BP_DoorActor.Interact_Implementation → door logic │ +│ ├─► BP_PuzzleDeviceActor.Interact_Implementation → puzzle │ +│ ├─► BP_ItemPickup.Interact_Implementation → inventory add │ +│ ├─► BP_ContainerInventory.Interact_Implementation → container │ +│ ├─► BP_UsableWorldObject.Interact_Implementation → lever/etc. │ +│ └─► I_HidingSpot → BPC_HidingSystem.EnterHideSpot() │ +│ │ +│ Independent systems (not through InteractionDetector): │ +│ ├─► BPC_ContextualTraversalSystem (movement-based, auto-detect) │ +│ └─► BPC_PhysicsDragSystem (grab input, physics constraint) │ +└────────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 16 — BPC_InteractionDetector: The Interaction Hub + +**What It Does:** The player's "interaction eye" — performs continuous sphere traces forward from the camera, detects all `I_Interactable` actors within range, sorts them by priority and distance, selects the best target, and manages the interaction prompt UI. Every interactive object in the game funnels through this component. + +**How It Works Internally:** + +**Detection Loop:** +- Timer fires every `ScanInterval` (default 0.1s) +- Sphere trace forward: `InteractionRange` (default 250cm), `DetectionAngle` cone, `TraceRadius` sphere +- Each hit actor checked for `I_Interactable` implementation +- Duplicates removed, sorted by `Priority` descending then `Distance` ascending +- Clamped to `MaxTargetsInRange` (default 16) +- `DetectionState` tracks: NoTarget → TargetInRange → TargetConfirmed → Interacting + +**Input Modes:** +- `Press`: Single press to interact (standard) +- `Hold`: Hold button for `HoldDuration` seconds with progress bar +- `DoubleTap`: Two rapid presses within threshold +- `Auto`: Triggers on proximity without input + +**Interaction Protocol:** +1. Player presses interact → `OnInputInteractPressed` +2. If `DetectionState >= TargetConfirmed` and input mode matches: + - Press mode: calls `PerformInteraction(Press)` immediately + - Hold mode: starts hold timer, fires `OnHoldProgressUpdated` each tick (for radial UI fill) + - DoubleTap mode: waits for second press within window +3. `PerformInteraction` sets `bIsPerformingInteraction = true`, calls `CurrentTarget.InterfaceRef.ExecuteInteraction(Instigator)` +4. Waits for interaction completion or timeout +5. On completion/cancel: resumes scanning + +**Blocking Conditions:** +- During death (`bBlockDuringDeath`): interaction blocked +- While hidden (`bBlockDuringHiding`): blocked (player is inside a locker) +- During combat (`bBlockDuringCombat`): optionally blocked +- While already interacting (`bIsPerformingInteraction`): blocked (no double-interact) + +**Target Scoring:** +- `CalculateInteractionScore()`: `Score = Priority * 100 - Distance * 0.5` +- Facing bonus: if camera angle to target < 15°, add 50 +- Best target = highest score within range + +**Implementation Patterns:** +- Trace pauses while interacting, resumes after completion +- `ForceSetTarget(Actor)` for scripted interactions (cutscene buttons) +- Highlight effect applied to current target via `I_Interactable.SetHighlighted()` +- Enter/exit tracking: fires `OnTargetEntered`/`OnTargetExited` when actors enter/leave range + +**Integration Points:** +- **Broadcasts:** `OnTargetFound/Lost`, `OnInteractionStarted/Completed/Cancelled/Error`, `OnHoldProgressUpdated` +- **Calls:** `I_Interactable.ExecuteInteraction()` on target, `I_Interactable.SetHighlighted()` +- **Listens to:** `BPC_MovementStateSystem.OnPostureChanged`, `BPC_HealthSystem.OnDeathStateChanged` + +--- + +## 17 — I_HidingSpot: Hiding Spot Interface + +**What It Does:** Interface that all hideable world objects must implement. Provides slot management, entry/exit transforms, peek capability, and type classification. + +**Key Functions:** +- `GetHideSpotInfo()` → returns `S_HideSpotInfo` (type, slots, peek sockets, exit location, tags) +- `HasAvailableSlots()` → boolean for occupancy check +- `OnPlayerEntered(Player)` / `OnPlayerExited(Player)` → notify on occupancy change +- `GetEntryAnimation()` / `GetExitAnimation()` → animation montages for smooth transitions +- `IsDetectableFrom(EnemyLocation)` → LOS check helper + +**Implementation:** Actors like lockers, wardrobes, beds, tall grass volumes, and shadow volumes implement this interface. The `BPC_HidingSystem` calls these functions to manage hide state. + +--- + +## 18 — BPC_DiegeticDisplay: In-World Screens + +**What It Does:** Manages in-world display surfaces — the player's wristwatch UI, computer monitors, holographic projectors, and security camera feeds. These are diegetic (exist in the game world) rather than screen-space UI. + +**Key Features:** +- Renders widget blueprints onto world-space surfaces via `WidgetComponent` +- Supports multiple display types: wristwatch, monitor, hologram, projection +- Screen power states: on/off/damaged/static +- Distortion effects for damaged screens +- Interaction-based activation (press E on monitor to view) + +--- + +## 19 — BP_DoorActor: Physical Door System + +**What It Does:** Powers all door-like actors — hinged doors, sliding doors, double doors, roll-up doors, and trap doors. Manages a 6-state machine with lock/key mechanics, barricade health, one-way passage, auto-close, and puzzle-linked unlocking. + +**State Machine:** +``` +Closed → Opening → Open → Closing → Closed + ↑ ↓ +Locked ← (unlock transitions to Closed) + ↑ +Barricaded → (break) → Closed +``` + +**Lock Types:** Unlocked, KeyRequired (specific key item), ItemRequired (crowbar/code), PuzzleLinked (external puzzle), Breachable (force/weapon) + +**Animation System:** +- Uses Timeline to interpolate door rotation (hinged) or translation (sliding) from 0→OpenAngle +- `OpenSpeed` and `CloseSpeed` control animation rate +- `AutoCloseDelay` starts timer after open; resets on re-open +- `LinkedActors` array notified on open/close (lights, alarms, traps) + +**Implementation Patterns:** +- Implements `I_Interactable` — called by InteractionDetector +- `TryUnlockWithItem()` queries `BPC_InventorySystem` for required key +- `DamageBarricade()` reduces health, broadcasts `OnBarricadeBroken` at 0 +- `ForceSetState()` for save/load restoration — bypasses animation +- One-way doors track which side was opened from (`bIsOpenFromFront`) + +**Integration Points:** +- **Called by:** `BPC_InteractionDetector` (interact) +- **Queries:** `BPC_InventorySystem` (key check) +- **Notifies:** `LinkedActors`, AI perception (pathfinding update), AudioManager (door sounds), Save System + +--- + +## 20 — BP_PuzzleDeviceActor: Puzzle Device Base + +**What It Does:** Base class for puzzle devices — combination locks, pressure plate sequences, symbol matching, pipe routing, and any interactive puzzle. Manages a state machine, validates solutions, and provides hints and rewards. + +**Features:** +- State machine: Idle → Active → Solved → Failed +- Solution checking against `DA_PuzzleData` Data Asset +- Hint system with configurable hint count and cooldown +- Reward dispatching on solve (item grant, door unlock, narrative flag set) +- Linked actor notifications (unlock connected door, activate machine) +- Timer-based puzzles with configurable countdown + +--- + +## 21 — BPC_ContextualTraversalSystem: Vaulting & Climbing + +**What It Does:** Handles player traversal of environmental obstacles using UE5 Motion Warping. Detects traversable surfaces (low walls, ledges, gaps, barriers) and plays root motion traversal montages with precise target alignment. + +**Traversal Types:** Vault (low obstacles), Mantle (ledges), Slide (under barriers), Squeeze (narrow gaps), LedgeGrab (hang from ledges) + +**Detection:** +- Forward capsule trace at waist, chest, and head heights +- Classifies obstacles by height: Low (step up), Medium (vault), High (mantle) +- Cooldown between traversals prevents animation spam + +**Motion Warping:** +- Calculates exact target location for landing +- Warps root motion to hit target precisely +- `bIsTraversing` flag blocks input and other actions during animation + +--- + +## 22 — BPC_PhysicsDragSystem: Object Grabbing + +**What It Does:** Enables the player to grab, drag, and release physics-simulated objects. Uses physics constraints for smooth dragging and supports throw mechanics. + +**Features:** +- Grab detection via line trace from camera +- Physics constraint attaches object to player's "hold position" +- Rotation control while held (mouse wheel or gamepad) +- Throw with configurable force on release +- Weight limit: heavier objects require more time to lift +- Works with `I_Holdable` interface for puzzle-specific objects + +--- + +## 23 — BPC_UsableWorldObjectSystem: Generic World Devices + +**What It Does:** Provides a generic interaction system for world objects that don't fit into door/puzzle/pickup categories — levers, valves, buttons, switches, panels, dials, and crank handles. + +**Features:** +- Implements `I_Interactable`, `I_Toggleable`, and `I_Adjustable` interfaces +- Binary devices (levers, buttons): toggle on/off +- Analog devices (valves, dials): continuous adjustment via mouse wheel or hold-and-drag +- Linked actor notifications: pulling a lever opens a gate elsewhere +- Animation playback with configurable duration +- State persistence via `I_Persistable` + +--- + +## Common Implementation Patterns in This Category + +1. **Interface-Driven Detection:** `BPC_InteractionDetector` doesn't know about doors, pickups, or puzzles — it only checks for `I_Interactable`. Any new interactable just implements the interface. +2. **Priority Sorting:** Emergency targets (hide spots in combat) always selected over Low priority (ambient items). +3. **State Machines on Actors:** Doors, puzzles, and devices all use discrete state machines exposed via dispatchers — never polling. +4. **Linked Actor Pattern:** Doors/puzzles/devices can notify other actors (lights, traps, doors) on state change via `LinkedActors` array. +5. **Input Mode Variety:** Press for quick actions, Hold for deliberate actions (pick lock, solve puzzle), DoubleTap for rapid actions. +6. **Save-Aware:** All interactive objects implement `I_Persistable` for state restoration. + +--- + +*Developer Reference v1.0 — 03 Interaction Systems. Companion to docs/blueprints/03-interaction/ specs.* diff --git a/docs/developer/04-inventory-systems.md b/docs/developer/04-inventory-systems.md new file mode 100644 index 0000000..00f13f6 --- /dev/null +++ b/docs/developer/04-inventory-systems.md @@ -0,0 +1,243 @@ +# 04 — Inventory, Items & Collectibles Systems (Systems 24-34) + +**Category Purpose:** These 11 systems form the complete inventory management layer — core item storage grid, world containers, item pickups, consumable usage, equipment slots, item combination/crafting, key item tracking, document archiving, quick slots, journal tracking, and collectible progression. The `BPC_InventorySystem` is the single source of truth for all item data; every other inventory subsystem reads from and writes through it. + +--- + +## System Index + +| # | System | Asset Type | Role | +|---|--------|-----------|------| +| 24 | `BPC_ContainerInventory` | Component | World container inventory (chests, drawers, safes) | +| 25 | `BP_ItemPickup` | Actor | Physical item pickup in world with bob/rotate effects | +| 26 | `BPC_ActiveItemSystem` | Component | Quick-slot item management; contextual item use | +| 27 | `BPC_CollectibleTracker` | Component | Collectible tracking, found count, set bonuses | +| 28 | `BPC_ConsumableSystem` | Component | Consumable use (health packs, syringes, buffs) | +| 29 | `BPC_DocumentArchiveSystem` | Component | Document/journal archive; read, categorize, flag | +| 30 | `BPC_EquipmentSlotSystem` | Component | Equipment slots (weapon, armor, tool); equip/unequip | +| 31 | `BPC_InventorySystem` | Component | **Core inventory grid** — add/remove/sort/stack/weight | +| 32 | `BPC_ItemCombineSystem` | Component | Item combination crafting; recipe validation | +| 33 | `BPC_JournalSystem` | Component | Quest/objective journal; active, completed, failed | +| 34 | `BPC_KeyItemSystem` | Component | Key item tracking; use-on-target, consumed-on-use | + +--- + +## Category Data Flow + +``` +┌──────────────────────────────────────────────────────────────────────┐ +│ INVENTORY ECOSYSTEM │ +│ │ +│ BPC_InventorySystem (CENTRAL AUTHORITY) │ +│ │ Array of S_InventorySlot → each holds S_InventoryEntry │ +│ │ Operations: AddItem, RemoveItem, UseItem, DropItem, │ +│ │ TransferItem, MoveItem, SplitStack, SortInventory │ +│ │ │ +│ ├─► OnInventoryChanged → ALL other inventory systems react │ +│ │ │ +│ ├─► BPC_ActiveItemSystem (quick slots) │ +│ │ └─► Routes equip/use to EquipmentSlotSystem or Consumable │ +│ │ │ +│ ├─► BPC_EquipmentSlotSystem (equip/unequip) │ +│ │ └─► Validates slot type, notifies BP_WeaponBase │ +│ │ │ +│ ├─► BPC_ConsumableSystem (use health/stamina/stress items) │ +│ │ └─► Calls BPC_HealthSystem.ApplyHealing() etc. │ +│ │ │ +│ ├─► BPC_ItemCombineSystem (crafting) │ +│ │ └─► Reads DA_ItemData.CombinesWith/CombineResult │ +│ │ │ +│ ├─► BPC_KeyItemSystem (key item use-on-target) │ +│ │ └─► Checks I_Lockable on target, consumes key if matching │ +│ │ │ +│ ├─► BPC_DocumentArchiveSystem (reading documents) │ +│ ├─► BPC_JournalSystem (quest tracking) │ +│ ├─► BPC_CollectibleTracker (completion tracking) │ +│ │ │ +│ External interactions: │ +│ BP_ItemPickup ←── player picks up → BPC_InventorySystem.AddItem │ +│ BPC_ContainerInventory ←── looting → transfer between inventories │ +│ BPC_InventorySystem.DropItem → spawns BP_ItemPickup in world │ +└──────────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 31 — BPC_InventorySystem: Core Inventory Grid + +**What It Does:** The central inventory authority on the player. Stores all items as an array of `S_InventorySlot` structs, each potentially containing an `S_InventoryEntry` with a reference to `DA_ItemData` plus runtime state (stack count, durability, custom metadata). All other inventory subsystems read from this component as their single source of truth. + +**How It Works Internally:** + +**Core Data Structures:** +- `S_InventorySlot`: SlotIndex, Entry (S_InventoryEntry), bIsLocked, bIsQuickSlot, CategoryRestriction +- `S_InventoryEntry`: ItemData (DA_ItemData*), ItemID (FGuid unique), StackCount, MaxStackSize, Durability, CustomTags, CustomData, SlotIndex, bIsEquipped +- Slots array is the authoritative item list + +**Operation Validation (every add/remove is validated):** +- `ValidateAddItem`: checks free slots, weight capacity (`TotalWeight + new weight <= MaxWeightCapacity`), category restrictions +- `ValidateRemoveItem`: checks item exists, sufficient quantity +- Returns `E_InventoryOperationResult`: Success, InventoryFull, ItemNotFound, StackLimitReached, InsufficientQuantity, ItemNotUsable, CategoryRestricted, WeightCapacityExceeded + +**Add Item Flow:** +1. `FindExistingStack()` — same ItemData, below MaxStackSize → increment stack +2. If overflow: `FindFreeSlot()` for remainder +3. If no existing stack: `FindFreeSlot()`, create new `S_InventoryEntry` +4. `RecalculateWeight()`, fire `OnItemAdded` + `OnInventoryChanged` + +**Remove Item Flow:** +1. Decrement stack count by Quantity +2. If stack <= 0: `ClearSlot()` +3. `RecalculateWeight()`, fire `OnItemRemoved` + `OnInventoryChanged` + +**Use Item Flow:** +1. Check cooldown (per-item cooldown map) +2. Check `bIsUsable` from DA_ItemData +3. Fire `OnItemUsed` → consumer systems react (health pack → heal, etc.) +4. If consumable: reduce stack, clear slot if 0 + +**Drop Item Flow:** +1. Remove item from inventory +2. Spawn `BP_ItemPickup` at world location with correct ItemData and StackCount +3. Fire `OnItemDropped` + +**Transfer Item Flow (between inventories):** +1. Validate source has item, target has space +2. Remove from source, add to target +3. Fire `OnItemTransferred` + +**Sort Modes:** ByName, ByCategory, ByRarity, ByWeight, ByQuantity, ByRecent + +**Weight System:** +- `RecalculateWeight()` iterates all slots, sums `ItemData.Weight * StackCount` +- `bIsOverEncumbered = TotalWeight > MaxWeightCapacity` +- `OnOverEncumberedStateChanged` fires on threshold crossing + +**Replication:** Slots array replicated with `RepNotify` → `OnRep_Slots` refreshes UI and recalculates weight + +**Implementation Patterns:** +- Stack split: creates new slot from partial stack +- Stack combine: merges two same-item slots into one (capped at MaxStackSize) +- `HasItemQuantity(Tag)` returns total count matching a tag across all slots +- `FindAllItemsByCategory/Tag` for filtered queries +- Cooldowns managed locally (not replicated), validated server-side + +**Integration Points:** +- **Broadcasts:** `OnInventoryChanged`, `OnItemAdded/Removed/Used/Dropped/Transferred`, `OnOverEncumberedStateChanged`, `OnInventoryFull` +- **Read by:** Every other inventory subsystem, `WBP_InventoryMenu`, `BPC_InteractionDetector` (pickup routing), Save System + +--- + +## 24 — BPC_ContainerInventory: World Container Storage + +**What It Does:** Provides inventory storage for world actors (crates, cabinets, corpses, safes). Uses the same `S_InventorySlot` structs as `BPC_InventorySystem` but operates standalone — interacted with via `BPC_InteractionDetector`, transfers items to/from the player's inventory. + +**Fill Methods:** +- `Fixed`: designer-defined contents via Data Asset +- `LootTable`: randomly generated from weighted loot table +- `Empty`: starts empty, filled by designer or player +- `PlayerStored`: safe storage that persists + +**Key Features:** +- Lock states: Unlocked, Locked, Jammed, KeyRequired, PuzzleRequired +- Loot rarity tiers: Trash, Common, Uncommon, Rare, Legendary +- `GenerateLoot()`: rolls weighted random selection, respects rarity filters +- Respawn timer: refills after `RespawnTimeHours` +- Decay timer: clears items after `DecayTimeHours` +- Implements `I_Interactable` and `I_Persistable` + +**Interaction Flow:** +1. Player interacts → `OpenContainer()`, validates distance/lock/alive +2. UI opens showing container slots +3. Player clicks: `RemoveItemFromContainer()` transfers to player inventory +4. Player places: `AddItemToContainer()` transfers from player inventory +5. `CloseContainer()` → if empty, mark `bIsLooted`, start respawn/decay timers + +--- + +## 25 — BP_ItemPickup: World Item Pickup Actor + +**What It Does:** A world-placed or runtime-spawned actor representing an item to pick up. Implements `I_Interactable` and optionally `I_Persistable`. Handles visual effects (bobbing, rotating), pickup animation, inventory transfer, and respawn. + +**Visual States:** Idle (floating/rotating) → Highlighted (within range, glowing outline) → BeingPickedUp (pickup animation) → Respawning (hidden during cooldown) + +**Spawn Reasons:** PlacedInLevel, DroppedFromInventory, LootDrop, QuestReward + +**Pickup Flow:** +1. Player overlaps interaction sphere → highlight, show prompt widget +2. Player leaves → unhighlight, hide prompt +3. Player interacts → validate availability + inventory space +4. Call `BPC_InventorySystem.AddItem(ItemData, Quantity)` +5. Play pickup sound + particle +6. If succeeded: broadcast `OnPickupCollected` +7. If infinite: don't destroy; if respawns: start timer; else: destroy + +**Drop from Inventory:** +- Called by `BPC_InventorySystem.DropItem` +- Sets transform, optionally applies physics velocity +- Configures respawn behavior + +--- + +## 28 — BPC_ConsumableSystem: Consumable Usage + +**What It Does:** Handles consumable item usage — health packs, stamina boosters, temporary buffs. Reads from `BPC_InventorySystem` when `OnItemUsed` fires for consumable items, applies effects through relevant player systems. + +**Key Features:** +- Global cooldown between consumable uses +- `ActiveBuffs` array tracks temporary buffs with durations +- `TickBuffs()` decrements durations, removes expired, fires `OnBuffExpired` +- Buff types affect: Health, Stamina, Speed, Stress, Damage +- All effects data-driven via `DA_ItemData.ConsumableData` + +**Integration:** Calls `BPC_HealthSystem.ApplyHealing()`, `BPC_StaminaSystem.RestoreStamina()`, `BPC_StressSystem.RemoveStress()` based on item data. + +--- + +## 30 — BPC_EquipmentSlotSystem: Equipment Slots + +**What It Does:** Manages equipment slots (primary weapon, secondary weapon, flashlight, shield, armor, tool). Validates equip/unequip operations against slot type restrictions and coordinates with `BP_WeaponBase` for visual attachment. + +**Key Features:** +- Slot types mapped to body sockets (equip socket, holster socket) +- Validation: slot type must match item's EquipmentData.SlotType +- Unequip returns item to inventory; equip removes from inventory slot +- `bIsEquipped` flag on inventory entry tracked +- Notifies animation system for equip/holster montages + +--- + +## 32 — BPC_ItemCombineSystem: Item Crafting + +**What It Does:** Handles item combination/crafting. Two items can be combined if one's `CombinesWith` array contains the other's ItemTag, producing the item specified in `CombineResult`. + +**Flow:** +1. Player selects two items in inventory UI +2. System checks: does ItemA.CombinesWith contain ItemB.ItemTag? (or vice versa) +3. If valid: remove both source items, add CombineResult item +4. Fire `OnItemsCombined` dispatcher + +--- + +## 26, 27, 29, 33, 34 — Supporting Subsystems + +- **26 BPC_ActiveItemSystem:** Quick-slot hotbar mapping. Manages which items are on quick slots (1-4), routes quick-use to correct system (equip weapon, use consumable). +- **27 BPC_CollectibleTracker:** Tracks found collectibles, fires dispatchers on set completion, unlocks rewards at milestones. +- **29 BPC_DocumentArchiveSystem:** Stores read documents, categorizes them, allows flagging as important, supports re-reading. +- **33 BPC_JournalSystem:** Quest/objective journal separate from inventory. Tracks active, completed, and failed objectives independently. +- **34 BPC_KeyItemSystem:** Key items that can be used on locked targets. Checks `I_Lockable` on target, consumes key if matching `RequiredKeyTag`. + +--- + +## Common Implementation Patterns in This Category + +1. **Central Authority Pattern:** `BPC_InventorySystem` is the single source of truth. All additions, removals, and modifications go through it. Subsystems read and react to its dispatchers. +2. **Data-Driven Items:** All item properties live in `DA_ItemData` Data Assets. Changing an item's behavior never requires Blueprint edits. +3. **Stack Management:** Duplicate items automatically stack to `MaxStackSize`; overflow creates new slots. +4. **Validation Before Action:** Every operation validates capacity, weight, stack limits, and category restrictions before executing. +5. **Dispatcher Cascade:** `OnInventoryChanged` fires on any modification → UI updates, weight recalculates, metrics log, save system marks dirty. +6. **Weight as Soft Limit:** Over-encumbered is a state flag, not a hard block — systems can choose to penalize movement or block sprinting. + +--- + +*Developer Reference v1.0 — 04 Inventory Systems. Companion to docs/blueprints/04-inventory/ specs.* diff --git a/docs/developer/05-saveload-systems.md b/docs/developer/05-saveload-systems.md new file mode 100644 index 0000000..68aa3e8 --- /dev/null +++ b/docs/developer/05-saveload-systems.md @@ -0,0 +1,186 @@ +# 05 — Save/Load, Persistence & Death Loop Systems (Systems 35-43) + +**Category Purpose:** These 9 systems handle everything related to game state persistence — saving and loading player progress, checkpoint management, the death/respawn loop, the alternate death space (void/purgatory mechanic), persistent corpses, world state recording, run history tracking, and the `I_Persistable` interface contract that all saveable actors implement. + +--- + +## System Index + +| # | System | Asset Type | Role | +|---|--------|-----------|------| +| 35 | `SS_SaveManager` | Subsystem | Save/load subsystem; slot management, serializer, manifest | +| 36 | `I_Persistable` | Interface | Persistence contract for any actor that saves state | +| 37 | `BP_Checkpoint` | Actor | Checkpoint actor; respawn point, activation, save-on-touch | +| 38 | `BPC_AltDeathSpaceSystem` | Component | Alternate death/void space; enter, explore, find exit | +| 39 | `BPC_DeathHandlingSystem` | Component | Death orchestrator; outcome determination, animation, respawn | +| 40 | `BPC_PersistentCorpseSystem` | Component | Corpse persistence across death/respawn/level transitions | +| 41 | `BPC_PersistentWorldStateRecorder` | Component | Records world state changes (doors, items, enemies) for save | +| 42 | `BPC_PlayerRespawnSystem` | Component | Respawn logic; checkpoint resolution, state restoration | +| 43 | `BPC_RunHistoryTracker` | Component | Run/session history; death count, time, checkpoint progression | + +--- + +## Category Data Flow — The Death Loop + +``` +┌──────────────────────────────────────────────────────────────────┐ +│ DEATH & PERSISTENCE │ +│ │ +│ BPC_HealthSystem.OnDeath │ +│ ↓ │ +│ BPC_DeathHandlingSystem (death orchestrator) │ +│ │ Determines outcome: Alt Death Space? Normal Respawn? │ +│ ├─► Alt Death Space: │ +│ │ BPC_AltDeathSpaceSystem.Enter() │ +│ │ Player explores void/purgatory │ +│ │ Find exit → RestorePreviousState() │ +│ │ │ +│ └─► Normal Respawn: │ +│ GM_CoreGameMode.HandlePlayerDead() │ +│ SS_SaveManager.LoadCheckpoint() │ +│ BPC_PlayerRespawnSystem.Respawn() │ +│ │ +│ SS_SaveManager (persistence subsystem) │ +│ │ Manages save slots, serialization, manifest │ +│ ├─► OnSave: iterates all I_Persistable actors │ +│ ├─► OnLoad: restores actor states from save file │ +│ │ │ +│ │ Coordinates with: │ +│ ├─► BPC_PersistentWorldStateRecorder (world changes) │ +│ ├─► BPC_PersistentCorpseSystem (corpse data) │ +│ └─► BP_Checkpoint (save-on-touch activation) │ +│ │ +│ BPC_RunHistoryTracker (session stats) │ +│ │ Tracks: death count, play time, checkpoint progression │ +│ └─► Persists across sessions for meta-progression │ +└──────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 35 — SS_SaveManager: Save/Load Subsystem + +**What It Does:** The central save/load authority as a GameInstanceSubsystem. Manages save slots (create, load, delete, list), handles serialization of all `I_Persistable` actors, maintains a save slot manifest, and coordinates with platform save services. + +**How It Works Internally:** + +**Save Protocol:** +1. Save triggered (manual, auto-save, checkpoint) +2. Iterates all actors implementing `I_Persistable` in the world +3. Each actor returns its state via `OnSave()` as a GameplayTagContainer +4. Serializes all actor states + global data (chapter, play time, objectives) to save file +5. Updates slot manifest with timestamp, screenshot, play time + +**Load Protocol:** +1. Load slot selected +2. Deserializes save file +3. Loads correct level/chapter +4. Iterates `I_Persistable` actors, calls `OnLoad(SaveData)` on each +5. Restores global state (chapter, objectives, inventory) +6. Player placed at appropriate spawn point + +**Slot Management:** +- Multiple save slots with metadata (timestamp, play time, chapter name, thumbnail) +- Auto-save slot separate from manual slots +- Slot manifest tracks all available saves + +--- + +## 36 — I_Persistable: Persistence Interface + +**What It Does:** The contract that any actor must implement to be saveable. The save system scans the world for `I_Persistable` implementors and calls these functions. + +**Key Functions:** +- `OnSave()` → returns actor state as GameplayTagContainer for serialization +- `OnLoad(SaveData)` → restores actor state from saved data +- `GetSaveTag()` → returns unique GameplayTag identifying this actor for lookup +- `NeedsSave()` → whether this actor has unsaved changes + +**Implementation:** Doors (save locked/open state), chests (looted/not), enemies (alive/dead/position), items (collected/not), narrative triggers (fired/not), checkpoints (active/not). + +--- + +## 37 — BP_Checkpoint: Checkpoint Actor + +**What It Does:** A world-placed actor that serves as a respawn point. On player touch or interaction, becomes the active checkpoint. Triggers auto-save. Overrides previous checkpoint. + +**Features:** +- Activates on overlap or interaction +- Stores checkpoint transform (player respawn location/rotation) +- Triggers `SS_SaveManager.AutoSave()` on activation +- Visual states: inactive (dim), active (glowing), previous (faded) +- One checkpoint active at a time +- Save-on-touch: automatic save reduces lost progress + +--- + +## 38 — BPC_AltDeathSpaceSystem: Alternate Death Space + +**What It Does:** Implements the "void space" or "purgatory" mechanic — when the player dies in specific circumstances, instead of a standard respawn, they enter an alternate death dimension. They must explore this space, find an exit, and return to the main world. + +**State Machine:** +1. `Enter()` — player dies, teleports to death space level +2. Player explores void environment (puzzle, narrative, combat) +3. `FindExit()` — player discovers exit point +4. `Exit()` — teleports back to main world at respawn point +5. Fires `RestorePreviousState()` — pops back from force stack + +**Features:** +- Separate level or sub-level for death space +- Unique atmosphere, enemies, and narrative content +- Exit conditions configurable (time, puzzle solve, item find) +- Multiple death space variants possible +- Coordinates with `BPC_DeathHandlingSystem` for entry conditions + +--- + +## 39 — BPC_DeathHandlingSystem: Death Orchestrator + +**What It Does:** Listens for `BPC_HealthSystem.OnDeath` and determines what happens next. The central death logic router — decides between alt death space, checkpoint respawn, permadeath, or game over. + +**Flow:** +1. Binds to `OnDeath` dispatcher +2. Determines death context: enemy killed? environmental? scripted? +3. Checks `BPC_DeathCauseTracker` for specific death cause +4. Evaluates conditions: + - Should alt death space trigger? (configurable chance / specific enemies) + - Is this permadeath mode? → wipe save + - Normal death? → checkpoint respawn +5. Routes to appropriate system: `BPC_AltDeathSpaceSystem.Enter()` or `GM_CoreGameMode.HandlePlayerDead()` +6. Plays death animation, screen effects +7. Logs death to `BPC_RunHistoryTracker` + +--- + +## 40 — BPC_PersistentCorpseSystem: Corpse Persistence + +**What It Does:** When the player dies, their previous body becomes a persistent corpse in the world. On respawn, the old body remains as a lootable container with the player's previous inventory. Corpses persist across deaths and level transitions. + +**Features:** +- Spawns corpse actor at death location with player's appearance +- Contains `BPC_ContainerInventory` with player's previous items +- Corpse persists across respawns (doesn't disappear) +- Configurable corpse limit (oldest despawns when max reached) +- Companions can loot player corpse (co-op) + +--- + +## 41-43: Supporting Systems + +- **41 BPC_PersistentWorldStateRecorder:** Records every world state change (door opened, item collected, enemy killed) to a change log for save/load. On load, replays changes to restore exact world state. +- **42 BPC_PlayerRespawnSystem:** Loads checkpoint data, places player at checkpoint transform, restores health/stamina/inventory from save state, applies brief invincibility. +- **43 BPC_RunHistoryTracker:** Tracks per-session stats: death count, play time, checkpoints reached, enemies killed, items collected. Persists for meta-progression (achievements, difficulty scaling). + +--- + +## Common Implementation Patterns in This Category + +1. **Force Stack Pattern:** Death and alt death space push state onto a stack; `RestorePreviousState()` pops back. Enables nested state changes (death → void → return). +2. **Interface-Based Persistence:** Save system doesn't know about doors or enemies — it only calls `I_Persistable.OnSave()` / `OnLoad()`. Any new saveable type just implements the interface. +3. **Save Tag Uniqueness:** Each saveable actor has a unique GameplayTag for identity. The save file maps tag → serialized state. +4. **Checkpoint Cascade:** Checkpoints are linear — activating a new one overrides the previous. Auto-save on activation prevents progress loss. +5. **Corpse as Container:** Corpses reuse `BPC_ContainerInventory` — no special corpse inventory code needed. + +--- + +*Developer Reference v1.0 — 05 Save/Load Systems. Companion to docs/blueprints/05-saveload/ specs.* diff --git a/docs/developer/06-ui-systems.md b/docs/developer/06-ui-systems.md new file mode 100644 index 0000000..b80f4bb --- /dev/null +++ b/docs/developer/06-ui-systems.md @@ -0,0 +1,157 @@ +# 06 — UI, Menus & Diegetic Presentation Systems (Systems 44-57) + +**Category Purpose:** These 14 systems form the complete UI layer — menu management, HUD presentation, inventory display, interaction prompts, notifications, screen effects, settings, accessibility, and diegetic in-world interfaces. The `SS_UIManager` is the central orchestrator; all widgets operate under its stack-based menu system. The architectural principle "UI Reads, Never Writes" applies: widgets display data but never own game logic. + +--- + +## System Index + +| # | System | Asset Type | Role | +|---|--------|-----------|------| +| 44 | `SS_UIManager` | Subsystem | UI subsystem; menu stack, context-based switching, input mode | +| 45 | `WBP_AccessibilityUI` | Widget | Accessibility settings; subtitles, colorblind, controller | +| 46 | `WBP_DiegeticHUDFrame` | Widget | Diegetic in-world HUD frame (wristwatch, helmet display) | +| 47 | `WBP_HUDController` | Widget | Root HUD widget; manages all HUD sub-widgets | +| 48 | `WBP_InteractionPromptDisplay` | Widget | Interaction prompt popup; key, description, hold progress | +| 49 | `WBP_InventoryMenu` | Widget | Inventory grid UI; drag-drop, sort, examine, equip, drop | +| 50 | `WBP_JournalDocumentViewer` | Widget | Document/journal viewer; pages, font styles, highlights | +| 51 | `WBP_MainMenu` | Widget | Main menu; new game, continue, load, settings, quit | +| 52 | `WBP_MenuFlowController` | Widget | Menu state machine; transitions, back navigation | +| 53 | `WBP_NotificationToast` | Widget | Toast notification; objective update, item found, achievement | +| 54 | `WBP_ObjectiveDisplay` | Widget | Active objective HUD element; current quest/objective | +| 55 | `WBP_PauseMenu` | Widget | Pause menu; resume, settings, save, load, quit | +| 56 | `WBP_ScreenEffectController` | Widget | Full-screen effects; damage vignette, stress, flash | +| 57 | `WBP_SettingsMenu` | Widget | Settings menu; audio, video, controls, gameplay | + +--- + +## Architecture: UI Layer + +``` +┌────────────────────────────────────────────────────────────────┐ +│ UI ARCHITECTURE │ +│ │ +│ SS_UIManager (GameInstanceSubsystem) │ +│ │ Menu stack: push/pop menus with priority │ +│ │ Context switching: Default → Hiding → Wristwatch → UI │ +│ │ Input mode coordination with SS_EnhancedInputManager │ +│ │ │ +│ ├─► WBP_MenuFlowController (menu state machine) │ +│ │ ├─► WBP_MainMenu │ +│ │ ├─► WBP_PauseMenu │ +│ │ ├─► WBP_SettingsMenu → WBP_AccessibilityUI │ +│ │ └─► WBP_CreditsScreen │ +│ │ │ +│ └─► WBP_HUDController (ingame HUD root) │ +│ ├─► WBP_ObjectiveDisplay (current objective) │ +│ ├─► WBP_InteractionPromptDisplay (interact prompt) │ +│ ├─► WBP_NotificationToast (popup notifications) │ +│ ├─► WBP_ScreenEffectController (damage/stress FX) │ +│ ├─► WBP_DiegeticHUDFrame (in-world wristwatch) │ +│ └─► WBP_InventoryMenu (inventory screen) │ +│ └─► WBP_JournalDocumentViewer (documents) │ +└────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 44 — SS_UIManager: UI Orchestrator + +**What It Does:** The central UI authority. Manages a menu stack for push/pop navigation, handles context-based UI switching (Default/Hiding/Wristwatch/UI modes), coordinates input mode changes with `SS_EnhancedInputManager` (cursor visibility, input blocking), and provides the canonical entry point for opening any menu. + +**How It Works Internally:** + +**Menu Stack:** +- `PushMenu(MenuWidget)` — adds to stack, opens widget, applies input mode +- `PopMenu()` — removes top, returns to previous, restores input mode +- Priority-based: UI(100) > Inspection(20) > WristwatchUI(10) > Hiding(5) > Default(0) +- Higher priority menus block lower ones + +**Context Switching:** +- Listens to game state changes (death, hiding, combat) +- Automatically shows/hides appropriate HUD elements per context +- Coordinates with `SS_EnhancedInputManager` for input mode changes (game-only vs UI-only vs game-and-UI) + +**Input Mode Coordination:** +- On menu open: request UI input mode (show cursor, block game input) +- On menu close: request game input mode (hide cursor, enable game input) +- Handles edge cases: pause menu over inventory, settings over pause + +--- + +## 47 — WBP_HUDController: Root HUD Widget + +**What It Does:** The root widget that owns and manages all HUD sub-widgets. Handles visibility toggling based on game context, manages layout, and routes data from gameplay systems to correct sub-widgets. + +**Key Sub-Widgets Managed:** +- Health/stamina/stress bars (bound to respective system dispatchers) +- `WBP_ObjectiveDisplay` — current quest text +- `WBP_InteractionPromptDisplay` — shows/hides based on `OnTargetFound`/`OnTargetLost` +- `WBP_NotificationToast` — queued notification display +- `WBP_ScreenEffectController` — damage vignette, stress overlay +- `WBP_DiegeticHUDFrame` — wristwatch HUD for immersive mode + +**Data Flow:** HUD binds to dispatchers; never polls. `OnHealthChanged` → update health bar. `OnObjectiveTagsChanged` → update objective text. `OnTargetFound` → show interaction prompt. + +--- + +## 48 — WBP_InteractionPromptDisplay: Interaction Prompt + +**What It Does:** Shows the "Press E to Open" style prompt when the player looks at an interactable. Handles three input modes: +- **Press:** shows key icon + action text +- **Hold:** shows radial fill progress bar + action text +- **DoubleTap:** shows double-tap indicator + +Binds to `BPC_InteractionDetector.OnTargetFound/Lost` and `OnHoldProgressUpdated`. + +--- + +## 49 — WBP_InventoryMenu: Inventory Grid UI + +**What It Does:** Full inventory screen with drag-and-drop grid layout. Displays all items from `BPC_InventorySystem`, supports sort modes, item inspection, equip/unequip, drop, use, and combine operations. + +**Features:** +- Grid-based layout with item icons and stack counts +- Drag-and-drop between slots (rearrange) +- Right-click context menu: Use, Equip, Drop, Examine, Combine +- Category tabs for filtering +- Weight bar showing current/max capacity +- Tooltip on hover showing item details (name, description, stats) +- Quick slot assignment (drag to hotbar) + +**Data Binding:** Subscribes to all `BPC_InventorySystem` event dispatchers. On any change, refreshes the affected slot, not the entire grid. + +--- + +## 51-57: Menu & Screen Widgets + +- **51 WBP_MainMenu:** New Game, Continue, Load Game, Settings, Quit. Checks save manifest for Continue availability. +- **52 WBP_MenuFlowController:** State machine for menu navigation. Handles transitions, back button, and prevents menu stacking bugs. +- **53 WBP_NotificationToast:** Animated popup for objectives, items, achievements. Queued system — multiple toasts stack vertically with auto-dismiss. +- **54 WBP_ObjectiveDisplay:** Shows current active objective text on HUD. Updates on `GS_CoreGameState.OnObjectiveTagsChanged`. +- **55 WBP_PauseMenu:** Resume, Settings, Save, Load, Quit to Menu. Checks `GM_CoreGameMode.bPauseAllowed`. +- **56 WBP_ScreenEffectController:** Full-screen post-process effects driven by gameplay state: damage vignette (red flash on hit), stress overlay (chromatic aberration, darkening), healing glow, death fade to black. +- **57 WBP_SettingsMenu:** Audio (volume sliders per bus), Video (resolution, quality), Controls (key rebinding via `SS_EnhancedInputManager`), Gameplay settings, Accessibility tab → `WBP_AccessibilityUI`. + +--- + +## 45-46, 50: Supporting Widgets + +- **45 WBP_AccessibilityUI:** Subtitle toggle/size, colorblind modes, controller remapping, difficulty presets, hold-to-confirm toggle. Reads/writes via `SS_SettingsSystem`. +- **46 WBP_DiegeticHUDFrame:** In-world HUD rendered on wristwatch or helmet display via `BPC_DiegeticDisplay`. Shows minimap, compass, health, ammo — diegetic (exists in world) not screen-space. +- **50 WBP_JournalDocumentViewer:** Reads documents from `BPC_DocumentArchiveSystem`. Page-turning interface with font styles, highlighted keywords, and categorization. + +--- + +## Common Implementation Patterns in This Category + +1. **UI Reads, Never Writes:** Widgets bind to gameplay dispatchers and display data. They call functions on systems (UseItem, EquipItem) but never own game state. +2. **Menu Stack Navigation:** `SS_UIManager.PushMenu()` / `PopMenu()` ensures clean navigation without manual visibility management. +3. **Context Priority Ladder:** Default(0) < Hiding(5) < WristwatchUI(10) < Inspection(20) < UI(100). Higher priority contexts override lower ones automatically. +4. **Input Mode Sync:** Every menu open/close coordinates with `SS_EnhancedInputManager` for cursor + input blocking. +5. **Dispatcher Binding, Not Polling:** All HUD widgets bind to gameplay dispatchers on construct and unbind on destruct. No widget uses Event Tick for polling. +6. **Toast Queue:** Notifications are queued and displayed sequentially with auto-dismiss — prevents notification spam. + +--- + +*Developer Reference v1.0 — 06 UI Systems. Companion to docs/blueprints/06-ui/ specs.* diff --git a/docs/developer/07-narrative-systems.md b/docs/developer/07-narrative-systems.md new file mode 100644 index 0000000..767eda3 --- /dev/null +++ b/docs/developer/07-narrative-systems.md @@ -0,0 +1,133 @@ +# 07 — Narrative, Dialogue & Objectives Systems (Systems 58-68) + +**Category Purpose:** These 11 systems handle the entire story layer — narrative state tracking, objective/quest management, dialogue playback with choices, branching consequences, cutscene bridging, timed trial scenarios, lore/journal unlocks, narrative trigger volumes, and ending condition accumulation. The `BPC_NarrativeStateSystem` is the central narrative authority; all story beats flow through it. + +--- + +## System Index + +| # | System | Asset Type | Role | +|---|--------|-----------|------| +| 58 | `BPC_NarrativeStateSystem` | Component | Narrative state machine; flags, milestones, chapter progression | +| 59 | `BPC_ObjectiveSystem` | Component | Objective tracker; activate, complete, fail, branching objectives | +| 60 | `BPC_DialoguePlaybackSystem` | Component | Dialogue playback; line queue, VO, subtitles, auto-advance | +| 61 | `BPC_DialogueChoiceSystem` | Component | Dialogue choices; present, select, filter by flags, consequence | +| 62 | `BPC_BranchingConsequenceSystem` | Component | Narrative consequence execution; state changes, item grants | +| 63 | `BPC_TrialScenarioSystem` | Component | Timed trial/puzzle scenario; begin, evaluate, success/fail | +| 64 | `BPC_CutsceneBridge` | Component | Cutscene bridge; play, skip, milestone flags, camera transfer | +| 65 | `BPC_LoreUnlockSystem` | Component | Lore/journal entry unlock; trigger, categorize, notify | +| 66 | `DA_NarrativeDataAssets` | Data Asset | Narrative data: DialogueData, CutsceneData, ScenarioData | +| 67 | `BP_NarrativeTriggerVolume` | Actor | Narrative trigger volume; sets flags, starts dialogue/scene | +| 68 | `BPC_EndingAccumulator` | Component | Ending tracker; accumulates conditions, determines outcome | + +--- + +## Category Data Flow + +``` +┌──────────────────────────────────────────────────────────────────┐ +│ NARRATIVE PIPELINE │ +│ │ +│ BP_NarrativeTriggerVolume (world-placed) │ +│ │ Player enters → triggers narrative event │ +│ ├─► Sets narrative flags in BPC_NarrativeStateSystem │ +│ ├─► Starts dialogue via BPC_DialoguePlaybackSystem │ +│ └─► Activates objectives via BPC_ObjectiveSystem │ +│ │ +│ BPC_NarrativeStateSystem (state machine) │ +│ │ Tracks: narrative flags, milestones, chapter phase │ +│ │ Gating: checks flags before allowing story beats │ +│ └─► Syncs to GS_CoreGameState for UI display │ +│ │ +│ BPC_ObjectiveSystem (quest tracker) │ +│ │ Activate → Complete → (optional: Fail) │ +│ │ Branching: objectives can split based on choices │ +│ └─► Updates GS_CoreGameState.ActiveObjectiveTags │ +│ │ +│ BPC_DialoguePlaybackSystem │ +│ │ Line queue: sequential or branching │ +│ │ VO playback with subtitles │ +│ └─► BPC_DialogueChoiceSystem (choice points) │ +│ │ +│ BPC_BranchingConsequenceSystem │ +│ │ Executes consequences of dialogue choices │ +│ │ State changes, item grants, NPC disposition │ +│ └─► Feeds back to NarrativeStateSystem │ +│ │ +│ BPC_EndingAccumulator │ +│ │ Accumulates ending conditions throughout the game │ +│ └─► At end: determines which ending plays │ +└──────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 58 — BPC_NarrativeStateSystem: Narrative State Machine + +**What It Does:** The central narrative authority. Tracks all story flags, milestones, and chapter progression. Every narrative system queries this component to determine what content is available. Uses GameplayTags for all state — no booleans or strings. + +**How It Works Internally:** +- Maintains a map of narrative flags (GameplayTag → current value) +- Tracks completed milestones (chapters, key story beats) +- Gates content: dialogue options, objective availability, trigger volume activation all check narrative flags +- Syncs with `GS_CoreGameState` for session-wide narrative state +- Chapter phase tracking: sub-chapter progression within acts +- Implements `I_Persistable` for save/load of story progress + +--- + +## 59 — BPC_ObjectiveSystem: Objective/Quest Tracker + +**What It Does:** Manages all active, completed, and failed objectives. Supports branching objectives (choice A leads to objective X, choice B to objective Y), sequential objectives, and hidden objectives that reveal on discovery. + +**How It Works Internally:** +- Activates objectives from `DA_ObjectiveData` Data Assets +- Tracks progress per objective (counters, location checks, item possession) +- Branching: objective completion can spawn child objectives based on player choices +- Hidden objectives: exist in background, reveal when conditions met +- Updates `GS_CoreGameState.ActiveObjectiveTags` → UI updates automatically +- Fires dispatchers: `OnObjectiveActivated`, `OnObjectiveCompleted`, `OnObjectiveFailed` + +--- + +## 60-61: Dialogue Systems + +**BPC_DialoguePlaybackSystem:** +- Manages a line queue: sequential dialogue lines with configurable auto-advance or manual continue +- VO (voice-over) playback with subtitle display +- Supports speaker identification (NPC name, portrait) +- Animation triggers on key lines (gestures, expressions) +- Skip functionality for individual lines or entire conversations + +**BPC_DialogueChoiceSystem:** +- Presents dialogue choices at branching points +- Filters available choices by narrative flags (choices only appear if conditions met) +- Each choice has consequences executed by `BPC_BranchingConsequenceSystem` +- Supports timed choices (auto-select default if timer expires) +- Tracks choice history for later reference + +--- + +## 62-68: Supporting Narrative Systems + +- **62 BPC_BranchingConsequenceSystem:** Executes narrative consequences: sets narrative flags, grants/removes items, changes NPC disposition, unlocks objectives, triggers cutscenes. +- **63 BPC_TrialScenarioSystem:** Timed challenges: puzzle solved within time? stealth section without detection? combat encounter with specific constraints? Evaluates success/fail conditions. +- **64 BPC_CutsceneBridge:** Manages cutscene playback: transfers camera to sequencer, blocks input, plays cutscene, restores control. Supports skip (with milestone flag set), pause, and post-cutscene state restoration. +- **65 BPC_LoreUnlockSystem:** Unlocks journal/lore entries on triggers (finding a document, reaching a location, completing an objective). Categorizes entries and notifies UI. +- **66 DA_NarrativeDataAssets:** Data Assets for DialogueData (lines, speakers, VO references), CutsceneData (sequencer references, skip flags), ScenarioData (trial parameters). +- **67 BP_NarrativeTriggerVolume:** World-placed trigger volume. On player overlap: sets narrative flags, starts dialogue, activates objectives. One-shot or repeatable. +- **68 BPC_EndingAccumulator:** Tracks ending conditions throughout the game (which key choices were made? which NPCs survived? which objectives completed?). At end-game trigger, evaluates all conditions and determines which ending sequence plays. + +--- + +## Common Implementation Patterns in This Category + +1. **Flag-Based Gating:** Every narrative decision sets a GameplayTag flag. Content (dialogue, objectives, endings) checks these flags to determine availability. +2. **Data-Driven Content:** Dialogue lines, objective descriptions, choice text — all in `DA_NarrativeDataAssets`. Writers never touch Blueprint logic. +3. **Choice → Consequence Pipeline:** Dialogue choice → executed by ConsequenceSystem → sets flags → future content gated by those flags. +4. **Accumulator Pattern:** Ending system doesn't decide at each moment — it accumulates evidence throughout the game and evaluates at the end. +5. **Trigger Volume Pattern:** World-placed triggers handle most narrative beats — no level blueprint spaghetti. + +--- + +*Developer Reference v1.0 — 07 Narrative Systems. Companion to docs/blueprints/07-narrative/ specs.* diff --git a/docs/developer/08-weapons-systems.md b/docs/developer/08-weapons-systems.md new file mode 100644 index 0000000..e01704d --- /dev/null +++ b/docs/developer/08-weapons-systems.md @@ -0,0 +1,139 @@ +# 08 — Weapons, Equipment & Damage Systems (Systems 69-79) + +**Category Purpose:** These 11 systems form the complete combat layer — weapon actors (ranged and melee), ammo management, combat feedback (hit markers, kill confirm), damage reception and resistance, death cause tracking, firearm specialization, hit reactions, melee combat, recoil patterns, reload mechanics, and shield defense. The `BP_WeaponBase` is the base actor class extended by all weapons; combat flows through `BPC_DamageReceptionSystem` to `BPC_HealthSystem`. + +--- + +## System Index + +| # | System | Asset Type | Role | +|---|--------|-----------|------| +| 69 | `BP_WeaponBase` | Actor | Weapon base actor; fire, equip, holster, FX, audio | +| 70 | `BPC_AmmoComponent` | Component | Ammo pool; reserve/loaded, ammo types, pickup | +| 71 | `BPC_CombatFeedbackComponent` | Component | Hit markers, kill confirm, damage direction indicators | +| 72 | `BPC_DamageReceptionSystem` | Component | Damage reception; calculate, resist, apply, stagger | +| 73 | `BPC_DeathCauseTracker` | Component | Death cause logging; killing blow, killer ID, damage type | +| 74 | `BPC_FirearmSystem` | Component | Firearm specialization; fire modes, ADS, chamber check | +| 75 | `BPC_HitReactionSystem` | Component | Hit reaction; directional flinch, stagger, knockdown anims | +| 76 | `BPC_MeleeSystem` | Component | Melee weapon; combos, hit detection, block, parry | +| 77 | `BPC_RecoilSystem` | Component | Recoil; camera spring arm offset, pattern, recovery | +| 78 | `BPC_ReloadSystem` | Component | Reload; tactical/empty reload, notifies, interrupt | +| 79 | `BPC_ShieldDefenseSystem` | Component | Shield defense; block, durability, break, stun | + +--- + +## Category Data Flow + +``` +┌──────────────────────────────────────────────────────────────────┐ +│ COMBAT PIPELINE │ +│ │ +│ Input → BP_WeaponBase │ +│ │ State machine: Holstered→Equipping→Ready→Firing→Reloading │ +│ │ │ +│ ├─► Ready state: StartFire → OnFire (subclass override) │ +│ │ │ │ +│ │ ├─► BPC_FirearmSystem (ranged): raycast/projectile │ +│ │ │ ├─► BPC_RecoilSystem.ApplyRecoil() │ +│ │ │ ├─► BPC_AmmoComponent.ConsumeAmmo() │ +│ │ │ └─► Hit target → BPC_DamageReceptionSystem │ +│ │ │ │ +│ │ └─► BPC_MeleeSystem (melee): hitbox sweep │ +│ │ ├─► Hit detection, combo tracking │ +│ │ └─► Hit target → BPC_DamageReceptionSystem │ +│ │ │ +│ └─► BPC_ReloadSystem (reload): tactical/empty, anim notifies │ +│ └─► BPC_AmmoComponent.RefillAmmo() │ +│ │ +│ BPC_DamageReceptionSystem (on target) │ +│ │ Calculate effective damage (resistance, armor) │ +│ ├─► BPC_HealthSystem.ApplyDamage() │ +│ ├─► BPC_HitReactionSystem (flinch, stagger) │ +│ └─► BPC_CombatFeedbackComponent (hit marker) │ +│ │ +│ BPC_ShieldDefenseSystem (on target, if equipped) │ +│ │ Blocks damage, reduces durability, breaks at 0 │ +│ └─► Staggers attacker on perfect parry │ +│ │ +│ BPC_DeathCauseTracker (on death) │ +│ └─► Logs: who killed, with what, damage type, location │ +└──────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 69 — BP_WeaponBase: Base Weapon Actor + +**What It Does:** The base class for all weapon actors. Manages the weapon lifecycle state machine, attachment to character sockets, fire input handling, aim-down-sights FOV transition, and event dispatching. Extended by ranged and melee weapon subclasses. + +**State Machine:** +``` +Holstered → Equipping → Ready ⇄ Firing → Reloading → Ready + → Holstering → Holstered +``` +- Firing blocked during: Holstered, Equipping, Holstering, Reloading, Broken +- `SetWeaponState(NewState)` updates state and broadcasts `OnWeaponStateChanged` + +**Fire Modes:** SemiAutomatic (one shot per press), FullAutomatic (continuous while held), BurstFire (fixed burst count), ChargeAndRelease (hold to charge), MeleeSwing + +**ADS System:** +- `StartAim()` / `StopAim()`: blends camera FOV between `DefaultFOV` and `AimDownSightsFOV` +- Uses `ADSInterpSpeed` for smooth transition +- Notifies `BPC_CameraStateLayer` for FOV management + +**Implementation Patterns:** +- `OnFire()` is virtual — subclasses implement actual fire logic (raycast, projectile, melee hitbox) +- Does NOT handle: specific fire logic, ammo math, damage calculation, visual/audio feedback — delegates to specialized components +- All properties from `DA_EquipmentConfig` Data Asset + +--- + +## 70 — BPC_AmmoComponent: Ammo Management + +**What It Does:** Manages ammunition for weapons. Tracks reserve ammo (total carried) and loaded ammo (in magazine). Handles ammo types, pickup from world, and consumption on fire. + +**Key Features:** +- Reserve ammo tracked per ammo type (GameplayTag) +- Magazine capacity from weapon data; reload transfers from reserve to loaded +- Ammo pickup: adds to reserve, respects max carry limits +- Different ammo types for different weapons (pistol, rifle, shotgun, energy) + +--- + +## 72 — BPC_DamageReceptionSystem: Damage Processing + +**What It Does:** Processes incoming damage on the target side before passing to `BPC_HealthSystem`. Handles armor calculation, damage type resistance, critical hit multipliers, and directional damage awareness. + +**Flow:** +1. Receive damage event (source weapon, damage type, hit location, base amount) +2. Calculate effective damage: apply armor reduction, type resistance, critical multiplier +3. Pass to `BPC_HealthSystem.ApplyDamage()` +4. Trigger `BPC_HitReactionSystem` for flinch/stagger based on damage amount +5. Notify `BPC_CombatFeedbackComponent` for hit marker display + +--- + +## 73-79: Supporting Combat Systems + +- **71 BPC_CombatFeedbackComponent:** Hit markers (direction, critical), kill confirm (X indicator), damage direction arrows. Visual/audio feedback for combat clarity. +- **73 BPC_DeathCauseTracker:** On death: records killing blow details (instigator, weapon, damage type, hit location). Used by death screen, player metrics, and narrative systems. +- **74 BPC_FirearmSystem:** Extends weapon base with firearm-specific logic: raycast hitscan, projectile spawning, spread patterns, aim-down-sights accuracy bonus, chamber check animation. +- **75 BPC_HitReactionSystem:** Directional hit reactions: flinch animation toward damage source, stagger on heavy hits, knockdown on lethal/critical hits. Drives animation montages and camera shake. +- **76 BPC_MeleeSystem:** Melee combat: combo system (light/heavy attacks chaining), hitbox sweep detection, blocking (reduces damage), parrying (timed block that staggers attacker), riposte (counter after parry). +- **77 BPC_RecoilSystem:** Camera recoil patterns: pitch/yaw offset per shot, pattern spread, recovery speed. Configurable per weapon via Data Asset. Affects camera spring arm. +- **78 BPC_ReloadSystem:** Reload mechanics: tactical reload (magazine not empty, faster), empty reload (magazine empty, slower with bolt/charge). Animation notifies for ammo refill timing. Interruptible during early phase. +- **79 BPC_ShieldDefenseSystem:** Active shield: blocks damage from front arc, has durability that depletes on block, breaks at 0 with stun, recharge delay before regenerating. + +--- + +## Common Implementation Patterns in This Category + +1. **Weapon as Actor, Logic in Components:** `BP_WeaponBase` is an attachable actor; specialized logic (ammo, recoil, reload) lives in components that can be mixed and matched. +2. **State Machine Gating:** Weapon state prevents firing during reload, equip, holster. Systems don't need to check each other — the state machine handles it. +3. **Data-Driven Weapon Stats:** Fire rate, damage, spread, recoil pattern, magazine size — all in `DA_EquipmentConfig`. Changing a weapon's stats never touches Blueprint. +4. **Damage Pipeline:** Damage flows: Weapon → DamageReceptionSystem → HealthSystem → HitReaction → CombatFeedback. Each step is a separate concern. +5. **Animation Notify Contract:** Reload and fire animations use specific notifies (`OnAmmoRefill`, `OnFireComplete`) that gameplay systems bind to — not hardcoded timers. + +--- + +*Developer Reference v1.0 — 08 Weapons Systems. Companion to docs/blueprints/08-weapons/ specs.* diff --git a/docs/developer/09-ai-systems.md b/docs/developer/09-ai-systems.md new file mode 100644 index 0000000..61ae058 --- /dev/null +++ b/docs/developer/09-ai-systems.md @@ -0,0 +1,118 @@ +# 09 — AI, Perception & Encounters Systems (Systems 80-88) + +**Category Purpose:** These 9 systems form the enemy AI layer — base enemy character, patrol paths, alert state management, AI state machine, controller with behavior tree, blackboard definition, memory/last-known-location tracking, perception (sight/hearing/damage), and behavior variant selection. The `AI_BaseAgentController` runs behavior trees; all AI logic is data-driven via blackboard keys and behavior variants. + +--- + +## System Index + +| # | System | Asset Type | Role | +|---|--------|-----------|------| +| 80 | `BP_EnemyBase` | Actor (Character) | Enemy base character; health, combat, patrol, death | +| 81 | `BP_PatrolPath` | Actor | Patrol path spline; waypoints, wait times, loop | +| 82 | `BPC_AlertSystem` | Component | AI alert states: Suspicious → Alerted → Combat | +| 83 | `BPC_AIStateMachine` | Component | AI state machine: Patrol/Search/Combat/Flee | +| 84 | `AI_BaseAgentController` | Controller | Base AI controller; behavior tree runner, perception init | +| 85 | `BB_AgentBoard` | Blackboard | AI blackboard definition; all keys for enemy AI | +| 86 | `BPC_AIMemorySystem` | Component | AI memory; last known locations, threat history | +| 87 | `BPC_AIPerceptionSystem` | Component | AI perception; sight, hearing, damage sense | +| 88 | `BPC_BehaviourVariantSelector` | Component | Behavior variant selection; weighted random from dataset | + +--- + +## AI Architecture + +``` +┌──────────────────────────────────────────────────────────────────┐ +│ AI PIPELINE │ +│ │ +│ AI_BaseAgentController (AIController) │ +│ │ Runs Behavior Tree defined in BB_AgentBoard │ +│ │ Initializes perception system │ +│ │ │ +│ ├─► BPC_AIPerceptionSystem (senses) │ +│ │ Sight: vision cone, distance, light level │ +│ │ Hearing: sound events (gunshots, footsteps) │ +│ │ Damage: takes damage → knows attacker location │ +│ │ Team awareness: allies share detection │ +│ │ │ +│ ├─► BPC_AIMemorySystem (memory) │ +│ │ Last known player location │ +│ │ Threat history (who damaged me?) │ +│ │ Investigation points (where to search) │ +│ │ Forgets old data after configurable time │ +│ │ │ +│ ├─► BPC_AlertSystem (alert level) │ +│ │ Suspicious → (investigate) → Alerted → (engage) │ +│ │ → Combat → (player lost) → Search → (timeout) → Patrol │ +│ │ Flee: low health threshold triggers retreat │ +│ │ │ +│ └─► BPC_AIStateMachine (behavior state) │ +│ Patrol → Search → Combat → Flee │ +│ State transitions driven by alert level + memory │ +│ │ +│ BPC_BehaviourVariantSelector │ +│ │ Selects behavior variant at spawn: │ +│ │ Attack patterns (aggressive, defensive, flanking) │ +│ │ Patrol style (predictable, random, stationary) │ +│ │ Aggression level (cautious, balanced, reckless) │ +│ └─► Weighted random from DA_BehaviourVariant dataset │ +│ │ +│ BP_PatrolPath │ +│ └─► Spline-based path with waypoints and wait times │ +└──────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 82 — BPC_AlertSystem: Alert States + +**What It Does:** Manages the enemy's alert progression — how aware they are of the player's presence. Drives behavior tree transitions and audio/visual feedback. + +**Alert Levels:** +- `None`: Unaware, patrolling normally +- `Suspicious`: Heard something, saw a glimpse — investigates last known location +- `Alerted`: Confirmed player presence — moves to engage +- `Combat`: Actively fighting — shooting, chasing, flanking +- `Search`: Lost sight of player — searches last known area +- `Flee`: Health critical — retreats to safety + +**Escalation:** Suspicion meter fills based on perception events. Partial sight = slow fill, full sight = fast fill, loud noise = burst fill. De-escalation: meter decays over time when no stimuli. + +--- + +## 87 — BPC_AIPerceptionSystem: AI Senses + +**What It Does:** Wraps UE5's AI Perception system with game-specific logic. Handles sight (vision cone + distance + light level), hearing (sound event radius + type priority), damage sense (instant alert on hit), and team awareness (nearby allies share detection). + +**Sight:** Vision cone angle, max distance, peripheral vision penalty, light level modifier (harder to see in darkness), obstruction (line of sight trace) + +**Hearing:** Gunshot > footstep > door creak. Louder sounds have larger radius. Running is louder than walking. Silenced weapons have reduced radius. + +**Team Awareness:** If one enemy in a group detects the player, all nearby allies are alerted to the player's approximate position. + +--- + +## 80-88: Remaining Systems + +- **80 BP_EnemyBase:** Character with health component, combat capability, patrol behavior, and death handling. Implements `I_Damageable`. +- **81 BP_PatrolPath:** Spline component with waypoints. Each waypoint has wait time, look direction, and optional animation. +- **83 BPC_AIStateMachine:** Discrete state machine: Patrol→Search→Combat→Flee. Transitions driven by blackboard values set by AlertSystem and PerceptionSystem. +- **84 AI_BaseAgentController:** Custom AIController that runs the behavior tree, initializes perception, and manages the blackboard. +- **85 BB_AgentBoard:** Blackboard Data Asset defining all keys: TargetActor, LastKnownLocation, AlertLevel, CurrentState, PatrolPath, HomeLocation, etc. +- **86 BPC_AIMemorySystem:** Stores last known player location, threat sources, investigation points. Data decays over configurable time. Behavior tree queries memory to decide search patterns. +- **88 BPC_BehaviourVariantSelector:** At spawn, selects a behavior variant from `DA_BehaviourVariant` with weighted random. Determines attack patterns, patrol style, and aggression. Creates enemy variety without separate classes. + +--- + +## Common Implementation Patterns in This Category + +1. **Behavior Tree + Blackboard:** All decision-making in behavior trees reading blackboard keys. Components write to blackboard; trees read and act. +2. **Alert Cascade:** Suspicious → Alerted → Combat → Search → Patrol. Each state has different behavior tree branches. +3. **Memory with Decay:** AI doesn't have infinite memory — last known locations are forgotten after time. Forces re-investigation. +4. **Perception Sharing:** Team awareness prevents "why didn't his friend react?" — nearby allies share detection. +5. **Behavior Variants for Variety:** Weighted random selection at spawn means enemies of the same class behave differently — no hardcoded enemy types. + +--- + +*Developer Reference v1.0 — 09 AI Systems. Companion to docs/blueprints/09-ai/ specs.* diff --git a/docs/developer/10-adaptive-systems.md b/docs/developer/10-adaptive-systems.md new file mode 100644 index 0000000..c2739f4 --- /dev/null +++ b/docs/developer/10-adaptive-systems.md @@ -0,0 +1,149 @@ +# 10 — Adaptive Environment, Atmosphere & Audio Systems (Systems 89-101, 132-133) + +**Category Purpose:** These 17 systems create the dynamic, reactive world — difficulty scaling, fear mechanics, performance optimization, procedural encounters, environment mutation, atmosphere control, lighting events, memory distortion, pacing direction, playstyle classification, rare/scare events, and the MetaSounds audio subsystem. The `BPC_AdaptiveEnvironmentDirector` is the central coordinator; `SS_AudioManager` is the sole audio entry point. + +--- + +## System Index + +| # | System | Asset Type | Role | +|---|--------|-----------|------| +| 89 | `BPC_DifficultyManager` | Component | Dynamic difficulty; metric-based scaling, adaptive tuning | +| 90 | `BPC_FearSystem` | Component | Fear system (AI + player); fear states, cower, flee | +| 91 | `BPC_PerformanceScaler` | Component | Performance scaling; LOD, spawn distance, effect quality | +| 92 | `BPC_ProceduralEncounter` | Component | Procedural encounter generation; difficulty-based spawn groups | +| 93 | `BPC_AdaptiveEnvironmentDirector` | Component | Adaptive environment; room mutation, event coordination | +| 94 | `BPC_AtmosphereStateController` | Component | Atmosphere state; room tone, tension, mood | +| 95 | `BPC_AudioAtmosphereController` | Component | [DEPRECATED] — superseded by SS_AudioManager | +| 96 | `BPC_LightEventController` | Component | Light events; flicker, dim, color shift, strobe | +| 97 | `BPC_MemoryDriftSystem` | Component | Memory drift; visual/audio/dialogue distortions | +| 98 | `BPC_PacingDirector` | Component | Pacing director; intensity bands, encounter frequency | +| 99 | `BPC_PlaystyleClassifier` | Component | Playstyle classification; Aggressive/Stealthy/Explorer | +| 100 | `BPC_RareEventSystem` | Component | Rare event system; weighted selection, cooldown | +| 101 | `BPC_ScareEventSystem` | Component | Scare event system; jump scares, anticipation, recovery | +| 132 | `SS_AudioManager` | Subsystem | Single audio entry point; 4 MetaSound buses, room zones | +| 133 | `BP_RoomAudioZone` | Actor (TriggerVolume) | Room audio zone; auto-switches reverb on overlap | + +--- + +## Adaptive Architecture + +``` +┌──────────────────────────────────────────────────────────────────┐ +│ ADAPTIVE SYSTEMS │ +│ │ +│ BPC_AdaptiveEnvironmentDirector (central coordinator) │ +│ │ Reads player state: stress, health, location │ +│ │ Coordinates subsystem responses: │ +│ │ │ +│ ├─► BPC_AtmosphereStateController (mood/tension) │ +│ │ Room tone: Safe → Neutral → Tense → Danger → Terror │ +│ │ Drives: lighting, audio ambience, fog, post-process │ +│ │ │ +│ ├─► BPC_LightEventController (lighting events) │ +│ │ Flicker, dim, color shift, strobe, blackout │ +│ │ Triggered by: tension level, scare events, combat │ +│ │ │ +│ ├─► BPC_MemoryDriftSystem (psychological horror) │ +│ │ Visual distortions, audio glitches, false dialogue │ +│ │ Intensity driven by stress tier │ +│ │ │ +│ ├─► BPC_ScareEventSystem (horror moments) │ +│ │ Jump scares, atmospheric scares, dread build-up │ +│ │ Anticipation → Trigger → Payoff → Recovery │ +│ │ │ +│ └─► BPC_RareEventSystem (special occurrences) │ +│ Weighted random events with long cooldowns │ +│ Ghost sightings, phone rings, TV static, whispers │ +│ │ +│ BPC_PacingDirector (mission-level pacing) │ +│ │ Intensity bands: Calm → Exploration → Tension → Combat │ +│ │ Controls: encounter frequency, music intensity, │ +│ │ scare event probability, ambient tension │ +│ └─► Feeds into AdaptiveEnvironmentDirector │ +│ │ +│ BPC_PlaystyleClassifier → BPC_DifficultyManager │ +│ │ Classifies: Aggressive / Stealthy / Explorer / Balanced │ +│ └─► Difficulty adapts: enemy count, loot quality, AI skill │ +│ │ +│ BPC_FearSystem (AI fear) │ +│ └─► AI enemies can feel fear: cower, flee, surrender │ +│ │ +│ BPC_PerformanceScaler (technical) │ +│ └─► Dynamically adjusts LOD, spawn distance, particle count │ +└──────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 132 — SS_AudioManager: MetaSounds Audio Subsystem + +**What It Does:** The **single entry point for all audio** in the framework. A GameInstanceSubsystem that owns 4 MetaSound mix buses (SFX, Ambience, Music, Dialogue → Master Bus), handles room acoustic zone switching, dynamic gameplay parameters (heart rate, stress, fear), volume control integration with settings, and audio pooling. + +**Mix Buses:** +- `MS_SFXBus`: weapon sounds, footsteps, UI sounds, impact FX +- `MS_AmbientBus`: environmental ambience, room tone, wind, water +- `MS_MusicBus`: background music, combat music, tension music +- `MS_DialogueBus`: NPC voices, radio chatter, narrator +- All feed into `MS_MasterBus` for final output + +**Gameplay Parameters:** Heart rate, stress level, fear intensity, music intensity pushed as MetaSound float parameters from gameplay systems — not hardcoded in audio assets. Enables dynamic mixing: heart beats faster → heartbeat sound intensifies. + +**Room Acoustic Zones:** +- `BP_RoomAudioZone` trigger volumes on overlap call `SS_AudioManager.SetRoomPreset(Preset)` +- Presets from `DA_RoomAcousticPreset`: SmallRoom, LargeRoom, Outdoor, Cave, Hallway, Bathroom, Cathedral +- Applies reverb, occlusion, reflection, and EQ settings +- Zone stack: push/pop allows nested zones (entering a closet inside a room) + +**Settings Integration:** +- `WBP_SettingsMenu` sliders call `SetBusVolume(Category, Volume)` +- Writes to the bus MetaSound patch directly +- Persistent settings loaded on init + +**Deprecation:** `BPC_AudioAtmosphereController` (95) is phased out — all audio now routes through this subsystem. + +--- + +## 133 — BP_RoomAudioZone: Room Audio Zone Trigger + +**What It Does:** A trigger volume placed in levels. When the player overlaps it, the room's acoustic preset is applied. On exit, the previous zone is restored via a push/pop stack. + +**Features:** +- Defines a `DA_RoomAcousticPreset` reference +- On overlap: pushes current zone, applies new preset +- On exit: pops back to previous zone +- Supports priority for overlapping zones +- Smooth blend time between acoustic transitions + +--- + +## 89-101: Adaptive Subsystems Summary + +- **89 BPC_DifficultyManager:** Reads player metrics (accuracy, deaths, completion time) and adjusts: enemy health/damage, loot quality/quantity, puzzle hint frequency, encounter intensity. +- **90 BPC_FearSystem:** AI fear mechanic — enemies can enter fear states (nervous → cowering → fleeing → surrendering) based on player power, ally deaths, supernatural events. +- **91 BPC_PerformanceScaler:** Dynamically adjusts LOD bias, spawn distance, particle count, shadow quality based on FPS target. Ensures smooth performance on varied hardware. +- **92 BPC_ProceduralEncounter:** Generates encounters from spawn groups weighted by difficulty. Selects enemy types, counts, and spawn locations. +- **93 BPC_AdaptiveEnvironmentDirector:** Central coordinator — reads all player state and directs atmosphere/light/scare systems. The "dungeon master" of the adaptive layer. +- **94 BPC_AtmosphereStateController:** Manages room tone and tension level. Drives lighting, fog, post-process, and ambient audio via Data Assets (`DA_AtmosphereProfile`). +- **95 BPC_AudioAtmosphereController:** [DEPRECATED] Replaced by `SS_AudioManager`. Do not use in new implementations. +- **96 BPC_LightEventController:** Dynamic light events: flicker (random/sine), dim (gradual), color shift (temperature), strobe (rapid), blackout (full dark). Triggered by adaptive systems. +- **97 BPC_MemoryDriftSystem:** Psychological horror — visual distortions (shimmer, double vision), audio glitches (reversed sounds, whispers), false dialogue events. Intensity from `BPC_StressSystem`. +- **98 BPC_PacingDirector:** Controls mission pacing: intensity bands (calm→exploration→tension→combat→climax→resolution). Manages encounter frequency, music, and scare probability. +- **99 BPC_PlaystyleClassifier:** Analyzes player behavior (weapon usage, stealth time, exploration percentage) and classifies as Aggressive/Stealthy/Explorer/Balanced. +- **100 BPC_RareEventSystem:** Special rare occurrences with weighted random selection and long cooldowns. Ghost sightings, environmental anomalies, hidden messages. +- **101 BPC_ScareEventSystem:** Horror scare management: anticipation phase (build-up), trigger (payoff), recovery (return to normal). Jump scares, atmospheric dread, slow-burn tension. + +--- + +## Common Implementation Patterns in This Category + +1. **Central Coordinator + Specialist Workers:** `BPC_AdaptiveEnvironmentDirector` coordinates; each subsystem (lighting, atmosphere, scares) is a specialist. +2. **Data-Driven Profiles:** `DA_AtmosphereProfile`, `DA_ScareEvent`, `DA_RoomMutation` — content teams configure atmosphere without touching Blueprints. +3. **Gameplay Parameters as Audio Inputs:** Heart rate, stress, fear are MetaSound float parameters — audio designers work in MetaSound editor, not Blueprint. +4. **Zone Stack for Audio:** Push/pop room presets enables nested acoustic spaces (a closet inside a room inside a building). +5. **Dynamic Difficulty as Metrics Response:** Difficulty doesn't use simple "easy/medium/hard" — it reads player performance and adapts continuously. +6. **Pacing Director Controls Everything:** Encounter frequency, music intensity, scare probability all derive from pacing band, not individual systems. + +--- + +*Developer Reference v1.0 — 10 Adaptive Systems. Companion to docs/blueprints/10-adaptive/ specs.* diff --git a/docs/developer/11-16-systems.md b/docs/developer/11-16-systems.md new file mode 100644 index 0000000..327113a --- /dev/null +++ b/docs/developer/11-16-systems.md @@ -0,0 +1,111 @@ +# 11 — Achievements, Progression & Meta Systems (Systems 102-103) + +**Category Purpose:** These 2 systems handle meta-progression — progress statistics tracking across sessions and the achievement/unlock system with platform integration. + +| # | System | Asset Type | Role | +|---|--------|-----------|------| +| 102 | `BPC_ProgressStatTracker` | Component | Progress stats; total playtime, collectibles, achievements | +| 103 | `SS_AchievementSystem` | Subsystem | Achievement subsystem; unlock, notify, platform integration | + +**102 BPC_ProgressStatTracker:** Tracks cumulative stats across play sessions: total playtime, collectibles found, enemies killed, deaths, items crafted, documents read, endings seen. Persists via `I_Persistable` for long-term tracking. + +**103 SS_AchievementSystem:** GameInstanceSubsystem that manages achievement unlocks. Listens to gameplay events (enemy killed, item found, chapter completed) and unlocks achievements when conditions met. Shows notification toast on unlock. Integrates with platform achievement APIs (Steam, PlayStation, Xbox). + +--- + +# 12 — Settings, Accessibility & Platform Systems (Systems 104-105) + +| # | System | Asset Type | Role | +|---|--------|-----------|------| +| 104 | `BPC_AccessibilitySettings` | Component | Accessibility; subtitles, colorblind, controller remap | +| 105 | `SS_SettingsSystem` | Subsystem | Settings subsystem; persistent settings, apply, reset | + +**104 BPC_AccessibilitySettings:** Manages accessibility features: subtitle toggle/size, colorblind mode selection (protanopia/deuteranopia/tritanopia), controller remapping, difficulty presets, hold-to-confirm toggle, camera shake reduction. Settings persisted via `SS_SettingsSystem`. + +**105 SS_SettingsSystem:** GameInstanceSubsystem for all persistent settings. Loads defaults on init, saves on change, supports reset-to-default. Settings categories: Audio, Video, Controls, Gameplay, Accessibility. Coordinates with `SS_AudioManager` for volume, `SS_EnhancedInputManager` for key rebinding. + +--- + +# 13 — Polish: Tutorial, Loading, Credits & Debug Systems (Systems 106-114) + +| # | System | Asset Type | Role | +|---|--------|-----------|------| +| 106 | `BPC_AnalyticsTracker` | Component | Analytics; event tracking, session metrics, telemetry | +| 107 | `BPC_DevCheatManager` | Component | Developer cheats; god mode, noclip, give item, teleport | +| 108 | `BPC_ErrorHandler` | Component | Error handler; crash logging, error display, recovery | +| 109 | `BPC_FPSCounter` | Component | FPS counter display; min/max/avg tracking | +| 110 | `BPC_LoadingScreen` | Component | Loading screen; progress bar, tips, background | +| 111 | `BPC_TutorialSystem` | Component | Tutorial system; contextual prompts, progression | +| 112 | `WBP_CreditsScreen` | Widget | Credits screen; scroll, skip, post-credit scene trigger | +| 113 | `WBP_DebugMenu` | Widget | Debug menu; state viewer, log, performance, cheats | +| 114 | `WBP_SplashScreen` | Widget | Splash screen; studio logo, engine logo, skip | + +**106 BPC_AnalyticsTracker:** Records gameplay events for telemetry: level starts/completes, deaths, item pickups, dialogue choices, playtime. Configurable event filtering. Stripped from shipping builds. + +**107 BPC_DevCheatManager:** Developer tools: god mode, noclip, infinite ammo, give item by tag, teleport to cursor, toggle HUD, slow motion. Only available in development builds. + +**108 BPC_ErrorHandler:** Global error handling: catches blueprint errors, logs to file, displays error toast (dev builds only). Graceful recovery from non-fatal errors. + +**109 BPC_FPSCounter:** Simple FPS display overlay with min/max/avg tracking. Toggle via debug menu or console command. + +**110 BPC_LoadingScreen:** Loading screen widget with progress bar, gameplay tips, background art. Manages level streaming progress display. + +**111 BPC_TutorialSystem:** Context-sensitive tutorial prompts. Triggered by gameplay events (first combat, first hide, first puzzle). Tracks which tutorials the player has seen. Supports dismiss/snooze. + +**112-114 Widgets:** Credits screen with scroll and post-credit scene trigger. Debug menu for development. Splash screen with studio/engine logos. + +--- + +# 14 — Data Assets (Systems 115-127, 129, 134-135) + +**Category Purpose:** These 16 systems define all Data Asset types used across the framework. Data Assets are the primary configuration mechanism — all content, rules, and settings live in these assets, never hardcoded in Blueprints. + +| # | Data Asset | Configures | +|---|-----------|-----------| +| 115 | `DA_AdaptationRule` | Difficulty adaptation rules (metric thresholds, responses) | +| 116 | `DA_AtmosphereProfile` | Atmosphere: audio ambience, lighting, fog, post-process per mood | +| 117 | `DA_BehaviourVariant` | AI behavior variant: attack patterns, patrol style, aggression | +| 118 | `DA_DataAssetArchitecture` | Overview document of all Data Asset types | +| 119 | `DA_EncounterData` | Encounter definitions: enemy groups, spawn rules, difficulty tier | +| 120 | `DA_EquipmentConfig` | Equipment/weapon stats: damage, fire rate, magazine, recoil | +| 121 | `DA_HapticProfile` | Haptic/force feedback patterns for controller | +| 122 | `DA_InteractionData` | Interaction definitions: prompt text, duration, icon, conditions | +| 123 | `DA_ObjectiveData` | Objective/quest: description, prerequisites, rewards, branching | +| 124 | `DA_PuzzleData` | Puzzle definitions: solution, steps, hints, rewards | +| 125 | `DA_RareEvent` | Rare event: weight, conditions, effects, cooldown | +| 126 | `DA_RoomMutation` | Room mutation: layout change, object swap, lighting change | +| 127 | `DA_ScareEvent` | Scare event: type, anticipation duration, payoff, recovery | +| 129 | `DA_InputMappingProfile` | Input mappings per platform (PC, Xbox, PS5) | +| 134 | `DA_AudioSettings` | Audio bus configs, volume defaults, ducking, pool limits | +| 135 | `DA_RoomAcousticPreset` | Room acoustics: 7 presets (Outdoor, SmallRoom, Cave, etc.) | + +**Pattern:** All Data Assets derive from `UPrimaryDataAsset`. They are pure data containers — no runtime logic. Designers edit these in the Content Browser; systems read them at runtime. This is the "No Hardcoded Names" principle in practice. + +--- + +# 15 — Enhanced Input System (System 128) + +| # | System | Asset Type | Role | +|---|--------|-----------|------| +| 128 | `SS_EnhancedInputManager` | Subsystem | Input manager; context switching, rebinding, platform profiles | + +**128 SS_EnhancedInputManager:** The sole authority for all input management. Handles Input Mapping Context push/pop with priority-based context switching. Coordinates input mode (game-only vs UI-only) with `SS_UIManager`. Manages key rebinding via `DA_InputMappingProfile`. Platform-specific bindings (PC keyboard/mouse, Xbox controller, PS5 controller). Gameplay systems query input state through this subsystem — never through raw Enhanced Input calls. + +**Context Priority Ladder:** Default(0) < Hiding(5) < WristwatchUI(10) < Inspection(20) < UI(100). Higher priority contexts override lower ones — UI blocks gameplay input. + +--- + +# 16 — State Management (Systems 130-131) + +| # | System | Asset Type | Role | +|---|--------|-----------|------| +| 130 | `BPC_StateManager` | Component | Central state authority; action gating, overlay, vital signs | +| 131 | `DA_StateGatingTable` | Data Asset | All state gating rules (37 action rules); designer-editable | + +**130 BPC_StateManager:** The **single source of truth** for player capability. Manages 42 exclusive action states and 18 overlay states. All systems query `IsActionPermitted(Tag)` instead of checking each other's states directly. This is the central decoupling mechanism — the StateManager knows what's allowed; no individual system needs to know about others. + +**131 DA_StateGatingTable:** A Data Asset containing all gating rules. Designers modify which actions are blocked during which states without touching Blueprints. For example: "Reloading blocks Sprint" or "Hiding blocks Interaction." + +--- + +*Developer Reference v1.0 — Categories 11-16 Systems. Companion to docs/blueprints/ specs.* diff --git a/docs/developer/INDEX.md b/docs/developer/INDEX.md new file mode 100644 index 0000000..8246b3a --- /dev/null +++ b/docs/developer/INDEX.md @@ -0,0 +1,193 @@ +# Developer Reference — UE5 Modular Game Framework + +**Version:** 1.0 | **Generated:** 2026-05-19 | **Files:** 14 (1 index + 2 overview + 10 category docs + 1 combined) + +This directory contains developer-facing reference documentation for every system in the framework. Unlike the blueprint spec files (which define *what* to build), these documents explain *how each system works internally* — the data flow, state machines, integration points, and design rationale. Use these when you need to understand a system's behavior to implement, debug, or extend it. + +## Who This Is For + +- **Blueprint implementers** turning `.md` specs into actual UE5 Blueprint assets +- **Debuggers** tracing why something doesn't work +- **Designers** needing to understand constraints before modifying Data Assets +- **New team members** learning the framework's internal logic + +## Directory Map + +``` +docs/developer/ +├── INDEX.md ← THIS FILE +├── architecture-overview.md ← Framework-wide architecture walkthrough +├── implementation-patterns.md ← Common UE5 Blueprint patterns used +│ +├── 01-core-foundation.md ← Foundation systems (systems 01-07) +├── 02-player-systems.md ← Player state & embodiment (systems 08-15) +├── 03-interaction-systems.md ← Interaction & world manipulation (systems 16-23) +├── 04-inventory-systems.md ← Inventory, items & collectibles (systems 24-34) +├── 05-saveload-systems.md ← Save/load, persistence, death loop (systems 35-43) +├── 06-ui-systems.md ← UI, menus & diegetic presentation (systems 44-57) +├── 07-narrative-systems.md ← Narrative, dialogue, objectives (systems 58-68) +├── 08-weapons-systems.md ← Weapons, equipment & damage (systems 69-79) +├── 09-ai-systems.md ← AI, perception & encounters (systems 80-88) +├── 10-adaptive-systems.md ← Adaptive environment & atmosphere (systems 89-101, 132-133) +└── 11-16-systems.md ← Meta, Settings, Polish, Data Assets, Input, State (systems 102-135) +``` + +## Quick Reference — Every System at a Glance + +| # | System | Category | Role | +|---|--------|----------|------| +| 01 | `GI_GameTagRegistry` | Foundation | Central GameplayTag → asset registry | +| 02 | `FL_GameUtilities` | Foundation | Shared utility functions (logging, math) | +| 03 | `I_InterfaceLibrary` | Foundation | All framework interfaces | +| 04 | `GI_GameFramework` | Foundation | Application kernel; owns subsystems | +| 05 | `GM_CoreGameMode` | Foundation | Spawns player, manages game rules | +| 06 | `GS_CoreGameState` | Foundation | Shared game state, phase tracker | +| 07 | `DA_ItemData` | Foundation | Base item data asset | +| 08 | `BPC_HealthSystem` | Player | Health, damage, death trigger | +| 09 | `BPC_StaminaSystem` | Player | Stamina pool, sprint drain, exhaustion | +| 10 | `BPC_StressSystem` | Player | Psychological stress tiers, hallucinations | +| 11 | `BPC_MovementStateSystem` | Player | Movement mode + posture, GASP liaison | +| 12 | `BPC_HidingSystem` | Player | Hide/peek/breath-hold, LOS checks | +| 13 | `BPC_EmbodimentSystem` | Player | First-person body, arm IK, overlays | +| 14 | `BPC_CameraStateLayer` | Player | Camera FOV/offset per state | +| 15 | `BPC_PlayerMetricsTracker` | Player | Player metrics: accuracy, deaths, ratios | +| 16 | `BPC_InteractionDetector` | Interaction | Raycast interaction detection | +| 17 | `I_HidingSpot` | Interaction | Interface for hideable objects | +| 18 | `BPC_DiegeticDisplay` | Interaction | In-world screens (wristwatch, monitors) | +| 19 | `BP_DoorActor` | Interaction | Physical door with state machine | +| 20 | `BP_PuzzleDeviceActor` | Interaction | Puzzle device base actor | +| 21 | `BPC_ContextualTraversalSystem` | Interaction | Vault/mantle/slide/squeeze/climb | +| 22 | `BPC_PhysicsDragSystem` | Interaction | Grab/drag/release physics objects | +| 23 | `BPC_UsableWorldObjectSystem` | Interaction | Generic world object use (levers, buttons) | +| 24 | `BPC_ContainerInventory` | Inventory | World container inventory | +| 25 | `BP_ItemPickup` | Inventory | Physical item pickup in world | +| 26 | `BPC_ActiveItemSystem` | Inventory | Quick-slot item management | +| 27 | `BPC_CollectibleTracker` | Inventory | Collectible tracking, set bonuses | +| 28 | `BPC_ConsumableSystem` | Inventory | Consumable use (health packs, syringes) | +| 29 | `BPC_DocumentArchiveSystem` | Inventory | Document/journal archive | +| 30 | `BPC_EquipmentSlotSystem` | Inventory | Equipment slots, equip/unequip | +| 31 | `BPC_InventorySystem` | Inventory | Core inventory grid | +| 32 | `BPC_ItemCombineSystem` | Inventory | Item combination crafting | +| 33 | `BPC_JournalSystem` | Inventory | Quest/objective journal | +| 34 | `BPC_KeyItemSystem` | Inventory | Key item tracking, use-on-target | +| 35 | `SS_SaveManager` | Save/Load | Save/load subsystem | +| 36 | `I_Persistable` | Save/Load | Persistence interface | +| 37 | `BP_Checkpoint` | Save/Load | Checkpoint actor | +| 38 | `BPC_AltDeathSpaceSystem` | Save/Load | Alternate death/void space | +| 39 | `BPC_DeathHandlingSystem` | Save/Load | Death orchestrator | +| 40 | `BPC_PersistentCorpseSystem` | Save/Load | Corpse persistence | +| 41 | `BPC_PersistentWorldStateRecorder` | Save/Load | World state change recording | +| 42 | `BPC_PlayerRespawnSystem` | Save/Load | Respawn logic | +| 43 | `BPC_RunHistoryTracker` | Save/Load | Run/session history | +| 44 | `SS_UIManager` | UI | UI subsystem, menu stack | +| 45 | `WBP_AccessibilityUI` | UI | Accessibility settings UI | +| 46 | `WBP_DiegeticHUDFrame` | UI | Diegetic in-world HUD frame | +| 47 | `WBP_HUDController` | UI | Root HUD widget | +| 48 | `WBP_InteractionPromptDisplay` | UI | Interaction prompt popup | +| 49 | `WBP_InventoryMenu` | UI | Inventory grid UI | +| 50 | `WBP_JournalDocumentViewer` | UI | Document/journal viewer | +| 51 | `WBP_MainMenu` | UI | Main menu | +| 52 | `WBP_MenuFlowController` | UI | Menu state machine | +| 53 | `WBP_NotificationToast` | UI | Toast notification | +| 54 | `WBP_ObjectiveDisplay` | UI | Active objective HUD element | +| 55 | `WBP_PauseMenu` | UI | Pause menu | +| 56 | `WBP_ScreenEffectController` | UI | Full-screen effects | +| 57 | `WBP_SettingsMenu` | UI | Settings menu | +| 58 | `BPC_NarrativeStateSystem` | Narrative | Narrative state machine | +| 59 | `BPC_ObjectiveSystem` | Narrative | Objective tracker | +| 60 | `BPC_DialoguePlaybackSystem` | Narrative | Dialogue playback | +| 61 | `BPC_DialogueChoiceSystem` | Narrative | Dialogue choices | +| 62 | `BPC_BranchingConsequenceSystem` | Narrative | Consequence execution | +| 63 | `BPC_TrialScenarioSystem` | Narrative | Timed trial/puzzle scenario | +| 64 | `BPC_CutsceneBridge` | Narrative | Cutscene bridge | +| 65 | `BPC_LoreUnlockSystem` | Narrative | Lore/journal unlock | +| 66 | `DA_NarrativeDataAssets` | Narrative | Narrative data assets | +| 67 | `BP_NarrativeTriggerVolume` | Narrative | Narrative trigger volume | +| 68 | `BPC_EndingAccumulator` | Narrative | Ending condition tracker | +| 69 | `BP_WeaponBase` | Weapons | Weapon base actor | +| 70 | `BPC_AmmoComponent` | Weapons | Ammo pool | +| 71 | `BPC_CombatFeedbackComponent` | Weapons | Combat feedback (hit markers) | +| 72 | `BPC_DamageReceptionSystem` | Weapons | Damage reception/resistance | +| 73 | `BPC_DeathCauseTracker` | Weapons | Death cause logging | +| 74 | `BPC_FirearmSystem` | Weapons | Firearm specialization | +| 75 | `BPC_HitReactionSystem` | Weapons | Hit reaction animations | +| 76 | `BPC_MeleeSystem` | Weapons | Melee weapon system | +| 77 | `BPC_RecoilSystem` | Weapons | Recoil pattern | +| 78 | `BPC_ReloadSystem` | Weapons | Reload system | +| 79 | `BPC_ShieldDefenseSystem` | Weapons | Shield defense | +| 80 | `BP_EnemyBase` | AI | Enemy base character | +| 81 | `BP_PatrolPath` | AI | Patrol path spline | +| 82 | `BPC_AlertSystem` | AI | AI alert states | +| 83 | `BPC_AIStateMachine` | AI | AI state machine | +| 84 | `AI_BaseAgentController` | AI | Base AI controller | +| 85 | `BB_AgentBoard` | AI | AI blackboard definition | +| 86 | `BPC_AIMemorySystem` | AI | AI memory/last known locations | +| 87 | `BPC_AIPerceptionSystem` | AI | AI perception (sight/hearing) | +| 88 | `BPC_BehaviourVariantSelector` | AI | Behavior variant selection | +| 89 | `BPC_DifficultyManager` | Adaptive | Dynamic difficulty scaling | +| 90 | `BPC_FearSystem` | Adaptive | Fear system (AI + player) | +| 91 | `BPC_PerformanceScaler` | Adaptive | Performance scaling (LOD) | +| 92 | `BPC_ProceduralEncounter` | Adaptive | Procedural encounter generation | +| 93 | `BPC_AdaptiveEnvironmentDirector` | Adaptive | Adaptive environment director | +| 94 | `BPC_AtmosphereStateController` | Adaptive | Atmosphere state (tone, tension) | +| 95 | `BPC_AudioAtmosphereController` | Adaptive | Audio atmosphere [DEPRECATED] | +| 96 | `BPC_LightEventController` | Adaptive | Light events (flicker/strobe) | +| 97 | `BPC_MemoryDriftSystem` | Adaptive | Memory drift distortions | +| 98 | `BPC_PacingDirector` | Adaptive | Pacing director | +| 99 | `BPC_PlaystyleClassifier` | Adaptive | Playstyle classification | +| 100 | `BPC_RareEventSystem` | Adaptive | Rare event system | +| 101 | `BPC_ScareEventSystem` | Adaptive | Scare event system | +| 102 | `BPC_ProgressStatTracker` | Meta | Progress statistics | +| 103 | `SS_AchievementSystem` | Meta | Achievement subsystem | +| 104 | `BPC_AccessibilitySettings` | Settings | Accessibility settings | +| 105 | `SS_SettingsSystem` | Settings | Persistent settings subsystem | +| 106 | `BPC_AnalyticsTracker` | Polish | Analytics/telemetry | +| 107 | `BPC_DevCheatManager` | Polish | Developer cheats | +| 108 | `BPC_ErrorHandler` | Polish | Error/crash handling | +| 109 | `BPC_FPSCounter` | Polish | FPS counter | +| 110 | `BPC_LoadingScreen` | Polish | Loading screen | +| 111 | `BPC_TutorialSystem` | Polish | Tutorial system | +| 112 | `WBP_CreditsScreen` | Polish | Credits screen | +| 113 | `WBP_DebugMenu` | Polish | Debug menu | +| 114 | `WBP_SplashScreen` | Polish | Splash screen | +| 115 | `DA_AdaptationRule` | Data Assets | Difficulty adaptation rules | +| 116 | `DA_AtmosphereProfile` | Data Assets | Atmosphere profile (audio/light/FX) | +| 117 | `DA_BehaviourVariant` | Data Assets | AI behavior variant | +| 118 | `DA_DataAssetArchitecture` | Data Assets | Data asset architecture overview | +| 119 | `DA_EncounterData` | Data Assets | Encounter definition | +| 120 | `DA_EquipmentConfig` | Data Assets | Equipment configuration | +| 121 | `DA_HapticProfile` | Data Assets | Haptic feedback profile | +| 122 | `DA_InteractionData` | Data Assets | Interaction definition | +| 123 | `DA_ObjectiveData` | Data Assets | Objective/quest data | +| 124 | `DA_PuzzleData` | Data Assets | Puzzle definition | +| 125 | `DA_RareEvent` | Data Assets | Rare event definition | +| 126 | `DA_RoomMutation` | Data Assets | Room mutation definition | +| 127 | `DA_ScareEvent` | Data Assets | Scare event definition | +| 128 | `SS_EnhancedInputManager` | Input | Enhanced Input manager | +| 129 | `DA_InputMappingProfile` | Data Assets | Input mapping profile per platform | +| 130 | `BPC_StateManager` | State | Central state authority | +| 131 | `DA_StateGatingTable` | State | State gating rules | +| 132 | `SS_AudioManager` | Adaptive | Audio subsystem (MetaSounds) | +| 133 | `BP_RoomAudioZone` | Adaptive | Room audio zone trigger | +| 134 | `DA_AudioSettings` | Data Assets | Audio bus/settings config | +| 135 | `DA_RoomAcousticPreset` | Data Assets | Room acoustic profile | + +## How to Use These Docs + +1. **New to the framework?** Start with [`architecture-overview.md`](architecture-overview.md) to understand the big picture. +2. **Implementing a system?** Find it in the quick reference above, then read its category document. +3. **Debugging?** Each category doc includes a data flow section showing how data moves between systems. +4. **Need implementation patterns?** See [`implementation-patterns.md`](implementation-patterns.md) for common UE5 Blueprint patterns. + +## Relationship to Spec Files + +| Aspect | Blueprint Spec (`docs/blueprints/`) | Developer Reference (`docs/developer/`) | +|--------|--------------------------------------|----------------------------------------| +| **Purpose** | Define what to build (contract) | Explain how it works (understanding) | +| **Audience** | Implementers following a spec | Anyone needing to understand internals | +| **Content** | Enums, structs, variables, functions | Data flow, state machines, design rationale | +| **Updates** | When design changes | When implementation details change | + +--- + +*Developer Reference Index v1.0 — Companion to the Blueprint Spec system. Update both together.* diff --git a/docs/developer/architecture-overview.md b/docs/developer/architecture-overview.md new file mode 100644 index 0000000..2f12825 --- /dev/null +++ b/docs/developer/architecture-overview.md @@ -0,0 +1,156 @@ +# Architecture Overview — UE5 Modular Game Framework + +**Purpose:** A high-level walkthrough of the entire framework architecture — the big picture before diving into individual system docs. Read this first if you're new to the framework. + +--- + +## The Core Idea + +This framework provides a complete, modular, Blueprint-only game architecture for Unreal Engine 5.5-5.7 built on 14 architectural principles. Every system is a self-contained Blueprint Component or Actor that communicates through interfaces, event dispatchers, and GameplayTags — never through direct hard references unless they're tightly coupled by design. + +## The Four Communication Methods + +``` +TIGHTLY COUPLED │ LOOSELY COUPLED +(use sparingly) │ (preferred) + │ +Direct Reference │ Interface Calls + GM → GS_CoreGameState │ I_Interactable, I_Damageable + Player → Components │ Caller knows interface, not class + │ + │ Event Dispatchers + │ OnHealthChanged, OnDeath + │ Fire-and-forget, one-to-many + │ + │ GameplayTag + Subsystem Lookup + │ GI_GameFramework.GetSubsystem(Tag) + │ Fully decoupled, globally accessible +``` + +--- + +## System Layers (Bottom-Up) + +``` +┌────────────────────────────────────────────────────────────────┐ +│ LAYER 8: POLISH & META │ +│ Tutorials, Loading, Credits, Analytics, Achievements │ +├────────────────────────────────────────────────────────────────┤ +│ LAYER 7: ADAPTIVE │ +│ Difficulty, Atmosphere, Pacing, Scares, Audio (MetaSounds) │ +├────────────────────────────────────────────────────────────────┤ +│ LAYER 6: AI │ +│ Enemy Behavior, Perception, Memory, Patrol, Combat │ +├────────────────────────────────────────────────────────────────┤ +│ LAYER 5: COMBAT │ +│ Weapons, Damage, Ammo, Recoil, Reload, Melee, Defense │ +├────────────────────────────────────────────────────────────────┤ +│ LAYER 4: NARRATIVE & UI │ +│ Dialogue, Objectives, Cutscenes, HUD, Menus, Inventory UI │ +├────────────────────────────────────────────────────────────────┤ +│ LAYER 3: INTERACTION & INVENTORY │ +│ Doors, Puzzles, Pickups, Inventory, Containers, Equipment │ +├────────────────────────────────────────────────────────────────┤ +│ LAYER 2: PLAYER SIMULATION │ +│ Health, Stamina, Stress, Movement, Hiding, Camera, Body │ +├────────────────────────────────────────────────────────────────┤ +│ LAYER 1: FOUNDATION │ +│ GameInstance, GameMode, GameState, Interfaces, Tags, Items │ +└────────────────────────────────────────────────────────────────┘ +``` + +Higher layers depend on lower layers. Foundation has no dependencies. Polish/Meta can observe everything. + +--- + +## Key Architectural Decisions + +### 1. Central State Authority (BPC_StateManager) +Instead of System A checking "is System B in state X?", all systems query `BPC_StateManager.IsActionPermitted(Tag)`. The StateManager maintains 42 exclusive action states and 18 overlay states. Gating rules are in `DA_StateGatingTable` — designers modify rules without touching Blueprints. + +### 2. Interface-First Communication +All cross-system communication uses Blueprint Interfaces (`I_Interactable`, `I_Damageable`, `I_Persistable`, etc.). The caller queries "does this actor implement this interface?" and calls the interface function — never casts to a concrete class. + +### 3. Data-Driven Everything +No hardcoded values. Every configuration lives in Data Assets (`DA_ItemData`, `DA_EquipmentConfig`, `DA_AtmosphereProfile`). Designers edit Data Assets in the Content Browser; Blueprints read from them at runtime. + +### 4. UI Reads, Never Writes +Widgets display data from gameplay systems but never own game state. They bind to event dispatchers (`OnHealthChanged` → update health bar) and call functions (`UseItem()`) — but never store authoritative data. + +### 5. GameplayTags for State, Not Booleans +No `bIsDead`, `bIsHidden`, `bIsInCombat` booleans. Everything is a GameplayTag compared via `HasTag()` / `MatchesTag()`. Tags are documented in `GI_GameTagRegistry`. + +### 6. Single Audio Entry Point (SS_AudioManager) +Never call `UGameplayStatics::PlaySound*` directly. All audio routes through `SS_AudioManager` which manages 4 MetaSound buses (SFX, Ambience, Music, Dialogue → Master Bus). Room acoustics switch automatically via `BP_RoomAudioZone` triggers. + +### 7. Enhanced Input Manager +All input goes through `SS_EnhancedInputManager`. Context switching uses priority-based stack. Key rebinding is platform-aware via `DA_InputMappingProfile`. + +### 8. Force Stack for State Overrides +Death, cutscenes, void space push state onto a stack. `RestorePreviousState()` pops back — the player returns to exactly their previous state after a forced interruption. + +--- + +## Data Flow: A Typical Interaction + +``` +Player looks at a locked door + → BPC_InteractionDetector sphere trace hits BP_DoorActor + → Detector checks: I_Interactable? ✓ Priority? High ✓ Distance? 150cm ✓ + → Dispatches OnTargetFound → WBP_InteractionPromptDisplay shows "Locked Door [E]" + +Player presses E + → Detector calls I_Interactable.ExecuteInteraction on door + → BP_DoorActor.Interact_Implementation: + → CurrentState = Locked + → TryUnlockWithItem() queries BPC_InventorySystem.HasItem(RequiredKeyTag) + → Player has key? Yes → RemoveItemOnUse = true → consume key + → UnlockDoor() → Play unlock sound via SS_AudioManager + → TryOpen() → Set state Opening → Play open animation + → OnOpenComplete → Set state Open → Broadcast OnDoorOpened + → AI Perception hears door sound → BPC_AlertSystem becomes Suspicious + → BPC_PersistentWorldStateRecorder logs door state change for save + → WBP_NotificationToast shows "Door Unlocked" +``` + +All this happens through interfaces, dispatchers, and the audio subsystem — no system directly references another's concrete class. + +--- + +## Build-Order Rationale + +The 16 build phases follow dependency order: +1. **Foundation + Input** (01-core, 15-input) — zero dependencies, everything else builds on these +2. **Player Core** (02-player) — depends on foundation +3. **Interaction** (03-interaction) — depends on player + foundation +4. **Inventory** (04-inventory) — depends on interaction + player +5. **Save/Load** (05-saveload) — depends on inventory + player + interaction +6. **UI** (06-ui) — depends on everything below +7. **Narrative** (07-narrative) — depends on UI + save +8. **Weapons** (08-weapons) — depends on inventory + player + UI +9. **AI** (09-ai) — depends on player (for detection) + weapons +10. **Adaptive** (10-adaptive) — reads everything +11. **Data Assets** (14-data-assets) — referenced by all, created when content is stable +12-16. **Meta, Settings, Polish, State, Audio** — layered on top + +--- + +## System Count by Type + +| Type | Count | Examples | +|------|-------|----------| +| `BPC_` Blueprint Components | 80 | HealthSystem, InventorySystem, AIPerception | +| `BP_` Blueprint Actors | 11 | DoorActor, WeaponBase, EnemyBase | +| `WBP_` Widget Blueprints | 14 | HUDController, InventoryMenu, MainMenu | +| `DA_` Data Assets | 18 | ItemData, EquipmentConfig, AtmosphereProfile | +| `SS_` GameInstance Subsystems | 7 | SaveManager, UIManager, AudioManager | +| `GI_` Game Instances | 2 | GameFramework, GameTagRegistry | +| `I_` Interfaces | 3 | InterfaceLibrary, HidingSpot, Persistable | +| `GM_` GameMode, `GS_` GameState | 2 | CoreGameMode, CoreGameState | +| `FL_` Function Library | 1 | GameUtilities | +| `AI_` Controller, `BB_` Blackboard | 2 | BaseAgentController, AgentBoard | +| **TOTAL** | **140** | | + +--- + +*Architecture Overview v1.0 — Start here before reading category-specific developer docs.* diff --git a/docs/developer/implementation-patterns.md b/docs/developer/implementation-patterns.md new file mode 100644 index 0000000..43dab93 --- /dev/null +++ b/docs/developer/implementation-patterns.md @@ -0,0 +1,295 @@ +# Common UE5 Blueprint Implementation Patterns + +**Purpose:** This document catalogs the recurring Blueprint implementation patterns used throughout the framework. When implementing a blueprint spec into an actual UE5 Blueprint asset, reference these patterns for consistent, correct implementation. + +--- + +## Pattern 1: Interface-First Communication + +**When to Use:** Any time System A needs to call a function on System B without knowing System B's concrete class. + +**Blueprint Implementation:** +``` +[System A Blueprint] + TargetActor = GetOwner() // or any actor reference + bImplements = DoesImplementInterface(TargetActor, I_Interactable) + Branch(bImplements) + True → Call I_Interactable::ExecuteInteraction(TargetActor, Self) + False → Return / Log Warning +``` + +**Framework Examples:** `BPC_InteractionDetector` → `I_Interactable`, `SS_SaveManager` → `I_Persistable`, Weapons → `I_Damageable` + +**Key Rules:** +- Always check `DoesImplementInterface` before calling +- Never cast to concrete class — use the interface +- Default return values (false/0.0f/empty) handle missing implementations gracefully + +--- + +## Pattern 2: Event Dispatcher Binding (UI Display) + +**When to Use:** Any system that needs to react to state changes in another system. + +**Blueprint Implementation:** +``` +[HUD Widget Blueprint — Event Construct] + PlayerPawn = GetOwningPlayerPawn() + HealthComponent = PlayerPawn.FindComponentByClass(BPC_HealthSystem) + Bind Event to HealthComponent.OnHealthChanged + → Custom Event: OnHealthChangedHandler(OldHealth, NewHealth, Delta) + → ProgressBar.SetPercent(NewHealth / MaxHealth) + +[HUD Widget Blueprint — Event Destruct] + Unbind Event from HealthComponent.OnHealthChanged +``` + +**Framework Examples:** `WBP_HUDController` binds to `OnHealthChanged`, `GS_CoreGameState` binds to `OnGamePhaseChanged` + +**Key Rules:** +- Always unbind in Event Destruct to prevent dangling references +- Never use Event Tick for polling — always bind to dispatchers +- Normalize values (0.0-1.0) before sending to UI for smooth interpolation + +--- + +## Pattern 3: Subsystem Lookup (Global Service Resolution) + +**When to Use:** Any system that needs a global service (save, audio, UI, input). + +**Blueprint Implementation:** +``` +[Any Blueprint] + GameInstance = GetGameInstance() + Cast to GI_GameFramework → Framework + SubsystemRef = Framework.GetSubsystem(Tag) // or FL_GameUtilities.GetSubsystemSafe() + IsValid(SubsystemRef)? + True → Call Subsystem function + False → Log warning, return gracefully +``` + +**Framework Examples:** Any system calling `SS_SaveManager.Save()`, `SS_AudioManager.PlaySound()` + +**Key Rules:** +- Always use `FL_GameUtilities.GetSubsystemSafe()` — returns null instead of crashing +- Check validity of the returned subsystem before calling functions +- Subsystems are singletons — no need to cache, just look up when needed + +--- + +## Pattern 4: Data Asset Configuration + +**When to Use:** Any system that needs configurable data (item stats, weapon balance, encounter rules). + +**Blueprint Implementation:** +``` +[Component Configuration] + Variable: ItemData + Type: DA_ItemData (Object Reference → Primary Data Asset) + Instance Editable: ✓ + Expose on Spawn: ✓ + Category: "Config" + +[Runtime Usage] + ItemData.ItemTag → GameplayTag + ItemData.DisplayName → Text for UI + ItemData.Weight → Float for carry capacity + ItemData.StackLimit → Integer for stack management +``` + +**Framework Examples:** All systems that reference `DA_*` Data Assets + +**Key Rules:** +- Data Assets are read-only at runtime — never modify them +- Use Soft Object References for async loading large Data Asset collections +- Register Data Assets with Primary Asset Manager for streaming support + +--- + +## Pattern 5: Timer-Based Ticks (Not Event Tick) + +**When to Use:** Any repeating operation that doesn't need per-frame precision (regen, decay, scan). + +**Blueprint Implementation:** +``` +[BeginPlay] + Set Timer by Event + Event: RegenTick + Time: 0.1 (seconds) + Looping: ✓ + +[Custom Event: RegenTick] + CurrentStamina = Min(MaxStamina, CurrentStamina + RegenRate * 0.1) + Fire OnStaminaChanged + If CurrentStamina >= MaxStamina: + Clear Timer (RegenTimerHandle) +``` + +**Framework Examples:** `BPC_HealthSystem` regen, `BPC_StaminaSystem` drain, `BPC_StressSystem` decay, `BPC_InteractionDetector` scan + +**Key Rules:** +- Use 0.1s intervals for smooth but performant updates +- Store timer handles and clear them on component destroy +- Never use Event Tick unless absolutely necessary (physics, camera) + +--- + +## Pattern 6: State Machine with Enum Switch + +**When to Use:** Any system that has distinct, mutually exclusive states. + +**Blueprint Implementation:** +``` +[Function: SetState(NewState)] + OldState = CurrentState + Switch on NewState: + Case StateA: + // StateA setup logic + Case StateB: + // StateB setup logic + Case StateC: + // StateC setup logic + CurrentState = NewState + Fire OnStateChanged(OldState, NewState) +``` + +**Framework Examples:** `BP_DoorActor` (Closed/Opening/Open/Closing/Locked/Barricaded), `BP_WeaponBase` (Holstered/Equipping/Ready/Firing/Reloading), `BPC_AIStateMachine` (Patrol/Search/Combat/Flee) + +**Key Rules:** +- Store previous state for transition detection +- Fire dispatcher on every state change +- Block operations that don't make sense in current state + +--- + +## Pattern 7: Validation Before Action + +**When to Use:** Any function that modifies state and can fail. + +**Blueprint Implementation:** +``` +[Function: AddItem(ItemData, Quantity)] + // Validate + FreeSlot = FindFreeSlot() + If FreeSlot < 0: + Fire OnInventoryFull + Return E_InventoryOperationResult::InventoryFull + + OverWeight = CheckWeight(ItemData.Weight * Quantity) + If OverWeight: + Return E_InventoryOperationResult::WeightCapacityExceeded + + // Execute + SetSlot(FreeSlot, ItemData, Quantity) + RecalculateWeight() + Fire OnItemAdded + Return E_InventoryOperationResult::Success +``` + +**Framework Examples:** `BPC_InventorySystem.AddItem`, `BPC_StaminaSystem.DrainStamina`, `BPC_HidingSystem.EnterHideSpot` + +**Key Rules:** +- Validate ALL conditions before making ANY changes +- Return descriptive result codes, not just true/false +- Fire error dispatchers with human-readable failure reasons + +--- + +## Pattern 8: RepNotify for Networked State + +**When to Use:** Any replicated variable that needs local effects when changed remotely. + +**Blueprint Implementation:** +``` +[Variable] + CurrentHealth: Float + Replication: RepNotify + OnRep Function: OnRep_CurrentHealth + +[Function: OnRep_CurrentHealth] + Fire OnHealthChanged (with cached old value) + // This runs on clients when server changes the value + // Local effects (UI update, effects) fire here +``` + +**Framework Examples:** All replicated variables in `GS_CoreGameState`, `BPC_InventorySystem.Slots` + +**Key Rules:** +- RepNotify fires on clients, NOT on server (server handles effects in the setter) +- Cache old value before replication to use in OnRep +- Single-player games can ignore replication entirely — framework is SP-first + +--- + +## Pattern 9: Tag-Driven Filtering + +**When to Use:** Any time you need to filter or categorize (items, interactions, states, narrative). + +**Blueprint Implementation:** +``` +[Function: HasTag(Actor, Tag)] + TagContainer = Actor.GetGameplayTagContainer() // or via interface + Return TagContainer.HasTag(Tag) + +[Function: FindItemsByTag(Tag)] + FilteredArray = [] + For Each Slot in Inventory.Slots: + If Slot.Entry.ItemData.ItemTag.MatchesTag(Tag): + Add to FilteredArray + Return FilteredArray +``` + +**Framework Examples:** Every system — tags replace booleans and strings everywhere + +**Key Rules:** +- Framework tags use `Framework.` prefix; project tags use `Game.` prefix +- All tags documented in `GI_GameTagRegistry` +- Never use `FName` or `FString` for state — always GameplayTags + +--- + +## Pattern 10: Linked Actor Notifications + +**When to Use:** When one actor's state change should trigger other actors (door opens → lights turn on). + +**Blueprint Implementation:** +``` +[Variable: LinkedActors] + Type: Array of Actor + Instance Editable: ✓ + Category: "Connections" + +[On Door Opened] + For Each LinkedActor in LinkedActors: + bImplements = DoesImplementInterface(LinkedActor, I_Toggleable) + If bImplements: + Call I_Toggleable::SetState(LinkedActor, True) +``` + +**Framework Examples:** `BP_DoorActor` notifying lights/traps, `BP_PuzzleDeviceActor` unlocking connected doors + +**Key Rules:** +- Use interfaces (I_Toggleable, I_Adjustable) for linked actor communication +- Designer sets LinkedActors in editor — no code changes needed +- Order of linked actor notification may matter — test edge cases + +--- + +## Quick Reference: Which Pattern for What? + +| Need | Pattern | +|------|---------| +| Call a function on unknown actor type | Pattern 1: Interface-First | +| React to another system's state change | Pattern 2: Dispatcher Binding | +| Access global services (save, audio, UI) | Pattern 3: Subsystem Lookup | +| Configure system behavior without code | Pattern 4: Data Asset | +| Repeating operation at interval | Pattern 5: Timer-Based Tick | +| Manage mutually exclusive states | Pattern 6: State Machine | +| Operation that can fail | Pattern 7: Validation Before Action | +| Network state synchronization | Pattern 8: RepNotify | +| Filter/categorize by type | Pattern 9: Tag-Driven Filtering | +| Chain reactions between actors | Pattern 10: Linked Actor Notifications | + +--- + +*Implementation Patterns v1.0 — Reference when building blueprint specs into UE5 Blueprint assets.*