- 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.
190 lines
8.1 KiB
Markdown
190 lines
8.1 KiB
Markdown
# 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.
|
||
|
||
---
|
||
|
||
## 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 |