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.
This commit is contained in:
354
docs/game/narrative-progression.md
Normal file
354
docs/game/narrative-progression.md
Normal file
@@ -0,0 +1,354 @@
|
||||
# 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.*
|
||||
Reference in New Issue
Block a user