Как сделать в своей игре кросс-платформенный мультиплеер
Привет, меня зовут Джордж Холл. Я соучредитель Мельбурнской студии Bit Dragon. Рад сообщить, что недавно мы запустили наш первый тайтл Hyper Jam. Энергичная игра в жанре arena brawler с динамической системой перков и элементами стиля синтвейв вышла на таких платформах, как PC, PS4 и Xbox One!
Несмотря на небольшой размер нашей команды, очень горжусь тем, что мы смогли реализовать в игре возможности локального мультиплеера, частных онлайн-матчей и кросс-платформенную систему распределения игроков по командам (с дополнительными локальными игроками). Проект стал удивительным опытом обучения, нам пришлось выложиться почти во всех направлениях. Я рад, что для создания Hyper Jam мы выбрали Unreal Engine. Для разработки амбициозной многопользовательской игры он предоставил нашей команде из трех программистов все необходимые инструменты.
Путь к кросс-платформенной игре
Наши первоначальные онлайн-эксперименты в основном были сосредоточены на частных лобби с использованием одноранговых серверов listen, что обычно происходит при создании большинства многопользовательских инди-игр. В стремлении к лучшему сетевому коду мы со временем протестировали наши выделенные серверы, чтобы увидеть как они сопоставляются. После первоначального теста игры мы все были удивлены тем, насколько хорошо они функционировали, особенно в Австралийском интернете. Расходы на выделенные серверы показались более обоснованными после того, как мы обязались провести кросс-платформенный запуск. В результате возможность организации системы кросс-платформенных матчей убедила нас заняться этим вопросом.
Кросс-платформенный матчмейкинг имеет несколько важных преимуществ. Наиболее очевидное — наличие большего количества игроков в пуле системы создания матчей. Для крупной игры эта особенность может уменьшить время ожидания и улучшить опыт игрока, а для маленькой — составить разницу между теми, кто нашел матч или покинул игру разочарованным. Совместное использование пула матчмейкинга также может подстраховать от отдельной платформы, если она работает хуже по сравнению с другими и становится похожей на призрачный город. Такое свойство поможет уменьшить количество плохих отзывов и увеличить долговечность вашей игры. Кроме того, если вам удается поддерживать кросс-платформенные команды участников, вы действительно расширили свою аудиторию!
Каким образом возможно реализовать кросс-платформенную игру в инди-проекте? Если вы занимаетесь онлайн-сервисами впервые, определенно потребуется освоить многие вещи и неизбежно преодолеть больше препятствий, чем вы ожидали. Однако есть хорошая новость — благодаря значительному количеству компаний, упорно работающих над консолидацией и демократизацией игровых онлайн-сервисов, со временем процесс разработки станет проще!
Непосредственно Epic Games предлагает набор кросс-платформенных онлайн-сервисов, которые выйдут в течение следующего года и будут добавлены в список опций, доступных разработчикам.
Если вы оказались в похожей ситуации и также обладаете игрой на нескольких платформах, тогда этот вариант отлично подойдет для кросс-плея.
Выделенные серверы
Главное необходимое условие для создания кросс-платформенной игры — выделенные серверы. Вы могли заметить, что при использовании одноранговых серверов listen невозможно просто разместить этот вид сервера на одной платформе и подключиться к нему с другой. Каждая платформа обычно обладает собственным сетевым драйвером, обрабатывающим протокол NAT Traversal (например, SteamNetDriver использует Steam Sockets). Но для возможности кросс-плея необходимо, чтобы каждая платформа подключалась к одному серверу и "говорила" на одном языке (например, используя стандартный IpNetDriver). Если вы, в любом случае, хотите использовать для частных матчей серверы listen (как и мы), потребуется изменить сетевой драйвер, который вы применяете в процессе выполнения программы.
Пиринговые сети (P2P) неплохо работают в частных матчах, где игроки знают друг друга. Однако они обладают некоторыми характерными недостатками, что не позволяет использовать их для создания матчмейкинга:
- Чтобы обеспечить игрокам возможность получения лучшего опыта, вы вынуждены полагаться на подключение хоста к интернету — даже с отличным контролем QoS
- Преимущество хоста в том, что мы полностью учитываем прогнозы игрового клиента файтинга
- Без возможности миграции хост может легко испортить игру другим пользователям, однако эту функцию сложно реализовать
- Вы не можете полагаться на хост, который исключает ранжированные режимы
Выделенные серверы решают все эти проблемы, но обладают очевидным недостатком. Они требуют больших финансовых затрат. В инди-игре трудно оправдать такие расходы, однако мы решили инвестировать после того, как взяли на себя обязательства по реализации кросс-платформенного запуска.
Выделенные серверы могут пугать, если раньше вы использовали только серверы listen. На самом деле они не вызывают затруднений. Вы можете создать сервер как для Windows, так и для Linux. Вероятно, стоит потратить время на организацию работы сборки Linux, поскольку запуск инстансов этой операционной системы дешевле, чем Windows. К счастью, UE4 позволяет легко это осуществить! После установки цепочки инструментов для кросс-компиляции вы можете включить Linux в качестве целевой платформы. Clang исторически был немного требовательнее, чем VC++, хотя постепенно эти компиляторы становятся все более похожими. Необходимо проверить, что все используемые плагины поддерживают Linux, и неукоснительно сохранять логичность игрового процесса от косметических объектов (поскольку выделенные серверы не запускают виджеты, звуки и т.д.).
По умолчанию, выделенный сервер будет работать и просто вести запись в лог-файле. Тем не менее, вы можете добавить аргумент “-log”, чтобы он также запускал окно журнала, который может оказаться очень полезен во время разработки. Выделенные серверы очень легко внедрять в процесс непрерывной интеграции (CI), что составляет дополнительный аргумент в пользу UAT (приемочное пользовательское тестирование)! Когда вам нужно протестировать сервер Linux, вы можете создать инстансы локальной VM (операционной системы) или EC2. Впрочем, для большинства тестов при разработке должно быть достаточно сервера Windows. Можно использовать выделенные серверы в PIE, которые отлично подходят для отладки Blueprints.
Облачный хостинг
Как только вы получите бинарные данные выделенного сервера и ваш сетевой код станет успешно работать, потребуется где-то разместить сервер, чтобы клиенты могли к нему подключиться! Есть много вариантов хостинга: Amazon GameLift, Google Cloud Compute/Kubernetes, PlayFab и другие. Главное, на что стоит обратить внимание — стоимость, масштабирование и поддержка.
У вас должна быть возможность масштабировать свои серверы по вертикали (вверх и вниз), чтобы удовлетворить потребности игрока. Во время наименьшей нагрузки предпочтительно масштабировать как можно ниже. Большинство этих систем будет запускать виртуальную машину, которая получает определенный IP-адрес и активирует некоторое количество серверных процессов, каждый из которых прослушивает другой порт. Затем диспетчер серверов может назначить игровые сессии каждому серверному процессу, отслеживая, какие из них заняты. Как только количество свободных серверных процессов на инстансе опустится ниже определенного порога, система запустит другую виртуальную машину, которая добавит еще некоторое количество доступных игровых сессий в протокол fleet / базу. Система масштабирования также должна разумно назначать новые сеансы, чтобы осуществить масштабирование по вертикали вниз и эффективно использовать ресурсы (например, вы не хотите, чтобы пять игровых процессов распределялись по пяти машинам).
Большинство провайдеров предоставляют определенный уровень бесплатного пользования, который вы можете применять, чтобы экспериментировать и пробовать разные конфигурации. Это отличный способ проверить свои силы.
В разработке инди-игр стоимость расходов всегда вызывает беспокойство. Необходимо будет сбалансировать процесс и решить, сколько дополнительной работы вы готовы вложить для снижения затрат на сервер.
При рассмотрении стоимости масштабирования основной формулой будет: «количество игроков на сервере x количество серверов на одном экземпляре объекта x одновременное число игроков». На странице цен сервиса Amazon GameLift приведен пример типичной кривой спроса игроков. Он показывает, как спрос влияет на количество инстансов, необходимых в течение дня. Однако эти цифры могут показаться высокими для инди-проекта.
Оптимизация игры для CPU и памяти увеличит количество серверов, которые вы можете разместить на каждом инстансе, снизив ваши затраты. Имейте в виду, за сетевой трафик с вас также может взиматься плата. Таким образом, оптимизация сетевого кода может фактически увеличить эффективность затрат на сервер, а также игровой процесс!
По меньшей мере, вы захотите, чтобы один из запущенных в каждом регионе инстансов принимал новых игроков. Возможно, для дополнительного масштабирования вы сможете использовать преимущества Spot/Preemptible инстансов. Это будет зависеть от ваших требований доступности. Облачные провайдеры могут в кратчайшие сроки отключить их в обмен на большие скидки.
Открывается хорошая возможность задолго до запуска спрогнозировать затраты по предполагаемому количеству игроков. Она позволит убедиться, что серверы могут принести больше пользы по сравнению с их стоимостью. Потребуется оценивать это в течение многих месяцев и лет после запуска. Стоит подумать о непредвиденных обстоятельствах, если вам в конечном итоге придется отключить серверы (например, вы можете вернуться к P2P).
При наличии программного конвейера CI, можно автоматизировать загрузку игровых серверов вместе с клиентскими сборками. Полезной будет возможность запустить протокол fleet для тестирования ночной сборки. Однако вам придется следить за ограничениями дискового пространства хостинга и т.д.
Выбор регионов для размещения серверов может быть сложным соотношением стоимости и спроса, особенно перед запуском. Как AWS, так и Google Cloud имеют довольно хороший охват по всему миру. AWS недавно открыл GameLift в Китае. Передавая данные о задержке игрока балансировщику, можно видеть отчетливее, откуда поступают запросы от игровых клиентов и какие регионы могли бы использовать некоторые серверы.
Могут потребоваться избыточные ресурсы для запуска, чтобы обеспечить обработку "лучшего варианта" трафика. Поскольку у вас, без сомнения, что-то пойдет не так, в день запуска поддержка будет играть немаловажную роль. Как можно больше помощи понадобится, чтобы заняться неотложными делами — чем я, вероятно, занят прямо сейчас!
Матчмейкинг
После того, как у вас появится масштабируемый fleet выделенных серверов, ожидающих получения игр, вам понадобиться способ, чтобы фактически сопоставить игроков вместе. Большинство платформ имеют определенный вид собственного матчмейкинга API. Однако для создания кросс-платформенной игры вам понадобиться централизованная система подбора игроков, которая может обмениваться данными с вашим менеджером серверов.
Как и в случае с хостингом, есть много различных вариантов для бэкендов игры — от полностью интегрированных решений с хостингом/матчмейкингом/клиентскими пакетами SDK до провайдеров, которые обрабатывают серверы/матчмейкинг. Тем не менее, для обработки аутентификации и связи с клиентом требуйте свой собственный бэкенд.
Как минимум, клиент должен сообщить бэкенду, что они хотят найти совпадение с определенными параметрами. Затем бэкенд будет аутентифицировать их запрос, используя токен аутентификации каждой платформы, и добавит их в пул матчмейкинга. После того, как матч будет найден, алгоритм создания матчей должен назначить серверу игровую сессию, передать каждому клиенту IP-адрес и порт этого сервера, а также сообщить серверу, каким игрокам можно присоединиться. Кроме того, он должен передавать любые полезные данные о матчмейкинге, например, команды или тип игры.
Оценивая различные варианты, учитывайте не только ваши текущие требования, но и будущие возможности. Такой подход позволит добавить функции, необходимые в будущем. Например:
- Какой матчмейкинг необходим: основанный на правилах или лобби?
- Потребуется ли возможность смягчить правила с течением времени?
- Хотите принять во внимание информацию о задержке?
- Организуете очередь для нескольких типов игр одновременно?
- Будете поддерживать команды участников в матчмейкинге?
- Могут ли они быть кросс-платформенными командами?
- Будете поддерживать нескольких локальных игроков?
- Вам нужны команды, смогут ли группы объединяться?
- Вы хотите асинхронный матчмейкинг, чтобы во время ожидания игроки могли заняться чем-то еще?
- Потребуется ли возможность ограничения совместимости платформ? (надеюсь, в конечном итоге ответ будет "нет!")
- Потребуются списки блокировки или исключения?
- Необходим ли доступ к постоянным данным игрока, чтобы включить основанный на навыках матчмейкинг и/или ранжированные режимы?
- Будете обеспечивать полное заполнение команд, чтобы игроки могли присоединиться к матчу в процессе?
Любой конкретный совет, который можно дать, вероятно, быстро устареет. Однако есть неподвластная времени рекомендация — начните думать об этом как можно раньше.
Оценивая возможности матчмейкинга, смотрите на другие предложения каждого провайдера бэкенда, такие как идентификация информации игрока, друзья, статус онлайн/оффлайн, группы участников, списки лидеров, аналитика и многое другое. Если вы в конечном счете используете бэкенд-провайдера, качество этих услуг позволит пойти на компромисс — все перечисленные нюансы требует времени для хорошей интеграции в игру. Не стоит торопиться в том, что потребует изменений позднее! Тем не менее, если вы уже задействовали определенного поставщика для некоторых областей, но хотите использовать кого-то другого для матчмейкинга, вы можете это сделать. Онлайн-сервисы, похоже, неизбежно включают в себя ряд подвижных частей. Решать вам, какие части вы получите и откуда.
Управление версиями и сетевая совместимость
После решения вопросов с выделенными серверами вам нужно подумать об управлении версиями клиента/сервера и как это влияет на ваш матчмейкинг, особенно, когда у вас кросс-платформенная игра. На самом деле, для этой области я еще не встречал большого количества хорошо интегрированных решений. Возможно, вам придется что-то придумывать самостоятельно.
Что происходит, когда нужно выпустить обновление, нарушающее сетевую совместимость? Можно ли выпускать новые, совместимые с сетью серверные сборки без необходимости обновления клиентов? Если требуется резко изменить кросс-плей для определенной платформы, можете ли вы по-прежнему сохранить постоянную версию на других платформах?
Обновление клиента на всех платформах и в регионах может занять некоторое время. Вероятно, вы не захотите немедленно завершить работу старых серверов, поскольку у игроков еще нет доступного им обновления. Даже в том случае, если обновление станет доступно кому-то из пользователей, у вас не появится желание прервать их игру в середине матча.
Создание бесшовного обновления не должно быть обязательно сложным. Тем не менее, оно требует некоторой предусмотрительности и планирования. Мы остановились на настройке, которая принимает матчи как для старых, так и для новых версий во время обновления, сохраняя вокруг старые сервера, чтобы игроки могли закончить матч. Мы разрешаем клиентам самостоятельно проверять наличие обновлений (и запускать обновления перед началом новых матчей). После разумного периода распространения мы отключаем старые серверы и отклоняем запросы от любых старых клиентов. Если нужно развернуть патч только для сервера, матчмейкер будет направлять новые матчи к новым комплектам патчей. Затем, после завершения всех матчей в старых группах, мы можем завершить их в фоновом режиме.
Тестирование клиентских/серверных сборок для сетевой совместимости также важно, в частности, при внесении исправлений в существующую ветвь выпуска. Используя функцию Blueprint Nativization, вы можете столкнуться с проблемами совместимости при подключении к нативному серверу от не нативного клиента (например, играть в игру непосредственно через редактор с помощью предварительного просмотра (PIE), или готовить контент "на лету" (COTF), задерживая его, пока игра не будет развернута на платформе. Если вы хотите избежать столкновения с ошибкой Net GUID Mismatch при тестировании в редакторе, можете установить net.IgnoreNetworkChecksumMismatch Cvar к 1.
Связанный с этим совет — проверьте переменную конфигурации TimeoutMultiplierForUnoptimizedBuilds, которая может увеличить пороги тайм-аута сетевого драйвера в редакторе. Поскольку у нас относительно короткие перерывы соединения и "отстающие" пороги, тестирование в редакторе может часто прерываться во время пути, если для загрузки или компиляции что-то заняло больше времени, чем ожидалось. Если вы разрабатываете сетевую игру, без сомнения, уже используете несколько окон PIE и PIE с несколькими функциями. Но стоит признать, насколько великолепны эти особенности по сравнению с тем, что доступно в других движках.
Требования платформы
Как стало известно из кросс-платформенной разработки, существуют довольно специфические требования, предъявляемые каждой платформой, особенно если вы создаете онлайн-игру. С точки зрения кросс-платформенной игры, они могут включать такие нюансы, как указание (или не указание), в какой сети находятся другие игроки, очистка данных об именах игроков и решение конфликтов, подтверждение привилегий игроков и вызов других API, специфичных для платформы.
Связываться с каждой платформой лучше всего на раннем этапе, чтобы понять, обладаете ли вы всей необходимой информацией для выполнения этих требований, и избежать неприятных сюрпризов, которые могут внести изменения в ваше расписание.
Задумайтесь над cross-play!
Создание инди-мультиплеера может быть трудной задачей. Однако cross-play — один из способов увеличить пул матчмейкинга и отдачу от кросс-платформенных инвестиций. Может показаться, что для независимой студии это большой объем работ. Вместе с тем, это может стать значительным преимуществом для продаж вашей игры. Со временем процесс станет проще, поскольку поставщики игровых услуг становятся более развитыми, а платформы — более открытыми.