问题
There's a couple of questions here.
Imagine I have client A who's going to send the following message to Server: "START MOVEMENT FORWARD".
The server will not receive this message instantly, as there is a delay because of latency.
Question 1: ping (or better: round trip time) is the amount of time it takes for the client to send a message to the server and receive a response back. Does this mean the following if you can ignore the time it takes for the server to notice that it has received a message and start sending a response (this should be very short)?
- time it takes for client to send someting to server = round-trip-time / 2
- time it takes for server to send something to client = round-trip-time / 2
So, when client A sends that message, the server will supposedly receive that message round-trip-time / 2 milliseconds after the client has send the message. This leads me to the next question.
Question 2: should the client first send the package, and then wait round-trip-time / 2 milliseconds before actually executing that command client-side (in this case: move forward) to compensate with the latency/lag?
Now, the server will send the following message to all nearby players: "CLIENT A IS NOW MOVING FORWARD". These clients will then make sure that the character of client a starts moving, this leads me to the next question.
Question 3: should the client receiving the message that an other client has moved take into account that this message was send by the server round-trip-time / 2 milliseconds ago? So that the current time used for movement calculations timestamps should be reduced by round-trip-time / 2?
All these methods would in my mind make sure that synchronisation improves between clients, as latency is taken into account. Is this the right way of doing things? Do most other good multiplayer games do this? Any comments, suggestions, alternatives or random but related shouts that you'd like to give? Thanks in advance.
回答1:
I think that in most mmo's your client mainly moves without interaction with the server unless bad lag occurs. The server reproduces the movement with the help of the messages the client send to the server. So if for example the server lags, the client will stop recieving feedback from the server and revert to the position the server determine that you are at. That is why you jump back several frames during bad lag. This way the server will also have control over your speed so that you are not speedhacking. If your client moves at a certain rate which is over the speed determined by the server, you would simply jump back the extra frames.
Other clients would not let you move at all without response from the server within a certain amount of time. This is the times you would experience 'freeze-lag'.
Of course there are also occurences where the server simply take the position sent by the client and blindly trusts it. These are the games that are generally vulnerable to teleport hacks.
When it comes to the position of other players there indeed is a delay, which can be seen if you take two computers, connect to a game such as wow and move the two characters simultaniously. You would see that on both computers the non-local character will start moving after you really started moving him.
The client usually have some sort of lag compensation. So if another player is moving at a certain direction and then stops, your client will still simulate the movement of that player until you recieve a message from the server that he changed direction or stoped moving. That is why other players can jump back and forth when the ping is high. This is also why players can seem to just slide/run/walk away when you hit lagspikes and then return to their real position when your clients recieve positions from the server.
Of course this changes from engine to engine but it's a rather general aproach.
Edit: Forgot to add that it is very common for the server to also use lag compensation. If you hit someone in a mmo that is in range of you, that person might not be in range from the servers view. So the server takes the latency for both your clients and tries to match up if you were really in range of eachother or not.
回答2:
This is an old question but I've worked out similar code recently so maybe this will help someone.
Yes latency is always useful in the calculation. But it is slightly more complex than RTT. Round trip time is always changing... your network code can keep an average, but the variance from that average is large.
The local client, remote client, and server all predict the current position using algorithms. The following data is close to typical:
- Time: t
- Placement: Position (x,y,z) and Orientation (x,y,z,w)
- Movement: Linear movement vector giving direction with length as speed (x,y,z), and rotational movement vector giving axis with length as rotational speed (x,y,z)
You need the algorithms that extrapolate from a [T,P,M] set to the simtime. I won't be providing those here.
When the client registers a change in the drive of the ship at [T,P,M], that wont get to the server until T+deltaT. But if deltaT is within the tolerance of typical network latencies, the server can say "Yes it happened at T, I accept that." Otherwise it might want to correct the client saying "No thats out of tolerance, it happened at my time T' " in which case the client will have to REPLAY all the subsequently driven [T,P,M] changes from the server's corrected one (meaning you need to keep a queue or list of them).
The next client will get it at T+deltaT+differentdeltaT. It can't possibly change what it has already simulated, so if it isn't delaying it's simulation it will jump the remote ship and you will see a jerk frame. That's why remote driven ships should have their simulations delayed by a time consistently greater than 2*typicaldeltaT. It should be a constant delay, or a delay that changes gradually, and in times of severe lag you will see jerk frames nonetheless
You can smooth all jerks with extra smoothing code but don't do it until your code is otherwise flawless because it will just make it impossible to see where the problems are.
You must have a good synchronized time reference. A lot of code out there does it rather sloppily (e.g. RakNet doesn't (or didn't) do it very well). Here's a good hint: in the short run you can presume that everyone's clocks are running at the same rate, and you only need to figure out what the offset is, so keep a window of maximum and minimum offset and close it as you learn; In the long run you need to compensate for clients whose clocks are running fast or slow, so allow the window to open if you know for sure it must. You must use a local timesource that is monotonically increasing and not keyed off of the processor speed (which nowadays is variable).
No, don't delay the local simulation when the local "avatar" moves. It would seem way too unresponsive. You could delay it slightly (up to maybe 50ms) to help improve synchronization, but a delay all the way out to the RTT would make your game seem frustratingly unresponsive. Set an option for local delay and play with it, because a small consistent delay can be acceptable and improve synchronization. But it's not necessary and can cause lots of problems so I recommend doing that code last. (If you are trying to do a FPS melee game, you'll need to do this and all the other help you can get).
As for cheat prevention vs. simulation smoothness: First, the clients shouldn't just extrapolate from the last known position, when the official position changes. It should register an adjustment vector and slowly move from the old path to the new path for smoothness (but like I said above do this code last or it will mask other bugs). Secondly, the server should tolerate a wide range of delays... even on machines on the same ethernet the packet delay typically runs 5ms to 100ms or so... that is quite a range. Of course you need to cut it off and say "if you say you moved at time T but I got the packet at T + some_large_number then I think you are trying to adjust the past and lying to me." some_large_number shouldn't be much bigger than the average RTT to keep people honest.
The simulations will never be tightly synchronized. They should stay within 400ms or so over the Internet but certainly will stray outside of that during times of lag... to 30 seconds or more, and you need to tolerate things that that because they aren't rare. Given that the Internet is limited by the speed of light in copper, you can always expect one-way latencies to typically be in the range of at least 100ms minimum for your far clients, often 500ms or longer.
Therefore I highly recommend you don't try to make a melee FPS game over the Internet (some big companies try but will always have troubles). There are tricks you can do if you are using projectiles (by running them fast in one simulation and slow in the other) so that even though the timing is off, it looks on. Also, FPS games use the rule that hit-detection is based on the attackers simulation... it feels more wrong when the attacker knows he was dead on target and misses, then when a defender knows he was out of the way and gets hit anyways. You have to choose one or the other, and psychologically that's how it's been done. Melee requires a level of synchronization which is frankly impossible and most game companies won't touch MMORPG FPS melee but rather use auto-targetting (try playing Mortal Online, you will see what I mean).
Good luck.
回答3:
for Q1: that looks right to me.
Q2: The way I've done this in the past is: if you want things to feel responsive, start executing the action instantly on the client's simulation, then the server simulates forward in game-time when the person initiated the action. i.e. the client knows at what ms in the game-simualation time it started, so the server can start it at that time also (note: this is always backwards in time from the server's current tick, so you have to save state back in time to do this).
Q3: the clients only really need to know that they are simulating at time X, and the server says the set of events {A,B,C} happened at times {X,Y,Z}. Then client and server can simulate forward with the same info and generally stay in sync (except when simultaneous conflicts occur). In those cases you have the server re-sync things so you usually end up within a pretty tight margin of error and a mostly smooth experience.
If your goal is to improve a perception of latency you might also just try trusting the client.
回答4:
There are several network models to solve these problems;
In network game, you need to sync two things, one is time, other is space.
- A network game model called lockstep;
you should have a look at the article written by age of empire2 game studio, which describe details in lockstep model.
In this Model, Client and server run game logic frame by frame, for example, RTS use 100ms as a frame, Server and client will sync frame Id, which means to sync time.
Client at frame 50, Send Command MoveForward, but not run it immediately, client will tell server to run move command at frame 51; then when frame 51 comes, server and client will run command at the same time. so client and server logic will be same.
In such model, at frame 50, client and server will run command issued at frame 49 perhaps, so there are alway 100ms or more delay in client input feedback.
the lag between client and server not only contains network RTT, but also contains logic frame delay, which is 100ms;
in this model, to sync space, you need to make your client code and server code Deterministic, so they can only sync command and frameId, there are no needs to sync entity state.
in this model, input feedback is large, so you need to play animation or sound to help player ignore the lag.
- other models use state sync
in this model, we also need to sync time, so client will guess what current time in server.
when player input, client move immediately, then send move command or client target pos to server with current server timestamp, which is estimated by client.
when server receive the client command, it know when the command is issued in server time by client, it will try to run the command with extrapolation.
all other clients will receive the command, with its server time, the all other clients will try to extrapolate the command.
these technologies include Client Prediction, Server Lag compensation, Server Entity interpolation.
in this model, client input feedback is short, but for some impulse command, such as using skill, we still need to use lockstep method, with animation , sound and particle effects to makeup the input feedback time.
In network game, there at least two kinds command, first like movement, command will run for a certain time, like a steady stream, which has the attribute of Continuity.
the other like using skill with cold time, command effect will take in impulse, we should treat them differently.
回答5:
Some good multiplayer games uses a mechanism to allow players move smoothly even under heavy round trip times by allowing client to decide and send the position of the player to the server. There are fraud checking mechanisms but client is free for that. So if the round trip time goes wacko you see people jumping from place to place while you are moving smoothly. Even some MMO games take it to the next stage by allowing client to handle single player content without consent of the server. Only stats, battle reports and some other info is sent to the server along with few fraud checking data.
来源:https://stackoverflow.com/questions/1448997/do-good-multiplayer-mmo-clientserver-games-use-latency-within-movement-calcula