PhotonNetwork.time & online timer

The whole answer can be found below.

Please note: The Photon forum is closed permanently. After many dedicated years of service we have made the decision to retire our forum and switch to read-only: we've saved the best to last! And we offer you support through these channels:

Try Our
Documentation

Please check if you can find an answer in our extensive documentation on PUN.

Join Us
on Discord

Meet and talk to our staff and the entire Photon-Community via Discord.

Read More on
Stack Overflow

Find more information on Stack Overflow (for Circle members only).

Write Us
an E-Mail

Feel free to send your question directly to our developers.

PhotonNetwork.time & online timer

darkgolemgames
2015-08-09 17:48:10

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

[Deleted User]
2015-08-10 15:24:30

Hi,

I hope similar topic can help: http://forum.photonengine.com/discussion/comment/23653/#Comment_23653

PeP
2016-03-01 16:01:28

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.

Tobias
2016-03-10 11:51:56

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.

PeP_Bkool
2016-03-18 14:27:38

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.

BigGameCo
2020-04-11 02:03:55

@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

BigGameCo
2020-04-11 02:23:32

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

BigGameCo
2020-04-11 02:33:06

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
2020-04-11 02:56:05

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
2020-05-17 02:01:07

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!

PeP
2020-05-17 02:17:28

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.

Back to top