Skip to content

Commit

Permalink
Reduce number of rpc calls from client
Browse files Browse the repository at this point in the history
Old: client does an ack rpc every time it receives timeslots, so up
\ to 10 times per second
New: client bundles ack together into the ping rpc, so 1 time per second
Result: a bit less bandwidth usage in multiplayer, bigger benefit when
\ there are more than 2 players
  • Loading branch information
Kvel2D committed Nov 10, 2024
1 parent f40872e commit 57095f0
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 19 deletions.
10 changes: 7 additions & 3 deletions src/game_scene/game_client.gd
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ var _time_when_sent_ping: int = 0
var _ping_history: Array = [0]
var _received_any_timeslots: bool = false
var _paused_by_host: bool = false
var _last_received_timeslot_list: Array = []


@export var _game_host: GameHost
Expand Down Expand Up @@ -118,8 +119,7 @@ func receive_timeslots(timeslot_list: Dictionary):
for tick in timeslot_list.keys():
_timeslot_map[tick] = timeslot_list[tick]

var tick_list: Array = timeslot_list.keys()
_game_host.receive_timeslots_ack.rpc_id(1, tick_list)
_last_received_timeslot_list = timeslot_list.keys()


@rpc("authority", "call_local", "reliable")
Expand Down Expand Up @@ -363,6 +363,10 @@ func _get_ping_max() -> float:
### Callbacks ###
#########################

# Periodically send a ping from client to host. This ping is
# used to calculate ping time. It also includes a list of
# last received timeslots to ack receival of those timeslots
# and let the host know which timeslots it can stop sending.
func _on_ping_timer_timeout():
_time_when_sent_ping = Time.get_ticks_msec()
_game_host.receive_ping.rpc_id(1)
_game_host.receive_ping.rpc_id(1, _last_received_timeslot_list)
24 changes: 8 additions & 16 deletions src/game_scene/game_host.gd
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const TICK_DELTA: float = 1000 / 30.0
# player. If host hasn't received any responses from player
# for this long, host will start considering that player to
# be lagging and will pause game turns.
const LAG_TIME_MSEC: float = 2000.0
const LAG_TIME_MSEC: float = 3000.0

@export var _game_client: GameClient
@export var _hud: HUD
Expand Down Expand Up @@ -96,20 +96,6 @@ func _physics_process(_delta: float):
### Public ###
#########################

# When player ack's timeslots, host erases ack'd timeslots
# from queue and stops sending them.
@rpc("any_peer", "call_local", "reliable")
func receive_timeslots_ack(tick_list: Array):
var peer_id: int = multiplayer.get_remote_sender_id()
var player: Player = PlayerManager.get_player_by_peer_id(peer_id)
var player_id: int = player.get_id()

var timeslots_to_send: Dictionary = _player_timeslot_send_queue[player_id]

for tick in tick_list:
timeslots_to_send.erase(tick)


@rpc("any_peer", "call_local", "reliable")
func receive_alive_check_response():
var peer_id: int = multiplayer.get_remote_sender_id()
Expand Down Expand Up @@ -163,13 +149,19 @@ func receive_timeslot_checksum(tick: int, checksum: PackedByteArray):


@rpc("any_peer", "call_local", "reliable")
func receive_ping():
func receive_ping(last_received_timeslot_list: Array):
var peer_id: int = multiplayer.get_remote_sender_id()
var player: Player = PlayerManager.get_player_by_peer_id(peer_id)
var player_id: int = player.get_id()

_update_last_contact_time_for_player(player_id)

# When player ack's timeslots, host erases ack'd timeslots
# from queue and stops sending them.
var timeslots_to_send: Dictionary = _player_timeslot_send_queue[player_id]
for tick in last_received_timeslot_list:
timeslots_to_send.erase(tick)

_game_client.receive_pong.rpc_id(peer_id)


Expand Down

0 comments on commit 57095f0

Please sign in to comment.