private void DoClientUpdate() { int maxRollbackCount = 5; if (_isDebugRollback && _world.Tick > maxRollbackCount && _world.Tick % maxRollbackCount == 0) { var rawTick = _world.Tick; var revertCount = LRandom.Range(1, maxRollbackCount); for (int i = 0; i < revertCount; i++) { var input = new Msg_PlayerInput(_world.Tick, LocalActorId, _inputService.GetDebugInputCmds()); var frame = new ServerFrame() { tick = rawTick - i, _inputs = new Msg_PlayerInput[] { input } }; _cmdBuffer.ForcePushDebugFrame(frame); } _debugService.Trace("RollbackTo " + (_world.Tick - revertCount)); if (!RollbackTo(_world.Tick - revertCount, _world.Tick)) { _commonStateService.IsPause = true; return; } while (_world.Tick < rawTick) { var sFrame = _cmdBuffer.GetServerFrame(_world.Tick); Logging.Debug.Assert(sFrame != null && sFrame.tick == _world.Tick, $" logic error: server Frame must exist tick {_world.Tick}"); _cmdBuffer.PushLocalFrame(sFrame); Simulate(sFrame); if (_commonStateService.IsPause) { return; } } } while (_world.Tick < TargetTick) { FramePredictCount = 0; var input = new Msg_PlayerInput(_world.Tick, LocalActorId, _inputService.GetInputCmds()); var frame = new ServerFrame() { tick = _world.Tick, _inputs = new Msg_PlayerInput[] { input } }; _cmdBuffer.PushLocalFrame(frame); _cmdBuffer.PushServerFrames(new ServerFrame[] { frame }); Simulate(_cmdBuffer.GetFrame(_world.Tick)); if (_commonStateService.IsPause) { return; } } }