PhotonNetwork.time & online timer

I'm making a timer based off the server time. This is what the docs have to say about PhotonNetwork.time:

"Use this value with care:
It can start with any positive value.
It will "wrap around" from 4294967.295 to 0!"

So what happens if someones joins a room and the time is 4294965? In just 2 seconds, it will go back to 0, which could really screw the timer, am I right?
Is there a "deltaTime" or equivalent function? What's the best way to accomplish this?

Comments

  • Hi,

    I am having that problem too. What happens with the games that begins just before the restart of the timer??
    I calculate some events in the game based in the creation time of the room. A restart of the timer will produce that some events will not happen until 48 days after!
    Are there any way to solve this? even with a "hack"?

    Thanks.
  • PhotonNetwork.time did not turn out to be as useful as we wished it should be. We plan to refactor this but don't know when this will happen.

    It's better to use the lower-level PhotonNetwork.ServerTimestamp.
    This is a signed integer, based on Environment.TickCount. The benefit of this is: When you substract any two values, you always get a valid time difference in milliseconds. The overflow (on the server) doesn't matter in this use case, which is effective when you measure how long things last.

    It can also be used to establish an in-room time: A client can store the timestamp of "when the match begins" and everything happening later on can be based off that.

  • Thanks Tobias, but, why it has no problem when the var reachs its final value?

    We are changing from seconds to milliseconds in all the game code using now PhotonNetwork.ServerTimestamp.

  • Tobias wrote: »

    It's better to use the lower-level PhotonNetwork.ServerTimestamp.
    This is a signed integer, based on Environment.TickCount. The benefit of this is: When you substract any two values, you always get a valid time difference in milliseconds. The overflow (on the server) doesn't matter in this use case, which is effective when you measure how long things last.

    Can you please elaborate on this?

    I'm just trying to start a battle at the same time on 2 devices. If device A says
    int startTime = PhotonNetwork.ServerTimestamp +2000;
    
    and sends that to Device B. Meanwhile, PhotonNetwork.ServerTimestamp wraps around to 0 or even a negative value. Once device B receives the startTime and checks it against the PhotonNetwork.ServerTimestamp, won't the whole calculation be wrong?

    eg
    //on device B
    //startTime really big
    //PhotonNetwork.ServerTimestamp really small or negative
    int timeUntilStart = PhotonNetwork.ServerTimestamp - startTime;
    

    Thanks




  • or does the way it wraps mean that if device A sends the PhotonNetwork.ServerTimestamp and then device B says
    int elapsedTime = PhotonNetwork.ServerTimestamp - sentTimeStamp;
    

    then elapsedTime will always be correct?

    Thanks

  • I can see how that would work when the ServerTimestamp goes from negative to positive as the message is sent, but not when it goes from positive to negative. Do I need to convert the values to make them all positive or something when doing the calculation?
  • BigGameCo
    BigGameCo
    edited April 2020
    does this look like it would start the battle 1 second after the RPC is sent? Can this be broken by the value wrapping? Thanks
    photonView.RPC("ReadyToStartBattle", RpcTarget.All, PhotonNetwork.ServerTimestamp);
    
    [PunRPC]
        void ReadyToStartBattle(int startTimestamp)
        {
            Debug.Log("ReadyToStartBattle " + startTimestamp);
            startBattleTimestamp = startTimestamp;
            StartCoroutine(StartBattleAtSameTime());
        }
    
        IEnumerator StartBattleAtSameTime()
        {
            while ((uint) ReturnElapsedTimeSinceBattleReadyToStartMessageSent() < 1000)
            {
                yield return Yielders.EndOfFrame;
            }
            //start the battle
        }
        
        int ReturnElapsedTimeSinceBattleReadyToStartMessageSent()
        {
            return PhotonNetwork.ServerTimestamp - startBattleTimestamp; 
        }
    
  • doug_h
    doug_h
    edited May 2020
    You might have figured this out by now, but after reading into this wrap around 'problem' for a day whilst trying to figure out how to write my timer code, I feel like it's not properly explained why it's not an issue in any of the other responses on this forum (sorry if I missed a good explanation somewhere).

    I suspect the reason for this is that it's a pretty basic (at least for people more experienced than myself) integer overflow code - PhotonNetwork.ServerTimestamp is a signed int which will overflow when it hits 2,147,483,647 to -2,147,483,648.

    Lets say we get the server timestamp at our max int value (2,147,483,647) and then wrap around by 5 seconds. 2,147,483,647 +5 seconds (5,000 milliseconds) overflows to -2,147,478,649.

    Now when doing a normal, non 32bit integer calculation to work out end time minus start time, -2,147,478,649 - 2,147,483,647 would equal -4,294,962,296, which is not our desired time difference of 5,000ms. However the important thing to understand is that we are doing an integer operation, which means that the result must also fit within the previously mentioned singed int range. The result of -4,294,962,296 is therefore automatically 'overflowed' for us by the compiler to become -5,000, as -4,294,962,296 cannot be represented in the singed integer range of -2,147,483,648 to 2,147,483,647.

    As a result, the timer code of endTime - startTime will always work as expected, even when an overflow occurs. Hope this helps someone!
  • Yes, That works ok in terms of the time transcurred before/after the overflow.
    But the problem is when you store times before the overflow and later you compare that saved times with the new ones with the inverted sign times.
    The time transcurred is ok. But when you compare times stored in one moment with times after the overflow you have big lapse of time.
    Do you see my point?

    A problematic scenario:
    In a lobby sorting the rooms by date of creation. Imagine that rooms can be active for days. In the overflow day you can see strange things related with the sorting of rooms depending in creation dates.