Wednesday, August 20, 2008

Playing Nice with Lag

Preface: New method of interpolation and "slack" to minimize "hitching" (suddenly jumping location while walking because of a lag spike.)

Every online gamer at one point or another will experience LAG. It is sadly a fact of life.
Although I've been busy trying to minimize bandwidth and packet exchange where-ever possible until this point, delays in a network router somewhere between the server and the clients could cause a sudden lack of communication. If that delay is even half a second, players may notice a "jolt" in their movement as they resynchronize with the server. This in inevitable playing over a network as large as the internet.

So I began looking at ways to minimize the effects of this; and came up with the concept of "movement slack". Basically, when moving between tiles, the client and server generally don't have to agree on the exact location of the client at the exact moment. In fact, even without changing any code, it is impossible to have PERFECT synchronization. What is important however, is the location where the client is going - ie; their destination.

So, to use this in our advantage I have changed the synchronization routines a little, and it looks something like these 2 flow-charts (click to enlarge):




As you can see, the server now has a "tollerance" for the client to choose the stop location, but to avoid exploits being made of this, there are a number of guarding factors in place:

I add speed-hack proofing server side. So, although it "trusts" the client's "stop location" (the location of your char whenever you let up on the movement keys) within 2 tiles (value can be changed in the INI but 2 is the best), it only trusts stop-location packets that arrived more than xms apart or so.

to test it out, i actually modified client code to add a "speed hack" and if i remove the check the speed-hack works, by basically bombarding the server with UserPosition+StopAtPos packets (a kind of modified version of the Server_SetUserPosition packet)

Sure enough, without any checks, the player can zoom around the map at insane speed (illegally)

So this check is necessary, after applying the speedhack check I tested again; With the checks in place, only legal movements are allowed

The nice thing about this new feature (the new StopAtPos packet) is it keeps the client + server more synced up, but places trust on the clients location by x tiles (default is 2; loads from Server.ini), but does so in a secure way, AND sometimes saves a packet from being sent when the user lets up on the movement keys. It is like win-win-win situation

Also note that it does not add any bandwidth, as the StopAtPos packet is basically just a replacement for the SetUserPosition packet in a specific situation (when the player stands still after moving)
and on client side, when moving, it doesn't "jump" the client around when an update is recieved from the server about location and the client location is less than 2 tiles off, it more fluently remains synced. To test it, I set the Packet_WaitTime to 600 to simulate a ping of 600+

No comments: