I'm working on a 2D lockstep networked game so I'm looking at using BEPU1Int to be my collision separation solution. However the simulations of two players keeps diverging. I've created a simple in process test that fails due to divergence.
Code: Select all
[Test]
public void TestDeterminismLateJoin()
{
// Can't use mutlithreading so don't pass in an IParallelLooper
Space space1 = new Space();
space1.TimeStepSettings.TimeStepDuration = ((Fix64) 1 / 60);
Box box11 = CreatePhysicsObject(space1);
box11.ActivityInformation.IsAlwaysActive = true;
box11.LinearDamping = ((Fix64) 1 / 2);
Box box12 = CreatePhysicsObject(space1);
box11.ActivityInformation.IsAlwaysActive = true;
box11.LinearDamping = ((Fix64) 1 / 2);
int preIterations = 100;
for (int i = 0; i < preIterations; i++)
{
space1.Update(space1.TimeStepSettings.TimeStepDuration);
}
Box box13 = CreatePhysicsObject(space1);
box13.ActivityInformation.IsAlwaysActive = true;
box13.LinearDamping = ((Fix64) 1 / 2);
box13.Position = box11.Position;
Space space2 = new Space();
// As far as I can tell this will impact the random(?) solver
space2.Solver.PermutationMapper.PermutationIndex = space1.Solver.PermutationMapper.PermutationIndex;
space2.TimeStepSettings.TimeStepDuration = ((Fix64) 1 / 60);
Box box21 = CreatePhysicsObject(space2);
box21.ActivityInformation.IsAlwaysActive = true;
box21.LinearDamping = ((Fix64) 1 / 2);
// Saw in a forum post that this is what is needed to get full state across
box21.Position = box11.Position;
box21.LinearVelocity = box11.LinearVelocity;
box21.Orientation = box11.Orientation;
box21.AngularVelocity = box11.AngularVelocity;
Box box22 = CreatePhysicsObject(space2);
box22.ActivityInformation.IsAlwaysActive = true;
box22.LinearDamping = ((Fix64) 1 / 2);
box22.Position = box12.Position;
box22.LinearVelocity = box12.LinearVelocity;
box22.Orientation = box12.Orientation;
box22.AngularVelocity = box12.AngularVelocity;
Box box23 = CreatePhysicsObject(space2);
box23.ActivityInformation.IsAlwaysActive = true;
box23.LinearDamping = ((Fix64) 1 / 2);
box23.Position = box21.Position;
Assert.IsTrue(box11.Position != Vector3.Zero);
Assert.IsTrue(box12.Position != Vector3.Zero);
Assert.IsTrue(box21.Position != Vector3.Zero);
Assert.IsTrue(box22.Position != Vector3.Zero);
int iterations = 1000;
for (int i = 0; i < iterations; i++)
{
space1.Update(space1.TimeStepSettings.TimeStepDuration);
space2.Update(space2.TimeStepSettings.TimeStepDuration);
}
// THESE ASSERTS FAIL
Assert.IsTrue(box11.Position == box21.Position);
Assert.IsTrue(box12.Position == box22.Position);
Assert.IsTrue(box13.Position == box23.Position);
}
private static Box CreatePhysicsObject(Space space)
{
Box box = new Box(Vector3.Zero, 1, 1, 1, 1);
box.PositionUpdateMode = PositionUpdateMode.Continuous;
PointOnPlaneJoint pointOnPlaneJoint = new PointOnPlaneJoint(
null,
box,
new Vector3(),
new Vector3(0, 0, -1),
box.Position);
space.Add(pointOnPlaneJoint);
RevoluteAngularJoint angularJoint = new RevoluteAngularJoint(
null,
box,
new Vector3(0, 0, -1));
space.Add(angularJoint);
space.Add(box);
return box;
}
At the end of this their positions do not match. I'm not sure if I missing state or otherwise haven't set something up correctly. Or if I just messed up the test but I've looked over it numerous times and don't see anything.
If able to help it would be much appreciated! Thanks!