schteppe / p2.js

JavaScript 2D physics library
Other
2.64k stars 330 forks source link

Is p2 deterministic? Slightly different floating point numbers on same run. #236

Closed simplyanything closed 8 years ago

simplyanything commented 8 years ago

Hi Scheppe. First of all, truly, what a great physics engine. Thank you for this!

I'm developing a multiplayer game. However, I noticed that the positions of some bodies floating points are not equal if I run the same simulation and apply the same impulse on a couple of objects. The floating point is not equal after 4 digits after the decimal. (so 0.0000xxxxxxx where x are different each time). I run this impulse on the postStep function. Once the objects are not moving anymore, I check their positions and compare them with a previous run (exact same impulse size/initial position start etc.) and then I notice that they are slightly different. This is on 1 machine. I'm updating the world inside a setInterval function.

Hence, if I run it on the server, the position will vary greatly after a couple of impulses with the client (unless I correct the position after every impulse).

Is this expected behaviour? Do you perhaps have some tips to deal with this?

Thank you!

schteppe commented 8 years ago

Hi. If you use the step method like this: world.step(dt) and use a constant value of dt, then all should be deterministic. Of course, you'll have to make sure the number of steps are synced and that the rest of your code is deterministic.

The impulse must be applied on the exact same step (physics time) on both client and server.

simplyanything commented 8 years ago

Thank you for the reply! Interesting, I tried world.step(dt, timeSinceLastCalled, maxSubSteps), but then tried world.step(dt), while also syncing the time (world.time) between the client and server. It looks much better although sometimes still a little bit different on numbers after the decimal. I will try to see what I can do to further fix this based on your advice. Thanks for this!

One final question regarding the world object itself. I'm planning to host multiple games on the same server. Each game would have a separate world (due to different players and objects). Do you think that this may be heavy and are there other options? Or should I try to use only 1 world for all players (and hide the players that are in another game)?

schteppe commented 8 years ago

Ok cool!

The best would probably be to have separate World instances. The solver would not have to do all the splitting work by itself. Having multiple simulations running in the same thread can be a problem though. Maybe they should run in their own threads?

simplyanything commented 8 years ago

Thank you! :)