Skip to content

feat: snapshot. Fully integrated despawn, mtt-1092, mtt-1056 #1062

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 58 commits into from
Aug 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 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
f8bddd1
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
7599ac0
test: removing Sleep() code in NetworkShowHide that attempted to deal…
jeffreyrainy Aug 18, 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
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
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ public class NetworkConfig

// todo: transitional. For the next release, only Snapshot should remain
// The booleans allow iterative development and testing in the meantime
public bool UseSnapshotDelta = false;
public bool UseSnapshotSpawn = false;
public bool UseSnapshotDelta { get; } = false;
public bool UseSnapshotSpawn { get; } = false;

public const int RttAverageSamples = 5; // number of RTT to keep an average of (plus one)
public const int RttWindowSize = 64; // number of slots to use for RTT computations (max number of in-flight packets)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ private void Initialize(bool server)
SnapshotSystem = null;
}

SnapshotSystem = new SnapshotSystem();
SnapshotSystem = new SnapshotSystem(this);

if (server)
{
Expand Down
129 changes: 92 additions & 37 deletions com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,11 @@ public void NetworkShow(ulong clientId)
throw new VisibilityChangeException("The object is already visible");
}

if (NetworkManager.NetworkConfig.UseSnapshotSpawn)
Copy link
Contributor

Choose a reason for hiding this comment

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

Interesting, when I look at this code I'm expecting to see an 'else' where the old way of spawning happens. So SnapshotSpawn doesn't include a call to SendSpawnCallForObject? Could it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've put in Slack a link to the lucidchart diagram about this "[Thursday PR]". NetworkObject.Show calls directly into Snapshot. It then calls into SendSpawnCallForObject in SpawnManager. The old way, in SpawnManager is then disabled, there. That's where the missing else is

That design came around because the other flow, SpawnInternal, can be put in Snapshot at once (one command for all connections). If I had put the Snapshot hook in SendSpawnCallForObject then SnapshotSystem would get the same spawn multiple times. Similarly if I had refactored the old ways to be done for all connections at once, I would have touched code I didn't need to and risk breaking things.

{
SnapshotSpawn(clientId);
}

Observers.Add(clientId);

NetworkManager.SpawnManager.SendSpawnCallForObject(clientId, OwnerClientId, this);
Expand Down Expand Up @@ -310,23 +315,30 @@ public void NetworkHide(ulong clientId)
}


// Send destroy call
Observers.Remove(clientId);

var context = NetworkManager.MessageQueueContainer.EnterInternalCommandContext(
MessageQueueContainer.MessageType.DestroyObject, NetworkChannel.Internal,
new[] { clientId }, NetworkUpdateStage.PostLateUpdate);
if (context != null)
if (NetworkManager.NetworkConfig.UseSnapshotSpawn)
{
using (var nonNullContext = (InternalCommandContext)context)
SnapshotDespawn(clientId);
}
else
{
// Send destroy call
var context = NetworkManager.MessageQueueContainer.EnterInternalCommandContext(
MessageQueueContainer.MessageType.DestroyObject, NetworkChannel.Internal,
new[] { clientId }, NetworkUpdateStage.PostLateUpdate);
if (context != null)
{
var bufferSizeCapture = new CommandContextSizeCapture(nonNullContext);
bufferSizeCapture.StartMeasureSegment();
using (var nonNullContext = (InternalCommandContext)context)
{
var bufferSizeCapture = new CommandContextSizeCapture(nonNullContext);
bufferSizeCapture.StartMeasureSegment();

nonNullContext.NetworkWriter.WriteUInt64Packed(NetworkObjectId);
nonNullContext.NetworkWriter.WriteUInt64Packed(NetworkObjectId);

var size = bufferSizeCapture.StopMeasureSegment();
NetworkManager.NetworkMetrics.TrackObjectDestroySent(clientId, NetworkObjectId, name, size);
var size = bufferSizeCapture.StopMeasureSegment();
NetworkManager.NetworkMetrics.TrackObjectDestroySent(clientId, NetworkObjectId, name, size);
}
}
}
}
Expand Down Expand Up @@ -405,6 +417,74 @@ private void OnDestroy()
}
}

private SnapshotDespawnCommand GetDespawnCommand()
{
SnapshotDespawnCommand command;
command.NetworkObjectId = NetworkObjectId;
command.TickWritten = default; // value will be set internally by SnapshotSystem
command.TargetClientIds = default;

return command;
}

private SnapshotSpawnCommand GetSpawnCommand()
{
SnapshotSpawnCommand command;
command.NetworkObjectId = NetworkObjectId;
command.OwnerClientId = OwnerClientId;
command.IsPlayerObject = IsPlayerObject;
command.IsSceneObject = (IsSceneObject == null) || IsSceneObject.Value;

ulong? parent = NetworkManager.SpawnManager.GetSpawnParentId(this);
if (parent != null)
{
command.ParentNetworkId = parent.Value;
}
else
{
// write own network id, when no parents. todo: optimize this.
command.ParentNetworkId = command.NetworkObjectId;
}

command.GlobalObjectIdHash = HostCheckForGlobalObjectIdHashOverride();
// todo: check if (IncludeTransformWhenSpawning == null || IncludeTransformWhenSpawning(clientId)) for any clientId
command.ObjectPosition = transform.position;
command.ObjectRotation = transform.rotation;
command.ObjectScale = transform.localScale;
command.TickWritten = default; // value will be set internally by SnapshotSystem
command.TargetClientIds = default;

return command;
}

private void SnapshotSpawn()
{
var command = GetSpawnCommand();
NetworkManager.SnapshotSystem.Spawn(command);
}

private void SnapshotSpawn(ulong clientId)
{
var command = GetSpawnCommand();
command.TargetClientIds = new List<ulong>();
command.TargetClientIds.Add(clientId);
NetworkManager.SnapshotSystem.Spawn(command);
}

internal void SnapshotDespawn()
{
var command = GetDespawnCommand();
NetworkManager.SnapshotSystem.Despawn(command);
}

internal void SnapshotDespawn(ulong clientId)
{
var command = GetDespawnCommand();
command.TargetClientIds = new List<ulong>();
command.TargetClientIds.Add(clientId);
NetworkManager.SnapshotSystem.Despawn(command);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void SpawnInternal(bool destroyWithScene, ulong? ownerClientId, bool playerObject)
{
Expand All @@ -422,32 +502,7 @@ private void SpawnInternal(bool destroyWithScene, ulong? ownerClientId, bool pla

if (NetworkManager.NetworkConfig.UseSnapshotSpawn)
{
SnapshotSpawnCommand command;
command.NetworkObjectId = NetworkObjectId;
command.OwnerClientId = OwnerClientId;
command.IsPlayerObject = IsPlayerObject;
command.IsSceneObject = (IsSceneObject == null) || IsSceneObject.Value;

ulong? parent = NetworkManager.SpawnManager.GetSpawnParentId(this);
if (parent != null)
{
command.ParentNetworkId = parent.Value;
}
else
{
// write own network id, when no parents. todo: optimize this.
command.ParentNetworkId = command.NetworkObjectId;
}

command.GlobalObjectIdHash = HostCheckForGlobalObjectIdHashOverride();
// todo: check if (IncludeTransformWhenSpawning == null || IncludeTransformWhenSpawning(clientId)) for any clientId
command.ObjectPosition = transform.position;
command.ObjectRotation = transform.rotation;
command.ObjectScale = transform.localScale;
command.TickWritten = 0; // will be reset in Spawn
command.TargetClientIds = default;

NetworkManager.SnapshotSystem.Spawn(command);
SnapshotSpawn();
}

ulong ownerId = ownerClientId != null ? ownerClientId.Value : NetworkManager.ServerClientId;
Expand Down
Loading