Что такое рассинхронизация в игре
Как избавиться от разрыва кадров и задержки ввода в играх
Разрыв кадров (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.
Вертикальная синхронизация V-Sync — что это, как работает и включать ли её?
Что такое вертикальная синхронизация?
Вертикальная синхронизация или же V-Sync представляет собой синхронизацию частоты кадров в играх с частотой развертки дисплея. Если функция V-Sync включена, то максимальное количество кадров в секунду будет строго ограничено частотой обновления вашего экрана.
Бывают ситуации, когда компьютер или ноутбук не может обеспечить показатель FPS, который будет равен частоте обновления монитора. В таких ситуациях рекомендуется активировать тройную буферизацию, если хочется задействовать V-Sync.
Как V-Sync работает в играх?
Вертикальная синхронизация способна влиять на производительность в компьютерных играх. В стандартном режиме ваша видеокарта будет максимально нагружена во время запуска очередной игрушки. Если речь идет о производительных комплектующих, то они будут работать в таком максимальном режиме вхолостую. При этом компьютер станет дополнительно нагреваться, а также потреблять огромное количество электроэнергии. С V-Sync ситуация кардинально меняется. Пользователь получает четкую картинку на своем мониторе, а, например, видеокарта функционирует не на всю мощь. Это не только экономит ее ресурс и ваши деньги, но и позволяет системному блоку гораздо меньше нагреваться, а также существенно снизить уровень шума.
Когда вертикальная синхронизация отключена, то в некоторых играх будут хорошо заметны своеобразные «рывки» и «Лесенки». Также возможно появление разнообразных артефактов. Все это действительно портит впечатление от игрового процесса. При включенной V-Sync ничего подобного уже не происходит. С помощью данной функции выравнивается и показатель FPS. Это отлично заметно, когда отключаешь данную синхронизацию. Тогда дерганная картинка сразу же бросается в глаза.
Почему же вообще появляются различные артефакты и рывки изображения? Здесь проблема кроется в видеокарте и мониторе, которые не могут обеспечить четкую синхронизацию в обычном режиме. Например, мощная видеокарта способна передать большое количество кадров в секунду. Но монитор имеет фиксированную скорость обновления. Естественно, появляется рассинхронизация, которая проявляется в виде искажений, рывков и прочих артефактов. И здесь приходит на помощь вертикальная синхронизация. В этом случае происходит опрос монитора на предмет имеющейся частоты развертки, а также копирования кадров в первичный буфер до обновления картинки. Благодаря этому изображение станет гладким, а артефакты уже не смогут досаждать вам во время игры.
Если же ваш монитор получил частоту развертки 60 Гц, а видеокарта может обеспечить уровень FPS в районе 40-60 к/с, тогда вертикальная синхронизация снижает количество кадров в секунду до 30. В обычных ситуациях FPS держится на уровне 60 к/с. Это нужно обязательно учитывать перед включением V-Sync.
Как включить или отключить вертикальную синхронизацию в любой игре?
Во многих современных играх V-Sync можно включить или отключить в настройках, в разделе «графика» или «видео», там же можно выставить разрешение, буферизацию, сглаживание и т.д. Такие настройки в основном доступны в самой игре, но иногда выскакивает окно настроек и перед самим запуском игры. Также существуют и такие проекты, которые очень странно работают с вертикальной синхронизацией, либо же и вовсе не дают пользователю возможность ее активировать. В такой ситуации правильнее будет обратиться к настройкам видеокарты, чтобы насильно отключить или включить V-Sync. Делается это через панель управления в драйверах, но для каждого производителя (NVIDIA, AMD) предусмотрены свои правила работы с синхронизацией по вертикали.
Как включить V-Sync на видеокартах семейства AMD Radeon?
Если у вас имеется видеокарта от AMD, тогда необходимо прямо на рабочем столе нажать правую кнопку мыши, а затем выбрать Catalyst Control Center. Откроется фирменная панель управления картой. Нас больше всего интересует раздел «Игры». Открываем его, а потом переходим в пункт «Настройки 3D-приложений». Появится специальное окно со списком, где можно принудительно управлять сглаживанием, частотой кадров, текстурной фильтрацией и прочим. Все это находится во вкладке «Системные параметры». Поэтому выбранные правила относятся ко всем без исключения приложениям. При этом во вкладке «Параметры приложения» можно настраивать функции под конкретную программу.
Если же в списке доступных приложений нет желаемой игры, то ее получится добавить с указанием пути к exe-файлу. Теперь нам остается отыскать в списке опцию «Ждать вертикального обновления». Здесь можно выбрать: всегда выключено, либо же включено.
Как включить V-Sync на видеокартах от семейства NVIDIA?
Когда речь заходит о видеокартах NVIDIA, то делается все по аналогии с картами AMD. Для манипулирования V-Sync необходимо открыть панель управления NVIDIA, а затем перейти во вкладку «Управление параметрами 3D». В окне появятся все доступные настройки, которые можно изменять по своему усмотрению. Здесь также есть «программные настройки» для каждой игры в отдельности, а также «Глобальные параметры». Так как нас интересует именно вертикальная синхронизация, то ищем ее в доступных настройках. Тут она называется «Вертикальный синхроимпульс».
Мы может включить или выключить V-Sync. Предлагается и третий вариант — использовать настройку трехмерного приложения.
Можно ли включить V-Sync на интегрированной видеокарте Intel HD Graphics, Vega?
Вертикальной синхронизацией можно управлять даже в случае со встроенной графикой Intel HD Graphics. Для интегрированного чипа также предусмотрена панель управления. Вызвать ее можно при помощи комбинации Ctrl + Alt + F12, либо же рабочего стола и правой клавиши мыши. Находим пункт «Трехмерная графика». Затем ставим галочку, чтобы активировать «Пользовательские настройки».
Здесь надо выбрать опцию «Синхронизация по вертикали». V-Sync получится включить или доверить самому приложению. К сожалению, полностью отключить функцию нельзя.
Стоит ли включать вертикальную синхронизацию или нет?
Если вас смущают и напрягают частые рывки картинки во время игры, а также внезапно появляющиеся артефакты, то вертикальную синхронизацию обязательно стоит включить. Более того, рекомендуется активировать V-Sync во всех однопользовательских игрушках. Это сделает изображение на мониторе действительно качественным. Но нельзя забывать, что среднее количество кадров в секунду должно превышать частоту развертки дисплея. В противном случае FPS упадет до минимального значения (например, 30 к/с). Что касается онлайн-игр, то здесь вертикальная синхронизация может только мешать из-за input lag, ведь даже мизерная задержка способна оказать существенное влияние на динамический игровой процесс. Но тогда придется мириться с различными дефектами изображения.
Синхронизация состояний в многопользовательских играх
Проблема многопользовательских игр
Одна из самых сложных задач многопользовательских игр заключается в синхронизации состояний всех игроков с состоянием сервера. В Интернете есть хорошие статьи по этой теме. Однако в них не достаёт кое-каких подробностей, что может сбивать с толку новичков в программировании игр. Надеюсь, что у меня получится объяснить всё в этой статье.
Я обозначу несколько техник, обычно используемых для решения таких задач. Прежде чем переходить к проблеме, давайте вкратце рассмотрим принцип работы многопользовательских игр.
Обычно программа игры должна симулировать следующее:
изменения в окружении с учётом времени и вводимых игроками данных.
Игра — это программа, хранящая состояние, поэтому она зависит от времени (реального или логического). Например, 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. Создав между ними буфер, можно разделить процесс их выполнения, что обеспечивает нам гибкость в создании более качественного игрового процесса.
Заключение
На этом заканчивается моя статья о многопользовательских играх. Многое по теме я узнал от специалистов в этой области, также мне очень помог пример простой многопользовательской игры. Я показал только один способ реализации многопользовательского сервера, есть и другие. Выбор подходящего зависит от типа создаваемой вами игры. Рекомендую вам изучить некоторые подходы, создав простую игру.
- Что такое стиль по русскому языку
- Что такое овуляционный пик