Facepunch / sbox-issues

175 stars 12 forks source link

TimeUntil and TimeSince are not fully synchronized in multiplayer #5065

Closed Weldify closed 6 months ago

Weldify commented 6 months ago

Describe the bug

I have a [HostSync] TimeUntil timeUntil property. It always seems to be off by some amount for connections that aren't the host. This is especially noticeable when you have a crappy connection, in my case I saw it reach upwards of 2 seconds of desync.

It looks like only the host can see it.

To Reproduce

  1. Have a [HostSync] TimeUntil timeUntil property
  2. Set it on the host and display it in some way (ui counter for example)
  3. Have someone else join your game - the timing will be off

Expected behavior

Time should be synced as closely as possible

Media/Files

No response

Additional context

No response

kurozael commented 6 months ago

Have you tried using RealTimeUntil, does it make a difference at all?

Weldify commented 6 months ago

No, but I will test when I get the chance

MrBrax commented 6 months ago

Time.Now might be desynced too, I'm gonna do more testing myself, but having a single reliable multiplayer time sync is crucial.

kurozael commented 6 months ago

I suggest using RealTimeUntil for a more accurate synchronization between networked clients. Time.Now tries to synchronize but it will never be 100% accurate because of latency. Where as RealTime.GlobalNow is synchronized by epoch.

MrBrax commented 6 months ago

i get big php function retcon vibes from that naming, is there any point of using just regular timeuntil then?

garrynewman commented 6 months ago

FYI RealTime isn't synced between clients at all.

Realtime is the amount of seconds since sbox.exe was launched.

I would expect TimeUntil to be kind of off by one ping time, maybe a whole round trip time. Anything more than that is a bug.

kurozael commented 6 months ago

I was referring to RealTime.GlobalNow:

    /// <summary>
    /// The number of a seconds since a set point in time. This value should match between servers and clients. If they have their timezone set correctly.
    /// </summary>
    public static double GlobalNow => (nowOffset + timeMeasure.Elapsed.TotalSeconds);

Which is what RealTimeUntil uses. But maybe it isn't as accurate as I thought, if it relies on the timezone being set correctly.

Weldify commented 6 months ago

RealTimeUntil is also not really suitable for gameplay because it doesn't respect timescale.

Why not just have Time try to keep up with the host, slow down a bit if we're ahead and speed up a bit if we are behind?

garrynewman commented 6 months ago

It does

MrBrax commented 6 months ago

There's something wrong with TimeUntil then, since players that were able to join my lobby once couldn't ride the platforms up because they depend on the current time. But I'll have to continue testing and see which one works best.