Determinism in multiplayer simulation with Box2D, and single computer
- by Jake
I wrote a small test car driving multiplayer game with Box2D using TCP server-client communcations.
I ran 1 instance of server.exe and 2 instance of client.exe on the same machine that I code and compile the executables. I type inputs (WASD for a simple car movement) into one of the 2 clients and I can get both clients to update the simulation.
There are 2 cars in the simulation. As long as the cars do not collide, I get the same identical output on both client.exe. I can run the car(s) around for as long as I could they still update the same. However, if I start to collide the cars, very quickly they go out of sync.
My tools: Windows 7, C++, MSVS 2010, Box2D, freeGlut.
My Psuedocode:
// client.exe
void timer(int value)
{
tcpServer.send(my_inputs);
foreach(i = player including myself) inputs[i] = tcpServer.receive();
foreach(i = player including myself) players[i].process(inputs[i]);
myb2World.step(33, 8, 6); // Box2D world step simulation
foreach(i = player including myself) renderer.render(player[i]);
glutTimerFunc(33, timer, 0);
}
// server.exe
void serviceloop
{
while(all clients alive)
{
foreach(c = clients) tcpClients[c].receive(&inputs[c]);
// send input of each client to all clients
foreach(source = clients)
{
foreach(dest = clients)
{
tcpClients[dest].send(inputs[source]);
}
}
}
}
I have read all over the internet and SE the following claims (paraphrased):
Box2D is deterministic as long as floating point
architecture/implementation is the same.
(For any deterministic engine) Determinism is gauranteed if playback of recorded inputs is on the same machine with exe compiled using same compiler and machine.
Additionally my server.exe and client.exe gameloop is single thread with blocking socket calls and fixed time step.
Question: Can anyone explain what I did wrong to get different Box2D output?