gg.easy.airship 0.1.2150 → 0.1.2151
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -71,6 +71,7 @@ namespace Code.Network.StateSystem
|
|
|
71
71
|
|
|
72
72
|
// How many commands we should generally have in the command buffer
|
|
73
73
|
private int serverCommandBufferTargetSize = 0;
|
|
74
|
+
private int serverCommandCatchUpRequired = 0;
|
|
74
75
|
|
|
75
76
|
// Non-auth server command tracking
|
|
76
77
|
// Note: we also re-use some of the above command buffer fields
|
|
@@ -331,6 +332,20 @@ namespace Code.Network.StateSystem
|
|
|
331
332
|
{
|
|
332
333
|
this.Interpolate();
|
|
333
334
|
}
|
|
335
|
+
|
|
336
|
+
// We check this in Update so that we have finished processing all required fixedUpdates before checking
|
|
337
|
+
// if we are behind. Next time fixed update runs, we will process the additional amount we need to catch up.
|
|
338
|
+
if (isServer && serverAuth) {
|
|
339
|
+
if (serverCommandBuffer.Count > serverCommandBufferTargetSize) {
|
|
340
|
+
serverCommandCatchUpRequired = serverCommandBuffer.Count - serverCommandBufferTargetSize;
|
|
341
|
+
print($"Command catchup required for {this.name}: {serverCommandCatchUpRequired}");
|
|
342
|
+
}
|
|
343
|
+
else {
|
|
344
|
+
serverCommandCatchUpRequired = 0;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// todo: we probably need to do the same as above for client auth snapshots
|
|
334
349
|
}
|
|
335
350
|
|
|
336
351
|
#endregion
|
|
@@ -551,25 +566,21 @@ namespace Code.Network.StateSystem
|
|
|
551
566
|
}
|
|
552
567
|
|
|
553
568
|
// Delay processing until we have at least one send interval worth of commands to process.
|
|
554
|
-
if (this.serverCommandBuffer.Count == 0 ||
|
|
555
|
-
this.
|
|
556
|
-
(int)Math.Ceiling(NetworkClient.sendInterval / Time.fixedUnscaledDeltaTime)) {
|
|
557
|
-
// Debug.Log($"Waiting for additional commands for {this.name}. There are {this.serverCommandBuffer.Count} commands in the buffer.");
|
|
569
|
+
if (this.serverCommandBuffer.Count == 0 || this.serverCommandBuffer.Count < Math.Ceiling(NetworkClient.sendInterval / Time.fixedUnscaledDeltaTime)) {
|
|
570
|
+
Debug.Log($"Waiting for additional commands for {this.name}. There are {this.serverCommandBuffer.Count} commands in the buffer.");
|
|
558
571
|
this.stateSystem.Tick(null, tick, time, false);
|
|
559
572
|
return;
|
|
560
573
|
}
|
|
561
574
|
|
|
562
575
|
var commandsProcessed = 0;
|
|
563
|
-
do
|
|
564
|
-
{
|
|
576
|
+
do {
|
|
565
577
|
commandsProcessed++;
|
|
566
578
|
|
|
567
579
|
// Attempt to get a new command out of the buffer.
|
|
568
580
|
var commandEntry = this.serverCommandBuffer.Count > 0 ? this.serverCommandBuffer.Values[0] : null;
|
|
569
581
|
|
|
570
582
|
// If we have a new command to process
|
|
571
|
-
if (commandEntry != null)
|
|
572
|
-
{
|
|
583
|
+
if (commandEntry != null) {
|
|
573
584
|
// Get the command to process
|
|
574
585
|
var command = this.serverCommandBuffer.Values[0];
|
|
575
586
|
// Get the expected next command number
|
|
@@ -582,10 +593,10 @@ namespace Code.Network.StateSystem
|
|
|
582
593
|
if (this.lastProcessedCommand != null && command.commandNumber != expectedNextCommandNumber &&
|
|
583
594
|
this.serverPredictedCommandCount < Math.Ceiling(this.maxServerCommandPrediction *
|
|
584
595
|
(NetworkServer.sendInterval /
|
|
585
|
-
Time.fixedUnscaledDeltaTime)))
|
|
586
|
-
{
|
|
596
|
+
Time.fixedUnscaledDeltaTime))) {
|
|
587
597
|
Debug.LogWarning("Missing command " + expectedNextCommandNumber +
|
|
588
|
-
" in the command buffer for " + this.name + ". Next command was: " +
|
|
598
|
+
" in the command buffer for " + this.name + ". Next command was: " +
|
|
599
|
+
command.commandNumber +
|
|
589
600
|
". Predicted " +
|
|
590
601
|
(this.serverPredictedCommandCount + 1) + " command(s) so far.");
|
|
591
602
|
this.serverLastProcessedCommandNumber = expectedNextCommandNumber;
|
|
@@ -595,8 +606,7 @@ namespace Code.Network.StateSystem
|
|
|
595
606
|
}
|
|
596
607
|
// We have a valid command that is in sequence, or we reached our max fill. Remove the next
|
|
597
608
|
// valid command from the buffer and process it.
|
|
598
|
-
else
|
|
599
|
-
{
|
|
609
|
+
else {
|
|
600
610
|
// Debug.Log("Ticking next command in sequence: " + command.commandNumber);
|
|
601
611
|
this.serverPredictedCommandCount = 0;
|
|
602
612
|
this.serverCommandBuffer.RemoveAt(0);
|
|
@@ -608,20 +618,23 @@ namespace Code.Network.StateSystem
|
|
|
608
618
|
command.tick = tick; // Correct tick to local timeline for ticking on the server.
|
|
609
619
|
this.stateSystem.Tick(command, tick, time, false);
|
|
610
620
|
}
|
|
611
|
-
else
|
|
612
|
-
{
|
|
621
|
+
else {
|
|
613
622
|
// Ensure that we always tick the system even if there's no command to process.
|
|
614
|
-
Debug.LogWarning($"No commands left for {this.name}. Last command processed: " +
|
|
623
|
+
Debug.LogWarning($"No commands left for {this.name}. Last command processed: " +
|
|
624
|
+
this.lastProcessedCommand);
|
|
615
625
|
this.stateSystem.Tick(null, tick, time, false);
|
|
616
626
|
// we processed a command that never reached the server, advance so the associated
|
|
617
627
|
// command's tick result will be used to match up with state. The command that should have been used
|
|
618
628
|
// here will be ignored when it arrives (if it ever does)
|
|
619
|
-
this.serverLastProcessedCommandNumber += 1;
|
|
629
|
+
this.serverLastProcessedCommandNumber += 1;
|
|
620
630
|
}
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
631
|
+
|
|
632
|
+
if (commandsProcessed > 1) {
|
|
633
|
+
serverCommandCatchUpRequired--;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
} while (commandsProcessed < 1 + this.maxServerCommandCatchup && serverCommandCatchUpRequired > 0);
|
|
637
|
+
// We add 1 to maxServerCommandCatchup because we always want to process at least 1 command per fixed update.
|
|
625
638
|
|
|
626
639
|
if (commandsProcessed > 1)
|
|
627
640
|
{
|
|
@@ -14,7 +14,7 @@ namespace Code.Network.StateSystem.Structures
|
|
|
14
14
|
/**
|
|
15
15
|
* The unscaled time the snapshot was created. This time is local to the client/server that created it. In server
|
|
16
16
|
* authoritative mode, this time is what is used to render observed characters. This should _not_ be converted
|
|
17
|
-
* to ticks! Ticks use scaled time and will not always map 1 to 1 with a
|
|
17
|
+
* to ticks! Ticks use scaled time and will not always map 1 to 1 with a unscaled time value.
|
|
18
18
|
*/
|
|
19
19
|
public double time;
|
|
20
20
|
public uint tick;
|
package/Runtime/Code/Player/Character/MovementSystems/Character/Structures/CharacterSnapshotData.cs
CHANGED
|
@@ -60,8 +60,8 @@ namespace Code.Player.Character.MovementSystems.Character
|
|
|
60
60
|
var lastProcessedCommandEqual = this.lastProcessedCommand == other.lastProcessedCommand;
|
|
61
61
|
var positionEqual = (this.position - other.position).sqrMagnitude < vectorTolerance;
|
|
62
62
|
var velocityEqual = (this.velocity - other.velocity).sqrMagnitude < vectorTolerance;
|
|
63
|
-
var currentSpeedEqual =
|
|
64
|
-
var speedModifierEqual = NetworkSerializationUtil.
|
|
63
|
+
var currentSpeedEqual = Math.Round(this.currentSpeed, 2) == Math.Round(other.currentSpeed, 2);
|
|
64
|
+
var speedModifierEqual = NetworkSerializationUtil.CompressToUshort(this.speedModifier) == NetworkSerializationUtil.CompressToUshort(other.speedModifier);
|
|
65
65
|
var inputDisabledEqual = inputDisabled == other.inputDisabled;
|
|
66
66
|
var isFlyingEqual = isFlying == other.isFlying;
|
|
67
67
|
var isSprintingEqual = isSprinting == other.isSprinting;
|
|
@@ -252,7 +252,7 @@ namespace Code.Player.Character.MovementSystems.Character
|
|
|
252
252
|
if (canJumpChanged) BitUtil.SetBit(ref changedMask, 8, true);
|
|
253
253
|
|
|
254
254
|
// Write only changed fields
|
|
255
|
-
var writer =
|
|
255
|
+
var writer = NetworkWriterPool.Get();
|
|
256
256
|
writer.Write(NetworkSerializationUtil.CompressToUshort(other.time - time));
|
|
257
257
|
writer.Write((ushort)(other.tick - tick)); // We should send diffs far before 65,535 ticks have passed. 255 is a little too low if messing with time scale (ticks will skip in slow timescales)
|
|
258
258
|
writer.Write((ushort)(other.lastProcessedCommand - lastProcessedCommand)); // same with commands (~1 processed per tick)
|
|
@@ -279,10 +279,13 @@ namespace Code.Player.Character.MovementSystems.Character
|
|
|
279
279
|
writer.WriteBytes(customDataDiff, 0, customDataDiff.Length);
|
|
280
280
|
}
|
|
281
281
|
|
|
282
|
+
var dataArray = writer.ToArray();
|
|
283
|
+
NetworkWriterPool.Return(writer);
|
|
284
|
+
|
|
282
285
|
return new CharacterStateDiff {
|
|
283
286
|
baseTick = tick, // The base is the instance CreateDiff is being called on, so use our instance time value as the base time.
|
|
284
287
|
crc32 = other.ComputeCrc32(),
|
|
285
|
-
data =
|
|
288
|
+
data = dataArray
|
|
286
289
|
};
|
|
287
290
|
}
|
|
288
291
|
|
|
@@ -305,7 +308,7 @@ namespace Code.Player.Character.MovementSystems.Character
|
|
|
305
308
|
return null;
|
|
306
309
|
}
|
|
307
310
|
|
|
308
|
-
var reader =
|
|
311
|
+
var reader = NetworkReaderPool.Get(stateDiff.data);
|
|
309
312
|
var snapshot = (CharacterSnapshotData) this.Clone();
|
|
310
313
|
|
|
311
314
|
snapshot.time = time + NetworkSerializationUtil.DecompressUShort(reader.Read<ushort>());
|
|
@@ -346,6 +349,8 @@ namespace Code.Player.Character.MovementSystems.Character
|
|
|
346
349
|
else {
|
|
347
350
|
snapshot.customData = null;
|
|
348
351
|
}
|
|
352
|
+
|
|
353
|
+
NetworkReaderPool.Return(reader);
|
|
349
354
|
|
|
350
355
|
var crc32 = snapshot.ComputeCrc32();
|
|
351
356
|
if (crc32 != diff.crc32) {
|
|
@@ -365,29 +370,28 @@ namespace Code.Player.Character.MovementSystems.Character
|
|
|
365
370
|
|
|
366
371
|
// We serialize to a byte array for calculating the CRC32. We use slightly more lenient compression
|
|
367
372
|
// on things like the vectors so that floating point errors don't cause the crc checks to fail.
|
|
368
|
-
var writer =
|
|
373
|
+
var writer = NetworkWriterPool.Get();
|
|
369
374
|
byte bools = 0;
|
|
370
375
|
CharacterSnapshotDataSerializer.EncodeBools(ref bools, this);
|
|
371
376
|
writer.Write(bools);
|
|
372
|
-
if (this.customData != null) {
|
|
373
|
-
writer.WriteInt(this.customData.dataSize);
|
|
374
|
-
writer.WriteBytes(this.customData.data, 0, this.customData.data.Length);
|
|
375
|
-
}
|
|
376
|
-
else {
|
|
377
|
-
writer.WriteInt(0);
|
|
378
|
-
}
|
|
379
377
|
writer.Write(this.tick);
|
|
380
378
|
writer.Write(this.lastProcessedCommand);
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
writer.Write(NetworkSerializationUtil.CompressToShort(
|
|
386
|
-
writer.Write(NetworkSerializationUtil.CompressToShort(
|
|
379
|
+
|
|
380
|
+
// Floating point issue make it difficult to use these values directly. We normalize them
|
|
381
|
+
// and compress to short. We need to normalize since these values can be larger than a short.
|
|
382
|
+
var normalPos = this.position.normalized;
|
|
383
|
+
writer.Write(NetworkSerializationUtil.CompressToShort(normalPos.x));
|
|
384
|
+
writer.Write(NetworkSerializationUtil.CompressToShort(normalPos.y));
|
|
385
|
+
writer.Write(NetworkSerializationUtil.CompressToShort(normalPos.z));
|
|
386
|
+
var normalVel = this.velocity.normalized;
|
|
387
|
+
writer.Write(NetworkSerializationUtil.CompressToShort(normalVel.x));
|
|
388
|
+
writer.Write(NetworkSerializationUtil.CompressToShort(normalVel.y));
|
|
389
|
+
writer.Write(NetworkSerializationUtil.CompressToShort(normalVel.z));
|
|
390
|
+
|
|
387
391
|
writer.Write(NetworkSerializationUtil.CompressToShort(this.lookVector.x));
|
|
388
392
|
writer.Write(NetworkSerializationUtil.CompressToShort(this.lookVector.y));
|
|
389
393
|
writer.Write(NetworkSerializationUtil.CompressToShort(this.lookVector.z));
|
|
390
|
-
writer.Write(this.currentSpeed);
|
|
394
|
+
writer.Write(Math.Round(this.currentSpeed, 2));
|
|
391
395
|
// This makes our max speed modifier 65.535 with a 0.001 precision.
|
|
392
396
|
writer.Write(NetworkSerializationUtil.CompressToUshort(this.speedModifier));
|
|
393
397
|
writer.Write(this.canJump);
|
|
@@ -396,6 +400,8 @@ namespace Code.Player.Character.MovementSystems.Character
|
|
|
396
400
|
if (this.customData != null) writer.Write(this.customData.data);
|
|
397
401
|
var bytes = writer.ToArray();
|
|
398
402
|
|
|
403
|
+
NetworkWriterPool.Return(writer);
|
|
404
|
+
|
|
399
405
|
_crc32 = Crc32Algorithm.Compute(bytes);
|
|
400
406
|
return _crc32;
|
|
401
407
|
}
|