Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

About Determinism

Discussion in 'Multiplayer' started by tasadar, Sep 17, 2013.

  1. tasadar

    tasadar

    Joined:
    Nov 23, 2010
    Posts:
    286
    hi, for the past couple of days ive been toying with a rts demo that will be synched over network with the classical lock step method. before diving into network stuff i wanted to make a sample that can be replayed locally. so i set up a system that runs at 10 fps, records user commands and applies them at fixed updates. i store the initial state of the world and the history of user commands. whenever i want, i press a button and the scene goes back to the initial state and the commands are executed at the exact game tick that they were saved.

    to check the correctness, i calculate a md5 hash value of the world state when i press replay and when the replay ends. so if the hash values are the same, we are ok.

    i force ToString method to give 10 digits for hash generation:
    Code (csharp):
    1.  
    2. position.x.ToString("F10");
    3.  
    here is a pseudo code of world state hash:
    Code (csharp):
    1.  
    2. string unit::getHashString()
    3. {
    4.    return pos.x + pos.y + pos.z + hp;
    5. }
    6.  
    7. string world::getHashString()
    8. {
    9.    string hash;
    10.    for each unit
    11.    {
    12.       hash += unit.getHashString();
    13.    }
    14.    return MD5(hash);
    15. }
    16.  
    well the problem is i can get the same hash values but i am not sure that this hash checking method is reliable. i read some stuff about floating point determinism but all was about c++, i have no information about mono and i am a bit surprised that i could get the same hash values at first try.

    i would like to hear any experience you can tell, thanks in advance.
     
    Last edited: Sep 17, 2013
  2. probbins

    probbins

    Joined:
    Oct 19, 2010
    Posts:
    216
    Floats are going to be your big issue, but in order to test for deterministic behaviour you will need to try it out on different hardware and architecture.

    Using ints is one way to deal with the issue.

    Some other causes that may cause non-deterministic behaviour is
    • Random number generator using different seed or being accessed in different orders.
    • Collections such as dictionaries do not maintain deterministic ordered.
    • Physics - In general is just a big no-no, especially Unity's PhysX. There are physic libraries which are deterministic but I am not sure if any work with Unity. (Havok, Box2D)

    I am currently using MD5 hash to check the game state, which has worked well for me so far.
     
  3. tasadar

    tasadar

    Joined:
    Nov 23, 2010
    Posts:
    286
    thanks for the reply.
    i have started working on networked sync but just as expected desyncs can easily happen. i'm trying to setup a proper lock step mechanism.

    - i will look out for dictionaries since i used them in some places.
    - there is no dynamics in the demo but i hope that i can use physx just for collision detection like line of sight checks.

    finally i think there is not much to do for different hardware and architecture but i'll think about it when it works locally...