0 votes

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.

in Engine by (19 points)
edited by

1 Answer

0 votes
Best answer

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.

by (19 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.