Players spawning only on host and can only be controlled by host.

Godot Version

Godot 4.3

Question

The players are only spawning on the host window and can only be controlled by host in my multiplayer game. (This is a starter kit that I’m trying to make multiplayer)

Host doesn’t have any errors, but client does, here is the error:

_send_sync: Condition “!sync || !sync->get_replication_config_ptr() || !_has_authority(sync)” is true. Continuing.

My full project code is here: GitHub - bladeclickers/faith-in-action-src

Your link is broken, here is a working one

It looks like you have two scripts for level one. Level_01.gd
And
level_01s.gd

The “s” version has code to add players and is attached to the level one scene but it does not setup the peer. Level_01.gd has the packet peer setup code but it isn’t used. (It also doesn’t have add player code)

Level_01s.gd needs to create a enet packet peer for server and client.

That’s the old script, now the ENet packet peer is created in the default scene (mp.tscn)'s script (control.gd) because the buttons and text broke in the 2D game scene.

Also, now the client doesn’t spawn on the host scene at all.

One, you should create a spawner for loading the level. This will tell the client what level to load. (currently it loads the first level manually and spawns player. this potentially is causing a race condition. I wonder if you are getting get_path errors on the client)

@rpc("call_local")
func _on_connected():
	var players = multiplayer.get_peers()
	
	if multiplayer.is_server():
		add_player(multiplayer.get_unique_id())
		for peer in players:
			add_player(peer)
			print(peer)
			readyforpeerspawn.emit() # <-this will not signal the remote peer
	else:
		await readyforpeerspawn # <- this will never get signaled.
		add_player(multiplayer.get_unique_id())  # #<- a multiplayer spawner will add this from the host.
		for peer in players:
			add_player(peer)
			print(peer)

The code above is not doing any harm, just wanted to point that out. I think the issue is is loading the level. you can either have a spawner load the level on the client, or make a system that can make sure all clients of loaded the level before adding the players.

How exactly could I spawn the level with a MultiplayerSpawner?

The same way you spawn a player.

Btw I haven’t ran your project. Just was looking at it via GitHub. I could try it later today. I had another thought, your code also didn’t connect peer connected, and you only check peers joined once when the level starts. But the client will only join once you click the client button, well after that fact. Yeah, so now I think you should just use the peer_connected signal to add_player on host for joining clients.

When i use peer_connected, _on_connected never gets called.

The code I used:

if multiplayer.is_server():
_on_connected.rpc()
else:
multiplayer.peer_connected.connect(_on_connected.rpc)

UPDATE: I managed to get the client to see the host, and the camera moves with the host, but the client doesn’t spawn, and only the host can move the character. The client is now pretty much just spectating the host. New code has been uploaded to the GitHub repository.

peer_connected signal has an int parameter id to indicate the peer commecting. Your function _on_connect doesn’t have a parameter. Which will fail to receive the signal as the function signature doesn’t match.

You also don’t need to have an RPC as the method for the signal if you have the a MultiplayerSpawner to spawn the peer players on the server.