Files
tedwardsandCursor 53315574a4 Document Batch 4C Pass 9 enemy AI archaeology: missing chase and attack implementation.
Records empty enemy EventGraphs, stock AIController possession, orphan attack montage, and separates GetASC defect from chase/attack failure.

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

268 lines
19 KiB
Markdown
Raw Permalink 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.
# 05 — Legacy Ability Architecture
**Status: Draft**
- **Scope:** Shared `BP_PlayerCharacterBase` ability architecture (Batch 2) plus per-character Ability 001004 connected-path reconstruction (Batch 3 Pass 6), qualified by animation-notify wiring (Batch 4A Pass 8) and Pass 7 legacy/GAS boundary clarification.
- **Inspection method:** BlueprintTools connected subgraphs (Pass 6); AnimNotify `Received_Notify` DSL + montage dependency/referencer graphs (Pass 8); Pass 7 GAS GE/ASC inventory correlation.
- **Evidence classifications used:** Observed Implementation, Documented Intent, Observed Runtime Behavior, Inferred, Unknown.
- **Tool or visibility limitations:** CustomEvent Reliable flags not exposed; Montage Notifies array / trigger times unreadable via ObjectTools; AnimGraph DSL empty.
- **Last updated:** 2026-07-16
- **Current phase:** Phase 1 — Static Architecture
- **Last completed pass:** Pass 7 (Batch 4B) — boundary clarification only; ability tables unchanged
- **Next pass expected to contribute:** Pass 11 migration matrix / other Batch 4 passes when authorized
## Draft tracking
### Completed sections
- Shared input → Server RPC routing on base
- Base Server_Ability_* stubs
- Multicast FX helpers
- Death / respawn / HUD (DEPRECATED floats)
- Per-character Ability 001004 connected paths for all five playables
- Parent-call inventory
- Resource / damage / projectile inventories
- Montage dependency seeds
- **Pass 8:** UseAbility* callers resolved (`AN_Ability_001004`); `AN_AttackComplete` cleanup; Pass 6 reclassification table in `10`
- **Pass 7:** Legacy vs GAS dual-resource boundary clarified (no ability-graph GE/ASC usage)
### Pending sections
- Cross-character migration matrix (Pass 11 → doc 07)
- Runtime verification of CDO damage/mana values (PIE)
- Interrupt cleanup if `AN_AttackComplete` skipped
### Evidence still required
- Notify trigger times (Manual Editor Inspection)
- FCanUseMana implementation body (call sites only)
- Client_Charge timeline numeric details
- PIE: potion ASC Health vs DEPRECATED_CurrentHealth divergence
---
## Shared architecture (Batch 2 baseline — verified)
```mermaid
flowchart TD
IA[IA_Ability_001to004] -->|Started| SBegin[Server_Ability_N_Begin]
IA -->|Completed_or_Canceled| SEnd[Server_Ability_N_End]
SBegin -->|base| Print[PrintString Override]
SBegin -->|child override| Child[Character body]
Child --> MC[Multicast_PlayMontage]
MC --> AN[AN_Ability_00N notify]
AN --> Use[UseAbilityN Authority]
Use --> Dmg[ApplyDamage or RecoverHealth]
MC --> ANC[AN_AttackComplete]
ANC --> Clear[SetIsAttacking clears CurrentlyAttacking]
```
**Observed Implementation:** No `UGameplayAbility` activation. Reliability: **Unknown — MCP property visibility limitation**.
**Pass 8:** `UseAbility*` is invoked from AnimNotify Blueprints (`AN_Ability_001004`), not from AnimBP EventGraphs. `Multicast_PlayMontage` completion pins are unwired — cleanup for notify-driven attacks uses `AN_AttackComplete``SetIsAttacking`. Full animation tables: `10-AnimationDependencies.md`.
| Base event | Body |
|---|---|
| Server_Ability_*_Begin | PrintString `"Override Ability N"` |
| Server_Ability_*_End | then unconnected |
| Multicast_PlayMontage / PlaySFX / Multi_SpawnParticle | Active helpers |
---
## Parent-call inventory (Pass 6)
| Character | Ability overrides call Parent? | Other Parent calls |
|---|---|---|
| Paladin | **No** on Ability Begin/UseAbility | Tick/Overlap call Parent; BeginPlay does **not** (leader-pose style local) |
| Amazonian | **No** | — |
| Cleric | **No** on any ability override | BeginPlay no Parent (leader pose) |
| Wizard | N/A (no ability overrides) | BeginPlay **no Parent**; Tick/Overlap **call Parent** |
| Gunslinger | N/A | BeginPlay/Tick/Overlap **call Parent** |
---
## Player_Paladin
**Path:** `/Game/_Main/Blueprints/Characters/PlayerCharacters/PlayerCharacterClasses/Paladin/Player_Paladin`
| Slot/System | Entry point | Parent called | Server path | Multicast/client path | Validation | Resource | Damage/effect | Animation | End/cleanup | Status | Evidence |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Ability 001 | Server_Ability_001_Begin; UseAbility001 | No | Gate !attacking && !dead → CurrentlyAttacking → SetPlayerCanMove(true) → Multicast_PlayMontage(random Ability001Montages) | Multicast_PlayMontage | Gate only | None | UseAbility001 Authority BoxOverlap ApplyDamage — **caller: AN_Ability_001** | Attack_A/B/C/D_Fast_Montage | **AN_AttackComplete** → SetIsAttacking (no local End) | **Implemented** (Pass 8 qualified) | Pass 6 + Pass 8 |
| Ability 002 | Server_Ability_002_Begin; Server_Ability_002_End | No | Begin: gate → CurrentlyAttacking → CanMove false → IsBlocking true | ABP Block (no Montage) | Gate | None | Block state only | ABP_Paladin Block via IsBlocking | End clears attacking/CanMove/IsBlocking | **Partial** | Pass 6 + Pass 8 |
| Ability 003 | Server_Ability_003_Begin; Charge; Client_Charge; ChargeBox overlap | No | Gate → FCanUseMana → Charge + Client_Charge | Client_Charge | Gate + mana | DEPRECATED_Ability003ManaCost | ChargeBox Authority ApplyDamage | ChargeTimeline (not Montage) | Not notify-driven | **Implemented** | Pass 6 |
| Ability 004 | Server_Ability_004_Begin; UseAbility004 | No | Gate → FCanUseMana → Multicast_PlayMontage(Paladin_Ability004_Montage) | Multicast_PlayMontage | Gate + mana | DEPRECATED_Ability004ManaCost | UseAbility004 Authority AoE — **caller: AN_Ability_004**; empty particle | Paladin_Ability004_Montage | **AN_AttackComplete** cleanup | **Implemented** (Pass 8 qualified; FX hole) | Pass 6 + Pass 8 |
| Basic attack | Same as Ability 001 | No | Same | Same | Same | Same | Same | Attack_* montages | Same | **Implemented** (=001) | — |
| Passive | — | — | — | — | — | — | — | — | — | **Missing** | — |
| Death | Inherited PlayerDeath | — | Base | Base | — | DEPRECATED health (if damaged via AnyDamage — Paladin has no local AnyDamage) | Base | Base | Base | **Inherited** | list_events |
| Legacy HUD | Inherited Server_UpdateHUD | — | Base DEPRECATED floats | — | — | Reads DEPRECATED health/mana | — | — | — | **Inherited** | Batch 2 |
**Paladin montages:**
`/Game/_Main/Animations/PlayerCharacters/Human/CharacterClasses/Paladin/AnimMontages/Attack_{A,B,C,D}_Fast_Montage`
`/Game/_Main/Animations/PlayerCharacters/Human/CharacterClasses/Paladin/AnimMontages/Abilities/Paladin_Ability004_Montage`
---
## Player_Amazonian
**Path:** `/Game/_Main/Blueprints/Characters/PlayerCharacters/PlayerCharacterClasses/Amazonian/Player_Amazonian`
| Slot/System | Entry point | Parent called | Server path | Multicast/client path | Validation | Resource | Damage/effect | Animation | End/cleanup | Status | Evidence |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Ability 001 | Server_Ability_001_Begin; UseAbility001 | No | Gate → CurrentlyAttacking → CanMove true → Multicast_PlayMontage(random Ability001Montage) | Multicast_PlayMontage | Gate | None | UseAbility001 Authority BoxOverlap ApplyDamage — **caller: AN_Ability_001** | A_Hu_F_Combat_2H_Attack* montages | **AN_AttackComplete** → SetIsAttacking | **Implemented** (Pass 8 confirmed) | Pass 6 + Pass 8 |
| Ability 002004 | Inherited only | N/A | Base PrintString | — | — | — | — | — | Base empty End | **Stub** (inherited) | list_events |
| Basic attack | Ability 001 | No | Same | Same | Same | Same | Same | Attack montages | Same | **Implemented** (=001); **Observed Runtime Behavior:** known working melee | parity brief + subgraph |
| Passive | — | — | — | — | — | — | — | — | — | **Missing** | — |
| Whirlwind | PerformingWhirlwind Get only | — | — | — | Gates AnyDamage | — | — | — | Never Set | **Partial / Present but Unconnected setter** | find_nodes |
| Death | ReceiveAnyDamage → PlayerDeath | — | Local health subtract DEPRECATED_CurrentHealth → Server_UpdateHUD → PlayerDeath if ≤0 | Base death | PlayerHitCheck when whirlwind | Writes DEPRECATED_CurrentHealth | ApplyDamage inbound | — | Base | **Partial** (legacy health) | subgraph |
| Legacy HUD | Server_UpdateHUD after damage | — | Base | — | — | DEPRECATED health | — | — | — | **Active** | subgraph |
**Amazonian montages:**
`/Game/_Main/Animations/PlayerCharacters/Human/CharacterClasses/Amazon/AnimMontages/A_Hu_F_Combat_2H_Attack01_Montage` (+ Attack02, Attack_Base, Attack)
---
## Player_Cleric
**Path:** `/Game/_Main/Blueprints/Characters/PlayerCharacters/PlayerCharacterClasses/Cleric/Player_Cleric`
| Slot/System | Entry point | Parent called | Server path | Multicast/client path | Validation | Resource | Damage/effect | Animation | End/cleanup | Status | Evidence |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Ability 001 | Server_Ability_001_Begin | No | Gate → CurrentlyAttacking → CanMove false → Multicast_PlayMontage(random Ability001Montages) | Multicast_PlayMontage | Gate | None | **AN_Ability_001 present but UseAbility001 unimplemented** — no hit | Cleric_PrimaryAttack_* | AN_AttackComplete still clears attacking | **Partial** (montage + dead notify) | Pass 6 + Pass 8 |
| Ability 002 | Server_Ability_002_Begin; UseAbility002 | No | Gate → FCanUseMana → Multicast_PlayMontage(Cleric_Ability002_Montage) | Multicast_PlayMontage | Gate + mana | DEPRECATED_Ability002ManaCost | UseAbility002 Authority heal — **caller: AN_Ability_002**; empty particle | Cleric_Ability002_Montage | AN_AttackComplete | **Partial** (notify-driven heal; FX hole) | Pass 6 + Pass 8 |
| Ability 003 | Server_Ability_003_Begin; Server_Ability_003_End; ConcentrateHandle; EndConcentrate | No | Mana≥cost → DivineCircleActive + SetTimer 0.25 ConcentrateHandle | ConcentrateHandle plays montage + ApplyDamage; ABP Divine Circle state | Gate + mana | DEPRECATED_Ability003ManaCost | ApplyDamage in timer; **AN_Ability_003 → UseAbility003 dead/vestigial** | Cleric_Ability003_Montage (timer byproduct) | EndConcentrate | **Implemented** (timer-driven; vestigial notify) | Pass 6 + Pass 8 |
| Ability 004 | Server_Ability_004_Begin; UseAbility004 | No | Gate → FCanUseMana called but Branch Condition=**literal true** → montage | Multicast_PlayMontage | Gate; mana bypassed | DEPRECATED_Ability004ManaCost unused | UseAbility004 — **caller: AN_Ability_004**; SpawnActor Class empty | Cleric_Ability004_Montage | AN_AttackComplete | **Partial / Existing Baseline Defect** | Pass 6 + Pass 8 |
| Basic attack | Ability 001 montage | No | Same | Same | Same | — | Missing hit | PrimaryAttack montages | — | **Partial** | — |
| Passive | — | — | — | — | — | — | — | — | — | **Missing** | — |
| Death / HUD | Inherited | — | Base | Base | — | — | — | — | — | **Inherited** | — |
**Cleric GE** `GE_Cleric_DefaultAttributes` exists but **0 referencers**; not in ability graphs.
---
## Player_Wizard
**Path:** `/Game/_Main/Blueprints/Characters/PlayerCharacters/PlayerCharacterClasses/Wizard/Player_Wizard`
| Slot/System | Entry point | Parent called | Server path | Multicast/client path | Validation | Resource | Damage/effect | Animation | End/cleanup | Status | Evidence |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Ability 001004 | Inherited Server_Ability_* only | N/A | Base PrintString | — | — | — | — | — | Base empty End | **Stub** (inherited PrintString) | list_events + EventGraph walk |
| Basic attack | Same | N/A | Stub | — | — | — | — | — | — | **Stub** | — |
| Passive | — | — | — | — | — | — | — | — | — | **Missing** | — |
| Death / HUD | Inherited | Tick/Overlap Parent yes; BeginPlay **no Parent** | Base | Base | — | — | — | — | — | **Inherited** | subgraph |
| Alternate paths | UseAbility* false; no Input/Montage/spell nodes | — | — | — | — | — | — | — | — | **Missing** | find_nodes |
| Unwired assets | NS_Wizard_Ability001; GE_Wizard_DefaultAttributes; BP_PlayerProjectile | — | — | — | — | — | — | — | — | **Present but Unconnected** | deps/referencers |
Local vars `EnemyFound`, `IsBlocking`, `ClosestEnemy`: **declared, zero EventGraph uses**.
---
## Player_Gunslinger
**Path:** `/Game/_Main/Blueprints/Characters/PlayerCharacters/PlayerCharacterClasses/Gunslinger/Player_Gunslinger`
| Slot/System | Entry point | Parent called | Server path | Multicast/client path | Validation | Resource | Damage/effect | Animation | End/cleanup | Status | Evidence |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Ability 001004 | Inherited only | N/A | Base PrintString | — | — | — | — | — | Base empty End | **Stub** (inherited) | IsDataOnly + deps |
| Basic attack | Inherited stub | N/A | Stub | — | — | — | — | — | — | **Stub** | — |
| Passive | — | — | — | — | — | — | — | — | — | **Missing** | — |
| Death / HUD | Inherited; BeginPlay Parent | Yes | Base | Base | — | — | — | — | — | **Inherited** | subgraph |
| Weapon/projectile | None | — | — | — | — | — | — | — | — | **Missing** | deps only base |
**IsDataOnly=True.** No GE_Gunslinger. Referencers registry [].
---
## Cross-character RPC inventory (ability-related)
| Event | Paladin | Amazonian | Cleric | Wizard | Gunslinger |
|---|---|---|---|---|---|
| Server_Ability_001_Begin | Local override | Local | Local | Inherit stub | Inherit stub |
| Server_Ability_001_End | Inherit empty | Inherit empty | Inherit empty | Inherit | Inherit |
| Server_Ability_002_Begin | Local (block) | Inherit stub | Local | Inherit | Inherit |
| Server_Ability_002_End | Local | Inherit | Inherit empty | Inherit | Inherit |
| Server_Ability_003_Begin | Local (charge) | Inherit | Local (DivineCircle) | Inherit | Inherit |
| Server_Ability_003_End | Inherit | Inherit | Local → EndConcentrate | Inherit | Inherit |
| Server_Ability_004_Begin | Local | Inherit | Local (mana bypass) | Inherit | Inherit |
| Server_Ability_004_End | Inherit | Inherit | Inherit | Inherit | Inherit |
| UseAbility001 | Local Authority damage | Local Authority damage | Missing | Missing | Missing |
| UseAbility002 | Missing | Missing | Local Authority heal | Missing | Missing |
| UseAbility004 | Local Authority AoE | Missing | Local Authority spawn broken | Missing | Missing |
| Charge / Client_Charge | Local | — | — | — | — |
| ConcentrateHandle / EndConcentrate | — | — | Local | — | — |
Reliability: **Unknown — MCP property visibility limitation** for all CustomEvents.
---
## Resource and legacy-state inventory
| Symbol | Readers/Writers | Notes |
|---|---|---|
| DEPRECATED_Ability001Damage | Paladin UseAbility001; Amazonian UseAbility001 | ApplyDamage BaseDamage |
| DEPRECATED_Ability003Damage | Paladin ChargeBox | ApplyDamage |
| DEPRECATED_Ability004Damage | Paladin UseAbility004 | ApplyDamage |
| DEPRECATED_Ability002Damage | Cleric UseAbility002 | Heal amount via RecoverPlayerHealth |
| DEPRECATED_Ability00{2,3,4}ManaCost | Paladin 003/004; Cleric 002/003/004 | FCanUseMana / compare |
| DEPRECATED_CurrentHealth | Amazonian AnyDamage | Subtract + death check |
| DEPRECATED_RecoverPlayerHealth | Cleric UseAbility002 | Interface message |
| CurrentlyAttacking / IsDead | All ability gates | Replicated on base |
| IsBlocking | Paladin 002 Begin/End | Local; **ABP_Paladin Block state** (Pass 8 Observed Implementation) |
| PerformingWhirlwind | Amazonian AnyDamage | Get only — never Set; **not in AnimBP/montages** (Pass 8) |
| DivineCircleActive / TimerHandle | Cleric 003 | Timer loop; **ABP_Cleric Divine Circle state** reads flag (Pass 8) |
**No ASC attribute reads/writes in ability graphs.** No GameplayAbility grant/activate.
### Pass 7 — Legacy vs GAS boundary (clarification)
| Concern | Legacy ability path | GAS path | Sync |
|---|---|---|---|
| Combat damage / heal | ApplyDamage / DEPRECATED_Recover* | Consumable GEs only (potions/food) | **None observed** |
| Mana cost | DEPRECATED floats + FCanUseMana | Attribute Mana modified by potions only | **None observed** |
| Default spawn resources | Not from abilities | Orphan `GE_*_DefaultAttributes`; native AttributeSet Init* used | Defaults unreachable via GE |
| UI | Server_UpdateHUD DEPRECATED % | OverlayWidgetController ASC | Dual, unsynchronized |
### Pass 9 — Player ApplyDamage vs enemy reception
Playable Paladin/Amazonian/Cleric attacks apply `ApplyDamage` (Pass 6). Enemy Blueprints implement **no** `ReceiveAnyDamage` / health mutation / death. Enemy ASC Health is not bridged from ApplyDamage. **Static implication:** player attack damage paths have **no observed enemy health/death consumer** — Existing Baseline Defect on the enemy side; player attack graph status unchanged.
Full matrices: `06-PartialGASArchitecture.md`, `09-EnemyAI-StaticAnalysis.md`. Ability status labels from Pass 6/8 are **unchanged** by Pass 7/9.
---
## Authority / networking findings (flags, no fixes)
- Client IA → Server Begin: Observed Implementation
- Damage on UseAbility* / ChargeBox: Authority SwitchHasAuthority — Observed Implementation
- Multicast used for montage/SFX/particle presentation — Observed Implementation
- **Pass 8:** Multicast montage → AnimNotifies fire on evaluating machines; gameplay still Authority-gated inside UseAbility* / SetIsAttacking
- **Pass 8 static risk:** hit windows depend on server evaluating Multicast montage notifies; interrupt may skip `AN_AttackComplete` (completion pins unwired)
- Cleric Ability 004: mana CanUse **unwired** (literal true) — Existing Baseline Defect
- Cleric Ability 004: SpawnActor Class empty — Existing Baseline Defect
- Multi_SpawnParticle EmitterTemplate empty (Paladin 004, Cleric 002) — Partially Implemented
- End events missing for most slots — Incomplete Refactor (cleanup often via `AN_AttackComplete` instead)
- Amazonian/Paladin Ability 001: no mana cost — Observed Implementation
- Dual HUD still uses DEPRECATED floats on Server_UpdateHUD — Incomplete Refactor (Batch 2)
---
## Status rollup
| Classification | Characters / slots |
|---|---|
| **Implemented** | Paladin 001, 003, 004 (FX hole on 004); Amazonian 001; Cleric 003 (timer; vestigial AN_Ability_003) |
| **Partial** | Paladin 002; Cleric 001 (dead notify), 002 (heal + FX hole), 004 (broken spawn); Amazonian whirlwind |
| **Stub** | Wizard 001004; Gunslinger 001004 (inherited PrintString) |
| **Missing** | Wizard/Gunslinger combat bodies; most Server Ends |
| **Present but Unconnected** | NS_Wizard_Ability001; GE_* orphans; BP_PlayerProjectile; PerformingWhirlwind setter; Cleric_Hu_M_Spell_Staff_Up_Impact_Montage (0 refs) |
| **Deprecated connected** | All DEPRECATED_* damage/mana/health in active paths |
| **Notify Present; Receiver Unimplemented** | Cleric AN_Ability_001 → UseAbility001; Cleric AN_Ability_003 → UseAbility003 |
---
## Pass 8 animation callback note
Full tables and reclassification: `10-AnimationDependencies.md`. Primary status labels unchanged except qualifications above; no silent rewrites.
---
## Migration relevance (inventory only)
Replacement targets: IA→Server custom events; AnimNotify→UseAbility timing; ApplyDamage/RecoverPlayerHealth; FCanUseMana + DEPRECATED costs; Multicast_PlayMontage; Charge timeline; DivineCircle timer; dual HUD floats; `AN_AttackComplete` lockout cleanup.