This commit is contained in:
SepComet
2026-04-06 11:58:36 +08:00
parent b1b38b485e
commit aebc4011c7
84 changed files with 5796 additions and 238 deletions
@@ -0,0 +1,17 @@
## ADDED Requirements
### Requirement: Client prediction bootstraps from server-confirmed movement parameters
The client SHALL establish controlled-player prediction parameters from server-confirmed authoritative movement settings before treating local prediction as steady-state truth. Client-local candidate values MAY exist before login succeeds, but long-lived prediction MUST switch to the server-confirmed parameters for the controlled player.
#### Scenario: Login success provides authoritative movement parameters for prediction
- **WHEN** the controlled client completes login and receives the server-confirmed movement bootstrap data
- **THEN** the client stores the authoritative movement parameters for that controlled player
- **THEN** subsequent local movement prediction uses those server-confirmed parameters instead of continuing to rely on an unrelated local UI value
### Requirement: Server-owned movement parameters remain the single gameplay authority
The server SHALL keep authoritative ownership of movement tuning used for authoritative movement resolution, and any client-visible movement parameters used for prediction MUST be derived from that server-owned configuration rather than from an independent client-only truth source.
#### Scenario: Client candidate speed does not override server movement authority
- **WHEN** a client proposes or locally configures a movement speed that differs from the server-owned movement speed
- **THEN** the server-owned movement configuration remains authoritative for gameplay resolution
- **THEN** the client's steady-state prediction parameters converge to the server-confirmed value instead of preserving the divergent local candidate
@@ -0,0 +1,11 @@
## MODIFIED Requirements
### Requirement: Local player reconciliation applies the full authoritative state by tick
The controlled client SHALL continue reconciling local prediction from authoritative `PlayerState` updates, but it MUST distinguish between the authoritative snapshot tick and the acknowledged movement-input tick carried by that snapshot. Reconciliation MUST use the acknowledged movement-input tick to prune and replay predicted movement, while continuing to apply the accepted authoritative `position` and `rotation` and keeping authoritative HP and optional velocity synchronized with the owned player-state snapshot.
#### Scenario: Local authoritative state corrects predicted presentation
- **WHEN** the controlled player accepts an authoritative `PlayerState` snapshot with snapshot tick `S` and acknowledged movement-input tick `N`
- **THEN** local reconciliation prunes or replays predicted movement using acknowledged tick `N` according to the sync strategy
- **THEN** stale rejection or snapshot ordering for authoritative state continues to use snapshot tick `S`
- **THEN** the local player's visible transform is corrected toward authoritative `position` and `rotation`
- **THEN** the local player's authoritative HP on the client matches the accepted `PlayerState`
@@ -0,0 +1,11 @@
## MODIFIED Requirements
### Requirement: Gameplay-flow regressions include a fake-transport authoritative round trip
The edit-mode regression suite SHALL include at least one deterministic fake-transport test that spans client send behavior, server-authoritative processing, and outgoing authoritative results. That round-trip regression MUST cover `MoveInput -> PlayerState` and `ShootInput -> CombatEvent` within the same MVP gameplay-flow suite. Movement round-trip coverage MUST also prove that authoritative `PlayerState` snapshots preserve a distinct snapshot tick and acknowledged movement-input tick, and that controlled-client prediction bootstraps from server-confirmed movement parameters rather than a divergent local-only value.
#### Scenario: Fake-transport round trip preserves server authority across movement and combat
- **WHEN** an edit-mode regression test drives gameplay input through fake client/server transports and advances the server authority loop
- **THEN** the authoritative server path emits `PlayerState` snapshots in response to movement input
- **THEN** the authoritative server path emits `CombatEvent` results in response to shooting input
- **THEN** the movement assertions prove snapshot ordering and acknowledged-input reconciliation use distinct `PlayerState` fields
- **THEN** the combined test protects both client single-session input flow and server multi-session authoritative behavior from regression
@@ -0,0 +1,24 @@
## MODIFIED Requirements
### Requirement: Gameplay messages expose explicit MVP payload fields
The shared networking contract SHALL define the MVP payload fields for gameplay messages explicitly in the source protobuf schema and generated C# messages. `MoveInput` MUST expose `playerId`, `tick`, `moveX`, and `moveY`; `ShootInput` MUST expose `playerId`, `tick`, `dirX`, `dirY`, and an optional `targetId`; `PlayerState` MUST expose `playerId`, `tick`, `acknowledgedMoveTick`, `position`, `rotation`, `hp`, and an optional `velocity`; `CombatEvent` MUST expose `tick`, `eventType`, `attackerId`, `targetId`, `damage`, and an optional `hitPosition`. The shared contract MUST also provide `CombatEventType` so combat results use explicit event categories rather than ad hoc integer payload conventions.
#### Scenario: Movement input carries explicit movement fields
- **WHEN** client or server code constructs or parses `MoveInput`
- **THEN** the message exposes `playerId`, `tick`, `moveX`, and `moveY`
- **THEN** movement intent does not rely on an overloaded payload extension
#### Scenario: Shooting input carries explicit aim fields
- **WHEN** client or server code constructs or parses `ShootInput`
- **THEN** the message exposes `playerId`, `tick`, `dirX`, `dirY`, and `targetId`
- **THEN** shooting direction and optional target selection are represented directly in the message contract
#### Scenario: Authoritative player state carries explicit gameplay state fields
- **WHEN** client or server code constructs or parses `PlayerState`
- **THEN** the message exposes `playerId`, `tick`, `acknowledgedMoveTick`, `position`, `rotation`, `hp`, and `velocity`
- **THEN** snapshot ordering and acknowledged-input reconciliation are both expressed without ad hoc payload extensions or overloaded tick semantics
#### Scenario: Combat events carry explicit result fields and event categories
- **WHEN** client or server code constructs or parses `CombatEvent`
- **THEN** the message exposes `tick`, `eventType`, `attackerId`, `targetId`, `damage`, and `hitPosition`
- **THEN** `CombatEventType` provides explicit combat-result categories for interpreting that event payload
@@ -0,0 +1,10 @@
## MODIFIED Requirements
### Requirement: Authoritative correction prunes acknowledged prediction history
The client sync strategy SHALL reconcile local prediction against authoritative player-state updates by pruning acknowledged movement inputs at or before the acknowledged movement-input tick carried by the authoritative snapshot and only reapplying newer pending `MoveInput` messages. The snapshot tick used for stale rejection or remote interpolation MUST NOT be reused as the local prediction-acknowledgement boundary.
#### Scenario: Reconciliation removes already acknowledged movement inputs
- **WHEN** the client accepts an authoritative `PlayerState` update whose acknowledged movement-input tick is `N`
- **THEN** locally buffered predicted `MoveInput` messages with tick less than or equal to `N` are removed from the replay buffer
- **THEN** only `MoveInput` messages newer than `N` remain eligible for re-simulation
- **THEN** the client does not infer the acknowledgement boundary solely from the snapshot tick
@@ -0,0 +1,19 @@
## MODIFIED Requirements
### Requirement: Server broadcasts authoritative `PlayerState` snapshots on the sync cadence
The shared server networking path SHALL emit authoritative `PlayerState` snapshots for managed peers at a fixed cadence using the existing sync-lane message contract. Each snapshot MUST be derived from the server-owned authoritative player state and include both the authoritative snapshot tick for client stale rejection or interpolation and the last acknowledged `MoveInput.Tick` for client reconciliation. Authoritative HP changes produced by server-side combat resolution MUST be reflected in later snapshots for the affected peer.
#### Scenario: Authority update step emits sync-lane player snapshots
- **WHEN** the server reaches a configured authority broadcast cadence while one or more managed peers have authoritative player state
- **THEN** it sends `PlayerState` snapshots using the sync-lane delivery policy when a distinct sync transport exists
- **THEN** each snapshot includes the authoritative position, rotation, velocity, HP, snapshot tick, and acknowledged movement-input tick from server-owned state
#### Scenario: Combat-driven HP changes appear in later player snapshots
- **WHEN** the server applies authoritative combat damage or death to a managed peer
- **THEN** later `PlayerState` snapshots for that peer carry the updated authoritative HP value
- **THEN** clients do not need to invent or persist a separate HP truth outside authoritative server snapshots
#### Scenario: Reliable transport remains fallback when no sync transport exists
- **WHEN** the server broadcasts authoritative `PlayerState` snapshots without a dedicated sync transport
- **THEN** the shared routing path still emits `PlayerState` through the existing fallback lane behavior
- **THEN** the authoritative snapshot contract remains unchanged