9.1 KiB
E5.M1 — CombatRulesEngine
Summary
| Field | Value |
|---|---|
| Module ID | E5.M1 |
| Epic | Epic 5 — PvE Combat |
| Stage target | Prototype |
| Status | In Progress — Slice 1 backlog E5M1-prototype-backlog.md: E5M1-01 NEO-76 ability catalog + CI landed; E5M1-02 NEO-77 server load landed; E5M1-03 NEO-79 registry + hotbar/cast migration landed; E5M1-04 NEO-78 ability-definitions GET landed; E5M1-05 NEO-80 combat entity health store landed; E5M1-06 NEO-81 combat operations + CombatResult landed; E5M1-07 NEO-82 cast POST + wire combatResolution landed; E5M1-08 NEO-83 combat-targets GET landed; E5M1-09+ pending (see dependency register) |
| Linear | Label E5.M1 · E5M1-prototype-backlog.md E5M1-01 NEO-76 → E5M1-12 NEO-86; gig XP E5M1-10 NEO-44 |
Purpose
Authority: Client vs server — server validates intents and computes all outcomes; never trust client damage/healing/crit/death.
Core tab-target combat resolution: valid actions against a locked target, hit resolution, cooldown and resource timing, and threat state as needed for prototype encounters. Presents readable outcomes in fixed isometric view and feeds XP awards through E2.M2.
PvP: Single engine for PvE and PvP; player-target hostility gates on E6.M1. See PvP and the combat engine.
Responsibilities
- Combat state machine for tab-target flow (attacks, abilities per prototype scope).
- Validate and apply
CombatAction; produceCombatResolutionfor UI and logs (include PvP deny reasons when player targets are blocked; see pvp_combat_integration.md). - Integrate with targeting/interaction from E1.M3 (target lock, valid target checks).
- Award combat XP via E2.M2 integration where specified in slices.
Key contracts
| Contract | Role |
|---|---|
CombatAction |
Attack, ability, or other combat intent from client/input scaffold. |
CombatResolution |
Hits, misses, damage, denies with reason codes (no silent failures). |
ThreatState |
Aggro/threat for NPC and encounter coordination (as scoped). |
Module dependencies
- E1.M3 — InteractionAndTargetingLayer:
TargetState, selection, and alignment with E1.M4 (AbilityInputScaffold) forAbilityCastRequestwiring. - E2.M2 — XpAwardAndLevelEngine: combat XP grants.
Dependents (by design)
- E5.M2 — NpcAiAndBehaviorProfiles.
- E5.M3 — EncounterAndRewardTables.
- E1.M4 — AbilityInputScaffold sends
AbilityCastRequestto combat. - E7.M1 — QuestStateMachine for combat-related quest steps.
- E2.M2 — Invoked as integration caller for XP (not a structural child).
Related implementation slices
See Epic 5 Slice 1 — Combat rules MVP: target lock, basic attacks, 4–6 abilities, cooldowns/resources; telemetry encounter_start, ability_used, player_death, enemy_defeat.
E5M1-04 (NEO-78): GET /game/world/ability-definitions — AbilityDefinitionsWorldApi + DTOs in Game/Combat/ (NEO-78 plan); server README — Ability definitions (NEO-78); Bruno bruno/neon-sprawl-server/ability-definitions/.
E5M1-05 (NEO-80): ICombatEntityHealthStore + InMemoryCombatEntityHealthStore — lazy HP init for PrototypeTargetRegistry dummies at PrototypeCombatConstants.MaxPrototypeTargetHp (100) (NEO-80 plan); server README — Combat entity health (NEO-80).
E5M1-06 (NEO-81): CombatOperations.TryResolve + CombatResult + CombatReasonCodes — deterministic catalog damage, defeated pre-check deny (target_defeated), unknown ability/target validation (NEO-81 plan); server README — Combat engine (NEO-81).
E5M1-07 (NEO-82): AbilityCastApi → CombatOperations.TryResolve — nested wire combatResolution on accept, per-ability catalog cooldownSeconds, target_defeated cast deny without cooldown commit (NEO-82 plan); server README — Ability cast (NEO-82); Bruno bruno/neon-sprawl-server/ability-cast/.
E5M1-08 (NEO-83): GET /game/world/combat-targets — CombatTargetsWorldApi + DTOs in Game/Combat/; authoritative HP snapshot from ICombatEntityHealthStore (NEO-83 plan); server README — Combat targets snapshot (NEO-83); Bruno bruno/neon-sprawl-server/combat-targets/.
Linear backlog (decomposed)
Full story tables, kickoff defaults, and blockedBy graph: E5M1-prototype-backlog.md.
| Slug | Linear |
|---|---|
| E5M1-01 | NEO-76 |
| E5M1-02 | NEO-77 |
| E5M1-03 | NEO-79 |
| E5M1-04 | NEO-78 |
| E5M1-05 | NEO-80 |
| E5M1-06 | NEO-81 |
| E5M1-07 | NEO-82 |
| E5M1-08 | NEO-83 |
| E5M1-09 | NEO-84 |
| E5M1-10 | NEO-44 |
| E5M1-11 | NEO-85 |
| E5M1-12 | NEO-86 |
Prototype Slice 1 freeze (E5M1-01)
The first shipped four-ability combat spine under content/abilities/*.json is frozen for hotbar bindings, cast validation, and combat resolution until a deliberate migration or follow-up issue expands the roster.
AbilityDef.id |
displayName |
baseDamage |
cooldownSeconds |
abilityKind |
|---|---|---|---|---|
prototype_pulse |
Prototype Pulse | 25 | 3.0 | attack |
prototype_guard |
Prototype Guard | 0 | 6.0 | utility |
prototype_dash |
Prototype Dash | 0 | 4.0 | movement |
prototype_burst |
Prototype Burst | 40 | 5.0 | attack |
Rules: Do not rename these id values—change displayName only, or add a new id in a follow-up issue. CI (scripts/validate_content.py) and server startup (NEO-77) enforce exactly these four ids and duplicate-id rejection across all ability JSON files. Relaxing or changing that gate belongs in a new Linear issue once the catalog intentionally grows. prototype_pulse at 25 damage × 4 casts defeats a 100 HP prototype dummy (E5M1 backlog default). IAbilityDefinitionRegistry + hotbar/cast migration landed (NEO-79, E5M1-03).
Prototype notes (NEO-28)
Epic 1 Slice 3 cast accept/deny on POST /game/players/{id}/ability-cast remains the E1.M4 gate funnel: hotbar/loadout validation (E1.M4), targetId must match the persisted combat lock, resolve in the prototype target registry, and sit within horizontal lock radius against authoritative PositionState. Deny codes invalid_target and out_of_range reuse the same strings as E1.M3 TargetState.validity. NEO-82 (E5M1-07): after gates pass, CombatOperations.TryResolve runs; accept returns nested wire combatResolution (damageDealt, targetRemainingHp, targetDefeated, …) and commits per-ability catalog cooldown; target_defeated JSON deny on re-hit at zero HP.
Risks and telemetry
- Sluggish or opaque tab-target: prototype readability gate; instrument time-in-combat and deny reasons.
- Desync logging via E9.M1 taxonomy when available.
Source anchors
- Master plan:
neon_sprawl_vision.plan.md— Core Epic Map, Epic 5. - Module dependency register