补充输入重放

输入重放是指当收到一个服务器状态包时以那个包为初始状态,然后重新计算所有未确认的输入来得到当前帧的状态,然后再对当前角色的位置进行插值移动。服务器状态包只能给出前几帧的权威数据,而当前帧的状态则需要通过输入回放来得到
This commit is contained in:
SepComet
2026-04-08 10:33:42 +08:00
parent da2b93e59c
commit 75289b5690
29 changed files with 850 additions and 573 deletions
@@ -8,7 +8,7 @@ Define the contract that client-side replay of pending movement inputs after aut
### Requirement: Replay uses fixed-step accumulation matching server cadence
The controlled-client prediction replay path SHALL consume each pending `PredictedMoveStep` by applying its input in fixed-duration substeps equal to the server authoritative movement cadence, regardless of the step's total `SimulatedDurationSeconds`. **Forward prediction accumulation SHALL also use the same server authoritative movement cadence as the unit of accumulation, ensuring forward accumulated duration and replay duration are derived from the same cadence constant.** The replay accumulation shape MUST be identical to the live `FixedUpdate` prediction path for the same input values.
The controlled-client prediction replay path SHALL consume each pending `PredictedMoveStep` by applying its input in fixed-duration substeps equal to the server authoritative movement cadence, regardless of the step's total `SimulatedDurationSeconds`. Forward prediction accumulation SHALL also use the same server authoritative movement cadence as the unit of accumulation, and replaying a step MUST NOT remove that step from the pending-input buffer unless the server has acknowledged its tick. The replay accumulation shape MUST be identical to the live `FixedUpdate` prediction path for the same input values.
#### Scenario: Replay produces same trajectory as live prediction for steady input
- **WHEN** the client replays a `PredictedMoveStep` with turn=0, throttle=1, duration=0.15s using a 0.05s server cadence
@@ -25,12 +25,23 @@ The controlled-client prediction replay path SHALL consume each pending `Predict
- **THEN** the replay applies 0.05s + 0.05s + 0.02s substeps sequentially
- **THEN** no remaining duration is lost or double-counted
#### Scenario: Replay preserves unacknowledged inputs for later authoritative rebuilds
- **WHEN** the client replays pending inputs after accepting an authoritative state that acknowledges ticks through `N`
- **THEN** only steps with tick less than or equal to `N` are removed from the pending-input buffer
- **THEN** replayed steps with tick greater than `N` remain available for later replay against a newer authoritative baseline
- **THEN** the pending-input buffer still exposes those unacknowledged steps after replay completes
### Requirement: Replay trajectory determinism is verifiable
The client prediction system SHALL provide a deterministic way to verify that replay and live prediction produce identical trajectories for a given input sequence, enabling regression coverage.
The client prediction system SHALL provide a deterministic way to verify that replay and live prediction produce identical trajectories for a given input sequence, enabling regression coverage. The verification path MUST also support repeated authoritative rebuilds while the same unacknowledged input sequence remains pending.
#### Scenario: Replay and live prediction produce identical results
- **WHEN** a controlled client records a `MoveInput` sequence during live play
- **AND** the client triggers reconciliation and replays those same inputs
- **THEN** the final predicted pose after replay equals the predicted pose that would result from live FixedUpdate simulation for the same input sequence
- **THEN** the result is stable across multiple replays of the same input sequence
#### Scenario: Repeated rebuilds remain deterministic while inputs stay unacknowledged
- **WHEN** the controlled client accepts multiple increasing authoritative snapshots while the same later input ticks remain unacknowledged
- **THEN** replaying the remaining unacknowledged input sequence against each accepted baseline produces deterministic predicted results for that baseline
- **THEN** the test harness can verify replay correctness without requiring those inputs to be consumed from the buffer
@@ -0,0 +1,46 @@
# local-player-reconciliation Specification
## Purpose
Define how the local (controlled) player reconciles client-side prediction with server authoritative state. This capability ensures that when the client receives a server `PlayerState`, it treats that snapshot as the latest gameplay baseline, rebuilds local prediction from still-unacknowledged inputs, and smooths visible presentation toward the rebuilt predicted pose.
## Requirements
### Requirement: Reconcile applies authoritative state and replays unconfirmed inputs in correct order
The controlled-client reconciliation path SHALL treat a newly accepted authoritative `PlayerState` as the latest gameplay baseline, prune only pending movement inputs whose tick is less than or equal to `AcknowledgedMoveTick`, replay all still-unacknowledged pending inputs from that authoritative baseline using fixed-step substeps matching the server authoritative movement cadence, and publish the replay result as the controlled player's latest predicted simulation pose. Presentation smoothing MUST consume that rebuilt predicted pose as a target without redefining the gameplay truth of the replay result.
#### Scenario: Authoritative acceptance rebuilds prediction from the latest baseline
- **WHEN** the controlled player accepts an authoritative `PlayerState` whose acknowledged movement-input tick is `N`
- **THEN** the reconciliation treats the received authoritative position and rotation as the new gameplay baseline
- **THEN** the reconciliation replays all pending inputs with tick greater than `N` using 50ms fixed-step substeps
- **THEN** the replay result becomes the controlled player's latest predicted simulation pose for that authoritative update
- **THEN** the presentation layer receives that predicted pose as its smoothing target
#### Scenario: Repeated authoritative updates rebuild prediction without consuming pending inputs
- **WHEN** the controlled player accepts two increasing authoritative `PlayerState` snapshots before all pending inputs have been acknowledged
- **THEN** each accepted snapshot rebuilds the predicted simulation pose from its own authoritative baseline
- **THEN** only inputs acknowledged by the newer snapshot are pruned from the pending-input buffer
- **THEN** still-unacknowledged inputs remain available for replay against later authoritative snapshots
#### Scenario: Visible smoothing does not redefine rebuilt gameplay truth
- **WHEN** the controlled player has a rebuilt predicted simulation pose and a visible presentation pose that has not yet converged
- **THEN** gameplay logic continues to treat the rebuilt predicted pose as the latest client prediction truth
- **THEN** the visible pose may temporarily differ while smoothing converges
- **THEN** a large divergence may still hard-snap the visible pose directly to the rebuilt predicted pose
### Requirement: Bounded correction handles residual error after replay
The controlled-client reconciliation SHALL compare the controlled player's visible presentation pose against the rebuilt predicted simulation pose after replay, interpolate the visible pose toward that predicted pose for small residual error, and snap the visible pose directly to the predicted pose when divergence exceeds the configured snap threshold.
#### Scenario: Small residual error uses presentation interpolation
- **WHEN** the controlled player completes replay and the remaining distance between visible pose and rebuilt predicted pose is within the configured snap threshold
- **THEN** the client keeps the rebuilt predicted pose as presentation target
- **THEN** the visible pose converges toward that target through presentation smoothing across later frames
- **THEN** the replayed predicted pose remains unchanged as gameplay truth during that convergence
#### Scenario: Large divergence snaps visible pose to rebuilt predicted pose
- **WHEN** the controlled player completes replay and the remaining distance between visible pose and rebuilt predicted pose exceeds the configured snap threshold
- **THEN** the client snaps the visible position and rotation directly to the rebuilt predicted pose
- **THEN** any previous presentation-only smoothing state is cleared or replaced
- **THEN** later local prediction continues from the rebuilt predicted baseline