Networked physics

Networked physics

S_W's picture

Hi,

After reading this article http://www.gaffer.org/game-physics/networked-physics, I'm trying to implement a client-server model with client-side-prediction with some vehicles. I'm going to use a third party game networking library, so UDP packet ordering, server thread creation for each client etc. doesn't have to be done by myself.

I'm actually more uncertain about the best way of predicting physics on the client and the stepping on the server.

When does the server know it can step the simulation forward? Because waiting for all client to respond doesn't seem to be a solution. Or should there be some sort of "individual" stepping for each object as mentioned in the article? But I'm not sure how this could be done with Havok.

And how should the client reset or yet better interpolate its rigidbodies once a packet arrives from the server containing the correct transforms? How can I make sure that bodies won't interpenetrate? Maybe switching to keyframed for the sake of transforming the positions? But will this keep the physics running correctly and give a good input feedback to the player?

I know networked physics isn't an easy topic and it's the first time I'm trying to get this running, but maybe someone can help me with the two problems mentioned above. Well probably more to come... ;)

Thanks!

S_W

10 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
sean.thurston's picture

Hi S_W,

Networking physics is a tricky topic and Havok does not have an out-of-the-box solution for it. There are many different approaches to take and there are many different approaches people have taken in the past. A lot of the decisions you make will be based upon what is necessary for the gameplay of your specific game.

In terms of stepping the world, you want both the client and server to step the world with the same delta time. we've talked a little about the bad things that can happen when you variably step the world. I don't think waiting for input from the user is necessarily a good idea either. It will just hold up the game for everyone.

There are several things you can do to get the rigid bodies to where they need to be. This will also be determined by what the importance of the rigid body is in the simulation. Your vehicles are very important and need to be close to accurate over all the clients, while debris does not necessarly need to be absolutely correct across all the machines. Some possible actions you could take are as follows based on the priority of the object and how far away from where it needs to be:

1. acceptable/zero deviation, don't do anything
2. small noticeable deviation, apply impulse to correct
3. large noticeable deviation, keyframe the object for a few frames to get it to where it needs to be
4. unacceptable, very large deviation, warp the object to where it needs to be with setPosition(), setRotation(),etc.

The last one is probably a very bad case and shouldn't be used unless absolutely necessary as using setPosition() could cause interpenetration and requires calculating all new collision agents. I don't think there will be any guarantees that objects won't interpenetrate at least a little when you are doing networked physics, but this will probably be something you need to sort out on your end.

As I mentioned, there are probably unimportant objects that don't need to be net synced. When you collide with these objects you are going to want to use a mass modifier that makes the vehicle infinitely heavy in relation to these objects so they don't affect the vehicle.

Alright, I hope this helps and I at least answered some of your questions.

Thanks,
Sean

Developer Support Engineer Havok www.havok.com
S_W's picture

Hi Sean,

so I'm stepping the world as usual and using the techinques you described above to correct the positions.

I guess I got the basic idea, which was actually the most important thing for me to get started.

Thanks for the responce!

S_W

S_W's picture

A little off-topic: but maybe someone has some good advice on literature on this topic?

HavokGuy's picture
Quoting - s_w

A little off-topic: but maybe someone has some good advice on literature on this topic?

Hey S_W,

I don't know of any official physics networking literature, but here's a good article about networked physics (and the same author has some other good articles as well):

http://www.gaffer.org/game-physics/networked-physics

Cheers,
-Guy

S_W's picture

Hi,

another question coming up is how to "reverse" the time in a hkpWorld for lag compensation on the server?

For example if a client command is executed and the server estimates at what time the command was created. Then the server moves all objects back to where they were at command execution time.

How could this be done to cast a ray correctly for example (e.g. a weapon fired)? Keeping a history of body transforms doesn't seem to be sufficient to do raycasts etc, or is there any common practice in solving this issue in terms of physics?

Thanks again for any hints!

S_W

sean.thurston's picture

Hey S_W,

This sounds like more of a synchronization issue than a "reversing" time issue. I'm not sure that you would want to reverse time on the server, cast the ray, and then reupdate the server. This might be a tough question, but how far off the server time are you going to allow the client to be? It's probably not going to be perfect any way you do it.

If you do plan on trying to do things into an old hkpWorld, then it might be best to do what you mentioned and maintain a buffer of the transforms going back a certain amount of time.

I hope this helps.Let me know how it goes and if you have other questions.

Thanks,
Sean

Developer Support Engineer Havok www.havok.com
S_W's picture

Hi Sean,

I think I'm going to use some value around 100ms to 250ms for the client to buffer one or more packets before starting the actual rendering to allow some sort of entity interpolation without the need of extrapolating anything.

I've used this idea from this article concerning the Source engine (http://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking).

But in this case it's more about the lag compensation in terms of firing weapons. Without lag compensation when a weapon is fired, you can see and hear the animation immediately, but the shot will be fired a little later when the server has calculated the shot. With lag compensation this would allow the player to aim correctly instead of having to guess where to aim like in Quake3 for example. It's also described here: http://developer.valvesoftware.com/wiki/Lag_Compensation#Lag_Compensation

The article mentions this technique of "reversing" the simulation on the server to an estimated command execution time for the client to fire a shot at something the client might have aimed at the time firing the shot.

So if you're saying there's no direct way of "reversing" a simulation, then I guess this is done using some advanced history keeping etc. Would a snapshot of the world maybe allow such reversing? Taking a snapshot, loading a saved one and doing the raycast, then reload the first snapshot again? But I guess this would be way too inefficient? This would also require some sort of interpolation between two snapshots, which I guess isn't possible?

Thanks again for the help!

S_W

joseph2008's picture
Quoting - s_w

Hi,

After reading this article http://www.gaffer.org/game-physics/networked-physics, I'm trying to implement a client-server model with client-side-prediction with some vehicles. I'm going to use a third party game networking library, so UDP packet ordering, server thread creation for each client etc. doesn't have to be done by myself.

I'm actually more uncertain about the best way of predicting physics on the client and the stepping on the server.

When does the server know it can step the simulation forward? Because waiting for all client to respond doesn't seem to be a solution. Or should there be some sort of "individual" stepping for each object as mentioned in the article? But I'm not sure how this could be done with Havok.

And how should the client reset or yet better interpolate its rigidbodies once a packet arrives from the server containing the correct transforms? How can I make sure that bodies won't interpenetrate? Maybe switching to keyframed for the sake of transforming the positions? But will this keep the physics running correctly and give a good input feedback to the player?

I know networked physics isn't an easy topic and it's the first time I'm trying to get this running, but maybe someone can help me with the two problems mentioned above. Well probably more to come... ;)

Thanks!

S_W

sean.thurston's picture

Hi S_W,

Those are pretty good articles (for anyone else doing netwroking). I would not recommend doing a snapshot because then you are going to save out a lot of information that you probably don't want. Things like world information and static geometry information. You pretty much only want to buffer the dynamic body transforms for a few frames. If memory becomes an issue than you can try saving a regular intervals and interpolating between those states. Then you could do the "reversing", registering any hits using the old transforms. It sounds like you have a pretty good grasp of this as it is.

Hopefully that helps. I'm anxious to hear how this turns out.

Thanks,
Sean

Developer Support Engineer Havok www.havok.com

Login to leave a comment.