# E5.M2 — NpcAiAndBehaviorProfiles ## Summary | Field | Value | |--------|--------| | **Module ID** | E5.M2 | | **Epic** | [Epic 5 — PvE Combat](../epics/epic_05_pve_combat.md) | | **Stage target** | Prototype | | **Status** | In Progress — Slice 2 backlog [E5M2-prototype-backlog.md](../../plans/E5M2-prototype-backlog.md): **E5M2-01** [NEO-87](https://linear.app/neon-sprawl/issue/NEO-87) catalog + CI landed · **E5M2-02** [NEO-88](https://linear.app/neon-sprawl/issue/NEO-88) server load landed → **E5M2-12** [NEO-98](https://linear.app/neon-sprawl/issue/NEO-98) | | **Linear** | Label **`E5.M2`** · [E5M2-prototype-backlog.md](../../plans/E5M2-prototype-backlog.md) **E5M2-01** [NEO-87](https://linear.app/neon-sprawl/issue/NEO-87) · **E5M2-02** [NEO-88](https://linear.app/neon-sprawl/issue/NEO-88) → **E5M2-12** [NEO-98](https://linear.app/neon-sprawl/issue/NEO-98) | ## Purpose **Authority:** [Client vs server](client_server_authority.md) — server owns NPC behavior state, aggro holders, telegraph timing, and NPC→player damage; client displays telegraphs and state from polled snapshots only. Enemy archetype behavior loops, aggro logic, and telegraph scheduling on top of [E5.M1 — CombatRulesEngine](E5_M1_CombatRulesEngine.md). Replaces passive **`prototype_target_alpha` / `beta`** dummies with **three** fight-back NPC instances for the vision prototype minimum ([three archetypes](../../../neon_sprawl_vision.plan.md#prototype-content-minimums)). ## Responsibilities - Run `NpcBehaviorDef`; emit `TelegraphEvent`; apply `AggroRule` / **`ThreatState`** integration with combat state. - Lazy NPC tick advance on **`GET /game/world/npc-runtime-snapshot`** poll (prototype). - Session **`IPlayerCombatHealthStore`** for incoming NPC damage (no Postgres in Slice 2). ## Key contracts | Contract | Role | |----------|------| | `NpcBehaviorDef` | Archetype scripts or state machines (content JSON + schema). | | `TelegraphEvent` | Telegraph timing for UI and dodge windows. | | `AggroRule` | Target selection and leash behavior. | | `ThreatState` | Per-NPC aggro holder (`playerId` or empty). | ## Module dependencies - **E5.M1** — CombatRulesEngine (player → NPC damage, combat-target HP, cast funnel). ## Dependents (by design) - **E4.M2** — SpawnEcologyController. - **E5.M3** — EncounterAndRewardTables. ## Related implementation slices Epic 5 **Slice 2 — NPC archetypes and telegraphs**: three archetypes (melee pressure, ranged control, elite mini-boss); telemetry `telegraph_fired`, `npc_state_transition`. ## Linear backlog (decomposed) Full story tables, kickoff defaults, and **`blockedBy` graph:** [E5M2-prototype-backlog.md](../../plans/E5M2-prototype-backlog.md). | Slug | Linear | |------|--------| | E5M2-01 | [NEO-87](https://linear.app/neon-sprawl/issue/NEO-87) | | E5M2-02 | [NEO-88](https://linear.app/neon-sprawl/issue/NEO-88) | | E5M2-03 | [NEO-89](https://linear.app/neon-sprawl/issue/NEO-89) | | E5M2-04 | [NEO-90](https://linear.app/neon-sprawl/issue/NEO-90) | | E5M2-05 | [NEO-91](https://linear.app/neon-sprawl/issue/NEO-91) | | E5M2-06 | [NEO-92](https://linear.app/neon-sprawl/issue/NEO-92) | | E5M2-07 | [NEO-93](https://linear.app/neon-sprawl/issue/NEO-93) | | E5M2-08 | [NEO-94](https://linear.app/neon-sprawl/issue/NEO-94) | | E5M2-09 | [NEO-95](https://linear.app/neon-sprawl/issue/NEO-95) | | E5M2-10 | [NEO-96](https://linear.app/neon-sprawl/issue/NEO-96) | | E5M2-11 | [NEO-97](https://linear.app/neon-sprawl/issue/NEO-97) | | E5M2-12 | [NEO-98](https://linear.app/neon-sprawl/issue/NEO-98) | ## Prototype Slice 2 freeze (E5M2-01) The **first shipped three-archetype NPC spine** under `content/npc-behaviors/*.json` is **frozen** for behavior binding, aggro tuning, and telegraph timings until a deliberate migration issue expands the roster. | `NpcBehaviorDef.id` | `displayName` | `archetypeKind` | `maxHp` | `aggroRadius` | `leashRadius` | `telegraphWindupSeconds` | `attackDamage` | `attackCooldownSeconds` | |---------------------|---------------|-----------------|---------|---------------|---------------|--------------------------|----------------|-------------------------| | **`prototype_melee_pressure`** | Melee Pressure | `melee_pressure` | 100 | 8.0 | 16.0 | 1.5 | 15 | 3.0 | | **`prototype_ranged_control`** | Ranged Control | `ranged_control` | 80 | 10.0 | 20.0 | 2.0 | 12 | 4.0 | | **`prototype_elite_mini_boss`** | Elite Mini-Boss | `elite_mini_boss` | 200 | 8.0 | 18.0 | 2.5 | 25 | 5.0 | **NPC instance ids (E5M2-05):** **`prototype_npc_melee`**, **`prototype_npc_ranged`**, **`prototype_npc_elite`** — each binds one behavior def + world anchor (replaces **`prototype_target_alpha` / `beta`**). **Rules:** Do **not** rename frozen behavior **`id`** values without a migration issue. CI ([`scripts/validate_content.py`](../../../scripts/validate_content.py)) and server startup ([NEO-88](../../plans/NEO-88-implementation-plan.md)) enforce **exactly** these three behavior ids, duplicate-`id` rejection, and **`leashRadius` > `aggroRadius`** per row. Relaxing or changing that gate belongs in a new Linear issue once the catalog intentionally grows. Catalog + CI plan: [NEO-87 implementation plan](../../plans/NEO-87-implementation-plan.md). ## Risks and telemetry - Telegraph desync: single **`npc-runtime-snapshot`** poll surface; no client windup math. - Aggro confusion: deterministic first-hit + leash rules; instrument `npc_state_transition` when E9.M1 lands. ## Source anchors - Master plan: [`neon_sprawl_vision.plan.md`](../../../neon_sprawl_vision.plan.md) — Epic 5, prototype enemy minimums. - [Module dependency register](module_dependency_register.md)