My goal is to get multiplayer working between different scenes, so that players can be in any one given scene, and the server only pushes updates to that exact scene to the clients.
Currently, I have one big main scene “GameOwner”, which has some UI, aswell as the “EnvironmentContainer”, which works slightly differently on client and server:
Server: instantiates every environment under this node
Client: Only instantiates the scene the client is currently in
Here a simplified version of the GameOwner tree:
GameOwner Node (res://scripts/…game_owner.gd)
ServerData Node (res://scripts/…server_data.gd, used for server settings)
CanvasLayer
ViewportContainer
GameViewport SubViewport
EnvironmentContainer Node3D (this is where all the scenes go for the server)
Players Node3D (will probably split this into multiple sub-nodes, so each scene has its own collection of players)
MainCamera Camera3D
I want this to work with the MultiplayerSynchronizer, Spawner and if possible also rpc calls..
The MultiplayerSynchronizer has this method set_visibility_for(port: int, visible: bool), which allows to set which clients get which updates, but unfortunately no such method exists for the MultiplayerSpawner.
And rpc calls are a whole other story… They seem to always expect every client to have the same scene tree … which works great for basic games which work within a single scene on both server and client… but not as well, when the client is meant to only load a single scene at a time, like in my case.
I have heard of the idea to create a new MultiplayerAPI for each scene, but im not sure how the client would then know which exact MultiplayerAPI it would have to connect to.
Using that method you won’t be able to use a MultiplayerSpawner as the server will try to sync spawned nodes to all clients. I’ve not tried using the MultiplayerSynchronizer but it may have the same issues.
I read the poat you linked, but it doesnt seem useful to me in this case.
Hmmm… so its essentially impossible to have clients dynamically instance new scenes as they enter them, because the server will always try to sync everything to every client?
I feel like… thats off… hmm… is it not maybe possible to have a MultiplayerSpawner only sync the tree to just some clients? Which are maybe stired in an int array like this?
var players_in_locations: Dictionary[String, PackedInt32Array] = {
"hub_world": [485826634, 1222067994],
"first_level": [788005365312, 8742533582],
# and so on, for all scenes with all the player ids listed
}
this way, we could have a nice rpc method which the clients could call on the server, specifically:
remove_client_from_scene(client_id: int) -> void
removes that player from all clients who were in the same area
uses set_visibility_for(id: int = client_id, visible: bool = false) on all MultiplayerSynchronizers to stop synchronization of these variables to this client
maybe somehow deacticates rpcs from that scene being sent to the client leaving that scene
mayyyyyyybe in some possible way deactivating the MultiplayerSynchronizers to stop sending scene updates to that client
add_client_to_scene(client_id: int) -> void
essentially everything above, but in reverse -
add player to all the clients in the new scene
activate all MultiplayerSynchronizers in that scene foe the client
Perhaps even make the MultiplayerSpawner pass updates to this client
if somehow possible, also let rpc calls through to the client
Is this me having too high hopes for multiplayer matureness in Godot? Because like - if this doesnt work, I will have to omplement my own MultiplayerSynchronizer using rpc calls on a node which client and server have access to…
EDIT: i just realized, i i can just have the server only push rpc calls to the clients which are in the relevant scene. so rpc calls and MultiplayerSynchronizers work already with this config.
Now the question is: Can we somehow deactivate MultiplayerSpawners from syncing their state to certain clients