static void DoAdjustmentForPrediction() { //if client prediction is enabled, input is sampled in fixed updated //so we only adjust fixed update delta time //error = actual server frame number - predicted server frame number if (_avgPredictionError > 1) { //predicted is less than actual //local should run faster so local can predicter a larger frame numbers internalFixedDeltaTime = internalFixedDeltaTime * FrameSyncConstant.DYNAMIC_ADJUST_STEP; if (internalFixedDeltaTime < _minDeltaTime) { internalFixedDeltaTime = _minDeltaTime; } SWConsole.Warn($"Adjust FASTER internalFixedDeltaTime={internalFixedDeltaTime}"); } else if (_avgPredictionError < -1) { //predicted is greater than actual //local should run slower so local can predict smaller frame numbers internalFixedDeltaTime = internalFixedDeltaTime / FrameSyncConstant.DYNAMIC_ADJUST_STEP; if (internalFixedDeltaTime > _maxDeltaTime) { internalFixedDeltaTime = _maxDeltaTime; } SWConsole.Warn($"Adjust SLOWER internalFixedDeltaTime={internalFixedDeltaTime}"); } }
void SetSaveHandler(int skipSaveIndex) { SWConsole.Warn($"SetSaveHandler skipSaveIndex={skipSaveIndex}"); if (_game.replayFileName != null) { if (_saveHandler != null) { inputFrameDeltas.SetSaveDataHandler(_saveHandler, InputFrameDelta.DataSize); inputFrameDeltas.SetSkipSaveIndex(skipSaveIndex); } } }
public static bool Adjust(int predictionError, float deltaTime) { _adjustTimer += deltaTime; if (_adjustTimer > _adjustInterval) { _adjustTimer = 0; SWConsole.Warn($"======================Adjust======================="); //SWConsole.Warn($"Adjust serverPlayerFrameCount={serverPlayerFrameCount} localServerFrameCount={localServerFrameCount}"); UpdatePredictionError(predictionError); //SWConsole.Warn($"Adjust AVG _avgServerPlayerFrameCount={_avgServerPlayerFrameCount} _avgLocalServerFrameCount={_avgLocalServerFrameCount}"); DoAdjustmentForPrediction(); return(true); } return(false); }
void WaitingForInitialSystemData() { if (HasNewInitialInputFrameDeltas()) { //play all initial input frame SWConsole.Crit($"WaitingForInitialSystemData has initial input deltas startFrameNumber={_startFrameNumber}"); InputFrame inputFrame1 = new InputFrame(); InputFrame inputFrame2 = new InputFrame(); int frameNumber = _startFrameNumber + 1; //if start number is 1 delta, we need to simulate 2 because 2 = 1 input + 1 delta foreach (InputFrameDelta delta in _initialInputFrameDeltas) { inputFrame2.ResetBytes(); delta.Apply(_input, inputFrame1, inputFrame2); FrameSyncUpdateType updateType = FrameSyncUpdateType.Restore; SWConsole.Crit($"WaitingForInitialSystemData simulate {frameNumber}"); DoSimulate(updateType, inputFrame2, frameNumber); InputFrame temp = inputFrame1; inputFrame1 = inputFrame2; inputFrame2 = temp; frameNumber++; } //start from the last restored frame; frameNumber--; _currentInputFrameNumber = frameNumber; ExportSimulationResult(); //create an empty input frame to start with inputFrames[frameNumber] = inputFrame1; //export system data ExportSimulationResult(); SWConsole.Warn($"WaitingForInitialSystemData _initialInputFramesData={_initialInputFramesData.DataLength}"); _saveHandler(_initialInputFramesData, _startFrameNumber, _endFrameNumber); _game.gameState = FrameSyncGameState.Running; SetSaveHandler(_endFrameNumber - 1); //end frame was excluded from initial frames, so we want to save it SWConsole.Crit($"WaitingForInitialSystemData game is running now _currentInputFrameNumber={_currentInputFrameNumber}"); ResetTimeStamp(); return; } }
void RunningOnlineWithPrediction() { SWConsole.Crit("Engine: ================RunningOnlineWithPrediction================="); //FlushInputOnlinePrediction(); // check if we got new server frame to simulate int nextServerFrame = _currentInputFrameNumber + 1; if (true) //CanSimulateInputFrame(nextServerFrame)) { // restore the last simulated server frame before simulate any new server frame RestoreToConfirmedFrame(); } int lastSimulatedPlayerFrameNumber = 0; // simulate all server frames first for (; nextServerFrame <= _lastReceivedInputFrameDeltaNumber + 1; nextServerFrame++) { if (CanSimulateInputFrame(nextServerFrame)) { lastSimulatedPlayerFrameNumber = SimulateInputFrame(nextServerFrame); SWConsole.Crit($"lastSimulatedPlayerFrameNumber={lastSimulatedPlayerFrameNumber}"); if (lastSimulatedPlayerFrameNumber == 0) { // local player's input frame missing for this frame if (_nextPlayerFrameNumberToConfirm > 1) { SWConsole.Warn("wtf"); } } else { _nextPlayerFrameNumberToConfirm = lastSimulatedPlayerFrameNumber + 1; SWConsole.Crit($"nextPlayerFrameNumberToConfirm={_nextPlayerFrameNumberToConfirm}"); } ExportSimulationResult(); } else { break; } } // if last simulated server frame has local player's input // we should simulate all player's input frames after it if (true) // lastSimulatedPlayerFrameNumber > 0) { InputFrame lastInputFrame = inputFrames[nextServerFrame - 1]; lastInputFrame.Copy(_lastInputFrameForPrediction); int startPlayerFrameNumber = _nextPlayerFrameNumberToConfirm; int endPlayerFrameNumber = _currentLocalInputFrameDeltaNumber - FrameSyncConstant.PREDICTION_GLOBAL_DEBAY_FRAMES; int predictFrameNumber = nextServerFrame; SWConsole.Crit($"startPlayerFrameNumber={startPlayerFrameNumber}"); SWConsole.Crit($"endPlayerFrameNumber={endPlayerFrameNumber}"); // endPlayerFrameNumber + 1 to include the endPlayerFrameNumber for (int i = startPlayerFrameNumber; i < endPlayerFrameNumber + 1; i++) { Predict(i, predictFrameNumber); predictFrameNumber++; //swap prediction InputFrames for the next prediction InputFrame temp = _lastInputFrameForPrediction; _lastInputFrameForPrediction = _inputFrameForPrediction; _inputFrameForPrediction = temp; } } //reset game.frameNumber to the last confirmed frame //this is for debug server _game.frameNumber = _currentInputFrameNumber; SWConsole.Crit("Engine: ================end================="); }