# `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` | 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` | Widget to display in Idle mode. | | `MenuWidget` | `TSubclassOf` | Widget to display in Menu mode. | | `MessagingWidget` | `TSubclassOf` | Widget for incoming/outgoing messages. | | `MapWidget` | `TSubclassOf` | Widget for mapping overlay. | | `ScanWidget` | `TSubclassOf` | 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` | 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` | 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)