# 38 — BPC_NarrativeStateSystem ## Blueprint Spec — UE 5.5–5.7 --- ### Parent Class `ActorComponent` ### Dependencies - [`I_Persistable`](../01-core/29_I_Persistable.md) Interface - Gameplay Tag System - [`SS_SaveManager`](../05-save/28_SS_SaveManager.md) - [`BPC_ObjectiveSystem`](39_BPC_ObjectiveSystem.md) - [`BPC_EndingAccumulatorSystem`](45_BPC_EndingAcceleratorSystem.md) - [`BPC_BranchingConsequenceSystem`](42_BPC_BranchingConsequenceSystem.md) - All `I_NarrativeActor` implementors ### Purpose The authoritative store of all narrative flags. Every story decision, discovered secret, and consequence tag is registered here. Acts as the single source of truth for narrative state — all other systems read from here rather than maintaining their own flag copies. ### Responsibilities - Store narrative flags as `GameplayTag → Bool` map - Store numeric narrative values as `GameplayTag → Float` map - Provide add / check / remove flag API - Persist flags via [`I_Persistable`](../01-core/29_I_Persistable.md) - Broadcast flag changes so reactive systems update (doors, dialogue, environment) - Maintain ordered acquisition log for run summary ### Does NOT Handle - What happens when a flag changes (that is [`BPC_BranchingConsequenceSystem`](42_BPC_BranchingConsequenceSystem.md) job) - Dialogue flow or choices (those are separate systems) - Objective tracking (that is [`BPC_ObjectiveSystem`](39_BPC_ObjectiveSystem.md)) - Ending condition evaluation (that is [`BPC_EndingAccumulatorSystem`](45_BPC_EndingAcceleratorSystem.md)) --- ### Variables | Name | Type | Description | |------|------|-------------| | `NarrativeFlags` | Map (GameplayTag → Bool) | Binary story flags | | `NarrativeValues` | Map (GameplayTag → Float) | Numeric story values (reputation, corruption, etc.) | | `NarrativeHistory` | Array of GameplayTag | Ordered flag acquisition log | | `bPersistEnabled` | Bool | Whether state auto-persists through [`I_Persistable`](../01-core/29_I_Persistable.md) | | `MaxHistorySize` | Integer | Limits history log to prevent save bloat (default: 500) | ### Enums None required. Flags are GameplayTag-driven. ### Structs None required. Flat Tag maps suffice. ### Functions / Events | Name | Inputs | Outputs | Description | |------|--------|---------|-------------| | `SetFlag` | Tag: GameplayTag, Value: Bool | — | Sets a narrative flag to true/false | | `GetFlag` | Tag: GameplayTag | Bool | Reads a flag; returns false if tag not present | | `RemoveFlag` | Tag: GameplayTag | — | Removes a flag entirely from the map | | `SetValue` | Tag: GameplayTag, Value: Float | — | Sets a numeric narrative value | | `GetValue` | Tag: GameplayTag | Float | Reads numeric value; returns 0 if not present | | `AddToValue` | Tag: GameplayTag, Delta: Float | — | Adds delta to existing value (creates if absent) | | `HasAllFlags` | Tags: Array of GameplayTag | Bool | Returns true only if ALL flags are true | | `HasAnyFlag` | Tags: Array of GameplayTag | Bool | Returns true if ANY flag is true | | `GetAllActiveFlags` | — | Array of GameplayTag | Returns all currently-true flags | | `ClearAllFlags` | — | — | Resets all flags and values (used on new game) | | `CollectState` (I_Persistable) | — | S_WorldObjectState | Serializes flags and values into the custom data map | | `RestoreState` (I_Persistable) | Data: S_WorldObjectState | — | Deserializes flags and values from the custom data map | ### Event Dispatchers | Name | Parameters | Fired When | |------|-----------|-----------| | `OnFlagChanged` | Tag: GameplayTag, NewValue: Bool | Any flag value changes | | `OnValueChanged` | Tag: GameplayTag, NewValue: Float | Any numeric value changes | | `OnHistoryFull` | — | History log reaches MaxHistorySize | ### Blueprint Flow ``` [SetFlag called] └─► Store value in NarrativeFlags map └─► Append tag to NarrativeHistory (if becoming true) └─► Broadcast OnFlagChanged └─► Mark owner for persistence via I_Persistable [GetFlag called] └─► Look up tag in NarrativeFlags map └─► Tag found? → return its value └─► Tag missing? → return false [CollectState for save] └─► Serialize NarrativeFlags → array of (Tag, Bool) pairs └─► Serialize NarrativeValues → array of (Tag, Float) pairs └─► Bundle into S_WorldObjectState.CustomData with key "NarrativeData" ``` ### Communications With | Target System | Method | Why | |---------------|--------|-----| | [`BPC_ObjectiveSystem`](39_BPC_ObjectiveSystem.md) | Direct + Dispatcher | Objective activation / completion | | [`BPC_BranchingConsequenceSystem`](42_BPC_BranchingConsequenceSystem.md) | Dispatcher | Consequence evaluation trigger | | [`BPC_EndingAccumulatorSystem`](45_BPC_EndingAcceleratorSystem.md) | Direct | Ending condition evaluation | | [`BPC_DialoguePlaybackSystem`](40_BPC_DialoguePlaybackSystem.md) | Direct | Dialogue condition checks | | [`BPC_LoreUnlockSystem`](46_BPC_LoreUnlockSystem.md) | Dispatcher | Lore discovery on flag set | | All `I_NarrativeActor` implementors (doors, lights, etc.) | Interface | World reacts to flag changes | | [`SS_SaveManager`](../05-save/28_SS_SaveManager.md) | [`I_Persistable`](../01-core/29_I_Persistable.md) | Flag persistence across sessions | ### Reuse Notes The entire system is tag-driven and fully generic. The `Narrative.Flag.*` and `Narrative.Phase.*` namespaces are empty by default — fill them per project with game-specific flags. Add new numeric value types (reputation, corruption, etc.) by simply calling `SetValue` with the appropriate tag. No code/blueprint changes needed.