Search Unity

TransformSystemGroup breaks Deterministic FixedStepSimulationSystemGroup Physics, how to solve?

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

  1. Arnold_2013

    Arnold_2013

    Joined:
    Nov 24, 2013
    Posts:
    285
    TL;DR;
    1. Is there a way to run the TransformSystemGroup deterministically in the FixedStepSimulationSystemGroup? (I dont mind the performance cost at this time)
    2. Is the TransformSystemGroup un-deterministic by default? (like using concurrent hashmaps or other known un-deterministic stuff)
    3. Why is TransformSystemGroup changing the Translate or Rotation of the root object ('parent physics cube')?
    4. Is there a better way to gain determinism?


    Full context:
    For my VR game I record the input which is relevant at every fixedstep so I can replay the input. I use this as a test during development so I dont have to put the VR set on my head as often. But when the physics starts to deviate from the recorded situation the test breaks.
    For the game itself I don't require determinism (its on my featurecreep list :)), so bad performance solutions are fine.

    Going through the forums I found that determinism should work on the same architecture even without deterministic floating points currently supported.

    Havok physics should also work deterministically as long as the 'internal simulation caches are also copied'. I assume (please correct me if i am wrong) this means that in my case where I start the simulation from the same point (run scene). The caches will be buildup deterministically.

    I created a new project to do some tests. I spawn a 'cube with physics & renderdata' every 30 fixedstep-steps every thing is fine (tested for 5000 fixed steps with 5 spawners). I have a waitSystem in the SimulationSystemGroup (not fixed) that stalls the CPU to force different amount of steps to be taken (catch up) in the FixedStepSimulationSystemGroup.
    But when I split the cube into a 'parent cube with physics' and a 'child cube with renerder data' the simulation works deterministically when there is no catch up, but with the waitSystem forcing different amount of fixedSteps to be taken in a frame determinism fails. When I disable the TransformSystemGroup the determinism comes back, but everything is rendered at (0,0,0). Which makes it less ideal to judge the test.

    I tried to force the TransformSystemGroup to run in FixedStepSimulationSystemGroup, but this is not running deterministically (if there is better code to do this please let me know):
    Code (CSharp):
    1.  var temp =  World.GetExistingSystem<TransformSystemGroup>();
    2.         temp.Enabled = true;
    3.         EntityManager.CompleteAllJobs();
    4.         temp.Update();
    5.         EntityManager.CompleteAllJobs();
    6.         temp.Enabled = false;
    I determine the determinism by creating new entities in a new world (serialisation world) and I add Translation, Rotation and PhysicsVelocity data from the default world after sorting by distance from origin (so only the 'parent cube with physics' is serialised, but only the relevant data). The resulting file is hashed every fixed frame and this hash is later used to compare against next runs per fixed frame.

    1. Is there a way to run the TransformSystemGroup deterministically in the FixedStepSimulationSystemGroup? (I dont mind the performance cost at this time)
    2. Is the TransformSystemGroup un-deterministic by default? (like using concurrent hashmaps or other known un-deterministic stuff)
    3. Why is TransformSystemGroup changing the Translate or Rotation of the root object ('parent physics cube')?
    4. Is there a better way to gain determinism?
     
    Last edited: Jul 26, 2021
  2. Arnold_2013

    Arnold_2013

    Joined:
    Nov 24, 2013
    Posts:
    285
    Just in case someone stumbels onto this thread. I had an extra issue with determinism. (https://forum.unity.com/threads/res...s-steps-per-frame-are-taken-in-rerun.1148021/)

    The solution from this thread that worked for me was to make my own catch up system that only runs 0 or 1 physics ticks per frame (so not really catchup, but also not running faster than normal time). This also avoids the TransformSystemGroup problem from the current thread, because this only happens when ticks processed are different.