Files
UE5-Modular-Game-Framework/docs/game/narrative-progression.md
Lefteris Notas 040db37720 Add UI Overrides and Weapons Index documentation for Project Void
- Created ui-overrides.md detailing game-specific Widget Blueprint overrides, including purpose, widget index, visual styling, and accessibility requirements.
- Established weapons-index.md outlining all held weapon actors, including their components, logic, and comparisons for gameplay mechanics.
2026-05-21 22:27:57 +03:00

355 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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

# Narrative & Progression — Objectives, Dialogue, Cutscenes, Endings
**Game:** Project Void | **Build Phase:** 13
**Framework Systems:** 58_BPC_NarrativeStateSystem, 59_BPC_ObjectiveSystem, 60_BPC_DialoguePlaybackSystem, 61_BPC_DialogueChoiceSystem, 62_BPC_BranchingConsequenceSystem, 63_BPC_TrialScenarioSystem, 64_BPC_CutsceneBridge, 65_BPC_LoreUnlockSystem, 66_DA_NarrativeDataAssets, 67_BP_NarrativeTriggerVolume, 68_BPC_EndingAccumulator
---
## Purpose
Defines the complete narrative structure: objectives, dialogue, cutscenes, lore, and the multiple-ending system. Every narrative system from the framework is demonstrated.
---
## Objective Flow
### Main Objectives (Required for Completion)
```
OBJ_1: "Find a way out of this wing"
├─ Chapter: Entry
├─ Trigger: After opening cutscene
├─ Completion: Reach Nurses Station → interact with exit door
└─ Reward: Unlocks WardA + first checkpoint
OBJ_2: "Restore power to the asylum"
├─ Chapter: WardA
├─ Trigger: Enter WardA
├─ Sub-objectives:
│ ├─ "Find the fusebox" → Locate utility closet
│ ├─ "Reset the circuit breakers" → Solve fusebox puzzle
│ └─ "Access the treatment room" → Unlocked door
├─ Completion: Fusebox puzzle solved + door opened
└─ Reward: Treatment room access (lore + photo collectible)
OBJ_3: "Find the Warden's Key"
├─ Chapter: WardB → Basement
├─ Trigger: Read patient file mentioning "Warden's Master Key"
├─ Sub-objectives:
│ ├─ "Find the morgue" → Navigate WardB to morgue
│ ├─ "Search the morgue drawers" → Solve morgue puzzle
│ └─ "Retrieve the key" → Open correct drawer
├─ Completion: Morgue puzzle solved
└─ Reward: Warden's Key + Void Shard (crematorium access)
OBJ_4: "Confront the truth"
├─ Chapter: WardensOffice
├─ Trigger: Enter Warden's Office
├─ Sub-objectives:
│ ├─ "Read the Warden's journal" → Find and read journal
│ └─ "Face the entity" → Trigger dialogue choice
├─ Completion: Dialogue choice made
└─ Reward: Ending triggered
```
### Optional / Side Objectives
```
SIDE_1: "Find the survivors"
├─ Trigger: Find first Patient File mentioning "Subject 77 escaped"
├─ Objective: Locate BP_NPC_Survivor in WardB
└─ Reward: Lore, possible ending flag (SurvivorSaved), item gift
SIDE_2: "Collect the memories"
├─ Trigger: Find first Old Photo
├─ Objective: Find all 4 Old Photos
└─ Reward: Achievement "Photographer", lore about asylum history
SIDE_3: "Touch the void"
├─ Trigger: Find first Void Shard
├─ Objective: Collect all 3 Void Shards
└─ Reward: Unlocks Ending C (Sacrifice), achievement "Void Touched"
```
---
## Objective Data Assets
Each objective has a `DA_ObjectiveData` (123):
| DA_Objective_* | Type | Prerequisites | Completion | Chapter |
|----------------|------|--------------|-----------|---------|
| `DA_Objective_FindKeys` | Main | None | Has item: Keycard Alpha | WardA |
| `DA_Objective_RestorePower` | Main | OBJ_1 complete | Flag: PowerRestored | WardA |
| `DA_Objective_FindWardenKey` | Main | OBJ_2 complete | Has item: Warden's Key | Basement |
| `DA_Objective_ConfrontTruth` | Main | OBJ_3 complete | DialogueChoice made | WardensOffice |
| `DA_Objective_FindSurvivors` | Side | Find PatientFile #2 | NPC Interacted | WardB |
| `DA_Objective_CollectMemories` | Side | Find Photo #1 | All 4 photos found | Any |
| `DA_Objective_TouchVoid` | Side | Find Shard #1 | All 3 shards found | Any |
---
## Dialogue System
### Dialogue Data Assets (DA_Dialogue_*)
| DA_Dialogue_ | Speaker | Lines | Location |
|-------------|---------|:---:|----------|
| `DA_Dialogue_Intro` | Player (internal monologue) | 3 lines | L_Asylum_Entry — wake up |
| `DA_Dialogue_SurvivorEncounter` | NPC Survivor | 8 lines + 3 player choices | WardB — hidden room |
| `DA_Dialogue_VoidWhispers` | Void Entity | 12 lines (random) | Throughout — triggered by stress |
| `DA_Dialogue_EndingTruth` | Void Entity | 15 lines + 3 player choices | WardensOffice — final |
### Dialogue Playback (BPC_DialoguePlaybackSystem)
```
PlayDialogue(DialogueData)
├─ [Queue Lines]
│ └─ For each line in DialogueData.Lines:
│ ├─ Show speaker name (WBP_AccessibilityUI)
│ ├─ Play VO audio (SS_AudioManager.PlayDialogue)
│ ├─ Show subtitle text
│ ├─ Wait(DialogueData.LineDuration)
│ └─ Auto-advance to next line
├─ [On Line Change]
│ ├─ BPC_LoreUnlockSystem → auto-unlock if line contains lore reference
│ └─ WBP_NotificationToast → "New Lore Entry: [Name]" if lore unlocked
└─ [On Dialogue Complete]
├─ If has choices → BPC_DialogueChoiceSystem.PresentChoices()
└─ If no choices → Broadcast OnDialogueCompleted
```
### Dialogue Choices (BPC_DialogueChoiceSystem)
Example: Final confrontation — "Accept / Resist / Sacrifice"
```
PresentChoices(ChoiceSet, Options[])
├─ [Display] Show 3 buttons on WBP_JournalHorror:
│ ├─ "Accept the entity's offer" (Option A)
│ ├─ "Resist and fight" (Option B)
│ └─ "Sacrifice yourself to seal it" (Option C)
├─ [Conditions] Show/hide options based on flags:
│ ├─ Option C (Sacrifice) → requires all 3 VoidShards collected
│ ├─ Option A (Accept) → requires Sanity < 50% (broken enough)
│ └─ Option B (Resist) → always available
├─ [Player Selects]
│ │
│ ├─ BPC_BranchingConsequenceSystem.ExecuteConsequence(Choice)
│ │ ├─ Record choice on PS_HorrorPlayerState
│ │ ├─ Set narrative flag: "ChoseAccept" / "ChoseResist" / "ChoseSacrifice"
│ │ └─ BPC_EndingAccumulator.SubmitChoice(Choice)
│ │
│ └─ Play consequence dialogue/cutscene
└─ [Consequence Results]
├─ Accept → Entity possesses player → Ending B
├─ Resist → Entity attacks → Chase sequence → Ending A
└─ Sacrifice → Entity sealed → Player dies → Ending C
```
---
## Cutscene System (BPC_CutsceneBridge)
### Cutscenes
| DA_Cutscene_ | Type | Duration | Trigger |
|-------------|------|:---:|---------|
| `DA_Cutscene_Opening` | In-engine | 5s | OnPostLogin in L_Asylum_Entry |
| `DA_Cutscene_ShadeFirstAppearance` | In-engine | 8s | Enter WardB courtyard |
| `DA_Cutscene_VoidFirstShift` | In-engine | 12s | Enter WardB morgue |
| `DA_Cutscene_Ending` | Pre-rendered or in-engine | 30-60s | Dialogue choice resolution |
### Cutscene Bridge Flow
```
PlayCutscene(CutsceneData)
├─ [Pre-Cutscene]
│ ├─ BPC_StateManager.ForcePushState(Cutscene)
│ ├─ SS_EnhancedInputManager.PopAllContexts → PushContext(UI)
│ └─ WBP_HUDController.HideAllDiegetic()
├─ [Play]
│ ├─ If CutsceneData.Type == InEngine:
│ │ ├─ Spawn cutscene actors from CutsceneData.ActorList
│ │ ├─ Sequencer → Play Level Sequence
│ │ └─ Camera transfer → BPC_CameraStateLayer.SetSequenceCamera()
│ │
│ └─ If CutsceneData.Type == PreRendered:
│ ├─ Load video file
│ └─ Play on full-screen media texture
├─ [Skip Detection]
│ ├─ Listen for IA_SkipCutscene (Hold for 1.5s)
│ └─ OR: Any key press if CutsceneData.bAllowSkip
├─ [Post-Cutscene]
│ ├─ BPC_StateManager.RestorePreviousState()
│ ├─ Restore input context
│ ├─ BPC_NarrativeStateSystem.SetFlag(CutsceneData.CompletionFlag)
│ └─ WBP_HUDController.ShowAllDiegetic()
└─ Broadcast OnCutsceneCompleted
```
---
## Lore System (BPC_LoreUnlockSystem)
Lore entries unlock as the player discovers documents, patient files, and experiences events:
| Lore Entry | Unlock Method | Category |
|-----------|-------------|----------|
| "The Founding of Blackwood" | Read Journal Page #1 | History |
| "Patient Zero" | Read Patient File #3 | Patients |
| "The Void Breach" | Experience first void shift | Events |
| "Dr. Blackwood's Descent" | Read Warden's Journal | Characters |
| "The Entity's Origin" | Collect all 3 VoidShards | Secrets |
| "Treatment Methods" | Read Patient File #2 | Patients |
| "Asylum Layout" | Find Map item (optional) | World |
Each unlocked entry:
- Appears in WBP_JournalHorror → "Lore" tab
- Grants small stress reduction (-5) when read (understanding = comfort)
- May contain clues for puzzles (e.g., morgue drawer order hidden in Patient File)
---
## Ending Accumulator (BPC_EndingAccumulator)
The system that determines which ending the player receives.
### Input Factors
| Factor | Source | Possible Values |
|--------|--------|----------------|
| **VoidShards collected** | BPC_CollectibleTracker | 0, 1, 2, 3 |
| **Survivor saved** | Narrative flag | true / false |
| **Final Sanity** | PS_HorrorPlayerState | 0-100 (Low <33, Med 33-66, High >66) |
| **Dialogue choice** | BPC_DialogueChoiceSystem | Accept / Resist / Sacrifice |
| **Playstyle** | BPC_PlayerMetricsTracker | Aggressive / Stealthy / Balanced |
| **Enemies killed** | BPC_ProgressStatTracker | Count (0, 1-5, 6-15, 16+) |
### Ending Determination
```
EvaluateEnding(FinalChoice)
├─ [Check Sacrifice Qualification]
│ └─ FinalChoice == Sacrifice AND VoidShards >= 3?
│ ├─ True → ENDING C: "The Seal" (Sacrifice)
│ └─ False → "You lack the void-touched knowledge to seal it."
│ └─ Force player to choose Accept or Resist
├─ [Evaluate Accept vs Resist]
│ │
│ ├─ Score "Accept" based on:
│ │ ├─ VoidShards (×10 each)
│ │ ├─ Sanity < 50 (+20)
│ │ ├─ Playstyle == Aggressive (+10)
│ │ └─ EnemiesKilled > 10 (+10)
│ │
│ ├─ Score "Resist" based on:
│ │ ├─ Sanity > 50 (+20)
│ │ ├─ SurvivorSaved (+25)
│ │ ├─ Playstyle == Stealthy (+10)
│ │ └─ EnemiesKilled == 0 (+15 — Pacifist bonus)
│ │
│ └─ Higher score wins:
│ ├─ Accept > Resist → ENDING B: "The Merge" (Become)
│ └─ Resist ≥ Accept → ENDING A: "The Escape" (Flee)
├─ [Record Result]
│ ├─ GS_HorrorGameState → SetGlobalFlag("EndingAchieved", EndingTag)
│ ├─ BPC_ProgressStatTracker.RecordEnding(EndingTag)
│ └─ Broadcast OnEndingDetermined(EndingTag)
└─ → GM_HorrorGameMode.TriggerEnding(EndingTag)
```
### Ending Variants Summary
| Ending | Name | Conditions | Cutscene Description |
|--------|------|-----------|---------------------|
| **A** | "The Escape" | Resist + low void influence | Player flees collapsing asylum, emerges into daylight. Free, but haunted. |
| **B** | "The Merge" | Accept + high void influence | Entity merges with player. Asylum calms. Patients bow. Player's eyes glow void-purple. |
| **C** | "The Seal" | Sacrifice + 3 VoidShards | Player walks into void. Light fades. Entity sealed. Player's sacrifice remembered in credits. |
---
## Narrative Trigger Volumes (BP_NarrativeTriggerVolume)
| Volume | Level | Trigger | Action |
|--------|-------|---------|--------|
| `BP_NarrativeTrigger_Intro` | L_Asylum_Entry | OnBeginOverlap (player) | Play opening cutscene |
| `BP_NarrativeTrigger_WardA_Enter` | L_Asylum_WardA | OnBeginOverlap | Set flag "WardA_Entered", update objective |
| `BP_NarrativeTrigger_VoidFirst` | L_Asylum_WardB (morgue) | OnBeginOverlap | Trigger first void shift event |
| `BP_NarrativeTrigger_ShadeAppear` | L_Asylum_WardB (courtyard) | OnBeginOverlap | Spawn Shade teaser |
| `BP_NarrativeTrigger_Ending` | L_Asylum_WardensOffice | OnBeginOverlap | Start final dialogue + ending evaluation |
---
## Narrative Flow Diagram
```
Player → ENTRY CHAPTER
│ "Dr. Eliza Vance wakes in a padded cell."
│ "Her memory is fragmented. Voices whisper from the dark."
Player → WARDA CHAPTER
│ "The asylum is a maze. Patients roam, their minds hollowed."
│ "A security office. A pistol. A guarded corridor."
│ "A nurse's station. A keycard. A way forward."
Player → WARDB CHAPTER
│ "The high-security ward. Orderlies patrol. Something watches."
│ "A morgue. A shotgun. A void that shifts reality."
│ "A courtyard. A shadow that moves wrong. First contact."
│ "A chapel. An organ. A melody that opens sealed doors."
Player → BASEMENT CHAPTER
│ "Absolute darkness. The Shade hunts. Every sound is death."
│ "Morgue drawers. A puzzle. A key belonging to the warden."
│ "A crematorium. A void shard. Memories of fire."
Player → WARDEN'S OFFICE
│ "The warden's final journal. The truth laid bare."
│ "The entity speaks through the mirror."
│ "A choice that determines everything."
┌─────────┼─────────┐
▼ ▼ ▼
ENDING A ENDING B ENDING C
Escape Merge Sacrifice
```
---
## Notes for Expansion
- Add **branching mid-game**: saving survivor opens alternate route through WardB
- Add **multiple NPC dialogues**: more survivors with different agendas
- Add **mystery documentation**: some patient files have blacked-out text → find "decoder lens" item
- Add **trial scenarios**: timed escape sequences where player must reach exit before Shade
- Add **New Game+ lore**: after first completion, new documents appear that explain the entity's origin
- Add **voice acting** support: hook VO audio clips to dialogue lines
- Add **dialogue history**: player can review past dialogue in journal
- Multiplayer: narrative flags must be server-authoritative and replicated to joining clients
---
*Narrative & Progression for Project Void. See [GAMEINDEX.md](GAMEINDEX.md) for full game structure. See [07-narrative/](../blueprints/07-narrative/) for framework narrative system specs.*