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>
This commit is contained in:
@@ -2,75 +2,240 @@
|
||||
|
||||
**Status: Draft**
|
||||
|
||||
- **Scope:** Native enemy class (Batch 1) + Pass 3 structural Blueprint inventory. Deep Tick/overlap/AI graph walk deferred to Pass 9.
|
||||
- **Inspection method:** Native read; Batch 2 AssetTools tags + BlueprintTools list_graphs/events/variables/deps.
|
||||
- **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
|
||||
- **Last completed pass:** Pass 3 (Batch 2) — structural only
|
||||
- **Next pass expected to contribute:** Batch 4 Pass 9
|
||||
- **Last completed pass:** Pass 9 (Batch 4C)
|
||||
- **Next pass expected to contribute:** Pass 4 / Pass 10 when authorized — not auto-started
|
||||
|
||||
## Draft tracking
|
||||
|
||||
### Completed sections
|
||||
- Native enemy ASC ownership and highlight interface
|
||||
- Confirmation: no chase/attack/MoveTo in native C++
|
||||
- Blueprint child paths + Pass 3 structural sheets
|
||||
- BPI_EnemyCharacter API surface
|
||||
- Native enemy ASC, highlight, no native AI combat
|
||||
- Full BP_EnemyCharacterBase / BP_Enemy_Skeleton structural + EventGraph reconstruction
|
||||
- BPI_EnemyCharacter implementation status
|
||||
- Controller / AutoPossessAI class + instance
|
||||
- AI framework negative inventory
|
||||
- Targeting / chase / attack absence
|
||||
- Attack montage orphan
|
||||
- ABP_Skeleton locomotion + Death + IsDead forced false
|
||||
- Damage/death reception absence at BP layer
|
||||
- Enemy GAS compatibility (Pass 7 + Pass 9)
|
||||
- Test01 navigation context (no NavMeshBoundsVolume / RecastNavMesh)
|
||||
- Root-cause classifications for chase and attack
|
||||
|
||||
### Pending sections
|
||||
- Connected Tick / overlap / timer / MoveTo graphs on enemy BPs
|
||||
- AIControllerClass / AutoPossessAI on CDOs (reconfirm)
|
||||
- Consumers of GetASC on enemies
|
||||
- Runtime possession confirmation under PIE
|
||||
- Whether engine TakeDamage has any other consumer outside enemy BP
|
||||
- ABP Death transition condition exact VariableGet wiring (DSL empty)
|
||||
|
||||
### Evidence still required
|
||||
- Where chase/attack was intended to live (Blueprint vs missing)
|
||||
- Runtime root cause of nonfunctional chase/attack — Requires Runtime Inspection
|
||||
- PIE: does stock AIController possess placed skeletons?
|
||||
- PIE: player ApplyDamage visual/health effect on skeleton
|
||||
- Manual Editor: ABP Death transition rule pins
|
||||
|
||||
---
|
||||
|
||||
## Native findings
|
||||
## Executive summary
|
||||
|
||||
**Observed Implementation:** `ARIRBaseEnemyCharacter` implements:
|
||||
**Observed Runtime Behavior (project brief):** Enemy chase and attack are nonfunctional — Existing Baseline Defect.
|
||||
|
||||
- ASC + AttributeSet on self (Minimal replication)
|
||||
- InitAbilityActorInfo(this, this) in BeginPlay
|
||||
- ITargetInterface highlight via custom depth
|
||||
- Visibility collision on mesh
|
||||
**Pass 9 static conclusion:**
|
||||
|
||||
**Observed Implementation:** No AIController subclass, no MoveTo, no perception, no attack timers in native.
|
||||
| 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 |
|
||||
|
||||
**Calibration (prior Observed Implementation):** Stock `/Script/AIModule.AIController`; AutoPossessAI PlacedInWorld on skeleton instance; no project BehaviorTree assets.
|
||||
|
||||
**Issue:** Existing Baseline Defect (enemy chase/attack nonfunctional per project brief).
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
## Pass 3 Blueprint structure (not Pass 9 deep dive)
|
||||
## 1. Enemy class and control matrix
|
||||
|
||||
### `BP_EnemyCharacterBase`
|
||||
| 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 |
|
||||
|
||||
| Field | Value |
|
||||
|-------|--------|
|
||||
| Path | `/Game/_Main/Blueprints/Characters/Enemies/BP_EnemyCharacterBase` |
|
||||
| Parent | `RIRBaseEnemyCharacter` |
|
||||
| IsDataOnly | True |
|
||||
| Graphs | UserConstructionScript, EventGraph |
|
||||
| Variables | [] |
|
||||
| Implemented events | ReceiveBeginPlay, ReceiveTick, ReceiveActorBeginOverlap |
|
||||
| Deps | `/Script/REALMSINRUIN` only |
|
||||
**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.
|
||||
|
||||
### `BP_Enemy_Skeleton`
|
||||
**Blueprint EventGraphs (both base and Skeleton) — Observed Implementation:**
|
||||
|
||||
| Field | Value |
|
||||
|-------|--------|
|
||||
| Path | `/Game/_Main/Blueprints/Characters/Enemies/Skeleton/BP_Enemy_Skeleton` |
|
||||
| Parent | `BP_EnemyCharacterBase_C` |
|
||||
| Interface | `BPI_EnemyCharacter` (`GetEnemyREF`) |
|
||||
| Graphs | UCS, EventGraph, GetEnemyREF |
|
||||
| Variables | [] |
|
||||
| Implemented events | ReceiveBeginPlay, ReceiveTick, ReceiveActorBeginOverlap |
|
||||
| Deps | SKM_Skeleton_Guard_Body, BPI_EnemyCharacter, BP_EnemyCharacterBase, ABP_Skeleton, REALMSINRUIN |
|
||||
```
|
||||
(event EventBeginPlay)
|
||||
(event Collision|EventActorBeginOverlap (OtherActor))
|
||||
(event EventTick (DeltaSeconds))
|
||||
```
|
||||
|
||||
### `BPI_EnemyCharacter`
|
||||
All three entry nodes are **Present but Unconnected** (no wired body). Variables on both BPs: **[]**.
|
||||
|
||||
Graphs: `GetEnemyREF`, `AddPlayerTarget`, `EnemyMeleeAttack` — **Documented Intent** surface for targeting/melee; connected implementations on Skeleton/base **not traced in Batch 2** (Pass 9).
|
||||
**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.
|
||||
|
||||
Reference in New Issue
Block a user