Проще говоря, вам нужно отправить отметку времени с каждым снимком с сервера и с каждым входом от клиента.
На обоих концах вам нужен процесс для «заполнения» любых кадров, в которые пакеты не принимаются.
В моей игре (быстро развивающейся игре в жанре экшн - ваша может отличаться), на сервере я отбрасываю любой «более старый» (не в порядке) ввод и просто предполагаю, что если новые входные пакеты не поступают, те же кнопки просто продолжайте удерживать (есть еще кое-что для того, чтобы быть уверенным в том, что короткие нажатия / отпускания кнопок обрабатываются, но это основная предпосылка).
На клиенте я держу «буфер задержки» (описанный в этой статье, который связал Tetrad). Я использую скользящее среднее время прибытия, чтобы гарантировать, что буфер задержки остается нужной длины - заставляя клиентскую игру работать немного медленнее или быстрее, чтобы наверстать упущенное. Если моментальные снимки не приходят вовремя, я делаю экстраполяцию на клиенте. В противном случае я интерполирую снимки в буфере.
Клиент также отвечает за отслеживание времени прохождения сигнала в обоих направлениях и его использование для прогнозирования (сервер отправляет обратно метку времени входа, который он использовал при расчете данного кадра). Он буферизует входные данные на этот промежуток времени, воспроизводя их, чтобы перенести позицию игрока из «старой» позиции (в моментальном снимке с сервера) в предсказанную «текущую» позицию.
По сути, сервер просто продолжает работать с фиксированной частотой кадров. Это зависит от клиентов, которые остаются синхронизированными с сервером.
Конечно, это просто обзор высокого уровня. Есть много мельчайших деталей, которые вы должны выяснить, когда реализуете это.