🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Detecting entities coming in range and replicating their static data

Started by
1 comment, last by hplus0603 2 years, 7 months ago

Heyo, I'm fleshing out the replication logic for my single-server MMO engine and could use some help.

I already have movement replication working, but I'm adding the replication of data that you only need to send once when you first see a new entity (just name and sprite for now). The scenario I'm trying to support is “client's entity walks in range of peer's entity → server sends peer data (name/sprite) to client (and client data to peer)”. My first thought is an approach like:

During a server tick:

  1. Move all entities.
  2. For each client entity, build a list of all other client entities that are in range of it (using a spatial partitioning grid).
  3. Compare the list of in-range entities to a saved list of in-range entities from the last tick.
  4. Send the data of all newly in-range entities to the client (and maybe also tell it which ones just went out of range).
  5. Save the new list, to be used next tick.

Is this the way to do it? Or is there a more efficient way to handle this?

Advertisement

Yes, typically, you will have a set of entities that are visible, per viewer. This ends up being n-squared memory/pointers to manage, which is in fact one of the things that end up limiting the scalability of MMOs from being just purely linear. (Although the game design of trying to draw 1000 players in the same screenful location is more of a challenge, on modern hardware that could otherwise keep up…)

A straightforward algorithm is to run, for each player, a spatial query against their viewing radius, and update each entity that is within the viewing radius with a “last seen at tick X.” There, in turn, you probably use a double index structure, where you have a hash table from entity ID to viewed-entity record, AND you have a heap/priority queue (or maybe just a set of buckets) which tells you when an entity was last seen. When an entity is seen in the query, and is not found as currently visible when you try to look it up in the hash table, you know that this is a “newly visible” entity, and can schedule the static data for sending.

You'll typically also walk the list of all entities visible to a player, and send updates about them, perhaps on some schedule. And when you do this, you can detect entities that have not been within visibility range for some time, and schedule a message for “this entity is no longer visible.” Depending on how you implement reliable state replication, you may still need to hang on to the entity visibility record until the other end acknowledges the packet that contains the “not visible” message, though, so that you can re-send it if the message gets lost. If you use TCP, then that's obviously less important, but then you instead have to live with TCP withholding newer information from the recipient while it's waiting for retransmission of older data. There are many ways to skin that cat.

enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement