Late joiners drop network data events occuring between Start() and first update
tracked
TapGhoul
- Create a scene with a button, with a counter, using a script similar to the one below.
- Have 2 players in the instance
- Have one rejoin, start sending events. Press the button to increment while other player is in loading screen, after you've seen the STARTevent in the log (as per the script below)
When the player joins, you will see the data (or at least world state) is stale.
This can sometimes break game worlds, if a game starts/ends while on a loading screen.
This is harder to trigger on a simpler world during the loading screen due to how short it is, but larger/heavier worlds this becomes more common.
This affects manual sync scripts with OnDeserialization, I have not tested with Continuous sync.
Note, there may also be a similar issue in the persistence system, which can cause similarly stale data to appear, but this is as of now untested.
using TMPro;
using UdonSharp;
using UnityEngine;
using VRC.Udon.Common;
[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]
public class Script2 : UdonSharpBehaviour
{
public TextMeshPro tmp;
[UdonSynced] public int counter;
void Start() => _Upd("START");
public override void OnDeserialization(DeserializationResult result) => _Upd("DESER");
public override void OnPostSerialization(SerializationResult result) => _Upd("POSTSER");
public override void Interact()
{
counter++;
RequestSerialization();
}
private void _Upd(string msg)
{
tmp.text = $"Value: {counter}";
Debug.Log($"[TEST2] {msg} {counter}");
}
}
Worth a note: this bug has existed since automatic restore of synced data was introduced, if not longer. I just forgot to report it, oops.
Log In
StormRel
tracked
TapGhoul
After further testing, this appears to not be events, it's network data altogether. Trying to poll every frame (the "curr" value) gets the same result as the event-triggered one.
using TMPro;
using UdonSharp;
using UnityEngine;
using VRC.Udon.Common;
[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]
public class Script2 : UdonSharpBehaviour
{
public TextMeshPro tmp;
[UdonSynced] public int counter;
private int _lastSerCount;
void Start() => _Upd("START");
public override void OnDeserialization(DeserializationResult result) => _Upd("DESER");
public override void OnPostSerialization(SerializationResult result) => _Upd("POSTSER");
public override void Interact()
{
counter++;
RequestSerialization();
}
private void _Upd(string msg)
{
_lastSerCount = counter;
Debug.Log($"[TEST2] {msg} {counter}");
}
private void Update()
{
tmp.text = $"Ser: {_lastSerCount}\nCurr: {counter}";
}
}