Sign in to follow this  
Almindor

Anti-lag with descrete steps

Recommended Posts

I'm making an arcade style game with one screen. Currently I've implemented basic multi-player over TCP (might get changed to udp eventually) pure client-server style, where client sends commands (like "going left now") and server sends delta status when needed. My biggest issue is that, because the game is using discrete steps (currently 1 step = ~55ms, or in other words 18fps), I sometimes get steps "misses" by clients who lag behind. My net code is of course listening/replying for data all the time, not just at end of each step but the problem is, that when a client lags even just 1 step, the "jerking" is quite visible. Say a client-player goes "up" for a few steps (this is fluid, because server responds with "you are here and with status XXX" and client just does the movement on it's end until a new status update). Then the player presses "left". The problem here is, that it might be possible that the client is say 1 step behind the server. So the client sends left, and receives new position and status from server. However the new position is a bit "futuristic" :) In other words at least 1 step was jumped because of this. I'm wondering if there's a general way how to handle these things, because no matter how good the network, this can happen (someone's computer may hickup etc.). I was thinking about using numbering of steps with "future status buffer" on client side (so the client can basically execute stuff "when right" for it). But this further complicates things and is basically just curing of the symptoms with possible side effects. (the client can virtually "future" it self out of sync this way IMHO)

Share this post


Link to post
Share on other sites
The client should just catch up when it's behind, by running simulation but not rendering. In general, the client should, in the construction you suggest, just wait, collecting user input, until a new step is received from the server. When a new step is received from the server, the client should advance by one step and, if not falling behind, render one frame.

You could for example structure the loop something like:

forever {
bool rendered = false;
input = read_input();
send_input();
while (!has_network_data()) {
if (!rendered) {
render();
rendered = true;
}
blocking_wait_for_network_data();
}
read_network_data();
simulate();
}

Share this post


Link to post
Share on other sites
That won't really fix anything, it's actually more primitive to what I do now. The problem is with hickups and network speed changes, not LAG per-se.

If LAG was say 200ms but stable, then the client would feel it (because when they press some command key the reaction would come 3-4 moves later) BUT it wouldn't be jerky.

However if LAG jumps say between 20ms and 200ms the client will experience "jumps" even if it's simulating same-length steps on it's side all the time with prediction (that's what I do now).

My question is if there's a method to minimize that without overcomplicating the thing.

Your way is actually a step back because then EACH visible move on the client's side would depend on network LAG stability (in my case it's only for those situations where e.g: player changes direction or shoots, not pure moves).

Share this post


Link to post
Share on other sites
To smooth out jitter, add artificial lag on the client side. Decide that you will draw everything, for example, 200 milliseconds late. When something arrives early, you queue it for application sometime later. You can determine the actual amount of de-jitter time dynamically if you want, too, by raising it up when a packet arrives late, and slowly back off (say, one millisecond per received packet) when packets arrive early.

Edit: I said "server" where I meant "client."

[Edited by - hplus0603 on July 7, 2008 11:29:42 AM]

Share this post


Link to post
Share on other sites
Yes, I was thinking about that too, I think I'll implement it option-based (e.g: on servers which know are not just for LAN but WAN).

I also thought about making the client-side player move right when it sends the command (local collision detection without notification is already being done on client-side to prevent bump-backs) but that just delegates the jerk-effect on some other sync event.

I guess there's no clean way out of lag fluctuations (this isn't much of an issue for this game generally, it's meant mostly for LAN but I was curious).

In any case, thanks.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this