Figuring out the cause of jitter

Started by
1 comment, last by hplus0603 10 years, 11 months ago

Hi there! I'm having some trouble dealing with jitter in my networked game. I've created a simplified example that should explain the problem:

Client A updates its position, P, each frame. For simplicity, say that P is incremented by one each frame. The game updates 60 frames per second, and every 3 frames (20 updates / second) the client sends this position to Client B.

B receives the position and uses this value. However, since we expect less than 60 updates per second from A, B will try to predict the increment to P by adding one to it each frame. This works just fine - most of the time.

What I'm seeing is some jittery movement on B's end, caused by packets arriving at an uneven pace. For example, here's a printout of P at the end of each frame:

P: 4

P: 5

P: 6 <- Got update from A, value = 6. All is well since we expect one update every three frames.

P: 7

P: 8

P: 9 <- Got update from A, value = 9.

P: 10

P: 11

P: 12 <- Missed an update!

P: 12 <- Got update from A, value = 12. Since it was one frame late, P stands still and we get jitter.

P: 13

...

I guess I can't expect packets to arrive exactly on time, even though I'm running the test on a single computer and with all clients at 60 FPS. However, what to do about it? The obvious answer is smoothing, but I'd need a lot of it to cover up the jitter - the difference is often more than a frame or two. Are these results to be expected or would you suspect that something is wrong here?

Advertisement

I think I'm making some progress with queueing up the updates in case they are early, and applying them at their designated time. It definitely removed the worst of the jitter. However, there's some inherent problems with this:

* Queuing up = introducing latency. Not much to do about this.

* How large queue should one allow? I've set an arbitrary number right now (3!) but I think it needs some more thought...

* What happens to packets that are too late? I think I'll try extrapolating the position in case this happens.

Yes, queuing is the right solution for de-jittering.

Another problem you may end up seeing is that the player sends "position X, direction Y" at time T, and then turns around at time T+1, and the packet that sends the next direction won't go out until time T+3, meaning there will be a "snap" on the receiving end if it does forward extrapolation.

The smoothest option is to wait until you have data for all your time before you display the entity. I e, if you send data for times (T-2, T-1, T) at time T, and it's received on the other end at time T+2, then the other end would display the location at time T-2 at time T+3, aiming to display the location at time T a timt T+5, so the next packet arrives in time to display T+1 at T+6.

If you don't want to always display "known" data (which introduces this latency) then you have to extrapolate, and you will get jitter. The Entity Position Interpolation Code (EPIC) library is one way of smoothing out the extrapolation, but it will never be perfect, because you are, at the core, guessing, and you will guess wrong at times.
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement