Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

In online games, people prefer to log on and off whenever they want. Usually, their game achievements are seamlessly saved, on the server. That is not that difficult to achieve, but I am wondering how can be done in an efficient way that makes sense and will scale.

Does it make sense to save the player's coordinates and state with every time they send it? My node.js server can do that easily without blocking a response, and I want to employ a Mongo database, but maybe it's more appropriate to do that once a second and in a server-wide event, collecting all at once?

share|improve this question
    
I save the game state every 10 seconds. I think that is enough, it goes unnoticed (and I'm running my MMORPG server on my netbook that has 512Mb of RAM). –  jco Nov 8 '11 at 23:05

3 Answers 3

up vote 8 down vote accepted

I have in mind a traditional MMORPG like World of Warcraft.

Save after every command from each player and autonomous thing (e.g. NPC)

  • Constant backup. The server could go down at any moment, and the state of the game is saved up to that moment (or as recent as possible, anyway).
  • Impact to server performance; even if it's non-blocking (i.e. on another thread), even if the database is on another server, it is processing that you would otherwise not do. If it is non-blocking like you say, then another thread has to handle it, and that's a thread that could be occupied with something else.
  • Increased disk I/O, thus increasing risk/rate of failure. This is especially a concern if you are using SSDs for storage, given their lower life.
  • If you offload the database to another server, then increased bandwidth; this might be a concern if you are paying for bandwidth, and if it's not on a separate network card then it's taking up resources that could be better put to use handling player traffic.
  • What happens if the server gets further and further behind in saving the state of these commands? I.e. if more commands come in than can be saved, so they pile up in a queue? Does this queue overflow and cause an error? Do you stop everything so the queue can catch up?
  • It seems to me that this approach, while it sounds simple, would need to be carefully planned. For example, consecutive commands that rely on each other will need to be saved together; otherwise a failure could occur in the middle of the commands, and only one will be saved but not the other. Consider if two players execute a trade and two commands are saved to disk: "add 1 of the item to recipient" and "subtract 1 of the item from sender". If a failure happens after the first command but before the second command is saved, you have an item duplication. (if the order is reversed, then you have a lost item)

Save everything periodically

  • In case of a failure, the server will be somewhat out of date. Hopefully you use something like a journaled approach, so the most recent snapshot will at least be whole and consistent, and all the active players are set back by the same amount of time.
  • Whatever database system you use might have an optimization for batch updating, which is more efficient (less overhead) than updating one at a time.
  • If you opt instead for a binary file system, this method is dead simple. Make a new file, dump memory into it, throw a marker on the end which signals that the backup was fully completed. Once one backup completes, delete the previous backup (or don't).
  • The backup process may also need to account for things mentioned in the last bullet point of the other section, such as saving in the middle of consecutive commands that should not be broken up. You might opt to lock the entire set of data, dump it to disk, and unlock it, but depending on how much time that takes, it could result in a pretty hefty pause or slowdown in the game.

Save a character on logout (don't save anything else)

  • The most important thing to a player is their character, which includes the items they have, the skills they've earned, their friends list, and so on. If they kill a monster and the loot is on the ground in front of them and then the server fails, they're going to be a little heartbroken at not having the chance to pick up their loot, but they'll get over it. So just save the important stuff, and don't sweat the small stuff. Don't save the positions of NPCs, for example; if the server goes down, when it comes back up, they'll spawn in the general area that they should be in. The exception, of course, is for any "smart" NPCs that for some reason need to remain in the place they were when the server went down.
  • Furthermore, a player shouldn't be logged in for too many hours at a time (note that here I'm considering "going back to a lobby" as logging out). They will eventually need to take a bathroom break or get food or get interrupted by their parent/friend/whatever or sleep. So they really shouldn't realistically be logged on nonstop more than, say, 8 hours for even the most hardcore gamer. If a "player" is logged on for a really long period of time, there's a good chance that it's either multiple people or a bot, and neither one is desirable or normal.
  • Also, your logout process should already be checking for things like the above-mentioned consecutive commands. It should essentially already be packing up the character, so it's obviously a prime time to dump it to disk.

Closing thoughts

  • Clearly I'm in favor of the last approach, but I tried to be unbiased about all three.
  • It's difficult to say which of the first two methods is more wasteful. With the first method, if the character sends several move commands, these will each be saved to disk and overwritten, when clearly they could be packaged up into one. But with the second method, if you have half of your population standing around, their positions are being saved to disk even if they're the exact same since the last backup operation. In the third case, it is very possible that someone could log on and immediately log off, but most often, many things about the player will have changed so the wastefulness seems like it would be minimal.
  • Keep in mind that this is entirely for backup in case of failure, and a failure should be absolutely minimized. It's good to handle this exception case, but in the end, if the server fails, some data is going to be lost and some players are going to be upset. So just implement whatever method you can, whatever you think is simplest or best, and continue on.
  • Don't rely on this as the default save; put in a nice shutdown button on your server application, which gracefully closes connections and writes everything to the database. Use that on a normal basis.

Lastly, don't take this advice as absolute truth. I haven't written a multiplayer backup system. I am working on an online "game", which is why I have thought of this and wrote out my thoughts above, but I haven't gotten to the stage of implementing this yet. So this is written without actual experience, but after lots of reading and collecting knowledge about the topic.

share|improve this answer
3  
From what I have personally observed commercial MMOs use a combination of all three of these. Saves occur after important events and actions such as boss kills / looting / trading, periodically to prevent non-critical actions from being missed (and to not punish those who are logged in for long periods of time), and always at log out. One single method is generally not enough. Almost all of these methods rely on an underlying SQL style database that is transparently backed up and restored if there is a hardware malfunction. –  NtscCobalt Nov 3 '11 at 3:12
    
@NtscCobalt - I was with you until "SQL style database". Is SQL really a requirement? What about NoSQL? –  tjameson Mar 15 '13 at 23:26
    
@tjameson Well my comment was written before I had touched NoSQL. I was only trying to say that you shouldn't roll your own format but anyway I'd still recommend SQL as you should know the schema before hand (or be lazy and use Entity-Key-Value) and consistency is more important than the ability to partition that data. See stackoverflow.com/questions/7339374/… for more info. –  NtscCobalt Mar 16 '13 at 21:20

I suppose it depends on the type of game an the amount of traffic between players and the server.

In an MMORPG, it would not make sense to save the players position every time they send the information to the server. It would make more sense to update when the player's current data is 'stale', so to speak. It might also be beneficial to save the player's state on major events such as crossing into new territory, defeating a boss or leaving a store.

In a turn-based game, it would definitely make sense to save the player's state every time they end their turn as well as after an opposing player's turn (save health loss, spell effects, etc).

Again, the answer depends entirely on scale and the capabilities of your server. It's all about finding the best balance and optimizing as much as possible without sacrificing quality.

share|improve this answer

If your only concern is when they log off, then one simple answer is to save their position when whatever conditions for them no longer existing in the game world (due to log off or disconnect) occur.

On a side note though, I would be somewhat wary of the client reporting to the server it's position, or at very least without some form of server side sanity check. If you already have this in place though, you can likely save that position on log off or disconnect as you don't have to worry about getting any data from the client directly.

share|improve this answer
    
Yeah, hence the need to send regular updates to the server on values like position and XP. The longer you leave it, the more debatable it becomes as to whether the player actually racked up the reported deltas or not. If you restrict those "check-in" time periods its a lot easier to monitor/control. –  Nick Wiggill Nov 2 '11 at 22:30
    
The problem of telling when exactly a player logged off in a long running browser game is actually not a trivial one. –  Lambda Dusk Nov 2 '11 at 22:32
    
I agree it is non-trivial, but it's a problem you have to address one way or another in most games anyway, even if just for deciding when their avatar no longer appears. Once that is done, it should be a relatively simple matter to hook into that scenario and save their last valid position. –  Lunin Nov 4 '11 at 22:32

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.