# 12 — Pickups and Effects **Status: Draft** - **Scope:** Pass 10 pickup / consumable / EffectActor / currency archaeology (Batch 4D). Complements Pass 7 GE inventory in doc 06. - **Inspection method:** BlueprintTools EventGraph DSL; ObjectTools CDO; `search_subclasses` on `RIREffectActor`; AssetTools referencers; SceneTools `find_actors` on already-loaded Test01 (read-only). - **Last updated:** 2026-07-16 - **Current phase:** Phase 1 — Static Architecture - **Last completed pass:** Pass 10 (Batch 4D) - **Next pass expected to contribute:** Pass 11 when authorized; PIE for authority / overlap validation ## Draft tracking ### Completed sections - All four `ARIREffectActor` children overlap → Apply → Destroy - Legacy `BP_BasePickUp` / gold path - GE application matrix + enemy GetASC incompatibility - Currency / collectible matrix + negative stamina-potion inventory - Pickup issue matrix ### Pending sections - Sphere collision profile / `GenerateOverlapEvents` exact values (tool limit) - Runtime multiplayer authority behavior for non-replicating EffectActors - Whether full-health HealthPickUp leaves actor undestroyed (DSL branch shape) ### Evidence still required - PIE: player overlap applies GE and updates Overlay bars - PIE: enemy overlap early-out - PIE: gold AddGold no-op (unimplemented BPI) - Respawn / lifespan (none found statically) ### Tool or visibility limitations - CDO `get_properties("sphere")` → None (component templates) - Redirector paths reject `read_graph_dsl` (use canonical Potion/Food/Treasure paths) - Native `ApplyEffectToTarget` body in C++ (already documented Pass 7) --- ## Native mechanism (Observed Implementation) `ARIREffectActor::ApplyEffectToTarget`: 1. `UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(TargetActor)` 2. Early-out if null 3. `MakeOutgoingSpec(GEClass, 1.f)` + `ApplyGameplayEffectSpecToSelf` **Enemy compatibility:** Library/interface GetASC uses `ARIRBaseCharacter::GetAbilitySystemComponent` → PlayerState. Enemies return **nullptr** → early-out. **Enemy-Incompatible Due to ASC Accessor** (static). Separate from chase/attack Implementation Missing (doc 09). --- ## 1. Pickup inventory | Pickup | Parent | Collision/overlap | Authority | Effect or mutation | Presentation | Destroy/respawn | Status | |--------|--------|-------------------|-----------|--------------------|--------------|-----------------|--------| | `/Game/_Main/Blueprints/Items/Potion/BP_HealthPotion` | `RIREffectActor` | `OnComponentBeginOverlap(Sphere)` | **None** (`SwitchHasAuthority` absent); `bReplicates=false` | Instant `GE_PotionHeal` via `ApplyEffecttoTarget` | None in graph | Immediate `DestroyActor`; **no respawn/lifespan** | Active but Unverified / Authority Risk | | `/Game/_Main/Blueprints/Items/Potion/BP_ManaPotion` | `RIREffectActor` | Sphere overlap | Same | Instant `GE_PotionMana` | None | Destroy; no respawn | Active but Unverified / Authority Risk | | `/Game/_Main/Blueprints/Items/Potion/BP_ManaCrystal` | `RIREffectActor` | Sphere overlap | Same | Duration `GE_MoT_Small` | None | Destroy; no respawn | Active but Unverified / Authority Risk | | `/Game/_Main/Blueprints/Items/Food/BP_OrangeSlice` | `RIREffectActor` | Sphere overlap | Same | Duration `GE_HoT_Small` | None | Destroy; no respawn | Active but Unverified / Authority Risk | | `/Game/_Main/Blueprints/Items/Treasure/BP_SmallGoldPickUp` | `BP_BasePickUp` → `Actor` | Parent `PickUpRadius` overlap | **Yes** Authority + tag `Player` | `AddGold(PickUpAmount=25)` | `CoinsPickUp_Cue` | Destroy; no respawn | Partial (AddGold unimplemented) | | `/Game/_Main/Blueprints/Items/BP_BasePickUp` | `Actor` | `PickUpRadius` | Authority + `Player` tag | Switch `E_PickUpType`: Gold / Health / Mana | SFX on paths | Destroy on success paths | Partial / Technical Debt | **Redirectors (not separate logic):** `Items/BP_HealthPotion`, `Items/BP_ManaPotion`, `Items/BP_OrangeSlice`, `Items/BP_SmallGoldPickUp` → canonical paths above. **`search_subclasses(RIREffectActor)`:** only the four GE pickups (+ native base). Gold is **not** an EffectActor child. **Stamina pickup:** project search for stamina potion/widget assets → **none**. Explicit negative inventory. **Test01 placement (Observed Implementation):** 1× each GE pickup; 3× `BP_SmallGoldPickUp`. --- ## 2. Gameplay Effect application matrix | Pickup | Target filter | ASC lookup | GE | Apply call | Null behavior | Player compatibility | Enemy compatibility | |--------|---------------|------------|----|------------|---------------|----------------------|---------------------| | BP_HealthPotion | None in BP (any OtherActor) | Native ApplyEffectToTarget → GetASC | `GE_PotionHeal` Instant +25 Health | `ApplyEffecttoTarget(OtherActor, InstantGameplayEffectClass)` | Early-out; **DestroyActor still runs after call** | Compatible if player ASC via PlayerState | **Enemy-Incompatible Due to ASC Accessor** (null ASC) | | BP_ManaPotion | None | Same | `GE_PotionMana` Instant +30 Mana | Instant class | Same (destroy always) | Compatible (static) | Enemy-Incompatible | | BP_ManaCrystal | None | Same | `GE_MoT_Small` Duration | `DurationGameplayEffectClass` | Same | Compatible (static) | Enemy-Incompatible | | BP_OrangeSlice | None | Same | `GE_HoT_Small` Duration | Duration class | Same | Compatible (static) | Enemy-Incompatible | **Connected path (all four GE pickups):** `OnComponentBeginOverlap(Sphere)` → `ApplyEffecttoTarget` → `DestroyActor` No actor-class filter, no Player tag, no authority switch, no UI notification, no Niagara in graph. **Classification reminder:** GE property assignment + overlap apply call = Connected static path. Runtime success = **Requires Runtime Inspection**. --- ## 3. Currency / collectible matrix | Asset/system | Entry point | Stored value | Authority | Replication | UI | Persistence | Status | |--------------|-------------|--------------|-----------|-------------|----|-------------|--------| | `BP_SmallGoldPickUp` / `GoldPickUp` | Authority overlap + tag Player | Calls `BPI_PlayerController.AddGold(PickUpAmount)`; CDO Amount=25 | Authority gated on pickup | Pickup `bReplicates=true` | No gold UI widget found | **No GI / save store found** | Partial | | `AddGold` on `PC_Character` | Called from `GoldPickUp` | Interface method | — | — | — | — | **Present but Unconnected** (`bIsImplemented=false`; not in `RIRPlayerController` C++) | | Legacy Health/Mana via `BP_BasePickUp` | Enum Health/Mana | `DEPRECATED_RecoverPlayerHealth/Mana` | Authority | — | None | Character DEPRECATED floats | Technical Debt / dual with GAS potions | | Inventory / Coin / Currency / Score systems | Searched | — | — | — | — | — | **Explicit negative inventory** (no connected non-gold currency beyond above) | | Stamina collectible | Searched | — | — | — | — | — | **Missing** | **Gold consequence:** Overlap can destroy the gold actor and play SFX while `AddGold` does nothing statically — **Incomplete Refactor**. --- ## 4. Pickup issue matrix | Asset | Missing or defective link | Static consequence | Runtime question | Classification | |-------|---------------------------|--------------------|------------------|----------------| | All four EffectActor pickups | No `SwitchHasAuthority`; `bReplicates=false` | Overlap may fire on clients; destroy may desync | Who applies GE / who destroys? | Authority Risk | | All four EffectActor pickups | No target filter | Non-player actors may trigger destroy | Does debris/AI destroy potions? | Requires Runtime Inspection | | All four EffectActor pickups | Destroy after Apply even if ASC null | Enemy (or null ASC) still destroys pickup | Wasted loot on enemy touch? | Enemy-Incompatible Due to ASC Accessor + destroy side effect | | All four EffectActor pickups | No respawn / lifespan | One-shot only | Intentional? | Partially Implemented | | All four EffectActor pickups | No UI notify | Overlay may update via ASC only | Bars animate on pickup? | Active but Unverified | | `BP_BasePickUp` Health/Mana | Uses DEPRECATED recover, not GEs | Dual heal/mana systems vs potions | Which values HUD shows? | Technical Debt / Incomplete Refactor | | `BP_SmallGoldPickUp` | `AddGold` unimplemented on PC | Gold mutation missing | Does gold vanish with no score? | Present but Unconnected (receiver) | | Stamina | No pickup / no Overlay widget | Stamina attribute UI unused | — | Missing | | Sphere collision props | Unreadable via MCP CDO | Cannot classify Collision Configuration Conflict from profile alone | GenerateOverlapEvents true? | Unknown — Tool Limitation | --- ## Legacy BP_BasePickUp detail (Observed Implementation) ``` OnComponentBeginOverlap(PickUpRadius) → SwitchHasAuthority → Authority → ActorHasTag(OtherActor, "Player") → Switch E_PickUpType: Gold → GoldPickUp → GetPlayerREF → AddGold(PC, Amount) → Coins SFX → Destroy Health → HealthPickUp → if DEPRECATED health < max → DEPRECATED_RecoverPlayerHealth → potion SFX → Destroy Mana → ManaPickUp → analogous DEPRECATED mana recover ``` **DSL note:** Health/Mana sound+destroy appear in the true branch of the “not full” check (no explicit `else`). If already full, static reading suggests **no destroy** — **Requires Runtime Inspection** / possible Partial behavior. --- ## UI notifications from pickups | Source | Notification | Status | |--------|--------------|--------| | GE pickups | None in graphs | Missing | | Gold | Audio only | Partial | | `WBP_BannerMessage` | Not referenced by pickups this pass | Present; Unconnected to pickups | ASC Overlay health/mana bars may reflect GE changes if InitOverlay path active — that is attribute UI, not pickup-specific notification. --- ## Correlation to prior docs - GE CDO magnitudes / orphan default-attribute GEs: **doc 06** (unchanged inventory; reachability of consumable GEs **confirmed Active static path** again). - Enemy GetASC: **doc 06 / 09** — pickup enemy incompatibility unchanged; no new enemy AI analysis. - HUD dual path: **doc 11** — Overlay may show GE heals; legacy UpdatePlayerHUD unimplemented.