Announcement

Collapse
No announcement yet.

Game Server Architecture -- Oct. 20 2015

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Game Server Architecture -- Oct. 20 2015

    Originally written by PSForever founder and lead developer Chord:

    Okay, PlanetSide is current divided up in two server classes: Login and Game.
    It makes sense that PSForever follows this same model to be compatible. It allows for the isolation of account handling (passwords, tokens) to one server and code base.

    Login Server
    The login server merely logs a user in, presents a list of servers, and provides a hand off to specific servers. The number of packets that the login server uses are limited and this would be simple to implement. The login server is the only server that handles usernames and passwords (through the skip launcher). If we're to implement a Sony-like launcher, then maybe having a lightweight REST API for logging in would be sufficient instead of using the built-in login form.

    Game Server Scalability
    Sony's original game server was supposedly able to handle 3,500 players. With today's computers, meeting this goal should be trivial. Scalability is difficult to think about early on in a project, but I believe every project should keep scalability concerns in mind from the very beginning. Similar to security, if it isn't thought up at design time, retrofitting it is a terrible, if not impossible process.

    One of the core issues with game servers is that clients need status updates of all of the other clients around them. For example, if there are 100 players standing in a circle, strafing back and forth, then every server update will need to send out 100 x 100 position updates. Essentially state updates for games are an O(n^2) problem, where n is the number of clients. Optimizations can be made to limit the number of status updates, such as only sending updates if someone is visible. This requires more server side checks in order to determine what clients are visible to other clients. PlanetSide already does this with people despawning when they walk out of range. Sometimes in big fights, people will be ping-ponging between appearing and reappearing due to either a clientside limitation or a lack of server updates. When and for whom updates are given is also important from a security standpoint. If the clients have all of the players near by in memory, even if they can't see them, then this allows for trivial map hacking. PlanetSide currently sends player updates in, what I believe, is a sphere surrounding the current player, regardless if they are visible. It also prioritizes updates depending on certain factors, such as distance or if the object is a vehicle.

    Game Server Security
    The reason that current PlanetSide game servers are so vulnerable is that they don't perform enough serverside checks. They trust the client, which is controlled by attackers to assert that events are true. PSForever needs to check the work of the clients in order to detect deviations from the true game state on the server. Any deviations could be the result of bad clientside prediction, a laggy connections, deliberate client editing (hacking), or even a clientside bug. We can't just immediately ban someone because we detected a single deviation. I believe that using statistics and creating a function or threshold for "badness" would allow for small upsets to pass through, but for the real offenders to get a lot of badness. This is similar to the grief system: you shoot someone by accident, okay no problem, you get a small bit of grief. Continue shooting people though and your grief rises faster until you are weapon locked.

    Backend Requirements
    • A database engine for storing world and account state
    • One or more login servers
    • One or more game servers
    • A REST API for other applications to query server state
    Language Choices
    For data storage, SQL is definitely a top choice. Use of MySQL bindings will be excellent and it is what most private servers today do. As for server language, this is a touchier subject. C++ is the first to come to mind due to its performance. C++11 is an even better candidate as its new features for memory management and anonymous functions greatly improves development. One downside to using something as heavyweight as C++ is that crashes are much more likely and without a good framework, there will be a lot of boiler plate. Boost libraries could be used similar to TrinityCore, which would greatly speed up development and allow for a cross-platform server implementation.
    There are also less obvious languages, such as Scala, NodeJS, or Go. Scala runs off of the JVM, but it's amazing Akka Actor framework would allow for simple and safe concurrency and by extension parallelism. C++11 actually has a mature actor library that may be an interesting choice ([urlnew=http://actor-framework.org/]see CAF[/urlnew]) The issue with Scala is that many are not familiar with it and it does run off of the JVM (i.e. garbage collection). NodeJS would be a very strange choice and I can't see myself ever making a game server in JavaScript. Go is an interesting candidate. It has native concurrency support like Scala, but has a more C-like syntax and is touted as a 'systems language'. Choosing the right abstraction is important for this project.
Working...
X