I am trying to interpolate players in a multiplayer game like so:

var lastTime = now - (1000 / config.serverUpdateRate);
for (var i = 0; i < players.length; ++i) {
    tmpObj = players[i];
    var total = tmpObj.t2 - tmpObj.t1;
    var fraction = lastTime - tmpObj.t1;
    var ratio = fraction / total;
    tmpObj.x = UTILS.lerp(tmpObj.x1, tmpObj.x2, ratio);
    tmpObj.y = UTILS.lerp(tmpObj.y1, tmpObj.y2, ratio);

The server update rate is the frequency with which the server send the player positions. The x2 is the newest position and x1 is the position from the previous update.

Now this works fine on my localhost and on an empty server. But as soon as the game server has around 60 people on it, it begins to stutter. I am assuming that this is because the positions are coming in at an inconsistent rate. How can I adjust for that in my interpolation?

You can see the issue in action here: http://moomoo.io

I have tried to simply interpolate without lerping, but the movement felt too floaty. Also client prediction is not an option in this case

  • \$\begingroup\$ How are you assigning x2 and x1? I assume t2, x2, y2 are all the most recent snapshot from the server. Are you treating t1, x1, y1 as the previous snapshot, or as the interpolated state of the object at the time the newer snapshot was received? \$\endgroup\$
    – DMGregory
    Mar 25 '17 at 16:54
  • \$\begingroup\$ Professionally, I come from a different background (EE / Signal Processing), so I'm not sure if this is applicable. Have you heard of a Kalman Filter? You can use a Kalman Filter to track e.g. radar targets over time. The idea is that the position information is noisy and the Kalman Filter takes in the noisy measurements over time and uses them to reduce the error due to noise. The data you have might be "perfect" position information but slightly unknown time information. But I think it's mathematically the same. \$\endgroup\$
    – derstander
    Mar 27 '17 at 0:07

I doubt there is any healing interpolation magic...

You could try to synchronise time for all clients, against one or multiple time servers, then embed a timestamp in the packages and inter/extrapolate movement based on that. Then it won't matter if the transmission times are unstable.

By that you don't change the computer clock, just calculate and use an offset between that (the local crystal and frequenxy) and sync'ed world time. You should get an accuracy of a few milliseconds. PC clocks typically have an error of 0...a few seconds per 24 h, so one may have to re-sync now and then.

The local crystal is stable and fixed (eg. the QueryPerformance API in Windows). Windows "stretches" that (adjusts over a longer time period) when announcing clock time, so the "clock time" itself is useless - one must get down to the hardware.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.