Smoothing out extrapolated positions when working with physics simulations

Started by
2 comments, last by pTymN 17 years, 4 months ago
Hello. Im working the multiplayer part of a game that uses a physicssimulation (novodex). The game is really simple, you control a ball which you roll around with, trying to push the other players off a platform. Iv approched this with a client/server model. The server runs a physicssimulation, and sends position updates of all objects except the balls which the clients control to each client. However, since its physics involved, i also run a simulation on each client, and since responsivness to input controlls are really important, each client controlls its own ball, and sends its position to the server, which distrubutes it to all clients. However, when a client receives an position update. The simulation on the client often have a diffrent resulting position from what the physicssimulation have calculated then from what my simple extrapolation algorithm have. (since the internal physics of the simulation is really advanced, takes into account stuff like friction, angular velocity etc) While the extrapolator only calculates the new position based on time and velocity and direction. However! It works pretty good, it actually looks "good enough". But sometimes when the diff between what the extrapolator calculated and what the client simulation did, there is a small unsmooth "jump" of objects. Anyone got any good advice on how to apply interpolation between the the extrapolated position and the calculated physics position? Since they change on a frame basis, i find it hard to just interpolate over time.. Im not sure how to explain it better. (on a side not the clients must run the simulation for all objects and cant just take server positions from the extrapolator since collisions etc must work clientside) Thanks in advance
Shields up! Rrrrred alert!
Advertisement
I'm gonna start off by saying that 1.) This is a hard problem, and 2.) I'm hardly qualified to answer it, seeing as I've got about 50 questions somewhere on this forum that all involve either the word prediction or the word interpolation. Nonetheless, I like to talk, so let's see what we can do.

If I'm understanding the structure of your system correctly, you're going to have to deal with some innate problems. First off, collisions absolutely can't work client side. That's because neither one of them has accurate current data about the position of the other client. If A thinks he collided with B but B thinks she dodged out of the way at the last second, at least one of them is wrong. That's why collisions are generally decided by the server alone.

Now, you need the client to be responsive, and you certainly don't want to wait a whole round trip before you notice a collision, so what do you do? I don't know. Normal movement can be handled with client prediction, but collisions are gonna be messier. You can factor likely collisions into the client prediction, but if they don't happen and you expected them to, there's going to be a jerk. Sadly, a game that's 90% about collisions is really hard to do with a laggy network. Maybe somebody else has a better idea.

I may have misunderstood your design, since you mention you're using an extrapolation algorithm for something. But I think it sounds like, and tell me if I'm wrong, that you're running a physics simulation on the server and some simplified algorithm on the client. Why not run a fully identical physics simulation on the client, too, that takes into account all the same factors and produces identical results?
When clients go head-to-head using direct interaction, latency is not a perfectly solvable problem. Your options all come down to hiding discrepancies one way or another. One way is to interpolate the physics, rather than jumping them, between each frame. I e, maybe you update the physics data as a "snap," but what you render is actually an interpolated (or extrapolated) version of what comes out of the simulator.
enum Bool { True, False, FileNotFound };
1) Clients run a full simulation including collisions.
2) The server says otherwise whenever it pleases, but hey, at least the client is close to accurate.
3) Add an input lag, where you send out input data 50-70ms before you intend upon using it, especially if your game is running over the internet. I've done some testing that suggests that 50-70ms lag in input cannot be clearly noticed by a user, while buying a network based app just enough time to bypass latency created issues.
4) Display visual proxies of the physics state. By this, I mean that you want to store a second world transformation for the physically affected objects. This transformation is lerped against the actual state each frame. On a client experiencing jumps and stutters, this will smooth out the movements. You should probably use an aggressive lerp of 0.95-0.99 so that your proxies are close to the actual object locations, but will also act smoothly when jumps happen. That's my thought.

This topic is closed to new replies.

Advertisement