Обновлено: 23 июня 2026 г. в 01:45

Real-time Gaming

средний

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

Бэкенд многопользовательской игры в реальном времени живёт в мире миллисекунд: задержка, колебания канала и короткие обрывы связи здесь ощущаются сразу, а не прячутся за ретраями.

Глава собирает в одну систему подбор матча, авторитетную симуляцию, размещение игровых сессий по регионам, доставку обновлений состояния и восстановление после разрыва соединения.

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

Бюджет задержки

Каждый лишний переход на пути от ввода до действия сразу ощущается игроком, поэтому задержку нужно раскладывать по этапам, а не держать одной общей цифрой.

Региональный матчмейкинг

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

Авторитетная симуляция

Сервер должен оставаться источником истины для состояния матча, иначе отзывчивость быстро превратится в читы и расхождение между клиентами.

Восстановление сессии

Короткий обрыв связи не должен выбрасывать игрока из матча: заранее проектируйте окно переподключения, снимки состояния и быстрый досинхрон.

Источник

Gaffer On Games

Классические материалы о сетевой архитектуре многопользовательских игр и синхронизации состояния.

Открыть

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

Требования

Функциональные

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

Нефункциональные

Задержка: p95 < 80ms

Задержка от ввода до действия должна оставаться низкой и предсказуемой.

Частота тиков: 20-60 TPS

Цикл симуляции должен быть стабильным, чтобы игра ощущалась честной и ровной.

Доступность: 99.99%

Матч не должен разваливаться из-за отказа одного узла или зоны.

Честность: защита от читов и злоупотреблений

Сервер проверяет действия игроков, а клиент не считается источником истины.

Оценка масштаба

Одновременных игроков:1M
Игроков в матче:10-100
Активных матчей:~20-100K
Трафик на игрока:~10-50 KB/s

Каждый матч — это отдельный процесс симуляции с жёстким на кадр: при 60 тиках в секунду на всю симуляцию остаётся ~16.7 мс, при 128 тиках — всего 7.8 мс. Поэтому масштабирование здесь — это не «больше реплик за балансировщиком», а управление парком из десятков тысяч независимых игровых серверов.

Высокоуровневая архитектура

Архитектура игры и сценарии

Авторитетная многопользовательская модель с интерактивными путями выполнения
Маршрут сценарияВся схема
1Игровые клиенты
2Пограничный шлюз
3Координатор сессий
4Игровой сервер
5Кэш состояния
6Поток событий
7Аналитика и рейтинг

Доступ и управляющий контур

Клиенты -> шлюз -> сессия
вход, транспорт и маршрутизация
Авторизация -> подбор матча
токен, MMR, регион и лобби

Игровой и событийный контур

Сервер -> кэш -> события
тик симуляции, снимки и дельты
Профиль, рейтинг и аналитика
метаданные сессии и итоги матча
запись
сохранение метаданных сессии
события
запись итогов событий
Базовая архитектура многопользовательской игры: управляющий контур готовит матч, игровой контур ведёт симуляцию, а аналитический хвост забирает итоговые события.
Выберите сценарий сверху, чтобы подсветить путь через архитектуру и посмотреть ключевые шаги выполнения.

Главный принцип: цикл симуляции изолирован от медленных внешних операций. Один синхронный запрос к БД внутри тика срывает бюджет кадра для всех игроков матча, поэтому тяжёлую логику выносят в асинхронный контур вне критического пути.

Клиентское предсказание и серверное согласование

GDC 2017

Overwatch Gameplay Architecture and Netcode

Доклад Тима Форда о серверной авторитетности, предсказании и откатах в Overwatch.

Смотреть

При времени прохождения туда и обратно (RTT) в 60-100 мс наивная схема «нажал — отправил — подождал ответ сервера — подвинулся» делает управление ватным: игрок замечает разрыв между нажатием и движением уже при задержке около 100 мс. Поэтому клиент применяет ввод немедленно и локально, не дожидаясь сервера, — а сервер остаётся единственным источником истины и позже подтверждает или исправляет результат.

Цикл предсказания

  1. Клиент применяет ввод сразу к локальной симуляции и кладёт его в буфер неподтверждённых вводов с порядковым номером.
  2. Тот же ввод уходит на сервер, который прогоняет его через авторитетную симуляцию.
  3. Сервер отвечает подтверждённым состоянием и номером последнего обработанного ввода.
  4. Клиент сравнивает серверное состояние со своим предсказанием на тот же номер ввода.
  5. При расхождении клиент делает к серверному состоянию и за один кадр заново прогоняет все ещё не подтверждённые вводы из буфера (re-simulation).

Почему это стандарт для шутеров

  • Overwatch по умолчанию предсказывает всё: движение, способности и оружие — команда явно отключает предсказание только для отдельных эффектов вроде крупных видимых снарядов.
  • Предсказывать безопасно только детерминированную локальную часть состояния: собственное движение, анимации, перезарядку.
  • Результаты, которые задевают других игроков — урон, смерть, захват цели, — клиент не объявляет сам: их подтверждает только сервер.

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

Снимки состояния, дельта-компрессия и тикрейт

Источник

Quake 3 Network Model

Разбор сетевой модели Quake 3: снимки, дельта-компрессия против последнего подтверждённого состояния.

Открыть

Сервер рассылает клиентам мира с частотой тикрейта. Слать полный мир каждый тик нельзя: снимок матча на 100 сущностей занимает единицы килобайт, и при 60 тиках в секунду это сотни килобайт в секунду на каждого игрока. Классическое решение из Quake 3 — дельта-компрессия: сервер хранит историю снимков по каждому клиенту и отправляет только разницу относительно последнего снимка, который клиент подтвердил.

Как работает дельта-цикл

  1. Подтверждения клиента ездят в обычном входящем трафике, без отдельных запросов.
  2. Сервер кодирует новый снимок как разницу против последнего подтверждённого: только изменившиеся поля изменившихся сущностей.
  3. Если подтверждение потерялось, сервер просто считает дельту от более старого снимка — повторных передач и блокировок нет.
  4. Если клиент отстал слишком сильно, сервер отправляет полный снимок и цикл начинается заново — это же спасает при переподключении.

Интерполяция и экстраполяция

  • Клиент рендерит чужих игроков в прошлом: он буферизует два-три снимка и плавно интерполирует между ними. В движке Source это окно по умолчанию равно 100 мс.
  • Если очередной снимок не пришёл, клиент экстраполирует движение по последней скорости (dead reckoning) — короткая потеря пакета остаётся незаметной.
  • Долгая экстраполяция опасна: предсказанная траектория расходится с реальной, и персонажей начинает «телепортировать» при следующем снимке.

Тикрейт: бюджет кадра против стоимости

ТикрейтБюджет кадраГде встречаетсяЦена
20-30 Hz33-50 мсBattle royale и большие миры с 100+ игрокамиДешёвые серверы, но заметнее задержка регистрации попаданий
60-64 Hz~16 мсOverwatch (16 мс на командный кадр), CS2Баланс отзывчивости и стоимости для матчей 10-12 игроков
128 Hz7.8 мсValorant, киберспортивные конфигурацииЖёсткая оптимизация: Riot уложила кадр сервера в ~2.6 мс, чтобы плотнее упаковать матчи на ядро

Компромисс прозрачный: удвоение тикрейта почти удваивает CPU-стоимость каждого матча и трафик, но уменьшает интервал между подтверждениями и делает более гранулярной. Поэтому тикрейт выбирают от жанра: тактическому шутеру нужны 64-128 тиков, а кооперативной игре на 4 человека хватает 20-30.

Interest management: кому какую часть мира слать

Дельта-компрессия сокращает размер пакета, но не количество получателей. Если каждый из 100 игроков должен знать о каждом, сервер рассылает порядка 100 × 99 обновлений на тик — при 30 тиках это сотни тысяч записей в секунду, классическая проблема . Interest management решает её: каждый клиент подписан только на ту часть мира, которая ему действительно видна и важна.

Механика area of interest

  • Мир режется на ячейки — на равномерной сетке или quadtree, если плотность игроков сильно неравномерна.
  • Клиент подписан на свою ячейку и соседние; при движении подписки переезжают, а гистерезис на границе ячеек гасит дребезг подписаться-отписаться.
  • В снимок клиента попадают только сущности из его зоны интереса: вместо 99 игроков — ближайшие 10-20, и стоимость рассылки растёт почти линейно, а не квадратично.
  • Quake 3 делал то же самое через потенциально видимое множество (potentially visible set): сервер хранил историю снимков по каждому клиенту и сериализовал только видимое ему подмножество состояния.

Компромиссы и побочные эффекты

  • Слишком мелкие ячейки — высокий churn подписок при движении; слишком крупные — лишний трафик. Размер подбирают от скорости перемещения и дальности обзора.
  • Снайперские прицелы, миникарты и звуки выстрелов ломают простую геометрию зоны: для них нужны отдельные правила интереса с другим радиусом.
  • Бонус для честности: если позиции врагов за стеной вообще не приходят на клиент, wallhack-читам нечего показывать. Фильтрация по видимости — это и оптимизация, и защита.

Компенсация задержки: перемотка мира при проверке попаданий

Valve

Source Multiplayer Networking

Каноническое описание интерполяции, предсказания и компенсации задержки в движке Source.

Открыть

Из-за интерполяции стрелок целится не в актуальное состояние мира, а в картинку из прошлого: интерполяционное окно плюс сетевой путь до сервера легко дают 100-150 мс отставания. Если сервер проверит попадание по текущим позициям, идеально наведённые выстрелы будут «проходить сквозь» цель. Поэтому соревновательные шутеры применяют компенсацию задержки по принципу favor the shooter — «правда на стороне стрелка».

Механизм перемотки

  1. Сервер хранит кольцевой буфер позиций и хитбоксов всех игроков за последнюю секунду.
  2. Получив выстрел, сервер вычисляет момент, который видел стрелок: текущее время минус сетевая задержка пакета минус интерполяционное окно клиента — формула из движка Source.
  3. Хитбоксы целей перематываются в это прошлое, и попадание проверяется там.
  4. После проверки мир возвращается в актуальное состояние, урон применяется уже в нём.

Цена favor the shooter

  • Жертва иногда получает урон уже «за укрытием»: с её точки зрения она спряталась, но в перемотанном прошлом стрелка ещё была видна.
  • Окно перемотки ограничивают сотнями миллисекунд: игрок с огромным пингом не должен стрелять в слишком далёкое прошлое, иначе компенсация превращается в эксплойт с искусственной задержкой.
  • Альтернатива favor the victim (не компенсировать) честнее для жертвы, но требует от стрелка упреждения на величину пинга — для массового продукта это хуже.

Компенсация работает только при авторитетном сервере: клиент сообщает «я выстрелил в такой-то момент», но решение о попадании, уроне и боезапасе принимает сервер, сверяя скорострельность, патроны и физическую достижимость позиции. Любая проверка, отданная клиенту, рано или поздно становится читом — от aimbot до телепортов через speedhack.

Матчмейкинг и жизненный цикл игрового сервера

Источник

Agones

Открытая платформа Google Cloud и Ubisoft для размещения и масштабирования игровых серверов поверх Kubernetes.

Открыть

Подбор матча и выделение сервера — это конвейер с собственными компромиссами: чем дольше игрок ждёт, тем шире система готова трактовать «подходящий» матч и по рейтингу, и по задержке.

Путь от кнопки «Играть» до первого тика

  1. Клиент измеряет до региональных точек присутствия и прикладывает результаты к заявке вместе с рейтингом и режимом.
  2. Заявка попадает в очередь матчмейкера; допустимые окна по рейтингу и задержке расширяются по мере ожидания — это и есть управляемый компромисс между качеством матча и временем в очереди.
  3. Для собранной группы выбирается регион с приемлемым для большинства и запрашивается сервер из тёплого пула — аллокация занимает секунды, потому что процессы уже подняты.
  4. Игроки получают адрес сервера и одноразовый токен сессии; сервер сверяет токены, дожидается подключений и запускает матч.
  5. После матча сервер сбрасывает результаты в персистентный контур — рейтинги, статистику, экономику — и либо возвращается в пул, либо завершается, освобождая место новому.

Управление парком серверов

игровых серверов — отдельный класс инфраструктуры со своими готовыми решениями.

  • Agones — открытый проект Google Cloud и Ubisoft: ресурсы GameServer и поверх , защита подов с активными игроками от вытеснения и проверка работоспособности через лёгкий SDK.
  • Amazon GameLift — управляемый аналог: размещение по регионам, очереди аллокаций и FleetIQ для экономии на спотовых инстансах.
  • В обоих случаях ключевое отличие от веб-нагрузки: сервер с живым матчем нельзя убить при сокращении парка — он хранит состояние матча до последнего игрока.

Масштабирование под пики

парка работает не так, как у обычных веб-сервисов.

  • Метрика масштабирования — не CPU, а буфер готовых серверов: «держать N свободных процессов в каждом регионе» с прогнозом по времени суток и анонсам событий.
  • Скейлинг вниз — дренаж: узел перестаёт получать новые матчи и ждёт окончания текущих, поэтому сокращение парка занимает десятки минут.
  • Регулярный от игрового процесса отделяет зависшие серверы от занятых: молчащий процесс с матчем — это инцидент, а не кандидат на тихую замену.

Транспорт: протокол UDP, надёжностные каналы и браузерные игры

гарантирует порядок и доставку, но платит за это блокировкой очереди: потерянный пакет задерживает все последующие, пока не приедет ретрансмит, и клиент получает пачку устаревших состояний разом. Для игрового состояния свежесть важнее полноты, поэтому основной трафик идёт по , а гарантии собираются выборочно на уровне приложения.

Каналы с разными гарантиями

  • Unreliable sequenced — снимки состояния: новый пакет обесценивает старый, поэтому терпима, а устаревшие просто отбрасываются по номеру.
  • Reliable ordered — события, которые нельзя потерять: покупка предмета, начало раунда, сообщение чата. Поверх это порядковые номера, поле подтверждений и ретрансмиты только для этого канала.
  • Раздельные каналы не дают надёжному трафику блокировать быстрый: даже при снимки продолжают приходить без очереди.

Браузер: WebRTC и WebTransport

  • Браузеру сырой недоступен, поэтому браузерные игры используют WebRTC DataChannel: SCTP поверх DTLS, где режим ordered: false с maxRetransmits: 0 ведёт себя как с шифрованием. Сервер при этом выступает обычным WebRTC-пиром.
  • WebTransport поверх — более простая клиент-серверная альтернатива: ненадёжные датаграммы и потоки без взаимной блокировки, без церемоний ICE-сигналинга.
  • Прохождение для клиент-серверной модели тривиально — клиент всегда инициирует соединение; STUN и TURN нужны в основном P2P-режимам и voice-чату.

Выбор транспорта по типу трафика

ТранспортГарантииГде уместен
+ свой надёжностный слой ✓Настраиваются по каналамИгровое состояние нативных клиентов: снимки, вводы, выстрелы
TCP / Надёжно, упорядоченноЛобби, матчмейкинг, чат, магазин — всё вне игрового тика
WebRTC DataChannelНастраиваемые: от -подобных до надёжныхБраузерные клиенты против выделенного сервера-пира
WebTransport / QUICДатаграммы и потоки без взаимной блокировкиСовременная замена обоим браузерным вариантам по мере поддержки

Практическое правило: по быстрому пути — только то, что обесценивается за один тик; всё остальное выносится на обычный надёжный канал. Так потеря пакетов деградирует картинку, но никогда не ломает целостность матча.

Надёжность и типичные ошибки

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

Надёжные решения

  • Региональное размещение матчей: игроков стараются сводить в пределах допустимой задержки.
  • Липкая сессия для трафика игровых и постоянных соединений в рамках активного матча.
  • Резервные игровые серверы и быстрый перенос матча при отказе узла.
  • Снимки состояния и дельта-обновления для экономии полосы пропускания и быстрого досинхрона.
  • Ограничение очередей на входе, чтобы перегрузка не ломала цикл симуляции.

Частые ошибки

  • P2P-модель с клиентом как источником истины в соревновательных режимах.
  • Глобальный подбор матча без региональной сегментации по задержке.
  • Синхронные вызовы к БД или внешним сервисам внутри игрового тика.
  • Отсутствие окна повторного подключения и механизмов досинхронизации состояния.
  • Полная рассылка состояния вместо компактных дельта-пакетов.

Что хранить постоянно

  • Профиль игрока и его прогресс.
  • Историю матчей и ключевые телеметрические счётчики.
  • Снимки MMR, результаты ранжирования и агрегаты таблиц лидеров.
  • События инвентаря и игровой экономики, если в продукте есть монетизация.
  • Аудиторский след для модерации и расследования читов.

На интервью важно проговорить между отзывчивостью, которую даёт , и честностью матча, которую сервер возвращает через .

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

Связанные главы

  • UDP - разбирает транспорт, который чаще всего используют для критичного игрового трафика с минимальной задержкой.
  • WebSocket - дополняет тему постоянным каналом для лобби, уведомлений и части сессионных событий.
  • Chat System - даёт смежный кейс по коммуникациям в реальном времени, онлайн-статусу и масштабированию долгоживущих соединений.
  • Rate Limiter - полезен для защиты игровых API от всплесков нагрузки, злоупотреблений и нечестного поведения клиентов.
  • Content Delivery Network (CDN) - объясняет, как ускорять доставку ассетов и патчей и уменьшать задержку для игроков из разных регионов.

Чтобы отмечать прохождение, включи трекинг в Настройки