Я на самом деле не реализовал это (поэтому могут быть некоторые проблемы, которые я не сразу вижу), но я подумал, что постараюсь помочь.
Вот что вы сказали, что происходит:
Клиент A отправляет данные в момент времени T0
Сервер получает вход в T1
Все клиенты получают изменения в T2
Однако в момент Т2, используя прогнозирование клиента, клиент А теперь находится в позиции, соответствующей Т4.
Вероятно, было бы полезно подумать о времени сервера. Это (вероятно) очень похоже на то, как работает интерполяция .
Каждая команда отправляется с серверным временем. Это серверное время вычисляется в начале матча, запрашивая тик сервера, компенсируя время пинга. На клиенте у вас есть свой локальный счетчик тиков, и каждая отправляемая вами команда преобразуется в тики сервера (это простая операция вычитания)
Также клиент всегда рендерит «в прошлое». Итак, вы предполагаете, что мир, который видит клиент, скажем, на 100 мс отстает от времени сервера.
Итак, давайте перефразируем ваш пример с временем сервера (обозначено S).
Клиент отправляет входные данные в момент времени T0 со временем сервера S0 (что, я полагаю, на самом деле является «клиентским представлением времени сервера минус время интерполяции»). Клиент не ждет ответа от сервера и немедленно перемещается.
Сервер получает вход в T1. Сервер определяет авторитетную позицию клиента в момент времени сервера S0, данный клиентом. Отправляет это клиенту.
Клиент получает официальную позицию в T2 (все еще с обозначением времени сервера S0). Клиент следит за прошлым количеством времени предыдущих событий (вероятно, просто очередью всех неподтвержденных предсказаний).
Если прогнозируемая позиция / скорость / независимо от того, что сервер отправляет обратно на S0, отличается от того, что клиент сохранил на S0, клиент каким-то образом это обрабатывает. Либо вернув игрока обратно в его предыдущую позицию, либо изменив имитацию предыдущего ввода, либо, может быть, что-то еще, о чем я не думал.