Files
tedwardsandCursor ee65271212 Document Batch 4D archaeology and add README title image outside LFS.
Exclude REALMSINRUIN_TITLE_DEV.png from Git LFS so the README hero renders on Gitea.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 23:17:56 -07:00

210 lines
17 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 11 — UI, HUD, and Sessions
**Status: Draft**
- **Scope:** Pass 4 frontend / sessions / maps + Pass 10 HUD / widget architecture (Batch 4D). Static read-only only.
- **Inspection method:** BlueprintTools `read_graph_dsl` / `list_events`; ObjectTools CDO; AssetTools deps/refs; UMG `GetWidgetDescription`; filesystem `Config/*.ini` grep; EditorApp `IsPIERunning` / SceneTools `get_current_level`.
- **Last updated:** 2026-07-16
- **Current phase:** Phase 1 — Static Architecture
- **Last completed pass:** Pass 4 + Pass 10 (Batch 4D)
- **Next pass expected to contribute:** Pass 11 (synthesis) when explicitly authorized
## Draft tracking
### Completed sections
- Framework / frontend matrix
- Session create / find / join graphs and classification
- Online configuration inventory (negative for OnlineSubsystem under project Config)
- Map / travel / pawn-spawn matrix
- HUD architecture (ASC Overlay + legacy BPI hole)
- Widget inventory
- Character-selection matrix
### Pending sections
- Runtime session / travel validation (PIE / standalone / multiplayer — not authorized)
- JoinSession internal ClientTravel confirmation
- CommonUI production usage beyond enabled plugin
### Evidence still required
- Whether `JoinSession` travels without an explicit success pin
- Whether listen-server remote clients ever receive `WBP_CharacterSelect`
- Whether `W_HUD_OLD` is ever created (no connected creator found)
- Steam / OnlineSubsystem runtime defaults when INI keys are absent
### Tool or visibility limitations
- Map World Settings GameMode not in asset-registry tags; inferred from map→GM package dependencies
- Sphere / widget collision templates often unreadable via CDO `get_properties`
- Native `RIRHUD` / `OverlayWidgetController` bodies opaque to BP DSL (header/source used where present)
- `GI_Dungeoneer` empty EventGraph returns `""` from `read_graph_dsl`
---
## 1. Framework and frontend matrix
| Asset | Parent | Role | Entry points | Connected downstream flow | Status | Evidence |
|-------|--------|------|--------------|---------------------------|--------|----------|
| `/Game/_Main/Blueprints/Game/GameInstance/GI_Dungeoneer` | `GameInstance` | Intended GI scaffold | None found | Empty EventGraph; **0 referencers**; not in `DefaultEngine.ini` `GameInstanceClass` | Present but Unconnected | AssetTools refs; DSL empty; Config grep |
| `/Game/_Main/Blueprints/Game/GameMode/GM_MainMenu` | `GameModeBase` | Main-menu GameMode | Map World Settings (MainMenu) | CDO: `PC_MainMenu`, `BP_MainMenuPawn`; EventGraph empty stubs | Active but Unverified | CDO + map deps |
| `/Game/_Main/Blueprints/Game/GameMode/GM_Dungeoneer` | `GameModeBase` | Gameplay GameMode | Test01 / Dev_Island / LEVEL_01 deps | Collects PlayerStarts; `GetSelectedClass``PlayerFirstSpawn`; PostLogin/Logout track PCs | Active but Unverified | EventGraph DSL |
| `/Game/_Main/Blueprints/Player/PC_MainMenu` | `PlayerController` | Host / join session owner | BeginPlay; `HostGame`; `JoinGame` | Creates `WBP_MainMenu`; AdvancedSessions create; JoinSession | Active but Unverified | EventGraph DSL |
| `/Game/_Main/Blueprints/Player/PC_Character` | `RIRPlayerController` | Char-select + spawn | BeginPlay; BPI select/spawn/respawn | Char-select widget (server branch); `ServerSpawnCharacter` → GM → `PlayerFirstSpawn` | Partial | EventGraph + `list_events` |
| `/Game/_Main/UI/Widgets/MainMenu/BP_MainMenuPawn` | (menu pawn) | Default pawn on MainMenu | GM_MainMenu DefaultPawn | Visual / idle menu pawn | Active but Unverified | GM CDO |
| `/Game/_Main/UI/Widgets/MainMenu/WBP_MainMenu` | UserWidget | Main menu + session UI | PC_MainMenu BeginPlay | NewGame→Test01; Host→PC_MainMenu; Find→FindSessionsAdvanced; slots | Active but Unverified | EventGraph DSL |
| `/Game/_Main/UI/Widgets/MainMenu/WBP_GameSlot` | UserWidget | Session row | Created by Find success loop | Displays GameName/MaxPlayers; Join→PC_MainMenu.JoinGame | Active but Unverified | EventGraph DSL |
| `/Game/_Main/UI/Widgets/CharacterSelectScreen/WBP_CharacterSelect` | UserWidget | Class picker | PC_Character BeginPlay (Authority+IsServer) | Sets class soft refs; Start→`PlayerSelectScreenChoice`; MainMenu→OpenLevel MainMenu | Partial (server-only create) | EventGraph DSL |
| `/Game/_Main/UI/Widgets/WBP_PreAlphaDevMessage` | UserWidget | Dev watermark | PC_MainMenu + PC_Character BeginPlay | AddToViewport only | Active but Unverified | EventGraph DSL |
| `/Game/_Main/Blueprints/Examples/ExampleAdvancedSessionsFunctionsChar` | Character example | Plugin sample | None | **0 referencers** | Example Only | get_referencers |
---
## 2. Session flow matrix
| Operation | Entry point | Session node | Settings | Success path | Failure path | Travel/cleanup | Status |
|-----------|-------------|--------------|----------|--------------|--------------|----------------|--------|
| Host / create | `WBP_MainMenu` StartGameButton → `PC_MainMenu.HostGame` | `CreateAdvancedSession` | Extra: `GameName` (string), `MaxPlayers` (int); MaxPlayers arg = Players (24) | OnSuccess → `OpenLevel` `/Game/_Main/Levels/Testing/Dev_Island` with `?listen` | **No OnFailure pin connected in DSL** | Listen-server OpenLevel; no DestroySession | Partial |
| Find | RefreshButton / RefreshGames | `FindSessionsAdvanced` (results max 999) | Default AdvancedSessions search (no extra filters in graph) | OnSuccess → clear scroll → create `WBP_GameSlot` per result | OnFailure → PrintString `FailedtoFindSessions` | None | Active but Unverified |
| Join | `WBP_GameSlot` Clicked → `PC_MainMenu.JoinGame` | Engine/Advanced `JoinSession` | SearchResult from slot | **No OnSuccess pin in DSL** | OnFailure → PrintString `FailedtoJoinGame` | Relies on JoinSession internal travel; **no explicit ClientTravel** | Partial |
| Destroy / leave | — | — | — | — | — | **No DestroySession / EndSession graph found** | Missing |
| Return to menu | `WBP_CharacterSelect` MainMenuButton | None | — | `OpenLevel` MainMenu | — | Level travel only; no session cleanup | Partial |
| Single-player New Game | `WBP_MainMenu` NewGameButton | None | — | `OpenLevel` Test01 | — | No session | Active but Unverified |
**Classification note:** Production AdvancedSessions **nodes are connected** in menu Blueprints. That does **not** prove sessions work without OnlineSubsystem configuration + runtime testing. Plugins enabled ≠ production online service configured.
---
## 3. Online configuration inventory
Project `Config/*.ini` and `Plugins/*/Config/*.ini` grep for OnlineSubsystem / Steam / NetDriver / GameInstanceClass returned **no matches**. No `Saved/Config/**/*.ini` present in the workspace snapshot.
| File | Section | Key | Value classification | Consumer | Ownership | Status |
|------|---------|-----|----------------------|----------|-----------|--------|
| `Config/DefaultEngine.ini` | `/Script/EngineSettings.GameMapsSettings` | `GameDefaultMap` | `/Game/_Main/Levels/Maps/MainMenu.MainMenu` | Engine startup map | Project-owned | Observed Implementation |
| `Config/DefaultEngine.ini` | same | `EditorStartupMap` | `/Game/_Main/Levels/Testing/Test01.Test01` | Editor load | Project-owned | Observed Implementation |
| `Config/DefaultEngine.ini` | — | `GameInstanceClass` | **Absent** | Would wire `GI_Dungeoneer` | — | Missing |
| `Config/DefaultEngine.ini` | — | `GlobalDefaultGameMode` | **Absent** | Per-map overrides used instead | — | Missing (by design / debt) |
| `Config/*.ini` | — | `DefaultPlatformService` / `OnlineSubsystem*` / `SteamDevAppId` / `SteamNetDriver` / `NetDriverDefinitions` | **Absent** | AdvancedSessions create/find/join | Engine default / unknown | Missing (project config) |
| `REALMSINRUIN_DEV.uproject` | Plugins | `AdvancedSessions`, `AdvancedSteamSessions` | Enabled (prior Pass 1) | Menu session nodes | Project-owned plugin enable | Active but Unverified |
| — | — | Secret-bearing Steam keys | **Not present** in inspected project Config | — | — | Negative inventory |
**Production reachability:** Session Blueprint path is **Partial / Active but Unverified**. OnlineSubsystem project configuration is **Missing**. Do not claim multiplayer sessions function.
---
## 4. Map and travel matrix
| Map | GameMode | Entry referencers | Exit/travel path | Pawn-spawn path | Role | Reachability |
|-----|----------|-------------------|------------------|-----------------|------|--------------|
| `/Game/_Main/Levels/Maps/MainMenu` | `GM_MainMenu` (deps) | `GameDefaultMap`; CharacterSelect MainMenuButton | Host→Dev_Island; NewGame→Test01; Join→(JoinSession) | `BP_MainMenuPawn` via DefaultPawn | Frontend | Config + UI connected |
| `/Game/_Main/Levels/Testing/Test01` | `GM_Dungeoneer` | NewGame; EditorStartupMap | CharSelect→MainMenu OpenLevel | Char-select → ServerSpawnCharacter → PlayerFirstSpawn | Testing gameplay | Connected (SP path) |
| `/Game/_Main/Levels/Testing/Dev_Island` | `GM_Dungeoneer` | Host OnSuccess `?listen` | Same char-select spawn | Same | Host listen target | Connected (host path) |
| `/Game/_Main/Levels/Maps/LEVEL_01` | `GM_Dungeoneer` (+ dungeon generator dep) | No menu OpenLevel found | Unknown | Same GM spawn path if entered | Gameplay / dungeon | Present; menu reachability **Unknown** |
No dedicated lobby or character-select map. Character select is an in-level widget under `GM_Dungeoneer`.
---
## 5. Pawn spawn and possession (DefaultPawn = None)
**Observed Implementation** connected path:
1. `GM_Dungeoneer` CDO `DefaultPawnClass = None`
2. `PC_Character` BeginPlay (Authority ∧ IsServer) creates `WBP_CharacterSelect`, AddToViewport, GameAndUI cursor
3. Player picks Paladin / Wizard / Cleric / Amazon → stores soft class on widget
4. StartButton → `PlayerSelectScreenChoice(SelectedClass)` → RemoveFromParent HUD → `ServerSpawnCharacter`
5. `GM_Dungeoneer.GetSelectedClass``PlayerFirstSpawn(PC, class, random PlayerStart location + Z50)`
6. `SpawnActor` + `Possess`
**Remote branch empty:** listen-server **clients** have no CreateWidget for character select in this graph (**Partial** / multiplayer risk).
**Gunslinger:** `Player_Gunslinger` exists (doc 08) but is **not** offered on `WBP_CharacterSelect`.
**Respawn:** `PlayerRespawn` also SpawnActor+Possess; call-site inventory deferred (not fully traced this pass).
---
## 6. HUD architecture matrix
| Layer | Creator | Widget/controller | Data source | Viewport path | Cleanup/recreation | Status |
|-------|---------|-------------------|-------------|---------------|--------------------|--------|
| Game HUD class | Engine via `GM_Dungeoneer.HUDClass` | `/Game/_Main/UI/Widgets/HUD/WBP_PlayerHUD` (`RIRHUD`) | CDO class defaults only (data-only BP) | Engine HUD spawn | Per-PC HUD lifetime | Active but Unverified |
| ASC Overlay | Native `ARIRHUD::InitOverlay` from `ARIRPlayerCharacter::InitAbilityActorInfo` | `WBP_Overlay` + `BP_OverlayWidgetController` | `URIRAttributeSet` Health/Mana/(Stamina broadcasts) | Native AddToViewport | Recreate on InitAbilityActorInfo / local HUD present | Active but Unverified |
| Health bar | `WBP_Overlay` EventWidgetControllerSet | `WBP_HealthProgressBar` | OnHealthChanged / OnMaxHealthChanged | Child of Overlay | With Overlay | Connected (static) |
| Mana bar | same | `WBP_ManaProgressBar` | OnManaChanged / OnMaxManaChanged | Child of Overlay | With Overlay | Connected (static) |
| Stamina UI | — | **No stamina widget in Overlay tree** | Controller still has stamina delegates (doc 06 type debt) | **None** | — | Present but Unconnected (broadcasts without widget) |
| Legacy HUD update | `BP_PlayerCharacterBase` Server_UpdateHUD | `BPI_PlayerController.UpdatePlayerHUD` | DEPRECATED health/mana % | **No implementer** | — | **Present but Unconnected** |
| Legacy widget asset | Unknown | `/Game/_Main/UI/Widgets/HUD/W_HUD_OLD` | Unknown | No creator found this pass | — | Present but Unreferenced / Unknown |
| Char-select UI | PC_Character BeginPlay | `WBP_CharacterSelect` | Local widget vars | AddToViewport (server) | RemoveFromParent on Start | Partial |
| Main menu UI | PC_MainMenu BeginPlay | `WBP_MainMenu` | Session results | AddToViewport | Level travel tears down | Active but Unverified |
### ASC Overlay path (Observed Implementation)
`InitAbilityActorInfo``ARIRHUD::InitOverlay` → create `OverlayWidgetClass` (`WBP_Overlay_C`) + `OverlayWidgetControllerClass` (`BP_OverlayWidgetController_C`) → bind ASC → broadcast initial values → progress bars bind delegates → SetProgressBarPercent.
**CDO assignments confirmed:** both Overlay classes non-null on `Default__WBP_PlayerHUD_C` — null-class abort of InitOverlay **not** indicated for defaults.
### Legacy path (caller Connected; receiver Missing)
Possession → Delay → `Server_UpdateHUD` → DEPRECATED % → `UpdatePlayerHUD` on PC.
`PC_Character` `list_events`: `UpdatePlayerHUD` **`bIsImplemented=false`**. Native `ARIRPlayerController` header/source contain **no** `UpdatePlayerHUD`. **Issue:** Incomplete Refactor / Present but Unconnected.
**Dual-system reachability:** ASC Overlay statically reachable after pawn InitAbilityActorInfo. Legacy UpdatePlayerHUD call is connected from character but **lands on unimplemented BPI** — not a second working bar system unless another implementer exists (none found on PC_Character).
---
## 7. Widget inventory
| Widget/HUD | Asset class | Parent | Owner | Data inputs | Connected entry path | Status |
|------------|-------------|--------|-------|-------------|----------------------|--------|
| WBP_PlayerHUD | AHUD BP | `RIRHUD` | GM_Dungeoneer HUDClass | Overlay class CDOs | GameMode HUD spawn | Active but Unverified |
| WBP_Overlay | UserWidget | `RIRUserWidget` | RIRHUD InitOverlay | WidgetController | Native InitOverlay | Active but Unverified |
| BP_OverlayWidgetController | WidgetController BP | `OverlayWidgetController` | InitOverlay | ASC AttributeSet | Native | Active but Unverified (empty BP graph) |
| WBP_HealthProgressBar | UserWidget | ProgressBar hierarchy | Overlay child | Health/MaxHealth delegates | EventWidgetControllerSet | Connected |
| WBP_ManaProgressBar | UserWidget | ProgressBar hierarchy | Overlay child | Mana/MaxMana delegates | EventWidgetControllerSet | Connected |
| WBP_ProgressBarBase | UserWidget | — | Parent of bars | — | Inheritance | Scaffolding |
| WBP_MainMenu | UserWidget | — | PC_MainMenu | Players, FoundSessions | BeginPlay | Active but Unverified |
| WBP_GameSlot | UserWidget | — | MainMenu Find loop | FoundSession | Find OnSuccess | Active but Unverified |
| WBP_CharacterSelect | UserWidget | — | PC_Character | SelectedCharacterClass | Server BeginPlay | Partial |
| WBP_PreAlphaDevMessage | UserWidget | — | Both PCs | None | BeginPlay | Active but Unverified |
| W_HUD_OLD | UserWidget | — | Unknown | Unknown | **No creator found** | Present but Unreferenced |
| WBP_BannerMessage | UserWidget | — | Unknown | — | Not traced to pickups | Present; consumer Unknown |
| WBP_PlayerStats / WBP_GameStats* | UserWidget | — | Unknown | — | Not traced this pass | Present; reachability Unknown |
| Pause menu | — | — | — | — | Project search empty | Missing |
---
## 8. Character-selection matrix
| Entry point | Available classes | Selection storage | Server authority | Spawn/possession consumer | Persistence | Status |
|-------------|-------------------|-------------------|------------------|---------------------------|-------------|--------|
| `WBP_CharacterSelect` buttons | `Player_Paladin`, `Player_Wizard`, `Player_Cleric`, `Player_Amazonian` | Widget var `SelectedCharacterClass` (soft class) | Start → `PlayerSelectScreenChoice``ServerSpawnCharacter` → GM | `PC_Character.PlayerFirstSpawn` SpawnActor+Possess | **Session/travel only** (widget local; not GI) | Partial |
| Gunslinger | — | — | — | — | Not in UI | Missing from select UI |
| GI storage | — | `GI_Dungeoneer` empty / unwired | — | — | None | Missing |
---
## 9. Startup and frontend flow (summary)
1. Packaged/game default map: **MainMenu** (`GameDefaultMap`)
2. Editor default: **Test01** (`EditorStartupMap`) — skips menu when editing
3. MainMenu: `GM_MainMenu` + `PC_MainMenu` creates `WBP_MainMenu`
4. Branches: NewGame→Test01; Multiplayer Host→CreateAdvancedSession→Dev_Island `?listen`; Find/Join→session nodes
5. Gameplay maps: `GM_Dungeoneer` + `PC_Character` → character select (server) → spawn selected class
6. `GI_Dungeoneer` does **not** participate in observed flow
---
## 10. Confirmed classifications (Pass 4 / Pass 10 UI)
| System | Classification |
|--------|----------------|
| ASC Overlay Health/Mana bars | Active but Unverified |
| Stamina UI | Present but Unconnected (no widget) |
| Legacy UpdatePlayerHUD | Present but Unconnected (unimplemented on PC) |
| AdvancedSessions menu create/find/join graphs | Partial / Active but Unverified |
| OnlineSubsystem project INI | Missing |
| ExampleAdvancedSessionsFunctionsChar | Example Only |
| GI_Dungeoneer | Present but Unconnected |
| Pause menu | Missing |
| Session destroy/cleanup | Missing |