PhotonNetwork.time is not synchronized

I faced strange behavior:

PhotonNetwork.time is synchronized in proper way in Editor/Standalone build, but
when I run it under iOS devices PhotonNetwork.time is different from sever timestamps dramatically (millions)

What can cause this problem?

I am using PhotonServer on standalone machine and free PUN from asset store...

On iOS I got negative values.

Server time double: -1155847.248
Server time ms: -1155847248

Server time that I got via RPC is: 3137684
PhotonNetwork.FetchServerTimestamp() - does not help...

Very strange that it reproducible on iOS actual device only (not in editor/nor standalone build for win/mac)

BTW, in editor I got following:

Server time double: 3139752.208 (using PhotonNetwork.time)
Server time ms: -1155215088 (using PhotonNetwork.networkingPeer.ServerTimeInMilliSeconds)


I think the problem is near....

Somehow on iOS the following line in getter produce NEGATIVE value:

public static double time
{
...
return ((double)(uint)networkingPeer.ServerTimeInMilliSeconds) / 1000.0f;
...
}

Comments

  • I'm facing similar issues. I posted on the forums about it the other day but didn't get a response. Have you tried 1.54? It was released recently but there's nothing in the changelog about this bug. I'll post again when I get a chance to test it myself.
  • I think this is UNITY bag, more specific in IL2CPP (because in Editor/standalone all is good)

    return ((double)(uint)networkingPeer.ServerTimeInMilliSeconds) / 1000.0f;

    and return NEGATIVE number on iOS device
    BTW, it works correct on android devices.

    May be because of 64bit target for compilation under iOS... not sure :)
  • No problems with PUN 1.51. Bug occurs when using PUN 1.53. Checkout the changelog, they are aware of the issue and attempted a fix in a recent update. Seems the bug is still present in 1.53.

    If its a unity bug I could really do with a work-around from the PUN team until unity fixes it. Since the code is wrapped up in DLLs its very difficult to isolate the problem myself and submit an effective bug report to unity. This really needs to be done by the PUN team.

    There's some more details in my post from a few days ago:
    viewtopic.php?f=17&t=6153
  • quickfix is possible and it WORKS fine for me :)
    also I replace 1000.0f -> 1000.0 when return double

    PhotonNetwork.cs
    public static double time
        {
            get
            {
                if (offlineMode)
                {
                    return Time.time;
                }
                else
                {
    				// VH FIX - negative value on iOS (!!! sad, but true)
    #if UNITY_IPHONE
    				int timeInt = networkingPeer.ServerTimeInMilliSeconds;
    				double result = timeInt > 0 ? (double)timeInt : (double)(uint.MaxValue + timeInt);
    				return result / 1000.0; 
    #else
    				return ((double)(uint)networkingPeer.ServerTimeInMilliSeconds) / 1000.0;
    #endif
                }
            }
        }
    

    the same added PhotonMessageInfo class
    public double timestamp
        {
    		get 
    		{
    			// VH FIX - negative value on iOS (!!! sad, but true)
    #if UNITY_IPHONE
    			double result = timeInt > 0 ? (double)timeInt : (double)(uint.MaxValue + timeInt);
    			return result / 1000.0;
    #else
    			return ((double)(uint)this.timeInt) / 1000.0;
    #endif
    		}
        }
    
  • The server time (networkingPeer.ServerTimeInMilliSeconds) is different per server and can be very different per room, too. Important is, the same time is available in a room.
    The negative values are OK and expected (but annoying to use in Unity, so we change that).
    The cause for the recent PhotonNetwork.time changes are problems in some Unity versions with IL2CPP. Those are gone in the more recent patches.

    To avoid the negative values, it should be enough to cast the ServerTimeInMilliseconds to an uint before using it. However, just putting the cast before the ServerTimeInMilliSeconds does not help (IL2CPP strips that).


    Use this code to avoid negative time values:
    [code2=csharp]public static double time
    {
    get
    {
    if (offlineMode)
    {
    return Time.time;
    }
    else
    {
    uint u = (uint)networkingPeer.ServerTimeInMilliSeconds;
    double t = u;
    return t / 1000;
    }
    }
    }[/code2]


    I will change how the time is updated.
    Right now, it's based on Environment.TickCount but that's not as precise as Time.time.
    Also, there can be an overflow of networkingPeer.ServerTimeInMilliSeconds. As double, the value will jump when ServerTimeInMilliSeconds goes from -1 to 0. This is rare but using Time.realtimeSinceStartup should avoid that issue, too.

    I will post another update in an hour or so.
  • We kept thinking about this topic and came to the conclusion, that it's probably a bad design idea to give you PhotonNetwork.time as double. The time we get from the server is not a double and will overflow at some point, depending on how long it's running already. That can be in three weeks or right after a few seconds. And as double, the overflow is harder to detect and it's harder to calculate time-deltas for events.

    We will need more time and discussion to come up with a good solution.
    Right now, please use the fix above and we will update PUN early next week, too.
  • Any updates Tobias? I think it would also be nice to have a "TimeSinceRoomOpened".
  • Sorry, I didn't tackle this yet.
    Afaik, the issues on IL2CPP should be resolved, no?

    The rest would mean a change in the API and I always take a long time before I do those.
    Right now, I am working on something else (ability to block slots in rooms for friends/teammates) and can't say when I find the time to redo the time system.

    The TimeSinceRoomOpened is a good idea. Will take a note to add this.
  • Any chance there is something like 'TimeSinceRoomOpened' already implemented? Trying to make some countdown for Live games that depends on room's lifetime.
  • What is the status of PhotonNetwork.time? What's the best way to get elapsed time accounting for rollover?
  • &gt?
    LeshaVH said:

    quickfix is possible and it WORKS fine for me :)

    also I replace 1000.0f -> 1000.0 when return double



    PhotonNetwork.cs


    public static double time
        {
            get
            {
                if (offlineMode)
                {
                    return Time.time;
                }
                else
                {
    				// VH FIX - negative value on iOS (!!! sad, but true)
    #if UNITY_IPHONE
    				int timeInt = networkingPeer.ServerTimeInMilliSeconds;
    				double result = timeInt > 0 ? (double)timeInt : (double)(uint.MaxValue + timeInt);
    				return result / 1000.0; 
    #else
    				return ((double)(uint)networkingPeer.ServerTimeInMilliSeconds) / 1000.0;
    #endif
                }
            }
        }
    

    the same added PhotonMessageInfo class
    public double timestamp
        {
    		get 
    		{
    			// VH FIX - negative value on iOS (!!! sad, but true)
    #if UNITY_IPHONE
    			double result = timeInt > 0 ? (double)timeInt : (double)(uint.MaxValue + timeInt);
    			return result / 1000.0;
    #else
    			return ((double)(uint)this.timeInt) / 1000.0;
    #endif
    		}
        }
    
  • Get startTime from Master client through room properties
    DateTime localStartTime;
    IncreasingTimer = PhotonNetwork.time - startTime ;
    if(IncreasingTimer > 0)
    {
    localStartTime = system.DateTime.UtcNow - increasing timer;// updating local start time if timer runs positive
    }
    else
    {
    increasing timer = system.DateTime.UtcNow - localStartTime;
    }

    use increasing timer for updating timer in game.