Files
UE5-Modular-Game-Framework/docs/blueprints/07-narrative/58_BPC_NarrativeStateSystem.md
Lefteris Notas bec6cb715e Enhance narrative systems with detailed implementation guides and data-driven structures
- Updated BPC_NarrativeStateSystem with a comprehensive manual implementation guide, including class setup, variable initialization, and function breakdowns.
- Expanded BPC_ObjectiveSystem documentation to include a manual implementation guide and detailed function descriptions.
- Added a manual implementation guide for BPC_DialoguePlaybackSystem, outlining class setup and function nodes.
- Introduced a manual implementation guide for BPC_DialogueChoiceSystem, detailing choice presentation and selection processes.
- Enhanced BPC_BranchingConsequenceSystem documentation with a manual implementation guide for consequence evaluation.
- Updated BPC_TrialScenarioSystem with a manual implementation guide for scenario management.
- Expanded BPC_LoreUnlockSystem documentation to include a manual implementation guide for lore entry management.
- Added a manual implementation guide for BP_NarrativeTriggerVolume, detailing trigger volume setup and action execution.
- Enhanced BPC_EndingAccumulator documentation with a manual implementation guide for ending evaluation.
- Updated BPC_HitReactionSystem with a manual implementation guide for hit reaction management.
- Added a manual implementation guide for BPC_RecoilSystem, detailing recoil application and recovery processes.
- Introduced DT_ProjectTags.csv to define gameplay tags for various systems, enhancing data-driven design capabilities.
2026-05-19 18:48:37 +03:00

190 lines
8.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 38 — BPC_NarrativeStateSystem
## Blueprint Spec — UE 5.55.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.
---
## Manual Implementation Guide
### Class Setup
1. Create Blueprint Class: Parent = `ActorComponent`, Name = `BPC_NarrativeStateSystem`
2. Add to Player Character or GameState (if shared)
3. Implement Interface: `I_Persistable`
### Variable Init (BeginPlay)
```
Event BeginPlay
├─ Set NarrativeFlags = empty Map<GameplayTag, Boolean>
├─ Set NarrativeValues = empty Map<GameplayTag, Float>
├─ Set NarrativeHistory = empty Array<GameplayTag>
├─ Set MaxHistorySize = 500
└─ If implementing I_Persistable: register with SS_SaveManager
```
### Function Node-by-Node
#### `SetFlag(Tag: GameplayTag, Value: Boolean)` → `void`
```
Step 1: OldValue = NarrativeFlags.Find(Tag) or false
Step 2: NarrativeFlags.Add(Tag, Value) ← Map Add (overwrites if exists)
Step 3: If Value == true AND OldValue == false:
NarrativeHistory.Add(Tag)
If NarrativeHistory.Length > MaxHistorySize: Remove oldest entry
Step 4: Fire OnFlagChanged(Tag, Value)
Step 5: Notify I_Persistable: Mark dirty for save
```
**Nodes:** `Map Find`, `Map Add`, `Array Add`, `Array Length`, `Remove Index 0`
#### `SetValue(Tag, Value: Float)` → `void`
```
Step 1: NarrativeValues.Add(Tag, Value)
Step 2: Fire OnValueChanged(Tag, Value)
```
#### `GetFlag(Tag)` → `Boolean` *(Pure)*
```
NarrativeFlags.Find(Tag) → if found: return value, else: return false
```
#### `HasAllFlags(Tags: Array<GameplayTag>)` → `Boolean`
```
ForEach Tags:
If GetFlag(ArrayElement) == false → Return false
Return true
```
#### `CollectState()` → `S_WorldObjectState` *(I_Persistable)*
```
Step 1: Create S_WorldObjectState
Step 2: Serialize NarrativeFlags: ForEach → store (Tag, Value) as string pairs in CustomData
Step 3: Serialize NarrativeValues similarly
Step 4: Return struct
```
#### `RestoreState(Data: S_WorldObjectState)` *(I_Persistable)*
```
Step 1: Clear NarrativeFlags, NarrativeValues, NarrativeHistory
Step 2: Parse CustomData → ForEach entry → NarrativeFlags.Add(Tag, BoolValue)
Step 3: Parse values → NarrativeValues.Add(Tag, FloatValue)
```
### Build Checklist
- [ ] Create BPC_NarrativeStateSystem, add to Player Character
- [ ] Define variables: NarrativeFlags (Map), NarrativeValues (Map), NarrativeHistory (Array), MaxHistorySize
- [ ] Implement SetFlag/GetFlag with map operations
- [ ] Implement SetValue/GetValue for numeric values
- [ ] Implement HasAllFlags/HasAnyFlags for batch queries
- [ ] Implement CollectState/RestoreState for I_Persistable
- [ ] Create OnFlagChanged/OnValueChanged event dispatchers
- [ ] Test: call SetFlag → verify OnFlagChanged fires → other systems react