Significant Problems with PhotonNetwork.time and timestamps
The whole answer can be found below.
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).
Significant Problems with PhotonNetwork.time and timestamps
invulse
2012-02-14 02:20:21
I've searched through the forums and docs for some clarity on this but to my surprise I appear to be the only one whos noticed this.
After having serious issues and discrepancies with timestamps in OnPhotonSerializeView and PhotonNetwork.time's I started investigating what why I was getting such strange results and I discovered these values are only being recorded in increments of .256 .
Basically PhotonNetwork.time is only updated every .256 seconds, with values in increments of .256, which makes the time value unusable as objects in my game are updated locally up to 60 times a second and need to get a very precise number from this. Not only is this the case but any value in PhotonMessageInfo.timestamp is also constrained to the same precision! With both of these issues, it is the case that I will get RPC calls and Serialization updates on my PhotonView's which are not the correct times and in many cases have the exact same time values as previous updates or RPCs. This causes my interpolation scripts to not function at all since they require precision to the thousandth of a second and not 1/4 seconds.
Here are some print values I got by sending and RPC to another client the printing the PhotonNetwork.time value and info.timestamp value of the RPC.
TIME: 3059293.952 TIMESTAMP: 3059293.696 DIFFERENCE: .256 TIME: 3059294.2080000001 TIMESTAMP: 3059293.952 DIFFERENCE: .256 TIME: 3059294.7200000002 TIMESTAMP: 3059294.4640000002 DIFFERENCE: .256
Obviously in a networked game delays between the sending of a packet and receiving of a packet remotely should vary pretty significantly, but in every case here the difference between the timestamp and time when received is exactly .256 seconds.
Has anyone else noticed this or any Photon developers have a solution? I am very surprised that no one else has posted this before, as having accurate timestamps and network time values are imperative to a realtime multiplayer game running smoothly and accurately.
Comments
why should it vary greatly?
If your latency is lower than whats required to keep up with the sendrate for serialization, then it should definitely not vary significantly or the server hw / connection are at fault of it and the server location should be reconsidered (read that as 'crap on the level of amazon EC2 which you never should touch for anything realtime / latency dependent as pings from 80ms to 3000ms+ in a matter of minutes is inacceptable' ).
That it naturally is that 'point on' is a bit strange but might actually be a sign that it went through even faster and was delayed until the call to service at which point the client processed this received packet (256ms latency is a long time, don't forget that)
Heres a clearer idea of what is happening in Photon.
I added this update function to a script:
void Update ( )
{
print("Time.time: " + Time.time + " PhotonNetwork.time: " + PhotonNetwork.time);
}
and this is what it outputted:
Time.time: 3.098199 PhotonNetwork.time: 3869677.824 Time.time: 3.114767 PhotonNetwork.time: 3869678.08 Time.time: 3.131337 PhotonNetwork.time: 3869678.08 Time.time: 3.147892 PhotonNetwork.time: 3869678.08 Time.time: 3.164488 PhotonNetwork.time: 3869678.08 Time.time: 3.181095 PhotonNetwork.time: 3869678.08 Time.time: 3.197635 PhotonNetwork.time: 3869678.08 Time.time: 3.21418 PhotonNetwork.time: 3869678.08 Time.time: 3.230913 PhotonNetwork.time: 3869678.08 Time.time: 3.247299 PhotonNetwork.time: 3869678.08 Time.time: 3.26386 PhotonNetwork.time: 3869678.08 Time.time: 3.281671 PhotonNetwork.time: 3869678.08 Time.time: 3.298252 PhotonNetwork.time: 3869678.08 Time.time: 3.31481 PhotonNetwork.time: 3869678.08 Time.time: 3.331405 PhotonNetwork.time: 3869678.08 Time.time: 3.348012 PhotonNetwork.time: 3869678.08 Time.time: 3.364512 PhotonNetwork.time: 3869678.336
The PhotonNetwork.time is updating every .256 seconds and is always exactly .256 seconds difference between the last and new time value when it changes.. Even if ping times were as steady as that, this is still a big issue because this makes PhotonMessageInfo.timestamp inherently inaccurate and the PhotonNetwork.time value unusable as its not precise. When using Unity's Network.time, I had to manually send a message to Synchronize clients times as each persons Network.time value was different, but I was able to do this because the timestamps in Unity's networking are accurate. Without these timestamps or time values being accurate in Photon I cannot use any time values at all that are related to when messages were sent or when serializations were sent.
In the Photon client library, we usually use the Environment.TickCount value. This is a (very) cheap but (somewhat) inaccurate way to get the timestamp and measure time in general. The inaccuracy you detected is too big to be just caused by the TickCount, which is accurate to ~15ms. However, TickCount also is a int value, which we convert into the double-typed value you're used by Unity's time.
Maybe it's a loss of accuracy during conversion. Which PUN version are you using?
@Tobias wrote:
In the Photon client library, we usually use the Environment.TickCount value. This is a (very) cheap but (somewhat) inaccurate way to get the timestamp and measure time in general. The inaccuracy you detected is too big to be just caused by the TickCount, which is accurate to ~15ms. However, TickCount also is a int value, which we convert into the double-typed value you're used by Unity's time.
Maybe it's a loss of accuracy during conversion. Which PUN version are you using?
This is very strange, something has changed since I posted this morning. The PhotonNetwork.time value is now very low compared to the value this morning but all of a sudden its values are showing up as correct.
Here are the values printed out now:
Time.time: 17.80166 PhotonNetwork.time: 7326.403 Time.time: 17.81821 PhotonNetwork.time: 7326.419 Time.time: 17.83483 PhotonNetwork.time: 7326.436
As you can see the values are actually updating correctly now but the time is in the thousands of seconds not millions. I read somewhere on the forum that the time continues to go up on the server for approximately 49 days until the value overflows and resets to 0. Is it possible that this needs to happen much earlier, as it seems like when the value gets into the millions of seconds the accuracy when converted to seconds drops.
Yes, internally, our time is based on "milliseconds since server started". This will wrap after ~49 days. So depending on which game server you are on, the time value will be different (no absolute base).
It's also ~15ms accurate but no longer when we're up in the high values, obviously. I didn't expect this issue as we are converting to double, which should have enough precision, even when our internal time is close to wrapping.
We could base the time on room-creation probably. You would still have to think about the wrap-around to 0 but have 49 days time per room. Not sure if that's preferable to the current solution??
@Tobias wrote:
Yes, internally, our time is based on "milliseconds since server started". This will wrap after ~49 days. So depending on which game server you are on, the time value will be different (no absolute base).
It's also ~15ms accurate but no longer when we're up in the high values, obviously. I didn't expect this issue as we are converting to double, which should have enough precision, even when our internal time is close to wrapping.
We could base the time on room-creation probably. You would still have to think about the wrap-around to 0 but have 49 days time per room. Not sure if that's preferable to the current solution??
That would be a better solution than it currently is. Right now it seems that any game that relies on comparing timestamp values with network times will stop working at some point when reaching the 49 day limit until it resets to 0. If the times were based on when you entered a room, for games that are not MMO's this would be fine as i doubt anyone would be playing in a single room for 49 days straight. Wouldn't a simpler solution be to reset the time value earlier? Couldn't the server have a check that resets the time value once it reaches a certain point which is sooner?
You should never mix Time.time or Time.realtimeSinceStartup against network time, no matter what. Either base your stuff on NetworkTime, which you should if its MP as the server drives the simulation and thus the time or base it on Unity time, which you should if its Single Player or 'server independent approximation to reduce polling' (means if you approximate the end of an operation to request verification then - building in 'ville' style MMOs would be such a case)
Reason is that no matter how you do it your hardware is practically granted to not run on the same tick as the server, as the time precision is different on each hardware. Even if it uses the high precision timer x64 hw offers, which often is not even enabled in bios on home user boxes, Unity will not do it so the time values you get from untiy are always crapped, they are only meaningful as long as all your stuff bases on them only.
Beside that, you get the overflow problem on homeuser machines too so the Time values will not work there either
Back to top