public override void Update() { base.Update(); var input = InputSource.SampleInput(); if (InputHistory.Current.Timestep == 0) { InputHistory.Current.Input.MergeWith(input); } input = InputHistory.Append(input); GameStats.Network.Client.UnconfirmedInputs.Update(InputHistory.Count); InputContext.Reset(InputHistory.Current.Input, input); InputContext.Predict(); CurrentState = Simulation.Simulate(CurrentState, InputContext); InputSendTimer++; if (InputSendTimer < NetworkConfig.InputSendRate) { return; } var timestamp = InputHistory.Oldest.Timestep; var mask = InputSource.ValidMask; var inputs = InputHistory.Take(kMaxInputsSent).Select(i => i.Input); NetworkClient.SendInput(timestamp, mask, inputs); InputSendTimer = 0; }
void FastForwardServerState() { if (latestServerState == null || latestServerStateTimestamp < InputHistory.Oldest.Timestep) { return; } CurrentState = latestServerState; var start = latestServerStateTimestamp != 0 ? latestServerStateTimestamp - 1 : 0; foreach (var timedInput in InputHistory.StartingWith(start)) { if (timedInput.Timestep >= InputHistory.Current.Timestep) { break; } var input = timedInput.Input; if (latestServerInput != null) { input.MergeWith(latestServerInput.Value); } if (timedInput.Timestep < latestServerStateTimestamp || timedInput.Timestep == 0) { InputContext.Reset(input); } else { InputContext.Update(input); InputContext.Predict(); var state = CurrentState; Simulation.Simulate(ref state, InputContext); CurrentState = state; } } InputHistory.DropBefore(latestServerStateTimestamp); latestServerState = null; }