Skip to content

feat: snapshot. MTT-1088 Snapshot acknowledgment gaps #1083

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 77 commits into from
Aug 24, 2021
Merged
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
94313c7
feat: snapshot. Attempt at applying snapshot spawn branch over new me…
jeffreyrainy Jul 27, 2021
daa7477
feat: snapshot. Reusing spawn entries.
jeffreyrainy Aug 2, 2021
9cb59e4
Merge branch 'develop' into experimental/snapshot-system-spawn3
jeffreyrainy Aug 2, 2021
62e87d5
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 3, 2021
64bb7ec
feat: snapshot fix, prefab handling
jeffreyrainy Aug 3, 2021
847adcd
feat: snapshot. reduce log spam
jeffreyrainy Aug 3, 2021
bc49244
Merge branch 'develop' into experimental/snapshot-system-spawn3
jeffreyrainy Aug 3, 2021
4963d9c
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 3, 2021
10ed439
snapshot: merge preparation. Removing old acks, removing unused varia…
jeffreyrainy Aug 3, 2021
9674acc
feat: snapshot. merge preparation. Removing old acks, removing unused…
jeffreyrainy Aug 3, 2021
bc4805d
Merge branch 'experimental/snapshot-prep2-spawn' of github.com:Unity-…
jeffreyrainy Aug 3, 2021
5c9a703
Merge branch 'develop' into experimental/snapshot-prep2-spawn
0xFA11 Aug 3, 2021
411ef16
Merge branch 'experimental/snapshot-prep2-spawn' into experimental/sn…
jeffreyrainy Aug 3, 2021
8201cd2
Merge branch 'experimental/snapshot-prep2-spawn' into experimental/sn…
jeffreyrainy Aug 3, 2021
7a597b3
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 3, 2021
d2318bc
feat: snapshot. more reasonable sentinel checks around snapshot send/…
jeffreyrainy Aug 4, 2021
9f81229
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 4, 2021
d0b6617
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 4, 2021
43c26f6
feat: snapshot. small clenaup
jeffreyrainy Aug 4, 2021
4e32df9
feat: snapshot. Moving configuration items to NetworkConfig
jeffreyrainy Aug 4, 2021
4222365
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 4, 2021
2bf493d
feat: snapshot. Adjusting to code standard
jeffreyrainy Aug 4, 2021
16d3db1
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 5, 2021
d421c64
refactor: moved code from SpawnInternal into separate SendToSnapshot …
jeffreyrainy Aug 5, 2021
d891f1e
refactor: calling networkShow(NetworkObject) code in networkshow(List…
jeffreyrainy Aug 5, 2021
7c55e4e
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 5, 2021
140a9e7
style: whitespace
jeffreyrainy Aug 5, 2021
775eb83
Merge remote-tracking branch 'origin/experimental/snapshot-prep3-spaw…
jeffreyrainy Aug 5, 2021
8494c4d
refactor: also using NetworkHide(NetworkObject) to implement NetworkH…
jeffreyrainy Aug 5, 2021
767d9eb
Merge remote-tracking branch 'origin/experimental/snapshot-prep3-spaw…
jeffreyrainy Aug 5, 2021
ce3bb6f
feat: snapshot. Safer access to Connection RTT structures
jeffreyrainy Aug 9, 2021
0c7a8b1
feat: snapshot. placeholder comment for code to come later
jeffreyrainy Aug 9, 2021
1cd9af7
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 10, 2021
0c0b298
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 10, 2021
f8df5c7
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 10, 2021
121646f
feat: snapshot. Snapshot fully working for spawn test.
jeffreyrainy Aug 10, 2021
1049f53
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 10, 2021
06284f5
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 11, 2021
1c17469
feat: snapshot. despawn going via snapshot. snapshot message size lim…
jeffreyrainy Aug 13, 2021
2bc5ae1
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 13, 2021
60c1cc0
feat: snapshot. Incrementing the local span and despawn store (amorti…
jeffreyrainy Aug 13, 2021
cb38fd9
feat: snapshot. Using different list to keep track of spawn despawn t…
jeffreyrainy Aug 14, 2021
948f4fa
feat: snapshot. extra logging for debugging
jeffreyrainy Aug 14, 2021
75ba255
fix: snapshot. MTT-1056 despawn loss
jeffreyrainy Aug 16, 2021
564dc26
feat: snapshot. Proper test for length used in snapshot message. Remo…
jeffreyrainy Aug 16, 2021
f79b182
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 17, 2021
3077c38
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 17, 2021
1984155
fix: snapshot. NetworkHide in snapshot mode was incorrectly hiding th…
jeffreyrainy Aug 17, 2021
e659949
feat: snapshot. Keeping snapshot disabled for this release
jeffreyrainy Aug 17, 2021
192bcc3
style: coding standards fix
jeffreyrainy Aug 18, 2021
e79efce
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 18, 2021
f8bddd1
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 18, 2021
d44337d
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 18, 2021
081df43
test: making the networkshow/hide test more resistant to timing diffe…
jeffreyrainy Aug 18, 2021
2c8fbbc
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 18, 2021
2aeff8f
Merge branch 'experimental/snapshot-mtt1092-mtt1056' into experimenta…
jeffreyrainy Aug 18, 2021
7599ac0
test: removing Sleep() code in NetworkShowHide that attempted to deal…
jeffreyrainy Aug 18, 2021
a66108d
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 18, 2021
edadc75
feat: snapshot, computing the mask of past received messages. Not use…
jeffreyrainy Aug 18, 2021
21fca5c
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 19, 2021
1caaca3
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 19, 2021
cf6b615
feat: snapshot. First pass at PR code review
jeffreyrainy Aug 19, 2021
4c48ced
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 19, 2021
5015050
feat: snapshot. Adjusting to int ticks
jeffreyrainy Aug 19, 2021
dc9dfbc
feat: snapshot. Reducing the amount of logging, as this is getting me…
jeffreyrainy Aug 19, 2021
2fa6f59
Merge remote-tracking branch 'origin/experimental/snapshot-mtt1092-mt…
jeffreyrainy Aug 19, 2021
489d592
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 19, 2021
8b42189
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 19, 2021
802703a
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 20, 2021
dd4eb5e
feat: snapshot. MTT-1088. Acknowledgement for multiple messages, not …
jeffreyrainy Aug 23, 2021
051caec
feat: snapshot. Enabling snapshot in this branch, by default
jeffreyrainy Aug 23, 2021
975a52a
Merge remote-tracking branch 'origin/develop' into experimental/snaps…
jeffreyrainy Aug 23, 2021
6d1d2e7
feat: snapshot. Fixing a bad merge from develop
jeffreyrainy Aug 24, 2021
1a8a5cf
feat: snapshot. prep for PR, MTT-1088, plus packet loss for testing
jeffreyrainy Aug 24, 2021
f5768a2
feat: snapshot. prep 2 for PR, MTT-1088
jeffreyrainy Aug 24, 2021
b0d9e5e
feat: snapshot. prep 3 for PR, MTT-1088. disbaling snapshot, and whit…
jeffreyrainy Aug 24, 2021
3c905a8
Merge branch 'develop' into experimental/snapshot-system-mtt-1088
jeffreyrainy Aug 24, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 51 additions & 14 deletions com.unity.netcode.gameobjects/Runtime/Core/SnapshotSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -472,10 +472,30 @@ internal void ReadSpawns(NetworkReader reader)
}
}

internal ushort ReadAcks(ulong clientId, ClientData clientData, NetworkReader reader)
internal void ReadAcks(ulong clientId, ClientData clientData, NetworkReader reader, ConnectionRtt connection)
{
ushort ackSequence = reader.ReadUInt16();
ushort seqMask = reader.ReadUInt16();

// process the latest acknowledgment
ProcessSingleAck(ackSequence, clientId, clientData, connection);

// for each bit in the mask, acknowledge one message before
while (seqMask != 0)
{
ackSequence--;
// extract least bit
if (seqMask % 2 == 1)
{
ProcessSingleAck(ackSequence, clientId, clientData, connection);
}
// move to next bit
seqMask >>= 1;
}
}

internal void ProcessSingleAck(ushort ackSequence, ulong clientId, ClientData clientData, ConnectionRtt connection)
{
// look through the spawns sent
foreach (var sent in clientData.SentSpawns)
{
Expand Down Expand Up @@ -529,7 +549,8 @@ internal ushort ReadAcks(ulong clientId, ClientData clientData, NetworkReader re
}
}

return ackSequence;
// keep track of RTTs, using the sequence number acknowledgement as a marker
connection.NotifyAck(ackSequence, Time.unscaledTime);
}

/// <summary>
Expand Down Expand Up @@ -564,6 +585,7 @@ internal struct SentSpawn // this struct also stores Despawns, not just Spawns

internal ushort SequenceNumber = 0; // the next sequence number to use for this client
internal ushort LastReceivedSequence = 0; // the last sequence number received by this client
internal ushort ReceivedSequenceMask = 0; // bitmask of the messages before the last one that we received.

internal int NextSpawnIndex = 0; // index of the last spawn sent. Used to cycle through spawns (LRU scheme)
internal int NextDespawnIndex = 0; // same as above, but for despawns.
Expand Down Expand Up @@ -686,8 +708,6 @@ private void SendSnapshot(ulong clientId)

m_ConnectionRtts[clientId].NotifySend(m_ClientData[clientId].SequenceNumber, Time.unscaledTime);

// Send the entry index and the buffer where the variables are serialized

var context = m_NetworkManager.MessageQueueContainer.EnterInternalCommandContext(
MessageQueueContainer.MessageType.SnapshotData, NetworkChannel.SnapshotExchange,
new[] { clientId }, NetworkUpdateLoop.UpdateStage);
Expand All @@ -698,20 +718,27 @@ private void SendSnapshot(ulong clientId)
{
var sequence = m_ClientData[clientId].SequenceNumber;

// write the tick and sequence header
nonNullContext.NetworkWriter.WriteInt32Packed(m_CurrentTick);
nonNullContext.NetworkWriter.WriteUInt16(sequence);

var buffer = (NetworkBuffer)nonNullContext.NetworkWriter.GetStream();

using (var writer = PooledNetworkWriter.Get(buffer))
{
// write the snapshot: buffer, index, spawns, despawns
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have to remember to port this over to @ShadauxCat's new scheme

writer.WriteUInt16(SentinelBefore);
WriteBuffer(buffer);
WriteIndex(buffer);
WriteSpawns(buffer, clientId);
WriteAcks(buffer, clientId);
writer.WriteUInt16(SentinelAfter);

m_ClientData[clientId].LastReceivedSequence = 0;

// todo: this is incorrect (well, sub-optimal)
// we should still continue ack'ing past messages, in case this one is dropped
m_ClientData[clientId].ReceivedSequenceMask = 0;
m_ClientData[clientId].SequenceNumber++;
}
}
Expand Down Expand Up @@ -806,7 +833,9 @@ private void WriteAcks(NetworkBuffer buffer, ulong clientId)
{
using (var writer = PooledNetworkWriter.Get(buffer))
{
// todo: revisit whether 16-bit is enough for LastReceivedSequence
writer.WriteUInt16(m_ClientData[clientId].LastReceivedSequence);
writer.WriteUInt16(m_ClientData[clientId].ReceivedSequenceMask);
}
}

Expand Down Expand Up @@ -911,12 +940,6 @@ private void WriteVariableToSnapshot(Snapshot snapshot, INetworkVariable network
/// <param name="snapshotStream">The stream to read from</param>
internal void ReadSnapshot(ulong clientId, Stream snapshotStream)
{
// poor man packet loss simulation
//if (Random.Range(0, 10) > 5)
//{
// return;
//}

// todo: temporary hack around bug
if (!m_NetworkManager.IsServer)
{
Expand All @@ -937,6 +960,23 @@ internal void ReadSnapshot(ulong clientId, Stream snapshotStream)
var sequence = reader.ReadUInt16();

// todo: check we didn't miss any and deal with gaps

if (m_ClientData[clientId].ReceivedSequenceMask != 0)
{
// since each bit in ReceivedSequenceMask is relative to the last received sequence
// we need to shift all the bits by the difference in sequence
m_ClientData[clientId].ReceivedSequenceMask <<=
(sequence - m_ClientData[clientId].LastReceivedSequence);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to to bounds checking on sequence - m_ClientData[clientId].LastReceivedSequence to guard against it being negative or overflowing the 16 bit value?

}

if (m_ClientData[clientId].LastReceivedSequence != 0)
{
// because the bit we're adding for the previous ReceivedSequenceMask
// was implicit, it needs to be shift by one less
m_ClientData[clientId].ReceivedSequenceMask +=
(ushort)(1 << (ushort)((sequence - 1) - m_ClientData[clientId].LastReceivedSequence));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same check here on under / overflow?

}

m_ClientData[clientId].LastReceivedSequence = sequence;

var sentinel = reader.ReadUInt16();
Expand All @@ -948,10 +988,7 @@ internal void ReadSnapshot(ulong clientId, Stream snapshotStream)
m_Snapshot.ReadBuffer(reader, snapshotStream);
m_Snapshot.ReadIndex(reader);
m_Snapshot.ReadSpawns(reader);
var ackSequence = m_Snapshot.ReadAcks(clientId, m_ClientData[clientId], reader);

// keep track of RTTs, using the sequence number acknowledgement as a marker
GetConnectionRtt(clientId).NotifyAck(ackSequence, Time.unscaledTime);
m_Snapshot.ReadAcks(clientId, m_ClientData[clientId], reader, GetConnectionRtt(clientId));

sentinel = reader.ReadUInt16();
if (sentinel != SentinelAfter)
Expand Down