Investigate Cross Platform Determinsim
Ughuuu opened this issue · 6 comments
Right now the plugin isn't cross platform deterministic. The issues could be from:
- The internal state of the plugin
- The wrapper of rapier
- Something else
From my investigation the plugin uses .length(), as it uses Vector2 of godot-cpp, which in turn uses sqrt, which isn't cross platform deterministic.
Need to investigate other possible things as well. After asking on chat.godotengine.com about it, got some helpful tips as well:
AThousandShips:
Then it isn't related to the extension code itself, and the only possible cause is the cross-platform differences in sqrt etc.
As the built-in types like those are entirely self-contained on extensions, for performance reasons
But I'd suggest just testing the output of various simple operations across platforms just to see, generate a bunch of vectors for example and run the operations on them on both systems, just create a data file to store them in and load them on both machines
If they yield the same results then it's going to be the way you've translated this library to the language in question, it's easy to make mistakes when translating between languages
And of course make sure you're actually setting up a test that ensures determinism, because floating point mathematics isn't deterministic when out of order due to rounding, so it's important that your testing conditions are actually such that they test for determinism
And, and this is really important, make sure the data for the tests are dynamic, no compile time tests, it has to be loaded, because that's a classic trap
Especially with floating point math compile time and runtime is a mess
Can refer to this:
https://gitlab.com/snopek-games/sg-physics-2d
Doesn't support rigid bodies and is written from scratch but the author has created a separate vector implementation
Running the following code:
extends Node2D
func _ready():
var angle_start = -PI
var steps = 1000
var step_increase = 1.0 / steps
var hash_final :int = 0
for step in 1000:
var angle :float= angle_start + step * step_increase * 2 * PI
var value :float= step * step_increase * 10
var str1 :String= "angle: " + str(angle) + " sin: " + str(sin(angle))+ " cos: "+ str(cos(angle))+ " tan: "+ str(tan(angle))
var str2 :String= "value: " + str(value) + " sqrt: " + str(sqrt(value))
hash_final += str1.hash()
hash_final += str2.hash()
print(hash_final)
on both mac and web, I get the following hashes:
- mac: 4235844765204
- web: 4233582584233
So it seems the sin/cos/tan/sqrt implementations are indeed not cross platform deterministic.
For me it gives same hash:
Web: 4233582584233
Linux: 4233582584233
has there been any progress on this front?
With the new rewrite itll be possible and easier to do this, add in rust it's easier to save state of objects, and also to build for web.
Removing it from issues as it is in readme as limitation. Better to not track it in issues also.