Skip to content

Commit 5537326

Browse files
authored
fix(NetworkIdentity): Check unreliableBaseline when sending baseline (#4095)
1 parent cb50246 commit 5537326

File tree

2 files changed

+19
-19
lines changed

2 files changed

+19
-19
lines changed

Assets/Mirror/Core/NetworkIdentity.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1188,8 +1188,13 @@ internal void SerializeServer_Broadcast(
11881188
if (ownerMaskUnreliableDelta != 0) Compression.CompressVarUInt(ownerWriterUnreliableDelta, ownerMaskUnreliableDelta);
11891189
if (observerMaskUnreliableDelta != 0) Compression.CompressVarUInt(observersWriterUnreliableDelta, observerMaskUnreliableDelta);
11901190

1191-
if (ownerMaskUnreliableBaseline != 0) Compression.CompressVarUInt(ownerWriterUnreliableBaseline, ownerMaskUnreliableBaseline);
1192-
if (observerMaskUnreliableBaseline != 0) Compression.CompressVarUInt(observersWriterUnreliableBaseline, observerMaskUnreliableBaseline);
1191+
// only write baseline mask when actually sending a baseline.
1192+
// otherwise an orphaned 1-2 byte mask is written with no data following it.
1193+
if (unreliableBaseline)
1194+
{
1195+
if (ownerMaskUnreliableBaseline != 0) Compression.CompressVarUInt(ownerWriterUnreliableBaseline, ownerMaskUnreliableBaseline);
1196+
if (observerMaskUnreliableBaseline != 0) Compression.CompressVarUInt(observersWriterUnreliableBaseline, observerMaskUnreliableBaseline);
1197+
}
11931198

11941199
// serialize all components
11951200
// perf: only iterate if either dirty mask has dirty bits.
@@ -1355,7 +1360,6 @@ internal void SerializeClient(NetworkWriter writerReliable, NetworkWriter writer
13551360
comp.Serialize(writerUnreliableBaseline, true);
13561361

13571362
// for unreliable components, only clear dirty bits after the reliable baseline.
1358-
// unreliable deltas aren't guaranteed to be delivered, no point in clearing bits.
13591363
// -> don't clear sync time: that's for delta syncs.
13601364
comp.ClearAllDirtyBits(false);
13611365
}
@@ -1640,7 +1644,7 @@ public void RemoveClientAuthority()
16401644
// Marks the identity for future reset, this is because we cant reset
16411645
// the identity during destroy as people might want to be able to read
16421646
// the members inside OnDestroy(), and we have no way of invoking reset
1643-
// after OnDestroy is called.
1647+
// after OnDestroy() is called.
16441648
internal void ResetState()
16451649
{
16461650
hasSpawned = false;

Assets/Mirror/Tests/Editor/NetworkIdentity/NetworkIdentitySerializationTests.cs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,7 @@ public void SerializeServer_Broadcast_NotDirty_WritesNothing()
479479
Assert.That(ownerWriterReliable.Position, Is.EqualTo(0));
480480
Assert.That(observersWriterReliable.Position, Is.EqualTo(0));
481481

482+
// unreliableBaseline=false: no baseline mask or data should be written
482483
Assert.That(ownerWriterUnreliableBaseline.Position, Is.EqualTo(0));
483484
Assert.That(observersWriterUnreliableBaseline.Position, Is.EqualTo(0));
484485

@@ -639,19 +640,16 @@ public void SerializeServer_ObserversMode_ServerToClient_UnreliableOnly()
639640
Assert.That(ownerWriterReliable.Position, Is.EqualTo(0));
640641
Assert.That(observersWriterReliable.Position, Is.EqualTo(0));
641642

642-
Assert.That(ownerWriterUnreliableBaseline.Position, Is.GreaterThan(0));
643-
Assert.That(observersWriterUnreliableBaseline.Position, Is.GreaterThan(0));
643+
// unreliableBaseline=false: no baseline mask or data should be written
644+
Assert.That(ownerWriterUnreliableBaseline.Position, Is.EqualTo(0));
645+
Assert.That(observersWriterUnreliableBaseline.Position, Is.EqualTo(0));
644646

645647
Assert.That(ownerWriterUnreliableDelta.Position, Is.GreaterThan(0));
646648
Assert.That(observersWriterUnreliableDelta.Position, Is.GreaterThan(0));
647649
}
648650

649651
[Test]
650-
[Ignore("BUG: NetworkIdentity.SerializeServer_Broadcast() writes baseline dirty mask even when unreliableBaseline=false. " +
651-
"This wastes 1-2 bytes per object per frame. " +
652-
"Fix: Wrap baseline mask writes in 'if (unreliableBaseline) { ... }' block. " +
653-
"See lines ~1150-1153 in NetworkIdentity.cs")]
654-
public void UnreliableBaseline_Timing_REVEALS_BUG()
652+
public void UnreliableBaseline_Timing()
655653
{
656654
CreateNetworkedAndSpawn(
657655
out _, out NetworkIdentity serverIdentity, out SerializeTest1NetworkBehaviour serverComp,
@@ -691,11 +689,9 @@ public void UnreliableBaseline_Timing_REVEALS_BUG()
691689
// Delta should be written
692690
Assert.That(deltaSize, Is.GreaterThan(0), "Delta should be written");
693691

694-
// BUG REVEALED: This should be 0 but is actually 1
695-
// The baseline mask byte is written even though no data follows
692+
// unreliableBaseline=false: only delta is sent, baseline writers stay empty
696693
Assert.That(deltaOnlyBaselineSize, Is.EqualTo(0),
697-
"EXPECTED: No baseline data when unreliableBaseline=false. " +
698-
"ACTUAL: Writes 1-byte dirty mask, wasting bandwidth.");
694+
"No baseline data when unreliableBaseline=false");
699695

700696
// === SCENARIO 3: Serialize with unreliableBaseline=true ===
701697
serverComp.value = 200;
@@ -950,10 +946,10 @@ public void SerializeServer_SyncModeAndDirection_Matrix(
950946
$"[Broadcast/Hybrid] Reliable must be empty. SyncMode={syncMode}, SyncDirection={syncDirection}");
951947

952948
// unreliableBaseline=false: no baseline mask or data should be written
953-
Assert.That(ownerWriterUnreliableBaseline.Position, NonZeroIf(expectOwner),
954-
$"[Broadcast/Hybrid] Unreliable baseline mask written (BUG). SyncMode={syncMode}, SyncDirection={syncDirection}");
955-
Assert.That(observersWriterUnreliableBaseline.Position, NonZeroIf(expectObservers),
956-
$"[Broadcast/Hybrid] Unreliable baseline mask written (BUG). SyncMode={syncMode}, SyncDirection={syncDirection}");
949+
Assert.That(ownerWriterUnreliableBaseline.Position, Is.EqualTo(0),
950+
$"[Broadcast/Hybrid] Unreliable baseline must be empty. SyncMode={syncMode}, SyncDirection={syncDirection}");
951+
Assert.That(observersWriterUnreliableBaseline.Position, Is.EqualTo(0),
952+
$"[Broadcast/Hybrid] Unreliable baseline must be empty. SyncMode={syncMode}, SyncDirection={syncDirection}");
957953
}
958954
}
959955

0 commit comments

Comments
 (0)