Stopping Jittering.

Started by
7 comments, last by oliii 11 years, 9 months ago
hey good people, I need a bit of help to figure out the best solution for my current network problem:



so, my setup is such:

the server is currently localhost, so it's all on the same computer at the moment. The server sends packets 6 times a second, and the client update's the server with it's new heading's 6 times a second. when the client receives a new state of the game, it updates the real positions of the snakes, and they go off these new positions, and i interpolate the draw positions to the new positions. works decently, but I'm still getting minor glitchyness, particularly in the way the user turns itself.

i was thinking a potential solution is to wait until the client receives the new heading, then begin turning, instead of turning when the client clicks to the new target, but this seems like the user would feel input lag.

any ideas on ways to improve my setup?
Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.
Advertisement
"this video is private".

Everything is better with Metal.


"this video is private".


opps, should work now.
Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.
Depends on many things. What's the interaction between the server and client, for example.

From what I understand, the client sends inputs to the server, the server applies the inputs, and send the positions back to the client. That means on the client side, the input lag would be a round trip time (which could be huge), plus around a network frame delta time (which at 6 fps, would be quite significant, between 300-150ms).

OnLive kinda works like that, and relies on reducing the latency between user inputs and video streams of the game render frames as much as possible.

For a networked game context, look up client-side prediction, which allows the client to compute the movement in real time locally, and the server to correct the client if his prediction drifts too far away.

Here is an example of such a system.

http://gafferongames.com/game-physics/networked-physics/

Many games use that sort of client side prediction and correction mechanism.

Now, for a remote client (imagine another client spectating the game), it is slightly different. The host just sends position updates, and the client interpolates positions, as you seem to be doing at the moment. The client then has to run his clock behind the host. This is so the client always interpolates between known positions, instead of extrapolating and 'guessing' where the next position will be. Extrapolation can introduce more jitter is the position updates are not predictable and more chaotic (for example, a player bullet dodging left and right).

'Entity interpolation' : https://developer.va...ayer_Networking

the 'Input prediction' part is a summary fo what is presented in Glen Fiddler's article.

Thirdly, for the host to provide accurate hit detection, he has to 'simulate' what each client see, how much they are compensating for lag in their interpolation, and wind back some physics and animations at the time of the shot. That's the 'Lag compensation' part of that article above.

Note that 6 fps is kinda low for network updates. Right there, you already introducing around 150ms latency just because of your network tick rate. Input network packets need to be a lot higher, say 20 fps.

The advantage of that method is that the client -> server bandwidth usage will be very low, as you only need to send inputs, and predicted physical states of your local player. So you can send at a higher frame rate. Secondly, the correction packets send by the server do not need to be of high frequency. The higher the frequency, the less 'rubber banding' the user will experience when their prediction goes wrong (for example near another player or some server entity they collide with).

I know it sounds complicated, maybe too much for your purpose. But since I can't see the video or have to guess what you want to do precisely...

Everything is better with Metal.

The 'jitter' looks to be when you interpolate the orientation, which I assume is a linear interpolation of the orientation head of the snake.

If you want to completely eliminate that jitter, as well as input lag, and also reduce your network traffic (although now it will be mostly client->server rather than server->client), I guess the input prediction and server correction mechanism would work.

As a sanity check, you should have NO corrections happening on the server. The server and client should be perfectly in sync since the simulation looks completely deterministic (since there are no external factors that would introduce unpredictability).

Everything is better with Metal.

I could be totally off on my analysis, but here's what I think is going on (assuming the game client updates at 30fps):

At time t = 0 / 30, client sends heading packet to server. They are in sync, and things are good.
t = 1 / 30, player starts turning towards mouse and moves. Server still uses heading from t = 0 to move the player though.
t = 2 / 30, player turns slightly more, moving towards mouse. Server is still unware, and advances the player using the heading from time t = 0.
t = 3 / 30, player turns a little more again and advances. Server still uses heading from t = 0.
t = 4 / 30, same thing.
t = 5 / 30, player sends current heading to server, receives actual position from server. Server receives new heading, and begins using it.

And here's an illustration:
[attachment=10320:path.png]

So how do you fix this? Well, one option would be to keep "turning" on the server. Send both the heading and the turning rate to the server from the client, and have the server update its heading each iteration with the turning rate it received. This isn't perfect, per say, as there are ways it can backfire and be worse.

Another option would to have the client update the server with its position (that is, the client does more work in controlling the player, but the server still truly owns and validates it). At t = 0 / 30, the client can tell the server that the player is at position p with heading v. Then the client keeps updating, and at t = 5 / 30 it sends off another packet to the server with the most up to date position and heading. The server then takes the headings and positions from t = 0 / 30 and t = 5 / 30, and does two things. First it does a validation, where it makes sure that the client's position is legal (if you move too far or turn too fast, it can either boot you for cheating or change them to what's the closest real possibility). Second it interpolates the heading and position from t = 0 / 30 to t = 5 / 30, and "catches up" in updating the actual game world. It then replies back to the client with the actual position and heading of the player (maybe the player hit a wall at t = 3 / 30).

These are a couple of simplified options. They can probably be improved (with additional complexity). There's probably other solutions out there too, but it's time for me to eat so I can't ponder this anymore right now.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
Thanks for the input guys.

@papalazaru, thanks for the good links, i'm looking over them now. I'm attempting to do prediction on the client side, but it looks like my naive attempt needs a bit more work.

@cornstalk, thanks for the great diagram, it's most defiantly what must be occurring, when the server sends the game state to the client, i take that, and try to interpolate the value back to the real position along with the correct heading, unfortunately it's pretty apparent in practice.

I've also doubled the number of packets sent per second on both sides, and it's defiantly decreased the noticability of the effect, but i'm unsure how this well function over a lan. I currently don't intend to do anything over the internet, but learning better networking practices is something i should defiantly do.
Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.
For interpolation, you might want to try a library like EPIC.
enum Bool { True, False, FileNotFound };
'definitely' not 'defiantly', although that works for me.

The general idea of the client side prediction is relying determinism, to a degree. It's a bit like a replay system, where you store inputs (and frame timesteps, if your frame timesteps are variable), start from a initial state, and by replaying the outputs, you will end up at the exact same state after a while. So all you need, as long as the system is deterministic, is storing the initial state, and the stream of inputs. You could certainly start with that concept and a simple app like yours.

The difference between a replay system and network prediction is that determinism doesn't have to be strict, and you can use the server to correct the client when he starts drifting.

Things get complicated once you introduce player interactions and AI. Then determinism is broken, and the server has to ask the client to step back to the point where he started drifting, rewind to a valid state, and re-apply his inputs.

Everything is better with Metal.

This topic is closed to new replies.

Advertisement