Files
realms-in-ruin-dev/Documentation/Archaeology/06-PartialGASArchitecture.md
T
tedwardsandCursor e50c8032ef Document Batch 4B Pass 7 partial GAS archaeology: effects, tags, and legacy boundaries.
Inventories Gameplay Effects, orphan default attributes, missing abilities/cues, and consumable EffectActor wiring without modifying Unreal assets.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 21:29:19 -07:00

258 lines
20 KiB
Markdown
Raw 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.
# 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 7 (Batch 4B)
- **Next pass expected to contribute:** Pass 9 (enemy) / Pass 10 (pickup graphs deep) / Pass 4 when authorized — not auto-started
## 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
- 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 broadcasts + binds | WBP_Overlay via WBP_PlayerHUD | Dual path with DEPRECATED HUD; stamina delegates wrong type alias | RIRHUD.cpp; OverlayWidgetController.h |
| 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 | **Both connected** | Dual UI | Which bars visible? |
| 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 | Lookup method | Expected ASC owner | Static result | Potential impact | Runtime verification |
|---|---|---|---|---|---|
| `IAbilitySystemInterface` / `UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent` | `ARIRBaseCharacter::GetAbilitySystemComponent``GetPlayerState<ARIRPlayerState>()` | Enemy self ASC | **nullptr** (no PlayerState ASC) | EffectActor early-out; any BP using library GetASC | Requires Runtime Inspection |
| Enemy native code using `AbilitySystemComponent` member | Direct `TObjectPtr` on enemy | Self | Valid if used | Unknown consumers | Pass 9 |
| Player EffectActor target | Library GetASC on player character | PlayerState ASC | Valid via character GetASC → PS | Potions work on players (static) | PIE authority |
| Blueprint enemy GetASC | Inherited base | — | nullptr | Incomplete Refactor / Existing Baseline Defect | PIE |
---
## 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 deferred)
`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 pattern (agent + refs) |
| `BP_ManaCrystal` | None | GE_MoT_Small | Same Duration pattern |
| `BP_OrangeSlice` | None | GE_HoT_Small | Same Duration pattern |
Authority on overlap application: **Requires Runtime Inspection** (not traced beyond DSL). Full pickup respawn/UI → Pass 10.
---
## 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 | [] |