In my multiplayer game there are different levels that any player can access independently. So players that are not together don’t need to share information.
I noticed that rpc sends data to all clients and there’s no way to change this. So I’ve been keeping an array of users for each area and then using rpc_id to loop through the players in the area that need the data.
I assume this is the correct way to do this. If not please enlighten me.
Next question is, the MultiplayerSynchronizer also doesn’t have any options for which users to sync with.
The two options I can think of are to either write my own synchronizer, which I can’t seem to find any information online about how to sync movement manually because everyone just has tutorials on the built in synchronizer. Any guidance or links to how to do this via code would be appreciated. OR I can have my dedicated server build dynamically create another server instance when a player moves to a new area and dynamically disconnect and then reconnect the player to the new server for the new area. Then all these problems would go away because each server would only contain the players in that area.
The second option seems like it might be the way to go, except there are certain things the players need to share even when they are in different areas and I’m not sure how I would handle data transfer between server instances.
That is correct, the other option is MultiplayerSynchronizers and their visibility settings.
This isnt true visibility. (Sorry im responding in real time.)
I dont believer there are any guides out there for making your own syncer. But it is a very simple node that interfaces with the SceneMultiplayer class (a MultiplayerAPI implementation, you interact with it as multiplayer).
The spawner and syncer and RPCs register configurations with the SceneMultiplayer to do various checking of things like visibility authority and rpc attributes.
So if you want to write your own syncer you can look to see how visibilty works in the SceneMultiplayer source code. But i bet its very similar as the rpc array method you mentioned.
So just stick that into its own node and make the proper parameter map to sync data and you should be on your way.
I did see visibility and I took it at face value. That it would just hide objects visibly. Based on your response, I would assume turning off visibility also stops it from synching data to that ID.
My concern is this:
Let’s say I have 2 areas. I spawn 10 players in area 1 and 10 players in area 2. Visibility of players in area 1 is turned off for players in area 2 and vise versa, however. From what I understand, this still means I have to send unnecessary updates to all clients in area 2 every time an area 1 player joins. Creating the player object and then marking it invisible. Which also means all clients in this scenario will have 20 player objects, even though only 10 are relevant. Seems like extra overhead. Maybe at small scale is not a big deal, but if I have 10,000 players. Clients handling 10,000 objects when there’s only 10 in their area seems like a bad idea.
Either direction you go you will have to manage it some how.
As far as i know visibility works hand-in-hand with spawners. and when something becomes invisible it is despawned from the client. so all you would have to do is set the visibility once for the level and it will despawn everything underneath it in the tree for the client changing levels.
only the server will have to keep track of both levels and all players. the clients will only need to know about the level they exist in. of course, any cross information visible to all players needs to be managed outside the levels.
Warning though. I have read issues here with large scenes (like levels) and child spawners, running into replication failures because the level isn’t fully loaded when the child spawners, that dont exist yet, are asked to spawn nodes. So unitl it is fixed you may need to organize sub spawners with care. (i.e. only nest spawners in small scenes and never in large ones.)
When you say small scenes, what do you mean exactly? Here is an example node structure:
Root
-levels
–level1
—spawner
–level2
—spawner
Upon player join level1, use level1 spawner to spawn player, then loop through all connected clients and if clients level is not this level, set visible to false.
Upon change level from 1 to 2, use level1 spawner to despawn, then use level 2 spawner to spawn and repeat the process.
Or…
Root
-levels
–spawner
–level1
–level2
Upon player join level1, use level1 spawner to spawn player, then loop through all connected clients and if clients level is not this level, set visible to false.
Upon change level from 1 to 2, loop through all connected clients and of the clients level is not this level, set visible to false else set to true.
The second option seems better? But either way I’ll have to loop through every client and set visibility. Let’s assume there are 100 levels, and each level contains 100 synced clients, as well as 100 synced objects. I’m wondering when I’m going to start having performance issues and if I need to think about running each level as it’s own server and just pass the clients between servers and then handling communication between servers when necessary.
Thanks for your guidance, your thoughts are appreciated.