- 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.
8.6 KiB
8.6 KiB
BPC_EndingAccumulator — Actor Component
Blueprint Spec — UE 5.5–5.7
Parent Class
ActorComponent
Dependencies
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 |
Dispatcher (receives) | Listen for flag changes to accumulate score |
BPC_CutsceneBridge |
Direct | Trigger ending cutscene |
BP_Checkpoint |
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_EndingAccumulatorSystemtoBPC_EndingAccumulatorper Master naming convention. - Cross-references updated:
BPC_CheckpointSystem→BP_Checkpoint.
Manual Implementation Guide
Class Setup
- Create Blueprint Class: Parent =
ActorComponent, Name =BPC_EndingAccumulator - Add to Player Character or GameState
Variable Init (BeginPlay)
Event BeginPlay
├─ Set EndingScores = empty Map<GameplayTag, Float>
├─ Load all DA_EndingData assets into EndingDefinitions array
└─ Bind to BPC_NarrativeStateSystem.OnFlagChanged
Function Node-by-Node
OnNarrativeFlagChanged(Flag: GameplayTag, NewValue: Boolean) → void
Step 1: If NewValue == false → Return (only accumulate on true flags)
Step 2: ForEach EndingDefinitions:
ForEach Entry in Ending.ScoreEntries:
If Entry.FlagTag == Flag:
EndingScores[Ending.EndingTag] += Entry.Weight
Break inner loop
Step 3: Fire OnEndingScoresUpdated(EndingScores)
EvaluateEndings() → DA_EndingData
Step 1: QualifiedList = empty array
Step 2: ForEach EndingDefinitions:
If EndingScores[Ending.EndingTag] >= Ending.RequiredScore:
Check Ending.RequiredFlags: all set? → Add to QualifiedList
Check Ending.ExclusiveFlags: any set? → Skip
Step 3: Sort QualifiedList by Priority (descending)
Step 4: Return QualifiedList[0] (highest priority qualified ending)
GetQualifiedEndings() → Array<DA_EndingData> (Pure)
Same logic as EvaluateEndings but returns all qualified, not just best
TriggerGameEnding(OverrideTag: GameplayTag) → void
Step 1: If OverrideTag valid → SelectedEnding = Find(OverrideTag)
Else: SelectedEnding = EvaluateEndings()
Step 2: Fire OnGameEndingTriggered(SelectedEnding)
Step 3: GM_CoreGameMode.TriggerEnding(SelectedEnding.EndingTag)
→ initiates cutscene, game-over screen, credits
Build Checklist
- Create BPC_EndingAccumulator
- Define DA_EndingData with ScoreEntries, RequiredFlags, ExclusiveFlags, RequiredScore, Priority
- Bind to NarrativeStateSystem.OnFlagChanged → accumulate scores
- Implement EvaluateEndings with qualification gating
- Wire to GM_CoreGameMode.TriggerEnding
- Test: make choices throughout game → check ending scores → trigger end → correct ending plays