public void SendGameStateUpdate(bool force = false, bool forceFullState = false) { //Obey the updates per second limit TimeSpan elapsed = Time - _lastStateTime; if (force || elapsed.TotalMilliseconds > (1000 / updateRate)) { //Save last state time _lastStateTime = Time; //Create a new GameState object var stateManager = IoCManager.Resolve <IGameStateManager>(); var state = new GameState(++_lastState); if (EntityManager != null) { state.EntityStates = EntityManager.GetEntityStates(); } state.PlayerStates = IoCManager.Resolve <IPlayerManager>().GetPlayerStates(); stateManager.Add(state.Sequence, state); //LogManager.Log("Update " + _lastState + " sent."); List <NetConnection> connections = IoCManager.Resolve <ISS13NetServer>().Connections; if (connections.Count == 0) { //No clients -- don't send state _oldestAckedState = _lastState; stateManager.Clear(); } else { foreach ( NetConnection c in IoCManager.Resolve <ISS13NetServer>().Connections.Where( c => c.Status == NetConnectionStatus.Connected)) { IPlayerSession session = IoCManager.Resolve <IPlayerManager>().GetSessionByConnection(c); if (session == null || (session.status != SessionStatus.InGame && session.status != SessionStatus.InLobby)) { continue; } NetOutgoingMessage stateMessage = IoCManager.Resolve <ISS13NetServer>().CreateMessage(); uint lastStateAcked = stateManager.GetLastStateAcked(c); if (lastStateAcked == 0)// || forceFullState) { int length = state.WriteStateMessage(stateMessage); //LogManager.Log("Full state of size " + length + " sent to " + c.RemoteUniqueIdentifier); } else { stateMessage.Write((byte)NetMessage.StateUpdate); GameStateDelta delta = stateManager.GetDelta(c, _lastState); delta.WriteDelta(stateMessage); //LogManager.Log("Delta of size " + delta.Size + " sent to " + c.RemoteUniqueIdentifier); } IoCManager.Resolve <ISS13NetServer>().SendMessage(stateMessage, c, NetDeliveryMethod.Unreliable); } } stateManager.Cull(); } }