Constantly Looping When a Second Instance Joins: on_sync_receive: Ignoring sync data from non-authority or for missing node

Godot Version

4.6.1 stable

Question

i’ve started working on multiplayer for my game, but i’m now getting this error sent on both sessions every frame once the second person joins. nothing gets synced, and it looks like it at least seems to recognize who should be controlling what player object at this point, but like i said, nothing actually syncs. i’ve tried searching for answers, but everything is relating to quitting, so it doesn’t show the same way for others. i’ve made sure i’m not changing any values on an object the session doesn’t have access to, and i’m not deleting any nodes, so i’m EXTREMELY confused right now

here’s some relevant code:

– multiplayer_spawner.gd

extends MultiplayerSpawner
class_name MultiSpawner

const PLR_SCN = preload("res://nodes/player.tscn")
var player_container

func spawn_player(plr_dat: Dictionary, id: int):
	var new_plr = PLR_SCN.instantiate()
	new_plr.peer_id = id
	player_container.add_child(new_plr)
	new_plr.load_from_data(plr_dat, multiplayer.is_server())

– game_manager.gd (excerpt)

#region Multiplayer
func find_player(peer_id: int) -> Player:
	for p in players:
		if peer_id == p.peer_id:
			return p
	return null

func init_multiplayer():
	spawner.player_container = player_container
	multiplayer.peer_connected.connect(player_connected)
	multiplayer.peer_disconnected.connect(player_disconnected)
	multiplayer.connected_to_server.connect(connect_success)
	multiplayer.connection_failed.connect(connect_fail)
	multiplayer.server_disconnected.connect(server_disconnected)

func start_hosting():
	server_open = true
	var peer = ENetMultiplayerPeer.new()
	peer.create_server(multiplayer_port, 4)
	multiplayer.multiplayer_peer = peer
	
	print("server started on port " + str(multiplayer_port) + "!")

func stop_hosting():
	server_open = false
	multiplayer.multiplayer_peer = OfflineMultiplayerPeer.new()
	for p in players:
		if p != local_player:
			# TODO: SAVING
			
			p.queue_free()
			players.erase(p)

func player_connected(id: int):
	print("connection to " + str(multiplayer.get_unique_id()) + "! peer_id: " + str(id))
	# TODO: LOADING
	
	var new_player_data = {
		"name": "CLIENT_PLAYER", 
		"load_map": current_map_path,
		"tp_id": last_teleport_id
	}
	spawner.spawn_player(new_player_data, id)

func player_disconnected(id: int):
	print("peer_id " + str(id) + " disconnected!")
	var plr = find_player(id)
	if plr:
		plr.queue_free()
		players.erase(plr)

func connect_success():
	var id = multiplayer.get_unique_id()
	print("connect success! my id is: " + str(id))
	local_player.peer_id = id
	local_player.set_multiplayer_authority(id)

func connect_fail():
	print("connect fail!")
	leave_game()

func server_disconnected():
	print("server disconnected!")
	leave_game()

func join_game(address: String = "localhost"):
	var peer = ENetMultiplayerPeer.new()
	var err = peer.create_client(address, multiplayer_port)
	if err:
		print("ERROR CREATING CLIENT: " + str(err))
		return
	multiplayer.multiplayer_peer = peer

func leave_game():
	multiplayer.multiplayer_peer = OfflineMultiplayerPeer.new()
	players.clear()
	SceneManager._load_scene("res://scenes/title_screen.tscn")

func kick_peer(id: int):
	if multiplayer.is_server() and id != 1:
		get_tree().network_peer.disconnect_peer(id)

@rpc("any_peer")
func authorize(id: int, password: String):
	print("peer_id " + str(id) + " wants to authorize with password '" + password + "'")
	if multiplayer.is_server():
		if password == multiplayer_password or multiplayer_password == "":
			var plr = find_player(id)
			plr.authorized = true
		else:
			kick_peer(id)
#endregion

– player.gd (excerpt)

func _ready():
	update_multiplayer_authority()
	if is_multiplayer_authority():
		Input.mouse_mode = Input.MOUSE_MODE_CAPTURED

func update_multiplayer_authority():
	set_multiplayer_authority(peer_id)
	if is_multiplayer_authority():
		#Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
		full_model.visible = false
		body_model.visible = true
		shadow_model.visible = true
		head.visible = true
		use_crosshair.visible = false
		calc_weight()
	else:
		full_model.visible = true
		body_model.visible = false
		shadow_model.visible = false
		use_crosshair.visible = false
		head.visible = false
# [...]
func _physics_process(delta: float) -> void:
	if not is_multiplayer_authority():
		return
# [...]

@rpc("any_peer", "call_local")
func load_from_data(data: Dictionary, from_server: bool):
	player_name = data["name"]
	if from_server and is_multiplayer_authority():
		if data["load_map"]:
			GameManager.game_man.local_player = self
			GameManager.game_man.load_map(data["load_map"], data["tp_id"])