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

186 lines
15 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.
# 10 — Animation Dependencies
**Status: Draft**
- **Scope:** Animation Blueprints, Montages, AnimNotify Blueprints for playable characters (Pass 8) plus enemy AnimBP/montage findings required by Pass 9 combat archaeology.
- **Last completed pass:** Pass 9 (Batch 4C) — enemy animation seed
- **Next pass expected to contribute:** Pass 4 / Pass 10 when authorized
## Draft tracking
### Completed sections
- Per-character AnimBP architecture table (playables)
- Per-ability Montage + notify tables
- AnimNotify/callback inventory (`AN_Ability_001004`, `AN_AttackComplete`)
- Resolved UseAbility* callers
- Pass 6 reclassification table
- Cleanup via `AN_AttackComplete``SetIsAttacking`
- Networking/authority static notes
- Wizard / Gunslinger animation dependency confirmation
- **Pass 9:** `ABP_Skeleton` locomotion/Death; `Anim_SkeletonAttackMontage` orphan; `SetIsDead(false)` every Update
### Pending sections
- Exact notify trigger times / track indices (Requires Manual Editor Inspection)
- Montage section names / blend / root-motion flags
- ABP_Skeleton Death transition rule pin details
### Evidence still required
- Manual editor confirmation of notify timing windows
- Whether interrupted montages skip `AN_AttackComplete` (static risk only)
- Gunslinger mesh AnimClass assignment on CDO (data-only; deps show no AnimBP)
---
## Shared animation → ability architecture
```mermaid
flowchart TD
Begin[Server_Ability_N_Begin] --> MC[Multicast_PlayMontage]
MC --> Play[PlayMontage Mesh]
Play --> AN1[AN_Ability_00N]
Play --> ANC[AN_AttackComplete]
AN1 --> BPI[BPI UseAbility00N]
BPI --> Auth[SwitchHasAuthority]
Auth --> FX[ApplyDamage / Heal / Spawn]
ANC --> SetAtk[BPI SetIsAttacking]
SetAtk --> Clear[CurrentlyAttacking false]
```
**Observed Implementation:** `Multicast_PlayMontage` on `BP_PlayerCharacterBase` plays the montage with **OnCompleted / OnBlendOut / OnInterrupted unwired**. Attack-window gameplay and `CurrentlyAttacking` cleanup for notify-driven abilities depend on embedded AnimNotify Blueprints, not montage delegates.
**Shared notify Blueprints** (`/Game/_Main/Blueprints/Characters/PlayerCharacters/PlayerCharacterRelated/`):
| Notify BP | Received_Notify body | Classification |
|---|---|---|
| `AN_Ability_001` | `Abilities\|UseAbility001(GetOwner(MeshComp))` | Observed Implementation |
| `AN_Ability_002` | `UseAbility002(GetOwner)` | Observed Implementation (Cleric agent + deps) |
| `AN_Ability_003` | `UseAbility003(GetOwner)` | Observed Implementation (Cleric agent + deps) |
| `AN_Ability_004` | `UseAbility004(GetOwner)` | Observed Implementation (Paladin/Cleric agents + deps) |
| `AN_AttackComplete` | `BPIPlayerCharacter\|SetIsAttacking(GetOwner(MeshComp))` | Observed Implementation (`read_graph_dsl`) |
---
## 1. Per-character animation architecture
| Character | AnimBP | Skeleton | Relevant state machines | Montage slots | Ability callbacks | Death path | Confidence |
|---|---|---|---|---|---|---|---|
| Paladin | `/Game/_Main/Animations/PlayerCharacters/Human/CharacterClasses/Paladin/ABP_Paladin` | `SKEL_Hu_M` | `Locomotion`: Idle, Walk/Run, Charge, Block, Death | UpperBody (montages) | None in ABP — notifies call character BPI | `IsDead` → Death state; DeathIndex random | High |
| Amazonian | `/Game/_Main/Animations/PlayerCharacters/Human/CharacterClasses/Amazon/ABP_Amazon` | `SKEL_Hu_F` | `Locomotion`: Idle, Walk/Run, Death | UpperBody | None in ABP | `IsDead` → Death | High |
| Cleric | `/Game/_Main/Animations/PlayerCharacters/Human/CharacterClasses/Cleric/ABP_Cleric` | Male (`SKEL_Hu_M` family) | `Locomotion`: Idle, Walk/Run, **Divine Circle**, Death | UpperBody | None in ABP; reads `DivineCircleActive?` from Cleric | `IsDead` → Death | High |
| Wizard | `/Game/_Main/Animations/PlayerCharacters/Human/CharacterClasses/Wizard/ABP_Wizard` | `SKEL_Hu_M` | `Locomotion`: Idle, Walk/Run, Death | None used by abilities | None — no ability montages in Wizard folder | Death anims in deps | High |
| Gunslinger | **None** (deps = base only; IsDataOnly) | Unknown / inherited | N/A | N/A | None | Inherited base death only | Medium |
**ABP parent class (all inspected):** stock `Engine.AnimInstance` — Observed Implementation.
**Paladin ABP drivers (EventGraph):** per-frame reads `IsCharging`, `IsBlocking`, `IsDead`, velocity→`IsMoving` from Paladin REF. Block/Charge/Death transitions driven by those booleans — Observed Implementation.
**Cleric ABP drivers:** `DivineCircleActive?``GetDivineCircleActive` on Cleric REF; `IsDead`; speed/moving — Observed Implementation (`read_graph_dsl`).
**Amazonian / Wizard ABP:** locomotion + death only — no Block/Charge/DivineCircle states — Observed Implementation.
---
## 2. Per-ability Montage table
| Character | Slot/system | Caller | Montage | Section | Notifies | Callback target | Gameplay consequence | Cleanup dependency | Evidence status |
|---|---|---|---|---|---|---|---|---|---|
| Paladin | Ability 001 | `Server_Ability_001_Begin` → Multicast | `.../Paladin/AnimMontages/Attack_{A,B,C,D}_Fast_Montage` (random) | Default (single segment); name Unknown | `AN_Ability_001`, `AN_AttackComplete` (+ sound on A) | `UseAbility001`; `SetIsAttacking` | Authority BoxOverlap ApplyDamage | `AN_AttackComplete` → clear CurrentlyAttacking | Observed Implementation |
| Paladin | Ability 002 | Begin/End set `IsBlocking` | **No Montage** | — | — | ABP Block state | Presentation only | End clears IsBlocking | Observed Implementation |
| Paladin | Ability 003 | Charge + Client_Charge | **No Montage** (ChargeTimeline) | — | — | — | ChargeBox ApplyDamage | Timeline/End paths (not notify) | Observed Implementation |
| Paladin | Ability 004 | `Server_Ability_004_Begin` → Multicast | `.../Paladin/AnimMontages/Abilities/Paladin_Ability004_Montage` | Unknown | `AN_Ability_004`, `AN_AttackComplete`, Niagara `NS_Paladin_Ability004` | `UseAbility004`; `SetIsAttacking` | Authority SphereOverlap ApplyDamage + SFX | `AN_AttackComplete` | Observed Implementation |
| Amazonian | Ability 001 / melee | `Server_Ability_001_Begin` → Multicast | `.../Amazon/AnimMontages/A_Hu_F_Combat_2H_Attack{01,02,_Base,_}_Montage` | Unknown | `AN_Ability_001`, `AN_AttackComplete` | `UseAbility001`; `SetIsAttacking` | Authority BoxOverlap ApplyDamage | `AN_AttackComplete` | Observed Implementation + Observed Runtime Behavior |
| Amazonian | 002004 | Inherited stubs | None | — | — | — | PrintString | — | Observed Implementation |
| Cleric | Ability 001 | `Server_Ability_001_Begin` → Multicast | `.../Cleric/AnimMontages/Cleric_PrimaryAttack_*` (4) | Unknown | `AN_Ability_001`, `AN_AttackComplete` | `UseAbility001` (**unimplemented** on Cleric) | **No hit** — dead notify | `AN_AttackComplete` still clears attacking | Observed Implementation |
| Cleric | Ability 002 | Begin → Multicast | `.../Cleric/AnimMontages/Abilities/Cleric_Ability002_Montage` | Unknown | `AN_Ability_002`, `AN_AttackComplete` (+ Niagara/sound deps) | `UseAbility002` (implemented) | Authority heal Players | `AN_AttackComplete` | Observed Implementation |
| Cleric | Ability 003 | `ConcentrateHandle` timer plays montage | `.../Cleric/AnimMontages/Abilities/Cleric_Ability003_Montage` | Unknown | `AN_Ability_003` (**dead**), `AN_AttackComplete` | `UseAbility003` unimplemented; damage in timer | ApplyDamage in ConcentrateHandle | `EndConcentrate` (not notify) | Observed Implementation |
| Cleric | Ability 004 | Begin → Multicast | `.../Cleric/AnimMontages/Abilities/Cleric_Ability004_Montage` | Unknown | `AN_Ability_004`, `AN_AttackComplete` | `UseAbility004` (broken spawn) | SpawnActor empty class | `AN_AttackComplete` | Observed Implementation |
| Wizard | 001004 | Inherited stubs | **No montages** in Wizard anim folder | — | — | — | PrintString | — | Observed Implementation |
| Gunslinger | 001004 | Inherited stubs | None | — | — | — | PrintString | — | Observed Implementation |
**Present but Unconnected montage:** `/Game/_Main/Animations/PlayerCharacters/Human/CharacterClasses/Cleric/AnimMontages/Cleric_Hu_M_Spell_Staff_Up_Impact_Montage` — references `AN_Ability_004` / `AN_AttackComplete`; **0 referencers**.
Play rate: Multicast path uses rate **1** (Pass 6 / Amazonian agent). Start position: Unknown. Root motion: Unknown — Tool Limitation.
---
## 3. AnimNotify / callback table
| Notify or callback | Asset | Character | Ability | Receiver | Downstream path | Authority observation | Connection status |
|---|---|---|---|---|---|---|---|
| AN_Ability_001 | `.../PlayerCharacterRelated/AN_Ability_001` | Paladin, Amazonian | 001 | Character via BPI `UseAbility001` | Authority overlap ApplyDamage | Multicast montage → notify all machines; damage Authority-only | **Connected** |
| AN_Ability_001 | same | Cleric | 001 | BPI `UseAbility001` | **No implementation** on Cleric/base | Notify fires; no gameplay | **Notify Present; Receiver Unimplemented** |
| AN_Ability_002 | `.../AN_Ability_002` | Cleric | 002 | `UseAbility002` | Authority heal | Same multicast pattern | **Connected** |
| AN_Ability_003 | `.../AN_Ability_003` | Cleric | 003 | `UseAbility003` | Unimplemented; damage is timer | Vestigial | **Notify Present; Receiver Unimplemented** |
| AN_Ability_004 | `.../AN_Ability_004` | Paladin | 004 | `UseAbility004` | Authority AoE damage | Multicast + Authority | **Connected** |
| AN_Ability_004 | same | Cleric | 004 | `UseAbility004` | Broken SpawnActor | Multicast + Authority | **Connected (broken body)** |
| AN_AttackComplete | `.../AN_AttackComplete` | Paladin, Amazonian, Cleric (all listed montages) | 001/002/004 (+ Cleric primary) | BPI `SetIsAttacking` | Base Authority: CurrentlyAttacking=false, CanMove true | Multicast notify; state Authority-only | **Connected** |
| PerformingWhirlwind | N/A animation | Amazonian | — | Character EventAnyDamage Get only | No AnimBP/montage Set | — | **Present but Unconnected setter** |
| Divine Circle state | ABP_Cleric | Cleric | 003 presentation | Reads DivineCircleActive | Locomotion state | Cosmetic | **Connected** (presentation) |
---
## 4. Pass 6 reclassification table
| Character | Slot | Previous status | Revised status | New evidence | Reason |
|---|---|---|---|---|---|
| Paladin | 001 | Implemented | **Implemented** (qualified) | `AN_Ability_001``UseAbility001`; cleanup `AN_AttackComplete` | Animation connectivity confirmed; status unchanged |
| Paladin | 002 | Partial | **No change** | ABP Block driven by `IsBlocking` | Presentation path confirmed; hit absorb still untraced |
| Paladin | 003 | Implemented | **No change** | No Montage; ChargeTimeline | Animation pass does not alter charge path |
| Paladin | 004 | Implemented | **Implemented** (qualified) | `AN_Ability_004``UseAbility004` | Connectivity confirmed; empty particle remains |
| Amazonian | 001 | Implemented | **No change** | Full notify → damage → cleanup chain | Confirms known working melee path |
| Amazonian | 002004 | Stub | **No change** | No montages/notifies | — |
| Amazonian | Whirlwind | Partial / unconnected setter | **No change** | Not in ABP or montages | Still Get-only on character |
| Cleric | 001 | Partial (montage only) | **Partial** (qualified: dead notify) | `AN_Ability_001` present; `UseAbility001` unimplemented | Notify does not add gameplay |
| Cleric | 002 | Partial | **Partial** (qualified: notify-driven heal) | `AN_Ability_002``UseAbility002` | Heal path confirmed animation-timed; FX hole remains |
| Cleric | 003 | Implemented | **Implemented** (qualified: timer + vestigial notify) | Damage in ConcentrateHandle; `AN_Ability_003` dead; ABP Divine Circle state | Notify not required for damage |
| Cleric | 004 | Partial / defect | **No change** (qualified: notify-timed) | `AN_Ability_004` → broken `UseAbility004` | Spawn defect unchanged |
| Wizard | 001004 | Stub | **No change** | ABP locomotion only; zero Wizard montages | — |
| Gunslinger | 001004 | Stub | **No change** | No AnimBP; deps = base only | — |
---
## Networking and authority (static)
| Observation | Classification |
|---|---|
| Montage started via Multicast → notifies evaluate on server and clients | Observed Implementation / Inferred (UE montage notify semantics) |
| `UseAbility*` / `SetIsAttacking` bodies use `SwitchHasAuthority` | Observed Implementation (Pass 6) |
| Duplicate damage prevented by Authority gate if notify fires everywhere | Inferred static risk mitigation — Requires Runtime Inspection |
| Gameplay depends on cosmetic Multicast montage evaluating notifies on the server | Observed Implementation — **static risk:** if server skips animation evaluation, hit windows may not fire |
| Missing `AN_AttackComplete` (interrupt) leaves `CurrentlyAttacking` true | Inferred — PlayMontage interrupt pins unwired |
| No client-authoritative ApplyDamage in notify receivers | Observed Implementation |
---
## Answers to Pass 8 known questions (compact)
1. **UseAbility* callers:** `AN_Ability_001004` AnimNotify BPs (not AnimBP EventGraph).
2. **Paladin 001 damage:** Yes — via `AN_Ability_001` during montage.
3. **Paladin block:** No Montage; ABP `Block` state from `IsBlocking`; End clears flags.
4. **Paladin charge cleanup:** Not Montage-callback; ChargeTimeline / ability logic.
5. **Amazonian melee path:** Begin → Multicast montage → `AN_Ability_001``UseAbility001` → Authority damage; `AN_AttackComplete` clears attacking.
6. **Weapon collision notifies:** Not observed on inspected montages (overlap queries inside UseAbility*).
7. **PerformingWhirlwind:** Never set by animation; still unconnected.
8. **Cleric 001 hidden gameplay:** No — notify dead (`UseAbility001` unimplemented).
9. **Cleric 002/003/004:** 002/004 notify-driven; 003 timer-driven; Divine Circle ABP presentation.
10. **Wizard spell assets via anim:** No Wizard montages; no notify chain to unwired NS/GE/projectile.
11. **Gunslinger shared AnimBP/Montage:** No — no AnimBP dependency.
12. **CurrentlyAttacking clear:** Via `AN_AttackComplete` for notify-driven attacks; interrupt cleanup Unknown.
13. **Death anims:** ABP Death state from `IsDead`; destruction/respawn remain character `PlayerDeath` (not notify-driven).
14. **Client-only gameplay timing:** Damage Authority-gated; presentation may diverge — Requires Runtime Inspection.
---
## Pass 9 — Enemy animation dependencies
| Character | AnimBP | Skeleton | Relevant state machines | Montage slots | Ability callbacks | Death path | Confidence |
|---|---|---|---|---|---|---|---|
| Skeleton enemy | `/Game/_Main/Animations/Enemies/Skeleton/ABP_Skeleton` | UE4_Mannequin_Skeleton (deps) | Locomotion: Idle/Walk/Run, Death | None used by combat | GetEnemyREF cache only | Death state + `Anim_Monster_Dead_1..4`; **`SetIsDead(false)` every Update** | High |
| Asset | Notify/callback | Character | Ability | Receiver | Downstream | Connection status |
|---|---|---|---|---|---|---|
| `Anim_SkeletonAttackMontage` | Unknown (unplayed) | Skeleton | Attack | None | None | **Present but Unreferenced** (0 referencers) |
| `ABP_Skeleton` Update | SetIsDead(false) | Skeleton | Death | Self | Blocks death flag | **Connected but Incomplete** |
No enemy AnimNotify → ApplyDamage path observed. Full enemy AI: `09-EnemyAI-StaticAnalysis.md`.