How should i go about implementing a lobby based system where the clients can either join room 1 / room 2 and can only see , interact , chat with each other if they are in the same.
I’ve tried doing this myself but got stuck multiple times.
You need to make chat its own scene so you can duplicate it easily, and when a peer sends a message you need to associate the message with chat session to direct the message to the right chat window. And the chat window is selected via the room the peer selects.
The biggest concern with the canvas/world is keeping lobbies separated in space. You want to avoid “cross talk” (visual glitches, player collisions, etc.) between lobbies.
First you can separate the lobbies in a single world by position. Spawning those who join into each room. The drawback is having to build a grid system to place a rooms positions that dont overlap. (We can hide adjacent rooms with MultiplayerSynchronizer visibility feature). The limit to this approach becomes the number of rooms * the size of the room, and the physical limitations of 32 bit vector positions.
Another option is to use subviewports that contain a separate world. The drawback is containing your game/lobby in a subviewport.
I would avoid using visual and collision layers to separate rooms, you may need those for other things and they are limited to 32 slots.
Multiplayer
Obviously the server needs to host every room, but you dont want clients to know about everything that happening on the network.
The best approach to resolving this is using MultiplayerSynchronizers visibility feature. ( Requires MultiplayerSpawners ). When a player joins they will not have visibility given to them. When they select a room only that rooms visibility is given. This will reduce bandwidth for the player and server. If a player does not have visibility the room can be despawned if its watched by a multiplayerspawner.
You can do this with RPC but you will have to devise your own visibility system.
Another approach to visibility is to have multiple enet instances on separate branches. The client will connect to two server ports. One that hosts the room list and the second that hosts the room. This has a limiting factor of free ports on the host, but can allow you to scale indefinitely as the room doesnt need to be hosted on the same computer.
Haha see my post above, but it all boils down to your goals and scale. If you want to scale this is the way. Hosting is a bigger topic as there are many ways to go about this at different costs. But architecturally i would have a server just to manager room/lobby stats by region, and N number of servers for the rooms.
Not exactly, one server is one IP. You can still run multiple processes, of your project, on different ports. And you can have multiple ports per process.
With each process you will have a some overhead, like memory and processing, so i would definitely want to see what that cost is before i would make a decision, if you just separated your lobbies by processes it would be really simple. You wouldn’t have to worry about other worlds and you wouldn’t have to manage network visibility. Very simple.
But if the overhead cost of running separate processes becomes too high, you could still try and make a server handle multiple isolated rooms in one process. However complicated that would be.
For what its worth i run my own hosting for development. Im not trying to scale in this same fashion, but i put a single Godot process inside a Docker container. This is typically what a web host would allow you to do when you define a service for hosting.
Running a virtual OS has some cost, but with some added security of a sandboxed envoroment, so if i was to scale i would probably run a script to put N number of game processes on a single container each assigned their own port, in a defined range, via a command line argument. Then a spin up multiple containers as i need them to meet demand. (And limit this number to the resources of the host machine)
Obviously you still need a central server for clients that haven’t yet selected a room. If that one service gets overloaded you will have to have some means to load balance people that haven’t selected a room. You might want to do some simple REST backend to do a one-off query to find which central service to connect to. Or maybe this “centeal-service” is just the REST api that provides a list to all the available rooms on the internet (room name, IPs and ports).