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.serverCommandBuffer.Keys[^1] - (this.serverLastProcessedCommandNumber + 1) <
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: " + command.commandNumber +
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: " + this.lastProcessedCommand);
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
- } while (this.serverCommandBuffer.Count >
622
- serverCommandBufferTargetSize &&
623
- commandsProcessed < 1 + this.maxServerCommandCatchup);
624
- // ^ we process up to maxServerCommandCatchup commands per tick if our buffer has more than serverCommandBufferTargetSize worth of additional commands.
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 real time value.
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;
@@ -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 = NetworkSerializationUtil.CompressToShort(this.currentSpeed) == NetworkSerializationUtil.CompressToShort(other.currentSpeed);
64
- var speedModifierEqual = NetworkSerializationUtil.CompressToShort(this.speedModifier) == NetworkSerializationUtil.CompressToShort(other.speedModifier);
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 = new NetworkWriter();
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 = writer.ToArray()
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 = new NetworkReader(stateDiff.data);
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 = new NetworkWriter();
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
- writer.Write(NetworkSerializationUtil.CompressToShort(this.position.x));
382
- writer.Write(NetworkSerializationUtil.CompressToShort(this.position.y));
383
- writer.Write(NetworkSerializationUtil.CompressToShort(this.position.z));
384
- writer.Write(NetworkSerializationUtil.CompressToShort(this.velocity.x));
385
- writer.Write(NetworkSerializationUtil.CompressToShort(this.velocity.y));
386
- writer.Write(NetworkSerializationUtil.CompressToShort(this.velocity.z));
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gg.easy.airship",
3
- "version": "0.1.2150",
3
+ "version": "0.1.2151",
4
4
  "displayName": "Airship",
5
5
  "unity": "2021.3",
6
6
  "unityRelease": "12f1",