# `BPC_DiegeticDisplay` — Diegetic Display System

**Parent Class:** `ActorComponent`
**Category:** Interaction / UI
**Target UE Version:** 5.5–5.7
**Build Phase:** 2 — Interaction

---

## 1. Overview

`BPC_DiegeticDisplay` manages any in-world screen that renders game UI directly inside the 3D scene — watches, PDAs, tablets, computer monitors, cockpit screens. Instead of traditional HUD overlays, the player looks down at their character's wrist (watch) or picks up a tablet to see inventory/map/messages rendered as a world-space widget on a static mesh.

The component provides a 6-mode state machine (`Off → Splash → Idle → Menu → Messaging → Mapping/Scanning`), handles input routing to the active widget, manages screen transitions (flicker, boot sequence, static interference), and communicates with other systems via Event Dispatchers.

---

## 2. Mermaid — Display Mode State Machine

```mermaid
flowchart TD
    A[Off] --> B{Power On?}
    B -->|Yes| C[Splash]
    C --> D[Idle]
    D --> E{User Input?}
    E -->|Open Menu| F[Menu]
    E -->|Open Map| G[Mapping]
    E -->|Receive Message| H[Messaging]
    E -->|Activate Scan| I[Scanning]
    F --> J{Close Menu?}
    J -->|Yes| D
    G --> K{Close Map?}
    K -->|Yes| D
    H --> L{Message Dismissed?}
    L -->|Yes| D
    I --> M{Scan Complete?}
    M -->|Yes| D
    D --> N{Idle Timeout?}
    N -->|Yes| A
```

---

## 3. Enums

### `E_DiegeticDisplayMode`

| Value | Description |
|-------|-------------|
| `Off` | Screen completely off (black/no widget). |
| `Splash` | Boot-up animation playing (logo, startup sequence). |
| `Idle` | Default active state. May show time, low-priority info. |
| `Menu` | Full menu — inventory, settings, journal. |
| `Messaging` | Incoming/outgoing message display. |
| `Mapping` | Map or floorplan overlay. |
| `Scanning` | Active scanning mode (environment analysis, entity detection). |

### `E_ScreenEffect`

| Value | Description |
|-------|-------------|
| `None` | No effect — clean image. |
| `Static` | Analog TV static / interference. |
| `Flicker` | Rapid on/off flicker (power fluctuation). |
| `Glitch` | Digital artifact corruption. |
| `ScanLine` | CRT scan lines overlay. |
| `BootSequence` | OS-style boot animation (loading bars, text crawl). |
| `LowBattery` | Dim + pulsing warning overlay. |

### `E_DisplayInputMode`

| Value | Description |
|-------|-------------|
| `Locked` | Display ignores player input. |
| `Passthrough` | Input forwarded to active widget. |
| `Modal` | Input consumed entirely by display (menu open). |

---

## 4. Structs

### `S_DiegeticDisplayConfig`

| Field | Type | Description |
|-------|------|-------------|
| `DisplayName` | `FText` | Human-readable name (e.g., "Wrist Link", "PDA-7"). |
| `DefaultMode` | `E_DiegeticDisplayMode` | Mode to start in at BeginPlay. |
| `bStartPoweredOn` | `bool` | If false, starts in Off mode. |
| `WidgetClass` | `TSubclassOf<UUserWidget>` | World-space widget class to render on the screen. |
| `ScreenMeshComponent` | `FName` | Name of the static mesh component the widget renders on. |
| `ScreenSize` | `FVector2D` | Widget resolution in pixels (e.g., 256x144). |
| `InteractionDistance` | `float` | Max distance to interact with the display (0 = attached to player). |
| `bIsPlayerOwned` | `bool` | If true, attached to player (watch) vs. world object (terminal). |
| `IdleTimeoutSeconds` | `float` | Seconds of inactivity before powering off. 0 = never timeout. |
| `BootDuration` | `float` | Seconds the Splash animation plays. |
| `bHasMapMode` | `bool` | If true, Mapping mode is available. |
| `bHasScanMode` | `bool` | If true, Scanning mode is available. |
| `bReplicates` | `bool` | Whether display state is replicated. |

### `S_ScreenState`

| Field | Type | Description |
|-------|------|-------------|
| `CurrentMode` | `E_DiegeticDisplayMode` | Active display mode. |
| `ActiveEffect` | `E_ScreenEffect` | Currently playing visual effect. |
| `EffectIntensity` | `float` | 0–1 intensity of the active effect. |
| `InputMode` | `E_DisplayInputMode` | Current input routing mode. |
| `BatteryLevel` | `float` | 0–1 remaining battery (if applicable). |
| `bIsPoweredOn` | `bool` | Quick check for power state. |

### `S_MessagePayload`

| Field | Type | Description |
|-------|------|-------------|
| `SenderName` | `FText` | Name of message sender. |
| `MessageBody` | `FText` | Message text content. |
| `bIsUrgent` | `bool` | If true, forces display to Messaging mode with priority. |
| `AssociatedQuestTag` | `FGameplayTag` | Quest/objective this message relates to. |
| `AudioAttachment` | `USoundBase*` | Optional audio clip attached to message. |

---

## 5. Variables

### Configuration (Instance Editable, Expose On Spawn)

| Variable | Type | Description |
|----------|------|-------------|
| `DisplayConfig` | `S_DiegeticDisplayConfig` | Primary configuration struct. |
| `IdleWidget` | `TSubclassOf<UUserWidget>` | Widget to display in Idle mode. |
| `MenuWidget` | `TSubclassOf<UUserWidget>` | Widget to display in Menu mode. |
| `MessagingWidget` | `TSubclassOf<UUserWidget>` | Widget for incoming/outgoing messages. |
| `MapWidget` | `TSubclassOf<UUserWidget>` | Widget for mapping overlay. |
| `ScanWidget` | `TSubclassOf<UUserWidget>` | Widget for scanning mode. |

### State (Blueprint Read Only)

| Variable | Type | Description |
|----------|------|-------------|
| `CurrentState` | `S_ScreenState` | Struct holding all current screen state. |
| `ActiveWidget` | `UUserWidget*` | Reference to the currently displayed widget instance. |
| `ScreenMesh` | `UStaticMeshComponent*` | Cached reference to the screen mesh. |
| `IdleTimerHandle` | `FTimerHandle` | Handle for idle power-off timer. |
| `BootTimerHandle` | `FTimerHandle` | Handle for boot-up duration timer. |
| `PendingMessages` | `TArray<S_MessagePayload>` | Queue of messages to display. |
| `CurrentMessageIndex` | `int32` | Index into PendingMessages for cycling. |

### Input Handling (Blueprint Read Only)

| Variable | Type | Description |
|----------|------|-------------|
| `bInputConsumed` | `bool` | Whether the display is currently consuming input. |
| `InputActionBindings` | `TArray<FInputActionBinding>` | Active input bindings for display mode. |

---

## 6. Functions & Events

### Public Functions

| Function | Description |
|----------|-------------|
| `PowerOn` | Boots the display. Plays Splash sequence, then transitions to Idle. |
| `PowerOff` | Immediately turns off display, clears widget, kills idle timer. |
| `SetDisplayMode` | Transitions to any `E_DiegeticDisplayMode`. Plays transition effect. |
| `ApplyScreenEffect` | Applies a temporary `E_ScreenEffect` for a given duration. |
| `ClearScreenEffect` | Immediately clears active effect, returns to clean image. |
| `ReceiveMessage` | Adds a `S_MessagePayload` to the queue. If current mode is Idle, auto-switches to Messaging. |
| `DismissMessage` | Closes current message. If queue has more, shows next; else returns to Idle. |
| `OpenMenu` | Transitions to Menu mode. Locks input to display. |
| `CloseMenu` | Returns to Idle mode. Releases input. |
| `OpenMap` | Transitions to Mapping mode (if `bHasMapMode`). |
| `CloseMap` | Returns to Idle mode. |
| `StartScan` | Begins Scanning mode (if `bHasScanMode`). |
| `StopScan` | Ends Scanning mode, returns to Idle. |
| `ToggleDisplay` | Toggles between current mode and Off/Idle based on power state. |
| `IsDisplayActive` | Returns true if powered on and not Off/Splash/Boot. |
| `GetScreenState` | Returns the `S_ScreenState` struct. |

### Protected Functions

| Function | Description |
|----------|-------------|
| `BeginPlay` | Caches references, creates widget instance if auto-start. |
| `Tick` | If `ActiveEffect != None`, applies effect material parameter animation. |
| `CreateWidgetInstance` | Creates the world-space widget for the given mode class. Attaches to `ScreenMesh`. |
| `DestroyWidgetInstance` | Removes and destroys current widget. |
| `PlayBootSequence` | Timelines splash animation. On complete, calls `OnBootComplete`. |
| `OnBootComplete` | Transitions to Idle, starts idle timeout timer. |
| `StartIdleTimer` | Resets and starts the idle timeout. |
| `OnIdleTimeout` | Powers off the display. |
| `SetupInputForMode` | Binds/unbinds input actions based on `CurrentState.InputMode`. |
| `HandleMenuInput` | Processes navigation/select inputs in Menu mode. |
| `HandleMessageInput` | Processes dismiss/respond inputs in Messaging mode. |
| `HandleMapInput` | Processes pan/zoom inputs in Mapping mode. |
| `HandleScanInput` | Processes scan activation input. |

### Event Dispatchers

| Dispatcher | Payload | Description |
|------------|---------|-------------|
| `OnDisplayModeChanged` | `E_DiegeticDisplayMode NewMode`, `E_DiegeticDisplayMode PreviousMode` | Fired on any mode transition. |
| `OnDisplayPoweredOn` | — | Fired after boot sequence completes. |
| `OnDisplayPoweredOff` | — | Fired when display is turned off. |
| `OnMessageReceived` | `S_MessagePayload Message` | Fired when a new message enters the queue. |
| `OnMessageDismissed` | `S_MessagePayload Message` | Fired when a message is dismissed. |
| `OnScreenEffectStarted` | `E_ScreenEffect Effect`, `float Duration` | Fired when a screen effect begins. |
| `OnScreenEffectEnded` | `E_ScreenEffect Effect` | Fired when a screen effect ends. |
| `OnDisplayInputLocked` | `bool bIsLocked` | Fired when input mode changes to Locked or unlocked. |

---

## 7. Blueprint Graph Flow

```
Event BeginPlay
    → GetOwner → FindComponentByTag (ScreenMeshComponent name) → Cache ScreenMesh
    → If DisplayConfig.bStartPoweredOn → Call PowerOn
    → Else → Set CurrentState.CurrentMode = Off

PowerOn
    → Set CurrentState.bIsPoweredOn = true
    → Set CurrentState.InputMode = Locked
    → Broadcast OnDisplayModeChanged (Off → Splash)
    → PlayBootSequence

PlayBootSequence
    → ApplyScreenEffect (BootSequence)
    → Set Timer by Event (DisplayConfig.BootDuration, Call OnBootComplete)

OnBootComplete
    → ClearScreenEffect
    → Set CurrentState.CurrentMode = Idle
    → CreateWidgetInstance (IdleWidget)
    → Set CurrentState.InputMode = Passthrough
    → Broadcast OnDisplayPoweredOn
    → Broadcast OnDisplayModeChanged (Splash → Idle)
    → StartIdleTimer

SetDisplayMode
    → Store PreviousMode = CurrentState.CurrentMode
    → If PreviousMode == NewMode → return
    → DestroyWidgetInstance
    → Broadcast OnDisplayModeChanged (PreviousMode → NewMode)
    → Set CurrentState.CurrentMode = NewMode
    → Branch on NewMode:
        — Menu → CreateWidgetInstance (MenuWidget), SetupInputForMode (Modal)
        — Messaging → CreateWidgetInstance (MessagingWidget), SetupInputForMode (Modal)
        — Mapping → CreateWidgetInstance (MapWidget), SetupInputForMode (Modal)
        — Scanning → CreateWidgetInstance (ScanWidget), SetupInputForMode (Modal)
        — Idle → CreateWidgetInstance (IdleWidget), SetupInputForMode (Passthrough), StartIdleTimer
    → If NewMode != Idle → Clear idle timer

ReceiveMessage
    → PendingMessages.Add(Message)
    → If CurrentState.CurrentMode == Idle:
        → SetDisplayMode (Messaging)
    → If CurrentState.CurrentMode == Messaging:
        → Update widget to show new message count
    → Broadcast OnMessageReceived

DismissMessage
    → Remove CurrentMessage from PendingMessages
    → If PendingMessages.Num() > 0:
        → Show next message
    → Else:
        → SetDisplayMode (Idle)
    → Broadcast OnMessageDismissed

PowerOff
    → ClearScreenEffect
    → DestroyWidgetInstance
    → Clear Input Bindings
    → Set CurrentState.bIsPoweredOn = false
    → Set CurrentState.CurrentMode = Off
    → Clear IdleTimerHandle
    → Broadcast OnDisplayPoweredOff
    → Broadcast OnDisplayModeChanged (previous → Off)

OpenMenu
    → SetDisplayMode (Menu)

CloseMenu
    → SetDisplayMode (Idle)

Event Tick (DeltaTime)
    → If ActiveEffect != None and ActiveEffectDuration > 0:
        → Update material parameter for effect animation (flicker intensity, static noise)
        → Decrement remaining duration
        → If duration expired → ClearScreenEffect
```

---

## 8. Replication

| Variable | Replication | Callback |
|----------|-------------|----------|
| `CurrentState.CurrentMode` | `RepNotify` | `OnRep_DisplayMode` — recreates widget on remote clients |
| `CurrentState.ActiveEffect` | `Replicated` | — |
| `CurrentState.bIsPoweredOn` | `Replicated` | — |

**Authority:** Server controls power/mode transitions. Client predicts input for Menu/Message dismissal, but server validates.

---

## 9. Widget Setup (Per-Mode)

| Mode | Widget Content |
|------|----------------|
| `Idle` | Time display, low-priority notifications, battery indicator. |
| `Menu` | Radial or list menu: Inventory, Journal, Settings, Map, Messages. |
| `Messaging` | Scrolling text log with sender avatar, reply options, audio playback. |
| `Mapping` | 2D floorplan with player position marker, discovered rooms, objective markers. |
| `Scanning` | Overlaid data readouts: entity heat signatures, material composition, structural integrity. |

All widgets are added as `UUserWidget` instances attached to the screen mesh via `AddToViewport`/`SetWidget` on a `UWidgetComponent`. The component handles creation/destruction; individual widgets handle their own internal state.

---

## 10. Dependencies & Communication

| System | Relationship |
|--------|--------------|
| `BPC_InteractionDetector` | Detects world terminals; calls `Interact_Implementation` on the host actor. |
| `BPC_InventoryComponent` | Menu mode reads inventory contents to display in widget. |
| `BPC_MappingSubsystem` | Supplies floorplan data to Map widget. |
| `BPC_ScanningSubsystem` | Supplies scan results to Scan widget. |
| `GI_GameFramework` | Provides game time, date, and phase info for idle widget display. |
| `BPC_StressSystem` | High stress may trigger screen flicker/glitch effects. |
| `BPC_HealthSystem` | Low health may apply low battery / dimming effect. |
| `BPC_PlayerMetricsTracker` | Logs display usage events for analytics. |
| `BPC_AdaptiveDifficulty` | May adjust idle timeout or boot duration based on player performance. |
| `Save/Load System` | Saves `CurrentState` and `PendingMessages` array for restore. |
| `Narrative Subsystem` | Pushes messages via `ReceiveMessage` for story-driven communication. |

---

## 11. Success Criteria

1. Display boots with splash sequence and transitions to idle.
2. Player can open/close menu from idle.
3. Receiving a message from narrative subsystem forces display to Messaging mode.
4. Player dismisses message and display returns to idle.
5. Display powers off after idle timeout; interact to power back on.
6. Screen effects (static, flicker, glitch) play on demand and clear correctly.
7. Stress/health systems trigger appropriate visual feedback on the display.
8. Multiplayer: display mode syncs across clients.
9. Save/load restores display mode, pending messages, and effect state.
10. Multiple displays (watch + terminal) operate independently with separate state.

---

## 12. Data Flow Summary

```
External System (e.g. Narrative)
    → calls ReceiveMessage (S_MessagePayload)
    → BPC_DiegeticDisplay.PendingMessages.Add
    → Auto-switches to Messaging mode if currently Idle
    → Broadcast OnMessageReceived
    → Widget shows message content
    → Player dismisses → DismissMessage
    → Broadcast OnMessageDismissed
    → If queue empty → return to Idle

Player Input (Menu)
    → Input routed via SetupInputForMode (Modal)
    → Widget handles navigation
    → On close → CloseMenu → SetDisplayMode (Idle)