What would be the best way to have different servers for different zones and have players be able to move through them in an MMO environment. So the servers would need to be able to communicate with each other to check that a player entering the zone arrived legitimately. Also would be nice for players to be able to message each other whilst in different zones etc.
#Running Multiple Servers
95 messages · Page 1 of 1 (latest)
@meager juniper I'm not sure if many people will have the answers to this other than you tbh
cross communication between server instances will be the hard part of that. Jumping servers is doable, while not exactly seamless, you can make it at least frictionless. You'll need a web service that talks to a database, and game servers will need access the web service and to the database as well (server side, obviously).
Web service would handle all authentication, and spinning up of game server instances, each of which would make API calls back to the web service letting it know it's up, going down, or needs to authenticate or transfer a client
Clients get tokens and connection endpoint from web service as part of authentication response, client connects as instructed with token, game server calls API with token to get player details it needs, accepts player to join that server
At some point, e.g. a portal or w/e, server determines client needs to be transferred, calls API with token and which Zone client needs to go to in a TransferRequest, response has new connection details, which are sent to client in a NetworkMessage to Transfer with those details. Web service updates itself / db as to which server / zone player is allowed into. Client disconnects and reconnects as instructed, same token API call process as before.
All that can be automated so it's frictionless, but takes a few seconds, because client needs to change scenes along the way, so a fade out > fade in would probably be needed with either a splash UI or just a black UI to cover the transition.
If you offload "chat" to a separate service that all clients connect to (again with token from web service) via some simple TCP Secure Client, then that would satisfy your cross-talk requirement. and keep chat traffic off the game network.
maybe even Discord could provide that...dunno.
Thanks for the response. I hadn't thought of using my database to validate for some reason for this problem, even though I use it for all the others. I wonder if anyone has made any chat functions that are kept off unity. That would be good
@meager juniper Would running multiple servers locally be possible for testing?
@meager juniper Once I figure out how to get 2 instances of Unity running in server mode which I'm hoping I can manage myself I wonder how my client will differentiate between them when swapping between them. The servers I run on AWS will have different IPs so that should be no problem.
each on a different port - you'll need to open a range of ports for a given server, same IP
maybe I misunderstood between multiple instances of the game server app on one server machine, vs separate server machines each with one server app running
Ah ok Thanks I'll look into this!
@meager juniper Would simply referencing the transport and changing the value be a clean way to handle different ports?
which transport?
Telepathy
It has a field, port = 7777. If I change to 7776 then start server, then have my client have it on 7776 when he starts client. Would this work fine?
((TelepathyTransport)Transport.active).port = 7776;
Oh Ok I'll look for this
for your headless server, you can pass command line args to it to tell it what port to listen to
e.g. MyGame.exe /p:7776
In your custom Network Manager, override Awake...
public override void Awake()
{
// This will set the singleton and Transport.active
base.Awake();
#if UNITY_SERVER
foreach (string arg in Environment.GetCommandLineArgs())
{
// Get the port from the cmd line...default is 7777
if (arg.StartsWith("/p:", StringComparison.InvariantCultureIgnoreCase))
if (ushort.TryParse(arg.Remove(0, 3), out ushort port))
((TelepathyTransport)Transport.active).port = port;
}
#endif
}
@meager juniper When I connect to Mirror from an offline screen it creates a player prefab. When I connect to another server whilst being online it doesnt.
If I try to StopClient(), wait till im disconnected, then StartClient() to another server that doesnt work.
How would you handle sending a player from one server to another? Can it all be done by the server?
This should work - need to see your code in https://pastie.io/
also inspector of your custom Network Manager
So this code works if you just have it ran seperately
but when i stopclient the rest of the code wont run
and if i remove stop client the player prefab doesnt spawn in
@meager juniper
Still struggling actually, not working
looking
not enough context, really. If there's an offline scene, StopClient will switch the client to the offline scene automatically, which is probably not what you want, since the offline scene will likely have content suitable for an offline client just starting the app.
Additionally, when Mirror switches to the offline scene, Network Manager is pushed out of DDOL and destroyed so you get a whole new one in the Offline scene where it originates.
So you'll need to do a few extra things for transfers....
- when server tells client to transfer, the code to handle that should be within your custom network manager, because that will be the most convenient, and that's already in DDOL.
- When a transfer message comes to client, set offlineScene to null (prevents the switch), but you'll need to keep a ref to that so you can set it back before calling StartClient again (in case new server tells to to buzz off)
Ah ok thanks ill give that a go now
Then set new endpoint in networkAddress. You still have NetworkAuthenticator, so you still have your token, which will be sent to the new server
Then you can call StopClient, yield a frame or two, then re-assign the offlineScene and call StartClient
@granite oyster
New server will automatically tell client what scene to load (which will be whatever server has for active scene at the time)
Looks to be working nicely now thank you ❤️ @meager juniper https://pastie.io/ttehbd.cs
You really need to yield at least a frame after StopClient
yield return new WaitForEndOfFrame();
Just to let it all finish before moving on?
yield return null;
Under the hood there's a round trip to the transport and some cleanup that happens in the transport and events raised by the transport
user will never notice a frame or 2 being skipped
especially given the need to load a new scene, all probably happening behind a cross-fade
Maybe yield return new WaitForSeconds(0.5f)?
the yield return null would stop everything beneath from running?
won't need that long.. 1 or 2 frames will do
yield return null; just skips to the next frame before proceeding
oh right, so just post 2 of them beneath StopClient?
at least 1, and make a note that you might need 2 if you see glitchy behaviour
Well I'd been using yield return null as the same as return in my scripts and had never noticed issues xD
This is not at all right 🙂
yield return null as the same as return
xD
How's your custom Network Manager shaping up?
@granite oyster Without knowing how you'd integrate it into the client itself I think Redis pub/sub is a quite nice tech for a game chat. But like I said, I'm not sure how you integrate it, maybe you wrap it with a barebones websocket API(maybe at that point you just build it around a normal database instead)? Just throwing ideas out there.
Probably some asset that'll do it for me. It'll be one of the last things I do though in the next few weeks 😄
Good I think. Everything is working now
Have the scene interest management for all the menus which will be on my main server
then each zone will have its own server running it
The Multiple Additive Levels example has a FadeInOut script you might want to look at for cross fading
Yeah I'm using it with my own visuals it's very useful
if you're doing a cross-fade with the transfer, you can yield return FadeIn(); after StopClient...the fade time will cover the transfer and scene change
Yeah that's likely what I'll go for
You're doing Additive Scenes, then?
Otherwise the player will see their character loading all his weapons and looks 😄
Yeah I'll be doing a bit of both
Maybe have a single server handle a few scenes together
scene interest management requires additive scenes
yeah I was thinking for the server running 'zone 2' for example I will have anyone who enters the server be sent there right away. All servers will have all of the zones so it will be like its just using additive scenes
Gives me a bit of flexibility. I could have a few zones on a single server or separate servers this way i figure
So you connect to the server, it will check the database for where you should be and what character. Then move you to it
Just send the scene message with the additive sceneOperation before you instantiate > move > spawn the player
@meager juniper If I have a While loop running in a coroutine and I want to leave the coroutine after lets say a number of times. If yield return null just waits a frame how do you do the 'return' to get out of the loop and out of the coroutine?
@meager juniper When I load into a new server with a new port can I prevent the online scene loading?
So that I can load only the scene I want
yield break; to get out of the coroutine
server and client always are on the same main scene...additives are in addition to that.
so your online scene is mostly empty...think of it as a container, generally, and then you load additives on top of that
Ah ok I will have my online scene be empty then and have players immediately sent to the correct scene thanks
Do players choose an avatar, or do they all just use the same playerPrefab?
Imagine world of warcraft, you create an avatar, it goes into a database, you can then have your x number of characters you can choose from
k - doing that in offline scene as part of your authenticator??
I ask because the Additive Levels network manager has 2 methods in "Server System Callbacks" region you should take a look at for getting the player into the game