Search Unity

Restitution breaks determinism when different physics steps per frame are taken in rerun

Discussion in 'Physics for ECS' started by Arnold_2013, Jul 28, 2021.

  1. Arnold_2013

    Arnold_2013

    Joined:
    Nov 24, 2013
    Posts:
    285
    I have a simple setup with some spawners spawning cubes with default physics values and no children (see this thread for more details). I get a hash of the state at every 'physics Tick' and write this hash to file to compare later. It all works fine with restitution value of 0 (tested to 5000 ticks), but when I use a higher value (tried 0.5 & 0.8) determinism breaks when the amount of 'physics ticks' in a frame is different from the original run.

    So if I just let it run the FPS will be >200 resulting in 1 physics tick per frame. And a rerun is equivalent (saved file hash is equal, so all bits are equal of the Translation, Rotation and PhysicsVelocity). But when I slow down the simulation before the fixedstepsystemgroup multiple steps will be taken to catch up to the real time and determinism breaks.

    I don't understand why the fixedStep catch up running the FixedStepSimulationGroup 3 times would result in a different result as running 3 frames with each 1 'physics tick'. What am i missing here?

    Is there a way to not have this issue? I am tempted to write my own catchup code and manually try to trigger a physics step... but it feels like a rabbit hole that might not even fix the issue or just lead to the next issue.
     
  2. TheOtherMonarch

    TheOtherMonarch

    Joined:
    Jul 28, 2012
    Posts:
    866
    Yes use

    Code (CSharp):
    1. new FixedRateUtils.FixedRateSimpleManager(MyFixedTimeStep)
     
  3. Arnold_2013

    Arnold_2013

    Joined:
    Nov 24, 2013
    Posts:
    285
    Thanks, I did not know this existed. It gave me more control over the amount of processed ticks and allowed me to confirm the amount of ticks processed matters for the FixedStepSimulationGroup.

    Code (CSharp):
    1. _fixedStepGroup = World.GetExistingSystem<FixedStepSimulationSystemGroup>();
    2.  
    3.  for (int i = 0; i < ticksToProccess; i++)
    4.     {
    5.       _fixedStepGroup.Update();
    6.       EntityManager.CompleteAllJobs();
    7.     }
    If I use a fixed value in 'ticksToProccess' it will be deterministic with the reference (1 tick per frame), using the values 2,3,5,6,10 or 15. It will not be deterministic with the values 4,7,8,9,11,12,13,14 or 16. Using a randomly picked value from the working values every frame does not work. o_O

    These results are far from conclusive, they might be very dependent on the values I used for my spawner positions, the friction and the restitution. And running a longer simulation might also result in currently deterministic values breaking determinism.

    I think for me a FixedRateSimpleManager with my own catchup system that processes 0 or 1 tick might work good enough for my needs.
     
  4. TheOtherMonarch

    TheOtherMonarch

    Joined:
    Jul 28, 2012
    Posts:
    866
    I don't know I am using world.update() not updating each system. But this breaks the debugger. There maybe a better way but I have not tested yet.

    Remember floats are not determinist yet.
     
    Last edited: Jul 29, 2021