# 09 — Enemy AI Static Analysis **Status: Complete** - **Scope:** Complete static reconstruction of enemy control, targeting, chase, attack, damage, death, animation callbacks, navigation context, and enemy-GAS boundary (Pass 9). Builds on Batch 1 native + Pass 3 structural seeds. - **Inspection method:** Native C++ read of `ARIRBaseEnemyCharacter` / `ARIRBaseCharacter` / `ITargetInterface`; BlueprintTools EventGraph DSL + interface graphs; AssetTools find/deps/refs; ObjectTools CDO + placed-instance properties; SceneTools find_actors in Test01; project-wide AI asset/subclass searches. - **Evidence classifications used:** Observed Implementation, Documented Intent, Observed Runtime Behavior, Inferred, Unknown. - **Tool or visibility limitations:** AnimGraph/transition DSL empty (Death transition rule not fully readable); CharacterMovement orient flags partially unreadable; no PIE possession/nav query validation. - **Last updated:** 2026-07-16 - **Current phase:** Phase 1 — Static Architecture (complete) - **Last completed pass:** Pass 11 (Batch 5) — status close; static content Pass 9 (Batch 4C). **Superseded:** earlier “next = Pass 4/10” — Batch 4D completed separately without reopening this doc’s combat findings. - **Next pass expected to contribute:** Phase 2D when authorized ## Completion notes Static enemy AI archaeology is complete. Chase/attack classified **Implementation Missing** (not caused by GetASC). Runtime possession/damage/Death pins: doc `13`. --- ## Executive summary **Observed Runtime Behavior (project brief):** Enemy chase and attack are nonfunctional — Existing Baseline Defect. **Pass 9 static conclusion:** | System | Primary classification | |--------|------------------------| | Target acquisition | **Implementation Missing** | | Chase | **Implementation Missing** (secondary: no navmesh in Test01) | | Attack initiation | **Implementation Missing** (interface stub + orphan montage) | | Attack damage | **Implementation Missing** | | Attack cleanup | **Missing** | | Damage reception | **Implementation Missing** (BP); ASC Health unconnected to ApplyDamage | | Death | **Connected but Incomplete** (ABP Death state exists; `IsDead` forced `false` every Update) | | Enemy GE compatibility | **Existing Baseline Defect** (GetASC → nullptr); separate from chase/attack | Chase and attack failures are **not** attributable to the enemy ASC accessor defect. They are attributable to **absence of connected chase/attack implementation** at native and Blueprint layers. --- ## 1. Enemy class and control matrix | Asset/class | Parent | Controller class | AutoPossessAI | Movement component | AnimBP | Interfaces | Status | Evidence | |---|---|---|---|---|---|---|---|---| | `ARIRBaseEnemyCharacter` | `ARIRBaseCharacter` + `ITargetInterface` | None set in native | N/A | Inherited CharacterMovement | N/A | ITargetInterface (Highlight/UnHighlight) | Active (ASC+highlight only) | RIRBaseEnemyCharacter.cpp | | `BP_EnemyCharacterBase` | `RIRBaseEnemyCharacter` | `/Script/AIModule.AIController` | PlacedInWorld | CharMoveComp (inherited) | None on base | None | Scaffolding / empty graphs | CDO + EventGraph DSL | | `BP_Enemy_Skeleton` | `BP_EnemyCharacterBase_C` | `/Script/AIModule.AIController` | PlacedInWorld | CharMoveComp | `ABP_Skeleton` | `BPI_EnemyCharacter` (GetEnemyREF only) | Scaffolding / empty combat graphs | CDO + DSL | **Native-only behavior (Observed Implementation):** ASC + AttributeSet on self (Minimal); `InitAbilityActorInfo(this,this)` in BeginPlay; mesh Visibility Block; custom-depth highlight. **No** MoveTo, perception, attack, damage, or health mutation in native. **Blueprint EventGraphs (both base and Skeleton) — Observed Implementation:** ``` (event EventBeginPlay) (event Collision|EventActorBeginOverlap (OtherActor)) (event EventTick (DeltaSeconds)) ``` All three entry nodes are **Present but Unconnected** (no wired body). Variables on both BPs: **[]**. **GetEnemyREF (Skeleton only):** returns `self` — Observed Implementation (trivial). **BPI members not implemented on Skeleton/base:** `AddPlayerTarget`, `EnemyMeleeAttack` — Documented Intent only on interface asset. --- ## 2. Current-level instance matrix Level: `/Game/_Main/Levels/Testing/Test01` | Instance | Class | Controller override | AutoPossess override | Relevant instance overrides | Navigation context | Evidence | |---|---|---|---|---|---|---| | `BP_Enemy_Skeleton_C_1` | `BP_Enemy_Skeleton_C` | `/Script/AIModule.AIController` (same as CDO) | PlacedInWorld | **None observed** vs CDO | No NavMeshBoundsVolume; no RecastNavMesh; only AbstractNavData fallback | get_properties; find_actors | | `BP_Enemy_Skeleton_C_0` | same | Unknown — not fully property-dumped | Unknown | Unknown | same level | find_actors presence only | Selected actor at Pass 9 start/end: `BP_Enemy_Skeleton_C_1` — unchanged. **Possession note:** `AutoPossessAI=PlacedInWorld` statically allows placed instances to receive AI possession; **spawned** enemies would not auto-possess under this setting. Runtime possession state: **Unknown** without PIE. Stock `AIController` provides no project behavior tree / blackboard / custom logic. --- ## 3. AI framework inventory | System | Assets/classes found | Active reference path | Status | Evidence | |---|---|---|---|---| | Behavior Tree | **None** (`find_assets` name BehaviorTree `/Game` → []) | None | Missing | find_assets | | Blackboard | **None** (`find_assets` Blackboard → []) | None | Missing | find_assets | | StateTree | **None** (`find_assets` StateTree → []) | None | Missing | find_assets | | EQS / EnvQuery | **None** (`find_assets` EnvQuery → []) | None | Missing | find_assets | | AIPerception assets | **None** (`find_assets` AIPerception → []) | None | Missing | find_assets | | PawnSensing | None on enemy components | None | Missing | ActorTools component list | | Custom AIController | search_subclasses → only engine `AIController`, `DetourCrowdAIController`, `GridPathAIController` | Assigned as stock AIController on enemy CDOs | Missing (project) | search_subclasses; CDO | | MassAI / SmartObject | Not searched by name beyond above; no enemy component refs | None observed | Missing (Observed absence on enemies) | component inventory | --- ## 4. Targeting and chase table | Entry point | Target source | Awareness check | Movement request | Update mechanism | Stop condition | Connection status | Root-cause relevance | |---|---|---|---|---|---|---|---| | EventTick (base/Skeleton) | None | None | None | Tick enabled natively; body empty | N/A | Present but Unconnected | Primary: no chase logic | | EventActorBeginOverlap | OtherActor pin only | None | None | None | None | Present but Unconnected | No target store | | BPI AddPlayerTarget | Interface signature only | — | — | — | — | Missing implementation | Documented Intent unused | | BeginPlay | None | None | None | None | None | Present but Unconnected | No init chase | | AI MoveTo / SimpleMoveTo / PathFollowing | — | — | **None observed** | — | — | Missing | No movement request exists | | GetPlayerCharacter / GetPlayerPawn nodes | — | — | — | — | — | Missing in enemy graphs | No player acquisition | **Primary chase classification: Implementation Missing.** **Secondary condition:** Test01 has **no** `NavMeshBoundsVolume` and **no** `RecastNavMesh` (find_actors empty). Navmesh readiness is **secondary** — even with a baked mesh, no movement request exists to consume it. --- ## 5. Attack table | Entry point | Range gate | State gate | Animation | Hit window | Damage path | Cooldown | Cleanup | Status | Evidence | |---|---|---|---|---|---|---|---|---|---| | BPI EnemyMeleeAttack | — | — | — | — | — | — | — | **Missing** (unimplemented) | list_graphs / Skeleton events | | EventTick / Overlap | — | — | — | — | — | — | — | No attack body | EventGraph DSL | | `Anim_SkeletonAttackMontage` | — | — | Asset exists | Unknown | None (0 referencers) | — | — | **Present but Unreferenced** | get_referencers [] | | Native C++ | — | — | — | — | None | — | — | Missing | RIRBaseEnemyCharacter.cpp | **Primary attack initiation classification: Implementation Missing.** **Secondary:** Orphan attack montage `/Game/_Main/Animations/Enemies/Skeleton/Anim_SkeletonAttackMontage` — Present but Unreferenced; not evidence of an attack path. --- ## 6. Damage and death table | Input mechanism | Health source | Mutation | Death threshold | Death behavior | Cleanup | Status | Evidence | |---|---|---|---|---|---|---|---| | Player ApplyDamage (Paladin/Amazonian/Cleric) | Expected engine TakeDamage | **No** enemy BP `ReceiveAnyDamage`; **no** ASC Health bridge | None observed | None in enemy BP | None | Implementation Missing (reception) | Event list; AttributeSet has no PostGEExecute | | ASC Health attribute | `URIRAttributeSet` on enemy | Not written by combat graphs | None | None | — | Scaffolding Only for combat | Pass 7 + Pass 9 | | Gameplay Effect on enemy | EffectActor library GetASC | **nullptr** via base GetASC | N/A | Early-out | — | Existing Baseline Defect | Pass 7 | | Death animation | ABP Death state + `Anim_Monster_Dead_1..4` | `IsDead` set to **literal false** every UpdateAnimation | Unreachable via IsDead | Death state present | Unknown | Connected but Incomplete | ABP EventGraph DSL | | DestroyActor / ragdoll / rewards | — | — | — | None observed on enemy BP | Missing | Missing | EventGraph DSL | **Player→enemy ApplyDamage compatibility (static):** Playable attacks **do** call `ApplyDamage` (Pass 6). Enemy Blueprints **do not** implement AnyDamage→health→death. Native AttributeSet does not clamp or kill from ApplyDamage. **Inferred:** player melee may deal engine damage events with **no observed enemy health/death consumer** — Requires Runtime Inspection for visual feedback only. --- ## 7. Animation callback table | Asset | Notify/callback | Receiver | Gameplay consequence | State reset | Connection status | Evidence | |---|---|---|---|---|---|---| | `ABP_Skeleton` EventGraph | BlueprintInitializeAnimation | GetEnemyREF → Enemy Reference | Cache REF | — | Connected | read_graph_dsl | | `ABP_Skeleton` EventGraph | BlueprintUpdateAnimation | SetSpeed from velocity; **SetIsDead(false)**; DeathIndex DoOnce | Locomotion speed; **blocks death flag** | — | Connected (death flag forced false) | read_graph_dsl | | `ABP_Skeleton` Locomotion | States: Idle/Walk/Run, Death | — | Presentation | — | Death transition Unknown (DSL empty) | list_graphs | | `Anim_SkeletonAttackMontage` | Unknown notifies | No owner plays montage | None | — | Present but Unreferenced | get_referencers [] | | Death sequences `Anim_Monster_Dead_1..4` | Via ABP Death state | ABP_Skeleton | Cosmetic death pose if state entered | — | Referenced by ABP only | get_dependencies | **No enemy AnimNotify → damage / UseAbility / ApplyDamage path observed.** --- ## 8. Enemy GAS compatibility table | Consumer | ASC lookup method | Expected owner | Static result | Null behavior | Potential impact | Runtime verification | |---|---|---|---|---|---|---| | `ARIREffectActor::ApplyEffectToTarget` | `UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent` → `ARIRBaseCharacter::GetAbilitySystemComponent` → PlayerState | Enemy self ASC | **nullptr** | Early return; no GE | Potions/effects skip enemies | PIE | | Enemy direct `AbilitySystemComponent` member | Native TObjectPtr on enemy | Self | Valid if used | — | No combat consumer observed | — | | IAbilitySystemInterface on enemy | Same as GetASC base | Self intended | nullptr | Same | Interface consumers fail | PIE | | Enemy AttributeSet Health | Direct member | Self | Exists; unreplicated combat use | — | Spawn Init values only | PIE | | Enemy BP damage/death | N/A | — | No ASC read/write in enemy graphs | — | Combat independent of ASC | — | | Chase / attack graphs | N/A | — | **No dependency on ASC** | — | **GetASC defect does not explain chase/attack failure** | — | --- ## 9. Root-cause summary | System | Primary classification | Secondary conditions | Exact evidence | Runtime question | |---|---|---|---|---| | Target acquisition | **Implementation Missing** | BPI AddPlayerTarget unimplemented; empty Tick/Overlap | EventGraph DSL; interface | — | | Chase | **Implementation Missing** | No MoveTo; stock AIController; **no navmesh in Test01** | DSL; find_assets; find_actors | Would possession alone idle forever? | | Attack initiation | **Implementation Missing** | EnemyMeleeAttack unimplemented; attack montage 0 refs | Interface; get_referencers | — | | Attack damage | **Implementation Missing** | No ApplyDamage/GE from enemy | Native + BP | — | | Attack cleanup | **Missing** | — | — | — | | Damage reception | **Implementation Missing** | No ReceiveAnyDamage; no ASC bridge from ApplyDamage | Event list | Do player hits show feedback? | | Death | **Connected but Incomplete** | ABP Death + death anims exist; **SetIsDead(false)** every frame | ABP EventGraph DSL | Can Death state ever enter? | | Enemy Gameplay Effect compatibility | **Existing Baseline Defect** / Incomplete Refactor | GetASC → PlayerState | RIRBaseCharacter.cpp | EffectActor on enemy | --- ## BPI_EnemyCharacter inventory Path: `/Game/_Main/Blueprints/Interfaces/BPI_EnemyCharacter` | Member | Implemented on Skeleton | Callers (referencers of interface asset) | |---|---|---| | GetEnemyREF | Yes → return self | `BP_Enemy_Skeleton`, `ABP_Skeleton` | | AddPlayerTarget | **No** | None observed beyond interface declaration | | EnemyMeleeAttack | **No** | None observed | --- ## Negative-search evidence log | Search | Scope | Result | |---|---|---| | find_assets BehaviorTree `/Game` | Project | [] | | find_assets Blackboard `/Game` | Project | [] | | find_assets StateTree `/Game` | Project | [] | | find_assets EnvQuery `/Game` | Project | [] | | find_assets AIPerception `/Game` | Project | [] | | search_subclasses AIController | Engine+project | Engine-only classes | | Source grep MoveTo/BehaviorTree/Attack AI | Source/REALMSINRUIN | No AI combat (only enemy class highlight/ASC) | | get_referencers Anim_SkeletonAttackMontage | Asset registry | [] | | find_actors NavMeshBoundsVolume / RecastNavMesh | Test01 | [] | | Enemy EventGraph MoveTo/GetPlayer*/ApplyDamage nodes | Both enemy BPs | None (empty DSL) | --- ## Migration / defect notes (inventory only) - Reconstructing enemy AI requires **new implementation** (or restoring unobserved deleted content) — not a reconnect of an existing connected graph. - Interface `AddPlayerTarget` / `EnemyMeleeAttack` are Documented Intent scaffolds. - Fixing enemy GetASC is a separate Incomplete Refactor; it does not restore chase/attack. - ABP `SetIsDead(false)` is a static death-path defect independent of chase.