add blueprints

This commit is contained in:
Lefteris Notas
2026-05-19 13:22:27 +03:00
parent f71bc678b2
commit 411edea8ce
138 changed files with 23330 additions and 0 deletions

View File

@@ -0,0 +1,189 @@
# GI_GameTagRegistry — Blueprint Specification
> **Asset Type:** Data Asset (derives from `UPrimaryDataAsset`)
> **UE Version:** 5.55.7
> **Category:** 01-Core / Foundation
> **Build Phase:** Phase 0 — Item 1
> **Dependencies:** None (this is the first system)
---
## 1. Purpose
Centralises every `GameplayTag` namespace used across the framework in a single asset. All other systems reference tags from this registry — never raw strings, never `FName` comparisons, never hardcoded booleans for state.
---
## 2. Class Settings
| Setting | Value |
|---------|-------|
| **Parent Class** | `UPrimaryDataAsset` |
| **Blueprint Type** | Data Asset |
| **Asset Path** | `/Game/Framework/Core/DA_GameTagRegistry` |
| **Is Abstract** | No |
---
## 3. Enums
None. This Data Asset uses only **Gameplay Tags** as the canonical state identifiers. No enums are defined here.
---
## 4. Structs
None. The registry is a flat collection of tag declarations.
---
## 5. Variables
| Name | Type | Category | Instance Editable | Description |
|------|------|----------|-------------------|-------------|
| `TagNamespace` | `FText` | Documentation | Yes | Human-readable description of the tag namespace (e.g. "Player.State") |
| `bIsFrameworkTag` | `bool` | Documentation | Yes | `true` for framework-defined tags, `false` for project-specific overrides |
**NOTE:** The tag definitions themselves live in the project's `DefaultGameplayTags.ini` file (or via the **Project Settings → Gameplay Tags** editor). This asset provides a centralised **documentation anchor** for those tags. The Blueprint graph does not hold tag data.
---
## 6. Functions
### 6.1 Blueprint Pure Functions
| Name | Inputs | Outputs | Category | Description |
|------|--------|---------|----------|-------------|
| `GetAllRegisteredTags` | — | `Array<FGameplayTag>` | Query | Returns all tags defined in this registry (reads from the project's tag table) |
| `GetTagDisplayName` | `Tag: FGameplayTag` | `FText` | Query | Returns the human-readable display name from the tag table |
| `ValidateTag` | `Tag: FGameplayTag` | `bool` | Validation | Returns `true` if the tag exists in the project's registered tag table |
### 6.2 Blueprint Callable Functions
| Name | Inputs | Outputs | Category | Description |
|------|--------|---------|----------|-------------|
| `LogAllTags` | — | — | Debug | Prints all registered tags to the output log (Editor-only) |
| `ExportTagNamespace` | `NamespacePrefix: FString` | `FString` | Tooling | Exports all tags matching a namespace prefix as a formatted string (for documentation generation) |
---
## 7. Event Dispatchers
None. This Data Asset is passive — it has no runtime events.
---
## 8. Overridden Events
| Event | Description |
|-------|-------------|
| `OnAssetLoaded` | Logs a validation warning if no Gameplay Tags are registered in the project |
| `PreSaveGameplayTags` | Ensures the tag table is synchronised with the asset's documented namespaces |
---
## 9. Blueprint Graph Logic
### 9.1 Initialisation Flow
```
[OnAssetLoaded]
└─► Call GetAllRegisteredTags()
└─► Length == 0?
├─► Yes → Print Warning: "No Gameplay Tags registered! /Game/Framework/Core/DA_GameTagRegistry is empty."
└─► No → Log: "N tags registered."
```
### 9.2 Validation Function Logic (ValidateTag)
```
[ValidateTag(Tag)]
└─► Use GameplayTag::RequestGameplayTag(Tag.TagName)
└─► IsValid?
├─► Yes → return true
└─► No → Print Warning: "Invalid Tag: {Tag}" → return false
```
---
## 10. Tag Namespace Reference (Framework Canonical)
All framework-level tags are defined in `DefaultGameplayTags.ini`. The following namespaces are **reserved and documented** by this asset:
```
Player.State.Alive
Player.State.Dead
Player.State.Hidden
Player.State.Interacting
Player.Stress.Low / Mid / High / Critical
Player.Posture.Standing / Crouching / Prone / Vaulting
Interaction.Type.Pickup / Door / Drawer / Container / Inspect / Climb / Hide / Use / Combine
Interaction.Context.Requires.Key / Requires.Item / Locked / Disabled
Item.Type.Weapon / Consumable / KeyItem / Document / Collectible / Ammo / Tool
Item.Slot.PrimaryWeapon / SecondaryWeapon / Flashlight / Shield / Active
Narrative.Flag.* ← game-specific flags
Narrative.Phase.* ← story chapters / acts
Narrative.Choice.* ← choice consequence tags
Narrative.Ending.* ← ending conditions
Objective.Status.Active / Complete / Failed / Hidden
AI.Alert.None / Suspicious / Alerted / Engaged
AI.Archetype.Patrol / Ambush / Stalker / Passive
Save.Type.Checkpoint / HardSave / AutoSave
Achievement.* ← per-achievement tags
Environment.Atmosphere.* ← atmosphere state tags
Environment.Scare.* ← scare event tags
DeathSpace.Active ← triggers alt death space layer
```
**Usage Rule:** All systems must add the prefix `Framework.` to framework tags in code comments. Project-specific tags use `Game.` prefix. Example: `Framework.Interaction.Type.Pickup` vs `Game.Narrative.Flag.BasementDoorOpened`.
---
## 11. Communication Matrix
| Target System | Method | Direction | Data |
|---------------|--------|-----------|------|
| All other systems | `GameplayTag` comparisons | Read-only | Framework-defined tag values |
This asset does not talk to other systems directly. All communication is passive — other systems read tag values from the project's tag table.
---
## 12. Validation Checklist
- [ ] All namespace prefixes documented in the Data Asset's `TagNamespace` text field
- [ ] `bIsFrameworkTag` set to `true` for framework namespaces
- [ ] At least one project-specific tag exists (e.g. `Game.Narrative.Flag.PrologueComplete`) to validate the workflow
- [ ] `DefaultGameplayTags.ini` contains ALL documented tags
- [ ] No duplicate tag names across namespaces
- [ ] No raw string comparisons exist in any other system (all must use `HasTag` / `MatchesTag`)
---
## 13. Reuse Notes
- The `Game.` namespace is reserved for **project-specific** tags and is empty in the framework distribution.
- To add new tags: edit `DefaultGameplayTags.ini` or use the **Gameplay Tags** editor under **Project Settings**.
- The Data Asset is purely documentary — the real tag data lives in the project's tag table. This file exists so systems have a single place to look up "what tags exist in the framework" without reading the `.ini` file directly.
---
## 14. Blueprint Implementation Steps (for Blueprint Agent)
1. Create a new **Data Asset** class.
2. Parent: `UPrimaryDataAsset`
3. Name: `DA_GameTagRegistry`
4. Save to: `/Game/Framework/Core/DA_GameTagRegistry`
5. Add variables `TagNamespace` (FText) and `bIsFrameworkTag` (bool).
6. Implement the functions listed in Section 6 as Blueprint Callable / Pure nodes.
7. Document all tag namespaces from Section 10 in the asset's description.
8. Save and run the validation test.

View File

@@ -0,0 +1,140 @@
# FL_GameUtilities — Blueprint Function Library
## Asset Details
| Property | Value |
|----------|-------|
| **Class** | [`FL_GameUtilities`] |
| **Parent** | [`BlueprintFunctionLibrary`] |
| **Folder** | [`Framework/Core/`] |
| **Categorization** | [Core\Framework] |
## Purpose
A static Blueprint Function Library providing common utility functions available everywhere in the project without needing an object reference. Every Blueprint, component, widget, and AI asset can call these functions directly from the context menu.
## Does NOT Handle
- Game logic or state management
- Actor spawning or lifecycle
- Data asset lookups (those belong to the specific system)
- Any operation that requires a persistent reference or tick
## Structs
No structs are defined in this library. All input/output types are native Blueprint types or interface-derived.
## Enums
No enums are defined in this library.
## Variables
This is a pure Function Library. It has **no variables, no event dispatchers, no tick**. All functions are static and context-free (with the exception of `WorldContextObject` for world-dependent operations).
## Functions
### Utility — Null-Safe Subsystem Retrieval
| Function | Category | Inputs | Outputs | Description |
|----------|----------|--------|---------|-------------|
| [`GetSubsystemSafe`] | Utility\Subsystems | `WorldContextObject: Object`, `SubsystemClass: Class` | `Subsystem: Object` | Null-safe subsystem retrieval. Returns `None` instead of crashing if the subsystem doesn't exist. |
| [`GetGameFramework`] | Utility\Subsystems | `WorldContextObject: Object` | `GameInstance: GI_GameFramework Object` | Typed cast to [`GI_GameFramework`](04_GI_GameFramework.md). Returns `None` if cast fails. Includes error log. |
| [`GetPlayerController`] | Utility\Subsystems | `WorldContextObject: Object` | `Controller: PC_CoreController Object` | Typed cast to [`PC_CoreController`](02-player/01_PC_CoreController.md). Returns `None` if cast fails. Includes error log. |
### Actor Utility
| Function | Category | Inputs | Outputs | Description |
|----------|----------|--------|---------|-------------|
| [`FindComponentByInterface`] | Actor\Components | `TargetActor: Actor`, `InterfaceClass: Interface` | `Component: ActorComponent` | Returns the first component on the given actor that implements the specified interface. Returns `None` if none found. |
| [`FindNearestActorWithTag`] | Actor\Spatial | `Origin: Vector`, `Radius: Float`, `Tag: GameplayTag`, `ActorsToIgnore: Array Actor` | `NearestActor: Actor`, `Distance: Float` | Scans all actors within radius for those with the given gameplay tag. Returns the closest one. |
### Math Utilities
| Function | Category | Inputs | Outputs | Description |
|----------|----------|--------|---------|-------------|
| [`RemapFloat`] | Math\Float | `Value: Float`, `InMin: Float`, `InMax: Float`, `OutMin: Float`, `OutMax: Float` | `Result: Float` | Linear remap from input range to output range. Clamped to output range. |
| [`LerpClamped`] | Math\Float | `A: Float`, `B: Float`, `Alpha: Float` | `Result: Float` | Lerp with alpha clamped 0-1. |
| [`VectorToAngle2D`] | Math\Vector | `Direction: Vector` | `Angle: Float (Degrees)` | Converts a 2D direction vector to an angle in degrees (0-360). |
| [`AngleDifference`] | Math\Float | `AngleA: Float`, `AngleB: Float` | `Difference: Float` | Shortest signed angle between two angles. |
### Gameplay Tag Utilities
| Function | Category | Inputs | Outputs | Description |
|----------|----------|--------|---------|-------------|
| [`HasGameplayTag`] | GameplayTags\Query | `TargetActor: Actor`, `Tag: GameplayTag` | `bHasTag: Bool` | Safe check if an actor's gameplay tag container includes the specified tag. Returns false if actor has no tag container. |
| [`AddGameplayTagToActor`] | GameplayTags\Modify | `TargetActor: Actor`, `Tag: GameplayTag` | — | Adds a gameplay tag to the actor's tag container if it implements the interface. Logs warning if missing. |
| [`RemoveGameplayTagFromActor`] | GameplayTags\Modify | `TargetActor: Actor`, `Tag: GameplayTag` | — | Removes a gameplay tag from the actor's tag container. |
| [`MakeTagFromString`] | GameplayTags\Conversion | `TagString: String` | `Tag: GameplayTag` | Converts a string to a GameplayTag. Returns `None` if the tag doesn't exist in the tag table. |
| [`TagContainerHasAny`] | GameplayTags\Query | `Container: GameplayTagContainer`, `TagsToCheck: GameplayTagContainer` | `bHasAny: Bool` | OR query: true if container has any of the specified tags. |
### String & Text Formatting
| Function | Category | Inputs | Outputs | Description |
|----------|----------|--------|---------|-------------|
| [`FormatTime`] | Text\Formatting | `TotalSeconds: Float` | `FormattedText: Text` | Converts seconds to "HH:MM:SS" or "MM:SS" display format. |
| [`Pluralise`] | Text\Formatting | `Count: Integer`, `Singular: Text`, `Plural: Text` | `Result: Text` | Returns singular or plural form based on count. |
| [`OrdinalSuffix`] | Text\Formatting | `Number: Integer` | `Suffix: String` | Returns "st", "nd", "rd", or "th" for a given number. |
| [`TruncateText`] | Text\Formatting | `Input: Text`, `MaxChars: Integer` | `Output: Text`, `bTruncated: Bool` | Truncates text with "..." if exceeding max length. |
### Screen & Viewport Utilities
| Function | Category | Inputs | Outputs | Description |
|----------|----------|--------|---------|-------------|
| [`WorldToScreenSafe`] | Screen\Conversion | `WorldContext: Object`, `WorldLocation: Vector` | `ScreenPosition: Vector2D`, `bIsOnScreen: Bool` | Projects world location to screen coordinates. Returns false if behind camera or off-screen. |
| [`ClampToViewport`] | Screen\Conversion | `WidgetPosition: Vector2D`, `Padding: Float` | `ClampedPosition: Vector2D` | Clamps a widget position to stay within the viewport bounds with padding. |
### Debug Helpers
| Function | Category | Inputs | Outputs | Description |
|----------|----------|--------|---------|-------------|
| [`LogDebug`] | Debug\Logging | `Category: Name`, `Message: String`, `Color: LinearColor` | — | Conditional screen + log output. Only fires in editor/development builds. Stripped in shipping builds via `DO_CHECK` flag. |
| [`DrawDebugSphere`] | Debug\Drawing | `WorldContext: Object`, `Center: Vector`, `Radius: Float`, `Color: LinearColor`, `Duration: Float` | — | Draws a debug sphere for visual debugging in-editor. Stripped in shipping builds. |
| [`DrawDebugString3D`] | Debug\Drawing | `WorldContext: Object`, `Location: Vector`, `Text: String`, `Color: LinearColor`, `Duration: Float` | — | Draws a 3D world-space debug string. Stripped in shipping builds. |
## Blueprint Flow
```
[Any Blueprint calls FL_GameUtilities function]
└─► Function executes immediately (no async)
└─► Returns value or performs side effect
└─► Caller uses result in next node
```
Since this is a pure static library, there is no lifecycle. Every function is callable from any Blueprint's event graph, construction script, or function.
## Communicates With
| Target System | Method | Why |
|---------------|--------|-----|
| [`GI_GameFramework`](04_GI_GameFramework.md) | Direct cast | `GetGameFramework()` helper |
| [`PC_CoreController`](02-player/01_PC_CoreController.md) | Direct cast | `GetPlayerController()` helper |
| Any Actor | Interface + Tag | Actor utility functions |
## Blueprint Editor Usage
### How to Call
1. Right-click in any Event Graph or Function.
2. Search for the function name (e.g. `RemapFloat`, `FormatTime`).
3. The functions appear under their category name in the context menu.
4. Wire inputs and use output.
### Construction Script Usage
All functions can be called from Construction Scripts since they are pure (no world context required for math/text functions). Functions requiring `WorldContextObject` pass the `Self` reference from the construction script context.
## Reuse Notes
- This library ships verbatim to every project.
- Add project-specific helpers in a separate `FL_ProjectUtilities` child library that references this one.
- Do **not** add game-specific functions here — extend with a new Function Library inheriting from this pattern.
- Debug functions are automatically stripped in Shipping builds via `DO_CHECK` preprocessor — no manual removal needed.
## Success Criteria
1. Any Blueprint in the project can call `RemapFloat` from the Math category without errors.
2. `GetSubsystemSafe` returns `None` instead of crashing when a subsystem doesn't exist.
3. `FormatTime(3661.0)` returns `01:01:01`.
4. `LogDebug` prints to both the output log and the viewport in editor builds.
5. `LogDebug` produces no output in a shipping build.

View File

@@ -0,0 +1,396 @@
# I_InterfaceLibrary — Interface Collection
## Overview
This document defines all **9 Blueprint Interfaces** that form the backbone of cross-system communication in the framework. Interfaces are the **preferred communication method** over direct references — they decouple the caller from the callee's concrete class. Any Actor or Component can implement any of these interfaces, and any system can query for them and call them without knowing the underlying type.
## Folder Structure
All interfaces are placed in: [`Framework/Interfaces/`]
| Interface | File | Purpose |
|-----------|------|---------|
| [`I_Interactable`] | I_Interactable | Primary interaction entry point |
| [`I_Inspectable`] | I_Inspectable | Inspection/Examine system |
| [`I_Damageable`] | I_Damageable | Health, damage, death |
| [`I_Holdable`] | I_Holdable | Two-hand hold / use in hand |
| [`I_Lockable`] | I_Lockable | Lock/Unlock with key checks |
| [`I_UsableItem`] | I_UsableItem | Consumable/equippable item usage |
| [`I_Persistable`] | I_Persistable | Save/Load serialization contract |
| [`I_Toggleable`] | I_Toggleable | On/Off, Open/Close state machines |
| [`I_Adjustable`] | I_Adjustable | Continuous adjustment (pressure, dials) |
## Dependency Table
Each interface is independent. None inherit from another. A single actor can implement multiple interfaces (e.g. a door implements [`I_Interactable`], [`I_Toggleable`], [`I_Persistable`]).
---
## I_Interactable
### Asset Details
| Property | Value |
|----------|-------|
| **Class** | [`I_Interactable`] |
| **Type** | Blueprint Interface |
| **Folder** | [`Framework/Interfaces/`] |
| **Category** | Interaction |
### Purpose
The primary interaction entry point. Any object the player can look at and press a button to interact with must implement this interface. It is the single point of contact for the interaction system.
### Functions
| Function | Inputs | Outputs | Description |
|----------|--------|---------|-------------|
| [`OnInteract`] | `Instigator: Actor` | `bSuccess: Bool` | Called when the player presses the interact button. Returns false if interaction failed. |
| [`OnFocusBegin`] | `Instigator: Actor` | — | Called when the crosshair hovers over the object. Used to show UI prompts. |
| [`OnFocusEnd`] | `Instigator: Actor` | — | Called when the crosshair leaves the object. Hides UI prompt. |
| [`GetInteractionPrompt`] | — | `PromptText: Text` | Returns the text to display on the interaction HUD (e.g. "Press E to Open"). |
| [`CanInteract`] | `Instigator: Actor` | `bCanInteract: Bool`, `BlockReason: Text` | Query if interaction is currently possible. `BlockReason` provides a why-not string for UI feedback. |
| [`GetInteractionType`] | — | `InteractionType: E_InteractionType` | Returns the type of interaction (see enum below). |
### Enums
| Enum | Values | Description |
|------|--------|-------------|
| `E_InteractionType` | `None`, `Pickup`, `Use`, `Examine`, `Talk`, `Open`, `Push`, `Pull`, `Custom` | Categorizes the interaction for UI icon and animation selection. |
### Blueprint Flow
```
[Player presses E]
└─► PC_CoreController calls OnInteract on target actor
└─► Target implements I_Interactable
└─► Returns bSuccess
└─► If false, PC plays "Blocked" feedback sound
```
### Communicates With
| Target | Direction | Why |
|--------|-----------|-----|
| [`PC_CoreController`](../02-player/01_PC_CoreController.md) | Called by | Interaction trace calls these functions |
| [`BPC_InteractionDetector`](../03-interaction/01_BPC_InteractionDetector.md) | Called by | Focus events are driven by the detector component |
| [`WBP_InteractionPrompt`](../05-ui/02_WBP_InteractionPrompt.md) | Consumed by | Reads `GetInteractionPrompt` and `GetInteractionType` for UI display |
---
## I_Inspectable
### Asset Details
| Property | Value |
|----------|-------|
| **Class** | [`I_Inspectable`] |
| **Type** | Blueprint Interface |
| **Folder** | [`Framework/Interfaces/`] |
| **Category** | Interaction |
### Purpose
Controls the **inspection/examine** system. Objects that can be picked up and rotated in front of the camera for close examination implement this.
### Functions
| Function | Inputs | Outputs | Description |
|----------|--------|---------|-------------|
| [`StartInspect`] | `Instigator: Actor` | `bSuccess: Bool` | Begins inspection mode. Returns false if inspection not possible. |
| [`EndInspect`] | `Instigator: Actor` | — | Ends inspection mode. |
| [`RotateInspect`] | `DeltaRotation: Rotator` | — | Applies incremental rotation while in inspection mode. |
| [`GetInspectData`] | — | `InspectData: F_InspectData` | Returns struct with inspect-relevant data. |
| [`HasInspectInfo`] | — | `bHasInfo: Bool` | Whether this object has additional inspectable lore/text. |
### Structs
| Struct | Fields |
|--------|--------|
| `F_InspectData` | `InspectDuration: Float`, `bCanRotate: Bool`, `bHasAudioLog: Bool`, `InspectSound: SoundBase` |
### Blueprint Flow
```
[Player holds E to inspect]
└─► PC calls StartInspect
└─► Object spawns inspect proxy or enters inspect mode
└─► Player drags mouse → RotateInspect
└─► Player releases → EndInspect
```
---
## I_Damageable
### Asset Details
| Property | Value |
|----------|-------|
| **Class** | [`I_Damageable`] |
| **Type** | Blueprint Interface |
| **Folder** | [`Framework/Interfaces/`] |
| **Category** | Combat |
### Purpose
Any actor that can take damage, heal, or die implements this interface. This includes the player character, enemies, destructibles, and breakable environmental objects.
### Functions
| Function | Inputs | Outputs | Description |
|----------|--------|---------|-------------|
| [`TakeDamage`] | `DamageAmount: Float`, `DamageType: F_GameplayTag`, `Instigator: Actor`, `SourceLocation: Vector` | `bSuccess: Bool` | Applies damage to the actor. Returns false if immune. |
| [`Heal`] | `HealAmount: Float`, `HealType: F_GameplayTag` | `bSuccess: Bool` | Heals the actor. |
| [`IsAlive`] | — | `bIsAlive: Bool` | Whether the actor is alive or destroyed. |
| [`GetMaxHealth`] | — | `MaxHealth: Float` | Returns the maximum health value. |
| [`GetCurrentHealth`] | — | `CurrentHealth: Float` | Returns the current health value. |
| [`OnDeath`] | `Instigator: Actor`, `DamageType: F_GameplayTag` | `bSuccess: Bool` | Called when health reaches zero. Handles death logic. |
| [`GetDamageModifier`] | `DamageType: F_GameplayTag` | `DamageMultiplier: Float` | Returns damage multiplier for a given damage type. |
### Enums
No enums. Damage types are handled via gameplay tags.
### Communicates With
| Target | Direction | Why |
|--------|-----------|-----|
| [`BPC_HealthComponent`](../07-weapons/01_BPC_HealthComponent.md) | Implements | The health component implements this interface |
| Any weapon/damage source | Calls | Calls `TakeDamage` when hitting a target |
---
## I_Holdable
### Asset Details
| Property | Value |
|----------|-------|
| **Class** | [`I_Holdable`] |
| **Type** | Blueprint Interface |
| **Folder** | [`Framework/Interfaces/`] |
| **Category** | Interaction |
### Purpose
Objects that can be grabbed and held in the player's hands (two-hand hold system). Used for puzzles where objects must be carried and placed.
### Functions
| Function | Inputs | Outputs | Description |
|----------|--------|---------|-------------|
| [`OnPickup`] | `Holder: Actor` | `bSuccess: Bool` | Called when the player picks up the object. |
| [`OnDrop`] | `Holder: Actor` | — | Called when the player drops the object. |
| [`GetHoldTransform`] | — | `HoldLocation: Transform` | Returns the relative transform where the object should be held. |
| [`IsHeld`] | — | `bIsHeld: Bool` | Whether the object is currently being held. |
| [`OnReleasedFromHold`] | `NewLocation: Vector` | — | Called when the object is released (thrown or placed). |
---
## I_Lockable
### Asset Details
| Property | Value |
|----------|-------|
| **Class** | [`I_Lockable`] |
| **Type** | Blueprint Interface |
| **Folder** | [`Framework/Interfaces/`] |
| **Category** | Interaction |
### Purpose
Doors, drawers, containers, and any object that can be locked/unlocked with a key item or puzzle solution.
### Functions
| Function | Inputs | Outputs | Description |
|----------|--------|---------|-------------|
| [`TryLock`] | `LockingItem: Actor` | `bSuccess: Bool` | Attempt to lock the object with a specific item. |
| [`TryUnlock`] | `KeyItem: Actor` | `bSuccess: Bool` | Attempt to unlock with a key item. |
| [`IsLocked`] | — | `bIsLocked: Bool` | Whether the object is currently locked. |
| [`GetRequiredKeyTag`] | — | `RequiredTag: F_GameplayTag` | Returns the gameplay tag of the required key/item. |
| [`OnLockStateChanged`] | `bNewLocked: Bool` | — | Event dispatcher-style notification (implemented via dispatchers in the actor). |
### Communicates With
| Target | Direction | Why |
|--------|-----------|-----|
| [`BPC_InventoryComponent`](../04-inventory/01_BPC_InventoryComponent.md) | Calls | Checks if the player has the required key tag |
| [`BP_DoorBase`](../03-interaction/02_BP_DoorBase.md) | Implements | Doors use this interface |
---
## I_UsableItem
### Asset Details
| Property | Value |
|----------|-------|
| **Class** | [`I_UsableItem`] |
| **Type** | Blueprint Interface |
| **Folder** | [`Framework/Interfaces/`] |
| **Category** | Inventory |
### Purpose
Consumable and usable inventory items (health packs, batteries, keys, quest items). Items implement this to define what happens when used from the inventory screen or hotbar.
### Functions
| Function | Inputs | Outputs | Description |
|----------|--------|---------|-------------|
| [`UseItem`] | `User: Actor` | `bConsumed: Bool` | Called when the player uses the item from inventory. Returns true if item should be consumed. |
| [`CanUseItem`] | `User: Actor` | `bCanUse: Bool`, `BlockReason: Text` | Whether the item can currently be used. |
| [`GetUseDuration`] | — | `Duration: Float` | How long the "use" action takes in seconds. |
| [`OnItemUsed`] | `User: Actor` | — | Broadcast event after item is used successfully. |
---
## I_Persistable
### Asset Details
| Property | Value |
|----------|-------|
| **Class** | [`I_Persistable`] |
| **Type** | Blueprint Interface |
| **Folder** | [`Framework/Interfaces/`] |
| **Category** | Save System |
### Purpose
**Save-System Awareness** contract. Every actor that needs to persist state (position, health, inventory contents, lock state, narrative flags) must implement this interface. The save system scans the world for `I_Persistable` implementors and calls these functions.
### Functions
| Function | Inputs | Outputs | Description |
|----------|--------|---------|-------------|
| [`OnSave`] | — | `SaveData: F_GameplayTagContainer` | Returns the actor's state as a tag container for serialization. |
| [`OnLoad`] | `SaveData: F_GameplayTagContainer` | `bSuccess: Bool` | Restores actor state from saved data. Returns false if load failed. |
| [`GetSaveTag`] | — | `SaveTag: F_GameplayTag` | Returns a unique gameplay tag identifying this actor for save/load lookup. |
| [`NeedsSave`] | — | `bNeedsSave: Bool` | Whether this actor currently has unsaved changes. |
### Blueprint Flow
```
[AutoSave Triggered]
└─► SS_SaveSystem/GS iterates all I_Persistable actors
└─► Calls GetSaveTag for unique ID
└─► Calls OnSave to get state data
└─► Serializes tag + data to save file
[Game Loaded]
└─► SS_SaveSystem reads save file
└─► Finds actors by GetSaveTag
└─► Calls OnLoad with saved data
```
### Communicates With
| Target | Direction | Why |
|--------|-----------|-----|
| [`SS_SaveSystem`](../04-save/02_SS_SaveSystem.md) | Called by | Save system iterates and invokes |
| [`GS_CoreGameState`](06_GS_CoreGameState.md) | Called by | GameState can trigger save sweeps |
| Any world actor | Implements | Doors, items, enemies, narrative triggers |
---
## I_Toggleable
### Asset Details
| Property | Value |
|----------|-------|
| **Class** | [`I_Toggleable`] |
| **Type** | Blueprint Interface |
| **Folder** | [`Framework/Interfaces/`] |
| **Category** | Interaction |
### Purpose
Objects with binary states: on/off, open/closed, active/inactive. Lights, doors, buttons, switches, and machines implement this interface.
### Functions
| Function | Inputs | Outputs | Description |
|----------|--------|---------|-------------|
| [`Toggle`] | `Instigator: Actor` | `bNewState: Bool` | Toggles the object to its opposite state. Returns the new state. |
| [`SetState`] | `Instigator: Actor`, `bNewState: Bool` | `bSuccess: Bool` | Sets the object to a specific state. |
| [`GetCurrentState`] | — | `bState: Bool` | Returns the current state. |
| [`GetStateLabel`] | — | `StateText: Text` | Human-readable label for the current state (e.g. "Open" / "Closed"). |
| [`OnStateChanged`] | `bNewState: Bool`, `Instigator: Actor` | — | Event dispatched when state changes (for animation/delegation). |
---
## I_Adjustable
### Asset Details
| Property | Value |
|----------|-------|
| **Class** | [`I_Adjustable`] |
| **Type** | Blueprint Interface |
| **Folder** | [`Framework/Interfaces/`] |
| **Category** | Interaction |
### Purpose
Objects with continuous adjustment values rather than binary states. Pressure valves, dials, sliders, tuning knobs, and analog controls.
### Functions
| Function | Inputs | Outputs | Description |
|----------|--------|---------|-------------|
| [`Adjust`] | `Delta: Float`, `Instigator: Actor` | `bSuccess: Bool` | Adjusts the value by delta. Positive = increase, negative = decrease. |
| [`SetValue`] | `NewValue: Float`, `Instigator: Actor` | `bSuccess: Bool` | Sets the value directly. |
| [`GetCurrentValue`] | — | `CurrentValue: Float` | Returns current value. |
| [`GetMinValue`] | — | `MinValue: Float` | Minimum allowed value. |
| [`GetMaxValue`] | — | `MaxValue: Float` | Maximum allowed value. |
| [`OnValueChanged`] | `NewValue: Float`, `Instigator: Actor` | — | Event dispatched when value changes (for visual/audio feedback). |
---
## Communication Overview
```
┌──────────────────────────────────────────────────────────┐
│ Any Blueprint │
│ (Player Controller, Widget, AI, Level Blueprint, etc.) │
└──────────┬───────────────────────────────────────────────┘
│ Calls Interface Function
┌──────────────────────┐
│ Interface Function │ (e.g. OnInteract, Toggle, TakeDamage)
└──────────┬───────────┘
│ Dispatched to implementor
┌────────────────────────────────────┐
│ Actor / Component implementing │
│ the interface │
│ (e.g. BP_DoorBase, BP_HealthPack)│
└────────────────────────────────────┘
│ May call back to other systems
┌──────────────────────────────┐
│ Other systems via interface │
│ or event dispatcher │
└──────────────────────────────┘
```
## Reuse Notes
- All interfaces are minimal — each function has a single clear responsibility.
- Implementors should **never** call interface functions on themselves. Callers should always query for the interface using `Does Implement Interface` or `Cast to Interface` nodes.
- New interfaces should be added here by following the same pattern: define functions, default return values (typically `false` or `0.0f`), and clear documentation.
- If a system needs additional interface functions, consider creating a child interface or extending the existing one. Prefer child interfaces to keep base interfaces stable.
## Success Criteria
1. An actor with [`I_Interactable`] implemented responds to `OnInteract` when detected by the interaction system.
2. An actor with [`I_Persistable`] saves and restores its state correctly through the save system.
3. An actor can implement multiple interfaces simultaneously without conflicts.
4. Calling an interface function on an actor that doesn't implement it safely returns the default value (no crash).
5. All interface functions are accessible via the Blueprint node context menu under their category name.

View File

@@ -0,0 +1,217 @@
# 04 — Game Instance Kernel (`GI_GameFramework`)
## Purpose
The single persistent object that lives for the entire application session. It owns global subsystems, manages save slot ownership, and provides the canonical entry point for service resolution.
## Dependencies
- **Requires:** GameplayTags plugin enabled, all `SS_` Subsystems
- **Required By:** `GM_CoreGameMode`, `WBP_HUDController`, `WBP_MenuFlowController`, any system that resolves a subsystem
- **Engine/Plugin Requirements:** GameplayTags, DeveloperSettings
## Class Info
| Property | Value |
|----------|-------|
| **Parent Class** | `GameInstance` |
| **Class Type** | Blueprint (BlueprintType) |
| **Asset Path** | `Content/Framework/Core/GI_GameFramework` |
| **Implements Interfaces** | None |
---
## 1. Enums
### `E_GamePhase`
| Value | Display Name | Description |
|-------|-------------|-------------|
| `MainMenu` = 0 | Main Menu | Game at main menu, no session active |
| `Loading` = 1 | Loading | Transition between levels or phases |
| `InGame` = 2 | In Game | Normal gameplay active |
| `Paused` = 3 | Paused | Game logic paused via pause menu or system |
| `Cutscene` = 4 | Cutscene | Sequencer-driven cutscene playing |
| `DeathLoop` = 5 | Death Loop | Player died and death loop is active |
| `AltDeathSpace` = 6 | Alt Death Space | Alternate death/purgatory space active |
| `Credits` = 7 | Credits | End credits playing |
| `PostGame` = 8 | Post Game | After credits, meta/post-game state |
### `E_PlatformType`
| Value | Display Name | Description |
|-------|-------------|-------------|
| `Steam` = 0 | Steam | Steam platform services |
| `PlayStation` = 1 | PlayStation | PlayStation platform services |
| `Xbox` = 2 | Xbox | Xbox platform services |
| `Switch` = 3 | Nintendo Switch | Nintendo platform services |
| `Generic` = 4 | Generic | Fallback for unknown/unlisted platforms |
---
## 2. Structs
*No structs defined in this class. All data is stored as direct variables or via subsystems.*
---
## 3. Variables
### Configuration (Instance Editable, Expose On Spawn)
| Variable | Type | Default | Category | Description |
|----------|------|---------|----------|-------------|
| `ActiveSaveSlotIndex` | `Integer` | `0` | `Save` | Which save slot is currently loaded (0\u2013N) |
| `PlatformType` | `E_PlatformType` | `Generic` | `Platform` | Identifies the current platform for service abstraction |
| `bFirstLaunch` | `Boolean` | `true` | `Save` | True on first-ever boot; triggers intro flow |
### Internal (Private / Protected, No Expose)
| Variable | Type | Default | Category | Description |
|----------|------|---------|----------|-------------|
| `SessionFlags` | `Map<GameplayTag, Boolean>` | `Empty Map` | `Session` | Transient flags that do not persist to disk |
| `CurrentGamePhase` | `E_GamePhase` | `MainMenu` | `State` | Tracks the top-level game phase for routing |
---
## 4. Functions
### Public Functions
#### `GetSubsystem` → `Object Reference`
- **Description:** Returns the requested subsystem by GameplayTag lookup. This is the canonical service resolver for all systems.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `Tag` | `GameplayTag` | The tag identifying which subsystem to return |
- **Blueprint Authority:** Any
- **Flow:**
1. Look up subsystem class reference mapped to the input tag
2. Call `GetSubsystem()` with resolved class
3. Return the subsystem reference (null if not found)
4. If null, log a warning via `FL_GameUtilities.LogDebug`
#### `SetSessionFlag` → `Void`
- **Description:** Sets a transient session flag that does not persist to disk.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `Tag` | `GameplayTag` | Flag identifier |
| `Value` | `Boolean` | Flag value |
- **Flow:** `SessionFlags.Add(Tag, Value)`
#### `GetSessionFlag` → `Boolean`
- **Description:** Reads a transient session flag value.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `Tag` | `GameplayTag` | Flag identifier |
- **Flow:** Return `SessionFlags.Find(Tag, false)`
#### `SetActiveSlot` → `Void`
- **Description:** Designates the active save slot index. Does not trigger a save or load.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `SlotIndex` | `Integer` | Slot index to set active |
#### `SetGamePhase` → `Void`
- **Description:** Updates `CurrentGamePhase` and broadcasts the `OnGamePhaseChanged` dispatcher. This is the single point of authority for phase transitions.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `Phase` | `E_GamePhase` | New phase value |
- **Flow:**
1. `CurrentGamePhase = Phase`
2. Broadcast `OnGamePhaseChanged`
#### `InitPlatformServices` → `Void`
- **Description:** Called during `Init()`; routes to platform-specific service wrappers based on `PlatformType`.
- **Flow:**
1. Switch on `PlatformType`
2. Call platform init stubs (empty in editor)
3. Broadcast `OnPlatformReady`
---
## 5. Event Dispatchers
| Dispatcher | Parameters | Bind Access | Description |
|------------|-----------|-------------|-------------|
| `OnGamePhaseChanged` | `NewPhase: E_GamePhase` | `Public` | Fired on any phase transition |
| `OnPlatformReady` | `PlatformType: E_PlatformType` | `Public` | Fired when platform services confirm ready |
---
## 6. Overridden Events / Custom Events
### Event: `Init()`
- **Description:** Override of `GameInstance.Init()`. Called automatically when the game instance is created.
- **Flow:**
1. Call parent `Init()`
2. Call `InitPlatformServices()`
3. All `SS_` Subsystems are automatically initialized by UE (they are GameInstanceSubsystems)
4. Load persistent settings via `SS_SettingsSystem.PopulateDefaults()`
5. Check existing save data via `SS_SaveSystem.GetSlotManifest()`
6. Call `SetGamePhase(MainMenu)`
7. Broadcast `OnPlatformReady`
### Event: `Shutdown()`
- **Description:** Override of `GameInstance.Shutdown()`. Called when the game instance is destroyed.
- **Flow:**
1. Save persistent settings via `SS_SettingsSystem`
2. Call parent `Shutdown()`
---
## 7. Blueprint Graph Logic Flow
```mermaid
flowchart TD
A[GameInstance Init] --> B[Call InitPlatformServices]
B --> C{Platform identified?}
C -->|Yes| D[Platform init stubs]
C -->|No| E[Set PlatformType = Generic]
D --> F[SS_SettingsSystem.PopulateDefaults]
E --> F
F --> G[SS_SaveSystem.GetSlotManifest]
G --> H[SetGamePhase MainMenu]
H --> I[Broadcast OnGamePhaseChanged]
I --> J[Broadcast OnPlatformReady]
K[Any system calls SetGamePhase] --> L[Update CurrentGamePhase]
L --> M[Broadcast OnGamePhaseChanged]
M --> N[Receivers: GM_CoreGameMode, WBP_HUDController, etc.]
```
---
## 8. Communication Matrix
| Who Talks | How | What Is Sent |
|-----------|-----|-------------|
| `GI_GameFramework` | `Direct Reference (owns)` | Manages lifecycle of all `SS_` Subsystems |
| `GI_GameFramework` | `Dispatcher: OnGamePhaseChanged` | `NewPhase: E_GamePhase` to `GM_CoreGameMode`, `WBP_HUDController` |
| `GI_GameFramework` | `Dispatcher: OnPlatformReady` | `PlatformType: E_PlatformType` to all listeners |
| Any Blueprint | `Direct GetSubsystem()` | Subsystem reference by GameplayTag lookup |
| `GM_CoreGameMode` | `Direct Reference` | Reads `CurrentGamePhase`, calls `SetGamePhase` |
---
## 9. Validation / Testing Checklist
- [ ] `Init()` fires without errors and all SS_ Subsystems are created
- [ ] `SetGamePhase()` updates `CurrentGamePhase` and fires `OnGamePhaseChanged`
- [ ] `GetSubsystem()` returns correct subsystem for each registered tag
- [ ] `GetSubsystem()` returns null and logs warning for unknown tags
- [ ] `SetSessionFlag()` and `GetSessionFlag()` round-trip correctly
- [ ] `SetActiveSlot()` updates slot index without side effects
- [ ] `InitPlatformServices()` routes to correct platform stub
- [ ] `bFirstLaunch` stays true until explicitly cleared by onboarding flow
- [ ] Edge case: calling `SetGamePhase()` with same value does not fire dispatcher (if desired)
- [ ] Edge case: `GetSubsystem()` during `PreInit()` returns null (graceful)
---
## 10. Reuse Notes
- Replace `E_PlatformType` routing with new platform entries for additional platforms.
- Add new subsystems to the init list; they are auto-initialized by UE's GameInstanceSubsystem system.
- The `SessionFlags` map lets you add per-project transient state without modifying this class.
- For multi-world / split-screen, treat this as a single-instance singleton per application session.
- `PlatformType` can be overridden via command-line switch `-Platform=Steam` in packaging scripts.

View File

@@ -0,0 +1,181 @@
# GM_CoreGameMode — Core GameMode
---
## Asset Details
| Field | Value |
|-------|-------|
| **Asset Type** | Blueprint Class |
| **Parent Class** | GameModeBase |
| **Folder** | Framework/Core/ |
| **UE Version** | 5.55.7 |
| **Prefix** | GM_ |
| **Icon** | GameMode icon |
---
## Purpose
Sets the rules of the game session: which pawn, controller, player state, HUD, and game state classes to use. Manages level-phase transitions, win/loss routing, and chapter transitions.
---
## Dependencies
| Dependency | Type | Why |
|------------|------|-----|
| [`GI_GameFramework`](01-core/04_GI_GameFramework.md) | Direct reference | Phase transition coordination |
| [`GS_CoreGameState`](01-core/06_GS_CoreGameState.md) | Owned/managed | Session state store |
| [`PC_CoreController`](../02-player/08_PC_CoreController.md) | Spawned | Default player controller |
| [`BPC_DeathHandlingSystem`](../08-saveload/23_BPC_DeathHandlingSystem.md) | Dispatcher (receives) | Receives death event |
| [`SS_SaveSystem`](../08-saveload/21_SS_SaveSystem.md) | Direct | Checkpoint load on respawn |
| [`BPC_NarrativeSystem`](../06-narrative/37_BPC_NarrativeSystem.md) | Interface | Chapter start/end hooks |
---
## Enums
No enums defined on this class directly. References [`E_GamePhase`](01-core/04_GI_GameFramework.md) from [`GI_GameFramework`](01-core/04_GI_GameFramework.md) and [`E_DeathCause`](../05-weapons/18_BPC_DeathCauseTracker.md) from death handling.
---
## Structs
None. All data is primitive or class references.
---
## Variables
| Name | Type | Description | Access |
|------|------|-------------|--------|
| `DefaultPawnClass` | Class Reference | GASP-based player pawn class | Public |
| `DefaultControllerClass` | Class Reference | [`PC_CoreController`](../02-player/08_PC_CoreController.md) | Public |
| `DefaultPlayerStateClass` | Class Reference | [`PS_CorePlayerState`](../02-player/09_PS_CorePlayerState.md) | Public |
| `DefaultGameStateClass` | Class Reference | [`GS_CoreGameState`](01-core/06_GS_CoreGameState.md) | Public |
| `DefaultHUDClass` | Class Reference | [`WBP_HUDController`](../05-ui/31_WBP_HUDController.md) | Public |
| `bPauseAllowed` | Boolean | Runtime flag — disables pause during scripted moments | Public |
| `CurrentChapterTag` | GameplayTag | Active chapter/level identifier | Public |
---
## Functions / Events
| Name | Inputs | Outputs | Description |
|------|--------|---------|-------------|
| `TransitionToChapter` | ChapterTag: GameplayTag | — | Loads next level, sets chapter tag, triggers narrative hooks |
| `TriggerGameOver` | Cause: E_DeathCause | — | Routes to death handler or alt death space |
| `TriggerEnding` | EndingTag: GameplayTag | — | Passes ending tag to [`BPC_EndingAccumulatorSystem`](../06-narrative/42_BPC_EndingAccumulatorSystem.md) |
| `SetPauseAllowed` | bAllowed: Boolean | — | Enables/disables pause permission |
| `HandlePlayerDead` | — | — | Called by [`BPC_DeathHandlingSystem`](../08-saveload/23_BPC_DeathHandlingSystem.md); routes respawn or game-over |
| `SetChapterTag` | ChapterTag: GameplayTag | — | Updates CurrentChapterTag and syncs to [`GS_CoreGameState`](01-core/06_GS_CoreGameState.md) |
| `GetCurrentChapter` | — | GameplayTag | Returns CurrentChapterTag |
### Function Details
#### `TransitionToChapter`
```
Input: ChapterTag (GameplayTag)
Output: none
Flow:
└─► Set ChapterTag on GM
└─► Set GamePhase(Loading) on GI_GameFramework
└─► OpenLevel / StreamLevel by ChapterTag
└─► On level loaded:
├─► Sync chapter to GS_CoreGameState
├─► Fire BPC_NarrativeSystem.OnChapterStart
└─► SetGamePhase(InGame)
```
#### `HandlePlayerDead`
```
Input: none (triggered by dispatcher)
Output: none
Flow:
└─► bPauseAllowed = false
└─► SetGamePhase(DeathLoop) on GI_GameFramework
└─► Decision:
├─► Alt death space configured? → TriggerEnding(AltDeathSpace)
└─► No → SetGamePhase(Loading)
→ SS_SaveSystem.LoadCheckpoint()
→ On load → BPC_PlayerRespawnSystem.Respawn()
```
---
## Event Dispatchers
| Name | Parameters | Fired When |
|------|-----------|------------|
| `OnChapterTransition` | NewChapterTag: GameplayTag | Before level loads for chapter transition |
| `OnGameOverTriggered` | Cause: E_DeathCause | Game-over sequence begins |
---
## Blueprint Flow
```mermaid
flowchart TD
A[BeginPlay / Init] --> B[Set Default Classes]
B --> C{Has Save Data?}
C -->|Yes| D[SS_SaveSystem.LoadFromSlot]
C -->|No| E[Start New Game]
D --> F[OnLoadComplete -> SetGamePhase InGame]
E --> G[TransitionToChapter first chapter]
H[Player Dies] --> I[BPC_DeathHandlingSystem dispatches]
I --> J[HandlePlayerDead]
J --> K{Alt Death Space?}
K -->|Yes| L[SetGamePhase AltDeathSpace]
K -->|No| M[SetGamePhase Loading]
M --> N[SS_SaveSystem.LoadCheckpoint]
N --> O[Respawn Player]
O --> P[SetGamePhase InGame]
Q[Chapter Trigger] --> R[TransitionToChapter]
R --> S[SetGamePhase Loading]
S --> T[Load Chapter Level]
T --> U[Update GS_CoreGameState]
U --> V[SetGamePhase InGame]
```
---
## Communication Matrix
| Target System | Method | Direction | Why |
|---------------|--------|-----------|-----|
| [`GI_GameFramework`](01-core/04_GI_GameFramework.md) | Direct reference | Both ways | Phase transitions, active slot index |
| [`GS_CoreGameState`](01-core/06_GS_CoreGameState.md) | Direct reference | Write | Sync chapter tag and objective state |
| [`BPC_DeathHandlingSystem`](../08-saveload/23_BPC_DeathHandlingSystem.md) | Dispatcher | Inbound | Receives OnPlayerDied event |
| [`SS_SaveSystem`](../08-saveload/21_SS_SaveSystem.md) | Direct reference | Outbound | Load checkpoint on respawn |
| [`BPC_NarrativeSystem`](../06-narrative/37_BPC_NarrativeSystem.md) | Interface call | Outbound | Chapter start/end narrative hooks |
| [`PC_CoreController`](../02-player/08_PC_CoreController.md) | Direct spawn | Create | Default controller class |
| All menu widgets | Phase dispatcher | Outbound | Phase transitions via GI |
---
## Validation Checklist
- [ ] All default class references point to valid Blueprint classes
- [ ] `TransitionToChapter` correctly loads the level associated with the chapter tag
- [ ] `TriggerGameOver` properly freezes input and shows game-over screen
- [ ] `HandlePlayerDead` correctly routes to checkpoint load or alt death space
- [ ] `bPauseAllowed` is respected by pause menu widget
- [ ] Chapter transitions trigger narrative system hooks
- [ ] Player respawn restores proper game state
- [ ] No hardcoded references — all class selectors are exposed as variables
---
## Reuse Notes
- **Override** default class references per project (different pawn, different controller)
- **`TransitionToChapter`** can use level streaming or full level load — configure via project settings
- **`TriggerEnding`** is the only project-specific hook — override to handle unique ending sequences
- **`bPauseAllowed`** can be extended to a tag-based system for finer control
- For multiplayer, extend to derive from a replicated GameMode base
- The entire class is project-agnostic — drop into any UE5 project and configure class references

View File

@@ -0,0 +1,270 @@
# 06 — Core GameState (`GS_CoreGameState`)
## Purpose
The single replicated game state object visible to all players (and potential future co-op clients). Tracks session-level progression data such as elapsed play time, active chapter, narrative phase, encounter activity, and active objectives.
## Dependencies
- **Requires:** `GI_GameFramework` (parent `GameStateBase`), `GameplayTag` system
- **Required By:** `GM_CoreGameMode`, `BPC_EncounterDirector`, `WBP_HUDController`, `WBP_ObjectiveDisplay`
- **Engine/Plugin Requirements:** GameplayTags, Networking (replication stubs)
## Class Info
| Property | Value |
|----------|-------|
| **Parent Class** | `GameStateBase` |
| **Class Type** | Blueprint (GameState) |
| **Asset Path** | `Content/Framework/Core/GS_CoreGameState` |
| **Implements Interfaces** | `I_Persistable` (optional for persisting elapsed time across saves) |
---
## 1. Enums
No enums defined by this class. Enums consumed:
- `E_GamePhase` (from `GI_GameFramework`) — for phase sync
---
## 2. Structs
No custom structs defined by this class.
---
## 3. Variables
### Configuration (Instance Editable, Expose On Spawn)
| Variable | Type | Default | Category | Description |
|----------|------|---------|----------|-------------|
| (none) | | | | |
### Internal (Private, No Expose)
| Variable | Type | Default | Category | Description |
|----------|------|---------|----------|-------------|
| `ElapsedPlayTime` | `Float` | `0.0` | Session | Session seconds accumulated across chapters |
| `ActiveChapterTag` | `GameplayTag` | `None` | Session | Current story chapter identifier |
| `ActiveNarrativePhase` | `GameplayTag` | `None` | Session | Sub-chapter narrative phase tag |
| `bEncounterActive` | `Bool` | `false` | Session | Is an AI encounter currently running |
| `ActiveObjectiveTags` | `Array of GameplayTag` | `Empty` | Session | Tags of currently active objectives |
### Replicated (if multiplayer)
| Variable | Type | Condition | Description |
|----------|------|-----------|-------------|
| `ElapsedPlayTime` | `Float` | `Replicated Using OnRep_ElapsedPlayTime` | Replicated session time |
| `ActiveChapterTag` | `GameplayTag` | `Replicated Using OnRep_ActiveChapterTag` | Replicated chapter tag |
| `ActiveNarrativePhase` | `GameplayTag` | `Replicated Using OnRep_ActiveNarrativePhase` | Replicated phase tag |
| `bEncounterActive` | `Bool` | `Replicated Using OnRep_EncounterActive` | Replicated encounter flag |
| `ActiveObjectiveTags` | `Array of GameplayTag` | `Replicated Using OnRep_ActiveObjectiveTags` | Replicated objective list |
---
## 4. Functions
### Public Functions
#### `SetElapsedPlayTime` → `void`
- **Description:** Sets the elapsed play time (called by time-tick timer).
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `NewTime` | `Float` | New elapsed time in seconds |
- **Blueprint Authority:** Server
- **Flow:** Update internal variable, broadcast `OnElapsedPlayTimeUpdated`.
#### `GetElapsedPlayTime` → `Float`
- **Description:** Returns current elapsed play time.
- **Parameters:** None
- **Blueprint Authority:** Any
- **Flow:** Return `ElapsedPlayTime`.
#### `SetActiveChapter` → `void`
- **Description:** Sets the current chapter tag and fires dispatcher.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `ChapterTag` | `GameplayTag` | New chapter identifier |
- **Blueprint Authority:** Server
- **Flow:** Update variable, broadcast `OnChapterChanged`.
#### `GetActiveChapter` → `GameplayTag`
- **Description:** Returns the active chapter tag.
- **Flow:** Return `ActiveChapterTag`.
#### `SetActiveNarrativePhase` → `void`
- **Description:** Sets the sub-chapter narrative phase tag.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `PhaseTag` | `GameplayTag` | New narrative phase |
- **Blueprint Authority:** Server
- **Flow:** Update variable, broadcast `OnNarrativePhaseChanged`.
#### `GetActiveNarrativePhase` → `GameplayTag`
- **Description:** Returns the active narrative phase tag.
- **Flow:** Return `ActiveNarrativePhase`.
#### `SetEncounterActive` → `void`
- **Description:** Sets whether an encounter is currently running.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `bActive` | `Bool` | Encounter active state |
- **Blueprint Authority:** Server
- **Flow:** Update variable, broadcast `OnEncounterActiveStateChanged`.
#### `GetEncounterActive` → `Bool`
- **Description:** Returns encounter active state.
- **Flow:** Return `bEncounterActive`.
#### `AddActiveObjectiveTag` → `void`
- **Description:** Adds an objective tag to the active list.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `ObjectiveTag` | `GameplayTag` | Objective to add |
- **Blueprint Authority:** Server
- **Flow:** Add to array (if not already present), broadcast `OnObjectiveTagsChanged`.
#### `RemoveActiveObjectiveTag` → `void`
- **Description:** Removes an objective tag from the active list.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `ObjectiveTag` | `GameplayTag` | Objective to remove |
- **Blueprint Authority:** Server
- **Flow:** Remove from array, broadcast `OnObjectiveTagsChanged`.
#### `GetActiveObjectiveTags` → `Array of GameplayTag`
- **Description:** Returns the array of active objective tags.
- **Flow:** Return `ActiveObjectiveTags`.
### Protected / Private Functions
#### `OnRep_ElapsedPlayTime` → `void`
- **Description:** Replication notification for `ElapsedPlayTime`.
- **Flow:** Broadcast `OnElapsedPlayTimeUpdated`.
#### `OnRep_ActiveChapterTag` → `void`
- **Description:** Replication notification for `ActiveChapterTag`.
- **Flow:** Broadcast `OnChapterChanged`.
#### `OnRep_ActiveNarrativePhase` → `void`
- **Description:** Replication notification for `ActiveNarrativePhase`.
- **Flow:** Broadcast `OnNarrativePhaseChanged`.
#### `OnRep_EncounterActive` → `void`
- **Description:** Replication notification for `bEncounterActive`.
- **Flow:** Broadcast `OnEncounterActiveStateChanged`.
#### `OnRep_ActiveObjectiveTags` → `void`
- **Description:** Replication notification for `ActiveObjectiveTags`.
- **Flow:** Broadcast `OnObjectiveTagsChanged`.
---
## 5. Event Dispatchers
| Dispatcher | Parameters | Bind Access | Description |
|------------|-----------|-------------|-------------|
| `OnElapsedPlayTimeUpdated` | `NewTime: Float` | Public | Fires whenever elapsed time changes |
| `OnChapterChanged` | `NewChapterTag: GameplayTag` | Public | Fires when the active chapter changes |
| `OnNarrativePhaseChanged` | `NewPhaseTag: GameplayTag` | Public | Fires when narrative phase transitions |
| `OnEncounterActiveStateChanged` | `bEncounterActive: Bool` | Public | Fires when encounter state toggles |
| `OnObjectiveTagsChanged` | `ActiveTags: Array of GameplayTag` | Public | Fires when objective list changes |
---
## 6. Overridden Events / Custom Events
### Event: `BeginPlay`
- **Description:** Initialise game state defaults and bind to `GI_GameFramework.OnGamePhaseChanged` to reset elapsed time on new game.
- **Flow:**
1. Call parent `BeginPlay`
2. Set `ElapsedPlayTime = 0`
3. Bind to `GI_GameFramework.OnGamePhaseChanged` dispatcher
4. If `I_Persistable` implemented, register with `SS_SaveSystem`
### Event: `Tick`
- **Description:** Accumulate `ElapsedPlayTime` while game phase is `InGame`.
- **Flow:**
1. Check `GI_GameFramework.CurrentGamePhase == InGame`
2. If true: `ElapsedPlayTime += DeltaTime`
3. If change exceeds 1 second threshold, broadcast `OnElapsedPlayTimeUpdated`
---
## 7. Blueprint Graph Logic Flow
```mermaid
flowchart TD
A[BeginPlay] --> B[Init variables to 0 / None]
B --> C[Bind to GI_GameFramework.OnGamePhaseChanged]
C --> D[Tick - Is GamePhase InGame?]
D -->|Yes| E[Accumulate ElapsedPlayTime]
D -->|No| F[Skip time accumulation]
E --> G[Fire OnElapsedPlayTimeUpdated]
G --> H[Wait next Tick]
H --> D
F --> H
I[GM_CoreGameMode calls SetActiveChapter] --> J[Update ActiveChapterTag]
J --> K[Broadcast OnChapterChanged]
K --> L[UI + Narrative systems react]
M[BPC_EncounterDirector sets EncounterActive] --> N[Update bEncounterActive]
N --> O[Broadcast OnEncounterActiveStateChanged]
O --> P[HUD shows encounter status]
Q[BPC_ObjectiveSystem adds/removes objective] --> R[Update ActiveObjectiveTags]
R --> S[Broadcast OnObjectiveTagsChanged]
S --> T[WBP_ObjectiveDisplay refreshes]
```
---
## 8. Communication Matrix
| Who Talks | How | What Is Sent |
|-----------|-----|-------------|
| `GI_GameFramework` | `OnGamePhaseChanged` Dispatcher | Game phase events |
| `GM_CoreGameMode` | Direct method call | `SetActiveChapter`, `SetActiveNarrativePhase` |
| `BPC_EncounterDirector` | Direct method call | `SetEncounterActive` |
| `BPC_ObjectiveSystem` | Direct method call | `AddActiveObjectiveTag`, `RemoveActiveObjectiveTag` |
| `WBP_HUDController` | `OnChapterChanged` / `OnElapsedPlayTimeUpdated` Dispatchers | Chapter and time data |
| `WBP_ObjectiveDisplay` | `OnObjectiveTagsChanged` Dispatcher | Active objective list |
| `BPC_RunHistoryTracker` | Direct read | `ElapsedPlayTime`, `ActiveObjectiveTags` |
---
## 9. Validation / Testing Checklist
- [ ] `BeginPlay` initialises all variables to correct defaults
- [ ] `ElapsedPlayTime` increments only when `GamePhase == InGame`
- [ ] `SetActiveChapter` updates variable and fires `OnChapterChanged`
- [ ] `SetActiveNarrativePhase` updates variable and fires `OnNarrativePhaseChanged`
- [ ] `SetEncounterActive` toggles correctly and fires `OnEncounterActiveStateChanged`
- [ ] `AddActiveObjectiveTag` / `RemoveActiveObjectiveTag` modify array and fire dispatcher
- [ ] Duplicate objective tags are not added twice
- [ ] `OnRep_*` functions fire corresponding dispatchers on clients
- [ ] Edge case: rapid chapter changes in the same tick (dispatchers fire correctly)
- [ ] Edge case: empty objective list and removal from empty list (no crash)
- [ ] Edge case: time accumulation stops correctly on phase change to Paused/Loading
---
## 10. Reuse Notes
- This class is intentionally lightweight. It is a singleton per session.
- For multiplayer: mark all variables `Replicated Using` with `OnRep` notification functions. Currently stubbed as single-player only.
- For save persistence: implement `I_Persistable` to save/restore `ElapsedPlayTime` and `ActiveChapterTag` via `SS_SaveSystem`.
- The `ActiveObjectiveTags` array is read-only for UI. All modification happens through `BPC_ObjectiveSystem` which calls `GS_CoreGameState` methods.
- `bEncounterActive` is written by `BPC_EncounterDirector` and read by UI and adaptive atmosphere controllers.
- No new enums or structs are needed — all data is simple types or `GameplayTag` arrays.
- To add new replicated state (e.g. `bIsInCombat`), follow the same pattern: variable + setter + dispatcher + `OnRep`.
---
*Blueprint Spec v1.0 — GS_CoreGameState for UE5.5-5.7*

View File

@@ -0,0 +1,185 @@
# 07 — Item Data Asset (`DA_ItemData`)
## Purpose
The single source of truth for every item in the game. Each item is represented by one `DA_ItemData` Primary Data Asset. No item data lives in Blueprint logic; all item definitions are data-driven from these assets.
## Dependencies
- **Requires:** `GameplayTag` system (`GI_GameTagRegistry`), `UPrimaryDataAsset` (engine base)
- **Required By:** `BPC_InventorySystem`, `BPC_EquipmentSlotSystem`, `BPC_ConsumableSystem`, `BPC_AmmoResourceSystem`, `BPC_ItemCombineSystem`, `BPC_KeyItemSystem`, `BPC_ActiveItemSystem`, `DA_ItemDatabase` (collection)
- **Engine/Plugin Requirements:** `GameplayTags`, `AssetManager` (Primary Data Asset registration)
- **Parent Class:** `UPrimaryDataAsset`
## Class Info
| Property | Value |
|----------|-------|
| **Parent Class** | `UPrimaryDataAsset` |
| **Class Type** | Blueprint Function Library (Data Asset) |
| **Asset Path** | `Content/Data/Items/DA_Item_[Name]` |
| **Implements Interfaces** | None |
---
## 1. Enums
### `E_ItemType`
| Value | Description |
|-------|-------------|
| `Weapon` | Equippable weapon (melee or ranged) |
| `Ammo` | Ammunition for weapons |
| `Consumable` | Single-use health/stamina/stress item |
| `KeyItem` | Story progression gating item (non-droppable) |
| `Document` | Readable document / note / file |
| `Collectible` | Optional hidden item for completion |
| `Tool` | Equipment item (flashlight, lockpick, etc.) |
| `Resource` | Crafting / repair material |
| `Misc` | Other (quest flags, no-function items) |
---
## 2. Structs
No custom structs defined in this Data Asset class. Consumed structs from other files:
- `S_EquipmentData` (from `BPC_EquipmentSlotSystem`) — optional, if item is equippable
- `S_ConsumableData` (from `BPC_ConsumableSystem`) — optional, if item is consumable
- `S_InspectData` (from `BPC_InspectItemSystem`) — optional, if item has 3D inspect model
- `S_AmmoData` (from `BPC_AmmoResourceSystem`) — optional, if item is ammo type
---
## 3. Variables
### Instance Editable (Category: "Item Definition")
| Variable | Type | Default | Description |
|----------|------|---------|-------------|
| `ItemTag` | `GameplayTag` | `None` | Unique identifier for this item (e.g. `Item.MedKit`) |
| `DisplayName` | `FText` | `""` | Player-visible item name |
| `Description` | `FText` | `""` | Item description text |
| `Icon` | `Texture2D (Soft)` | `None` | Inventory/UI icon |
| `WorldMesh` | `StaticMesh (Soft)` | `None` | 3D mesh when dropped in world |
| `Weight` | `Float` | `0.0` | Weight units (for carry limit) |
| `StackLimit` | `Integer` | `1` | Max stack count in a single inventory slot |
| `ItemType` | `E_ItemType` | `Misc` | Item classification |
| `bIsKeyItem` | `Bool` | `false` | Protected from drop/consume/clear |
| `CombinesWith` | `Array of GameplayTag` | `Empty` | Items this can combine with (item tags) |
| `CombineResult` | `GameplayTag` | `None` | Produced item tag on successful combine |
| `CustomProperties` | `Map (Name -> String)` | `Empty` | Per-project custom data (any key-value pairs) |
### Optional Sub-Data (EditCondition / Visible if applicable)
| Variable | Type | Default | EditCondition | Description |
|----------|------|---------|---------------|-------------|
| `EquipmentData` | `S_EquipmentData` | Default | `ItemType == Weapon || ItemType == Tool` | Weapon/tool equipment properties |
| `ConsumableData` | `S_ConsumableData` | Default | `ItemType == Consumable` | Health/stamina/stress restore values |
| `InspectData` | `S_InspectData` | Default | `bHasInspectMode` | 3D inspect rotation anchors and secrets |
| `AmmoData` | `S_AmmoData` | Default | `ItemType == Ammo` | Ammo type tag and per-pickup count |
### Metadata / Editor
| Variable | Type | Default | Description |
|----------|------|---------|-------------|
| `bHasInspectMode` | `Bool` | `false` | Whether item supports 3D inspection |
| `bCanBeDropped` | `Bool` | `true` | Allow dropping from inventory |
| `AssetSearchTags` | `Array of FName` | `Empty` | Editor search keywords |
---
## 4. Functions
No runtime functions. This is a pure data container. The only accessible operations are direct variable reads from Blueprints that hold a reference to the asset.
### Editor-Only Functions (for content team validation)
#### `ValidateItemData` → `Bool` (BlueprintCallable, Editor only)
- **Description:** Runs editor validation checks (tag uniqueness, required fields filled).
- **Parameters:** None
- **Flow:**
1. Check `ItemTag != None` — if None, log warning
2. Check `DisplayName != ""` — if empty, log warning
3. If `StackLimit < 1`, reset to 1
4. If `bIsKeyItem` then `bCanBeDropped = false` (forced)
5. Return true if all validations pass
---
## 5. Event Dispatchers
None. Data Assets are passive data containers; they do not fire events.
---
## 6. Overridden Events / Custom Events
No event overrides. Data Assets do not tick or have BeginPlay.
---
## 7. Blueprint Graph Logic Flow
No blueprint graph. This asset is created and edited in the Content Browser via "Create Advanced Asset -> Blueprint -> Data Asset -> DA_ItemData".
```mermaid
flowchart LR
A[Content Browser] --> B[Right-click > Data Asset > DA_ItemData]
B --> C[Name: DA_Item_MedKit]
C --> D[Fill ItemTag: Item.MedKit]
D --> E[Fill DisplayName: Med Kit]
E --> F[Assign Icon, Mesh]
F --> G[Set ItemType: Consumable]
G --> H[Fill ConsumableData]
H --> I[Save Asset]
I --> J[Registered in Asset Manager]
```
---
## 8. Communication Matrix
| Who Talks | How | What Is Sent |
|-----------|-----|-------------|
| `BPC_InventorySystem` | Direct asset reference | Reads `ItemTag`, `DisplayName`, `Weight`, `StackLimit`, `bIsKeyItem`, `Icon` |
| `BPC_ConsumableSystem` | Direct asset reference | Reads `ConsumableData` (HealthRestore, StressReduce, etc.) |
| `BPC_EquipmentSlotSystem` | Direct asset reference | Reads `EquipmentData` (slot type, allowed types) |
| `BPC_AmmoResourceSystem` | Direct asset reference | Reads `AmmoData` (AmmoTypeTag, PerPickupCount) |
| `BPC_ItemCombineSystem` | Direct asset reference | Reads `CombinesWith`, `CombineResult` to validate combinations |
| `BPC_ActiveItemSystem` | Direct asset reference | Reads `ItemType` to route to correct use system |
| `BPC_InspectItemSystem` | Direct asset reference | Reads `InspectData`, `bHasInspectMode` |
| `WBP_InventoryMenu` | Via `BPC_InventorySystem` | Reads `DisplayName`, `Description`, `Icon`, `ItemType` for display |
| `WBP_InteractionPromptDisplay` | Via `I_Interactable` on world pickup | Reads `DisplayName` for "Pick up [ItemName]" prompt |
---
## 9. Validation / Testing Checklist
- [ ] Each `DA_ItemData` asset has a unique `ItemTag` (no two items share the same tag)
- [ ] `DisplayName` and `Description` are non-empty for all player-facing items
- [ ] `Icon` is assigned for all items that appear in inventory UI
- [ ] `WorldMesh` is assigned for items that have a world pickup representation
- [ ] `StackLimit` >= 1 for all items
- [ ] `bIsKeyItem` items have `bCanBeDropped = false`
- [ ] Consumable items have `ConsumableData` filled with at least one effect value > 0
- [ ] Weapon/Tool items have `EquipmentData` filled with correct slot tag
- [ ] Ammo items have `AmmoData` filled with `AmmoTypeTag` and `PerPickupCount > 0`
- [ ] Combine items: both sources reference the exact result tag in `CombineResult`
- [ ] `CustomProperties` map is empty for framework-defined items; used only for project-specific extensions
- [ ] Asset is registered with Primary Asset Manager (label: `Item`)
- [ ] Asset path follows convention: `Content/Data/Items/DA_Item_[Name]`
---
## 10. Reuse Notes
- Create one `DA_ItemData` per item. Name convention: `DA_Item_[ShortName]` (e.g. `DA_Item_MedKit`, `DA_Item_Flashlight`, `DA_Item_KeyCard_Omega`).
- All `ItemTag` values must be registered in `GI_GameTagRegistry` before use.
- The `CustomProperties` map future-proofs any per-project additions without modifying the base asset class.
- For non-stackable items (weapons, key items, tools), set `StackLimit = 1`.
- For stacks, choose a sensible `StackLimit` (e.g. ammo = 999, consumables = 5).
- The `AssetManager` should be configured with `PrimaryAssetType = Item` and `PrimaryAssetLabel = Item` for async loading support.
- Document items (`E_ItemType.Document`) additionally populate `BPC_DocumentArchiveSystem` with their content; the `Description` field serves as document body text.
- To add a new item property across all items, add a new variable to `DA_ItemData`. Do not create a separate asset class per item type — use the `ItemType` enum for branching logic.
- The `ValidateItemData` editor function can be exposed as a Python command for batch validation on check-in.
---
*Blueprint Spec v1.0 — DA_ItemData for UE5.5-5.7*