public void Render(ComponentizedEntity entity, IGameContext gameContext, IRenderContext renderContext)
        {
            if (!_enabled || _serverOnly)
            {
                return;
            }

            if (renderContext.IsCurrentRenderPass <IDebugRenderPass>())
            {
                var debugRenderPass     = renderContext.GetCurrentRenderPass <IDebugRenderPass>();
                var entityTransformSync = _synchronisedData.Select(x => x.Value).FirstOrDefault(x => x.Name == "entity.transform");

                if (entityTransformSync != null && debugRenderPass.EnabledLayers.OfType <ServerStateDebugLayer>().Any())
                {
                    var lastValueSerialized = entityTransformSync.LastValueFromServer as NetworkTransform;
                    if (lastValueSerialized != null)
                    {
                        var timeMachine = entityTransformSync.TimeMachine;
                        if (timeMachine != null)
                        {
                            var lastValueRelative = lastValueSerialized.DeserializeFromNetwork();
                            var lastValueAbsolute = DefaultFinalTransform.Create(entity.FinalTransform.ParentObject,
                                                                                 new TransformContainer(lastValueRelative));

                            var clientLocalTickValueRelative = timeMachine.Get(_localTick) as ITransform;
                            var clientLocalTickValueAbsolute = DefaultFinalTransform.Create(entity.FinalTransform.ParentObject,
                                                                                            new TransformContainer(clientLocalTickValueRelative));

                            var clientRewindValueRelative = timeMachine.Get(_localTick - _networkEngine.ClientRenderDelayTicks) as ITransform;
                            var clientRewindValueAbsolute = DefaultFinalTransform.Create(entity.FinalTransform.ParentObject,
                                                                                         new TransformContainer(clientRewindValueRelative));

                            var lastValuePoint   = Vector3.Transform(Vector3.Zero, lastValueAbsolute.AbsoluteMatrix);
                            var lastValueUp      = Vector3.Transform(Vector3.Up, lastValueAbsolute.AbsoluteMatrix);
                            var lastValueForward = Vector3.Transform(Vector3.Forward, lastValueAbsolute.AbsoluteMatrix);
                            var lastValueLeft    = Vector3.Transform(Vector3.Left, lastValueAbsolute.AbsoluteMatrix);

                            var clientLocalTickPoint   = Vector3.Transform(Vector3.Zero, clientLocalTickValueAbsolute.AbsoluteMatrix);
                            var clientLocalTickUp      = Vector3.Transform(Vector3.Up, clientLocalTickValueAbsolute.AbsoluteMatrix);
                            var clientLocalTickForward = Vector3.Transform(Vector3.Forward, clientLocalTickValueAbsolute.AbsoluteMatrix);
                            var clientLocalTickLeft    = Vector3.Transform(Vector3.Left, clientLocalTickValueAbsolute.AbsoluteMatrix);

                            var clientRewindValueTickPoint   = Vector3.Transform(Vector3.Zero, clientRewindValueAbsolute.AbsoluteMatrix);
                            var clientRewindValueTickUp      = Vector3.Transform(Vector3.Up, clientRewindValueAbsolute.AbsoluteMatrix);
                            var clientRewindValueTickForward = Vector3.Transform(Vector3.Forward, clientRewindValueAbsolute.AbsoluteMatrix);
                            var clientRewindValueTickLeft    = Vector3.Transform(Vector3.Left, clientRewindValueAbsolute.AbsoluteMatrix);

                            if (entity.GetType().Name == "CubeEntity")
                            {
                                Console.WriteLine(lastValueSerialized);
                            }

                            // Render the previous and next server states.
                            _debugRenderer.RenderDebugLine(renderContext, lastValuePoint, lastValueUp, Color.Red, Color.Red);
                            _debugRenderer.RenderDebugLine(renderContext, lastValuePoint, lastValueForward, Color.Red, Color.Red);
                            _debugRenderer.RenderDebugLine(renderContext, lastValuePoint, lastValueLeft, Color.Red, Color.Red);
                            _debugRenderer.RenderDebugLine(renderContext, clientLocalTickPoint, clientLocalTickUp, Color.Orange, Color.Orange);
                            _debugRenderer.RenderDebugLine(renderContext, clientLocalTickPoint, clientLocalTickForward, Color.Orange, Color.Orange);
                            _debugRenderer.RenderDebugLine(renderContext, clientLocalTickPoint, clientLocalTickLeft, Color.Orange, Color.Orange);
                            _debugRenderer.RenderDebugLine(renderContext, clientRewindValueTickPoint, clientRewindValueTickUp, Color.Yellow, Color.Yellow);
                            _debugRenderer.RenderDebugLine(renderContext, clientRewindValueTickPoint, clientRewindValueTickForward, Color.Yellow, Color.Yellow);
                            _debugRenderer.RenderDebugLine(renderContext, clientRewindValueTickPoint, clientRewindValueTickLeft, Color.Yellow, Color.Yellow);
                        }
                    }
                }
            }
        }
        public void Update(ComponentizedEntity entity, IServerContext serverContext, IUpdateContext updateContext)
        {
            if (!_enabled)
            {
                return;
            }

            _localTick++;
            _isRunningOnClient = false;

            if (_uniqueIdentifierForEntity == null)
            {
                _uniqueIdentifierForEntity = _uniqueIdentifierAllocator.Allocate();
                _networkEngine.RegisterObjectAsNetworkId(_uniqueIdentifierForEntity.Value, entity);
            }

            if (_serverOnly)
            {
                return;
            }

            // Sync the entity to the client if it hasn't been already.
            foreach (var dispatcher in _networkEngine.CurrentDispatchers)
            {
                foreach (var group in dispatcher.ValidClientGroups)
                {
                    if (ClientAuthoritiveMode != ClientAuthoritiveMode.None &&
                        ClientOwnership != null &&
                        OnlySendToAuthoritiveClient)
                    {
                        if (ClientOwnership != group)
                        {
                            // This client doesn't own the entity, and this entity is only
                            // synchronised with clients that own it.
                            _consoleHandle.LogDebug("Entity is owned by " + ClientOwnership + ", and target client is " + group + " who doesn't own it, so I'm not syncing it.");
                            continue;
                        }
                    }

                    if (!_clientsEntityIsKnownOn.Contains(group))
                    {
                        _consoleHandle.LogDebug("Entity is not known to " + group + ", sending creation message.");

                        // Send an entity creation message to the client.
                        var createMessage = new EntityCreateMessage
                        {
                            EntityID         = _uniqueIdentifierForEntity.Value,
                            EntityType       = entity.GetType().AssemblyQualifiedName,
                            InitialTransform = entity.Transform.SerializeToNetwork(),
                            FrameTick        = _localTick,
                            MessageOrder     = _messageOrder++,
                        };
                        _networkEngine.Send(
                            dispatcher,
                            group,
                            createMessage,
                            true);

                        _clientsEntityIsKnownOn.Add(group);
                    }
                }
            }

            PrepareAndTransmitSynchronisation(entity, _localTick, false, ClientAuthoritiveMode);
        }