Search Unity

How are servers designed?

Discussion in 'Multiplayer' started by elmar1028, Mar 16, 2018.

  1. elmar1028

    elmar1028

    Joined:
    Nov 21, 2013
    Posts:
    2,359
    Hi guys,

    I've been looking into making my own multiplayer solution for quite some time now. There are already tons of great articles on various techniques on how game states are synchronizes across players' connections.

    What haven't been mentioned a lot are servers themselves. How do they behave? How are multiple matches handled? Is there a "Master Server" that redirects incoming connections to an appropriate room (mini-servers). How are simulations calculated? And so far so forth.

    These kind of questions are really bugging me because without understanding of how server works, you can't expect to make a game playable at all!

    Any ideas or online resources you guys could point out regarding the server architecture?

    Thanks!
     
  2. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    3,038
    There are probably many valid answers to this.

    If the game is large enough there's usually a generic service to balance the load and find one of several available servers, at least for more action-based likes like an FPS or MMO (or an FPSMMO). You might even want to load-balance login servers and have a number of databases with user accounts replicated between them. Such services don't need to know more than the addresses and ports to transfer users to.

    There are also other ways to balance it, like how content distribution networks pick a regionally closer server for your data to download from (Akamai, CloudFlare, Google and so on are experts at this - CF might have blogs explaining it in detail even).

    A typical mobile "strategy"[1] game can have one server handle many users and battles, and the front-end service could pick the server which responds the quickest (or rotate a list to distribute evenly, or whichever scheme is deemed necessary). Many matches of simple abstract numbers compared against each other don't take much processing power, so tens or hundreds of thousands of users per server could be possible if the bandwidth required is minimal.

    An FPS would usually fire up an instance of the in-engine server per match, and running in headless mode lets you run many on the same hardware if the resource requirements are reasonable. Valve's servers have relatively low RAM demands, for example, but variable bandwidth requirements to run smoothly. There's more traffic required for a dedicated instance of Team Fortress 2 than four friends playing L4D2.

    For turn-based games the servers handling the matches won't need to be written in the game engine used by the clients. There are many popular tools/services for setting up a basic room-based chat which could be used as the foundation for a matchmaker, with an API for creating match logic for more abstract games.

    If making an FPS in Unity you could integrate such a service for chat and matchmaking, but make the server a headless version of the game client. There might also be ways to create a slimmed down version of the client for headless mode, but you'd have to research that.

    I'd start by searching for terms like "load balancing games", "matchmaking servers", "game server architecture", "optimising game server bandwidth" and mixing with keywords for the game type you're interested in and perhaps keywords like "large scale". Running game servers is work which needs a few different fields of expertise :)

    Photon has all the elements you need to get started, including load-balancing, so reading documentation for it should give you some more insights.

    [1] Where the winning strategy is to have the most real-life money.
     
    elmar1028 likes this.
  3. elmar1028

    elmar1028

    Joined:
    Nov 21, 2013
    Posts:
    2,359
    First off, thank you very much for such detailed writing. I have learned a lot and this gave me a new sense of direction for my research!

    I always thought it would be more efficient to actually have in-engine servers be always enabled and reused between matches. This way there would be no need to actually wait for servers to start-up on demand. Kinda like object pooling (no need to re-allocate memory space at runtime).
     
  4. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    3,038
    Yep, you'd probably use pooling similar to how you pool game objects in-game :)

    Many servers have a minimum and maximum number of instances (sometimes threads, sometimes actual instances). The minimum is what it starts with, and where it drops down to after some criteria. For a game server with a fixed number of maximum users it would be most efficient to start them all and keep the maximum, and shuffle new players to the nearly-full servers as they connect.

    If you have a game where different game modes have different maximum numbers of players (like L4D with its co-op and versus mode difference), you could monitor the memory usage and adjust the number of servers according to how many players there are on one specific computer instead, and relocate them to some other system as needed.

    One exception to keeping warmed up servers is if you're using a cloud server system like Amazon's, because you might be paying for compute time. It might be cheaper to run exactly the number of servers you need and rather have a few seconds more of startup time.
     
    elmar1028 likes this.
  5. elmar1028

    elmar1028

    Joined:
    Nov 21, 2013
    Posts:
    2,359
    This is one of the things which I wondered about the most. Are servers (as in matches) handled as each separate app, or a single instance that runs multiple threads (each thread is a match). Now that dedicated servers are mentioned, I think latter is more common.

    This is something I did not consider! One minor addition could be that a dedicated server can auto-shutdown if it's been inactive for more than 5 minutes. That way if the game is very active (peak timings), servers won't have to always shutdown once game ends and won't have a large cost if the game isn't being played much (off-peak time).
     
  6. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    3,038
    For a typical case of the server running on Linux, it doesn't matter so much. Maybe it's easier to handle the operation of multiple server apps, as each component of the whole business can be separate (just set it up so the OS handles spawning a new server when its port is connected to, for example).

    Linux apps don't take up much more memory than the stack and other unique allocations for each app instance, as memory is optimised to make blocks of the same data (eventually) drop down to one shared copy. Running an app 10 times or spawning 9 copies of the same process will use about the same amount of memory, the total typically being far less than 10x app+data size. This even applies to container memory, so hundreds of isolated VPSes could end up using about the memory of two server apps.

    I think especially with memory-mapped files it can do this more efficiently. Map data, opened read-only, and the OS knows not to repeat the operation for other processes requesting exactly the same file - just clone the existing file descriptor.

    Of course, for a simple 2D turn-based strategy game where the logic boils down to checking for allowed moves on a flat map, one server app instance could easily handle thousands of users, perhaps hundreds of thousands. Likewise for mobile games which are just a GUI covering up some database access, comparing numbers to fake battles.