# 08 — Character Systems **Status: Draft** - **Scope:** Player character Blueprint hierarchy (Pass 3), shared base architecture (Pass 5), and per-character Ability 001–004 connected-path reconstruction (Pass 6). - **Inspection method:** Read-only AssetTools + BlueprintTools + ObjectTools; connected subgraphs on all five playables + base correlation. - **Last updated:** 2026-07-16 - **Current phase:** Phase 1 — Static Architecture - **Last completed pass:** Pass 7 (Batch 4B) - **Next pass expected to contribute:** Pass 9 / Pass 4 when authorized ## Draft tracking ### Completed sections - Native player chain + ASC ownership (Batch 1) - Blueprint parent chains and structural sheets for five playables + base - Shared input / RPC / death / HUD / multicast architecture - Interface BPI_PlayerCharacter surface - Override matrix (which Server_Ability events children implement) - Pass 6 Ability 001–004 path reconstruction - Pass 8: AnimBP/Montage/AnimNotify callback wiring — see `10-AnimationDependencies.md` - **Pass 7:** Character DefaultAttributes GEs orphaned; no per-character ASC grant; Gunslinger still no GE ### Pending sections - Weapon component deep dive if separate assets exist beyond overlaps - Gunslinger intended design (no static implementation) ### Evidence still required - Notify trigger times (Manual Editor) - Interrupt cleanup if AN_AttackComplete skipped - PIE spawn attribute values vs orphan default GEs --- ## Native player chain `ACharacter` → `ARIRBaseCharacter` → `ARIRPlayerCharacter` → `BP_PlayerCharacterBase` → `Player_*` **Observed Implementation:** ASC on `ARIRPlayerState`; character caches pointers in `InitAbilityActorInfo`. Native also calls `ARIRHUD::InitOverlay` (GAS attribute UI path). --- ## Playable Blueprint paths | Character | Asset path | |-----------|------------| | Base | `/Game/_Main/Blueprints/Characters/PlayerCharacters/BP_PlayerCharacterBase` | | Paladin | `.../PlayerCharacterClasses/Paladin/Player_Paladin` | | Amazonian | `.../Amazonian/Player_Amazonian` | | Cleric | `.../Cleric/Player_Cleric` | | Wizard | `.../Wizard/Player_Wizard` | | Gunslinger | `.../Gunslinger/Player_Gunslinger` | **Observed Runtime Behavior (project brief, not re-tested):** Amazonian melee works; most abilities inactive; Gunslinger incomplete — Existing Baseline Defects. --- ## BP_PlayerCharacterBase — shared architecture Full ability/RPC inventory: [`05-LegacyAbilityArchitecture.md`](05-LegacyAbilityArchitecture.md). ### Components (Observed Implementation) - Camera: TPSpringArm, ThirdPersonCamera, CameraPositionRef - Footsteps: BP_FootstepComponent_Left / Right (EasyFootstepSystem) - Native mesh / capsule / movement / arrow ### Shared vs child-owned behavior | Concern | Shared on base | Child-specific | |---------|----------------|----------------| | Ability input IA_001–004 | Yes — calls Server_Ability_* | Bodies overridden | | Camera zoom/pan | Yes | — | | Multicast montage/SFX/VFX | Yes helpers | Children supply montage assets | | Death / respawn | Yes | — | | HUD via DEPRECATED floats | Yes | — | | Charge / DivineCircle / Whirlwind | — | Paladin / Cleric / Amazonian | | Hit checks | — | PlayerHitCheck on Paladin/Amazonian/Cleric | ### BeginPlay / Possessed (Observed Implementation) - BeginPlay: Set `InitialSpawnLocation` = GetActorLocation only - Possessed: Set `PlayerController` → Delay 0.4 → `Server_UpdateHUD` ### Ability flow (shared) ``` IA_Ability_N Started → Server_Ability_N_Begin IA_Ability_N Completed/Canceled → Server_Ability_N_End ``` Base Begin stubs PrintString `"Override Ability N"`. Base End stubs empty. **Paladin Ability 001 override (Observed Implementation):** Does **not** call parent. Gate `NOT CurrentlyAttacking AND NOT IsDead` → set CurrentlyAttacking → SetPlayerCanMove(true) → Multicast_PlayMontage(random Ability001Montages). **Pass 6:** UseAbility001 Authority BoxOverlap → ApplyDamage(`DEPRECATED_Ability001Damage`). Full tables → `05-LegacyAbilityArchitecture.md`. --- ## Per-character structural sheets ### Paladin | Field | Value | |-------|--------| | Graphs | UCS, EventGraph, GetPlayerPaladinREF, PlayerHitCheck | | Local vars | Ability001Montages, ChargeStartLoc, ChargeFinishLoc, IsCharging, IsBlocking | | AnimBP | ABP_Paladin (`.../Paladin/ABP_Paladin`) — Locomotion: Idle/WalkRun/Charge/Block/Death | | Ability events | Server_001 Begin; 002 Begin+End; 003 Begin; 004 Begin; UseAbility001/004; Charge; Client_Charge | | Parent Call on Ability overrides | **No** | | Pass 6 status | 001 Implemented; 002 Partial (block); 003 Implemented (charge+damage); 004 Implemented (empty particle template) | | Pass 8 | AN_Ability_001/004 + AN_AttackComplete on montages; IsBlocking drives Block state | ### Amazonian | Field | Value | |-------|--------| | Graphs | UCS, EventGraph, GetPlayerAmazonREF, PlayerHitCheck | | Local vars | DynamicMaterials, Ability001Montage, PerformingWhirlwind | | AnimBP (deps) | ABP_Amazon — Locomotion Idle/WalkRun/Death only | | Ability events | Server_001 Begin; UseAbility001; ReceiveAnyDamage | | Pass 6 status | 001 Implemented (= known working melee); 002–004 inherited stubs; PerformingWhirlwind never Set | | Pass 8 | AN_Ability_001 + AN_AttackComplete on all four attack montages; whirlwind not in AnimBP | ### Cleric | Field | Value | |-------|--------| | Graphs | UCS, EventGraph, GetPlayerClericREF, PlayerHitCheck | | Local vars | Ability001Montages, DivineCircleActive, DivineCircleTimerHandle, IsBlocking, EnemyFound, ClosestEnemy | | Ability events | Server_001–004 Begin; Server_003 End; UseAbility002/004; ConcentrateHandle; EndConcentrate | | Parent Call on Ability overrides | **No** | | Pass 6 status | 001 Partial (montage only); 002 Partial heal (empty particle); 003 Implemented DivineCircle; 004 Broken spawn + mana bypass | | Pass 8 | AN_Ability_001/003 dead (UseAbility unimplemented); 002/004 notify-live; ABP Divine Circle state; AN_AttackComplete on all ability montages | ### Wizard | Field | Value | |-------|--------| | Graphs | UCS, EventGraph, GetPlayerWizardREF | | Local vars | EnemyFound, IsBlocking, ClosestEnemy (unused in EventGraph) | | Ability events | **None** implemented (BeginPlay/Tick/Overlap only) | | BeginPlay Parent | **No** (skips base InitialSpawnLocation set) | | Pass 6 status | 001–004 inherited PrintString stubs; NS_Wizard_Ability001 / GE_Wizard_DefaultAttributes / BP_PlayerProjectile unwired | | Pass 8 | ABP_Wizard locomotion+death only; **no** Wizard montages in class folder | ### Gunslinger | Field | Value | |-------|--------| | IsDataOnly | True | | Graphs | UCS, EventGraph | | Local vars | [] | | Dependencies | Only BP_PlayerCharacterBase | | BeginPlay/Tick/Overlap | Call Parent | | Pass 6 status | 001–004 inherited PrintString stubs; no weapon/projectile/AnimBP/GE | | Pass 8 | Confirmed: no AnimBP dependency; no shared attack montage path | --- ## Interfaces `BP_PlayerCharacterBase` implements `BPI_PlayerCharacter`. Class REF getters on base return self-cast nulls for wrong class; children override own REF. `BPI_PlayerController` used heavily for SetPlayerCanMove, UpdatePlayerHUD, PlayerRespawn, AddKill. --- ## GAS interaction findings (character side) | Finding | Classification | |---------|----------------| | No GA grant/activate on base or child ability EventGraphs | Observed Implementation | | Server_UpdateHUD uses DEPRECATED floats, not ASC | Observed Implementation | | Native InitOverlay still runs from C++ possession | Observed Implementation (Batch 1) | | Dual UI attribute paths | Incomplete Refactor | | Character DefaultAttributes GE assets orphaned (0 referencers); BP_PlayerState = None | Present but Unreferenced / Scaffolding Only (Pass 7) | | Amazon GE naming folder `Amazon` vs Blueprint `Amazonian` | Technical Debt (Pass 7) | | No GE_Gunslinger | Missing (Pass 7) | | Consumable GEs modify ASC Health/Mana independently of ability DEPRECATED state | Partially Integrated (Pass 7) | --- ## Networking summary See `05` RPC inventory. Replicated: IsDead, CurrentlyAttacking, DEPRECATED resource floats. Ability activation: client Enhanced Input → Server custom events → optional Multicast FX. Reliability: Unknown — MCP property visibility limitation.