Improved initial sync

This commit is contained in:
2026-06-24 11:38:43 +02:00
parent 3be8d2f6a6
commit ad605bcab3
5 changed files with 1309 additions and 1238 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+55 -39
View File
@@ -53,15 +53,19 @@ namespace Marro.PacManUdon
/// <summary>
/// The delay in ticks at which the receiving side replays events.
/// </summary>
[SerializeField] private int delay = 50;
[SerializeField] private int delay = 1;
/// <summary>
/// The maximum amount of times a message is sent.
/// </summary>
[SerializeField] private int maxEventSendTries = 3;
/// <summary>
/// How long to wait since last message to send next ping.
/// How long to wait since last message to send next message.
/// </summary>
[SerializeField] private int pingDelay = 15;
[SerializeField] private int sendingPingDelay = 15;
/// <summary>
/// How long to wait since last attempt to request sync.
/// </summary>
[SerializeField] private int syncingPingDelay = 300;
/// <summary>
/// The time delta at which updates occur.
/// </summary>
@@ -200,7 +204,7 @@ namespace Marro.PacManUdon
/// </summary>
private int eventTransmissionHistoryIndex;
/// <summary>
/// Time of last event transmission, in ticks.
/// Time of last event transmission sent, requested or received, in ticks.
/// </summary>
private int lastEventTransmissionTime;
@@ -210,7 +214,6 @@ namespace Marro.PacManUdon
/// </summary>
private byte lastEventId;
/// <summary>
/// Data which is currently available on the network.
/// </summary>
@@ -295,7 +298,7 @@ namespace Marro.PacManUdon
#region General
/// <summary>
/// Initializes the <see cref="NetworkManager"/>. Call <see cref="Reset"/> afterwards to activate networking.
/// Initializes the <see cref="NetworkManager"/>.
/// </summary>
public void Initialize()
{
@@ -361,7 +364,6 @@ namespace Marro.PacManUdon
Synced = IsOwner; // Owner is always synced
retriesWithoutSuccess = 0;
hasFullSyncReady = false;
targetTicks = 0;
startTime = Time.fixedTime;
@@ -371,11 +373,7 @@ namespace Marro.PacManUdon
Ready = true;
// Sync up
if (IsOwner)
{
SendEventSoon(NetworkEventType.FullSyncForced);
}
else
if (!IsOwner)
{
RequestEvent(NetworkEventType.FullSync);
}
@@ -409,15 +407,19 @@ namespace Marro.PacManUdon
{
if (Ready)
{
if (IsOwner)
if (isOwner)
{
ProcessEventsToSend(); // Prepare events from last cycle
ProgressPingTime(); // See if we need to send a ping
ProgressSendingPingTime(); // See if we need to send a ping
}
if (!isOwner)
else if (Synced || hasFullSyncReady)
{
ApplyReceivedEvents(); // See if there's events after last update that need to be replayed
}
else
{
ProgressSyncingPingTime(); // See if we should request syncing
}
}
ProgressSyncedTime();
@@ -532,6 +534,11 @@ namespace Marro.PacManUdon
eventsToSendLate[eventsToSendLateIndex++] = eventType;
}
if (IsFullSync(eventType))
{
hasFullSyncReady = true;
}
}
private void ProcessEventsToSend()
@@ -591,11 +598,6 @@ namespace Marro.PacManUdon
var eventSizeBytes = BitConverter.GetBytes((ushort)index);
Array.Copy(eventSizeBytes, 0, data, HeaderEventSizeIndex, eventSizeBytes.Length);
if (IsFullSync(eventType))
{
hasFullSyncReady = true;
}
data = GetArrayPart(data, 0, index);
QueueEventInBuffer(data);
@@ -641,27 +643,35 @@ namespace Marro.PacManUdon
if (IsFullSync(eventType) && hasFullSyncReady)
{
//Debug.Log($"Rejected event request because already have full sync ready");
return; // Don't send another full sync if we're already preparing to send one
}
if (eventType == NetworkEventType.FullSyncForced)
{
SendEventSoon(NetworkEventType.FullSync); // Remote is not allowed to request a forced full sync
return;
eventType = NetworkEventType.FullSync; // Remote is not allowed to request a forced full sync
}
SendEventSoon(eventType);
}
private void ProgressPingTime()
private void ProgressSendingPingTime()
{
if (eventsQueueIndex > 0 && !serializationRequested
&& targetTicks - lastEventTransmissionTime >= pingDelay)
&& targetTicks - lastEventTransmissionTime >= sendingPingDelay)
{
RequestSerializationForEvents();
}
}
private void ProgressSyncingPingTime()
{
if (targetTicks - lastEventTransmissionTime >= syncingPingDelay)
{
RequestEvent(NetworkEventType.FullSync);
}
}
public override void OnPreSerialization()
{
if (!Ready || !IsOwner || !serializationRequested || eventsQueue == null || eventsQueueIndex == 0)
@@ -688,6 +698,9 @@ namespace Marro.PacManUdon
// Version of OnPostSerialization which does not require instantiating SerializationResult, so that it can be called for debugging purposes.
public void OnPostSerializationInternal(bool success, int byteCount)
{
// If there was a full sync in the queue, it should now have been transmitted at least once
hasFullSyncReady = false;
if (!Ready || !IsOwner || networkedData.Length == 0)
{
return;
@@ -708,9 +721,6 @@ namespace Marro.PacManUdon
networkedData = new byte[0];
// If there was a full sync in the queue, it has now been transmitted at least once
hasFullSyncReady = false;
lastEventTransmissionTime = targetTicks;
}
#endregion
@@ -730,6 +740,7 @@ namespace Marro.PacManUdon
}
SendCustomNetworkEvent(VRC.Udon.Common.Interfaces.NetworkEventTarget.Owner, "RequestEventReceived", eventType);
lastEventTransmissionTime = SyncedTimeTicks;
if (tester != null)
{
@@ -798,25 +809,29 @@ namespace Marro.PacManUdon
continue;
}
QueueEventInBuffer(@event);
if (!QueueEventInBuffer(@event))
{
return;
}
if (eventsQueueIndex == 1) // If this is the next upcoming event, update the next event time
{
UpdateNextEventTime();
}
//Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)} Queued event with id {eventId}");
}
else if (IsFullSync(eventType)) // If we're not yet synced, we only care about full sync events.
{
QueueFullSyncForReplay(@event); // Immediately process full sync
}
else
{
// If we're not yet synced, we only care about full sync events.
if (IsFullSync(eventType))
{
QueueFullSyncForReplay(@event); // Immediately process full sync
}
return;
}
lastEventId = eventId;
}
if (Synced)
{
UpdateNextEventTime();
lastEventTransmissionTime = SyncedTimeTicks;
}
}
@@ -1211,6 +1226,7 @@ namespace Marro.PacManUdon
[SerializeField] private Animator DebugImageToIndicateReady;
private NetworkManagerTester tester;
public void SetNetworkManagerTester(NetworkManagerTester tester)
{
this.tester = tester;
@@ -1228,7 +1244,7 @@ namespace Marro.PacManUdon
public void DoFullSync()
{
SendEventSoon(NetworkEventType.FullSyncForced);
SendEventSoon(NetworkEventType.FullSyncForced);
}
public void Pause()