что такое рассинхрон в играх
Как избавиться от разрыва кадров и задержки ввода в играх
Разрыв кадров (screen tear) или задержка ввода (input lag)? Использовать ли vsync? Очень долгое время в мире игр для PC это был вопрос «или-или». Можно добиться или картинки без разрыва кадров, или низкой задержки ввода. Но невозможно получить и то, и другое. Или можно?
Ответ на этот вопрос неоднозначен. Если у вас уже есть современный игровой монитор с поддержкой переменной частоты обновления (FreeSync или G-Sync), то вам эта статья вообще не нужна. Но если у вас обычный монитор с постоянной частотой обновления или если вы любите играть в игры на телевизоре, то данная статья поможет вам снизить разрыв кадров и задержку ввода.
Используя ограничение кадров с миллисекундной точностью в RTSS (Rivatuner Statistics Server), можно обеспечить vsync с низкой задержкой. Что мы получим в результате? Чёткую картинку без разрывов кадров и задержку ввода на 50 мс меньше, чем при обычном vsync.
Это одно из тех немногих улучшений PC, которые могут значительно повысить удобство в играх с минимальными компромиссами и совершенно бесплатно. Что же это такое? И как этого добиться? В этой статье мы расскажем всё подробно и шаг за шагом.
Ужасный разрыв кадров с отключенным vsync
Что такое задержка ввода?
Прежде чем приступать к решению проблемы, неплохо бы понять, что конкретно мы будем делать. Vsync с низкой задержкой — это методика, позволяющая снизить задержку ввода. Что это означает? Когда вы печатаете на клавиатуре или перемещаете мышь, существует небольшая, почти неразличимая задержка между вашим действием и выводом на экран. Эта задержка настолько мала, что измеряется в миллисекундах. Если вы используете компьютер для чтения Интернета или казуальных игр, это не влияет на процесс ощутимым образом.
Однако в напряжённых ситуациях, например, в киберспортивных шутерах, важна каждая миллисекунда. Несколько миллисекунд задержки ввода могут решить судьбу хедшота или смерти вашего героя.
У всех мониторов (и телевизоров) по умолчанию добавляется определённая величина задержки ввода. Обычно она зависит от типа используемой панели. Панели IPS и TN с высокой частотой обновления по умолчанию обеспечивают наименьшую задержку ввода. У некоторых мониторов она составляет всего 0,5 мс. Панели VA обычно имеют задержку ввода побольше, у многих она достигает 8-10 мс. Телевизоры (в которых часто используют панели VA) обычно проявляют себя хуже всего, у некоторых задержка составляет до 30 мс или даже больше.
Когда vsync отключен, GPU компьютера отправляет отрендеренные кадры на дисплей с максимально возможной скоростью. Так как скорость вывода кадров на дисплей ограничена (у дисплеев с частотой 60 Гц это один кадр раз в 16,66 мс), разрыв кадров происходит, когда новый кадр прибывает до того, как с экрана пропал предыдущий.
Когда включен традиционный vsync, GPU больше не может заменять содержимое буфера монитора новым кадром, прежде чем старый кадр не получит свои 16,66 мс славы. Это означает, что каждый кадр удаётся отобразить полностью и устранить разрыв кадров. Однако это заставляет GPU составлять очередь из кадров, а не отправлять их максимально быстро.
Из-за создания очереди традиционный vsync может добавлять до 50 мс задержки вдобавок к стандартной задержке дисплея. Здесь на сцене появляется vsync с низкой задержкой.
С помощью vsync с низкой задержкой (low-lag vsync) мы, по сути, ограничиваем частоту кадров (скорость, с которой GPU передаёт кадры) числом, которое слегка ниже частоты обновления монитора. Это мешает GPU отправлять новые кадры до того, как монитор будет готов их выводить. Что мы получим в результате? Игру без разрывов кадров и почти такой же задержкой, как и при отключенном vsync. Теперь поговорим о том, как этого достичь…
Что нам понадобится
Прежде чем приступать, вам нужно скачать последнюю версию Rivatuner Statistics Server (RTSS). Также вам понадобится подключение к Интернету, чтобы перейти на эти две страницы для запуска тестов:
Приступаем к работе
Первым делом нам нужно определить истинную частоту обновления монитора. Если у вас дисплей на 60 Гц, то она, вероятно, очень близка к 60, но отличается на несколько сотых секунды. Используйте или UFO Refresh Rate Test, или vsync Tester. Если у вас есть свободное время, то запустите оба и проверьте, совпадают ли значения.
Чтобы протестировать частоту обновления вашего монитора, закройте все остальные вкладки браузера и все фоновые процессы, а затем подождите от 30 секунд до 1 минуты. Тестовая страница покажет частоту обновления вашего дисплея с точностью до нескольких десятичных разрядов. Для следующего шага округлите их до трёх цифр.
Используем UFO Test для определения истинной частоты обновления
Установка и запуск Rivatuner
После установки Rivatuner запустите программу с правами администратора. Затем нажмите на зелёную кнопку «Add» в левом нижнем углу. Перейдите в папку, где установлена нужная игра. (Стоит учесть, что можно задать параметры и глобально, но мы предпочитаем настраивать их индивидуально для каждой игры).
Выберите исполняемый файл игры, а затем добавьте его в Rivatuner.
Добавляем новую игру в RTSS
Вычисляем величину ограничения кадров
Возьмите частоту обновления с тремя знаками после запятой и вычтите из неё 0,01. Например, если ваша частота обновления равна 60,001, то ограничение кадров будет равно 59,991.
В левой части интерфейса Rivatuner выберите игру. Затем введите значение ограничения частоты кадров в поле рядом с Frame rate limit. Так мы ограничили частоту кадров игры значением ниже частоты обновления монитора. Возможно, с этим значением придётся немного поэкспериментировать. Некоторые игры более чувствительны к ограничению кадров, чем другие: если вы замечаете сильное дрожание, то попытайтесь увеличивать ограничение частоты кадров с инкрементом 0,002.
Включение vsync и запуск
Запустите игру, а затем включите vsync в её настройках. Если вы не можете этого сделать, то включите принудительный vsync на уровне драйвера из панели управления AMD или Nvidia. Вот и всё!
После включения vsync с низкой задержкой вы получите значительно лучшую задержку ввода без разрыва кадров. Однако существуют тонкости, на которые стоит обратить внимание. Vsync с низкой задержкой лучше всего работает, если ваша система способна устойчиво работать с частотой выше частоты кадров монитора. Если она достигает отметки только в 60 FPS, то включение этой функции может вызвать дополнительные рывки при снижении частоты кадров.
Scanline sync: ещё более удобная альтернатива
Если вы не хотите экспериментировать с дробными ограничениями частоты кадров, то у RTSS есть альтернатива: scanline sync. Синхронизация строк развёртки (Scanline sync) позволяет управлять тем, где на экране происходит разрыв кадров с отключенным vsync.
Как это поможет? Разрыв кадра отображается как одна строка, которую мы сможем переместить на край экрана, в самый верх или низ, где он, по сути, исчезнет. Для включения scanline sync нужно отключить ограничение частоты кадров, задав в RTSS Framerate limit равным 0 и отключив внутриигровой или драйверный vsync.
Теперь решим, где мы хотим разместить строку развёртки. Можно с этим поэкспериментировать, но в идеале стоит взять вертикальное разрешение монитора (1440, если это монитор 1440p), а затем вычесть 10-20. Введите это число в поле Scanline Sync. S-Sync часто обеспечивает даже меньшую задержку ввода, чем vsync с низкой задержкой.
Однако для оптимальной работы потребуется мощная система (или не очень требовательная игра). В играх, где уровень загрузки GPU постоянно выше 80 процентов, S-Sync не имеет достаточной производительности для удерживания линии разрыва на одном месте, что может вызвать значительные рывки.
Эмпирическое правило: используйте S-Sync для не очень требовательных игр, в которых средняя частота кадров может быть значительно выше 60 FPS. Vsync с низкой задержкой следует использовать в играх, которые работают близко к 60 FPS.
Беспроблемная настройка
Некоторые способы настройки производительности PC могут обладать эффектом плацебо или иметь издержки, как, например, в случае с масштабированием разрешения. Но в случае vsync с низкой задержкой вы на самом деле получаете более качественный игровой процесс без всяких компромиссов. Если у вас есть дополнительный ресурс производительности, но вы играете не на игровом мониторе с VRR, то включенный low-lag vsync может изменить ощущения от шутеров и соревновательных игр, в то же время избавив от разрыва кадров.
Для этого не требуется специальное оборудование, а из ПО нужен только RTSS. Если последуете нашим инструкциям, то сможете заметить значительное снижение задержки ввода и повышение отзывчивости во всех ваших играх.
На правах рекламы
Поиграть — всегда хорошо, но иногда и работать нужно. Эпичные серверы — прекрасный вариант не только для работы, а и для размещения игровых серверов. Вы можете выбрать абсолютно любую ОС или установить систему со своего ISO.
Что такое рассинхрон?
Очень часто все проблемы в игре списывают на рассинхрон
Кто может объяснить, что это такое?
Очень часто все проблемы в игре списывают на рассинхрон
Кто может объяснить, что это такое?
Звезда форума и рендома
У тебя на мониторе Танк врага находится в одном месте. А по факту, на сервере, он проехал уже немного дальше. Но из-за потери пакетов ты этого еще не видишь.
Отсюда и пролетание снарядов сквозь танк. Ты стреляешь якобы в танк. Но его там уже нет.
В общем картинка запаздывает, скажем так.
разница между тем, что ты видишь на мониторе и тем что сейчас «видит» и просчитывает сервер WOT. чем больше пинг тем больше рассинхрон
Очень часто все проблемы в игре списывают на рассинхрон
Кто может объяснить, что это такое?
Рассинхронизация происходит между происходящим в игровом клиенте (Ваш танк едет) и данными, отправляемыми на сервер (на сервере танк еще едет в квадрате А, а в игре он уже на квадрате В, например). Это вызвано лагами на серверами, проблемами с интернетом у Вас, либо загруженностью интернет-канала (не качайте торренты во время игры).
или http://forum.worldoftanks.ru/index.php?/topic/990631-%D1%80%D0%B0%D1%81%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD/
Синхронизация состояний в многопользовательских играх
Проблема многопользовательских игр
Одна из самых сложных задач многопользовательских игр заключается в синхронизации состояний всех игроков с состоянием сервера. В Интернете есть хорошие статьи по этой теме. Однако в них не достаёт кое-каких подробностей, что может сбивать с толку новичков в программировании игр. Надеюсь, что у меня получится объяснить всё в этой статье.
Я обозначу несколько техник, обычно используемых для решения таких задач. Прежде чем переходить к проблеме, давайте вкратце рассмотрим принцип работы многопользовательских игр.
Обычно программа игры должна симулировать следующее:
изменения в окружении с учётом времени и вводимых игроками данных.
Игра — это программа, хранящая состояние, поэтому она зависит от времени (реального или логического). Например, PACMAN симулирует окружение, в котором постоянно перемещаются призраки.
Многопользовательская игра не является исключением, однако из-за взаимодействия игроков её сложность намного выше.
Возьмём, например, классическую игру «Змейка»:
Предположим, что мы используем клиент-серверную архитектуру. Игровая логика работает следующим образом:
Простейший клиент считывает обновления сервера и рендерит каждый полученный кадр для игрока.
Обновление состояния с фиксированным шагом
Концепция
Для обеспечения синхронизации всех клиентов проще всего сделать так, чтобы клиент отправлял серверу обновления с фиксированным интервалом. Для примера возьмём интервал в 30 миллисекунд. Обновление содержит введённые пользователем данные, которые могут также содержать значение нет вводимых пользователем данных.
Получив вводимые данные от всех пользователей, сервер может перейти к следующему такту с учётом этих данных.
На рисунке выше показано взаимодействие одного клиента с сервером. Надеюсь, проблема для вас настолько же очевидна, как и для меня: клиент может простаивать на интервале от T0 до T1, ожидая для продолжения обновления с сервера. В зависимости от качества сети задержка может меняться в пределах от 50 до 500 мс, а современные игроки замечают задержки более 100 мс. Поэтому торможение интерфейса пользователя на 200 мс будет для некоторых игр огромной проблемой.
Это не единственная сложность подхода с фиксированным интервалом.
Рисунок выше немного более сложен, он демонстрирует взаимодействие с сервером нескольких клиентов. Видно, что у клиента B более медленное сетевое подключение, поэтому хотя A и B отправляют на сервер вводимые данные в T0, обновление от B достигает сервера в T2, а не в T1. Поэтому сервер продолжает расчёт только тогда, когда получит все обновления, то есть в T2.
Что это значит?
Задержка игры теперь равна задержке самого «лагающего» игрока.
Получается, что мы наказываем всех игроков потому, что у одного из них медленное соединение. Поэтому рано или поздно все игроки уйдут из вашей игры…
Не говоря уже о том, что есть вероятность отсоединения клиента B, которая заблокирует действия сервера до истечения таймаута соединения.
Обсуждение
Кроме двух вышеупомянутых проблем, есть ещё несколько:
Для медленных игр небольшая задержка тоже приемлема. Хорошим примером может служить Farm Ville.
Ещё один хороший пример — шахматы, в которых два игрока ходят по очереди и каждый ход длится около 10 секунд.
Прогнозирование клиента
Давайте сначала решим проблему отклика игрока. Игра реагирует через 500 мс после того, как игрок нажал на кнопку, из-за чего игровой процесс рушится.
Как решить эту проблему?
Концепция
Кое-кто из читателей уже знает ответ: вместо ожидания обновления сервера клиент на самом деле эмулирует игру, выполняя игровую логику локально (т.е. на машине клиента).
Предположим, для расчёта состояния игры в Tn нам нужно знать состояние в Tn-1 и введённые пользователем в Tn-1 данные.
Идея проста: давайте сделаем фиксированную скорость обновления, которая в нашем примере равна одной единице времени.
Клиент отправляет вводимые данные на сервер в T0 для эмуляции состояния игры в T1, поэтому клиент затем может рендерить игру, не ожидая обновления состояния от сервера, которое будет получено только в T3.
Такой подход работает только в следующих условиях:
На рисунке выше клиент A всё ещё пытается эмулировать состояние игры в T1 с помощью информации, полученной в T0, но клиент B в T0 уже отправил вводимые данные, о которых не знает клиент A.
Это значит, что прогноз клиента A о T1 будет ошибочным. К счастью, поскольку клиент A по-прежнему получает состояние T1 от сервера, он имеет возможность исправить свою ошибку в T3.
Стороне клиента необходимо выяснить, была ли верной предыдущая эмуляция, и как можно разрешить конфликты.
Разрешение конфликтов обычно называется согласованием (Reconcilation).
Реализация согласования зависит от конкретных условий использования. Я покажу простейший пример, в котором мы просто откажемся от прогнозирования и заменим его точным состоянием, получаемым от сервера.
Есть способы справиться с этой проблемой, но они не будут рассмотрены в этой статье.
Обсуждение
Техники прогнозирования на стороне клиента имеет огромное преимущество: клиент работате с собственной частотой обновления (независимой от частоты обновления сервера), поэтому когда сервер «тормозит», то это не влияет на частоту кадров на стороне клиента.
Но это неизбежно связано с определённой сложностью:
Заключение
В этой части мы рассмотрели всего два способа реализации сетевого соединения в многопользовательских играх:
Интересные статьи по теме
Какова роль сервера?
Давайте начнём с определения действий сервера. Типичные задачи сервера:
а) Соединительная точка для игроков
В многопользовательской игре игрокам нужна общая конечная точка для связи друг с другом. Это одна из ролей серверной программы. Даже в модели связи P2P присутствует соединительная точка для обмена сетевой информацией для установки соединения P2P.
б) Обработка информации
Во многих случаях сервер выполняет код симуляции игры, обрабатывает все вводимые игроками данные и обновляет состояние игры. Стоит учесть, что так бывает не всегда: некоторые современные игры перекладывают большую часть обработки на сторону клиента. В этой статье я буду считать, что именно сервер несёт ответственность за обработку игры, т.е., например, за создание тактов игры.
в) Единый источник истинного состояния игры
Во многих многопользовательских играх серверная программа также имеет власть над состоянием игры. Основная причина этого — защита от читерства. Кроме того, гораздо легче ориентироваться, когда есть единственная точка для получения правильного состояния игры.
Наивная реализация сервера
Давайте начнём реализацию сервера самым прямолинейным способом, а затем усовершенствуем его.
Ядром игрового сервера является цикл, выполняющий обновление GameState на основании вводимых пользователями данных. Этот цикл обычно называется TICK (такт) и обозначается следующим образом:
Упрощённый сниппет кода сервера может выглядеть так:
Обсуждение
Надеюсь, сниппет кода выглядит для вас интуитивно понятным и прямолинейным: сервер просто принимает вводимые данных из буфера и применяет их в следующей функции TICK для получения нового состояния GameState. Давайте назовём этот подход жадным игровым циклом, потому что он пытается обработать данные как можно быстрее. Это нормально, если не задумываться о нашей несовершенной Вселенной, в которой солнечный свет достигает Земли за восемь минут.
Здесь снова становится важной задержка.
Тот факт, что сервер обрабатывает вводимые данные из буфера каждый TICK означает, что GameState зависит от задержки сети. На схеме ниже показано, почему это становится проблемой.
На схеме показаны два клиента, отправляющие вводимые данные серверу. Мы видим два интересных факта.
Непостоянная задержка в сочетании с жадным игровым циклом приводят к нескольким проблемам. Мы рассмотрим их ниже.
Не работает прогнозирование на стороне клиента
Игроки с низкой задержкой получают преимущество
В следующем разделе мы поговорим о том, как заставить сторону сервера работать в быстрых играх.
Согласование на сервере
Для решения проблемы неточного прогнозирования на стороне клиента нам нужно сделать клиент-серверное взаимодействие более предсказуемым с точки зрения клиента. Когда игрок нажимает клавишу на стороне клиента, то клиентская программа должна знать, когда эти вводимые данные будут обработаны на стороне сервера.
Один возможный способ реализации этого — позволить клиенту предлагать, когда необходимо применить вводимые данные. Таким образом, сторона клиента сможет точно предсказывать время их применения. Термин «предлагать» использован, потому что сервер может отклонить это предложение, если оно неверно, например, игрок пытается произнести заклинание, хотя у него закончилась мана.
Вводимые данные должны применяться почти сразу после ввода данных игроком, например, Tinput+ X, где X — задержка. Точное значение зависит от игры, для отзывчивости обычно необходима задержка менее 100 мс. Заметьте, что X может быть и нулём. В таком случае данные применяются сразу же после ввода пользователем.
Давайте примем X = 30 мс, что примерно равняется одному кадру при 30 кадрах в секунду. Для передачи на сервер данным требуется 150 мс, тогда существует большая вероятность того, что когда вводимые данные достигнут сервера, кадр для ввода уже будет пропущен.
Посмотрите на схему: пользователь A нажал клавишу в T. Эти данные должны обработаться в T + 30 мс, но вводимые данные из-за задержки получены сервером в T + 150 мс, что уже находится за пределами T + 30 мс. Решением этой проблемы мы займёмся в данном разделе.
Как сервер применяет вводимые данные, которые должны были случиться в прошлом?
Концепция
Вы наверно помните, что прогнозирование на стороне клиента имело ту же проблему с неточными прогнозами из-за недостатка информации о противниках. Неверные прогнозы позже корректировались обновлениями состояния с сервера с помощью согласования. Ту же технику можно использовать здесь. Единственная разница в том, что мы исправляем GameState на сервере на основе данных, вводимых клиентами.
Все вводимые пользователями данные должны иметь метки времени. Эти метки используются для того, чтобы сообщить серверу, когда их нужно обрабатывать.
Примечание: на первой пунктирной линии Time X на стороне клиента, но Time Y на стороне сервера. Это интересная особенность многопользовательских игр (и многих других распределённых систем): поскольку клиент и сервер работают независимо, время на клиенте и на сервере обычно отличается. Наш алгоритм позволяет справиться с этой разницей.
На схеме выше показано взаимодействие между одним клиентом и сервером.
Подробности согласования (красное поле)
Обсуждение
Согласование на стороне сервера страдает от тех же проблем, что и согласование в клиенте. Когда нужно согласование, значит, мы сделали что-то не так, и мы исправляем ошибку, меняя историю. Это значит, что мы не можем применить необратимые последствия, например, убийство игроков. Такие необратимые последствия можно применять только когда они поступают из GameStateHistory, т.е. когда их больше нельзя перезаписывать.
Кроме того, неверные GameState иногда приводят к ужасным скачкам UI. На схеме ниже показано, как это происходит.
Объект сначала находится в левом верхнем углу и двигается вправо. Спустя пять таков он смещается вправо, но затем сервер получает введённые пользователем данные, сообщающие, что объект изменил направление в Tick N, поэтому сервер согласует состояние игры. При этом объект внезапно перескакивает в левый нижний угол экрана.
Возможно, я преувеличиваю это влияние, иногда объект двигается не так далеко и скачок менее заметен, но во многих случаях он всё равно очевиден. Мы можем контролировать скачки, меняя размер GameStateHistory, UnprocessedUserInput и ProcessedUserInput. Чем меньше размер буфера, тем меньше будут скачки, потому что мы будем менее терпимы к сильно запаздывающим вводимым данным. Например, если вводимые данные запаздывают более чем на 100 мс, то они игнорируются, а игрок с пингом > 200 мс не сможет играть в игру.
Мы можем пожертвовать толерантностью к задержкам сети для более точного обновления состояния игры, или наоборот.
Есть одна популярная техника для борьбы с проблемой неточных Game State — это интерполяция объектов (Entity Interpolation). Идея заключается в сглаживании скачков растягиванием их на короткие промежутки времени.
В этой статье я не буду описывать подробности реализации интерполяции объектов, однако приведу полезные ссылки в конце.
Подводим итог
Мы обсудили способы работы клиентов и сервера в многопользовательских играх.
В целом, многопользовательская игра содержит три свободно соединяемых цикла: серверный игровой цикл, клиентский цикл прогнозирования и клиентский цикл рендеринга UI. Создав между ними буфер, можно разделить процесс их выполнения, что обеспечивает нам гибкость в создании более качественного игрового процесса.
Заключение
На этом заканчивается моя статья о многопользовательских играх. Многое по теме я узнал от специалистов в этой области, также мне очень помог пример простой многопользовательской игры. Я показал только один способ реализации многопользовательского сервера, есть и другие. Выбор подходящего зависит от типа создаваемой вами игры. Рекомендую вам изучить некоторые подходы, создав простую игру.
- Олтуга что нужно для поступления
- исполнительный лист с какого момента удерживать