add blueprints
This commit is contained in:
114
docs/blueprints/07-narrative/58_BPC_NarrativeStateSystem.md
Normal file
114
docs/blueprints/07-narrative/58_BPC_NarrativeStateSystem.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# 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.
|
||||
117
docs/blueprints/07-narrative/59_BPC_ObjectiveSystem.md
Normal file
117
docs/blueprints/07-narrative/59_BPC_ObjectiveSystem.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# 39 — BPC_ObjectiveSystem
|
||||
|
||||
## Blueprint Spec — UE 5.5–5.7
|
||||
|
||||
---
|
||||
|
||||
### Parent Class
|
||||
`ActorComponent`
|
||||
|
||||
### Dependencies
|
||||
- Gameplay Tag System
|
||||
- [`BPC_NarrativeStateSystem`](58_BPC_NarrativeStateSystem.md)
|
||||
- [`WBP_ObjectiveDisplay`](../06-ui/35_WBP_InteractionUI.md) (via dispatcher)
|
||||
- [`BPC_JournalSystem`](41_BPC_JournalSystem.md)
|
||||
|
||||
### Purpose
|
||||
Tracks active, completed, and failed objectives. Supports main objectives, sub-objectives, hidden objectives, and optional objectives. Acts as the query layer for UI and journal.
|
||||
|
||||
### Responsibilities
|
||||
- Activate objectives by tag
|
||||
- Complete / fail objectives by tag or narrative flag trigger
|
||||
- Track objective dependency chains (must complete A before B activates)
|
||||
- Notify UI and journal on changes
|
||||
- Support objectives hidden until discovery condition met
|
||||
- Persist objective state via [`I_Persistable`](../01-core/29_I_Persistable.md)
|
||||
|
||||
### Does NOT Handle
|
||||
- What completing an objective does in the world (that is story content)
|
||||
- UI display of objectives (that is `WBP_ObjectiveDisplay`)
|
||||
- Ending condition evaluation
|
||||
|
||||
### Variables
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `AllObjectives` | Map (GameplayTag → S_ObjectiveState) | Full objective register |
|
||||
| `ActiveObjectiveTags` | Array of GameplayTag | Currently active objectives |
|
||||
| `CompletedObjectiveTags` | Array of GameplayTag | Completed objectives |
|
||||
| `FailedObjectiveTags` | Array of GameplayTag | Failed objectives |
|
||||
| `ObjectiveOrderPriority` | Array of GameplayTag | Display sort order for UI |
|
||||
|
||||
### Enums
|
||||
|
||||
| Enum | Values | Description |
|
||||
|------|--------|-------------|
|
||||
| `E_ObjectiveStatus` | Inactive, Active, Complete, Failed, Hidden | Objective lifecycle |
|
||||
|
||||
### Structs
|
||||
|
||||
| Struct | Fields | Description |
|
||||
|--------|--------|-------------|
|
||||
| `S_ObjectiveState` | ObjectiveTag: GameplayTag, Status: E_ObjectiveStatus, DisplayText: FText, Description: FText, SubObjectives: Array of S_ObjectiveState, Dependencies: Array of GameplayTag, bIsHidden: Bool, bIsOptional: Bool | Runtime objective state |
|
||||
| `S_ObjectiveDisplayData` | ObjectiveTag: GameplayTag, DisplayText: FText, bIsComplete: Bool, bIsOptional: Bool | Lightweight UI snapshot |
|
||||
|
||||
### Functions / Events
|
||||
|
||||
| Name | Inputs | Outputs | Description |
|
||||
|------|--------|---------|-------------|
|
||||
| `ActivateObjective` | ObjectiveTag: GameplayTag | — | Sets objective Active, checks dependencies |
|
||||
| `CompleteObjective` | ObjectiveTag: GameplayTag | — | Marks complete, broadcasts, unlocks dependents |
|
||||
| `FailObjective` | ObjectiveTag: GameplayTag | — | Marks failed |
|
||||
| `GetActiveObjectives` | — | Array of S_ObjectiveDisplayData | For UI consumption |
|
||||
| `GetCompletedObjectives` | — | Array of GameplayTag | Status check |
|
||||
| `GetFailedObjectives` | — | Array of GameplayTag | Status check |
|
||||
| `IsObjectiveComplete` | ObjectiveTag: GameplayTag | Bool | Single check |
|
||||
| `IsObjectiveActive` | ObjectiveTag: GameplayTag | Bool | Single check |
|
||||
| `RevealHiddenObjective` | ObjectiveTag: GameplayTag | — | Shows previously hidden objective |
|
||||
| `RegisterObjectiveFromDataAsset` | ObjectiveTag: GameplayTag, DataAsset | — | Registers an objective definition from a DA_ObjectiveData |
|
||||
| `CheckDependenciesMet` | ObjectiveTag: GameplayTag | Bool | Returns true if all dependency objectives are complete |
|
||||
| `CollectState` (I_Persistable) | — | S_WorldObjectState | Serializes objective state |
|
||||
| `RestoreState` (I_Persistable) | Data: S_WorldObjectState | — | Deserializes objective state |
|
||||
|
||||
### Event Dispatchers
|
||||
|
||||
| Name | Parameters | Fired When |
|
||||
|------|-----------|-----------|
|
||||
| `OnObjectiveActivated` | ObjectiveTag: GameplayTag, Data: S_ObjectiveDisplayData | New objective added to active list |
|
||||
| `OnObjectiveCompleted` | ObjectiveTag: GameplayTag | Objective marked complete |
|
||||
| `OnObjectiveFailed` | ObjectiveTag: GameplayTag | Objective marked failed |
|
||||
| `OnObjectiveRevealed` | ObjectiveTag: GameplayTag | Hidden objective revealed |
|
||||
| `OnAllObjectivesComplete` | — | All active objectives complete (chapter milestone) |
|
||||
|
||||
### Blueprint Flow
|
||||
|
||||
```
|
||||
[ActivateObjective called]
|
||||
└─► Look up objective in AllObjectives map
|
||||
└─► Check Dependencies:
|
||||
│ └─► DependenciesMet? → Set status = Active
|
||||
│ └─► Not met? → Set status = Inactive, wait for dependency completion
|
||||
└─► If Hidden → bIsHidden check
|
||||
└─► Add to ActiveObjectiveTags
|
||||
└─► Broadcast OnObjectiveActivated
|
||||
└─► Notify UI and JournalSystem
|
||||
|
||||
[CompleteObjective called]
|
||||
└─► Validate objective is currently Active
|
||||
└─► Set status = Complete
|
||||
└─► Move from ActiveObjectiveTags to CompletedObjectiveTags
|
||||
└─► Broadcast OnObjectiveCompleted
|
||||
└─► Check dependent objectives for activation
|
||||
└─► Check if AllObjectivesComplete → broadcast milestone
|
||||
└─► Set narrative flag via BPC_NarrativeStateSystem
|
||||
```
|
||||
|
||||
### Communications With
|
||||
|
||||
| Target System | Method | Why |
|
||||
|---------------|--------|-----|
|
||||
| [`BPC_NarrativeStateSystem`](58_BPC_NarrativeStateSystem.md) | Direct + Dispatcher | Flag-driven objective activation / completion |
|
||||
| [`WBP_ObjectiveDisplay`](../06-ui/35_WBP_InteractionUI.md) | Dispatcher | UI updates |
|
||||
| [`WBP_HUDController`](../06-ui/33_WBP_HUD.md) | Dispatcher | Objective display visibility |
|
||||
| [`BPC_JournalSystem`](41_BPC_JournalSystem.md) | Direct | Journal entries on objective events |
|
||||
| [`SS_SaveManager`](../05-save/28_SS_SaveManager.md) | [`I_Persistable`](../01-core/29_I_Persistable.md) | Objective state persistence |
|
||||
|
||||
### Reuse Notes
|
||||
Define objectives via `DA_ObjectiveData` data assets (one per objective) that specify display text, dependencies, associated narrative flag, and optional/hidden flags. The objective system reads from these assets at level start. Adding a new objective type (like timed objectives) requires adding an `S_TimedObjective` struct extension and a timer function — no system redesign needed.
|
||||
122
docs/blueprints/07-narrative/60_BPC_DialoguePlaybackSystem.md
Normal file
122
docs/blueprints/07-narrative/60_BPC_DialoguePlaybackSystem.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# 40 — BPC_DialoguePlaybackSystem
|
||||
|
||||
## Blueprint Spec — UE 5.5–5.7
|
||||
|
||||
---
|
||||
|
||||
### Parent Class
|
||||
`ActorComponent`
|
||||
|
||||
### Dependencies
|
||||
- [`DA_DialogueSequence`](47_DA_NarrativeDataAssets.md) data assets
|
||||
- [`WBP_SubtitleDisplay`](../06-ui/49_WBP_SubtitleDisplay.md)
|
||||
- [`BPC_NarrativeStateSystem`](58_BPC_NarrativeStateSystem.md)
|
||||
- [`BPC_DialogueChoiceSystem`](41_BPC_DialogueChoiceSystem.md)
|
||||
|
||||
### Purpose
|
||||
Manages the playback of dialogue sequences: line queuing, timing, subtitle routing, audio playback, and lip-sync. Serves as the audio/visual delivery layer for all spoken narrative content.
|
||||
|
||||
### Responsibilities
|
||||
- Receive dialogue sequence data from `DA_DialogueSequence`
|
||||
- Queue lines and play in order with timing
|
||||
- Trigger subtitle display via dispatcher
|
||||
- Play voiceover audio
|
||||
- Fire narrative flags on line completion (if configured in sequence data)
|
||||
- Pause/interrupt dialogue on player action or external event
|
||||
- Support skip-to-next-line and full-skip-sequence
|
||||
|
||||
### Does NOT Handle
|
||||
- Choice presentation (that is [`BPC_DialogueChoiceSystem`](41_BPC_DialogueChoiceSystem.md))
|
||||
- What dialogue plays when (that is level or narrative flow)
|
||||
- Subtitle styling (that is `WBP_SubtitleDisplay`)
|
||||
|
||||
### Variables
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `ActiveSequence` | DA_DialogueSequence | Currently playing sequence asset |
|
||||
| `LineQueue` | Array of S_DialogueLine | Remaining lines to play |
|
||||
| `bIsPlaying` | Bool | Dialogue currently active |
|
||||
| `bIsPaused` | Bool | Dialogue paused |
|
||||
| `CurrentLineIndex` | Integer | Index in sequence |
|
||||
| `LineTimer` | TimerHandle | Auto-advance timer |
|
||||
| `bBlockInputWhilePlaying` | Bool | Suppress player input during dialogue |
|
||||
|
||||
### Structs
|
||||
|
||||
| Struct | Fields | Description |
|
||||
|--------|--------|-------------|
|
||||
| `S_DialogueLine` | SpeakerTag: GameplayTag, LineText: FText, VoiceAudio: USoundBase, Duration: Float, LipSyncData: UAnimSequence, FlagToSetOnComplete: GameplayTag, AnimTag: GameplayTag, bIsChoicePoint: Bool | One dialogue line with metadata |
|
||||
| `S_DialoguePlaybackOptions` | bCanSkipLine: Bool, bCanSkipSequence: Bool, bShowSubtitles: Bool, SubtitleDelay: Float | Per-sequence playback settings |
|
||||
|
||||
### Functions / Events
|
||||
|
||||
| Name | Inputs | Outputs | Description |
|
||||
|------|--------|---------|-------------|
|
||||
| `PlaySequence` | Sequence: DA_DialogueSequence | — | Loads and begins playback of a dialogue sequence |
|
||||
| `PlaySequenceWithOptions` | Sequence, Options: S_DialoguePlaybackOptions | — | Play with overrides |
|
||||
| `QueueSequence` | Sequence | — | Adds sequence to pending queue (for chaining) |
|
||||
| `PlayNextLine` | — | — | Advances to next line in queue |
|
||||
| `SkipCurrentLine` | — | — | Ends current line early, plays next |
|
||||
| `SkipSequence` | — | — | Aborts entire sequence |
|
||||
| `PauseDialogue` | — | — | Pause audio, hold subtitles |
|
||||
| `ResumeDialogue` | — | — | Resume from pause |
|
||||
| `IsDialoguePlaying` | — | Bool | Query |
|
||||
| `SetSpeakerOverride` | SpeakerTag: GameplayTag | — | Override speaker for accessibility |
|
||||
| `GetCurrentLine` | — | S_DialogueLine | For UI binding |
|
||||
| `GetRemainingLineCount` | — | Integer | For UI progress indicator |
|
||||
| `EnqueueDialogueFromVolume` | OverlapActor | — | Called by trigger volume overlap |
|
||||
|
||||
### Event Dispatchers
|
||||
|
||||
| Name | Parameters | Fired When |
|
||||
|------|-----------|-----------|
|
||||
| `OnDialogueStarted` | SequenceTag: GameplayTag | Sequence begins |
|
||||
| `OnLineStarted` | Line: S_DialogueLine | New line begins playback |
|
||||
| `OnLineCompleted` | Line: S_DialogueLine | Line audio finishes |
|
||||
| `OnSequenceCompleted` | SequenceTag: GameplayTag | Full sequence done |
|
||||
| `OnDialogueSkipped` | SequenceTag: GameplayTag | Player skipped sequence |
|
||||
| `OnDialoguePaused` | — | Pause triggered |
|
||||
| `OnDialogueResumed` | — | Resume triggered |
|
||||
| `OnChoicePointReached` | Choices: Array of S_DialogueChoice | Sequence reaches a branching point |
|
||||
|
||||
### Blueprint Flow
|
||||
|
||||
```
|
||||
[PlaySequence called]
|
||||
└─► If bIsPlaying → return (or QueueSequence)
|
||||
└─► Set bIsPlaying = true
|
||||
└─► Validate sequence conditions (RequiredFlags from DA_DialogueSequence)
|
||||
└─► Load line queue from sequence asset
|
||||
└─► Broadcast OnDialogueStarted
|
||||
└─► Call PlayNextLine
|
||||
|
||||
[PlayNextLine]
|
||||
└─► Queue empty? → Broadcast OnSequenceCompleted → bIsPlaying = false → return
|
||||
└─► Get next S_DialogueLine
|
||||
└─► Start LineTimer (Duration)
|
||||
└─► Play VoiceAudio
|
||||
└─► Broadcast OnLineStarted
|
||||
└─► If line has AnimTag → notify ABP via dispatcher
|
||||
└─► If line is choice point → hand off to BPC_DialogueChoiceSystem
|
||||
└─► Wait for LineTimer or SkipCurrentLine
|
||||
|
||||
[OnLineCompleted]
|
||||
└─► If line has FlagToSetOnComplete → BPC_NarrativeStateSystem.SetFlag()
|
||||
└─► Advance CurrentLineIndex
|
||||
└─► Call PlayNextLine
|
||||
```
|
||||
|
||||
### Communications With
|
||||
|
||||
| Target System | Method | Why |
|
||||
|---------------|--------|-----|
|
||||
| [`WBP_SubtitleDisplay`](../06-ui/49_WBP_SubtitleDisplay.md) | Dispatcher | Show/hide subtitles |
|
||||
| [`BPC_NarrativeStateSystem`](58_BPC_NarrativeStateSystem.md) | Direct | Set flags on line completion |
|
||||
| [`BPC_DialogueChoiceSystem`](41_BPC_DialogueChoiceSystem.md) | Dispatcher | Hand off at choice points |
|
||||
| [`BPC_CameraStateLayer`](../02-player/14_BPC_CameraStateLayer.md) | Dispatcher | Cinematic camera mode for dialogue |
|
||||
| [`BPC_EmbodimentSystem`](../02-player/13_BPC_EmbodimentSystem.md) | Dispatcher | Gesture animation tags |
|
||||
| [`GI_GameFramework`](../01-core/04_GI_GameFramework.md) | Direct | Set game phase during dialogue |
|
||||
|
||||
### Reuse Notes
|
||||
`DA_DialogueSequence` data assets hold all content — add new sequences per project without touching this system. Voice audio is optional: sequences work without audio (text-only dialogue). Lip-sync data is per-line and can use audio-driven or procedural lip sync.
|
||||
107
docs/blueprints/07-narrative/61_BPC_DialogueChoiceSystem.md
Normal file
107
docs/blueprints/07-narrative/61_BPC_DialogueChoiceSystem.md
Normal file
@@ -0,0 +1,107 @@
|
||||
# 41 — BPC_DialogueChoiceSystem
|
||||
|
||||
## Blueprint Spec — UE 5.5–5.7
|
||||
|
||||
---
|
||||
|
||||
### Parent Class
|
||||
`ActorComponent`
|
||||
|
||||
### Dependencies
|
||||
- [`BPC_NarrativeStateSystem`](58_BPC_NarrativeStateSystem.md)
|
||||
- [`BPC_DialoguePlaybackSystem`](40_BPC_DialoguePlaybackSystem.md)
|
||||
- [`WBP_DialogueChoiceDisplay`](../06-ui/46_WBP_DialogueChoiceDisplay.md)
|
||||
- [`DA_DialogueSequence`](48_DA_NarrativeDataAssets.md)
|
||||
|
||||
### Purpose
|
||||
Presents branching dialogue choices to the player and routes the selected response back to the narrative system. Manages choice availability based on narrative flags and time limits.
|
||||
|
||||
### Responsibilities
|
||||
- Receive choice set from dialogue flow (via dispatcher from `BPC_DialoguePlaybackSystem`)
|
||||
- Filter choices by required flags (only show choices player qualifies for)
|
||||
- Display choices via `WBP_DialogueChoiceDisplay`
|
||||
- Apply time limit if configured (auto-select default on expiry)
|
||||
- Route selected choice tag to `BPC_NarrativeStateSystem`
|
||||
- Trigger consequence dialogue branches by returning next sequence tag
|
||||
|
||||
### Does NOT Handle
|
||||
- Playing dialogue lines (that is `BPC_DialoguePlaybackSystem`)
|
||||
- Evaluating narrative consequences beyond setting choice flag (that is `BPC_BranchingConsequenceSystem`)
|
||||
- UI visual styling (that is `WBP_DialogueChoiceDisplay`)
|
||||
|
||||
### Variables
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `CurrentChoices` | Array of S_DialogueChoice | Available options for active choice |
|
||||
| `DefaultChoiceIndex` | Integer | Auto-selected if timer expires |
|
||||
| `ChoiceTimeLimit` | Float | Seconds before auto-select (0 = no limit) |
|
||||
| `ChoiceTimer` | TimerHandle | Countdown timer |
|
||||
| `bChoiceActive` | Bool | Player is currently choosing |
|
||||
| `TimeRemaining` | Float | Remaining time for UI display |
|
||||
|
||||
### Structs
|
||||
|
||||
| Struct | Fields | Description |
|
||||
|--------|--------|-------------|
|
||||
| `S_DialogueChoice` | ChoiceText: FText, ResultFlagTag: GameplayTag, NextSequenceTag: GameplayTag, RequiredFlagTag: GameplayTag, bIsHidden: Bool, Priority: Integer, FlavorText: FText (tooltip/thought) | One choice option |
|
||||
|
||||
### Functions / Events
|
||||
|
||||
| Name | Inputs | Outputs | Description |
|
||||
|------|--------|---------|-------------|
|
||||
| `PresentChoices` | Choices: Array of S_DialogueChoice, TimeLimit: Float | — | Opens choice UI and starts timer |
|
||||
| `SelectChoice` | ChoiceIndex: Integer | — | Player or system selects a choice |
|
||||
| `GetValidChoices` | Choices: Array of S_DialogueChoice | Array of S_DialogueChoice | Filters choices by RequiredFlagTag against narrative state |
|
||||
| `HasValidChoices` | Choices: Array | Bool | At least one choice available? |
|
||||
| `OnChoiceTimedOut` | — | — | Default choice auto-selected |
|
||||
| `CancelChoice` | — | — | Exits choice without selecting |
|
||||
| `ProcessSelectedChoice` | Choice: S_DialogueChoice | GameplayTag (NextSequenceTag) | Sets narrative flag and returns next sequence |
|
||||
| `IsChoiceActive` | — | Bool | Query |
|
||||
|
||||
### Event Dispatchers
|
||||
|
||||
| Name | Parameters | Fired When |
|
||||
|------|-----------|-----------|
|
||||
| `OnChoicesPresented` | Choices: Array of S_DialogueChoice | Choice UI opens |
|
||||
| `OnChoiceSelected` | SelectedChoice: S_DialogueChoice, ChoiceIndex: Integer | Player makes selection |
|
||||
| `OnChoiceTimedOut` | DefaultChoiceIndex: Integer | Timer expired |
|
||||
| `OnChoiceCancelled` | — | Choice dismissed without selection |
|
||||
| `OnChoiceCompleted` | NextSequenceTag: GameplayTag | Choice processed, ready for next dialogue |
|
||||
|
||||
### Blueprint Flow
|
||||
|
||||
```
|
||||
[PresentChoices called]
|
||||
└─► Call GetValidChoices (filter by narrative flags)
|
||||
└─► If no valid choices → skip (choose default or cancel)
|
||||
└─► Set CurrentChoices to valid set
|
||||
└─► Set bChoiceActive = true
|
||||
└─► Broadcast OnChoicesPresented to WBP_DialogueChoiceDisplay
|
||||
└─► If TimeLimit > 0 → start ChoiceTimer
|
||||
|
||||
[SelectChoice called]
|
||||
└─► Validate ChoiceIndex is in range
|
||||
└─► Get selected S_DialogueChoice
|
||||
└─► Clear ChoiceTimer
|
||||
└─► Broadcast OnChoiceSelected
|
||||
└─► Call ProcessSelectedChoice
|
||||
|
||||
[ProcessSelectedChoice]
|
||||
└─► If ResultFlagTag is valid → BPC_NarrativeStateSystem.SetFlag(ResultFlagTag)
|
||||
└─► Set bChoiceActive = false
|
||||
└─► Broadcast OnChoiceCompleted with NextSequenceTag
|
||||
└─► Hand NextSequenceTag back to BPC_DialoguePlaybackSystem
|
||||
```
|
||||
|
||||
### Communications With
|
||||
|
||||
| Target System | Method | Why |
|
||||
|---------------|--------|-----|
|
||||
| [`BPC_NarrativeStateSystem`](58_BPC_NarrativeStateSystem.md) | Direct | Set choice flag, check required flags |
|
||||
| [`BPC_DialoguePlaybackSystem`](40_BPC_DialoguePlaybackSystem.md) | Dispatcher (receives) + Direct (returns) | Receives choice points, returns next sequence |
|
||||
| [`WBP_DialogueChoiceDisplay`](../06-ui/46_WBP_DialogueChoiceDisplay.md) | Dispatcher | Opens/closes choice UI |
|
||||
| [`BPC_BranchingConsequenceSystem`](42_BPC_BranchingConsequenceSystem.md) | Dispatcher | Choice flag changes trigger consequence evaluation |
|
||||
|
||||
### Reuse Notes
|
||||
Choice filtering by RequiredFlagTag allows context-sensitive dialogue without branching logic in the system. Choices can be hidden (e.g., secret dialogue options only appear if player has a specific lore unlock). The system handles all choice patterns: timed, untimed, locked, hidden, and priority-sorted.
|
||||
@@ -0,0 +1,127 @@
|
||||
# 42 — BPC_BranchingConsequenceSystem
|
||||
|
||||
## Blueprint Spec — UE 5.5–5.7
|
||||
|
||||
---
|
||||
|
||||
### Parent Class
|
||||
`ActorComponent`
|
||||
|
||||
### Dependencies
|
||||
- [`BPC_NarrativeStateSystem`](58_BPC_NarrativeStateSystem.md)
|
||||
- [`DA_ConsequenceRule`](48_DA_NarrativeDataAssets.md)
|
||||
- [`BPC_ObjectiveSystem`](39_BPC_ObjectiveSystem.md)
|
||||
- [`BPC_DialoguePlaybackSystem`](40_BPC_DialoguePlaybackSystem.md)
|
||||
|
||||
### Purpose
|
||||
Evaluates narrative consequences when flags change. Listens for flag changes across the narrative state and fires off deferred or immediate consequences: new dialogue, objective updates, world-state changes, or scene transitions.
|
||||
|
||||
### Responsibilities
|
||||
- Watch for flag changes (via dispatcher from `BPC_NarrativeStateSystem`)
|
||||
- Match changed flags against `DA_ConsequenceRule` entries
|
||||
- Execute matched consequence actions (play dialogue, update objective, modify world, trigger cutscene)
|
||||
- Handle priority and stacking for multiple consequences firing simultaneously
|
||||
- Separate immediate vs. delayed consequences (allow narrative beat to breathe)
|
||||
|
||||
### Does NOT Handle
|
||||
- Setting flags (that is `BPC_NarrativeStateSystem`)
|
||||
- Playing dialogue lines (that is `BPC_DialoguePlaybackSystem`)
|
||||
- Evaluating choices (that is `BPC_DialogueChoiceSystem`)
|
||||
- Triggering cutscene play (that is `BPC_CutsceneBridge`)
|
||||
|
||||
### Variables
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `ConsequenceRules` | Array of DA_ConsequenceRule | Loaded rules from content registry |
|
||||
| `PendingConsequences` | Array of FConsequencePayload | Queue of delayed consequences |
|
||||
| `ActiveConsequenceCount` | Integer | Prevent stacking beyond max |
|
||||
| `MaxConcurrentConsequences` | Integer | Max simultaneous actions (default 3) |
|
||||
|
||||
### Structs
|
||||
|
||||
| Struct | Fields | Description |
|
||||
|--------|--------|-------------|
|
||||
| `FConsequencePayload` | RuleRef: DA_ConsequenceRule, TriggerFlag: GameplayTag, FireTime: Float (world time for delayed), bIsImmediate: Bool | Holds a consequence awaiting execution |
|
||||
|
||||
### Enums
|
||||
|
||||
| Enum | Values | Description |
|
||||
|------|--------|-------------|
|
||||
| `EConsequenceActionType` | PlayDialogue, UpdateObjective, SetWorldState, TriggerCutscene, UnlockLore, ModifyStat, SpawnActor, DestroyActor | Types of actions a consequence can perform |
|
||||
|
||||
### Functions / Events
|
||||
|
||||
| Name | Inputs | Outputs | Description |
|
||||
|------|--------|---------|-------------|
|
||||
| `RegisterConsequenceRule` | Rule: DA_ConsequenceRule | — | Add a rule to active set |
|
||||
| `OnFlagChanged` | FlagTag: GameplayTag, bIsSet: Bool | — | Dispatcher callback from narrative state |
|
||||
| `EvaluateRulesForFlag` | FlagTag: GameplayTag | Array of DA_ConsequenceRule | Find matching rules |
|
||||
| `ExecuteConsequence` | Rule: DA_ConsequenceRule | — | Fire immediate or queue delayed |
|
||||
| `ExecuteImmediateAction` | Action: FConsequenceData | — | Internal: performs single action |
|
||||
| `ProcessDelayedConsequences` | — | — | Called every tick or on timer for delayed queue |
|
||||
| `ClearPendingConsequences` | — | — | Clear all pending (e.g., on scene transition) |
|
||||
| `GetActiveRuleCount` | — | Integer | |
|
||||
|
||||
### Data: FConsequenceData (Inline in DA_ConsequenceRule)
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| ActionType | Enum(EConsequenceActionType) | What to do |
|
||||
| TargetTag | GameplayTag | Dialogue sequence, objective, or world flag to apply |
|
||||
| FloatValue | Float | Numeric modifier (e.g., stat change) |
|
||||
| DelaySeconds | Float | 0 = immediate, >0 = delayed |
|
||||
| bBlocking | Bool | If true, wait for this to complete before next |
|
||||
| Priority | Integer | Higher = execute first |
|
||||
|
||||
### Event Dispatchers
|
||||
|
||||
| Name | Parameters | Fired When |
|
||||
|------|-----------|-----------|
|
||||
| `OnConsequenceTriggered` | Rule: DA_ConsequenceRule, ActionType: EConsequenceActionType | Consequence begins execution |
|
||||
| `OnConsequenceCompleted` | Rule: DA_ConsequenceRule | Consequence finished |
|
||||
| `OnConsequenceQueueChanged` | PendingCount: Integer | Delayed queue size changed |
|
||||
|
||||
### Blueprint Flow
|
||||
|
||||
```
|
||||
[BPC_NarrativeStateSystem dispatches OnFlagChanged]
|
||||
└─► BPC_BranchingConsequenceSystem.OnFlagChanged(FlagTag, bIsSet)
|
||||
└─► EvaluateRulesForFlag(FlagTag)
|
||||
└─► For each matching DA_ConsequenceRule:
|
||||
└─► Check rule's required flag state matches current state
|
||||
└─► If match → ExecuteConsequence(Rule)
|
||||
|
||||
[ExecuteConsequence - immediate]
|
||||
└─► Broadcast OnConsequenceTriggered
|
||||
└─► ExecuteImmediateAction(Action)
|
||||
└─► Switch on ActionType:
|
||||
PlayDialogue → request BPC_DialoguePlaybackSystem.PlaySequence(TargetTag)
|
||||
UpdateObjective → request BPC_ObjectiveSystem.AddOrUpdateObjective(...)
|
||||
SetWorldState → BPC_NarrativeStateSystem.SetStateFlag(TargetTag, true)
|
||||
TriggerCutscene → request BPC_CutsceneBridge.BeginCutscene(TargetTag)
|
||||
UnlockLore → BPC_NarrativeStateSystem.UnlockLoreEntry(TargetTag)
|
||||
ModifyStat → through player's stat component
|
||||
SpawnActor → spawn from registry
|
||||
DestroyActor → destroy by tag lookup
|
||||
└─► Broadcast OnConsequenceCompleted
|
||||
|
||||
[ExecuteConsequence - delayed]
|
||||
└─► Create FConsequencePayload with FireTime = WorldTime + DelaySeconds
|
||||
└─► Add to PendingConsequences array
|
||||
└─► Sort by FireTime
|
||||
└─► Broadcast OnConsequenceQueueChanged
|
||||
```
|
||||
|
||||
### Communications With
|
||||
|
||||
| Target System | Method | Why |
|
||||
|---------------|--------|-----|
|
||||
| [`BPC_NarrativeStateSystem`](58_BPC_NarrativeStateSystem.md) | Dispatcher (receives) + Direct (sets world state) | Listens for flag changes, may set additional flags |
|
||||
| [`BPC_DialoguePlaybackSystem`](40_BPC_DialoguePlaybackSystem.md) | Direct | Trigger dialogue sequences as consequences |
|
||||
| [`BPC_ObjectiveSystem`](39_BPC_ObjectiveSystem.md) | Direct | Update/add objectives as consequences |
|
||||
| [`BPC_CutsceneBridge`](44_BPC_CutsceneBridge.md) | Direct | Trigger cutscenes as consequences |
|
||||
| [`BPC_LoreUnlockSystem`](46_BPC_LoreUnlockSystem.md) | Direct | Unlock lore entries |
|
||||
|
||||
### Reuse Notes
|
||||
Consequence rules are data-driven via `DA_ConsequenceRule`, enabling designers to author branch logic without blueprint edits. The system supports both immediate and delayed consequences, allowing dramatic pacing. Priority sorting ensures critical consequences fire first. Blocking flag prevents race conditions between sequential narrative beats.
|
||||
131
docs/blueprints/07-narrative/63_BPC_TrialScenarioSystem.md
Normal file
131
docs/blueprints/07-narrative/63_BPC_TrialScenarioSystem.md
Normal file
@@ -0,0 +1,131 @@
|
||||
# 43 — BPC_TrialScenarioSystem
|
||||
|
||||
## Blueprint Spec — UE 5.5–5.7
|
||||
|
||||
---
|
||||
|
||||
### Parent Class
|
||||
`ActorComponent`
|
||||
|
||||
### Dependencies
|
||||
- [`BPC_NarrativeStateSystem`](58_BPC_NarrativeStateSystem.md)
|
||||
- [`BPC_ObjectiveSystem`](39_BPC_ObjectiveSystem.md)
|
||||
- [`DA_ScenarioData`](../12-content/48_DA_NarrativeDataAssets.md)
|
||||
- [`BPC_CheckpointSystem`](../04-save/34_BPC_CheckpointSystem.md)
|
||||
- [`BPC_DeathHandlingSystem`](../04-save/35_BPC_DeathHandlingSystem.md)
|
||||
|
||||
### Purpose
|
||||
Manages trial-based gameplay scenarios: combat gauntlets, escape sequences, investigation time-limits, survival waves. Tracks trial state (setup / active / success / fail), enforces rules, and reports outcome to the narrative system.
|
||||
|
||||
### Responsibilities
|
||||
- Load scenario definition from `DA_ScenarioData`
|
||||
- Initialize world state for the trial (spawn enemies, lock doors, set lighting)
|
||||
- Track trial objectives and completion conditions
|
||||
- Monitor failure conditions (player death, time expiry, target escape)
|
||||
- Broadcast success/failure to narrative state
|
||||
- Clean up trial elements on completion
|
||||
|
||||
### Does NOT Handle
|
||||
- Individual enemy AI (that is Phase 8 AI system)
|
||||
- Lighting or atmosphere changes (that is Phase 9 AtmosphereController)
|
||||
- Checkpoint creation (that is BPC_CheckpointSystem)
|
||||
|
||||
### Variables
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `ActiveScenario` | DA_ScenarioData | Currently running scenario (null if none) |
|
||||
| `ScenarioState` | EScenarioState | Current phase of scenario |
|
||||
| `ScenarioStartTime` | Float | World time when scenario began |
|
||||
| `SuccessTags` | Array of GameplayTag | Tags to set on success (fired to NarrativeState) |
|
||||
| `FailureTags` | Array of GameplayTag | Tags to set on failure |
|
||||
| `bHasCheckedFailure` | Bool | Already evaluated fail conditions this tick |
|
||||
|
||||
### Enums
|
||||
|
||||
| Enum | Values | Description |
|
||||
|------|--------|-------------|
|
||||
| `EScenarioState` | Inactive, SetupRunning, ActiveRunning, Success, Failure, Cleanup | Lifecycle of a trial scenario |
|
||||
|
||||
### Structs
|
||||
|
||||
| Struct | Fields | Description |
|
||||
|--------|--------|-------------|
|
||||
| `FScenarioObjective` | TargetTag: GameplayTag, RequiredCount: Integer, CurrentCount: Integer, bIsComplete: Bool | A tracked objective within the scenario |
|
||||
| `FScenarioCompletionReport` | bSuccess: Bool, ElapsedTime: Float, ObjectivesCompleted: Integer, ObjectivesTotal: Integer, FlagsSet: Array of GameplayTag | Outcome report for narrative |
|
||||
|
||||
### Functions / Events
|
||||
|
||||
| Name | Inputs | Outputs | Description |
|
||||
|------|--------|---------|-------------|
|
||||
| `BeginScenario` | Scenario: DA_ScenarioData | — | Start a new trial scenario |
|
||||
| `EndScenario` | bIsSuccess: Bool | — | End current scenario with outcome |
|
||||
| `UpdateObjectiveProgress` | ObjectiveTag: GameplayTag, Delta: Integer | — | Increment/update objective tracker |
|
||||
| `CheckAllObjectives` | — | Bool | Have all objectives been met? |
|
||||
| `CheckFailureConditions` | — | Bool | Has any failure condition triggered? |
|
||||
| `GetTimeRemaining` | — | Float | Time left if scenario has time limit |
|
||||
| `GetElapsedTime` | — | Float | Seconds since scenario started |
|
||||
| `GetScenarioCompletionReport` | — | FScenarioCompletionReport | |
|
||||
| `AbortScenario` | — | — | Force-end with failure, clean up |
|
||||
| `IsScenarioActive` | — | Bool | |
|
||||
|
||||
### Event Dispatchers
|
||||
|
||||
| Name | Parameters | Fired When |
|
||||
|------|-----------|-----------|
|
||||
| `OnScenarioStarted` | Scenario: DA_ScenarioData | Scenario begins setup |
|
||||
| `OnScenarioActive` | Scenario: DA_ScenarioData | Setup complete, trial is live |
|
||||
| `OnObjectiveProgressed` | ObjectiveTag: GameplayTag, Progress: Integer, Required: Integer | Any objective count changed |
|
||||
| `OnScenarioSuccess` | Report: FScenarioCompletionReport | All objectives complete |
|
||||
| `OnScenarioFailure` | Report: FScenarioCompletionReport | Failure condition met |
|
||||
| `OnScenarioAborted` | Scenario: DA_ScenarioData | Force-aborted |
|
||||
| `OnScenarioCleanup` | Scenario: DA_ScenarioData | Cleanup complete |
|
||||
|
||||
### Blueprint Flow
|
||||
|
||||
```
|
||||
[BeginScenario: DA_ScenarioData]
|
||||
└─► Set ScenarioState = SetupRunning
|
||||
└─► Broadcast OnScenarioStarted
|
||||
└─► Trigger checkpoint auto-save (if configured)
|
||||
└─► Execute scenario setup actions from DA_ScenarioData:
|
||||
└─► Spawn enemies on spawn points
|
||||
└─► Lock / unlock doors by tag
|
||||
└─► Set initial objective state from scenario definition
|
||||
└─► Apply lighting overrides (via AtmosphereController if present)
|
||||
└─► Set ScenarioState = ActiveRunning
|
||||
└─► Broadcast OnScenarioActive
|
||||
└─► Record ScenarioStartTime + start tick monitors
|
||||
|
||||
[Tick / UpdateObjectiveProgress]
|
||||
└─► CheckAllObjectives → if true → EndScenario(success = true)
|
||||
└─► If not bHasCheckedFailure → CheckFailureConditions
|
||||
└─► If failure condition true → EndScenario(success = false)
|
||||
|
||||
[EndScenario: bIsSuccess]
|
||||
└─► ScenarioState = Success or Failure
|
||||
└─► Build FScenarioCompletionReport
|
||||
└─► Broadcast appropriate dispatcher
|
||||
└─► Set narrative success/failure tags via BPC_NarrativeStateSystem
|
||||
└─► ScenarioState = Cleanup
|
||||
└─► Execute cleanup actions:
|
||||
└─► Despawn trial-specific actors
|
||||
└─► Reset doors, lights, etc.
|
||||
└─► Unlock doors that were locked for trial
|
||||
└─► Broadcast OnScenarioCleanup
|
||||
└─► ScenarioState = Inactive
|
||||
└─► ActiveScenario = null
|
||||
```
|
||||
|
||||
### Communications With
|
||||
|
||||
| Target System | Method | Why |
|
||||
|---------------|--------|-----|
|
||||
| [`BPC_NarrativeStateSystem`](58_BPC_NarrativeStateSystem.md) | Direct | Set success/failure flags upon completion |
|
||||
| [`BPC_ObjectiveSystem`](39_BPC_ObjectiveSystem.md) | Direct | Sync scenario objectives with objective UI |
|
||||
| [`BPC_CheckpointSystem`](../04-save/34_BPC_CheckpointSystem.md) | Direct | Create checkpoint on scenario start |
|
||||
| [`BPC_DeathHandlingSystem`](../04-save/35_BPC_DeathHandlingSystem.md) | Dispatcher | Player death triggers scenario failure |
|
||||
| Phase 8 AI | Indirect | Spawn/despawn enemy actors by tag |
|
||||
|
||||
### Reuse Notes
|
||||
Scenarios are fully data-driven via `DA_ScenarioData`. Designers configure spawn tags, objective tags, time limits, and cleanup actions without blueprint modifications. Supports mixed scenarios: combat + investigation, timed + untimed, survival + objective.
|
||||
142
docs/blueprints/07-narrative/64_BPC_CutsceneBridge.md
Normal file
142
docs/blueprints/07-narrative/64_BPC_CutsceneBridge.md
Normal file
@@ -0,0 +1,142 @@
|
||||
# 44 — BPC_CutsceneBridge
|
||||
|
||||
## Blueprint Spec — UE 5.5–5.7
|
||||
|
||||
---
|
||||
|
||||
### Parent Class
|
||||
`ActorComponent`
|
||||
|
||||
### Dependencies
|
||||
- [`BPC_NarrativeStateSystem`](58_BPC_NarrativeStateSystem.md)
|
||||
- [`BPC_DialoguePlaybackSystem`](40_BPC_DialoguePlaybackSystem.md)
|
||||
- [`BPC_CheckpointSystem`](../04-save/34_BPC_CheckpointSystem.md)
|
||||
- [`DA_CutsceneData`](48_DA_NarrativeDataAssets.md)
|
||||
|
||||
### Purpose
|
||||
Bridges gameplay and pre-authored cinematics. Manages cutscene triggers, playback, and cleanup. Handles player input suppression, camera transfer, HUD hiding, and seamless return to gameplay.
|
||||
|
||||
### Responsibilities
|
||||
- Load cutscene definition from `DA_CutsceneData`
|
||||
- Transition gameplay camera to cinematic camera
|
||||
- Suppress player input and hide HUD
|
||||
- Play Level Sequence actor or Sequencer track
|
||||
- Listen for sequence completion or skip input
|
||||
- Restore gameplay state on completion
|
||||
- Set narrative flags at cutscene milestones (start / beat / end)
|
||||
|
||||
### Does NOT Handle
|
||||
- Creating cutscene sequences in Sequencer (that is a content authoring task)
|
||||
- Dialogue during cutscenes (uses `BPC_DialoguePlaybackSystem` for subtitled lines)
|
||||
- Triggering cutscene based on narrative state (that is `BPC_NarrativeStateSystem` or level blueprints)
|
||||
|
||||
### Variables
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `ActiveCutscene` | DA_CutsceneData | Currently playing cutscene data |
|
||||
| `CutsceneSequence` | LevelSequenceActor | Reference to the spawned sequence |
|
||||
| `CinematicCameraActor` | CineCameraActor | Camera used during cutscene |
|
||||
| `bIsPlaying` | Bool | Currently in cutscene playback |
|
||||
| `bCanSkip` | Bool | Player can skip this cutscene |
|
||||
| `TimeBeforeSkip` | Float | Seconds before skip becomes available |
|
||||
| `bInputSuppressed` | Bool | Player input disabled |
|
||||
| `SkipHoldDuration` | Float | Seconds player must hold skip key |
|
||||
|
||||
### Enums
|
||||
|
||||
| Enum | Values | Description |
|
||||
|------|--------|-------------|
|
||||
| `ECutsceneTransitionType` | FadeInOut, HardCut, LetterBox, BlackBars | Visual transition style for cutscene |
|
||||
| `ECutsceneTriggerType` | OnVolumeEnter, OnNarrativeFlag, OnInteraction, OnLevelLoad, OnScenarioComplete | What triggers the cutscene |
|
||||
|
||||
### Structs
|
||||
|
||||
| Struct | Fields | Description |
|
||||
|--------|--------|-------------|
|
||||
| `FCutsceneMilestone` | TimeSeconds: Float, FlagTag: GameplayTag, bFireOnce: Bool | A narrative flag fired at a specific sequence time |
|
||||
| `FCutsceneSkipResult` | bWasSkipped: Bool, SkipTime: Float | Skip outcome |
|
||||
|
||||
### Functions / Events
|
||||
|
||||
| Name | Inputs | Outputs | Description |
|
||||
|------|--------|---------|-------------|
|
||||
| `PlayCutscene` | CutsceneData: DA_CutsceneData | — | Begin cutscene playback |
|
||||
| `OnCutsceneStarted` | — | — | Internal: after transition |
|
||||
| `OnCutsceneTick` | DeltaSeconds: Float | — | Check milestones, input, etc. |
|
||||
| `OnCutsceneEnded` | SkipResult: FCutsceneSkipResult | — | Cleanup and return to gameplay |
|
||||
| `SkipCutscene` | — | — | Player-initiated skip (with hold timer) |
|
||||
| `UpdateSkipHoldProgress` | DeltaSeconds: Float | Float (0-1) | For UI skip progress bar |
|
||||
| `SetNarrativeMilestone` | Milestone: FCutsceneMilestone | — | Fire flag at correct time |
|
||||
| `RestoreGameplayState` | — | — | Return camera, enable input, show HUD |
|
||||
| `CanSkipCutscene` | — | Bool | Checks if skip is available |
|
||||
| `GetActiveCutscene` | — | DA_CutsceneData | |
|
||||
|
||||
### Event Dispatchers
|
||||
|
||||
| Name | Parameters | Fired When |
|
||||
|------|-----------|-----------|
|
||||
| `OnCutscenePlayRequested` | CutsceneData: DA_CutsceneData | Cutscene about to play |
|
||||
| `OnCutsceneFadeOutStarted` | — | Fade out begins |
|
||||
| `OnCutsceneFadeInStarted` | — | Fade in begins (after black) |
|
||||
| `OnCutscenePlaying` | CutsceneData: DA_CutsceneData | Cutscene is actively playing |
|
||||
| `OnCutsceneMilestoneReached` | Milestone: FCutsceneMilestone | Narrative flag fired |
|
||||
| `OnCutsceneSkipAvailable` | — | Skip button becomes available |
|
||||
| `OnCutsceneSkipRequested` | — | Player holding skip |
|
||||
| `OnCutsceneSkipped` | — | Cutscene was skipped |
|
||||
| `OnCutsceneCompleted` | CutsceneData: DA_CutsceneData | Cutscene finished (skipped or ended) |
|
||||
|
||||
### Blueprint Flow
|
||||
|
||||
```
|
||||
[PlayCutscene: DA_CutsceneData]
|
||||
└─► Set bIsPlaying = true
|
||||
└─► Broadcast OnCutscenePlayRequested
|
||||
└─► Auto-save checkpoint (if configured)
|
||||
└─► Apply transition (fade out / letterbox)
|
||||
└─► Suppress input: set PlayerController input mode to UI Only
|
||||
└─► Hide HUD widgets (disable visibility on HUD parent)
|
||||
└─► Spawn LevelSequenceActor from DA_CutsceneData.SequenceSoftReference
|
||||
└─► If cinematics camera is in data → blend to it (SetViewTarget with blend)
|
||||
└─► Broadcast OnCutsceneFadeInStarted
|
||||
└─► Fade in
|
||||
└─► Broadcast OnCutscenePlaying
|
||||
└─► Set bCanSkip timer (if configured)
|
||||
|
||||
[OnCutsceneTick: DeltaSeconds]
|
||||
└─► Update milestones (check if any FCutsceneMilestone should fire)
|
||||
└─► If milestone reached → SetNarrativeMilestone → fire flag via BPC_NarrativeStateSystem
|
||||
└─► Update skip hold progress if player holding skip key
|
||||
└─► Check if sequence has finished → OnCutsceneEnded
|
||||
|
||||
[OnCutsceneEnded: SkipResult]
|
||||
└─► Broadcast milestone flags at end time if not already fired
|
||||
└─► RestoreGameplayState:
|
||||
└─► Blend back to player camera
|
||||
└─► Enable player input
|
||||
└─► Show HUD
|
||||
└─► Destroy LevelSequenceActor
|
||||
└─► Remove cinematic camera
|
||||
└─► Set bIsPlaying = false
|
||||
└─► Broadcast OnCutsceneCompleted
|
||||
|
||||
[SkipCutscene]
|
||||
└─► If !CanSkipCutscene → return
|
||||
└─► Broadcast OnCutsceneSkipped
|
||||
└─► Jump to end of sequence (or stop immediately)
|
||||
└─► Go to OnCutsceneEnded with SkipResult.bWasSkipped = true
|
||||
```
|
||||
|
||||
### Communications With
|
||||
|
||||
| Target System | Method | Why |
|
||||
|---------------|--------|-----|
|
||||
| [`BPC_NarrativeStateSystem`](58_BPC_NarrativeStateSystem.md) | Direct | Fire milestone flags during cutscene |
|
||||
| [`BPC_DialoguePlaybackSystem`](40_BPC_DialoguePlaybackSystem.md) | Direct | Play subtitled dialogue for spoken lines in cutscene |
|
||||
| [`BPC_CheckpointSystem`](../04-save/34_BPC_CheckpointSystem.md) | Direct | Auto-save before cutscene |
|
||||
| PlayerController | Direct | Suppress/restore input and view target |
|
||||
| HUD Widget | Dispatcher | Show/hide HUD |
|
||||
| [`BPC_TrialScenarioSystem`](43_BPC_TrialScenarioSystem.md) | Direct | Cutscene can trigger scenario start/end |
|
||||
|
||||
### Reuse Notes
|
||||
Cutscene data assets allow designers to configure skip availability, milestone flags, and transition types per cutscene without modifying the system. The milestone system enables narrative flags to fire at exact sequence timecodes for branching logic post-cutscene.
|
||||
138
docs/blueprints/07-narrative/65_BPC_LoreUnlockSystem.md
Normal file
138
docs/blueprints/07-narrative/65_BPC_LoreUnlockSystem.md
Normal file
@@ -0,0 +1,138 @@
|
||||
# 46 — BPC_LoreUnlockSystem
|
||||
|
||||
## Blueprint Spec — UE 5.5–5.7
|
||||
|
||||
---
|
||||
|
||||
### Parent Class
|
||||
`ActorComponent`
|
||||
|
||||
### Dependencies
|
||||
- [`BPC_NarrativeStateSystem`](58_BPC_NarrativeStateSystem.md)
|
||||
- [`DA_LoreEntryData`](48_DA_NarrativeDataAssets.md)
|
||||
- [`WBP_JournalDisplay`](../06-ui/43_WBP_JournalDisplay.md)
|
||||
|
||||
### Purpose
|
||||
Manages the discovery, unlocking, and tracking of lore entries (documents, notes, recordings, environmental texts, bestiary entries). Provides query methods for lore completeness, and dispatches events when new lore is discovered.
|
||||
|
||||
### Responsibilities
|
||||
- Register all discoverable lore entries from `DA_LoreEntryData` content
|
||||
- Unlock lore entries when narrative flags are set or when player picks up physical lore items
|
||||
- Track which lore entries have been read / unread
|
||||
- Provide category-based filtering (e.g., "All", "Notes", "Audio Logs", "Bestiary")
|
||||
- Dispatch notifications for newly discovered lore
|
||||
- Support lore completion tracking (X of Y discovered in a category)
|
||||
- Handle lore entry grouping (collections, series)
|
||||
|
||||
### Does NOT Handle
|
||||
- Displaying lore entries in UI (that is `WBP_JournalDisplay`)
|
||||
- Playing audio logs (that is `BPC_DialoguePlaybackSystem` or audio component)
|
||||
- Physical lore pickup interaction (that is `BPC_InteractionDetector`)
|
||||
|
||||
### Variables
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `AllLoreEntries` | Array of DA_LoreEntryData | All discoverable lore in game |
|
||||
| `UnlockedLoreTags` | Set of GameplayTag | Tags for unlocked entries |
|
||||
| `ReadLoreTags` | Set of GameplayTag | Tags for entries player has opened |
|
||||
| `LoreByCategory` | Map: GameplayTag (category) → Array of DA_LoreEntryData | Grouped for UI |
|
||||
| `UnreadCount` | Integer | Number of unread unlocked entries |
|
||||
| `NewLoreQueue` | Array of DA_LoreEntryData | Recently unlocked entries for notification |
|
||||
| `TotalLoreCount` | Integer | Total discoverable entries |
|
||||
| `TotalUnlockedCount` | Integer | Count of unlocked entries |
|
||||
|
||||
### Structs
|
||||
|
||||
| Struct | Fields | Description |
|
||||
|--------|--------|-------------|
|
||||
| `FLoreDiscovery` | Entry: DA_LoreEntryData, DiscoveredAt: Float (game time), DiscoverySource: FName (e.g., "pickup", "narrative", "exploration") | Record of a lore discovery event |
|
||||
| `FLoreCategoryProgress` | CategoryTag: GameplayTag, CategoryName: FText, TotalInCategory: Integer, UnlockedInCategory: Integer, ReadInCategory: Integer | Completion per category |
|
||||
|
||||
### Enums
|
||||
|
||||
| Enum | Values | Description |
|
||||
|------|--------|-------------|
|
||||
| `ELoreEntryType` | Document, AudioLog, Note, EnvironmentalText, BestiaryEntry, Collectible, Epistolary, VHSRecording, Photo | Type of lore entry (affects UI icon) |
|
||||
| `ELoreDiscoveryMethod` | OnPickup, OnNarrativeFlag, OnLocationEnter, OnInteraction, OnConsequence, OnEndingReward | How the entry is discovered |
|
||||
|
||||
### Functions / Events
|
||||
|
||||
| Name | Inputs | Outputs | Description |
|
||||
|------|--------|---------|-------------|
|
||||
| `RegisterLoreEntry` | Entry: DA_LoreEntryData | — | Add entry to tracking set |
|
||||
| `UnlockLoreByTag` | LoreTag: GameplayTag | Bool (success) | Unlock specific entry by tag |
|
||||
| `UnlockLoreByMethod` | DiscoveryMethod: ELoreDiscoveryMethod | Array of DA_LoreEntryData | Unlock all entries matching a discovery method |
|
||||
| `MarkLoreAsRead` | LoreTag: GameplayTag | — | Player has opened/viewed the entry |
|
||||
| `MarkLoreAsUnread` | LoreTag: GameplayTag | — | Reset read status |
|
||||
| `IsLoreUnlocked` | LoreTag: GameplayTag | Bool | Is the entry unlocked? |
|
||||
| `IsLoreRead` | LoreTag: GameplayTag | Bool |
|
||||
| `GetLoreByCategory` | CategoryTag: GameplayTag | Array of DA_LoreEntryData | Filter by category |
|
||||
| `GetAllUnlockedLore` | — | Array of DA_LoreEntryData |
|
||||
| `GetUnreadLore` | — | Array of DA_LoreEntryData |
|
||||
| `GetCategoryProgress` | CategoryTag: GameplayTag | FLoreCategoryProgress |
|
||||
| `GetOverallProgress` | — | FLoreCategoryProgress (total all categories) |
|
||||
| `GetLatestDiscoveries` | Count: Integer | Array of DA_LoreEntryData | Newest N unlocked entries |
|
||||
| `GetUnlockedCountByType` | Type: ELoreEntryType | Integer |
|
||||
| `DismissNewLoreNotification` | — | — | Clears new lore queue after UI displays |
|
||||
| `HasUnreadLore` | — | Bool |
|
||||
|
||||
### Event Dispatchers
|
||||
|
||||
| Name | Parameters | Fired When |
|
||||
|------|-----------|-----------|
|
||||
| `OnLoreEntryUnlocked` | Entry: DA_LoreEntryData, DiscoveryMethod: ELoreDiscoveryMethod | Any lore entry is newly unlocked |
|
||||
| `OnLoreEntryRead` | Entry: DA_LoreEntryData | Lore entry marked as read |
|
||||
| `OnLoreCategoryCompleted` | CategoryTag: GameplayTag, CategoryName: FText | All entries in a category discovered |
|
||||
| `OnNewLoreNotification` | NewEntries: Array of DA_LoreEntryData, Count: Integer | Batch of new lore for notification queue |
|
||||
| `OnLoreProgressUpdated` | OverallProgress: FLoreCategoryProgress | Any unlock/read changed progress |
|
||||
|
||||
### Blueprint Flow
|
||||
|
||||
```
|
||||
[Initialization]
|
||||
└─► At game start: load all DA_LoreEntryData from asset registry
|
||||
└─► Group by CategoryTag into LoreByCategory map
|
||||
└─► Set TotalLoreCount = AllLoreEntries.Num()
|
||||
└─► Bind to BPC_NarrativeStateSystem.OnFlagChanged for OnNarrativeFlag unlocks
|
||||
|
||||
[UnlockLoreByTag: LoreTag]
|
||||
└─► Find DA_LoreEntryData by LoreTag from AllLoreEntries
|
||||
└─► If not found → return false
|
||||
└─► If already in UnlockedLoreTags → return true (already unlocked, no duplicate notification)
|
||||
└─► Add LoreTag to UnlockedLoreTags
|
||||
└─► Increment TotalUnlockedCount
|
||||
└─► Add to NewLoreQueue
|
||||
└─► Broadcast OnLoreEntryUnlocked(Entry, DiscoveryMethod)
|
||||
└─► Broadcast OnLoreProgressUpdated
|
||||
└─► If NewLoreQueue size == 1 → broadcast OnNewLoreNotification
|
||||
└─► Check if category is now complete → broadcast OnLoreCategoryCompleted if yes
|
||||
└─► Return true
|
||||
|
||||
[MarkLoreAsRead: LoreTag]
|
||||
└─► If LoreTag not in UnlockedLoreTags → return
|
||||
└─► If already in ReadLoreTags → return
|
||||
└─► Add to ReadLoreTags
|
||||
└─► Decrement UnreadCount
|
||||
└─► Broadcast OnLoreEntryRead
|
||||
└─► Broadcast OnLoreProgressUpdated
|
||||
|
||||
[GetCategoryProgress: CategoryTag]
|
||||
└─► Get entries in this category
|
||||
└─► Count unlocked in category
|
||||
└─► Count read in category
|
||||
└─► Return FLoreCategoryProgress
|
||||
```
|
||||
|
||||
### Communications With
|
||||
|
||||
| Target System | Method | Why |
|
||||
|---------------|--------|-----|
|
||||
| [`BPC_NarrativeStateSystem`](58_BPC_NarrativeStateSystem.md) | Dispatcher (receives) + Direct (unlock by flag) | Narrative flags trigger lore unlocks |
|
||||
| [`WBP_JournalDisplay`](../06-ui/43_WBP_JournalDisplay.md) | Dispatcher | Notify UI of new lore, progress updates |
|
||||
| [`BPC_InteractionDetector`](../02-interaction/15_BPC_InteractionDetector.md) | Dispatcher (on pickup) | Physical lore items call UnlockLoreByTag |
|
||||
| [`BPC_BranchingConsequenceSystem`](42_BPC_BranchingConsequenceSystem.md) | Dispatcher | Consequences can unlock lore entries |
|
||||
| [Save System](../04-save/32_SS_SaveManager.md) | Direct (via I_Persistable) | Save unlocked/read state |
|
||||
|
||||
### Reuse Notes
|
||||
Pure data-driven: all lore content is defined in `DA_LoreEntryData` assets. The system requires zero blueprint changes to add new lore entries. Supports any mix of discovery methods (pickup, narrative flag, location trigger, consequence). Lore categories are defined by gameplay tags, allowing flexible grouping without code changes.
|
||||
250
docs/blueprints/07-narrative/66_DA_NarrativeDataAssets.md
Normal file
250
docs/blueprints/07-narrative/66_DA_NarrativeDataAssets.md
Normal file
@@ -0,0 +1,250 @@
|
||||
# 48 — DA_NarrativeDataAssets (Collection)
|
||||
|
||||
## Blueprint Spec — UE 5.5–5.7
|
||||
|
||||
---
|
||||
|
||||
### Purpose
|
||||
This file defines all Data Asset types used by the Narrative systems. Each data asset subclass is a standalone asset that designers create in the Content Browser to author narrative content without blueprint modifications.
|
||||
|
||||
### Relationship to Systems
|
||||
|
||||
| Data Asset | Consumed By | Purpose |
|
||||
|-----------|-------------|---------|
|
||||
| `DA_DialogueSequence` | [`BPC_DialoguePlaybackSystem`](40_BPC_DialoguePlaybackSystem.md) | Dialogue lines, voiceover, subtitles |
|
||||
| `DA_ConsequenceRule` | [`BPC_BranchingConsequenceSystem`](42_BPC_BranchingConsequenceSystem.md) | Flag → action mapping |
|
||||
| `DA_EndingData` | [`BPC_EndingAccumulatorSystem`](45_BPC_EndingAccumulatorSystem.md) | Ending evaluation criteria |
|
||||
| `DA_LoreEntryData` | [`BPC_LoreUnlockSystem`](46_BPC_LoreUnlockSystem.md) | Lore content and metadata |
|
||||
| `DA_ScenarioData` | [`BPC_TrialScenarioSystem`](43_BPC_TrialScenarioSystem.md) | Trial scenario definition |
|
||||
| `DA_CutsceneData` | [`BPC_CutsceneBridge`](44_BPC_CutsceneBridge.md) | Cutscene playback configuration |
|
||||
|
||||
---
|
||||
|
||||
### 48.1 — DA_DialogueSequence
|
||||
|
||||
**Parent Class:** `PrimaryDataAsset`
|
||||
|
||||
#### Variables
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `DialogueTag` | GameplayTag | Unique identifier for this sequence |
|
||||
| `SpeakerName` | FText | Display name for UI subtitle |
|
||||
| `DialogueLines` | Array of FDialogueLine | Ordered lines in this sequence |
|
||||
| `bLooping` | Bool | Repeat sequence until manually stopped |
|
||||
| `bInterruptible` | Bool | Can be skipped / interrupted |
|
||||
| `Priority` | Integer | Higher priority interrupts lower |
|
||||
| `Category` | GameplayTag | e.g., "Dialogue.Major", "Dialogue.Ambient" |
|
||||
| `PrerequisiteFlags` | Array of GameplayTag | Must all be set for this sequence to play |
|
||||
| `ConsequenceFlagsOnComplete` | Array of GameplayTag | Flags set when sequence finishes |
|
||||
|
||||
#### Struct: FDialogueLine
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `LineText` | FText | Subtitle text |
|
||||
| `VoiceoverSoftRef` | SoftObjectPath (USoundWave) | Audio file for this line |
|
||||
| `Duration` | Float | Seconds (0 = auto-calculate from audio) |
|
||||
| `EmotionOverride` | GameplayTag | e.g., "Emotion.Angry", "Emotion.Whisper" |
|
||||
| `bWaitForInput` | Bool | Pause after line until player presses continue |
|
||||
| `LineFlagsToSet` | Array of GameplayTag | Narrative flags set when this line plays |
|
||||
| `CustomDelayAfter` | Float | Extra pause after this line before next |
|
||||
|
||||
---
|
||||
|
||||
### 48.2 — DA_ConsequenceRule
|
||||
|
||||
**Parent Class:** `PrimaryDataAsset`
|
||||
|
||||
#### Variables
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `RuleTag` | GameplayTag | Unique identifier |
|
||||
| `TriggerFlagTag` | GameplayTag | Which flag change triggers this rule |
|
||||
| `bTriggerOnSet` | Bool | Fire when flag is set |
|
||||
| `bTriggerOnClear` | Bool | Fire when flag is cleared |
|
||||
| `RequiredContextFlags` | Array of GameplayTag | Additional flags that must be set for rule to fire |
|
||||
| `ExclusiveContextFlags` | Array of GameplayTag | Flags that block this rule |
|
||||
| `Actions` | Array of FConsequenceAction | Actions to execute |
|
||||
| `bIsImmediate` | Bool | Always immediate (overrides per-action delay) |
|
||||
| `Priority` | Integer | Execution order (higher first) |
|
||||
| `bOnlyOnce` | Bool | Remove rule after first fire |
|
||||
| `CooldownSeconds` | Float | Prevent re-fire within cooldown |
|
||||
|
||||
#### Struct: FConsequenceAction
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `ActionType` | EConsequenceActionType | PlayDialogue / UpdateObjective / SetFlag / ClearFlag / TriggerCutscene / UnlockLore / ModifyStat / SpawnActor / DestroyActor |
|
||||
| `TargetTag` | GameplayTag | Target dialogue sequence, lore entry, etc. |
|
||||
| `FloatValue` | Float | Numeric modifier for stat changes |
|
||||
| `StringValue` | FString | Actor tag for spawn/destroy |
|
||||
| `DelaySeconds` | Float | Delay before this action executes |
|
||||
| `bBlocking` | Bool | Wait for completion before next action |
|
||||
|
||||
---
|
||||
|
||||
### 48.3 — DA_EndingData
|
||||
|
||||
**Parent Class:** `PrimaryDataAsset`
|
||||
|
||||
#### Variables
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `EndingTag` | GameplayTag | Unique identifier |
|
||||
| `EndingName` | FText | Display name for UI / debug |
|
||||
| `EndingDescription` | FText | Brief description |
|
||||
| `Priority` | Integer | Higher priority endings win over lower |
|
||||
| `RequiredFlagTags` | Array of GameplayTag | All must be set to qualify |
|
||||
| `ExclusiveFlagTags` | Array of GameplayTag | None must be set to qualify |
|
||||
| `MinScore` | Float | Minimum accumulated score to qualify |
|
||||
| `ScoreEntries` | Array of FEndingScoreEntry | Flags that contribute score |
|
||||
| `CutsceneData` | TSoftObjectPtr<DA_CutsceneData> | Ending cutscene to play |
|
||||
| `bIsFallbackEnding` | Bool | Always available if no other ending qualifies |
|
||||
| `EndingRewards` | Array of GameplayTag | Bonuses, unlocks, achievements granted |
|
||||
|
||||
#### Struct: FEndingScoreEntry
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `FlagTag` | GameplayTag | Flag that grants score when set |
|
||||
| `ScoreValue` | Float | Points awarded |
|
||||
| `ScoreCategory` | FName | Group for UI display |
|
||||
|
||||
---
|
||||
|
||||
### 48.4 — DA_LoreEntryData
|
||||
|
||||
**Parent Class:** `PrimaryDataAsset`
|
||||
|
||||
#### Variables
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `LoreTag` | GameplayTag | Unique identifier |
|
||||
| `EntryType` | ELoreEntryType | Document, AudioLog, Note, EnvironmentalText, BestiaryEntry, Collectible |
|
||||
| `CategoryTag` | GameplayTag | e.g., "Lore.Notes.DrWatson", "Lore.Bestiary.Creatures" |
|
||||
| `Title` | FText | Entry title |
|
||||
| `BodyText` | FText | Main content text |
|
||||
| `FlavorText` | FText | Optional flavor/subtitle |
|
||||
| `AudioSoftRef` | SoftObjectPath (USoundWave) | Audio narration (if audio log) |
|
||||
| `AudioDuration` | Float | Length of audio in seconds |
|
||||
| `ImageSoftRef` | SoftObjectPath (UTexture2D) | Optional image / photo |
|
||||
| `UnlockMethod` | ELoreDiscoveryMethod | OnPickup / OnNarrativeFlag / OnLocationEnter / OnInteraction / OnConsequence |
|
||||
| `UnlockFlagTag` | GameplayTag | If OnNarrativeFlag, which flag triggers unlock |
|
||||
| `RequiredFlags` | Array of GameplayTag | Prerequisite flags |
|
||||
| `SeriesTag` | GameplayTag | Part of a series (e.g., "Lore.Series.InvestigationNotes") |
|
||||
| `SeriesIndex` | Integer | Order within series |
|
||||
| `IsTimedEntry` | Bool | Entry expires after game time |
|
||||
| `TimeToLiveSeconds` | Float | How long entry remains available |
|
||||
| `bAutoReadOnUnlock` | Bool | Auto-mark as read when discovered |
|
||||
|
||||
---
|
||||
|
||||
### 48.5 — DA_ScenarioData
|
||||
|
||||
**Parent Class:** `PrimaryDataAsset`
|
||||
|
||||
#### Variables
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `ScenarioTag` | GameplayTag | Unique identifier |
|
||||
| `ScenarioName` | FText | Display name |
|
||||
| `ScenarioType` | EScenarioType | CombatGauntlet, EscapeSequence, InvestigationTimed, SurvivalWave, Mixed |
|
||||
| `TimeLimitSeconds` | Float | 0 = no time limit |
|
||||
| `bFailOnPlayerDeath` | Bool | Player death = scenario failure |
|
||||
| `SpawnTags` | Array of GameplayTag | Enemy / actor tags to spawn |
|
||||
| `SpawnPointTags` | Array of GameplayTag | Where to spawn them |
|
||||
| `Objectives` | Array of FScenarioObjectiveDef | Scenario objectives |
|
||||
| `FailureConditions` | Array of FScenarioFailureCondition | What triggers failure |
|
||||
| `LockedDoorTags` | Array of GameplayTag | Doors to lock during scenario |
|
||||
| `UnlockOnSuccessDoorTags` | Array of GameplayTag | Doors to unlock on success |
|
||||
| `SuccessFlags` | Array of GameplayTag | Flags set on success |
|
||||
| `FailureFlags` | Array of GameplayTag | Flags set on failure |
|
||||
| `CutsceneOnStart` | TSoftObjectPtr<DA_CutsceneData> | Cutscene before scenario |
|
||||
| `CutsceneOnSuccess` | TSoftObjectPtr<DA_CutsceneData> | Cutscene on success |
|
||||
| `CutsceneOnFailure` | TSoftObjectPtr<DA_CutsceneData> | Cutscene on failure |
|
||||
| `bCreateCheckpointOnStart` | Bool | Auto-save before scenario |
|
||||
|
||||
#### Enums
|
||||
|
||||
| Enum | Values | Description |
|
||||
|------|--------|-------------|
|
||||
| `EScenarioType` | CombatGauntlet, EscapeSequence, InvestigationTimed, SurvivalWave, Mixed | Scenario gameplay type |
|
||||
|
||||
#### Struct: FScenarioObjectiveDef
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `ObjectiveTag` | GameplayTag | Reference to objective system |
|
||||
| `Description` | FText | Objective description |
|
||||
| `RequiredCount` | Integer | How many to complete |
|
||||
| `bIsOptional` | Bool | Not required for success |
|
||||
|
||||
#### Struct: FScenarioFailureCondition
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `ConditionType` | EFailureConditionType | TimeExpired / PlayerDeath / TargetEscaped / ObjectiveFailed |
|
||||
| `TargetTag` | GameplayTag | Specific target reference |
|
||||
| `FloatParam` | Float | Threshold (e.g., max deaths) |
|
||||
|
||||
---
|
||||
|
||||
### 48.6 — DA_CutsceneData
|
||||
|
||||
**Parent Class:** `PrimaryDataAsset`
|
||||
|
||||
#### Variables
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `CutsceneTag` | GameplayTag | Unique identifier |
|
||||
| `CutsceneName` | FText | Editor display name |
|
||||
| `SequenceSoftReference` | TSoftObjectPtr<ALevelSequenceActor> | The Level Sequence to play |
|
||||
| `TransitionType` | ECutsceneTransitionType | FadeInOut, HardCut, LetterBox, BlackBars |
|
||||
| `TransitionDuration` | Float | Fade duration in seconds |
|
||||
| `bCanSkip` | Bool | Player can skip |
|
||||
| `TimeBeforeSkipAvailable` | Float | Seconds before skip is enabled |
|
||||
| `SkipHoldDuration` | Float | Hold seconds to skip |
|
||||
| `Milestones` | Array of FCutsceneMilestone | Narrative flags at specific times |
|
||||
| `bAutoSaveBefore` | Bool | Create checkpoint before cutscene |
|
||||
| `bRestorePlayerState` | Bool | Save and restore player stats after |
|
||||
| `DialogueSequences` | Array of TSoftObjectPtr<DA_DialogueSequence> | Subtitled dialogue during cutscene |
|
||||
| `OnCompleteFlags` | Array of GameplayTag | Flags set when cutscene ends |
|
||||
| `OnSkippedFlags` | Array of GameplayTag | Flags set if player skips |
|
||||
| `bHideHUD` | Bool | Auto-hide HUD during cutscene |
|
||||
| `bSuppressPlayerInput` | Bool | Disable player input during cutscene |
|
||||
|
||||
#### Struct: FCutsceneMilestone
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `TimeSeconds` | Float | Sequence timecode |
|
||||
| `FlagTag` | GameplayTag | Flag to set |
|
||||
| `bFireOnce` | Bool | Only fire if not already set |
|
||||
|
||||
---
|
||||
|
||||
### Asset Registration Pattern
|
||||
|
||||
All narrative data assets should be registered in the **Primary Asset Registry** (Project Settings > Asset Manager) with the appropriate scan paths:
|
||||
|
||||
| Data Asset | Directory Convention | Asset Prefix |
|
||||
|-----------|---------------------|--------------|
|
||||
| DA_DialogueSequence | `/Game/Dialogue/` | `SEQ_` |
|
||||
| DA_ConsequenceRule | `/Game/Narrative/Consequences/` | `CON_` |
|
||||
| DA_EndingData | `/Game/Narrative/Endings/` | `END_` |
|
||||
| DA_LoreEntryData | `/Game/Narrative/Lore/` | `LORE_` |
|
||||
| DA_ScenarioData | `/Game/Narrative/Scenarios/` | `SCEN_` |
|
||||
| DA_CutsceneData | `/Game/Cinematics/CutsceneData/` | `CUT_` |
|
||||
|
||||
### Save System Integration
|
||||
|
||||
Each data asset is identified by its `Tag` field (GameplayTag). The narrative state system saves and loads only the tag references and flag states — the data assets themselves are loaded from content references and never serialized into save data. This means:
|
||||
- Flags persisted as `Set<GameplayTag>` in save file
|
||||
- Lore unlocked/read persisted as `Set<GameplayTag>`
|
||||
- Data assets can be modified between saves without breaking save compatibility
|
||||
159
docs/blueprints/07-narrative/67_BP_NarrativeTriggerVolume.md
Normal file
159
docs/blueprints/07-narrative/67_BP_NarrativeTriggerVolume.md
Normal file
@@ -0,0 +1,159 @@
|
||||
# BP_NarrativeTriggerVolume — Actor (with BoxComponent as root)
|
||||
|
||||
## Blueprint Spec — UE 5.5–5.7
|
||||
|
||||
---
|
||||
|
||||
### Parent Class
|
||||
`Actor` (with `BoxComponent` as root)
|
||||
|
||||
### Dependencies
|
||||
- [`BPC_NarrativeStateSystem`](58_BPC_NarrativeStateSystem.md)
|
||||
- [`BPC_DialoguePlaybackSystem`](40_BPC_DialoguePlaybackSystem.md)
|
||||
- [`BPC_CutsceneBridge`](44_BPC_CutsceneBridge.md)
|
||||
- [`BPC_TrialScenarioSystem`](43_BPC_TrialScenarioSystem.md)
|
||||
- [`BPC_LoreUnlockSystem`](46_BPC_LoreUnlockSystem.md)
|
||||
- [`I_NarrativeActor`](../01-core/03_I_NarrativeActor.md)
|
||||
|
||||
### Purpose
|
||||
A level-placed trigger volume that detects player overlap and fires narrative actions. Supports one-shot / reusable / conditional modes, with optional prerequisite flags and cooldown timers. The primary way for level designers to trigger narrative events without blueprint logic.
|
||||
|
||||
### Responsibilities
|
||||
- Detect player BeginOverlap / EndOverlap
|
||||
- Check prerequisite flags (required and exclusive)
|
||||
- Execute configured actions on trigger (fire-and-forget)
|
||||
- Support trigger types: Once, Reusable, Conditional, TimedAutoReset
|
||||
- Broadcast onset / offset variants if configured
|
||||
- Prevent re-trigger during cooldown
|
||||
|
||||
### Does NOT Handle
|
||||
- Playing dialogue or cutscenes directly (calls the relevant system)
|
||||
- Setting flags on the NarrativeState (that is what the actions do)
|
||||
- UI display (that is UI layer)
|
||||
|
||||
### Variables
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `TriggerTag` | GameplayTag | Unique identifier for this trigger |
|
||||
| `TriggerType` | ETriggerType | How the trigger behaves |
|
||||
| `TriggerActions` | Array of FTriggerActionEntry | Actions to fire when triggered |
|
||||
| `bAlsoFireOnExit` | Bool | Fire separate actions when player exits |
|
||||
| `ExitActions` | Array of FTriggerActionEntry | Actions fired on exit (if enabled) |
|
||||
| `RequiredFlags` | Array of GameplayTag | All must be set to enable |
|
||||
| `ExclusiveFlags` | Array of GameplayTag | If any are set, trigger is disabled |
|
||||
| `CooldownSeconds` | Float | Time before reusable triggers can re-fire |
|
||||
| `bHasTriggered` | Bool | Has fired at least once |
|
||||
| `bIsEnabled` | Bool | Can be toggled on/off by external systems |
|
||||
| `LastTriggerTime` | Float | World time of last trigger |
|
||||
| `CollisionBox` | BoxComponent | The overlap volume |
|
||||
| `TriggerDisplayName` | FText | Editor-friendly name |
|
||||
| `bDebugMode` | Bool | Print trigger events to screen |
|
||||
|
||||
### Enums
|
||||
|
||||
| Enum | Values | Description |
|
||||
|------|--------|-------------|
|
||||
| `ETriggerType` | Once, Reusable, ConditionalOnce, ConditionalReusable, TimedAutoReset | Once: fires first time only. Reusable: fires every time with cooldown. Conditional*: checks flags each time. TimedAutoReset: resets after cooldown. |
|
||||
| `ENarrativeActionType` | SetFlag, ClearFlag, PlayDialogue, StartCutscene, BeginScenario, UnlockLore, UpdateObjective, PlaySound, ExecuteConsoleCommand, ToggleActorEnabled, CustomEvent | Types of actions a trigger can perform |
|
||||
|
||||
### Structs
|
||||
|
||||
| Struct | Fields | Description |
|
||||
|--------|--------|-------------|
|
||||
| `FTriggerActionEntry` | ActionType: ENarrativeActionType, TargetTag: GameplayTag, FloatParam: Float (delay), StringParam: FString (for console commands), bBlocking: Bool (wait for completion), DelayBeforeFire: Float | One action entry in the trigger action list |
|
||||
| `FTriggerConditionState` | bMetRequirements: Bool, bBlockedByExclusive: Bool, bOnCooldown: Bool, bAlreadyTriggered: Bool | Debug state of trigger conditions |
|
||||
|
||||
### Functions / Events
|
||||
|
||||
| Name | Inputs | Outputs | Description |
|
||||
|------|--------|---------|-------------|
|
||||
| `OnPlayerEntered` | OverlappedComp: PrimitiveComponent, OtherActor: Actor | — | BeginOverlap event |
|
||||
| `OnPlayerExited` | OverlappedComp: PrimitiveComponent, OtherActor: Actor | — | EndOverlap event (if bAlsoFireOnExit) |
|
||||
| `EvaluateTriggerConditions` | — | Bool (can fire) | Check all conditions |
|
||||
| `FireTrigger` | — | — | Execute all trigger actions |
|
||||
| `ExecuteActionEntry` | Entry: FTriggerActionEntry | — | Perform one action |
|
||||
| `ResetTrigger` | — | — | Reset bHasTriggered (for TimedAutoReset) |
|
||||
| `SetTriggerEnabled` | bEnabled: Bool | — | External toggle |
|
||||
| `GetTriggerState` | — | FTriggerConditionState | Debug info |
|
||||
| `ManualTrigger` | — | — | Force trigger from external BP |
|
||||
| `PreviewActions` | — | — | Editor preview of what this trigger does |
|
||||
|
||||
### Event Dispatchers
|
||||
|
||||
| Name | Parameters | Fired When |
|
||||
|------|-----------|-----------|
|
||||
| `OnTriggerPrepared` | TriggerTag: GameplayTag | Conditions met, about to fire |
|
||||
| `OnTriggerFired` | TriggerTag: GameplayTag, ActionCount: Integer | All actions executed |
|
||||
| `OnTriggerBlocked` | TriggerTag: GameplayTag, Reason: FName | Conditions not met |
|
||||
| `OnTriggerCooldown` | TriggerTag: GameplayTag, RemainingCooldown: Float | Cooldown active |
|
||||
| `OnTriggerReset` | TriggerTag: GameplayTag | Trigger reset for reuse |
|
||||
|
||||
### Blueprint Flow
|
||||
|
||||
```
|
||||
[OnPlayerEntered]
|
||||
└─► If !bIsEnabled → return
|
||||
└─► If EvaluateTriggerConditions == false → broadcast OnTriggerBlocked → return
|
||||
└─► FireTrigger
|
||||
|
||||
[EvaluateTriggerConditions]
|
||||
└─► If TriggerType == Once && bHasTriggered → return false (already fired)
|
||||
└─► If TriggerType == ConditionalOnce && bHasTriggered → return false
|
||||
└─► If TriggerType == TimedAutoReset && !bHasTriggered → skip (but can fire if reset)
|
||||
└─► Check RequiredFlags: all must be set in BPC_NarrativeStateSystem
|
||||
└─► Check ExclusiveFlags: none must be set
|
||||
└─► If TriggerType == Reusable || ConditionalReusable:
|
||||
└─► Check LastTriggerTime + CooldownSeconds < CurrentTime
|
||||
└─► If on cooldown → broadcast OnTriggerCooldown → return false
|
||||
└─► Return true (all conditions pass)
|
||||
|
||||
[FireTrigger]
|
||||
└─► Broadcast OnTriggerPrepared
|
||||
└─► Set bHasTriggered = true
|
||||
└─► Set LastTriggerTime = CurrentTime
|
||||
└─► For each FTriggerActionEntry in TriggerActions (in order):
|
||||
└─► If entry.DelayBeforeFire > 0 → delay via timer
|
||||
└─► ExecuteActionEntry(Entry)
|
||||
└─► If bAlsoFireOnExit → bind OnPlayerExited to execute ExitActions
|
||||
└─► Broadcast OnTriggerFired
|
||||
└─► If TriggerType == TimedAutoReset → start timer for ResetTrigger after CooldownSeconds
|
||||
|
||||
[ExecuteActionEntry: Entry]
|
||||
└─► Switch on Entry.ActionType:
|
||||
SetFlag → BPC_NarrativeStateSystem.SetFlag(Entry.TargetTag)
|
||||
ClearFlag → BPC_NarrativeStateSystem.ClearFlag(Entry.TargetTag)
|
||||
PlayDialogue → Get BPC_DialoguePlaybackSystem → PlaySequence(Entry.TargetTag)
|
||||
StartCutscene → Get BPC_CutsceneBridge → PlayCutscene(Entry.TargetTag as DA_CutsceneData)
|
||||
BeginScenario → Get BPC_TrialScenarioSystem → BeginScenario(Entry.TargetTag as DA_ScenarioData)
|
||||
UnlockLore → Get BPC_LoreUnlockSystem → UnlockLoreByTag(Entry.TargetTag)
|
||||
UpdateObjective → Get BPC_ObjectiveSystem → AddOrUpdateObjective(...)
|
||||
PlaySound → Play sound at volume location
|
||||
ExecuteConsoleCommand → Exec(Entry.StringParam)
|
||||
ToggleActorEnabled → Find actor by tag, toggle set actor hidden / disable collision
|
||||
CustomEvent → Dispatch custom gameplay event tag (listeners in level blueprint)
|
||||
```
|
||||
|
||||
### Communications With
|
||||
|
||||
| Target System | Method | Why |
|
||||
|---------------|--------|-----|
|
||||
| [`BPC_NarrativeStateSystem`](58_BPC_NarrativeStateSystem.md) | Direct | Check/set flags for conditions and actions |
|
||||
| [`BPC_DialoguePlaybackSystem`](40_BPC_DialoguePlaybackSystem.md) | Direct | Trigger dialogue sequences |
|
||||
| [`BPC_CutsceneBridge`](44_BPC_CutsceneBridge.md) | Direct | Start cutscenes |
|
||||
| [`BPC_TrialScenarioSystem`](43_BPC_TrialScenarioSystem.md) | Direct | Begin trial scenarios |
|
||||
| [`BPC_LoreUnlockSystem`](46_BPC_LoreUnlockSystem.md) | Direct | Unlock lore |
|
||||
| [`BPC_ObjectiveSystem`](39_BPC_ObjectiveSystem.md) | Direct | Update objectives |
|
||||
| Level Blueprint | Dispatcher (CustomEvent) | Layer for designer-specific logic |
|
||||
|
||||
### Placement in Level
|
||||
- Drag into level from Content Browser
|
||||
- Scale BoxComponent to desired trigger area
|
||||
- Configure TriggerActions array in Details panel
|
||||
- Tag with TriggerTag for save/load identification
|
||||
- Optional: set PrerequisiteFlags to gate the trigger
|
||||
|
||||
### Reuse Notes
|
||||
This is the primary level-design tool for narrative gating. Designers place volumes, configure action lists, and set prerequisite flags — no blueprint editing required. Supports all narrative action types. The `CustomEvent` action type allows designers to bind custom level blueprint logic when no predefined action fits.
|
||||
|
||||
- Renamed from `47_BPC_NarrativeTriggerVolume` to `BP_NarrativeTriggerVolume` per Master naming convention.
|
||||
136
docs/blueprints/07-narrative/68_BPC_EndingAccumulator.md
Normal file
136
docs/blueprints/07-narrative/68_BPC_EndingAccumulator.md
Normal file
@@ -0,0 +1,136 @@
|
||||
# BPC_EndingAccumulator — Actor Component
|
||||
|
||||
## Blueprint Spec — UE 5.5–5.7
|
||||
|
||||
---
|
||||
|
||||
### Parent Class
|
||||
`ActorComponent`
|
||||
|
||||
### Dependencies
|
||||
- [`BPC_NarrativeStateSystem`](58_BPC_NarrativeStateSystem.md)
|
||||
- [`DA_NarrativeDataAssets`](48_DA_NarrativeDataAssets.md)
|
||||
- [`BPC_CheckpointSystem`](../05-saveload/BP_Checkpoint.md)
|
||||
- [`BPC_CutsceneBridge`](44_BPC_CutsceneBridge.md)
|
||||
|
||||
### Purpose
|
||||
Evaluates all narrative flags accumulated throughout gameplay and determines which ending the player qualifies for. Supports weighted scoring systems, required flag checks, and ending priority ranking.
|
||||
|
||||
### Responsibilities
|
||||
- Maintain an ending score table (flags → points)
|
||||
- Listen for narrative flag changes and accumulate score
|
||||
- Evaluate ending eligibility on demand or at game-end trigger
|
||||
- Rank endings by priority: specific requirements win over general
|
||||
- Provide preview data to UI for ending readiness indicator
|
||||
- Trigger the winning ending cutscene via `BPC_CutsceneBridge`
|
||||
|
||||
### Does NOT Handle
|
||||
- Setting individual narrative flags (that is `BPC_NarrativeStateSystem`)
|
||||
- Playing ending cutscene sequence (that is `BPC_CutsceneBridge`)
|
||||
- UI display of ending readiness (that is UI layer)
|
||||
|
||||
### Variables
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `EndingDefinitions` | Array of DA_EndingData | All possible endings loaded at game start |
|
||||
| `EndingScores` | Map: GameplayTag → Float | Current accumulated scores per category |
|
||||
| `bEndingReady` | Bool | At least one ending is achievable |
|
||||
| `QualifiedEndings` | Array of DA_EndingData | Endings that meet requirements |
|
||||
| `bGameEndTriggered` | Bool | Prevents re-evaluation after game end |
|
||||
| `HighestPriorityEnding` | DA_EndingData | The selected ending |
|
||||
|
||||
### Enums
|
||||
|
||||
| Enum | Values | Description |
|
||||
|------|--------|-------------|
|
||||
| `EEndingEvaluationMode` | OnDemand, Continuous, OnGameEndTrigger | When to evaluate ending eligibility |
|
||||
|
||||
### Structs
|
||||
|
||||
| Struct | Fields | Description |
|
||||
|--------|--------|-------------|
|
||||
| `FEndingScoreEntry` | FlagTag: GameplayTag, ScoreValue: Float, Category: FName | Scores accumulate when flag is set |
|
||||
| `FEndingQualification` | Ending: DA_EndingData, Score: Float, bRequiredFlagsMet: Bool, bExclusiveFlagsMet: Bool, Priority: Integer, bIsQualified: Bool | Full qualification result |
|
||||
|
||||
### Functions / Events
|
||||
|
||||
| Name | Inputs | Outputs | Description |
|
||||
|------|--------|---------|-------------|
|
||||
| `InitializeEndings` | — | — | Load all DA_EndingData from content registry |
|
||||
| `OnNarrativeFlagChanged` | FlagTag: GameplayTag, bIsSet: Bool | — | Accumulate score when flag is set |
|
||||
| `EvaluateEndings` | — | DA_EndingData | Evaluate all endings, return highest priority |
|
||||
| `GetEndingQualification` | Ending: DA_EndingData | FEndingQualification | Check specific ending qualification |
|
||||
| `GetQualifiedEndings` | — | Array of FEndingQualification | All endings player qualifies for |
|
||||
| `GetEndingReadinessPercentage` | — | Float | 0-1 how close player is to any ending |
|
||||
| `GetTotalScoreForEnding` | Ending: DA_EndingData | Float | Current accumulated score |
|
||||
| `TriggerGameEnding` | OverrideEndingTag: GameplayTag (optional) | — | Force game end with specific or best ending |
|
||||
| `ResetEndingState` | — | — | Clear scores (for new game+) |
|
||||
|
||||
### Event Dispatchers
|
||||
|
||||
| Name | Parameters | Fired When |
|
||||
|------|-----------|-----------|
|
||||
| `OnEndingScoresUpdated` | Scores: Map of GameplayTag → Float | Any score changes |
|
||||
| `OnEndingQualificationChanged` | QualifiedEndings: Array of DA_EndingData | Qualification set changed |
|
||||
| `OnGameEndingTriggered` | SelectedEnding: DA_EndingData | Game ending sequence begins |
|
||||
| `OnEndingReadyChanged` | bReady: Bool | Player became eligible / lost eligibility |
|
||||
|
||||
### Blueprint Flow
|
||||
|
||||
```
|
||||
[InitializeEndings]
|
||||
└─► Load all DA_EndingData from primary asset registry (tag-based lookup)
|
||||
└─► Sort by Priority (descending)
|
||||
└─► Bind to BPC_NarrativeStateSystem.OnFlagChanged dispatcher
|
||||
|
||||
[OnNarrativeFlagChanged: FlagTag, bIsSet]
|
||||
└─► If !bIsSet → return (only care about flags being set, not cleared)
|
||||
└─► For each DA_EndingData:
|
||||
└─► Lookup FlagTag in Ending.ScoreEntries
|
||||
└─► If found → EndingScores[FlagTag] += ScoreValue
|
||||
└─► If EEvaluationMode == Continuous → EvaluateEndings
|
||||
└─► Broadcast OnEndingScoresUpdated
|
||||
|
||||
[EvaluateEndings]
|
||||
└─► Clear QualifiedEndings array
|
||||
└─► For each DA_EndingData (sorted by priority descending):
|
||||
└─► Check RequiredFlagTags: all must be set
|
||||
└─► Check ExclusiveFlagTags: none must be set
|
||||
└─► Check score threshold: CurrentScore >= MinScore
|
||||
└─► If all pass → add to QualifiedEndings
|
||||
└─► If QualifiedEndings is empty:
|
||||
└─► HighestPriorityEnding = null
|
||||
└─► bEndingReady = false
|
||||
└─► Else:
|
||||
└─► HighestPriorityEnding = QualifiedEndings[0] (highest priority)
|
||||
└─► bEndingReady = true
|
||||
└─► Broadcast OnEndingQualificationChanged
|
||||
|
||||
[TriggerGameEnding: OverrideEndingTag]
|
||||
└─► If bGameEndTriggered → return (prevent double trigger)
|
||||
└─► Set bGameEndTriggered = true
|
||||
└─► If OverrideEndingTag is valid:
|
||||
└─► Find DA_EndingData by tag → SelectedEnding
|
||||
└─► Else:
|
||||
└─► EvaluateEndings → SelectedEnding = HighestPriorityEnding
|
||||
└─► If SelectedEnding is null → fallback ending (always exists)
|
||||
└─► Broadcast OnGameEndingTriggered with SelectedEnding
|
||||
└─► Create checkpoint if configured
|
||||
└─► Trigger BPC_CutsceneBridge.PlayCutscene(SelectedEnding.CutsceneData)
|
||||
```
|
||||
|
||||
### Communications With
|
||||
|
||||
| Target System | Method | Why |
|
||||
|---------------|--------|-----|
|
||||
| [`BPC_NarrativeStateSystem`](58_BPC_NarrativeStateSystem.md) | Dispatcher (receives) | Listen for flag changes to accumulate score |
|
||||
| [`BPC_CutsceneBridge`](44_BPC_CutsceneBridge.md) | Direct | Trigger ending cutscene |
|
||||
| [`BP_Checkpoint`](../05-saveload/BP_Checkpoint.md) | Direct | Save before ending sequence |
|
||||
| UI Layer | Dispatcher | Update ending readiness indicator |
|
||||
|
||||
### Reuse Notes
|
||||
Completely data-driven. Designers create DA_EndingData assets with required flags, exclusive flags, score thresholds, and score entries. The priority system ensures specific endings (e.g., "True Ending") override general ones. The system supports both linear and score-based ending evaluation simultaneously.
|
||||
|
||||
- Renamed from `45_BPC_EndingAccumulatorSystem` to `BPC_EndingAccumulator` per Master naming convention.
|
||||
- Cross-references updated: `BPC_CheckpointSystem` → `BP_Checkpoint`.
|
||||
Reference in New Issue
Block a user