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.

I'm confused how to handle the players in my MMO server (using Socket.IO but I think this should apply to any MMO).

Suppose there are 2 players in my server that are far away from eachother. I will call them A and B in this example.

The server launches. No clients are connected.

A joins and is added to the server's active playerlist.

Every second A gets a list from the server with the active players nearby to update their positions. Since there are none online currently, the list is empty.

B joins, far away from A. The server adds B to the active playerlist. Since A cannot see B yet, the list that A receives from the server is still empty.

B is moving towards A and comes within visual range.

What to do now for A? Send an event to A that B has come within range? How can the server know that A was informed of B being nearby? Does this mean I have to maintain a list on the server which player can see another?

Here's what I was doing before with my previous project: I never told the clients that a player was in range, instead the server just sent a list every second of players that are nearby and let the client do the rest. This way, the client keeps track which unit is added and which is not. Is this the best approach, or am I missing something?

share|improve this question
    
In your solution, consider the size of the other player (or object), not just distance. A tiny object doesn't have to be drawn until pretty close to the player. A huge object should be drawn at a much farther distance to avoid suddenly popping into the scene. –  Tim Holt Apr 25 '12 at 16:33
    
Will keep that in mind! Although in my case I think the size doesn't matter that much, as huge objects should load statically and not from the server. –  Nick Apr 26 '12 at 10:22

5 Answers 5

up vote 5 down vote accepted

Nic explained this to me briefly yesterday. Check out the explanation on his blog.

http://nic-gamedev.blogspot.com/2011/11/mmo-architecture-creating-ghosting.html

share|improve this answer
    
Thank you, this was a very useful read! –  Nick Apr 26 '12 at 8:47

It's quite an advanced topic, and as word of warning I'm hesitant to indulge too much in to this because I only know some theory and haven't actually produced an MMO.

In MMOs, optimization is perhaps the primary factor in decision making on the technical side. The more users you are able to host, the better. It's easy to accidentally use poorly scaling methods, and I recommend you find a good external resource on this.

The movement updates are a critical piece of any MMOs: They occur very often, and you will want to restrict these updates as efficiently as possible to others. Do consider carefully if you really require the visibility information to be part of server-side calculations. Most games only divide the world with some form of space partition in to many cells. The server then keeps track of which cell the player is at and informs that cells and nearby cells' users, when it comes to move-updates.

For efficiency, server will assume that clients keep track of the world accurately and will usually send out only when player has moved and output all new positions when moving from cell to another, or when player disconnects or connects etc. Usually absolute positions are used for movement updates. Client can keep its own state of the world and remove players in farther cells according to the same rules server uses.

Merely relying on these updates can sometimes lead to bugs and strange behavior though if the client's state strays from server's state, but for optimization's sake, we should rely on client to perform as intended. Client messing up only affects that one player usually, which is reasonable price to pay for being able to support more players on the server.

For other less-frequent actions, it's much cheaper to check the actual distance when you know the interacting players. For actions that target areas rather than other players, you would check against the cells first too. Space partitioning can be quite advanced topic, but probably what you want/need.

share|improve this answer
    
Thank you for this thorough explanation, I am learning more about space partitioning now! –  Nick Apr 26 '12 at 9:08
    
Well, I think it's more commonly called "spatial partitioning" now that I think about it. But you're welcome. –  Toni Apr 26 '12 at 9:57

Take position of player A. Subtract position of player B. Get the length of the resulting vector. If it's under the sightrange, add the other player to a list that a player can see. This will help you with all updates, ie you don't need to send all movement/socials that a player that isn't visible is doing. You can do the initial check fairly seldom(say once every few seconds), and then check for removal from the list every second if you're worried that it might take alot of processing power.

share|improve this answer
    
Thanks for the answer Eric, and welcome to GDSE. –  Byte56 Apr 25 '12 at 21:05
    
Consider using two different distances - one for sight, and one for what you're caching. You'll want the area just around what you can see to be cached. How far out you want to cache is a performance metric that should be determined experimentally. –  corsiKa Apr 25 '12 at 23:22

Does this mean I have to maintain a list on the server which player can see another?

Basically, yes. The way we did it on a previous project was that each character had 2 lists: one of IDs of the characters that it knew about, and one of IDs of characters that knew about it. (Obviously it's possible to derive the 2nd list from the 1st but it's quicker just to keep the 2 updated in parallel.) To decide what information is available to the character, you use the first list, and when deciding who to broadcast updates to, you use the second list.

How to manage the list(s) is basically a mix of a game design issue and an optimisation issue; ideally the list would always be "every other character in the world" but practically that doesn't tend to scale. So you may limit the lists by distance or by zone, or you might choose to update them only periodically, or you might sort by distance and cap the length of the lists, or some combination of the above.

share|improve this answer
    
Interesting! How was the performance in your server? Perhaps your way in combination with a cell grid (spatial partitioning) might work well. Also, what would be the difference between the two lists? I mean, why not just use one list? I drew an example on paper with 4 points representing players and came to the conclusion that the two lists should always be the same for each player, unless some players can see further than others. Am I missing something? –  Nick Apr 26 '12 at 9:06
    
Performance was fine - there's nearly always some other slow logic in the system or a networking bottleneck long before these calculations become an issue. The lists can be asymmetrical if not everything has the same visibility range, or if certain characters are invisible to others, etc. Consider customer service or gamemasters, or NPCs. –  Kylotan Apr 26 '12 at 12:59

One option is to make the server simulate what the client knows. You can then compare that to the real game state on the server and send update messages to the client when there's a difference.

The main benefit from that is you can use that information to minimize what you send to the client. Stationary objects only need sending once for example because after that the client and server will be in sync.

If you have limited bandwidth you can send only the updates for objects which are the worst synchronized to the client and leave ones which only have minor changes till later on.

share|improve this answer

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.