Skip to content
This repository was archived by the owner on Oct 22, 2023. It is now read-only.

Commit 2b349ba

Browse files
committed
Working rollback for spawning
Includes debug messages
1 parent 2b7547e commit 2b349ba

File tree

14 files changed

+215
-63
lines changed

14 files changed

+215
-63
lines changed

Engine/Client/Simulation.cs

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ public void Update(float deltaTime)
7373
_accumulatedTime += deltaTime;
7474

7575
while (_accumulatedTime >= _tickDt)
76-
{
76+
{
77+
78+
_logger.Warn(" ========= " + (_systems.CurrentTick + 1) + " ========= ");
7779

7880
Tick();
7981

@@ -82,20 +84,20 @@ public void Update(float deltaTime)
8284
}
8385

8486
private void Tick()
85-
{
87+
{
8688
ICommand[] frameCommands;
8789
lock (_temporaryCommandBuffer)
8890
{
8991
frameCommands = _temporaryCommandBuffer.ToArray();
9092
_temporaryCommandBuffer.Clear();
91-
}
92-
93+
}
94+
9395
if (frameCommands.Length > 0)
9496
{
9597
LocalCommandBuffer.Insert(_systems.CurrentTick + LagCompensation, LocalPlayerId, frameCommands);
9698
RemoteCommandBuffer.Insert(_systems.CurrentTick + LagCompensation, LocalPlayerId, frameCommands);
9799
}
98-
100+
99101
_systems.Tick(LocalCommandBuffer.GetMany(_systems.CurrentTick));
100102

101103
Ticked?.Invoke(_systems.CurrentTick);
@@ -106,26 +108,31 @@ private void SyncCommandBuffer()
106108
var currentRemoteFrame = RemoteCommandBuffer.LastInsertedFrame;
107109

108110
if (LastValidatedFrame < currentRemoteFrame)
109-
{
110-
var revertTick = currentRemoteFrame;
111+
{
112+
_logger.Warn("Catching up: " + LastValidatedFrame + " -> " + currentRemoteFrame + " of " + _systems.CurrentTick);
113+
114+
var revertFrame = currentRemoteFrame; //We guess everything was predicted correctly
111115

112116
for (var remoteFrame = LastValidatedFrame + 1; remoteFrame <= currentRemoteFrame; remoteFrame++)
113117
{
118+
//All frames that have no commands were predicted correctly => increase remote frame
114119
var allPlayerCommands = RemoteCommandBuffer.Get(remoteFrame);
115120
if (allPlayerCommands.Count <= 0)
116121
{
117122
continue;
118123
}
119124

120-
if (remoteFrame < revertTick)
125+
if (remoteFrame < revertFrame)
121126
{
122-
//Save the first tick which contains remote commands
123-
revertTick = remoteFrame;
127+
//Store the first frame where predicion was false (frame has commands)
128+
revertFrame = remoteFrame;
124129
}
125130

126131
//Merge commands into the local command buffer
127132
foreach (var commandPerPlayer in allPlayerCommands)
128133
{
134+
135+
_logger.Warn("Insert remote commands from " + remoteFrame);
129136
LocalCommandBuffer.Insert(remoteFrame, commandPerPlayer.Key, commandPerPlayer.Value.ToArray());
130137
}
131138
}
@@ -135,11 +142,22 @@ private void SyncCommandBuffer()
135142
{
136143
var targetTick = _systems.CurrentTick;
137144

138-
_systems.RevertToTick(revertTick);
139-
140-
while (_systems.CurrentTick < targetTick)
141-
{
142-
_systems.Tick(LocalCommandBuffer.GetMany(_systems.CurrentTick));
145+
//Revert everything that happened one tick after the last validated input
146+
_systems.RevertFromTick(revertFrame + 1);
147+
148+
//Execute all commands again, beginning from the first frame that contains remote input
149+
while (revertFrame <= targetTick)
150+
{
151+
if (LocalCommandBuffer.GetMany(_systems.CurrentTick).Length > 0)
152+
{
153+
154+
_logger.Warn("Execute " + LocalCommandBuffer.GetMany(revertFrame).Length + " commands from tick " + revertFrame);
155+
}
156+
157+
_logger.Warn(">>>>========= " + (revertFrame) + " ========= ");
158+
_systems.Tick(LocalCommandBuffer.GetMany(revertFrame));
159+
160+
revertFrame++;
143161
}
144162
}
145163

Engine/Core/GameSystems.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public GameSystems(Contexts contexts, params IService[] additionalServices)
2424
{
2525
Services.Register(service);
2626
}
27-
27+
2828
Add(new IncrementTick(Contexts));
2929

3030
Add(new InputFeature(Contexts, Services));
@@ -34,6 +34,7 @@ public GameSystems(Contexts contexts, params IService[] additionalServices)
3434
Add(new GameEventSystems(Contexts));
3535

3636
Add(new HashCodeFeature(Contexts, Services));
37+
3738
}
3839

3940
public void Tick(ICommand[] input)
@@ -44,7 +45,7 @@ public void Tick(ICommand[] input)
4445
Cleanup();
4546
}
4647

47-
public void RevertToTick(uint tick)
48+
public void RevertFromTick(uint tick)
4849
{
4950
foreach (var system in _executeSystems)
5051
{
@@ -53,8 +54,8 @@ public void RevertToTick(uint tick)
5354
stateSystem.RevertToTick(tick);
5455
}
5556
}
56-
57-
Contexts.gameState.ReplaceTick(tick);
57+
58+
Contexts.gameState.ReplaceTick(tick - 1);
5859
}
5960
}
6061
}

Engine/Core/Interfaces/ILogService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
{
33
public interface ILogService : IService
44
{
5-
void Warn(string message);
5+
void Warn(object message);
66
}
77
}

Engine/Core/Interfaces/ISystems.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ public interface ISystems
1111

1212
void Tick(ICommand[] input);
1313

14-
void RevertToTick(uint tick);
14+
void RevertFromTick(uint tick);
1515
}
1616
}

Engine/Core/Systems/Input/OnSpawnInputCreateEntity.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.Generic;
2+
using System.Linq;
23
using BEPUutilities;
34
using Entitas;
45
using Lockstep.Core.Interfaces;
@@ -51,28 +52,33 @@ protected override void Execute(List<InputEntity> inputs)
5152
_createdEntities.Add(_gameStateContext.tick.value, new List<uint>());
5253
}
5354

54-
_createdEntities[_gameStateContext.tick.value].Add(_nextEntityId);
55-
56-
_nextEntityId++;
55+
_createdEntities[_gameStateContext.tick.value].Add(_nextEntityId);
56+
_nextEntityId++;
5757
}
58+
59+
_logger?.Warn(_gameStateContext.tick.value + ": " + inputs.Count + " added");
5860
}
5961

6062
public void RevertToTick(uint tick)
61-
{
63+
{
64+
var t = tick;
65+
var count = 0;
6266
for (;tick <= _gameStateContext.tick.value; tick++)
6367
{
6468
if (_createdEntities.ContainsKey(tick))
6569
{
66-
_logger?.Warn("Destroying " + _createdEntities[tick].Count + " Entities from tick " + tick);
6770
foreach (var entityId in _createdEntities[tick])
6871
{
69-
_gameContext.GetEntityWithId(entityId).Destroy();
72+
_gameContext.GetEntities().First(entity => entity.id.value == entityId).Destroy();
7073
_nextEntityId--;
74+
count++;
7175
}
7276

7377
_createdEntities[tick].Clear();
7478
}
7579
}
80+
81+
_logger?.Warn(t + " -> " + tick + ": " + count + " destroyed");
7682
}
7783
}
7884
}

Engine/Server/Room.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ public class Room
1616

1717
private byte _nextPlayerId;
1818
private readonly int _size;
19-
20-
private InputBuffer _inputBuffer;
19+
2120
private readonly IServer _server;
2221

2322
public bool Running { get; private set; }

Engine/Test/Converter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public TestLogger(ITestOutputHelper outputHelper)
3333
{
3434
_outputHelper = outputHelper;
3535
}
36-
public void Warn(string message)
36+
public void Warn(object message)
3737
{
3838
_outputHelper.WriteLine($"Warn: {message}");
3939
}

0 commit comments

Comments
 (0)