I have dice game that I would like to have predictable physics given a seed to my own random number generator. I am using Physics.simulate() called from Update loop as in example.
If I restart the editor and have the dice roll, they land exactly the same way every time. I can play an entire game and get the exact same score.
If I play one game and then try to roll the dice using the exact same seed they behave close but slightly different. Not the same result as when I restart the emulator.
I have tried many combinations of making the rigid bodies kinematic, resetting their velocity and angular velocity etc.
I have turned Physics.autosimulate on then off again.
I have Logged all the values of the dice game objects and and they are all identical except the RigidBody.rotation quaternion, but when printed out they have the same Values and Euler values.
Is there a Physics.HardReset() function that can go through and set all calculations back to 0 like starting a PhysicsScene from scratch, just like starting the editor over?
Also interested in this. I’ve found that Physics is deterministic as long as you’re starting a new PlayMode session, but there’s no clear way to reset the physics scene in the middle of gameplay.
The only way I found to get real physics determinism is to load a new scene with Physics3D set for the Local Physics Mode. That creates a new PhysicsScene from scratch for the scene, which resets physics and I get deterministic behavior after that.
did you ever find a better way? I came to a similar solution as you but with 2D, but I would love to be able to reset without recreating the scene from scratch.
Sorry for asking a stupid question, but do you recreate scene, move all the bodies to the physics scene every time? I am in the same boat as I need determinism for my game… Would be great if you share the approach. Thank you!
Do you recreate scene and move all the bodies to the physics scene every time you want a determinism? I am in the same boat as I need determinism for my game… Would be great if you share the approach. Thank you!
We don’t move any bodies to the physics scene. That would probably break determinism, but it depends on what you mean, you’d need to be more precise.
The best way to think about it is that PhysX is deterministic as long as the APIs called are exactly the same, in the exact same order. So, in pseudocode, if your game does something like:
CreateNewScene (LocalPhysics = true)
AddRigidBody A
AddRigidBody B
Physics.Update
ApplyForce on A
AddRigidBody C
Physics.Update
then you could get determinism by making sure your game did exactly the same thing:
CreateNewScene (LocalPhysics = true)
AddRigidBody A
AddRigidBody B
Physics.Update
ApplyForce on A
AddRigidBody C
Physics.Update
However, you would not get determinism if you then did:
CreateNewScene (LocalPhysics = true)
AddRigidBody A
AddRigidBody B
AddRigidBody C
Physics.Update
ApplyForce on A
Physics.Update
This is because you’ve changed what objects are present on each frame.
Hey! thank you for the explanation. I was able to achieve determinism by creating a separate physics scene… Only bug I have is it works different the first time(going to fix it)
One thing though, the deterministic behaviour is different on PC, Android and iOS. Upon googling I found that Unity doesn’t support cross-platform determinism. Just wondering if you found any workaround for that?
Yeah, it’ll be tough, unless you’re satisfied with close-to-determinsm. If you just want the puzzles to play out similarly, you may not need perfect determinism… depends on the design of the game.
Personally, I’d recommend designing around this. Just make your puzzles somewhat robust to slight tweaks and rounding errors.
It’s not the physics system that’s (not) deterministic, it’s the fact that it uses floating-point which isn’t across CPU platforms. This affects absolutely everything in Unity both C++ and C# including your scripts.
It’s a myth that it’s somehow physics that fixes this. Physics is however a perfect system to highlight small changes (over time) making big differences (think “Chaos”) because it takes the previous set of calculations and bases the next set of calculations upon it so those feedback changes magnify but it isn’t physics specific nor would it be fixed by physics. You can easily do this in a script.
Systems such as physics can do things to make it less deterministic though such as solving on threads which can cause differences depending on how that works on different platforms but there are well established strategies to deal with this (sorting, working on spans of data only in the same order etc).
This is why there’s fully determinstic (numeric handling deterministic and everything process in the same order) but there’s less-than fully deterministic (numeric handling not deterministic) which is what all of Unity is now. It’s certainly not just “Deterministic” or “Not Deterministic”.