Advertisement

Seeking Advice on MMORPG Movement Netcode

Started by December 16, 2024 04:23 AM
3 comments, last by RmbRT 3 days ago

Hi everyone!

I’m currently trying to implement MMORPG-style movement netcode, but I’m unsure which solutions are most commonly used. I’m aiming to replicate the movement systems of games like EverQuest and World of Warcraft. Is there anyone here with MMO development experience who can provide a detailed explanation of how movement typically works in these games?

From what I understand, these games are client-authoritative when it comes to a player’s own position (often over a TCP connection) — meaning the client informs the server of its location. However, I have several questions about the specifics:

  1. Frequency of Updates:
    How often does the client notify the server of its position? Is it around 10-20 times per second, or only when the player presses a key (like WASD) and changes direction? And how often does the server send your positional data to other clients?
  2. Server to Clients Communication:
    Does the server send positional data and velocity, relying on other clients to apply dead-reckoning or extrapolation? If so, how do these clients handle lag or network jitter? Extrapolations are bound to be incorrect eventually due to network variations — is there a smoothing technique used to address this? Or does the server send position and rotation data to other clients 10-20 times per second, allowing clients to interpolate between the last two states? If so, what happens when a packet is dropped, does the system switch to extrapolation to maintain fluid movement?

These are the challenges I’m currently facing. If anyone has insights into this topic, especially from MMO development experience, I would greatly appreciate your input! There seems to be a lot of “the blind leading the blind” on this subject, so any expert advice would be invaluable.

Thank you!

None

There are a few different methods of updating data like this.

EverQuest famously sent snapshots of entities, and interpolated all the values – hitpoints, location, orientation, … When someone got snapshotted while turning, and then it took a while before you got the next snapshot, they would keep spinning in place on the remote screen. I wouldn't recommend using this extremely basic mechanism these days.

There.com used the “deterministic simulation” model. Send initial state, and send all commands with timesteps, and run the same simulation on server and client; they will come to the same conclusion about the outcome. Detect de-sync with occasional checksums, and re-send snapshots at that point. This saves a lot of bandwidth, but adds a lot of complexity that a modern game may not need, because bandwidth is not particularly scarce these days.

Some modern MMOs use Unreal Engine, and may even use the built-in networking in the engine, which is based on frequent snapshots with interpolation and class-specific movement controllers, and scales fine up to maybe a hundred players or so. (If your MMO wants more than 100 players within view of a player, you will have a bunch of other game design problems in addition to networking!)

There are a few decisions you have to make:
- Do I see “all” entities in my “area” or do I only see some subset? (this depends on game rules – does everybody in the same area see the exact same set of entities?)
- If my connection chokes up, do I see fewer entities in high quality, or same number of entities in lower quality? (this is visibility management versus update rate)
- Do I see entities “approximately where they are right now,” or do I see entities “exactly where they have been, but delayed in time?” (This is extrapolation vs interpolation)
- Do I use TCP, with its ordering guarantee but occasional data delay, or UDP, with its “fast or never” possibly lossy behavior?

The simplest thing that could possibly work, would be something like:
0. Build basic levels, and everyone in the level sees all entities in the level. When joining/leaving, everyone hears about it.
1. Set up a timer for how frequently you send updates. Call it 30 times a second.
2. In each update, figure out how much you can pack in (this may be based on previous acknowledgement, or a fixed upper bandwidth limit, or something else)
3. Send snapshots for the most important objects first, followed by some amount of “other” objects, on a rotating schedule.
4. Display objects “after the fact” following a path you can know for sure they have previously followed.
5. One-shot actions that affect the world (spells, attacks, etc) should be sent as events that are packed first in the packet, as “most important”
6. Use TCP. It's fine for a MMO.
7. Even if “events” are delivered over TCP, send occasional full-object snapshots. There are always bugs, and fixing up the game experience when you miss that someone changes their clothing or whatever is helpful.

So, position/velocity/orientation might be sent every packet for each player in your current group, and each mob within attack distance of each player in your group. The same snapshots may be sent on a rotating schedule for each other player and mob in the area. One full snapshot of one player (or mob?) might be finally packed into each network packet. If there's 300 entities, and 30 packets per second, this means you get a “full” snapshot every 10 seconds for each object.

enum Bool { True, False, FileNotFound };
Advertisement

Both of your question categories are “It Depends” style of questions.

On the frequency of updates, what does your game do? What do you need to actually feel responsive? The games back in the golden age of RTS would often only update their simulation 4 or 5 times per second, meaning 250ms or 200ms. Halo Infinite had this writeup, where they chose a 60 Hz (~16 ms) tick rate for 4v4 and 30 Hz (~33 ms) tick rate for BTB 24 player mode. IIRC, World of Warcraft originally had 4 Hz (250ms), then over time certain dungeons had faster tick rates, then when server load dropped and machines were faster rates were increased again. Fortnite originally used 20 Hz, they increased it in 2018 to 30 Hz after both tremendous efforts on code performance and a windfall of money to pay for bigger server machines.

Be mindful that simulation tick rates don't need to match what you see on the screen. Interpolation gives a lot of additional time, the time it takes for units to walk around, for bullets to travel, and latency mitigation like playing an audio event while you wait or different-length animations, all of them allow for games to feel responsive without having the game world simulate faster. Game clients can locally be playing animations at 144 Hz grahpics update rates even when the simulation is running at 30 Hz or slower.

Details of it will ultimately come down to the individual game.

On what data gets communicated, it is questions about what you actually need for the game, in combination with the frequency mentioned above. If your simulation ticks at 250 ms you've got quite a lot of time to batch information up and send it over the wire. If your simulation ticks at 60 ms, or 10ms, you'll have different amounts of time to do that.

You can never beat the speed of light, or the speed of electric signals over the wire, so your latency will always need to be a consideration.

There are some good comments by hplus on that above, and most of those decisions all come as tradeoffs. One enormous decision with tradeoffs is how much of the world is seen by everybody. If everybody has to see everything all the time your world needs to be small, which is fine for a small brawl-style game but terrible for an open world. If information is limited on each client then determining what each client knows, when they know it, and how they stay in sync will be tradeoff after tradeoff, balancing both what the hardware does as well as what the game simulation does.

On it being “blind leading the blind”, while that can happen, in professional settings it a balancing act with tradeoffs being made. Money is a big one: How much can a company afford for game servers? Faster processors cost money, and simulation costs processing. Bandwidth costs money, and tick rate increases bandwidth. Does your game require a server on the cloud that costs 0.02 per hour, or a machine that costs 3.83 per hour? Does the server run a single game at that cost per hour, or hundreds of games at that cost per hour? Popular games can pay many million dollars per month in hosting fees.

If your MMO has attacks like in WoW where you don't aim bullets, but simply select an enemy and then perform an action, positioning isn't that important, since you're not using hitboxes and raycasts. The only instance where it would be relevant is for AoE stuff, but even then you can adjust the mechanics to make them tolerant of slightly inaccurate positions (such as having a fade function instead of a hard cutoff at the edges of the AoE effect).

All logic should be deterministically decided by the server, to prevent cheating. So in the end, the only problem you're left with is how to make movements look smooth and how to have people at roughly the right position. Slight deviations during movement are not a problem.

It's an entirely different beast altogether if you need CoD style exact hitboxes etc. But then, you'd not want to use TCP anyway.

Walk with God.

Advertisement