# 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.*
