Smooth position prediction

Started by
5 comments, last by Hyunkel 13 years, 2 months ago
My client currently holds the last 10 positions it has received from the server in this fashion:

t=1, Pos=(0,0)
t=1.9, Pos=(1,0)
t=2.5, Pos=(2.3,0)
...etc

In order to compensate for jitter, when I predict the current position, I need to take into account the last 10 positions.
What is a good way of doing this?
I'm sure this is a common problem, but I don't know what this is called, so I'm having a hard time finding helpful resources online.

Cheers,
Hyu
Advertisement
Some keywords are interpolation, extrapolation, client prediction and dead reckoning.
What type of game are you writing?
Most fps use a form of client prediction where they just update the local player immediately after input and correct its position if it differs too much from the received server state.
Other players will appear in the state they were about ping/2 milliseconds ago on the server. This way you will always (under stable network conditions) receive server updates at the right time to display smooth enemy movement. Of course you will then be shooting at an enemy where it was in the past. So the server needs to take that into account and see if you would have hit the target had it received the "shoot" command in the past.

At least that's how I got it. I am implementing something like this myself but haven't got to the point where I can test it.

cheers.
Most games only use the last 1, 2 or 3 received messages. You can get away with the last received message if each data point is (position, velocity); if it's just position, you can get away with the last two.

Note that, if you extrapolate, you will have the problem that players will "overshoot" when they stop, because the stop packet takes some time to get to the destination. You may want to simply delay display, so that at time T, you display the user at time (T-0.1), assuming that you will get a new data point every 0.1 seconds to keep it up.
enum Bool { True, False, FileNotFound };

Some keywords are interpolation, extrapolation, client prediction and dead reckoning.
What type of game are you writing?
Most fps use a form of client prediction where they just update the local player immediately after input and correct its position if it differs too much from the received server state.
Other players will appear in the state they were about ping/2 milliseconds ago on the server. This way you will always (under stable network conditions) receive server updates at the right time to display smooth enemy movement. Of course you will then be shooting at an enemy where it was in the past. So the server needs to take that into account and see if you would have hit the target had it received the "shoot" command in the past.

At least that's how I got it. I am implementing something like this myself but haven't got to the point where I can test it.

cheers.


Thanks, this is going to help a lot!
The game is basically a space shooter (like wing commander, the x series etc), so I need to take into account bullet travel, which I imagine is instantaneous in most fps games.



Most games only use the last 1, 2 or 3 received messages. You can get away with the last received message if each data point is (position, velocity); if it's just position, you can get away with the last two.

Note that, if you extrapolate, you will have the problem that players will "overshoot" when they stop, because the stop packet takes some time to get to the destination. You may want to simply delay display, so that at time T, you display the user at time (T-0.1), assuming that you will get a new data point every 0.1 seconds to keep it up.


My current plan is to send position, velocity and rotation.
I'd like to experiment with simply delaying the display, it sounds quite straightforward, and I don't think seeing the game state "100ms in the past" should cause any problems.
However, how do I account for jitter in this situation?
Don't I need information about the past few game states in order to disguise jitter?
I have to admit, even using the past few game states, I'm not really sure how to disguise jitter, I think there's something I haven't fully understood yet.
I'll try to find a few more articles tomorrow and hopefully figure out what I'm currently misunderstanding.

Cheery,
Hyu

However, how do I account for jitter in this situation?


You increase the "100 ms" value until the delay masks whatever jitter you're prepared to tolerate. You can do this dynamically -- whenever two packet are late in a row, you increase jitter by 10 ms, for example. This will quickly build up whatever delay is needed, without over-compensating for a single, very late (or dropped) packet.


If jitter goes above your amount of delay, you can stop the entity at the last end point you got, or you can forward extrapolate. Stopping will cause a jump for each packet that is delayed/lost, but that jump will be predictable. Forward extrapolating, will cause less jumps for cases where it predicts correctly, and bigger jumps for cases where it predicts incorrectly. Your choice which you feel is better.
enum Bool { True, False, FileNotFound };
What jitter do you mean exactly? ping jitter? framerate jitter?

When you employ the delayed display method you should, under normal conditions, not have to extrapolate. That is, guess a position. You can always interpolate between the last-known states. Problems arise of course when there is a packet delay that is out of accptable bounds. But in that case there will be incontinuities in movement either way. (The well known jumping or warping of players under high ping conditions)

edit: Of course like hplus said you can dynamically adapt the delay.
(I'm talking about ping jitter)

Oh, alright, I see what you mean now.
The "100ms delay" is in this case independent of the actual latency time (but needs to be higher than the latency + jitter)
This way, looking at the last 2 states I received from the server, I will be able to tell where the object in question currently is. (or rather, where it was 100ms ago)
If my delay is higher than latency+jitter I will always have all the information I need, and I don't need to guess the current position.
For some reason, after reading an article about dead-reckoning, I wrongly assumed the delay I need to work with was supposed to be the current latency time which was confusing me.

I think I understand how to do it now, at least I don't see an immediate problem.
Thanks for the help!

Cheers,
Hyu

This topic is closed to new replies.

Advertisement