neon-sprawl/docs/decomposition/modules/E5_M1_CombatRulesEngine.md

8.1 KiB
Raw Blame History

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+ pending (see dependency register)
Linear Label E5.M1 · E5M1-prototype-backlog.md E5M1-01 NEO-76E5M1-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; produce CombatResolution for 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

Dependents (by design)

  • E5.M2 — NpcAiAndBehaviorProfiles.
  • E5.M3 — EncounterAndRewardTables.
  • E1.M4 — AbilityInputScaffold sends AbilityCastRequest to combat.
  • E7.M1 — QuestStateMachine for combat-related quest steps.
  • E2.M2 — Invoked as integration caller for XP (not a structural child).

See Epic 5 Slice 1 — Combat rules MVP: target lock, basic attacks, 46 abilities, cooldowns/resources; telemetry encounter_start, ability_used, player_death, enemy_defeat.

E5M1-04 (NEO-78): GET /game/world/ability-definitionsAbilityDefinitionsWorldApi + 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).

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