Character KnownLists in MMORPGs or as Such?

Started by
14 comments, last by Antheus 15 years, 8 months ago
How do games use World Entities. In such, you have 5,000 people online in games like Lineage 2, or World of Warcraft (Although they have instance in WoW). How do games keep up to date with your "KnownList" or "Visible Objects". I have researched in Open Source MMORPGs such as RunUO, and ArcEmu (World of Warcraft emulator), but unable to find an active idea on how they go about it. An easy way to answer the question, Do GameServers update a KnownList every X seconds? Things come into play, say a person is sitting, then you walk into the zone, well you must start with a packet saying the character is @ a Rested state. Does the server by Each Character? Does it work by Regions, IE Every region cycles through an update? I don't mind reading, so if you just post a link, I am 100% Fine with that. Thanks for any information you can provide.
Advertisement
Whenever an entity moves into the area of interest of a user, you "subscribe" the user to be interested in the entity. When you subscribe the user to the entity, you can send the user the creation information for the entity. From here on, every user subscribed to the entity will receive updates about the entity. When the entity leaves the user's area of interest, you unsubscribe the entity, and send a "destroy entity" message to the client.

The client only has interest in what it can see, plus a little to avoid delays on the creation of the entity (resulting in it appearing suddenly). There is no reason the client should ever be updated about an entity nowhere near them.
NetGore - Open source multiplayer RPG engine
Spodi,

Thanks for your post.

Few questions. How does the server update with the client? In sense, after someone moves into the range. We have him in the list. Now lets say the player sits. This is a new packet. We go through and say

Foreach (Player in List)
Send Sit Packet.

The server doesn't say every X Seconds go through the list and re-check the Range List? Or everytime it moves we re-check?
It depends. I assume you are using TCP or reliable UDP. If so, the easiest way is to do just that - send the message needed to notify all subscribed clients of the change*. To the entity sending the message to subscribed clients, all that it cares about is that the message is created and the subscribed clients get it. When this is actually sent depends on the network manager. For a MMO, you will most likely want to queue messages for a while (kind of your own Nagle-esque system) if your game can afford the extra latency. When you send the message, you will want to send as many at once as possible since TCP/IPv4 has at least a 40 byte overhead per send.

As for checking if clients are in range or not, it is up to you. At most, you will only want to check every affected subscriber when an entity moves, or if the client moves, every entity they are subscribed to. There is no point in checking anything else since they are not affected by the movement. You can lower the checks by checking only after T time has elapsed or after moving D distance, but since the check is probably a very simple and fast "rect contains point" check, I doubt it'd cause you any problems even if you had hundreds of subscribed clients.

*I'm not saying that you should have your entities sending messages, nor am I saying you shouldn't. How you design your code is up to you.
NetGore - Open source multiplayer RPG engine
Optimizations from rendering can help here. Specifically, if you can pre-compute a number of cells with a Potentially Visible Set from each, then you only need to change the visibility set when an object moves between two cells. I would keep the cells fairly big, to avoid too much computational overhead when objects move, because if something changes cell each tick, the network won't keep up with that anyway.
enum Bool { True, False, FileNotFound };
One way to manage majority of events is through a proxy server, which deals with actual clients.

The model then becomes something like:

Player --+Player --+-- Proxy --- Game ServerPlayer --+


Proxy receives all the messages, but also manages subscriptions.

Subscriptions can be managed through 4 messages:
- InitialState(client, entity) // subscribes client
- StateDelta(entity, ....) // sends what has changed
- Unsubscribe(client, entity) // individual client went out of range
- Destroy(entity) // entity no longer exists

When proxy receives InitialState message, it adds the client as a subscriber, and forwards initial state to that client only. Any additional events generated by that particular entity will be sent to all subscribers.

For example, let's say OnSit(entity) message arrives to proxy. Proxy will look up the current subscribers for the entity, and forward the message to them.

Proxy may or may not be a separate process, depending on the design. The biggest advantage of this approach is that it takes care of subscriptions, while keeping logic simple, since it completely ignores the range checks. Whenever a client is made aware of an entity, it will keep it updated as well. While game server will still use them to subscribe entities, the process of subscription becomes somewhat de-coupled.

If proxy is in a separate process, or on a separate machine, this model also reduces the traffic on LAN, since it will generate one single message (per proxy), regardless of how many clients need to receive the message.

This approach is more suited for logic where real-time response isn't highest priority, since it abstracts the replication logic. Messages can be prioritized, but not necessarily on per-client basis. It is however a fairly trivial and reliable model for this type of games.

For real-time or FPS-like games, finer control over message for each individual client may be desirable.



Another thing of interest when it comes to visibility sets - in most games, cities will be somewhat "overdesigned". Lots of hills, doorways, tunnels, high walls, all seemingly annoying. But the main reason for this is to minimize line of sight in crowded areas.

It's not uncommon for entrances to buildings to contain a curved corridor, preventing player to see inside. Same for windows, which tend to be opaque. While this helps with rendering, it can also benefit the network. The 200ms player will spend entering the building through the doorway will be used to load the contents of the building, while everyone else outside will not need this information.
Hello. Great stuff! Thank you.

I actually am doing a Proxy. Well 2 really. We have proxy which is the recieve/send of all Packets. Then we have a GameProxy. Which controls the current knownlist that I want to change.

I do currently have the world seperate into regions. And I have 5 Threads running each region to avoid 1 thread maxing @ 25% usage. You speak of the "When in Range". What do you suggest compute this, my guess would be the cell manager I have? Process through each entity in the cell, if within range, add to the proxy InitalState? Then when you recieve a packet filter through all players in the StateDelta?

Again,

Thank you all for your time, your logic, and your support. My MMO fans are in great appreciation.
One more thing,


Your saying that my KnownList should consist of not who I know about, but who knows about me?
On the sending side on the server cluster, for each connection, there needs to be a list of everything that that connection can see. However, for some designs, it makes sense to have a list for each entity of who knows about that entity. Then, when the entity moves, you can mark that entity as dirty for each connection that knows about that entity. At the communications tick rate, the connection will look at the dirty entities, and send an update for some number of them (in some priority order depending on time since update and distance from player, say).
enum Bool { True, False, FileNotFound };

The large MMORPGs have clusters of proxy servers. The intra machine transfers have to be optimized and the individual machines can have subscriptions (set depending on what zones their players are in) to the event-marshaling zones/cells. They then customize what events each player gets sent.

You want to minimize redundant intra server network traffic. One way is this 'two-level' system where coarse groupings of event data happens which then is subdivided locally (at a finer level) in the proxy server.


When the cells are small enough you dont have to subscribe to each individual object. If they are too small you spend alot of processing transfering the mobile entity's 'locality' (which cell it posts to) and more overlapping boundry special processing (where an object either also reports to its adjacent cells or the subscriptions have to be made to the listening object;s adjacent zones --- and add removal of duplicate events probably done at the proxy).
--------------------------------------------[size="1"]Ratings are Opinion, not Fact

This topic is closed to new replies.

Advertisement