Repository navigation
Description
Description
TimeSyncMessage is sent reliably, although MessageDelivery says it's meant to stay unreliable. Under packet loss a time sync arrives late. The client takes its old host tick as current, its time offset passes HardResetThresholdSec (0.2 s by default), and NetworkTimeSystem hard-resets the client's clock backwards.
After that, NetworkTransformTickRegistration.TickUpdate skips while CurrentTick <= m_LastTick. Every NetworkTransform the client owns therefore sends nothing until its clock passes the last tick it sent. Teammates see that player freeze for up to about 0.5 s and then jump.
Details (line numbers from 2.13.3; the same code is in develop-3.x.x today):
MessageDelivery.cs: the summary ofk_SkipMessageTypessays "Skip the time sync messages since it has always used unreliable network delivery". But the set holds onlyNamedMessageandUnnamed. SoUpdateMessageTypesgivesTimeSyncMessageReliableFragmentedSequenced, andNetworkTimeSystemsends it withMessageDeliveryType<TimeSyncMessage>.DefaultDelivery.NetworkTimeSystem: a sync whose send tick is old by the time it arrives produces a desired offset more than 0.2 s from the current one, so the clock is hard-reset to it, back in time.NetworkTransform.cs:4765(NetworkTransformTickRegistration.TickUpdate):if (CurrentTick <= m_LastTick)with the comment// TODO FIX: The local NetworkTickSystem can invoke with the same network tick as before. After a backward reset, this skips every tick until the clock catches up.
Reproduce Steps
- Host + 1 client (client-server), with the simulated poor connection on the host: about 75 ms delay, ±20 ms jitter and 2% packet loss.
- On the client, log
NetworkManager.ServerTime.Tickevery frame for a few minutes. - Give the client an owner-authoritative
NetworkTransformthat moves continuously, and log on the host when its state updates arrive.
Actual Outcome
About twice a minute the client's ServerTime.Tick steps backwards (one example: 568 → 548). The client's NetworkTransform sends nothing until its tick passes 568 again, so the host sees it stand still for up to about 0.5 s and then jump.
Expected Outcome
A delayed time sync doesn't move a client's clock backwards, and its transforms keep sending. Possible fixes:
- send
TimeSyncMessageunreliably (add it tok_SkipMessageTypes, as the comment intends), so a lost one is replaced by the next a second later instead of arriving late; - or ignore a time sync older than the last one applied;
- and/or let
NetworkTransformTickRegistrationrecover from a backward tick (resetm_LastTick) instead of skipping until the clock catches up.
Screenshots
None. The numbers come from per-frame logs.
Environment
- OS: Windows 11 Pro
- Unity Version: 6000.3.27f1
- Netcode Version: 2.13.3 (also present in
develop-3.x.xand 3.2.0) - Netcode Commit: the v2.13.3 release
- Netcode Topology: Client-Server (host)
Additional Context
- Unity Transport 2.7.4.
- Our workaround: each client raises
NetworkTimeSystem.HardResetThresholdSecto 1 s when it starts. With that, the backward resets went from about two a minute to none in three minutes under the same conditions.
Activity