MultiplayerSynchonizer visibility does not affect Spawner

Godot Version

4.6

Question

I have a goal of setting up multiple world simulations on a godot multiplayer server.
I somewhat understand that it’s possible to have multiple enet server peers with different ports, but I didn’t really want to use that, just don’t want to flood the ports.
I read this discussion: Implementing lobby / room based system in the godot-3d-multiplayer-template - #8 by pennyloafers
And I came to believe that Synchronizer Vilibility should affect MultiplayerSpawner actually spawning nodes. I have tried it out, and the nodes were still always spawning.

So what I have is a player scene with a MultiplayerSynchronizer where public Visibility is turned off,
Then when the client connects and loads the map (the map also contains the spawner, each map is suppose to be a separate world simulation) the player is spawned into the map.
This player scene gets multiplayer authority set for the peer that has just connected.
And to my surprise, this player scene is actually also spawned on the client, not only on the server
but at least it’s position is not synchronised to the server (because of the public visibility)

Then, when I connect another client to the server the server already is sending information about the spawned player to the new client and new client gets confused and does not do anything good (because it has not loaded the spawner yet).
But also this player scene is spawned on the first client (so I guess visibility does not affect the MultiplayerSpawner?)

I have also tried setting the visibility_filter
this is how it looks:

func _visibility_filter(peer_id: int) -> bool:
	return peer_id == 1

this happens when the Syncrhonizer enters the tree:

func _enter_tree() -> void:
	add_visibility_filter(_visibility_filter)
	update_visibility(0)

does nothing new.

Are spawners really not controllable? Is there really no way to control what nodes are spawned for what client? Because in the MultiplayerSynchronizer it says this: “MultiplayerSpawners will handle nodes according to visibility of synchronizers as long as the node at root_path was spawned by one.” but it does not seem to be the case at all?
Or maybe I am missing something?

One thing to look out for is nested visibility does not work. If the level is dynamically loaded, there is a chance you can get a spawn request before the spawner exists on the client. In this case you need to add visibility control on the level as well. But since your nested player spawner cannot tell its parent network visibility, the servers player spawners instance will attempt to spawn regardless if the clients level exists or not.

My advise is to not nest spawners, when utilizing network visibility, unless you can stomach writing a system to overcome the current limitation. There are issues on GitHub regarding this.

Another thing is spawner authority, all multiplayer nodes will default to the server authority. You should avoid giving a scene’s authority away when the spawner is authed to the server. Because of how you have described your setup i would only auth a child node of the player scene that handles sending input to the server, instead of the whole scene.

The alternative is authing a spawner for every client to control what is spawned. (If that makes sense to your design)

1 Like

Thank you very much for the response!

In my setup I didn’t have nested spawners (I have a map system that sends dictionary from which it is instantiated) and each map has it’s own spawner node.

During the weekend I had time to look over the godot source code and found out that if a node spawned by the spawner does not have matching authority (e.g. spawner belongs to one peer, instantiated node belongs to other) it disregards synchroniser visibility. And the player scenes spawned by the server where instantly given away to the connected peers causing them to be always persistent.

In the end I just decided the make everything server authoritative and send inputs using RPC.
Client authoritative players would’ve been much less code for responsive client experience (maybe) even though I would need to do some awkward hacks (no idea how I would reparent them to branches with different World3Ds).

1 Like