# 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-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-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)) enforces **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. 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)
