# 73 — BPC_TutorialSystem

## Blueprint Spec — UE 5.5–5.7

---

### Parent Class
`ActorComponent`

### Dependencies
- [`SS_SettingsManager`](71_SS_SettingsManager.md) — Tutorial enabled setting
- [`BPC_NarrativeState`](../07-narrative/36_BPC_NarrativeState.md) — Tutorial gating
- [`WBP_TutorialOverlay`](../06-ui/47_WBP_TutorialOverlay.md) — Tutorial UI display
- [`DA_TutorialData`](../12-content/77_DA_TutorialData.md) — Tutorial content definitions (Phase 12)

### Purpose
Manages contextual tutorial prompts, guided first-time experiences, and hint systems. Tracks which tutorials the player has seen, what actions they have performed, and shows relevant tips at appropriate moments. Supports contextual triggers (player performs action for first time), zone-based triggers (player enters new area), and manual triggers (player opens tutorial menu).

### Enums

**ETutorialTriggerType**

| Value | Description |
|-------|-------------|
| OnFirstAction | Player performs action for first time |
| OnEnterZone | Player enters tutorial zone volume |
| OnItemPickup | Player picks up key item first time |
| OnEncounterFirstEnemy | First enemy encounter |
| OnManualOpen | Player opens tutorial from menu |
| OnProximityToObject | Near specific interactable |
| OnNarrativePhase | Story progression trigger |
| OnSkillUnlock | Player unlocks ability |

**ETutorialDisplayStyle**

| Value | Description |
|-------|-------------|
| FullScreen | Large overlay with detailed instructions |
| Panel | Bottom-right panel with image and text |
| Tooltip | Small floating hint near relevant object |
| Toast | Brief notification that auto-dismisses |
| Interactive | Step-by-step guided tutorial |

### Structs

**FTutorialEntry**

| Field | Type | Description |
|-------|------|-------------|
| TutorialID | FName | Unique identifier |
| Title | FText | Tutorial title |
| Description | FText | Tutorial body text |
| DisplayStyle | ETutorialDisplayStyle | How to show |
| TriggerType | ETutorialTriggerType | Activation condition |
| bIsMandatory | Bool | Must complete to proceed |
| bCanBeSkipped | Bool | Player can dismiss |
| Priority | Int32 | Display priority |
| CooldownSeconds | Float | Min time before showing again |
| Image | UTexture2D | Optional illustration |
| InputActionShown | FName | Action key to highlight |
| RelatedTutorials | TArray\<FName\> | Chain of tutorials |

### Variables

| Name | Type | Description |
|------|------|-------------|
| `CompletedTutorials` | TSet\<FName\> | Tutorials player has completed |
| `SeenTutorials` | TSet\<FName\> | Tutorials shown this playthrough |
| `PendingTutorials` | TArray\<FTutorialEntry\> | Queue of tutorials to show |
| `ActiveTutorial` | FTutorialEntry | Currently displayed |
| `bTutorialActive` | Bool | Currently showing tutorial |
| `bTutorialsEnabled` | Bool | Global toggle |
| `bSkipAllTutorials` | Bool | Speedrun mode |
| `FirstActionTracker` | TMap\<FName, bool\> | Track first-time actions |
| `ZoneTracker` | TMap\<FName, bool\> | Track visited zones |

### Functions

| Name | Inputs | Outputs | Description |
|------|--------|---------|-------------|
| `Initialize` | — | — | Load completed tutorials from save |
| `RegisterTutorial` | Entry: FTutorialEntry | — | Add tutorial to registry |
| `TriggerTutorial` | TutorialID: FName | — | Force show tutorial |
| `TriggerTutorialByType` | Trigger: ETutorialTriggerType, Context: FName | — | Contextual trigger |
| `CompleteTutorial` | TutorialID: FName | — | Mark as completed |
| `DismissTutorial` | — | — | Close active tutorial |
| `SkipTutorial` | — | — | Skip current tutorial |
| `GetNextTutorialInChain` | TutorialID: FName | FName | Get related tutorial |
| `ShowTutorialOverlay` | Entry: FTutorialEntry | — | Display tutorial UI |
| `HideTutorialOverlay` | — | — | Close tutorial UI |
| `IsTutorialCompleted` | TutorialID: FName | Bool | Check completion |
| `HasTutorialBeenSeen` | TutorialID: FName | Bool | Check if shown |
| `OnFirstAction` | ActionName: FName | — | Track first action |
| `OnEnterZone` | ZoneName: FName | — | Track zone entry |
| `RegisterFirstActionTutorials` | — | — | Register common action tutorials |
| `RegisterZoneTutorials` | — | — | Register zone tutorials |
| `ProcessPendingQueue` | — | — | Show next queued tutorial |
| `SaveTutorialState` | — | — | Persist to save system |

### Blueprint Flow

```
[Initialize]
  └─► Load CompletedTutorials from save data
  └─► RegisterFirstActionTutorials()
  └─► RegisterZoneTutorials()
  └─► Listen to events:
         BPC_HealthSystem.OnHealthChanged (first damage)
         BPC_InventoryComponent.OnItemAdded (first pickup)
         BPC_InteractDetector.OnInteraction (first interact)
         BPC_Combat.OnFirstAttack (first attack)
         BPC_ProceduralEncounter.OnEncounterStarted (first combat)

[OnFirstAction]
  └─► If FirstActionTracker[ActionName] == true: return (already tracked)
  └─► FirstActionTracker[ActionName] = true
  └─► Look up tutorial with TriggerType == OnFirstAction and Context == ActionName
  └─► If found and not completed:
         TriggerTutorial(TutorialID)

[TriggerTutorial]
  └─► If bSkipAllTutorials or not bTutorialsEnabled: return
  └─► If IsTutorialCompleted(TutorialID): return
  └─► If bTutorialActive:
         Add to PendingTutorials queue
         Return
  └─► Get FTutorialEntry from registry
  └─► ActiveTutorial = Entry
  └─► bTutorialActive = true
  └─► SeenTutorials.Add(TutorialID)
  └─► ShowTutorialOverlay(Entry)
  └─► If bIsMandatory:
         Pause game and force focus
  └─► Start cooldown timer for auto-dismiss

[ShowTutorialOverlay]
  └─► Based on DisplayStyle:
         FullScreen:  Create WBP_TutorialFullScreen, add to viewport
         Panel:       Create WBP_TutorialPanel, add to viewport corner
         Tooltip:     Create WBP_TutorialTooltip, attach to relevant actor
         Toast:       Create WBP_TutorialToast, auto-dismiss after 5 seconds
         Interactive: Create WBP_InteractiveTutorial, step-by-step guide
  └─► Set tutorial text, title, image
  └─► If InputActionShown is set:
         Highlight the key in on-screen prompts

[CompleteTutorial]
  └─► CompletedTutorials.Add(TutorialID)
  └─► SeenTutorials.Add(TutorialID)
  └─► HideTutorialOverlay()
  └─► bTutorialActive = false
  └─► SaveTutorialState()
  └─► ProcessPendingQueue()

[ProcessPendingQueue]
  └─► If PendingTutorials.Num() > 0:
         Sort by Priority descending
         Next = PendingTutorials[0]
         PendingTutorials.RemoveAt(0)
         TriggerTutorial(Next.TutorialID)

[DismissTutorial]
  └─► If ActiveTutorial.bCanBeSkipped or not bIsMandatory:
         HideTutorialOverlay()
         bTutorialActive = false
         ProcessPendingQueue()

[SaveTutorialState]
  └─► Serialize CompletedTutorials to array
  └─► Call SS_SaveManager.SavePersistentData("Tutorials", CompletedTutorialsArray)
```

### Event Dispatchers

| Name | Payload | Description |
|------|---------|-------------|
| `OnTutorialStarted` | TutorialID: FName, Title: FText | Tutorial began |
| `OnTutorialCompleted` | TutorialID: FName | Tutorial finished |
| `OnTutorialDismissed` | TutorialID: FName, bWasSkipped: Bool | Tutorial closed |

### Communications With

| Target | Method | Why |
|--------|--------|-----|
| [`SS_SettingsManager`](71_SS_SettingsManager.md) | Direct call | Tutorial enabled check |
| [`SS_SaveManager`](../05-saveload/28_SS_SaveManager.md) | Direct call | Persist tutorial state |
| [`BPC_NarrativeState`](../07-narrative/36_BPC_NarrativeState.md) | Event | Narrative-gated tutorials |
| [`WBP_TutorialOverlay`](../06-ui/47_WBP_TutorialOverlay.md) | Create widget | Display tutorials |
| [`BP_PlayerController`] | Cast | Pause game for mandatory |

### Reuse Notes
- Tutorials are data-driven via FTutorialEntry — easy to add new ones
- First-action tracking uses FName keys for extensibility
- Queue system prevents tutorials from overlapping
- Skip option for speedrunners and repeat playthroughs
- State persists across save/load so tutorials don't repeat