# 03 — Class Hierarchy **Status: Draft** - **Scope:** Native C++ class hierarchy under `Source/REALMSINRUIN/`, including parents, components, properties, replication, RPCs, GAS hooks, Blueprint extension points, and discovered Blueprint subclass paths (seeds only). - **Inspection method:** Full read of every `.h`/`.cpp` under `Source/REALMSINRUIN/`; MCP `ObjectTools.search_subclasses` for child discovery (paths only — no Blueprint graph inspection). - **Evidence classifications used:** Observed Implementation, Documented Intent, Inferred, Unknown. - **Tool or visibility limitations:** Batch 1 forbids deep Blueprint graph analysis. Inherited Blueprint variables not inspected. No native RPCs found to verify runtime. - **Last updated:** 2026-07-16 - **Current phase:** Phase 1 — Static Architecture - **Last completed pass:** Pass 2 (Batch 1) - **Next pass expected to contribute:** Batch 2 Passes 3 + 5 (Blueprint hierarchy and BP_PlayerCharacterBase) ## Draft tracking ### Completed sections - Full native class inventory for characters, player framework, GAS, UI, interfaces - ASC ownership split (player vs enemy) - AttributeSet replication and constructor defaults - EffectActor GE application path - HUD / OverlayWidgetController attribute delegate wiring - Blueprint subclass path seeds ### Pending sections - Blueprint parent chains, variables, graphs, interfaces on children - GameMode / GameInstance Blueprint internals - Whether DefaultAttributesGameplayEffect is assigned on BP_PlayerState ### Evidence still required - Connected ability/RPC graphs on BP_PlayerCharacterBase and Player_* classes - Whether enemy BP overrides GetAbilitySystemComponent behavior (native override is PlayerState-based) ### Unknowns requiring later verification - Runtime behavior of `IAbilitySystemInterface` on enemies given base `GetAbilitySystemComponent` implementation - Application of `DefaultAttributesGameplayEffect` (declared, never called in native) --- ## Hierarchy overview ```mermaid flowchart TD ACharacter[ACharacter] --> ARIRBaseCharacter IASI[IAbilitySystemInterface] --> ARIRBaseCharacter ARIRBaseCharacter --> ARIRPlayerCharacter ARIRBaseCharacter --> ARIRBaseEnemyCharacter ITarget[ITargetInterface] --> ARIRBaseEnemyCharacter APlayerState --> ARIRPlayerState IASI --> ARIRPlayerState APlayerController --> ARIRPlayerController AHUD --> ARIRHUD UAbilitySystemComponent --> URIRAbilitySystemComponent UAttributeSet --> URIRAttributeSet UGameplayAbility --> URIRGameplayAbility AActor --> ARIREffectActor UUserWidget --> URIRUserWidget UObject --> URIRWidgetController URIRWidgetController --> UOverlayWidgetController ``` **Observed Implementation:** No native `AGameMode`, `UGameInstance`, or `AGameState` subclasses in the module. --- ## 1. Characters ### 1.1 `ARIRBaseCharacter` (ABSTRACT) | | | |--|--| | Header | [`Public/Characters/RIRBaseCharacter.h`](Source/REALMSINRUIN/Public/Characters/RIRBaseCharacter.h) | | Impl | [`Private/Characters/RIRBaseCharacter.cpp`](Source/REALMSINRUIN/Private/Characters/RIRBaseCharacter.cpp) | | Parent | `ACharacter` | | Interfaces | `IAbilitySystemInterface` | **Properties (Observed Implementation):** - `TObjectPtr AbilitySystemComponent` — VisibleAnywhere, BlueprintReadOnly, Category Abilities - `TObjectPtr AttributeSet` — same **Functions:** - `GetAbilitySystemComponent()` override — **returns `GetPlayerState()->GetAbilitySystemComponent()`**, else nullptr. Does **not** return the local `AbilitySystemComponent` member. - `GetAttributeSet()` — returns local `AttributeSet` member - Constructor empty; `BeginPlay` comment: "GAS Initialization moved to PossessedBy / OnRep_PlayerState" **Documented Intent:** Comment on class: "Base Character class using GAS for RIR Project." **Contradiction (Observed Implementation vs Documented Intent):** Header comment claims GAS-based character; `GetAbilitySystemComponent` assumes a player PlayerState. Enemies inherit this override but own ASC on the character — see §1.3 and §Contradictions. **RPCs / replication:** None declared on this class. **Blueprint children (seed):** See §1.2 / calibration — via `ARIRPlayerCharacter` and `ARIRBaseEnemyCharacter` lineages. --- ### 1.2 `ARIRPlayerCharacter` | | | |--|--| | Header | [`Public/Player/RIRPlayerCharacter.h`](Source/REALMSINRUIN/Public/Player/RIRPlayerCharacter.h) | | Impl | [`Private/Player/RIRPlayerCharacter.cpp`](Source/REALMSINRUIN/Private/Player/RIRPlayerCharacter.cpp) | | Parent | `ARIRBaseCharacter` | **Observed Implementation:** - Constructor comment: "Removed GAS component creation — now handled by PlayerState" - `PossessedBy` → `InitAbilityActorInfo()` (server) - `OnRep_PlayerState` → `InitAbilityActorInfo()` (client) - `InitAbilityActorInfo()`: 1. `check(GetPlayerState())` 2. `ASC->InitAbilityActorInfo(PlayerState, this)` — Owner = PlayerState, Avatar = Character 3. Copies ASC and AttributeSet pointers from PlayerState onto character members 4. If controller is `ARIRPlayerController` and HUD is `ARIRHUD`, calls `RIRHUD->InitOverlay(...)` **No RPCs. No ability granting. No DefaultAttributes application.** **Known Blueprint subclasses (seed — Observed Implementation via search_subclasses):** - `/Game/_Main/Blueprints/Characters/PlayerCharacters/BP_PlayerCharacterBase` - `/Game/_Main/Blueprints/Characters/PlayerCharacters/PlayerCharacterClasses/Amazonian/Player_Amazonian` - `.../Cleric/Player_Cleric` - `.../Paladin/Player_Paladin` - `.../Wizard/Player_Wizard` - `.../Gunslinger/Player_Gunslinger` --- ### 1.3 `ARIRBaseEnemyCharacter` | | | |--|--| | Header | [`Public/Characters/RIRBaseEnemyCharacter.h`](Source/REALMSINRUIN/Public/Characters/RIRBaseEnemyCharacter.h) | | Impl | [`Private/Characters/RIRBaseEnemyCharacter.cpp`](Source/REALMSINRUIN/Private/Characters/RIRBaseEnemyCharacter.cpp) | | Parent | `ARIRBaseCharacter` | | Interfaces | `ITargetInterface` | **Observed Implementation — constructor:** - Mesh Visibility channel → Block - Creates `URIRAbilitySystemComponent` on self; `SetIsReplicated(true)`; `SetReplicationMode(Minimal)` - Creates `URIRAttributeSet` on self **BeginPlay:** `AbilitySystemComponent->InitAbilityActorInfo(this, this)` — Owner and Avatar both the enemy. **ITargetInterface:** `HighlightActor` / `UnHighlightActor` toggle custom depth stencil `CUSTOM_DEPTH_RED` (250). **No AI movement, targeting, attack, Behavior Tree, or Perception code in native.** **Known Blueprint subclasses (seed):** - `/Game/_Main/Blueprints/Characters/Enemies/BP_EnemyCharacterBase` - `/Game/_Main/Blueprints/Characters/Enemies/Skeleton/BP_Enemy_Skeleton` **Issue classification:** Incomplete Refactor / Partially Implemented (ASC on enemy vs base GetASC from PlayerState). **Requires Runtime Inspection** for GE application to enemies via `UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent`. --- ## 2. Player framework ### 2.1 `ARIRPlayerState` | | | |--|--| | Header | [`Public/Player/RIRPlayerState.h`](Source/REALMSINRUIN/Public/Player/RIRPlayerState.h) | | Impl | [`Private/Player/RIRPlayerState.cpp`](Source/REALMSINRUIN/Private/Player/RIRPlayerState.cpp) | | Parent | `APlayerState` | | Interfaces | `IAbilitySystemInterface` | **Observed Implementation:** - Owns `URIRAbilitySystemComponent` — replicated, `EGameplayEffectReplicationMode::Mixed` - Owns `URIRAttributeSet` - `NetUpdateFrequency = 100.f` - `TSubclassOf DefaultAttributesGameplayEffect` (EditDefaultsOnly) — **never referenced in .cpp** **Blueprint subclass seed:** `/Game/_Main/Blueprints/Player/BP_PlayerState` **Issue:** Partially Implemented — default attributes GE property without native apply path. --- ### 2.2 `ARIRPlayerController` | | | |--|--| | Header | [`Public/Player/RIRPlayerController.h`](Source/REALMSINRUIN/Public/Player/RIRPlayerController.h) | | Impl | [`Private/Player/RIRPlayerController.cpp`](Source/REALMSINRUIN/Private/Player/RIRPlayerController.cpp) | | Parent | `APlayerController` | **Observed Implementation:** - `bReplicates = true` - Enhanced Input: `PlayerMappingContext`, `MovementInput` (EditAnywhere — must be assigned in editor/BP) - `BeginPlay`: `check(PlayerMappingContext)`; add IMC; show mouse; GameAndUI input mode - `SetupInputComponent`: bind MovementInput → `HandleMovementInput` - `PlayerTick` → `CursorTrace` for `ITargetInterface` highlight - `BindCallbacksToDependencies()` empty stub - TODO comment: controller-compatible cursor / Gauntlet-style targeting **No ability input bindings in native. No RPCs.** **Blueprint subclass seed:** `/Game/_Main/Blueprints/Player/PC_Character` --- ### 2.3 `ARIRHUD` | | | |--|--| | Header | [`Public/UI/HUD/RIRHUD.h`](Source/REALMSINRUIN/Public/UI/HUD/RIRHUD.h) | | Impl | [`Private/UI/HUD/RIRHUD.cpp`](Source/REALMSINRUIN/Private/UI/HUD/RIRHUD.cpp) | | Parent | `AHUD` | **Observed Implementation:** - `OverlayWidgetClass`, `OverlayWidgetControllerClass` (EditAnywhere — editor/BP assigned) - `InitOverlay`: checkf messages reference filling `WBP_PlayerHUD`; creates widget; builds `FWidgetControllerParams`; `BroadcastInitialInitialValues`; `AddToViewport` - `GetOverlayWidgetController`: creates controller, `SetWidgetControllerParams`, `BindCallbacksToDependencies` **Subclass search seed:** returned `/Game/_Main/UI/Widgets/HUD/WBP_PlayerHUD` — **Requires Manual Editor Inspection** to confirm whether this asset is a HUD Blueprint or mis-tagged; name suggests Widget Blueprint. --- ## 3. GAS scaffolding ### 3.1 `URIRAbilitySystemComponent` Thin subclass of `UAbilitySystemComponent`. Empty constructor. No custom granting, input binding, or tag logic. Header: [`Public/Abilities/RIRAbilitySystemComponent.h`](Source/REALMSINRUIN/Public/Abilities/RIRAbilitySystemComponent.h) ### 3.2 `URIRAttributeSet` | Attributes | Replication | |------------|-------------| | Health, MaxHealth, Mana, MaxMana, Stamina, MaxStamina | `DOREPLIFETIME_CONDITION_NOTIFY` + OnRep_* → `GAMEPLAYATTRIBUTE_REPNOTIFY` | Constructor inits: Health=75, MaxHealth=100, Mana=25, MaxMana=50. **Does not call InitStamina / InitMaxStamina** (remain default 0.f unless set by GE). No `PostGameplayEffectExecute` / clamping logic in .cpp. ### 3.3 `URIRGameplayAbility` **Documented Intent:** "Base class for all Gameplay Abilities in RIR Project" **Observed Implementation:** Sets `InstancingPolicy = InstancedPerActor` only. No ActivateAbility, tags, costs, or cooldowns. **search_subclasses:** **only** `/Script/REALMSINRUIN.RIRGameplayAbility` — **no derived project ability classes**. **Classification:** GAS infrastructure only / Partially Implemented. Do **not** conclude abilities migrated to GAS. ### 3.4 `ARIREffectActor` - Root: `USceneComponent` - `ApplyEffectToTarget` (BlueprintCallable): gets ASC via `UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent`; MakeOutgoingSpec level 1; ApplyGameplayEffectSpecToSelf - Properties: `InstantGameplayEffectClass`, `DurationGameplayEffectClass` (not auto-applied in native BeginPlay) **Blueprint subclass seeds:** - `/Game/_Main/Blueprints/Items/Food/BP_OrangeSlice` - `/Game/_Main/Blueprints/Items/Potion/BP_HealthPotion` - `/Game/_Main/Blueprints/Items/Potion/BP_ManaPotion` - `/Game/_Main/Blueprints/Items/Potion/BP_ManaCrystal` --- ## 4. UI ### 4.1 `URIRUserWidget` - `SetWidgetController` BlueprintCallable → fires `WidgetControllerSet` BlueprintImplementableEvent **Subclasses seed:** `WBP_ProgressBarBase`, `WBP_ManaProgressBar`, `WBP_HealthProgressBar`, `WBP_Overlay` ### 4.2 `URIRWidgetController` / `FWidgetControllerParams` Holds PC, PS, ASC, AS. Base `BroadcastInitialInitialValues` / `BindCallbacksToDependencies` empty. ### 4.3 `UOverlayWidgetController` **Observed Implementation:** Broadcasts and binds Health/MaxHealth/Mana/MaxMana/Stamina/MaxStamina via ASC attribute change delegates. **Observed Implementation quirk:** `OnStaminaChanged` typed as `FOnManaChangedSignature`; `OnMaxStaminaChanged` typed as `FOnMaxManaChangedSignature` — likely copy-paste. **Technical Debt** (delegate type names wrong; broadcast still float). **Subclass seed:** `/Game/_Main/UI/Widgets/WidgetController/BP_OverlayWidgetController` --- ## 5. Interfaces ### `ITargetInterface` Pure virtual `HighlightActor` / `UnHighlightActor`. Implemented by `ARIRBaseEnemyCharacter`. Used by `ARIRPlayerController::CursorTrace`. --- ## 6. Framework Blueprints discovered (seeds — no native parents in module) | Class | Path | |-------|------| | GameInstance | `/Game/_Main/Blueprints/Game/GameInstance/GI_Dungeoneer` | | GameMode | `/Game/_Main/Blueprints/Game/GameMode/GM_Dungeoneer` | | GameMode | `/Game/_Main/Blueprints/Game/GameMode/GM_MainMenu` | --- ## 7. Native RPCs **Observed Implementation:** Grep of `Source/REALMSINRUIN` found **no** `Server_`, `Client_`, or `Multicast_` UFUNCTIONs. Ability networking, if present, is Blueprint-only (Batch 2/3). --- ## Contradictions | Topic | Evidence A | Evidence B | Better supported | |-------|------------|------------|------------------| | Enemy ASC access | Enemy creates ASC on self; InitAbilityActorInfo(this,this) | Base `GetAbilitySystemComponent` reads PlayerState only | Both Observed Implementation; interface path likely broken for enemies | | Default attributes | `DefaultAttributesGameplayEffect` on PlayerState; GE assets exist (calibration) | Never applied in native .cpp | Property is scaffolding; apply path Unknown (Blueprint?) | | Gameplay Abilities | `URIRGameplayAbility` + Documented Intent "all abilities" | No subclasses; calibration found no GA assets | Infrastructure only — abilities not GAS-converted | Log also in `15-HandoffStatus.md`.