Перейти к основному содержимому
Живая игра

Эта страница ещё не переведена — показана английская версия.

Lag Compensation

Компенсация лагов (lag compensation) — серверный механизм, и её ошибки стоят игроку жизни — причём в пользу того, у кого соединение хуже. Эта асимметрия определяет всё, что описано на странице.

Вопрос, на который она отвечает, узкий: что на самом деле видел стрелок? Действие может нести время обзора — тик, на который смотрел актор, когда действовал. Платформа восстанавливает позы целей на этот тик, и выстрел оценивается по тому, что было у стрелка на экране.

Время обзора — утверждение, а не факт

Время обзора приходит от клиента, поэтому это заявление вызывающей стороны, и относятся к нему соответственно. Отсюда два следствия:

  • Окно компенсации ограничено, и за его пределами платформа отказывает. Она не экстраполирует, чтобы помочь: отказ — решение, которое видно, а молчаливая экстраполяция — решение, которого не видно.
  • Чтение прошлого состояния цели по-прежнему подчиняется видимости. Запрос к историческому тику не позволяет обойти Visibility: чего вы не могли видеть тогда, того не прочитаете и сейчас.

А «попадание не засчитано» — это вердикт, а не ошибка: успешный ответ с машиночитаемой причиной.

Что откатывается, объявлено, и откатывается не всё

Если откатывать всё, получаются двойные убийства: два игрока стреляют друг в друга, обоих отматывают к моменту, когда оба живы, и оба попадают. Если не откатывать ничего, компенсации лагов просто нет. Граница между этими крайностями — объявленный список.

Сам откат живёт здесь, а не в модулях, чьё состояние отматывается. Кольцо истории восстанавливает позы спорного тика, а затем модулю Collision задают обычный вопрос о пересечениях для этих поз. Своей истории у этого модуля нет, и ничто в нём не знает, что такое тик обзора. Само кольцо — это трек истории сущности, а не отдельное хранилище.

Решение принимается по прошлому, а последствия применяются в настоящем

the shooterthe server fired, seeing the world several ticks agorewind the declared state to that tick, judge thereapply the effect in the presentthe outcome
Выстрел оценивается на тике, который видел стрелок, а последствия применяются в настоящем

Компенсация лагов отвечает на вопрос о том моменте, который видел стрелок. А последствия — урон, смерть, награда — применяются к текущему состоянию. То, что произошло между моментом обзора и моментом решения, не отменяется и не пересчитывается.

Игрок может выстрелить уже после того, как его убили

Игрок (player) может успеть выстрелить после того, как его убил чужой выстрел, оценённый с откатом. Так и задумано: чтобы отменить такой выстрел, пришлось бы заново прогонять мир поверх отката, который не обещает воспроизводимости. Это порождает расхождения, а не устраняет их.

Повторная симуляция на сервере в задачи модуля не входит. Чтобы пересчитать последствия под новую правду, нужна фиксированная точка отсчёта, а состояние с плавающей точкой её не даёт. Остаётся всё, на чём держится модуль: клиент переигрывает свой неподтверждённый ввод (Предсказание своего движения), а компенсация лагов читает прошлое ради одного решения. Так на практике и работает принцип «в пользу стрелка».

Если вы раньше работали с другими решениями

  • Компенсация лагов в пользу стрелка, как в большинстве соревновательных шутеров: механизм тот же, и эта страница как раз о нём.
  • Полноценный rollback-неткод. Откат здесь есть, а повторного прогона мира после него нет — почему, объяснено выше. Если ваш дизайн рассчитывает на то, что последствия будут пересчитаны задним числом, обсудите это с нами как можно раньше, а не обнаруживайте в конце.

Что ещё полезно знать

  • Реализацию можно переопределить. Если вашей игре нужно другое правило компенсации, замените наше. Замена объявляет, какие из объявлений она соблюдает.
  • На пути предсказания и коррекции точек расширения нет. Эти шаги выполняются с частотой тика.
  • Если авторитетный источник внешний, ничего из этого не работает. Компенсация лагов существует для комнат (room), которые симулирует наша платформа. Если тик принадлежит игровому серверу студии или мастер-клиенту, компенсацией занимается тот, кто этот тик выполняет, — см. Кто выполняет тик.