From my experience, full replication of the physics engine state is difficult and unnecessary.
For real time multiplayer games, you usually run a local physics simulation and make corrections to it if the state (positions, rotations, velocities) differ too much from the server state. Unreal Engine uses this approach, read more at https://docs.unrealengine.com/udk/Three/NetworkingOverview.html#Physics
Games that only need the initial state of a physics scene to carry out an animation (such as turn based games), don't need the full physics engine state either. Physics engines are deterministic if you use them in a deterministic way. To re-play a physics animation the same way on two clients, keep in mind:
- Reset (re-create) the
b2World
before starting the simulation, to get rid of any internal state in the b2World
.
- Set up your physics world, create bodies at their initial positions, etc.
- Step the simulation forward, using the same fixed time step on all clients (don't use the render frame delta time because it's not the same on all clients!).
- If you need to interact with the bodies during simulation (for example, apply a force), then it's important to do it on the same step number.
As an example, the following function will return the same result every time on all clients, if they all get the same InitialPhysicsState
:
float deterministicFunction( InitialPhysicsState state ){
b2World* world = createWorld(state);
b2Body* body = world->GetBodyList();
for(int i=0; i<100; i++){
if(i==50){
body->ApplyForce(b2Vec2(10.0f, 2.0f));
}
world->Step(0.01f, 8, 3);
}
return body->GetPosition().y;
}