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

Commit

Permalink
Merge pull request #28 from proepkes/develop
Browse files Browse the repository at this point in the history
Adds Actor-context
Adds new way of rollback by simulating all input since the last received frame instead of adding a shadow each frame => high performance gain
  • Loading branch information
proepkes authored Feb 2, 2019
2 parents 8c4a48e + 282b49d commit 4e1c7af
Show file tree
Hide file tree
Showing 76 changed files with 1,352 additions and 836 deletions.
65 changes: 49 additions & 16 deletions Engine/Client/Simulation.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Threading;
using Lockstep.Client.Interfaces;
using Lockstep.Core.Interfaces;
using Lockstep.Network.Messages;
Expand All @@ -12,6 +13,8 @@ public class Simulation
/// </summary>
public uint LagCompensation { get; set; }

public bool SendCommandsToBuffer { get; set; } = true;

public bool Running { get; private set; }

public byte LocalPlayerId { get; private set; }
Expand All @@ -34,12 +37,12 @@ public Simulation(IWorld world, ICommandBuffer remoteCommandBuffer)
public void Initialize(Init init)
{
_tickDt = 1000f / init.TargetFPS;
LocalPlayerId = init.PlayerID;
LocalPlayerId = init.ActorID;

_world.Initialize(LocalPlayerId);
_world.Initialize(init.AllActors);

Running = true;
}
}

public void Execute(ICommand command)
{
Expand All @@ -54,7 +57,7 @@ public void Execute(ICommand command)
}
}

public void Update(float deltaTime)
public void Update(float elapsedMilliseconds)
{
if (!Running)
{
Expand All @@ -63,7 +66,7 @@ public void Update(float deltaTime)

SyncCommandBuffer();

_accumulatedTime += deltaTime;
_accumulatedTime += elapsedMilliseconds;

while (_accumulatedTime >= _tickDt)
{
Expand All @@ -80,13 +83,16 @@ private void Tick()
if (_commandCache.Count > 0)
{
_world.AddInput(_world.CurrentTick + LagCompensation, LocalPlayerId, _commandCache);
_remoteCommandBuffer.Insert(_world.CurrentTick + LagCompensation, LocalPlayerId, _commandCache.ToArray());
if (SendCommandsToBuffer)
{
_remoteCommandBuffer.Insert(_world.CurrentTick + LagCompensation, LocalPlayerId, _commandCache.ToArray());
}

_commandCache.Clear();
}
}
}

_world.Tick();
_world.Predict();
}

private void SyncCommandBuffer()
Expand All @@ -113,8 +119,8 @@ private void SyncCommandBuffer()
firstMispredictedFrame = remoteFrame;
}

//TODO: if command contains entity-ids (which can be predicted) and due to rollback we generated local ids, the command's entity-ids have to be adjusted
//https://github.com/proepkes/UnityLockstep/wiki/Rollback-WIP-Log
//TODO: if command contains entity-ids (which can be predicted) and due to rollback->fast-forward we generated local ids, the command's entity-ids have to be adjusted
//https://github.com/proepkes/UnityLockstep/wiki/Rollback-devlog
foreach (var playerCommands in allPlayerCommands)
{
_world.AddInput(remoteFrame, playerCommands.Key, playerCommands.Value);
Expand All @@ -128,18 +134,45 @@ private void SyncCommandBuffer()

_world.RevertToTick(firstMispredictedFrame);

var validInputFrame = firstMispredictedFrame;
while (_world.CurrentTick < firstMispredictedFrame)
{
_world.Simulate();
}

//Execute all commands again, beginning from the first frame that contains remote input up to our last local state
while (validInputFrame <= targetTick)
//Restore last local state
while (_world.CurrentTick < targetTick)
{
_world.Tick();
validInputFrame++;
_world.Predict();
}
}

_lastValidatedFrame = currentRemoteFrame;
}
}


/// <summary>
/// Experimental
/// </summary>
public void StartAsThread()
{
new Thread(Loop) { IsBackground = true }.Start();
}

private void Loop()
{
var timer = new Timer();

Running = true;

timer.Start();

while (Running)
{
Update(timer.Tick());

Thread.Sleep(1);
}
}
}
}
2 changes: 1 addition & 1 deletion Engine/Server/Timer.cs → Engine/Client/Timer.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Diagnostics;

namespace Server
namespace Lockstep.Client
{
public class Timer
{
Expand Down
13 changes: 13 additions & 0 deletions Engine/Core/Components/Actor/BackupComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Entitas;

namespace Lockstep.Core.Components.Actor
{
[Actor]
//An ActorEntity with BackupComponent refers to an actor in the past
public class BackupComponent : IComponent
{
public byte actorId;

public uint tick;
}
}
10 changes: 10 additions & 0 deletions Engine/Core/Components/Actor/EntityCountComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Entitas;

namespace Lockstep.Core.Components.Actor
{
[Actor]
public class EntityCountComponent : IComponent
{
public uint value;
}
}
12 changes: 12 additions & 0 deletions Engine/Core/Components/Actor/IdComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Entitas;
using Entitas.CodeGeneration.Attributes;

namespace Lockstep.Core.Components.Actor
{
[Actor]
public sealed class IdComponent : IComponent
{
[PrimaryEntityIndex]
public byte value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Lockstep.Core.Components.Game
{
[Game]
public class OwnerIdComponent : IComponent
public class ActorIdComponent : IComponent
{
public byte value;
}
Expand Down
13 changes: 13 additions & 0 deletions Engine/Core/Components/Game/BackupComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Entitas;

namespace Lockstep.Core.Components.Game
{
[Game]
//A GameEntity with BackupComponent refers to an entity in the past
public class BackupComponent : IComponent
{
public uint localEntityId;

public uint tick;
}
}
2 changes: 1 addition & 1 deletion Engine/Core/Components/Game/IdComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace Lockstep.Core.Components.Game
{
[Game]
public sealed class IdComponent : IComponent
{
{
public uint value;
}
}
5 changes: 4 additions & 1 deletion Engine/Core/Components/Game/NewComponent.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
using Entitas;

namespace Lockstep.Core.Components.Game
{
{
/// <summary>
/// Flags an entity as newly created. Useful for rollback: if a shadow marked as new, the referenced entity just gets destroyed.
/// </summary>
public class NewComponent : IComponent
{
}
Expand Down
10 changes: 0 additions & 10 deletions Engine/Core/Components/Game/ShadowComponent.cs

This file was deleted.

10 changes: 0 additions & 10 deletions Engine/Core/Components/Game/TickComponent.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
namespace Lockstep.Core.Components.GameState
{
[GameState, Unique]
public sealed class PlayerIdComponent : IComponent
public class PredictingComponent : IComponent
{
public byte value;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Lockstep.Core.Components.Input
{
[Input]
public class PlayerId : IComponent
public class ActorId : IComponent
{
public byte value;
}
Expand Down
2 changes: 1 addition & 1 deletion Engine/Core/Components/Input/TickComponent.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Entitas;

namespace Lockstep.Core.Components.Input
{
{
[Input]
public class TickComponent : IComponent
{
Expand Down
Loading

0 comments on commit 4e1c7af

Please sign in to comment.