Re-Calculations of movements

Started by
4 comments, last by Arngrim 23 years, 2 months ago
Hi, I''ve got a question concerning the synchronization of worldstates within a client/server environment. The problem is the following: I send ping packets to the server and get pong packets in response, thus being able to more or less accurately figure out the server''s local time as compared to the client''s local time. When I send out a message from the client (let''s say a simple input as in "Move Forward"), I add the time difference from server to the local timestamp, which should approximately be the time that this event would have happened on the server. Now comes the tricky part: when the packet arrives on the server, I have to "go back in time" and calculate the actual position of the object, considering the fact, that the event happened somewhen in the past and the current known position is invalid. But how to do this in a reasonable amount of time? Let''s say I have a tank, which can be rotated and moved forward and backward. The input event (occured at perhaps 100ms, arrived at 200ms) says that the tank moved forward at a rate of 1 m/s and rotated with a speed of 10 Degrees/s. The only way I know of to extrapolate the current position at 200ms would be to integrate over time, but isn''t this out of the question for performance issues, especially if we''re talking about a few hundred objects? How do other games handle these problems? Is the approach of dealing with the input data valid at all, or should be supposed that the client doesn''t move before the message arrives at the server? BTW, the problem occurs of course again when the server sends back a message to a client, which in turn gets an out of date update of it''s current position ... Any help is appreciated, Arngrim
Advertisement
Most games do not use retroactive commands, they just apply them on the momement of arrival of the packet. The only case which i can think of where you need retroactive commands is for extremely time senenstive events such as in Rainbow 6 where i think they do perfrom retroactive calculations for the shots (since thats a 1 shot 1 kill kinda game). The problems with retroactive commands is that the higher the latency of the client the larger the descrepency will be. This kinda gives the more lag users magical timewarping abilities, which can be/is exploited within such a scheme.

The synchronization routines your using is useful for smoothing deadrecoking extrapalations etc.. I would stay away from retroactive control schemes.

Good Luck

-ddn

The new halflife net code uses retroactive, but only on shots, as mentioned in the post above.

To find out how the code works, search the web for things like "tweak halflife netcode" or something similar. A lot of the network performance tweaking sites actually explain how the net code works in some depth.

DmGoober
Alexander "DmGoober" Jhinalexjh@online.microsoft.com[Warning! This email account is not attended. All comments are the opinions of an individual employee and are not representative of Microsoft Corporation.]
Yes, the Half-Life netcode does this as of version 1100.

Actually, there are several aspects to the HL netcode. One of them are the "retroactive" shots, the second one is client side prediction.

This is how retroactive shots work: The server keeps track of all the clients'' position for up to 1sec. When it receives a client input packet, the following steps are performed:

- Calculate the clients ping
- setup a temporary entity array where all positions are taken from the state we had ping time ago (this is the state the client was looking at when the command was issued)
- Run the mod''s game logic code, which contains weapon handling. If a shot was fired, this shot will use the temporary array for clipping. As a result of this, you actually hit your enemy when you''ve got your crosshair correct on the client. Without the adjustment, you''d have to compensate for the ping
- the temporary array is destroyed

Now this can have some very, very strange effects which caused a lot of "CHEATER" cries when the netcode came out.
Let''s say you have a low ping (referred to as LPB), and you''re shot at by someone with a high ping (reffered to as HPW). Now the LPB takes cover around a corner. However, on the HPW''s screen, the LPB is still in sight, and he''s still shooting. Now when the "shoot" commands arrive on the server, the LPB''s position is translated back into open space, the LPB is hit and might die. For the HPW everything looks fine, but for the LPB it seems as if the bullets were travelling around a corner. Note that this is no disadvantage for the LPB, as the same can happen when the HPW tries to move into cover.

One important thing to note: It''s the server that determines the client''s ping. If it was the client that determined the ping, it could fake its ping as a cheat in some cases.
Another important thing: There appeared a fakelag cheat shortly after the netcode came out. It works by faking a temporary network failure, thus freezing the game on the client''s screen. As long as the server believed that the network failure was genuine, it translated the player''s target position back, so the cheater had up to 1s to aim and kill the enemy.
This cheat was fixed, AFAIK by averaging out the player''s ping, so ping peaks are now ignored.

The second part of the netcode is the client side prediction. The way it works: Movement code and some of the weapon code was copied to the client side. Now whenever the local player issued an input command, these movement functions & weapon functions were called to create a temporary local state of the game.

Without client side prediction the weapon firing worked like this: you hit the fire button, an appropriate command was sent to the server, the server did the game logic and sent back a packet to describe the effects the client should show. So you hit the fire button, but you didn''t see the firing effects immediately.

With clientside prediction it works like this: You hit the fire button, and the command packet is sent to the server. However, at the same time the local version of the weapon firing code is called. This code produces the firing effects locally, so you see them immediately. When the previously sent packet arrives at the server, the server''s weapon firing code is executed. However, no effects packet is sent back to the client.

It''s important to note that the local prediction does _not_ affect the actual game state, i.e. hit&damage calculations are done on the server; changing the clientside ammo variable does not affect the amount of ammo you actually have, because the server''s decision is the one that counts.
Also note that only the local player is predicted. Other players'' positions and effects are displayed using the information from the server.

In HL, client side prediction is used for player movement and weapon code. It is not used for non-player entities like buttons and doors. This leads to some strange effects when walking through automatically opening doors: when the movement is predicted, the client will see a closed door, so the player is stopped. Now when the server does the movement calculations, it opens the door at the same time, so in the end the player isn''t blocked and can move a lot further. This leads to some warping around, which in turn caused a lot of false cheating complaints when the netcode came out.
You might be able to predict doors & buttons on the client-side, but it could get even more confusing (imagine an automatically opening door that can be overriden using a security switch somewhere else; now what if someone tries to pass the door when someone else turns the switch). It was a design decision made by Valve. The benefits of predicting buttons&doors aren''t that high, and it''s a lot of work. Maybe you will decide differently one day.

As I mentioned, there were many complaints when the netcode was introduced initially. However, this was simply because humans try to avoid change. Now, several months after the release, everybody is happy with it...
So definitely go for prediction in an inet game (especially action games where reaction times are important)

cu,
Prefect

---
Sanity is the trademark of a weak mind.
Widelands - laid back, free software strategy
quote:Original post by Anonymous Poster
The synchronization routines your using is useful for smoothing deadrecoking extrapalations etc..


OK, so the other players'' movements are smoothed out, when a new position update arrives from the server. That''s fine, but what about the player himself?

Let''s take the HPB with a ping of 300ms -> currently if the client executes a command I send it to the server and immediately execute it on the client (thus I''m doing some client prediction). BUT, if the server get''s the packet 150ms later, the player has already moved for 150ms on the client.

Let''s say the server now sends back a position update containing the client''s position, the client will find himself at a position 150ms in the past. How do I smooth THAT out? Just setting the position would lead to a warping experience, doing a smooth transition causes the player to move backwards.

How is this problem commonly solved? Just by telling the server to calculate the estimated client position by immediately executing the command as if it had been executed 150ms before?

Sincerly,
Arngrim


There are 2 schools of though to this problem.

In one you synchonrize the client to the servers time, and so when you recive the packet of your position 150ms old you exrapalte 150ms forward to find your actual server side position. This causes a hop from your current position. Some would say this is acceptable, in that you''ll have the most accurate representation of the actual server state/positions of the entites. Better to aim/shoot at your oppoenents. For low lag connections this is the better choice as the latency won''t be high enough nor the players moving fast enough for there to be a noticble jerk in the players position, and they would have the most accurate info.

In the other school you extrapalate to 1/2 your lag, that is the down stream latency from server to client (which doesnt have to be 1/2 lag). That way the client is perpetually behind the server by 1/2 its lag. Why would you want to do this? Well, there will be less jerkyness when you update the players position/state for one (difference between current clients time and server - 1/2 latency will be smaller). The apperance of smoothness is greatly increased for high latency players (300+ms). You still do extrapalation though, but instead of doing it to the servers time, you do it to the server time - 1/2 latency. This is what i do, as we i feel the apprerance of smoothness is very important. Also this system has a neglible effect on low latency players as 1/2 their latency is most likely less than an update tick for the server itself.

Good Luck

-ddn



This topic is closed to new replies.

Advertisement