Problems with mouse movements

Started by
6 comments, last by Enrico 18 years, 2 months ago
Hi, I am developing a small FPS (similar to Aquanox) and I have serious problems with mouse input: the client program detects the mouse movement and sends the delta coordinates immediately to server. The server saves the new mouse position (or pitch/yaw of the camera). Every 33ms the server updates his local copy of the world and every 100ms the clients get updates from the server. Now at the updates, the client camera (which gets the pich/yaw value directly from the client program) is jumping around. I tried to compensate this with an epsilon value: Only if the difference between the current and the new pitch/yaw values is bigger than this epsilon, the new value is applied. This helped, but has only moved the problem. I have only small "jumping" with the camera positions; I think I can compensate this with integrating the latency between client and server into the server calculation. But what to do with the mouse movements? I thought about not sending the pitch/yaw values from server to the client and hoping, that the client's values meet the server's values. Is this a good idea? Thanks in advance, Enrico
--
Advertisement
Any particular reason you are having the server authenticate camera movement for the clients? Do you have camera position directly tied to player orientation?

Are you interpolating between the orientation samples you are getting from the server?

For example, when you recieve a packet from the server that says the player is at a certain orientation, do you automatically set the player's camera to that location? or do you interpolate to it?

If you are just setting the position, then it's going to look really jumpy.

Interpolating with euler angles isn't gonna look all that great either. I would suggest you use quaternions for your orientation information, and then do a SLERP (Spherical Linear Interpolation). Things should look pretty smooth if you do that.

You may have to put in code to handle jitters in packet arrival times, that will cause some jumpy behavior too.

for example, if you expect to get a packet every 100ms, so you interpolate over a 100ms period.

If network congestion, or extra latency causes one packet to arrive a little late, (say you get it at 120ms after the last one) you will get a period where you are not interpolating the movement. which will cause the smooth rotation to stop for a little bit. So you might want to predict the position for a given time after your interpolation has completed (say an extra 1/4 of your update interval). So when you recieve the late packet, subtract the amount of time you have been predicting, from your interpolation interval, and then interpolate to the final position over the new calculated interval.

for example, you expect packets every 30ms, but congestion causes packets to come in like this:

packet1
120ms wait
packet2
80ms wait
packet3
100ms wait
packet4
(the second packet came 10ms late)

You would recieve the first packet, and begin interpolating to that position over a 100ms period.

after 100ms, the player has reached the position in packet 1, but you have not yet recieved a new update, so you decide to predict position for another 25ms.

20ms into your prediction, you recieve a new update. you subtract the time you have predicted (20ms) from your update interval (100ms) and get the interval you need to interpolate to the new sample in (80ms).



The part that reads:

for example, you expect packets every 30ms, but congestion causes packets to come in like this:

packet1
120ms wait
packet2
80ms wait
packet3
100ms wait
packet4
(the second packet came 10ms late)


should read:


for example, you expect packets every 100ms, but congestion causes packets to come in like this:

packet1
120ms wait
packet2
80ms wait
packet3
100ms wait
packet4
(the second packet came 20ms late)


(I had originally written examples using a 30ms update interval, but that wasn't a very realistic value)
Quote:Original post by Anonymous Poster
Any particular reason you are having the server authenticate camera movement for the clients? Do you have camera position directly tied to player orientation?

This is a space game. The player is "inside" his ship and when he moves the camera, his ship moves, too. All in all, the camera is the same as the player's ship.

Quote:Are you interpolating between the orientation samples you are getting from the server?

yes.

Quote:For example, when you recieve a packet from the server that says the player is at a certain orientation, do you automatically set the player's camera to that location? or do you interpolate to it?

I set directly the new values. I tried interpolation, but I wanted to keep this as simple as possible.

Quote:If you are just setting the position, then it's going to look really jumpy.

The position doesnot jump at all, it is just the camera orientation.

Quote:Interpolating with euler angles isn't gonna look all that great either.

Will it help or do I need to learn quaternions?

Quote:You may have to put in code to handle jitters in packet arrival times, that will cause some jumpy behavior too.

If network congestion, or extra latency causes one packet to arrive a little late, (say you get it at 120ms after the last one) you will get a period where you are not interpolating the movement. which will cause the smooth rotation to stop for a little bit.

I am using RakNet with a reliable/sequenced mode, so this should not happen (I think :D )...
--
How often are you sending updates?

It confuses me that you say you are interpolating, but then you say that you are setting the orientation directly. If you set the orientation directly, you will get jumpy movement, you are effectively reducing your rotation update rate to that of your network update rate. If you interpolate you will be sending a new orientation to the game every frame, which will make the rotation smooth.

If you don't interpolate, your movement will be jumpy, especially rotation from a first person perspective. So definately interpolate, and use quaternions if you can. Quaternions interpolate much better.

Raknet will give you reliable, sequenced packets. But it will not be able to alter the shape of spacetime to ensure that your packets will arrive at a fixed rate. You are confusing realiability with regularity.

Raknet will make sure you get your packets in the right order, without losing any, but it will not ensure that you get them evenly spaced, at exactly the same interval at which they were sent. In fact, the code in raknet that makes the packets reliable can delay packets while it waits for a dropped packet to be retransmitted.

The packets might be sent at exactly the same interval, but things like framerate, bandwidth, aggregation, send/recieve buffers, and routers, can all change the rate at which the data is actually recieved. This is called jitter. It's different than a dropped packet. Your data gets there, just not at exact intervals, it's usually give or take a few milliseconds.

Although it sounds to me like jitter isn't your problem right now, it's the fact that you aren't interpolating your orientation.
Quote:Original post by Anonymous Poster
How often are you sending updates?

The server sends every 100ms updates to all clients (should I send more updates?). The server updates the game every 33ms.
The client sends input changes without delay to the server and updates his world every frame (no limits here).

Quote:It confuses me that you say you are interpolating, but then you say that you are setting the orientation directly.

The client interpolates the movement of all objects based on the last server updates. But when such an update is received, the values are applied to the objects without interpolation.
Currently, the orientation is not interpolated. When the mouse is moved, the client applies the changes to the camera and sends the values to the server. These are overwritten, when an update is received.

Quote:Although it sounds to me like jitter isn't your problem right now, it's the fact that you aren't interpolating your orientation.

How can I interpolate between Euler angles? Just like the usual dead reckoning: define a fixed rate of degrees per second and update every frame?

Is this a good idea: Only set the values from the server updates, if they are bigger than a certain threshold. This would trust, that the simulation on the server reaches the same state as on the client within the next few ms and I dont need to interpolate. If there is something wrong with any simulation, the values are set to the server values and everything is smooth again (except the small jump). Would this work?

--
Your update interval seems ok.. 100ms is a good rate.

You also seem to be misunderstanding the term "interpolation". interpolation is when you have 2 discrete samples, and generate a set of samples inbetween those that smoothly connect them.

"extrapolation" is where you take the information you have, and predict where the next sample is going to be.

It sounds like you are extrapolating the player's position each frame, and then snapping to his known position when you recieve an update.

I assume you are extrapolating position by using a velocity vector?

you could do the same sort of thing for your orientation if you wanted. track the turn velocity of each of your axis, and send that information to your client. Your client can then extrapolate the orientation angles based on this velocity.

you will still probably get some jumpiness, when you "snap" to the position in each packet update, but you could apply a dead reckoning style algorithm to reduce this
Quote:Original post by Anonymous Poster
You also seem to be misunderstanding the term "interpolation". interpolation is when you have 2 discrete samples, and generate a set of samples inbetween those that smoothly connect them.

"extrapolation" is where you take the information you have, and predict where the next sample is going to be.

Thanks for clearing this up for me :-)
You really need to get an account, so I can rate you ;-)

Quote:It sounds like you are extrapolating the player's position each frame, and then snapping to his known position when you recieve an update.

Yes, that is what I am doing.

Quote:I assume you are extrapolating position by using a velocity vector?

I have only very limited basic physics (or none at all): Movement is based on a direction vector with a constant speed in all directions. A new position is calculated with this small formula:
new position = old position + direction * elapsted time * speed

Wouldnt this interpolation between the values from the server updates and the client values cause some visible glitches for the player? Because the camera moves on its own between two points.

I think, I will doing nothing at all (not event setting server updates and the clients) and just hope, that the games stays in sync between server and client... :-(
--

This topic is closed to new replies.

Advertisement