Add transactional RV decor synchronization
This commit is contained in:
parent
ee992d9f0c
commit
6578d3e870
7 changed files with 663 additions and 48 deletions
|
|
@ -28,6 +28,7 @@ const MAX_PENDING_MOVEMENT_INPUTS: int = 96
|
|||
const ANIMATION_REFRESH_INTERVAL: float = 1.0
|
||||
const MAX_MOVEMENT_INPUT_SEQUENCE: int = 2147483647
|
||||
const MAX_MOVEMENT_ONE_WAY_TRANSIT_SECONDS: float = 0.25
|
||||
const SPACE_TRANSITION_SNAPSHOT_GUARD_DISTANCE: float = 12.0
|
||||
|
||||
const MOVEMENT_FLAG_JUMP: int = 1 << 0
|
||||
const MOVEMENT_FLAG_SPRINT: int = 1 << 1
|
||||
|
|
@ -124,6 +125,9 @@ 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 _local_space_transition_guard_active: bool = false
|
||||
var _local_space_transition_guard_position: Vector3 = Vector3.ZERO
|
||||
var _local_space_transition_minimum_ack: 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] = {}
|
||||
|
|
@ -703,6 +707,40 @@ func peers_share_space(first_peer_id: int, second_peer_id: int) -> bool:
|
|||
return get_peer_space(first_peer_id) == get_peer_space(second_peer_id)
|
||||
|
||||
|
||||
func apply_authoritative_space_transition(
|
||||
peer_id: int,
|
||||
target_transform: Transform3D,
|
||||
acknowledged_input: int,
|
||||
) -> bool:
|
||||
if not target_transform.origin.is_finite():
|
||||
return false
|
||||
var local_peer_id: int = get_local_peer_id()
|
||||
var local_transition: bool = peer_id == local_peer_id
|
||||
var avatar: Player = _spawn_service.get_avatar(peer_id)
|
||||
# Remote home transitions can arrive before their player-spawn message. Keep
|
||||
# the new space assignment so the later spawn inherits correct visibility;
|
||||
# only a missing local avatar is a transition failure.
|
||||
if avatar == null:
|
||||
return not local_transition
|
||||
avatar.apply_network_space_transition(target_transform, local_transition)
|
||||
if (
|
||||
local_transition
|
||||
and state == State.JOINED_CLIENT
|
||||
):
|
||||
# Movement snapshots use another ENet channel and a pre-transition audit
|
||||
# can therefore arrive after the reliable home transition. Clear local
|
||||
# prediction and reject those old-world snapshots until the host publishes
|
||||
# its first audit from the new space.
|
||||
_pending_movement_inputs.clear()
|
||||
_last_local_snapshot_received_msec = 0
|
||||
_last_input_state_hash = 0
|
||||
_idle_input_accumulator = IDLE_INPUT_INTERVAL
|
||||
_local_space_transition_guard_active = true
|
||||
_local_space_transition_guard_position = target_transform.origin
|
||||
_local_space_transition_minimum_ack = maxi(acknowledged_input, 0)
|
||||
return true
|
||||
|
||||
|
||||
func get_peer_rtt_ms(peer_id: int) -> int:
|
||||
if peer_id == 1:
|
||||
return 0
|
||||
|
|
@ -2569,6 +2607,8 @@ func receive_movement_snapshots(encoded_snapshots: Array) -> void:
|
|||
if avatar == null:
|
||||
continue
|
||||
if peer_id == local_peer_id:
|
||||
if _reject_stale_space_transition_snapshot(snapshot):
|
||||
continue
|
||||
_discard_acknowledged_movement_inputs(
|
||||
int(snapshot.get("acknowledged_input", 0))
|
||||
)
|
||||
|
|
@ -2586,6 +2626,33 @@ func receive_movement_snapshots(encoded_snapshots: Array) -> void:
|
|||
)
|
||||
|
||||
|
||||
func _reject_stale_space_transition_snapshot(snapshot: Dictionary) -> bool:
|
||||
if not _local_space_transition_guard_active:
|
||||
return false
|
||||
var position_values: Array = snapshot.get("position", [])
|
||||
if position_values.size() != 3:
|
||||
return true
|
||||
var position := Vector3(
|
||||
float(position_values[0]),
|
||||
float(position_values[1]),
|
||||
float(position_values[2]),
|
||||
)
|
||||
var acknowledged_input: int = int(
|
||||
snapshot.get("acknowledged_input", 0)
|
||||
)
|
||||
if acknowledged_input < _local_space_transition_minimum_ack:
|
||||
return true
|
||||
if acknowledged_input > _local_space_transition_minimum_ack:
|
||||
_local_space_transition_guard_active = false
|
||||
return false
|
||||
if position.distance_to(_local_space_transition_guard_position) > (
|
||||
SPACE_TRANSITION_SNAPSHOT_GUARD_DISTANCE
|
||||
):
|
||||
return true
|
||||
_local_space_transition_guard_active = false
|
||||
return false
|
||||
|
||||
|
||||
func _discard_acknowledged_movement_inputs(acknowledged_sequence: int) -> void:
|
||||
while (
|
||||
not _pending_movement_inputs.is_empty()
|
||||
|
|
@ -2914,6 +2981,9 @@ func _teardown_peer() -> void:
|
|||
_snapshot_accumulator = 0.0
|
||||
_movement_snapshot_tick = 0
|
||||
_last_local_snapshot_received_msec = 0
|
||||
_local_space_transition_guard_active = false
|
||||
_local_space_transition_guard_position = Vector3.ZERO
|
||||
_local_space_transition_minimum_ack = 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