Saturday, November 12, 2011

MMO Architecture: Creating a ghosting system

In this post I will talk about a common part of an MMO's internal architecture, often referred to as ghosting. Ghosting is how the server tells the client about the world loading around the player as that player moves through the world. Because MMOs are often open-world games you cannot simply have the player load up all of the objects in the entire zone they're in, the game just couldn't run like that on a single player's computer. On top of that the server would have to constantly update every player about every thing happening within a zone, which would create bandwidth issues for both clients and server.

I'll discuss a few different, but similar, ways that ghosting can be achieved (I'm sure there are other ways as well). First of all, the server will only need to send down information of objects in the world that are not environmental, for example there is no need to send information to a client about a tree they're in range of, because that tree is likely static and can never change. The client will know about that tree based on assets/files on their own computer. The server will have an easy way to know which objects have information that can change (like their position, or stats, or state, etc...), so the main work the server will need to do is determine which of these networked objects are close enough to the player to tell the client about.

Method #1: Ghosting objects within a proximity around the player
With most physics engine the most efficient way to ghost objects within a proximity of the player is to give the player an axis-aligned bounding box (AABB). Axis-aligned shapes will have smaller broadphase sizes, which will result in them being checked against less objects for collision. Attach an AABB to a player on the server, and whichever networked objects collide with this box are entered into a list to send updates to the player about. Whenever the object un-collides with the bounding box then the server can tell the client to unload that object. Generally this bounding box is large enough the player doesn't see all of the objects loading and unloading right around them.

Method #2: Ghosting objects that have players in their proximity
This method is similar to the last method in that we're ghosting objects to clients based on proximity to those objects, the difference here is that rather than attaching an AABB to the player, you instead put AABBs on the networked objects instead. This method has its pros and cons. On the plus side this allows designers and engineers to tweak the distances that an object with ghost down to the player, on a per object basis. This means that if an object is deemed to be a higher priority than other objects then designers can increase the distance as which they'll ghost to players. The down side to this method is that it will use more memory and hit performance a bit more on the server, this is because you have potentially many more AABBs in the world checking for collisions.

Method #3:  Distance checking
This method is similar to method #1 in that it is proximity-based. This method entails mathematically brute force checking the player's position against the position of ghosted objects nearby. To realistically use this in a large-world MMO you would need some kind of spatial partitioning in your world so you knew which sub-set of objects were close enough to the player to do distance checking again, otherwise you'd likely be doing hundreds of distances checks per frame per player, possibly many more. If you already have spatial partitioning in your world you may not even need this method, which leads me to Method #4.

Method #4: Spatial partitioning
If your MMO's world is using a decent spatial partitioning algorithm to sort the scene then the server may already know which networked objects are close enough to the player, and could send those objects down. This method is the least expensive in terms of how expensive the ghosting is, however the spatial partitioning itself has a decent expense to it most of the time, so if ghosting was your only reason for using spatial partitioning on the server, then you're probably just as well off using Method #1 so long as you have a decent physics engine (as most physics engines have their own spatial partitioning anyway).

The above methods will allow you gather the objects that a client will care about. From here it's fairly simple, when the objects first enter range of the player (or the player first enters the object's range), you send the player an initial packet with the full current info about the object, and any changes that need to be networked while that object is in range will also go the player. This allows the player to get the full info as objects enter range so that they can see that object in the same state that the server does, and then it should receive any changes from the server object while it's in range as well. Combining all of this gives you a basic but fairly complete ghosting system for an MMO.

2 comments:

  1. Good article. Instead of commenting on the subject matter of the article, I would like to say a few words about the term "ghosting".

    First off, I want to acknowledge that a term is needed to discuss the subject of this article, and also that it is definitely related to ghosting. That said, the way that the term ghosting is used in this article is different from my personal definition of ghosting

    This made me look up a definition of ghosting on wikipedia, and google the term ghosting in relation to MMOs. As it turns out, ghosting is used in many different contexts, but does not seem to be very well defined at all when it comes to online multiplayer games.

    I made a wiki account to create a definition, but need to be able to find some good references to support my definition, otherwise it is just opinion.

    So I will leave you with my "opinion" of the definition of ghosting:
    The word "ghost(ing)" was chosen because it describes something you can see, but which is not really there.

    In an MMO, this is caused by a client being out of sync with the server (which is the authority on what is what), causing the client to display things to the end user, which are displaced. This can be subtle and be recovered by re-synchronizing with the server, or a complete breakdown, where the entire world is ghosted (for example if the client has lost connection to the server).

    Based on this definition, "ghosting" is not something that should be achieved. Rather it is something that must be avoided. A different term is needed for the subject of what/how objects should be loaded/visible and unloaded, as this by itself is only related to the separate topic of keeping a client and a server in sync.

    ReplyDelete
  2. Yes, I believe different networking architectures or game engines call this different things. In this case it was fresh in my mind as the last project I was coming off when I wrote this used the term. We were using RakNet for networking. I'll see if I can find some resources for what else this may be called within different engines.

    Thanks for the food for thought, I hadn't really thought about the term itself much before now.

    ReplyDelete