Reset Physics

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?

I am using Unity 2018.4.

Are you using FixedUpdate? Update() is framerate-dependent and can fluctuate, leading to inconsistencies.

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.

Try making your randomizable GameObject a prefab and instantiating it each time you set a new RandomState. Something like this:

public class RandomizableComponent : MonoBehaviour
{
    public static RandomizableComponent Instance { get; private set; }

    public static void Restart(int initState)
    {
        if (Instance != null) Destroy(Instance);

        Random.InitState(initState);
        Instance = Resources.Load<GameObject>("YourPrefabName").GetComponent<RandomizableComponent>();
    }
}

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.

Nope, unfortunately that’s the method we use for our game.

int seed; //The seed

void Start()
{
    System.Random seedRandom = new System.Random(seed);
}

It should work

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?

Unfortunately PhysX is nowhere close to being cross-platform deterministic. :frowning: Your best options would be:

  • Use a third party physics engine that is (not sure which ones).
  • Write your own custom physics using fixed-point numbers.
  • Wait for the Unity.Physics ECS package to be cross-platform deterministic (it’s on the roadmap).

We never needed cross-platform determinism because The Last Clockwinder is a singleplayer game.

Darn! I am making a physics based puzzle game and need cross platform determinism so the results are same on all platforms. Not a multiplayer game…

Guess I will have to scrap the project since custom physics is too much work. Maybe I can resume it once deterministic behaviour is available in ECS

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.

1 Like

Thank you for the suggestion. I’ll think over it!

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”.