Sync velocity or just interpolate positions?

Started by
1 comment, last by hplus0603 7 months, 3 weeks ago
Client.prototype.interpolateEntities = function() {
 // Compute render timestamp.
 var now = +new Date();
 var render_timestamp = now - (1000.0 / server.update_rate);

 for (var i in this.entities) {
   var entity = this.entities[i];

   // No point in interpolating this client's entity.
   if (entity.entity_id == this.entity_id) {
     continue;
   }

   // Find the two authoritative positions surrounding the rendering timestamp.
   var buffer = entity.position_buffer;

   // Drop older positions.
   while (buffer.length >= 2 && buffer[1][0] <= render_timestamp) {
     buffer.shift();
   }

   // Interpolate between the two surrounding authoritative positions.
   if (buffer.length >= 2 && buffer[0][0] <= render_timestamp && render_timestamp <= buffer[1][0]) {
     var x0 = buffer[0][1];
     var x1 = buffer[1][1];
     var t0 = buffer[0][0];
     var t1 = buffer[1][0];

     entity.x = x0 + (x1 - x0) * (render_timestamp - t0) / (t1 - t0);
   }
 }
}

https://www.gabrielgambetta.com/client-side-prediction-live-demo.html

in this article, specifically this line:

entity.x = x0 + (x1 - x0) * (render_timestamp - t0) / (t1 - t0);

He sets incoming positions from the server directly by lerping them rather than setting velocity and letting the clientside gameloop move it along by velocity. Do most games do it like this?

It seems like quake does both(lerping both position and velocity)

https://github.com/id-Software/Quake-III-Arena/blob/dbe4ddb10315479fc00086f08e25d968b4b43c49/code/cgame/cg_predict.c#L250

out->origin[i] = prev->ps.origin[i] + f * (next->ps.origin[i] - prev->ps.origin[i] );

out->velocity[i] = prev->ps.velocity[i] + f * (next->ps.velocity[i] - prev->ps.velocity[i] );

which seems a bit weird to me because wouldnt this be subject to overshooting? Say you want to lerp from tiles x: 1 → x: 2 , well if you just lerp between the two positions and set it directly, it will be just fine. If you lerp positions AND set velocity, I'm presuming somewhere else is doing pos.x += dt * vel.x , which means you're going to be moving a bit farther.

Advertisement

Exactly how you do this depends entirely on what experience you want to deliver to your users.

Because of latency, you have the option to show “mostly correct positions, delayed in time,” or you can show “predicted current positions, but sometimes out of place.”

If I remember correctly, this little app lets you check out the interpolation/extrapolation behavior: https://github.com/jwatte/EPIC

enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement