docs: PvP × combat engine integration (#4)

Add pvp_combat_integration.md: single E5.M1 pipeline for PvE/PvP;
E6.M1 gate before player-target hostility; stub for PvE-only milestones;
shared kernel + profiles escape hatch; deny reason / telemetry notes;
E6.M3 ordering after resolution.

Register cross-cutting subsection; links from E5.M1, E6.M1,
client_server_authority, contracts, decomposition README, tech_stack.
Fix E6.M1 master plan link markup.

Made-with: Cursor
pull/6/head
VinPropane 2026-03-30 18:55:46 -04:00
parent 837251d439
commit c9765da311
8 changed files with 81 additions and 15 deletions

View File

@ -113,3 +113,4 @@ Revisit this document if:
- [`docs/decomposition/README.md`](../decomposition/README.md) — epic/module decomposition - [`docs/decomposition/README.md`](../decomposition/README.md) — epic/module decomposition
- [`docs/decomposition/modules/contracts.md`](../decomposition/modules/contracts.md) — contract kinds (wire, content, telemetry), repo layout, versioning vs. register “Contract needed” - [`docs/decomposition/modules/contracts.md`](../decomposition/modules/contracts.md) — contract kinds (wire, content, telemetry), repo layout, versioning vs. register “Contract needed”
- [`docs/decomposition/modules/client_server_authority.md`](../decomposition/modules/client_server_authority.md) — intents vs authoritative state; movement, camera, combat, economy ownership - [`docs/decomposition/modules/client_server_authority.md`](../decomposition/modules/client_server_authority.md) — intents vs authoritative state; movement, camera, combat, economy ownership
- [`docs/decomposition/modules/pvp_combat_integration.md`](../decomposition/modules/pvp_combat_integration.md) — E5.M1 combat engine × E6.M1 PvP eligibility (single pipeline, deny reasons)

View File

@ -9,7 +9,7 @@ This workspace contains detailed planning artifacts derived from the finalized m
## Folder Layout ## Folder Layout
- `epics/` - One file per epic with implementation slices. - `epics/` - One file per epic with implementation slices.
- `modules/` - [Contract definitions](modules/contracts.md), [client vs server authority](modules/client_server_authority.md), [full module dependency register](modules/module_dependency_register.md) (all epic modules), [per-module docs](modules/module_dependency_register.md#per-module-documentation), and interface notes. - `modules/` - [Contract definitions](modules/contracts.md), [client vs server authority](modules/client_server_authority.md), [PvP × combat engine](modules/pvp_combat_integration.md), [full module dependency register](modules/module_dependency_register.md) (all epic modules), [per-module docs](modules/module_dependency_register.md#per-module-documentation), and interface notes.
- `milestones/` - Phase-gated implementation tracks and pass/fail checklists. - `milestones/` - Phase-gated implementation tracks and pass/fail checklists.
## Working Rules ## Working Rules

View File

@ -15,10 +15,12 @@
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](E2_M2_XpAwardAndLevelEngine.md). 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](E2_M2_XpAwardAndLevelEngine.md).
**PvP:** Single engine for PvE and PvP; player-target hostility **gates** on [E6.M1](E6_M1_PvPEligibilityAndFlagState.md). See [PvP and the combat engine](pvp_combat_integration.md).
## Responsibilities ## Responsibilities
- Combat state machine for tab-target flow (attacks, abilities per prototype scope). - Combat state machine for tab-target flow (attacks, abilities per prototype scope).
- Validate and apply `CombatAction`; produce `CombatResolution` for UI and logs. - Validate and apply `CombatAction`; produce `CombatResolution` for UI and logs (include **PvP deny reasons** when player targets are blocked; see [pvp_combat_integration.md](pvp_combat_integration.md)).
- Integrate with targeting/interaction from **E1.M3** (target lock, valid target checks). - Integrate with targeting/interaction from **E1.M3** (target lock, valid target checks).
- Award combat XP via E2.M2 integration where specified in slices. - Award combat XP via E2.M2 integration where specified in slices.

View File

@ -2,12 +2,14 @@
## Summary ## Summary
| Field | Value |
|--------|--------| | Field | Value |
| **Module ID** | E6.M1 | | ---------------- | ------------------------------------------------------------------ |
| **Epic** | [Epic 6 — PvP Security](../epics/epic_06_pvp_security.md) | | **Module ID** | E6.M1 |
| **Stage target** | Prototype | | **Epic** | [Epic 6 — PvP Security](../epics/epic_06_pvp_security.md) |
| **Status** | Planned (see [dependency register](module_dependency_register.md)) | | **Stage target** | Prototype |
| **Status** | Planned (see [dependency register](module_dependency_register.md)) |
## Purpose ## Purpose
@ -21,11 +23,13 @@ Server-enforced rules for whether player-versus-player combat is allowed: driven
## Key contracts ## Key contracts
| Contract | Role |
|----------|------| | Contract | Role |
| `PvPFlagState` | Current opt-in and effective PvP capability for an actor in context. | | ----------------- | -------------------------------------------------------------------- |
| `EligibilityRule` | Policy mapping from tier + context to allow/deny. | | `PvPFlagState` | Current opt-in and effective PvP capability for an actor in context. |
| `PvPStateChanged` | Event for subscribers (UX, analytics, combat deny reasons). | | `EligibilityRule` | Policy mapping from tier + context to allow/deny. |
| `PvPStateChanged` | Event for subscribers (UX, analytics, combat deny reasons). |
## Module dependencies ## Module dependencies
@ -35,7 +39,7 @@ Server-enforced rules for whether player-versus-player combat is allowed: driven
- **E6.M2** — ConsentAndRiskUxSignals: prompts and HUD indicators. - **E6.M2** — ConsentAndRiskUxSignals: prompts and HUD indicators.
- **E6.M3** — LossPenaltyAndAntiGriefRules: builds on eligibility and zone context. - **E6.M3** — LossPenaltyAndAntiGriefRules: builds on eligibility and zone context.
- **Combat resolution**E5.M1 (or dedicated PvP branch) consults eligibility before applying player-vs-player actions (integration detail per implementation). - **Combat resolution**[E5.M1](E5_M1_CombatRulesEngine.md) consults E6.M1 **in the same pipeline** before applying player-target hostility; see [PvP and the combat engine](pvp_combat_integration.md).
## Related implementation slices ## Related implementation slices
@ -50,3 +54,4 @@ See Epic 6 **Slice 1 — Zone-based PvP flag core**: high-sec blocks player comb
- Master plan: [`neon_sprawl_vision.plan.md`](../../../neon_sprawl_vision.plan.md) — Core Epic Map, Epic 6. - Master plan: [`neon_sprawl_vision.plan.md`](../../../neon_sprawl_vision.plan.md) — Core Epic Map, Epic 6.
- [Module dependency register](module_dependency_register.md) - [Module dependency register](module_dependency_register.md)

View File

@ -52,6 +52,7 @@ Naming on the wire may use `*Command` or `*Intent` for client→server and `*Sta
- **Never trust** client-supplied **damage**, **healing**, **crit rolls**, or **death** outcomes as source of truth. - **Never trust** client-supplied **damage**, **healing**, **crit rolls**, or **death** outcomes as source of truth.
- **Trust** only what the client can **observe** as intent: which action, which target, timing within tolerance—then **recompute** everything server-side from `SkillDef`, stats, and combat state. - **Trust** only what the client can **observe** as intent: which action, which target, timing within tolerance—then **recompute** everything server-side from `SkillDef`, stats, and combat state.
- **Player targets:** Before applying hostile effects to another player, consult [E6.M1](E6_M1_PvPEligibilityAndFlagState.md) in-process; one combat engine for PvE and PvP — [details](pvp_combat_integration.md).
### Economy, crafting, inventory, quests, zones, PvP ### Economy, crafting, inventory, quests, zones, PvP
@ -79,4 +80,5 @@ Revisit when the first **Protobuf** game channel and a **multiplayer** milestone
- [`docs/architecture/tech_stack.md`](../../architecture/tech_stack.md) — server-authoritative critical paths, intents vs state - [`docs/architecture/tech_stack.md`](../../architecture/tech_stack.md) — server-authoritative critical paths, intents vs state
- [contracts.md](contracts.md) — wire vs content artifacts - [contracts.md](contracts.md) — wire vs content artifacts
- [PvP and the combat engine](pvp_combat_integration.md) — E5.M1 × E6.M1 integration shape
- [Module dependency register](module_dependency_register.md) - [Module dependency register](module_dependency_register.md)

View File

@ -80,6 +80,7 @@ A modules register **Status** can move to **Ready** when the contracts it **e
- [tech stack](../../architecture/tech_stack.md) — Protobuf vs JSON spike, content validation, client/server split - [tech stack](../../architecture/tech_stack.md) — Protobuf vs JSON spike, content validation, client/server split
- [Client vs server authority](client_server_authority.md) — intents vs state, E1/E5 defaults, deferred networking choices - [Client vs server authority](client_server_authority.md) — intents vs state, E1/E5 defaults, deferred networking choices
- [PvP and the combat engine](pvp_combat_integration.md) — E5.M1 gating with E6.M1, deny reasons
- [Module dependency register](module_dependency_register.md) - [Module dependency register](module_dependency_register.md)
- [Decomposition README](../README.md) - [Decomposition README](../README.md)

View File

@ -2,7 +2,7 @@
Tracks cross-epic dependencies and contract readiness. Every **Depends On** module ID in this table has its own row (closed graph). Tracks cross-epic dependencies and contract readiness. Every **Depends On** module ID in this table has its own row (closed graph).
**Contract** means a stable boundary with a defined artifact (Protobuf wire message, JSON Schema content file, telemetry catalog entry, or server-internal type until promoted). See **[What a contract is](contracts.md)** for kinds, repo layout, and versioning. **Authority** (who owns `PositionState`, camera, combat outcomes): **[Client vs server authority](client_server_authority.md)**. **Contract** means a stable boundary with a defined artifact (Protobuf wire message, JSON Schema content file, telemetry catalog entry, or server-internal type until promoted). See **[What a contract is](contracts.md)** for kinds, repo layout, and versioning. **Authority** (who owns `PositionState`, camera, combat outcomes): **[Client vs server authority](client_server_authority.md)**. **PvP × combat:** **[PvP and the combat engine](pvp_combat_integration.md)**.
Fleshed-out scope, contracts, and integration notes live in **per-module documents** (see [Per-module documentation](#per-module-documentation)). Fleshed-out scope, contracts, and integration notes live in **per-module documents** (see [Per-module documentation](#per-module-documentation)).
@ -65,6 +65,10 @@ Fleshed-out scope, contracts, and integration notes live in **per-module documen
| E6.M3 | LossPenaltyAndAntiGriefRules | E6.M1, E9.M4 | PvPLossRule, SpawnProtectionState, GriefingStrike | Pre-production | Planned | | E6.M3 | LossPenaltyAndAntiGriefRules | E6.M1, E9.M4 | PvPLossRule, SpawnProtectionState, GriefingStrike | Pre-production | Planned |
| E6.M4 | RewardParityEnforcer | E3.M2, E5.M3, E7.M2 | RewardParityMap, EquivalentPowerBand, ParityViolationAlert | Prototype | Planned | | E6.M4 | RewardParityEnforcer | E3.M2, E5.M3, E7.M2 | RewardParityMap, EquivalentPowerBand, ParityViolationAlert | Prototype | Planned |
### Cross-cutting: combat and PvP eligibility
When hostile actions can target **players**, [E5.M1 — CombatRulesEngine](E5_M1_CombatRulesEngine.md) **must** consult [E6.M1 — PvPEligibilityAndFlagState](E6_M1_PvPEligibilityAndFlagState.md) in the same server handling path before applying effects. **PvE-only** milestones may use a **stub** that denies all player-target hostility until PvP is enabled. Shape and deny reasons: **[PvP and the combat engine](pvp_combat_integration.md)**.
### Epic 7 — Quest / Faction ### Epic 7 — Quest / Faction
| Module ID | Module Name | Depends On | Contract Needed | Phase Required | Status | | Module ID | Module Name | Depends On | Contract Needed | Phase Required | Status |

View File

@ -0,0 +1,51 @@
# PvP and the combat engine (#4)
This doc fixes **how** [E6.M1 — PvPEligibilityAndFlagState](E6_M1_PvPEligibilityAndFlagState.md) connects to [E5.M1 — CombatRulesEngine](E5_M1_CombatRulesEngine.md): one pipeline vs a forked “PvP combat” module, and how denials surface on the wire.
Complements [client_server_authority.md](client_server_authority.md) (authority) and [contracts.md](contracts.md) (artifact types).
---
## Decision: single combat rules engine
**Default for Neon Sprawl:** **E5.M1** is the **only** combat resolution engine for tab-target play. **Player vs player** uses the **same** code path as **player vs NPC** for formulas that should stay aligned (hit checks, cooldowns, resources, ability application), with **extra gating** when the target (or victims in an AoE) include **players**.
**Do not** introduce a separate “PvP combat engine” for the prototype unless design later proves **irreconcilable** rule divergence. If that happens, prefer a **shared resolution kernel** (pure functions / shared module) plus **policy profiles** (PvE vs PvP) rather than two divergent engines.
**Rationale:** One engine reduces duplicate bugs, keeps `CombatAction` / `CombatResolution` as a single wire story, and matches optional-PvP product goals (PvP is policy on top of the same abilities, not a different game).
---
## Where E6.M1 plugs in
- **When:** During **validation** of a `CombatAction` (or internal equivalent) **before** applying damage, debuffs, displacement, or other hostile effects to another **player** character.
- **Who calls whom:** **E5.M1** calls into **E6.M1** (or an abstraction it owns, implemented by E6.M1) — e.g. `CanApplyHostility(attacker, target, actionContext) → Allow | Deny(reason)`.
- **Consistency:** Use **current server** eligibility and zone policy for that tick/request; avoid stale client-only flags. If eligibility is cached per session, invalidate on zone transition and on `PvPStateChanged`.
**NPC targets:** No E6.M1 check for ordinary PvE (unless a future rule ties NPC combat to zone policy — then call out explicitly).
**Register note:** Epic 5 lists E5.M1 dependencies as E1.M3 and E2.M2 only. **Enabling player-target hostility** adds a **logical** dependency on E6.M1; PvE-only milestones may ship with a **stub** implementation that denies all player-target hostility until Epic 6 wiring lands. See [cross-cutting note in the dependency register](module_dependency_register.md#cross-cutting-combat-and-pvp-eligibility).
---
## Deny reasons and telemetry
PvP blocks must be **first-class** in combat outcomes, not silent failures:
- Extend the combat deny / `CombatResolution` reason set (or parallel field) with stable codes such as: `pvp_forbidden_in_zone`, `attacker_pvp_not_eligible`, `target_pvp_not_eligible`, `pvp_consent_required`, `pvp_flag_mismatch` (exact names to be frozen when Protobuf enums are defined).
- Align high-signal events with [E9.M1](E9_M1_TelemetryEventSchema.md) (e.g. ability denied with reason) and Epic 6 hooks (`pvp_state_changed`, zone enter/exit) without double-counting.
---
## E6.M3 and beyond
**E6.M3** (loss, spawn protection, grief strikes) applies **after** hostility is **allowed** by E6.M1 and **resolved** by E5.M1 (e.g. on death in PvP context). Order: **eligibility → combat resolution → loss/anti-grief rules**.
---
## Related docs
- [E5.M1 — CombatRulesEngine](E5_M1_CombatRulesEngine.md)
- [E6.M1 — PvPEligibilityAndFlagState](E6_M1_PvPEligibilityAndFlagState.md)
- [Client vs server authority](client_server_authority.md)
- [Module dependency register](module_dependency_register.md)