Improve multiplayer movement reconciliation
This commit is contained in:
parent
348ae261e1
commit
a3aea98982
3 changed files with 240 additions and 89 deletions
|
|
@ -13,6 +13,7 @@ const ENET_TIMEOUT_MAXIMUM_MS: int = 120000
|
|||
const INPUT_INTERVAL: float = 1.0 / 30.0
|
||||
const IDLE_INPUT_INTERVAL: float = 1.0 / 5.0
|
||||
const SNAPSHOT_INTERVAL: float = 1.0 / 30.0
|
||||
const OWNER_SNAPSHOT_DIVISOR: int = 3
|
||||
const NEAR_REMOTE_SNAPSHOT_DIVISOR: int = 2
|
||||
const FAR_REMOTE_SNAPSHOT_DIVISOR: int = 6
|
||||
const DISTANT_REMOTE_SNAPSHOT_DIVISOR: int = 8
|
||||
|
|
@ -122,6 +123,7 @@ var _last_input_state_hash: int = 0
|
|||
var _pending_movement_inputs: Array[Dictionary] = []
|
||||
var _snapshot_accumulator: float = 0.0
|
||||
var _movement_snapshot_tick: int = 0
|
||||
var _last_local_snapshot_received_msec: int = 0
|
||||
var _animation_refresh_accumulator: float = 0.0
|
||||
var _last_animation_state_by_peer: Dictionary[int, Dictionary] = {}
|
||||
var _pending_animation_state_by_peer: Dictionary[int, Dictionary] = {}
|
||||
|
|
@ -2248,13 +2250,16 @@ func _broadcast_movement_snapshots() -> void:
|
|||
var subject_avatar: Player = _spawn_service.get_avatar(subject_id)
|
||||
if subject_avatar == null:
|
||||
continue
|
||||
if (
|
||||
subject_id != recipient_id
|
||||
and not _should_send_remote_snapshot(
|
||||
if subject_id == recipient_id:
|
||||
# The owner already simulates locally. Its authoritative state is
|
||||
# an audit and acknowledgement, not a presentation stream, so it
|
||||
# does not need the full 30 Hz observer snapshot rate.
|
||||
if _movement_snapshot_tick % OWNER_SNAPSHOT_DIVISOR != 0:
|
||||
continue
|
||||
elif not _should_send_remote_snapshot(
|
||||
recipient_avatar.global_position,
|
||||
subject_avatar.global_position,
|
||||
)
|
||||
):
|
||||
):
|
||||
continue
|
||||
var encoded: Array = _encode_movement_snapshot(
|
||||
subject_avatar.make_network_snapshot(subject_id)
|
||||
|
|
@ -2538,8 +2543,10 @@ func receive_movement_snapshots(encoded_snapshots: Array) -> void:
|
|||
)
|
||||
avatar.apply_local_prediction_correction(
|
||||
snapshot,
|
||||
_pending_movement_inputs,
|
||||
_input_sequence,
|
||||
INPUT_INTERVAL,
|
||||
estimated_transit_seconds,
|
||||
_local_snapshot_delta_seconds(),
|
||||
)
|
||||
else:
|
||||
avatar.push_network_snapshot(
|
||||
|
|
@ -2557,6 +2564,20 @@ func _discard_acknowledged_movement_inputs(acknowledged_sequence: int) -> void:
|
|||
_pending_movement_inputs.pop_front()
|
||||
|
||||
|
||||
func _local_snapshot_delta_seconds() -> float:
|
||||
var now_msec: int = Time.get_ticks_msec()
|
||||
if _last_local_snapshot_received_msec <= 0:
|
||||
_last_local_snapshot_received_msec = now_msec
|
||||
return 0.0
|
||||
var elapsed_seconds: float = clampf(
|
||||
float(now_msec - _last_local_snapshot_received_msec) / 1000.0,
|
||||
0.0,
|
||||
Player.LOCAL_PREDICTION_MAX_AUDIT_DELTA_SECONDS,
|
||||
)
|
||||
_last_local_snapshot_received_msec = now_msec
|
||||
return elapsed_seconds
|
||||
|
||||
|
||||
@rpc(
|
||||
"authority",
|
||||
"call_remote",
|
||||
|
|
@ -2861,6 +2882,7 @@ func _teardown_peer() -> void:
|
|||
_pending_movement_inputs.clear()
|
||||
_snapshot_accumulator = 0.0
|
||||
_movement_snapshot_tick = 0
|
||||
_last_local_snapshot_received_msec = 0
|
||||
_animation_refresh_accumulator = 0.0
|
||||
_last_animation_state_by_peer.clear()
|
||||
_pending_animation_state_by_peer.clear()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue