Variable Not Being Updated in RPC

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By atomicbeef
:warning: Old Version Published before Godot 3 was released.

Hello everyone,

I’m currently working on a networked game and I’m trying to make the client be able to get the current map name from the server. Here is the script in question:

extends Node

var player_name = ""
# Player information in the form of {id:name}
var players = {}
var dedicated = false

# Game states
enum {
WAITING_FOR_PLAYERS,
IN_PROGRESS,
OVER
}
var gamestate

# Minimum number of players required to start a round
const MIN_PLAYERS = 2

# Map string set by the server
var map_name
# The map node
var map

signal player_list_changed

func _ready():
   get_tree().connect("connected_to_server", self, "_player_connected_ok")

func join_game(ip, port):
   var host = NetworkedMultiplayerENet.new()
   var error = host.create_client(ip, port)
   if error != OK:
	   print(error)
	   print("Couldn't create client connecting to ", ip, " on port ", port, "!")
  else:
	   get_tree().set_network_peer(host)
	   print("Connecting to ", ip, " on port ", port)

func host_game(port, max_players, map_string):
  var host = NetworkedMultiplayerENet.new()
  var error = host.create_server(port, max_players)
  if error != OK:
	 print(error)
	 print("Couldn't create server on port ", port, "!")
	 return
	
  get_tree().set_network_peer(host)
  print("Created server on port ", port)

  map_name = map_string
  gamestate = WAITING_FOR_PLAYERS

  get_tree().get_root().get_node("main_menu").hide()
  instance_map(map_name)

  if not dedicated:
	  players[1] = player_name
	  instance_player(1)
	  print("Registered ", player_name, " as host")

  # Used to check if the server has enough clients to start a round
  connect("player_list_changed", self, "_check_round_start")

remote func get_map_name(id):
  assert(get_tree().is_network_server())

  rpc_id(id, "set_map_name", map_name)

remote func set_map_name(name):
  map_name = name

remote func get_gamestate(id):
  assert(get_tree().is_network_server())

  rpc_id(id, "set_gamestate", gamestate)

remote func set_gamestate(state):
  print(get_tree().get_network_unique_id())
  gamestate = state

remote func register_player(id, name):
  if get_tree().is_network_server():
	  # Send the host to the new player
	  rpc_id(id, "register_player", 1, name)
	  # Send all of the other players to the new player and vice versa
	  for player_id in players:
		  rpc_id(id, "register_player", player_id, players[player_id])
		  # Don't try to send the player to the host
		  if player_id != 1:
			  rpc_id(player_id, "register_player", id, name)

  players[id] = player_name
  instance_player(id)
  emit_signal("player_list_changed")
  print("Registered ", player_name, " with ID ", id, " succesfully")

func start_round():
  assert(get_tree().is_network_server())

  var spawn_points = map.get_node("spawn_points").get_children()

  for player_id in players:
	  get_tree().get_root().get_node("map/" + str(player_id)).set_pos(spawn_points[randi() % spawn_points.size() - 1].get_pos())

func instance_map(map_name):
  # Add the map
  map = load("res://scenes/" + map_name + ".tscn").instance()
  get_tree().get_root().add_child(map)
  map.set_name("map")

func instance_player(player_id):
  var player = load("res://scenes/player.tscn").instance()
  map.add_child(player)
  player.set_name(str(player_id))

  if player_id == get_tree().get_network_unique_id():
	  player.set_network_mode(NETWORK_MODE_MASTER)
	  get_tree().get_root().get_node("map/" + str(player_id) + "/camera").make_current()
  else:
	  player.set_network_mode(NETWORK_MODE_SLAVE)

func _check_round_start():
  assert(get_tree().is_network_server())

  if players.size() >= MIN_PLAYERS:
	  # No need to continue checking
	  disconnect("player_list_changed", self, "_check_round_start")
	  start_round()

func _player_connected_ok():
  get_tree().get_root().get_node("main_menu").hide()

  rpc_id(1, "get_map_name", get_tree().get_network_unique_id())
  rpc_id(1, "get_gamestate", get_tree().get_network_unique_id())

  print("Map name: ", map_name)

  instance_map(map_name)

  # Register the player
  rpc("register_player", get_tree().get_network_unique_id(), player_name)

Unfortunately, doing rpc_id(1, "get_map_name", get_tree().get_network_unique_id()) results in map_name not being updated for the client. I’m not exactly sure what’s wrong with this code, so I’d greatly appreciate it if someone could enlighten me.

:bust_in_silhouette: Reply From: atomicbeef

I’ve received an answer to this question on Reddit. It turns out that there was a race condition between the variable being updated and the instancing of the map.