In the last dev blog where we talked about the last two playtests networking came up a lot. Either it was network lag, strange movement, and a general concern about client authoratative movement.
Last week I decided to bite the bullet and try to nip this in the bud.
This was a huge undertaking and my brain is still a bit fried from all of this. I worked super long days for essentially the whole week but it paid off.
Server Authoritative + Client Predicted
In basic terms we need to make it so when a player wants to move, they send the input command to the server, which then processes the command causes the players character to move.
On the (player’s) client side, this command is “predicted” by running the same movement logic and having the player character move before the result from server has arrived.

This diagram illustrates the time it takes for the move command to reach the server and then get back to the client. In our code we don’t wait for the server response to update, instead we take our best guess at what it would be (by running the same movement code.)
If for some reason the server response/update differs from the client predicted state, reconciliation happens, which in simple terms means we drop our predicted state and replace it with the server state.
Moving Platforms
Things start to get really complicated when you want to support a player being on a moving platform. Something like an elevator or a tram.
I got the core server/client architecture done in like a 1.5 days, but getting this part to work right was much more complicated. I’m still not 100% happy with it but I think it’s the best we can do right now.
Lag Compenstation
The magic really happens when we do things like shoot other players. Engines like Source or Unreal handle this by “rolling back” the world state to the moment when the client shot the bullet, and seeing if the bullet would collide.
This essentially means that as long as the client saw the bullet hit, the bullet would hit on the server. Since it takes time for the client input to get to the server, rolling back becomes necessary because the world state is no longer the same on the server.
Okay so let’s look at this demo.
The lines represent the bullet path as it flies.
The purple shapes represent the rolled back hitboxes of the player.
What’s happening is I (the client) am shooting be clicking my mouse. I immediately see where the bullet impacted on my screen (white sphere debug draw) and then a moment later i see some purple shapes show up, as well as a yellow line.
The yellow line represents the servers interpretation of where I shot from, and the bullet trajectory. The purple shapes are the hitboxes that the server believes that I saw. We see green circles when I hit a player and both the server and client (me) agree.
This is being recorded with 200ms of lag, which in my mind is the very max someone should ever play with (though honestly 100ms seems more reasonable.)
This is hard to talk about
This is a lot of deep stuff that’s kinda hard to talk about. My brain is a bit fried from all of this still so i’m trying to do my best. I haven’t posted a blog post in awhile so I wanted to post something even if it’s a bit half baked. I might do a follow up post in the future about this.
What’s next
This was all built in a separate test project, just to prove out the concepts. Next steps are to make sure i’m not code smelling much, and then it’s going to be to introduce this into the Morbus codebase and migrate the players to use it.
I’m sure this will be a tedious and bug heavy process so i’m not predicting another Morbus playtest for at least another week.
Leave a Reply