Files
realms-in-ruin-dev/Documentation/Archaeology/06-PartialGASArchitecture.md
T
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

21 KiB
Raw Blame History

06 — Partial GAS Architecture

Status: Draft

  • Scope: Complete static archaeology of partial GAS: ASC ownership, AttributeSet, Gameplay Effects, tags, cues, grant/activation absence, EffectActor boundary, legacy/GAS resource conflict, enemy ASC accessor defect.
  • Inspection method: Native C++ read of all GAS-related Source/REALMSINRUIN files; AssetTools find/deps/refs; ObjectTools CDO properties / search_subclasses; BlueprintTools EventGraph DSL on consumable BPs; GameplayTagsToolset (read-only); prior Pass 58 ability/anim negative GAS results.
  • Evidence classifications used: Observed Implementation, Documented Intent, Observed Runtime Behavior, Inferred, Unknown.
  • Tool or visibility limitations: GameplayEffectComponents array unreadable via ObjectTools (cues/component tags Unknown on GE CDOs); BlueprintGeneratedClass CDO sometimes rejects duration/modifier property names depending on load path — modifiers recovered via successful GE CDO queries on Default__ / generated class where available; no PIE.
  • Last updated: 2026-07-16
  • Current phase: Phase 1 — Static Architecture
  • Last completed pass: Pass 10 (Batch 4D) — Overlay bindings + EffectActor authority static pass
  • Next pass expected to contribute: Pass 11 when authorized

Draft tracking

Completed sections

  • ASC ownership + replication + InitAbilityActorInfo
  • AttributeSet inventory, replication, constructor defaults, absence of PostGameplayEffectExecute
  • Full project GE inventory (8 assets) with modifiers / duration / referencers
  • Default-attribute GE matrix + orphan status
  • Tag inventory from DefaultGameplayTags.ini + referencer status
  • Gameplay Ability / grant / activation negative searches
  • Gameplay Cue negative inventory
  • EffectActor + consumable BP wiring
  • Dual HUD path + stamina delegate type debt
  • Pass 10: WBP_Overlay Health/Mana bindings only; no stamina widget; EffectActor no authority; UpdatePlayerHUD unimplemented on PC

Pending sections

  • PIE: Overlay bars update on potion overlap; dual-resource display

Evidence still required

  • PIE: EffectActor vs enemy GetASC null early-out impact
  • Sphere collision GenerateOverlapEvents exact (tool limit)
  • Dual HUD path + stamina delegate type debt
  • Legacy vs GAS boundary table
  • Enemy ASC compatibility table
  • Subsystem status matrix

Pending sections

  • Runtime ASC attribute values after spawn (PIE)
  • Whether potion ApplyEffect succeeds on listen-server/client authority variants
  • Full WBP_Overlay bar binding node walk (beyond native controller)

Evidence still required

  • PIE: dual HUD coexistence; spawn Health/Mana vs native Init values
  • PIE: EffectActor vs enemy GetASC null early-out impact
  • Manual Editor: GE GameplayEffectComponents / cue slots if any

1. GAS subsystem status matrix

Subsystem Status Exact implementation Active reference path Conflict or gap Evidence
Player ASC ownership Active ARIRPlayerState creates URIRAbilitySystemComponent; Mixed replication Character caches ASC from PlayerState in InitAbilityActorInfo None for players RIRPlayerState.cpp
Enemy ASC ownership Active (component) ARIRBaseEnemyCharacter creates ASC + AttributeSet; Minimal replication; InitAbilityActorInfo(this,this) in BeginPlay Direct component on enemy Conflicts with interface GetASC RIRBaseEnemyCharacter.cpp
Actor-info initialization Active Player: PossessedBy + OnRep_PlayerState; Enemy: BeginPlay Observed Implementation RIRPlayerCharacter.cpp; RIRBaseEnemyCharacter.cpp
AttributeSet replication Active All six attrs DOREPLIFETIME + OnRep Overlay binds change delegates Stamina/MaxStamina not Init'd in ctor RIRAttributeSet.cpp
Default attribute initialization Scaffolding Only / Present but Unreferenced Property DefaultAttributesGameplayEffect on PlayerState; four character GE assets None — BP_PlayerState = None; GE_*_DefaultAttributes referencers [] Spawn uses native InitHealth/Mana only ObjectTools; get_referencers
Runtime attribute modification Partially Integrated Consumable GEs via EffectActor ApplyGameplayEffectSpecToSelf Potion/food overlap → ApplyEffectToTarget Abilities use ApplyDamage / DEPRECATED floats, not GE BP_HealthPotion DSL; Pass 56
Gameplay Ability classes Scaffolding Only URIRGameplayAbility InstancedPerActor only No project subclass beyond engine jump/montage No discrete GA assets (GA_ find = []) search_subclasses; find_assets
Ability granting Missing No GiveAbility / StartupAbilities / AbilitySet None observed Source grep; find_assets; BP find_nodes
Ability activation Missing No TryActivateAbility in native or playable ability graphs Legacy Server_Ability_* instead Pass 56; Pass 7 searches
Ability costs / cooldowns Missing No GA cost/cooldown classes Mana cost is DEPRECATED float + FCanUseMana Pass 6
Gameplay Effects Partially Integrated 8 GE BPs under GAS/GameplayEffects 4 consumable GEs assigned + applied; 4 default GEs orphaned No Max* on default GEs; no Gunslinger GE Pass 7 inventory
Gameplay Tags Present but Unreferenced 12 tags in DefaultGameplayTags.ini Zero native string refs; zero asset referencers observed Tags unused by GEs (legacy containers empty) Config; Source grep; tag tool
Gameplay Cues Missing No project cue notify assets; no GC_ assets; no GameplayCue.* project tags beyond Test orphan None observed SoundCue *_Cue assets are audio, not GAS find_assets; search_subclasses
Attribute-driven UI Active but Unverified InitOverlay → OverlayWidgetController → WBP_Overlay Health/Mana bars bind delegates WBP_Overlay via WBP_PlayerHUD CDO classes assigned Legacy UpdatePlayerHUD unimplemented; stamina broadcasts with no stamina widget RIRHUD; WBP_Overlay DSL; PC list_events
Legacy-resource synchronization Missing No mirror code between ASC attrs and DEPRECATED_* Both UI paths independent Static divergence possible Pass 57
Enemy effect compatibility Partially Integrated / Existing Baseline Defect Enemy owns ASC; EffectActor uses GetAbilitySystemComponent via interface Interface GetASC → PlayerState → nullptr on enemies Pickups/effects may skip enemies RIRBaseCharacter.cpp; RIREffectActor.cpp

2. Gameplay Effect inventory

All under /Game/_Main/Blueprints/Game/GameSystems/GAS/GameplayEffects/. Attribute owner: URIRAttributeSet. Magnitude type: ScalableFloat. StackingType: None / StackLimitCount 0 where read. Cues: Unknown — GameplayEffectComponents unreadable; no GC_ assets exist. Granted INI tags: not observed on readable legacy tag containers (empty).

Effect Duration Modifiers Tags Cues Referencers Application path Status Evidence
GE_PotionHeal Instant Health AddBase 25 Empty (legacy containers) Unknown — Tool Limitation BP_HealthPotion Overlap → ApplyEffectToTarget(Instant) → DestroyActor Active (static path) CDO + DSL
GE_PotionMana Instant Mana AddBase 30 Empty Unknown BP_ManaPotion Same Instant pattern Active (static path) CDO + refs
GE_HoT_Small HasDuration 1s, Period 0.1 Health AddBase 0.5/tick Empty Unknown BP_OrangeSlice Overlap → ApplyEffectToTarget(Duration) → Destroy Active (static path) CDO + refs
GE_MoT_Small HasDuration 1s, Period 0.1 Mana AddBase 0.25/tick Empty Unknown BP_ManaCrystal Same Duration pattern Active (static path) CDO + refs
GE_Paladin_DefaultAttributes Instant Health Override 100; Mana Override 100 Empty Unknown [] None Present but Unreferenced get_referencers
GE_Amazon_DefaultAttributes Instant Health Override 100; Stamina Override 100 Empty Unknown [] None Present but Unreferenced get_referencers
GE_Cleric_DefaultAttributes Instant Health Override 50; Mana Override 200 Empty Unknown [] None Present but Unreferenced get_referencers
GE_Wizard_DefaultAttributes Instant Health Override 100; Mana Override 150 Empty Unknown [] None Present but Unreferenced get_referencers

None observed: GE_Gunslinger_*; SetByCaller; MMC; ExecutionCalculation project subclasses (engine base only); overflow/expiration GE chains (not read / not present in modifiers).

Folder inventory: find_assets recursive on /Game/_Main/Blueprints/Game/GameSystems/GAS returned exactly these 8 assets — Observed Implementation (complete folder set).


3. Default attribute matrix

Character Effect Health MaxHealth Mana MaxMana Stamina MaxStamina Assigned at Applied at Reachability
Paladin .../Paladin/GE_Paladin_DefaultAttributes Override 100 Not modified Override 100 Not modified Not modified Not modified None None Unreachable
Amazonian .../Amazon/GE_Amazon_DefaultAttributes (folder Amazon, not Amazonian) Override 100 Not modified Not modified Not modified Override 100 Not modified None None Unreachable
Cleric .../Cleric/GE_Cleric_DefaultAttributes Override 50 Not modified Override 200 Not modified Not modified Not modified None None Unreachable
Wizard .../Wizard/GE_Wizard_DefaultAttributes Override 100 Not modified Override 150 Not modified Not modified Not modified None None Unreachable
Gunslinger None observed Missing
All (PlayerState) Property only BP_PlayerState.defaultAttributesGameplayEffect = None Native never applies Unreachable

Native spawn fallback (Observed Implementation): URIRAttributeSet ctor InitHealth(75), InitMaxHealth(100), InitMana(25), InitMaxMana(50); Stamina/MaxStamina not Init'd.

Naming inconsistency: Amazon GE folder/asset uses Amazon; playable Blueprint is Player_Amazonian — Documented Intent / Technical Debt.


4. Attribute architecture matrix

Attribute Native default Replication GE modifiers UI binding Blueprint reads/writes Legacy equivalent Synchronization Status
Health Init 75 Replicated + OnRep Potion +25; HoT +0.5/0.1s; default Override orphaned OnHealthChanged Ability graphs: none (use DEPRECATED) DEPRECATED_CurrentHealth None observed Dual sources
MaxHealth Init 100 Replicated + OnRep None on any GE OnMaxHealthChanged None in abilities DEPRECATED_MaxHealth None Partially Integrated
Mana Init 25 Replicated + OnRep Potion +30; MoT +0.25/0.1s; default Override orphaned OnManaChanged Abilities use DEPRECATED mana DEPRECATED_Mana / costs None Dual sources
MaxMana Init 50 Replicated + OnRep None on any GE OnMaxManaChanged None DEPRECATED_MaxMana None Partially Integrated
Stamina Not Init'd Replicated + OnRep Amazon default Override 100 (orphaned) OnStaminaChanged (typed as FOnManaChangedSignature) None None observed None Scaffolding / Technical Debt
MaxStamina Not Init'd Replicated + OnRep None OnMaxStaminaChanged (typed as FOnMaxManaChangedSignature) None None None Scaffolding / Technical Debt

No PostGameplayEffectExecute / PreAttributeChange on URIRAttributeSet — no clamp-to-max or death-from-attribute logic in native AttributeSet — Observed Implementation (absence).


5. Gameplay Tag inventory

Defined in Config/DefaultGameplayTags.ini (ImportTagsFromConfig=True).

Tag Defined at Native references Blueprint references GE/GA references Status Evidence
State.Dead DefaultGameplayTags.ini L12 None observed None observed None observed Present but Unreferenced Source string search; tag referencer search
State.Stunned L13 None None None Present but Unreferenced same
State.Blocking L14 None None None Present but Unreferenced same
State.Casting L15 None None None Present but Unreferenced same
Disable.Movement L17 None None None Present but Unreferenced same
Disable.Input L18 None None None Present but Unreferenced same
Disable.Attack L19 None None None Present but Unreferenced same
Disable.Ability L20 None None None Present but Unreferenced same
Effect.Damage L22 None None None Present but Unreferenced same
Effect.Heal L23 None None None Present but Unreferenced same
Effect.Buff L24 None None None Present but Unreferenced same
Effect.Debuff L25 None None None Present but Unreferenced same

Documented Intent (DevComment strings in INI) describes intended roles; no Observed Implementation of add/query/grant usage.

GameplayCue.Test: reported as lone cue tag orphan by GameplayCueToolset — Present but Unreferenced; no project notify.


6. Gameplay Ability and grant inventory

Ability or grant mechanism Asset/symbol Grant path Activation path Cost/cooldown Reachability Status Evidence
URIRGameplayAbility Source/.../RIRGameplayAbility.* None None None Scaffolding only Scaffolding Only InstancedPerActor ctor only
UGameplayAbility subclasses (project) search_subclasses → only engine Jump/Montage + URIRGameplayAbility None None No project GA BP Missing search_subclasses
GA_* assets find_assets /Game name GA_ [] Missing find_assets
AbilitySet / StartupAbilities find_assets [] Missing find_assets
GiveAbility / TryActivateAbility Source + BP_PlayerCharacterBase None observed Missing grep; find_nodes
DefaultAttributesGameplayEffect apply ARIRPlayerState property Never called in native BP = None Scaffolding Only RIRPlayerState.h; CDO
Legacy Server_Ability_* BP events N/A (not GAS) Enhanced Input DEPRECATED mana Active (legacy) See doc 05 Pass 56

Conclusion (Observed Implementation): No project-defined Gameplay Ability implementation or static grant path was observed within the inspected project scope. This does not prove GAS can never activate at runtime.


7. Gameplay Cue inventory

Cue Type Trigger Referencers Reachability Status Evidence
None observed (project) Missing find_assets GC_/GameplayCue; search_subclasses cue notifies → engine-only
GameplayCue.Test Tag only None None Unreachable Present but Unreferenced GameplayCueToolset
*_Cue SoundCue assets (e.g. MagicSpell_01_Cue) USoundCue audio Multicast_PlaySFX Ability graphs Active as audio, not GAS cue Not GAS Pass 68

8. Legacy / GAS boundary table

System Legacy path GAS path Synchronization Current source of truth Conflict Runtime question
Health combat damage ApplyDamage + DEPRECATED_CurrentHealth (Amazonian AnyDamage) Attribute Health via GE (potions only) None Legacy for combat; GAS for potions Dual health pools possible Does potion heal update combat death?
Mana ability cost DEPRECATED_*ManaCost + FCanUseMana Attribute Mana via GE potions None Legacy for abilities Potion mana may not affect ability costs PIE both meters
HUD bars Server_UpdateHUD → UpdatePlayerHUD (DEPRECATED %) InitOverlay → OverlayWidgetController ASC delegates None Overlay Connected; UpdatePlayerHUD Present but Unconnected Incomplete dual UI Overlay only?
Healing DEPRECATED_RecoverPlayerHealth (Cleric) GE_PotionHeal / HoT None Both Inconsistent heal systems
Death PlayerDeath / IsDead bool State.Dead tag unused; no attr death None Legacy Tag unused
Blocking IsBlocking bool + ABP State.Blocking unused None Legacy Tag unused
Default spawn attrs Native Init* only Orphan default GEs N/A Native Init 75/100/25/50 Orphan character GEs unused Spawn values in PIE

9. Enemy GAS compatibility table

Consumer ASC lookup method Expected owner Static result Null behavior Potential impact Runtime verification
ARIREffectActor::ApplyEffectToTarget Library GetASC → base GetASC → PlayerState Enemy self ASC nullptr Early return Potions/effects skip enemies PIE
Enemy direct ASC member Native TObjectPtr Self Valid if used No combat consumer in enemy BP (Pass 9)
Enemy BP combat / chase N/A No ASC dependency GetASC defect does not cause chase/attack failure
Player ApplyDamage → enemy Engine TakeDamage (not ASC) No enemy ReceiveAnyDamage / health mutation Damage event may fire with no health consumer Combat kill path missing on enemy PIE
Enemy AttributeSet Health Direct Self Exists; Init defaults only Scaffolding for combat PIE

Pass 9 addition: Enemy EventGraphs contain no ASC reads/writes. Chase/attack failure classification is Implementation Missing, independent of the GetASC Incomplete Refactor.


Ownership and init (detail)

Player (Observed Implementation):

  • ASC + AttributeSet on ARIRPlayerState
  • ReplicationMode Mixed; NetUpdateFrequency 100 (Batch 1/2)
  • ARIRPlayerCharacter::InitAbilityActorInfo: Owner=PlayerState, Avatar=Character; PossessedBy + OnRep_PlayerState
  • Then ARIRHUD::InitOverlay when local HUD present

Enemy (Observed Implementation):

  • ASC + AttributeSet on ARIRBaseEnemyCharacter
  • ReplicationMode Minimal
  • BeginPlay: InitAbilityActorInfo(this, this)

EffectActor boundary (Pass 7 + Pass 10)

ARIREffectActor::ApplyEffectToTarget:

  1. UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(TargetActor)
  2. null → return
  3. MakeOutgoingSpec(GEClass, 1.f) + ApplyGameplayEffectSpecToSelf

BlueprintCallable from children. Properties: InstantGameplayEffectClass, DurationGameplayEffectClass.

BP Instant Duration Graph
BP_HealthPotion GE_PotionHeal None Sphere OnComponentBeginOverlap → ApplyEffecttoTarget(Instant) → DestroyActor
BP_ManaPotion GE_PotionMana None Same Instant
BP_ManaCrystal None GE_MoT_Small Sphere → Apply(Duration) → Destroy
BP_OrangeSlice None GE_HoT_Small Sphere → Apply(Duration) → Destroy

Pass 10 static: No SwitchHasAuthority on any of the four; bReplicates=false; no target filter; Destroy always follows Apply call (including null ASC early-out path); no UI notify; no respawn. Authority / client overlap = Authority Risk / Requires Runtime Inspection. Full matrices: 12-Pickups-And-Effects.md.

Overlay (Pass 10): WBP_Overlay forwards controller to Health + Mana progress bars only; no stamina widget. Bars bind OnHealth/ManaChanged → SetProgressBarPercent.


Distinctions (updated)

Layer Status Evidence
GAS infrastructure Present / Active for ASC+attrs+UI binding Native classes
GAS data Partially present 8 GEs; 12 orphan tags; no cues; no GAs
GAS runtime abilities Not observed No grant/activate
GAS runtime effects Partially Integrated Consumables only
Legacy BP abilities Active doc 05 / 10

Negative-search evidence log

Search Scope Result
find_assets name GA_ folder /Game Project content []
find_assets name GC_ / GameplayCue Project content [] / no cue assets
find_assets under GAS folder Complete Exactly 8 GE assets
search_subclasses GameplayAbility Engine+project Engine Jump/Montage + URIRGameplayAbility only
search_subclasses RIRGameplayAbility Project No further subclasses
search_subclasses GameplayCueNotify_* Engine+project Engine unit-test/burst/etc only
search_subclasses GameplayEffectExecutionCalculation / ModMagnitudeCalculation Engine+project Engine base only
Source grep GiveAbility|TryActivateAbility|ApplyGameplayEffect Source/REALMSINRUIN Only EffectActor Apply + DefaultAttributes property
Source grep State.Dead / tag strings Source/REALMSINRUIN No matches (GameplayTags module linked in Build.cs only)
get_referencers each DefaultAttributes GE Asset registry []