что такое интерполяция в играх
Мультиплеер в быстрых играх (Часть III: появление врага)
Введение
В первой статье я рассказал про авторитарный сервер и его полезность для защиты от читов. В результате второй части мы получили набор техник, позволяющих игроку контролировать персонажа на удаленном сервере без лага.
В этой статье мы рассмотрим последствия одновременного подключения нескольких игроков к одному серверу.
От переводчика: в этой и последующих статьях для гифок используется демка, написанная мной и bogotoff из NerfGame.
Частота обновления сервера
В предыдущей статье поведение сервера было предельно простым — он считывает ввод клиента; обновляет состояние игры; отправляет его обратно на клиент. Но когда клиентов много, они очень часто отправляют команды. Обновление игрового мира для каждой команды и последующее оповещение всех клиентов об измененном состоянии основательно нагрузило бы процессор и сеть.
Более удачным подходом было бы накапливать все команды без выполнения. Вместо этого мир будет обновляться периодично с низкой частотой, например 10 раз в секунду. Во время каждого обновления все накопленные команды применяются(возможно с несколькими шагами физики, чтобы она была более стабильной) и новое состояние игры рассылается по клиентам.
Прим. Перев. В быстрых играх вы скорее всего захотите выставить частоту обновления не меньше 20 раз в секунду(как в Overwatch) и поднимать его вплоть до 120 (как в CS:GO).
Коротко говоря, у игрового мира есть собственная фиксированная частота обновления, не зависящая от наличия команд или их количества.
Справляемся с редкими обновлениями
Пока игрок один, с его точки зрения все работает так же гладко и мгновенно как и раньше, так как предсказание на стороне клиента работает вне зависимости от частоты ответов сервера.
Но ему приходят слишком редкие обновления о том, что происходит на сервере с другими игроками. Наивная реализация других игроков работает так: клиент применяет обновление состояния другого игрока, как только получает его. Естественно, это приводит к рывкам, так как частота обновления вражеских игроков будет 10 кадров в секунду.
В зависимости от типа разрабатываемой игры, есть различные способы бороться с этим. Причем чем более предсказуема игра, тем проще выйти из этой ситуации.
Экстраполяция
Предположим, что вы делаете гонки. Машины довольно предсказуемы — если машина едет 100 м/с, через секунду она будет примерно на 100 метров впереди от того места, где она была.
Почему “примерно”? В течении этой секунды машина могла немного ускориться, или затормозить; немного повернуться. Ключевое слово здесь — немного. Машины устроены так, что позиция преимущественно зависит от предыдущей позиции, скорости и направления; и в меньшей степени от действий пользователя. Другими словами, гоночная машина не может мгновенно развернуться на 180 градусов.
Как же это работает с обновлениями сервера каждые 100 мс? Клиент получает скорость и направление каждой машины; в течении следующих 100 мс он не будет получать новой информации, но он должен показать что машины едут. Самое простое что можно предположить — что направление и ускорение будут константными в течении этого времени и локально воспроизводить физику машины с учетом этих параметров. Позже, когда обновление придет, позиция машины будет скорректирована.
Эта коррекция может быть большой или маленькой в зависимости от множества параметров. Если игрок вел машину прямо и не менял скорость, экстраполированная позиция идеально совпадет со скорректированной. С другой стороны, если игрок врезался во что-то, предсказанная позиция будет абсолютно неправильна.
Этот метод подойдет только для объектов с большой инерцией: машины, корабли.
Интерполяция
Есть ситуации когда экстраполяция вообще не может быть применена. Собственно, во всех сценариях, где направление и скорость персонажа меняются быстро. Например в 3d шутере игроки обычно, останавливаются и огибают препятствия на больших скоростях, делая экстраполяцию бессмысленной, так как позиции не могут быть предсказаны из устаревшей информации.
При этом вы все еще не можете наивно применять обновления с сервера: игроки будут телепортироваться каждые 100 мс и при каждом потерянном/задержавшемся пакете.
У вас есть информация о позиции врагов каждые 100 мс. Так что трюк заключается в том, чтобы показывать игроку что происходило между этими обновлениями в прошлом.
Пусть вы получаете позиции в момент t = 1000. Вы уже получили информацию о t = 900, так что от t = 1000 до t = 1100, вы показываете что этот игрок делал с t = 900 до t = 1000. Таким образом вы показываете настоящее передвижение врагов, но на 100 мс позже.
Учтите, что при использовании этой техники игроки видят немного разное состояние мира, так как себя игрок видит в настоящем времени(это необходимо для отсутствие лага при вводе), а врагов видит в прошлом(это было бы даже без интерполяции, из-за ненулевого пинга). Но даже в быстрых играх задержка на 100 мс обычно незаметна.
Но есть исключения — если нужна высокая пространственная и временная точность, например при выстреле одного игрока в другого. Так как другие игроки видны в прошлом, вы целитесь с задержкой в 100 мс + пинг, то есть туда, где враг был более 100 мс назад! С этим мы будем разбираться в следующей статье.
В клиент-серверной модели с авторитарным сервером, редкими обновлениями и задержками в связи, вы все равно должны дать игроку иллюзию непрерывного движения. В предыдущей части мы рассматривали способы мгновенно реагировать на пользовательский ввод используя предсказание на стороне клиента и согласование с сервером.
Но другие игроки все еще для нас были проблемой. В этой статье мы рассмотрели два способа справиться с ними:
Экстраполяция — применяется когда позиция может быть предсказана исходя из предыдущей информации — позиции, скорости и ускорения.
Интерполяция — не предсказывает будущее, а использует только реальную информацию, предоставленную сервером, показывая вражеских игроков из недавнего прошлого.
В итоге игрок видит себя в настоящем, а остальных игроков — в прошлом. Обычно это создает отличный игровой опыт.
Но если больше ничего не делать, иллюзия сломается когда события потребуют высокой пространственно-временной точности, например при выстреле.
Что такое интерполяция в играх
ex_interp – консольная переменная, которая отвечает за перемещение объектов, а точнее за нахождение точек, через которые этот объект проходит. Данная переменная является клиентской, и для обеспечения комфортной игры очень важно правильно её настроить. Начнём с того, что под названием переменной подразумевается слово «интерполяция». Интерполяция – это способ нахождения промежуточных значений величины по набору известных значений. Иными словами, у нас есть функция, и есть значения этой функции в определённых точках. Задачей интерполяции является восстановление значений функции в точках, расположенных между точками с известным значением.
Зачем интерполяция в Counter-Strike? Всё просто. Ваш клиент не может быть на 100% синхронизирован с сервером в каждый момент времени. А это значит, что вы не сможете получать абсолютно все обновления с сервера. Здесь приходит на помощь интерполяция. Сначала вы получаете от сервера один пакет с обновлениями, затем второй. На основании данных этих пакетов ваш компьютер выстраивает картинку на экране. Рассмотрим принцип работы переменной ex_interp на двух примерах.
Пример первый. На сервер поступает обновление от одного из игроков-клиентов (пусть роль игрока будет изображать контр-террорист), что моделька этого игрока находится в точке A1 и начинает движение
Пример второй. Допустим, вы играете с 100 fps и получаете от сервера порядка 30 обновлений в секунду. Таким образом, вам известна всего лишь треть истинной информации, оставшиеся две трети просчитываются вашим компьютером. Но вашему компьютеру нужно время, чтобы просчитать эти 70 кадров. Специально для этого вводится задержка в 100 миллисекунд (ex_interp 0.1) между получением информации и выводом её на экран. За эти 100 миллисекунд ваш компьютер выполнит все необходимые операции по просчёту необходимых координат и отрисовке кадров и выведет изображение на экран.
Теперь, зная принцип работы переменной ex_interp, мы приступим к её настройке. Чем ниже значение ex_interp, тем чаще будет происходить обновление местоположения игроков в пространстве. Стандартным значением переменной ex_interp является «0.1». В ранних версиях Counter-Strike (до 1.6) было возможно выставлять любое значение ex_interp вплоть до «0». Это вызвало много споров. Ведь фактически можно было видеть модельку игрока на некоторое время раньше, чем её видели другие игроки или другой игрок, играющий со стандартным значением переменной, видел вас.
Рассмотрим ситуацию, когда значение ex_interp установлено на «0.05». Время интерполяции снижается вдвое, т.е. до 50 мс. Следовательно, контуры будут приближаться друг к другу, причём движение контуров будет направлено в сторону синего контура (см. рис. ниже). Таким образом, мы сможем увидеть модельку в два раза раньше.В итоге, значение ex_interp теперь выставляется принудительно по формуле 1/cl_updaterate. Я рекомендую установить значение «0», таким образом, дав возможность движку игры самостоятельно выставить нужное значение (об этом будет свидетельствовать следующее сообщение в консоли: “ex_interp forced up to xx msec”).
0.1 — интерполяция происходит каждые 100 мс (реже); плавное передвижение моделей игроков; расположение модельки не соответствует реальному расположению хитбоксов (отстает).
0.01 — интерполяция происходит каждые 10 мс (чаще); в некоторых случаях возможны подергивания в передвижении моделей игроков; расположение модельки соответствует реальному расположению хитбоксов.
0.05 — интерполяция происходит каждые 50 мс; Это что-то среднее между значением 0.1 и 0.01.
0.05 Чаще всего ставят если появляются подергивания моделей игроков.
Откуда берутся подергивания моделей в одном случае и разность в расположении модели и хитбокосов в другом? Существует мнение (небезосновательное), что расположение моделек при игре по интернету отстает от реального расположения хитбоксов. Скорее всего это связано с тем, что игроки неодинаково синхронизированы с сервером вследствие разности пингов (т.е. у игроков разное время задержки при обмене данными с сервером). Помимо этого, игроки сами не всегда в полном объеме отправляют нужные серверу данные, и тогда уже самому серверу приходится выполнять интерполяцию.
За пример возьмем ситуацию, когда вы получаете от сервера 100 обновлений в секунду (cl_updaterate = 100 пакетов, п.; время = 1 с = 1000 мс).
ex_interp 0.1: 1/10 c = 100 мс (интерполяция происходит каждые 100 мс); 100 п/1000 мс = 0.1 п/мс = 1 пакет в 10 мс (один пакет обновления приходит каждые 10 мс); 0.1 п/мс*100 мс = 10 пакетов. Следовательно, интерполяция будет выполняться только на основании данных каждых десяти пакетов. Это означает, что ваш компьютер сумеет отрисовать более плавную картинку за счет большего количество данных, которые, к сожалению, успеют устареть (в данном случае на 100 мс). Этим объясняется отставание модельки от хитбоксов.
[FAQ]Итерполяция, лерп и его важность в играх.
23 Apr 2013 в 21:38
23 Apr 2013 в 21:38 #1
Не всем игрокам сообщества Dota 2 известен такой параметр как интерполяция (далее лерп), но игроки более ранних произведений валв знают важность этого параметра, начиная с counter-strike он был очень полезен для адаптации полученных пакетов к внутрисерверной среде, ведь как-то нужно сгладить полученные 30 пакетов и отобразить действие которое происходит между ними, это очень важный инструмент в сетевой игре, который помогает сглаживать движение и в какой-то мере предугадывать положение хитбокса на местности.
Естественно у этого параметра есть минус- время обработки, соответственно и увеличивает время отклика.
Наша задача уменьшить и минимализировать это время отклика.
Q: Какими командами изменять lerp?
A: Lerp изменяется двумя параметрами самого временного отрезка на интерполяцию и интервалом интерполяции cl_interp cl_interp_ratio
Q: Где можно посмотреть какой у меня сейчас lerp?
A: В консоли, вызвав параметр cl_interp или в net_graph .
Q: Можно ли как-то рассчитать для себя идеальный параметр lerp?
A: Можно, cl_interp_ratio\cl_updaterate= 1\30 = 0.033, но это минимальное значение, которое не применимо в обычной игре дома т.к. накладываются огрехи в виде пинга, тикрейта, нагрузки и работы самого сервера, оборудования, которое обеспечивает связь. По сути дела лерп можно еще уменьшить в два раза увеличив количество команд посылаемых от сервера cl_updaterate, но valve ограничили эту переменную на 30.
Q: Зачем это нужно?
A: Уменьшить время отклика, отсюда следует улучшение ластхит потенциала на таких героях как Razor или Sniper, у которых сам хит проходит немного позже анимации. Игра будет быстрее реагировать на ваши посланные команды. Хуки будут вылетать раньше, блинки кастоваться быстрее.
Q: Какие минусы возникают при уменьшении лерпа?
A: Как и плюсы- они минорные- уменьшая временной отрезок вы также и уменьшаете расстояние поражение хитбокса в движении. Это важно лишь для такого героя как Pudge или Clockwerk.
Дефолтный хитбокс в движении при lerp 0,066
Хитбокс при lerp 0,033
Q: Так может мне увеличить лерп что бы мой скилл попадания хуком стал 100% точным?
A: Это не значит, что при увеличении лерпа вы станете попадать 32\32 хуков, но во время уменьшенного лерпа точные хуки всегда попадают и вы сможите хукать даже сквозь еще «не убитого» крипа. http://youtu.be/C-3O0Y9xmiM?t=23s
https://www.youtube.com/watch?v=y0FGwk72fYk
Надеюсь что-то из описанного здесь оказалось для вас полезным, на вас работал Battle Roar, эксклюзивно для портала dota2.ru. Попрошу модераторов закрепить тему, дабы труд не был напрасным.
Кадровая интерполяция, а-ля 60фпс из ничего для игр?
Что знаете по этому поводу? Тв-шника с такой функцией у меня нет, но я бы хотел попробовать фейковые 60 фпс из 30-ти.
Есть ли какой-то софт по этому поводу?
Понятно, что будет инпут лаг и бла-бла-бла, но, просто, интересно попробовать.
В неспешных играх типа кроссинга вполне нормально работает, но в динамичных превращается в говно.
Ну там главное чтобы исходные 30фпс были стабильными, иначе каждая просадка будет прям сильно на нервы действовать, на фоне общей плавности. И на мой взгляд как раз в динамичных максимальный эффект, особенно в 2Д-играх, где всё движется «в плоскости экрана».
еще и графические артефакты к этому добавляются т.к. проц не успевает накинуть фантомных кадров
Я все-таки думаю такая штука будет полезна в играх, где частота кадра варьируется от 50-60, чтобы просадки не особо ощущались.
Вот заикнулись об этом и я подумкал тут. А фигли новым консолям ее не заиметь? Как бы ряд моделей тв имеют очень щедящий импут (дорогие Самсы, случайные модели ЛыЖек) и по факту это позволит разрабам схалтурить слегка на стабильности. При этом надо будет не с 30 кадров повышать до 120, а фактически с 40-50 до 60. Что-то подобное замутить будет не то чтобы сложно людям, которые делают тв(сони) и сотрудничают с самсунгом (майки). В теории это люто выгодная хня для синглплеерных проектов.
UPD ах да, в любом видео (фильмы/тв) известен следующий кадр, а в играх нет. попробуй-ка построй промежуточный кадр между текущим и следующим (который не известен), гений. ред.
Да и вообще, я говорил о развитии технологии и не уплавнении с 30 кадров. При работе с 45-50 кадрами и нынешние телевизоры сделают всё очень даже удобоваримо (если не дешевить, офк). А уж если целенаправленно пилить для одной консоли, а не штук 6 вариаций на каждый класс телевизора с их доп обработкой цветов, может выйти вполне себе ничего.
cl_interp — интерполяция в CS:GO
cl_interp уже не используется в кс го, и сейчас настройку интерполяции можно рассмотреть с помощью других команд. О них подробнее и поговорим…
Содержание
Интерполяция в CS:GO
Интерполяция может колоссально повлиять на ваш геймплей. Неправильные настройки могут делать вашу игру ужасной. Если у вас были моменты когда вы стреляете, но ничего не засчитывает, возможно это именно траблы с неверными настройками интерполяции. Вот вам яркий пример:
Все это происходит из-за пинга. Вы можете видеть противника на своем мониторе, но на самом деле он находится в другой позиции. Простыми словами мы видим прошлое, но в момент выстрела сервер говорит что там никого нет.
Для того чтобы избежать подобных разногласий между вами и сервером, разработчики придумали команду cl_lagcompensation. Данная команда компенсирует ту самую разницу в пинге. Если вы включите данную команду, наш компьютер будет отправлять доказательства на сервер, а именно что противник был у нас на прицеле
Сама же команда вводится в классической консоли с помощью ввода
cl_lagcompensation 1
Бывало ли у вас когда вы зашли за стену, но вас убивают?
Если ваш ответ — «да», то это от части действия этой команды. Например, вы спрятались за стенку, но у игрока у которого большой пинг, вы все еще на мониторе. Он убивает вас, ведь его компьютер отправил на сервер подтверждение. Также, на это влияет и ваш пинг, ведь информацию, что вы все таки спрятались за стенку, будет доставляться долго. Если все два этих фактора накладываются, случается нечто подобное. Но это лишь излишки, ведь реальная польза от компенсации гораздо больше.
Всегда перед стартом игры прописывайте в консоли:
Но давайте сперва разберемся — что же такое интерполяция?
cl_interpolate 0
cl_interpolate 1
Теперь посмотрим на движение модельки со включенной интерполяцией
Как можно увидеть модель двигается очень плавно, потому что, теперь работает рендеринг. И даже в случае если из-за интернета мы потеряем тик, моделька по-прежнему будет плавно двигаться. Чтобы погрузится в суть этого, нужно посмотреть на скрин ниже:
Вертикальные палочки визуализирую пакеты которые мы получаем с сервера (тики). Как можно понять, то что мы видим на своих экранах во время игры, на самом деле отстает на два тика, то есть мы видим прошлое. Это происходит, потому что интерполяция будет ждать, пока еще не придут два тика (пакета данных), чтобы на их основе давать плавные движения окружающих объектов в игре
Внимательно посмотрев на фото, можно увидеть что между промежутками тика у нас есть задержка. Мы расчесывали длину тика, разделив одну секунду на количество самих тиков. В обычном матчмейкинге их 64, по этому формула выглядит так: 1000/64=15.625 мс – это точная задержка когда мы играем в ММ
cl_interp_ratio
Но как мы уже говорили, интерполяция добавляет искусственную задержку — это прошлое. По этому она подождет еще два тика. И если мы удвоим все данные, реальная задержка будет выглядеть так: 15.625*2=31.25 мс.
Эта задержка добавляется что бы сделать игру плавной. Но ее можно регулировать в зависимости от нужд. Для этого в кс го есть команда cl_interp_ratio. К CS:GO есть лимит и мы можем выставить только два значения:
cl_interp
В прошлом использовать команда cl_interp, в ней можно было ввести задержку интерполяции в секундах.
ВАЖНО:
Но в поздних версиях Source, interp контролируется командой cl_interp_ratio. Дело в том что разработчики просто забыли удалить команду из игры и теперь она гуляет по различным гайдам в интернете и путает людей. Проверить данный факт и убедится своими глазами довольно просто:
Для теста cl_interp нужно вводить меню, когда вы находитесь на карте ничего не поменяется. Во время теста легко убедится, что ничего не меняется, чего и следовало ожидать.
Если после всего если вы думаете что нужно использовать cl_interp_ratio 1, думая что задержки лучше убрать, вы будете не правы.
И так:
В другом случае пользуемся такой шпаргалкой:
ПОЛЕЗНАЯ СТАТЬЯ: Пропал интернет? Горит « Подключение к сети кс го «
Ниже по ссылке есть таблица с собранной статистикой, где отчетливо видно как влияют те или иные настройки на игру:
Заметно что большинство кто играет с сl_interp_ratio 1 имеют значительную просадку в статистике по убийствам в эру интернет турниров. Может ли это означать, что настройки так сильно влияют на игрока остается пищей для размышлений, но подтверждений полно. Вот полная таблица выглядит таким образом.
Пользуйтесь проверенной информацией, ведь возможно она вам
поможет выйти на новый уровень игры.
Почта для связи
gocsgo.net@gmail.com