feat: advance paused action snapshots to protocol v7
This commit is contained in:
parent
4c55fb6a15
commit
ad1af31492
6 changed files with 71 additions and 15 deletions
|
|
@ -1,7 +1,7 @@
|
|||
class_name NetworkProtocol
|
||||
extends RefCounted
|
||||
|
||||
const PROTOCOL_VERSION: int = 6
|
||||
const PROTOCOL_VERSION: int = 7
|
||||
const GAME_BUILD: String = "prealpha"
|
||||
const MAX_GAME_VERSION_LENGTH: int = 64
|
||||
const MAX_DISPLAY_NAME_LENGTH: int = 24
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ const AUTHENTICATION_TIMEOUT_SECONDS: float = 60.0
|
|||
const INPUT_INTERVAL: float = 1.0 / 30.0
|
||||
const SNAPSHOT_INTERVAL: float = 1.0 / 30.0
|
||||
const MOVEMENT_SNAPSHOT_BATCH_SIZE: int = 8
|
||||
const MOVEMENT_SNAPSHOT_FIELD_COUNT: int = 12
|
||||
const MOVEMENT_SNAPSHOT_FIELD_COUNT: int = 13
|
||||
const MAX_MOVEMENT_INPUT_SEQUENCE: int = 2147483647
|
||||
const MAX_MOVEMENT_ONE_WAY_TRANSIT_SECONDS: float = 0.25
|
||||
|
||||
|
|
@ -1837,6 +1837,7 @@ static func _encode_movement_snapshot(snapshot: Dictionary) -> Array:
|
|||
str(action["id"]),
|
||||
int(action["sequence"]),
|
||||
float(action["elapsed"]),
|
||||
bool(action.get("paused", false)),
|
||||
bool(snapshot.get("sitting", false)),
|
||||
bool(snapshot.get("casting", false)),
|
||||
]
|
||||
|
|
@ -1860,6 +1861,7 @@ static func _decode_movement_snapshot(value: Variant) -> Dictionary:
|
|||
or typeof(fields[9]) not in [TYPE_FLOAT, TYPE_INT]
|
||||
or typeof(fields[10]) != TYPE_BOOL
|
||||
or typeof(fields[11]) != TYPE_BOOL
|
||||
or typeof(fields[12]) != TYPE_BOOL
|
||||
):
|
||||
return {}
|
||||
var position: Vector3 = fields[2]
|
||||
|
|
@ -1880,9 +1882,10 @@ static func _decode_movement_snapshot(value: Variant) -> Dictionary:
|
|||
StringName(str(fields[7])),
|
||||
int(fields[8]),
|
||||
float(fields[9]),
|
||||
bool(fields[10]),
|
||||
),
|
||||
"sitting": bool(fields[10]),
|
||||
"casting": bool(fields[11]),
|
||||
"sitting": bool(fields[11]),
|
||||
"casting": bool(fields[12]),
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ func _run() -> void:
|
|||
var invalid_state: Dictionary = valid_state.duplicate(true)
|
||||
invalid_state["display_scale"] = 1000.0
|
||||
assert(not NetworkFishShowcaseProtocol.validate_state(invalid_state))
|
||||
assert(NetworkProtocol.PROTOCOL_VERSION == 6)
|
||||
assert(NetworkProtocol.PROTOCOL_VERSION == 7)
|
||||
assert(NetworkProtocol.ENET_CHANNEL_COUNT == 10)
|
||||
assert(
|
||||
NetworkProtocol.FISH_QUALITY_CAPABILITY
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ func _run() -> void:
|
|||
_validate_mail_round_trip()
|
||||
_validate_collection_mastery()
|
||||
_validate_version_four_migration()
|
||||
assert(NetworkProtocol.PROTOCOL_VERSION == 6)
|
||||
assert(NetworkProtocol.PROTOCOL_VERSION == 7)
|
||||
assert(NetworkProtocol.ENET_CHANNEL_COUNT == 10)
|
||||
assert(NetworkProtocol.FISH_QUALITY_CAPABILITY == "fish_quality_v1")
|
||||
print("Fish quality validation: PASS")
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ extends SceneTree
|
|||
|
||||
const MainScene: PackedScene = preload("res://main/main.tscn")
|
||||
const PlayerScene: PackedScene = preload("res://player/player.tscn")
|
||||
const TEST_PORT: int = 18141
|
||||
const TEST_PORT: int = 18171
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
|
|
@ -59,6 +59,26 @@ func _validate_compact_snapshot_encoding() -> void:
|
|||
encoded_snapshots[0]
|
||||
) == moving_snapshot
|
||||
)
|
||||
var paused_snapshot: Dictionary = moving_snapshot.duplicate(true)
|
||||
paused_snapshot["animation_state"] = (
|
||||
NetworkPlayerAnimationProtocol.make_state(
|
||||
NetworkPlayerAnimationProtocol.LOCOMOTION_IDLE,
|
||||
true,
|
||||
&"strike",
|
||||
7,
|
||||
0.5,
|
||||
true,
|
||||
)
|
||||
)
|
||||
var paused_encoded: Array = NetworkSession._encode_movement_snapshot(
|
||||
paused_snapshot
|
||||
)
|
||||
assert(paused_encoded.size() == NetworkSession.MOVEMENT_SNAPSHOT_FIELD_COUNT)
|
||||
var paused_decoded: Dictionary = (
|
||||
NetworkSession._decode_movement_snapshot(paused_encoded)
|
||||
)
|
||||
assert(not paused_decoded.is_empty())
|
||||
assert(bool(paused_decoded["animation_state"]["action"]["paused"]))
|
||||
|
||||
|
||||
func _validate_transit_estimation() -> void:
|
||||
|
|
@ -235,6 +255,10 @@ func _run_host() -> void:
|
|||
assert(session.set_host_open(true))
|
||||
var remote_peer_id: int = await _wait_for_remote_peer(session)
|
||||
assert(remote_peer_id > 1)
|
||||
# Authentication completes before the client has necessarily created and
|
||||
# begun observing the host avatar. Give its gameplay scene a bounded moment
|
||||
# to settle before emitting the one-shot locomotion/action sequence.
|
||||
await create_timer(1.0).timeout
|
||||
var player := main.get("_player") as Player
|
||||
player.configure_network_remote(true)
|
||||
player.apply_authoritative_network_input(_movement_input(1, true))
|
||||
|
|
@ -254,9 +278,9 @@ func _run_host() -> void:
|
|||
)
|
||||
await create_timer(1.0).timeout
|
||||
player.apply_authoritative_network_input(
|
||||
_movement_input(6, false, false, true, &"strike", 2)
|
||||
_movement_input(6, false, false, true, &"strike", 2, true)
|
||||
)
|
||||
await create_timer(0.5).timeout
|
||||
await create_timer(2.0).timeout
|
||||
player.apply_authoritative_network_input(
|
||||
_movement_input(7, false, false, false, &"", 3)
|
||||
)
|
||||
|
|
@ -294,7 +318,7 @@ func _run_client() -> void:
|
|||
var spawn_service := main.get_node(
|
||||
"%PlayerSpawnService"
|
||||
) as PlayerSpawnService
|
||||
var host_avatar: Player = spawn_service.get_avatar(1)
|
||||
var host_avatar: Player = await _wait_for_avatar(spawn_service, 1)
|
||||
assert(host_avatar != null)
|
||||
var animation_player := host_avatar.get_node(
|
||||
"Visuals/CharacterRig/AnimationPlayer"
|
||||
|
|
@ -306,11 +330,12 @@ func _run_client() -> void:
|
|||
var saw_idle_sneak: bool = false
|
||||
var saw_net_draw: bool = false
|
||||
var saw_net_strike: bool = false
|
||||
var saw_net_strike_paused: bool = false
|
||||
var saw_animation_advance: bool = false
|
||||
var saw_dust: bool = false
|
||||
var previous_animation: StringName = &""
|
||||
var previous_animation_position: float = -1.0
|
||||
var observation_deadline: int = Time.get_ticks_msec() + 14000
|
||||
var observation_deadline: int = Time.get_ticks_msec() + 18000
|
||||
while Time.get_ticks_msec() < observation_deadline:
|
||||
await process_frame
|
||||
var current_animation: StringName = animation_player.current_animation
|
||||
|
|
@ -319,7 +344,17 @@ func _run_client() -> void:
|
|||
saw_sneaking = saw_sneaking or current_animation == &"sneaking"
|
||||
saw_idle_sneak = saw_idle_sneak or current_animation == &"idle_sneak"
|
||||
saw_net_draw = saw_net_draw or current_animation == &"draw"
|
||||
saw_net_strike = saw_net_strike or current_animation == &"strike"
|
||||
saw_net_strike = (
|
||||
saw_net_strike
|
||||
or current_animation == &"strike"
|
||||
or animation_player.assigned_animation == &"strike"
|
||||
)
|
||||
saw_net_strike_paused = (
|
||||
saw_net_strike_paused
|
||||
or bool(host_avatar.get(
|
||||
"_network_target_animation_action_paused"
|
||||
))
|
||||
)
|
||||
var current_position: float = (
|
||||
animation_player.current_animation_position
|
||||
)
|
||||
|
|
@ -339,16 +374,18 @@ func _run_client() -> void:
|
|||
and saw_idle_sneak
|
||||
and saw_net_draw
|
||||
and saw_net_strike
|
||||
and saw_net_strike_paused
|
||||
and saw_animation_advance
|
||||
and saw_dust
|
||||
):
|
||||
break
|
||||
):
|
||||
break
|
||||
assert(saw_running)
|
||||
assert(saw_walking)
|
||||
assert(saw_sneaking)
|
||||
assert(saw_idle_sneak)
|
||||
assert(saw_net_draw)
|
||||
assert(saw_net_strike)
|
||||
assert(saw_net_strike_paused)
|
||||
assert(saw_animation_advance)
|
||||
assert(saw_dust)
|
||||
print("Movement multiplayer client validation: PASS")
|
||||
|
|
@ -367,6 +404,7 @@ func _movement_input(
|
|||
sneaking: bool = false,
|
||||
action_id: StringName = &"",
|
||||
action_sequence: int = 0,
|
||||
action_paused: bool = false,
|
||||
) -> Dictionary:
|
||||
return {
|
||||
"sequence": sequence,
|
||||
|
|
@ -381,6 +419,8 @@ func _movement_input(
|
|||
"animation_action": NetworkPlayerAnimationProtocol.make_action_state(
|
||||
action_id,
|
||||
action_sequence,
|
||||
0.0,
|
||||
action_paused,
|
||||
),
|
||||
}
|
||||
|
||||
|
|
@ -407,3 +447,16 @@ func _wait_for_remote_peer(session: NetworkSession) -> int:
|
|||
if peer_id != session.get_local_peer_id():
|
||||
return peer_id
|
||||
return 0
|
||||
|
||||
|
||||
func _wait_for_avatar(
|
||||
spawn_service: PlayerSpawnService,
|
||||
peer_id: int,
|
||||
) -> Player:
|
||||
var deadline: int = Time.get_ticks_msec() + 8000
|
||||
while Time.get_ticks_msec() < deadline:
|
||||
await process_frame
|
||||
var avatar := spawn_service.get_avatar(peer_id) as Player
|
||||
if avatar != null:
|
||||
return avatar
|
||||
return null
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ const NET_STRIKE_MARKER_DISTANCE: float = 0.85
|
|||
|
||||
|
||||
func _initialize() -> void:
|
||||
assert(NetworkProtocol.PROTOCOL_VERSION == 6)
|
||||
assert(NetworkProtocol.PROTOCOL_VERSION == 7)
|
||||
assert(
|
||||
NetworkWorldSpawnProtocol.CAPABILITY
|
||||
== NetworkProtocol.WORLD_SPAWN_CAPABILITY
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue