How to make a MMO (server side)?

mmo
user1090694 picture user1090694 · Nov 27, 2013 · Viewed 13.1k times · Source

I had tried to search about how to make a MMO and always find the same replies, it is impossible or need a lot of money, but never gives a guide on how to make one.

I want to build something very scalable, my current idea on how to build up the MMO is the following:


Components:

  • Login Server: client sends username&password to this server and if successful gives to the client which Game Server to connect.
  • Game Server [1..N]: all the game logic goes here, clients are connected to this one.
  • Position DB: stores data of currently logged users and active monsters, in which Game Server they are, their positions on the map and action they taking (move, attack, etc.).
  • Account Data DB: stores all data about the user (username, password, characters, items, quests, etc.)
  • Chat Server: since users that are on the same place can be in different servers, it is necessary to make an extra one so players can communicate between them.
  • Monster DB: a database with the attributes, base positions and AI scripts of all the monsters.
  • Monster Server [1..N]: all active monsters in the server
  • Log DB: stores all actions taken and chat texts.

Actions:

  • Login:
    1. Client sends Username&Password to Login Server.
    2. Login Server verifies the data with Account Data DB and checks that is not currently logged (Position DB), if successful go to 3, if not, sends back a unsuccessful login message.
    3. Login Server updates the Position DB adding the new connected user with the server he will be connected (lowest amount of people/nearest)
    4. Position DB informs the corresponding Game Server that the user has been connected.
    5. Login Server sends to the client the Game Server is connected to.
  • Main loop(client):
    1. Client checks in Position DB his current position and action and those near him (players and monsters), within the data received also includes a time of last update (gears or level) of the players.
    2. Client compares the date of the players received with current players saved on memory, if the player was not on memory or the date is not the same, Client asks Account Data DB for lvl, gears, etc.
    3. Client renders the players
    4. after a time go to 1.
  • Chat:
    1. Client sends a message (pm/normal/all) to the Chat Server
    2. If pm, Chat Server sends the message to the target
    3. If normal, Chat Server checks with Position Server the players in the area (same as main loop (client).1 when checking players near) and sends the message to those.
    4. If all, Chat Server broadcasts to all the players
    5. Confirms that sender&receiver got the message
  • Action:
    1. Client sends action (crafting, moving, attacking, etc.) to Game Server.
    2. Game Server processes the action and updates Position DB with the effects of the action (client will know what happened with the main loop action).
    3. In case of crafting or looting, Game Server returns to client the item gained.
  • Main loop (game server):
    1. Checks all received data from clients and processes them.
    2. Sends to the clients the results of the process (damage, xp, item gained, etc.) and updates Position DB with the effects of it (new position, etc.).
    3. After a time go to 1.
  • Main loop(monster server):
    1. Checks if an active monster there is a player near, if not removes it from the Monster Server and Position DB.
    2. Checks to all players in Position DB if there is any monster near (from monster DB) and is not active and activates it (updating Position Server and Monster Server).
    3. Monster takes action (attack, move, do nothing, etc) based on a script stored on monster DB.
    4. After a time go to 1.

and the questions I have:

  1. Would this way of implement work? (considering a big map with lots of monsters and players)
  2. I have the feeling that the Position DB will be quite stressed if things grow up. would be better if:
    • make multiple Position DB
    • make a DB that links (player/monster, Game Server, Position DB)
    • make a DB that links (Position DB, area)
    • So that a Position DB is based on an area (or areas) and when a player moves to another area, his data is moved to another Position DB; and the last DB (Position DB, area) would be in case that if an area have too many players few Position DBs could share the same area (and if areas do not have many people, a Position DB can hold some areas)
  3. About technologies used, I was thinking on the following:
    • Login Server: scala/django
    • Game Server: raw programming in C++?
    • Position DB: scala/django for communication and DB with SQL
    • Account Data DB: scala/django for communication and DB not sure if either using a NoSQL like mongoDB or accounts saved on files (wich would be better?)
    • Chat Server: raw programming in C++ or should I try to adapt an IRC server?
    • Monster DB: SQL
    • Monster Server: like Game Server
    • Log DB: SQL
  4. Communication between client-server should be UDP for faster communication? and TCP for login? or should keep an open TCP socket always between the client and server? also, for chat, TCP or UDP?
  5. Around every how long should the main loop run so that the game goes fluently? every 0.5 seconds, 0.1, something near a 60fps? also to make the timer would be better throwing a thread every loop? (controlling the amount of threads, so if the loop is taking longer than it should)

And I don't think I am forgetting anything for the moment to ask about and sorry for this big post...

Answer

Christian Flodihn picture Christian Flodihn · Dec 28, 2013

I don't think your solution would scale. The issue is your position DB that needs to be updated for every player action. You probably use this method to allow game servers to share data, which is a bad idea since databases are not meant to enable distribution of a system. Treat databases as real offline storage, only to load state when players or objects are activated.

You need to get rid of the position DB and store the players states distributed among the game servers.

Also consider having a front-end server that keeps one connection to the client at all time, relaying messages to the right game server etc. In this way you can avoid clients having to connect to the "right" game server and all the problems that comes with that level of trust.

Distributed programming is pretty hard, but the programming language Erlang makes it easier for you than Python/C++ etc.