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

О проекте

Для тех кто первый раз читает мои статьи — я разрабатываю авторитарный сервер игровой с управлением по API и прикладным ПО для редактирования карт, игровых механик , управления догружаемым контентом (музыки, анимаций, диалогов, переводов) и рассказываю об этом в серии статей. Это будет единое игровое пространство (не комнаты), где NPC будут под управление искусственного интеллекта.

Это Российская разработка — аналог западных сервисов таких как Firebase, Photon, PlayFab, Mirror, RakNet, AWS GameLift (во всяком случае так мне ответила нейросеть ChatGPT).

Открытый мир

Общий принцип открытого мира основана на том, что игра становится не линейной — мы можем отправиться куда нам хочется и обычно это сопряжено с побочными игровыми заданиями. Однако если мир огромен то для его полной загрузки и обработки потребуется очень много ресурсов компьютера. Эту проблему решают разбивая мир на отдельные локации переход между которыми сопряжен с загрузкой игры (во время которой обычно играет какая то анимация).

край локации игры Fallout справа внизу
край локации игры Fallout справа внизу

Бесшовный мир

мы видим соседние загруженные игровые локации
мы видим соседние загруженные игровые локации

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

Моя реализация для 2D онлайн игры

Я уже заранее позаботился что мир будет открытым и масштабируемым (где каждая локация может быть отдельно на физической машине), осталось придумать как сделать его бесшовным.

Первое что пришло на ум — соединятся по websoсket каналу не только с сервером (локацией) где мы играем, но и со смежными. Однако от этой идеи пришлось сразу отказаться ведь не только клиенту (игроку), но и серверу (локации) где клиент играет нужно знать что происходит на соседних (например механика взрыва снаряда на границе локаций должна задеть и тех существ что будут на соседней локации возле границы). В итоге наш сервер‑локация всегда соединяется по websocket со смежными локациями (то есть сервер становится еще и клиентом).

Сразу появилась проблемы — сервер после перезагрузки подымается только если на нем кто то играет (пришлось реализовать внутреннее api для самих серверов который проверяет статус другого, перезагружает, останавливает и запускает выбранную сервер‑локацию), а так же проблема согласованности кто с кем должен соединятся тк соседние локации так же хотят соединится с нами образуя некую сеть (временным решением стало то, что тот сервер у которого сумма цифр в IP выше — тот и должен инициализировать соединение, а в случае если на одном физическом сервере несколько локаций — в дополнении проверим порт тк локации работают на разных портах в рамках одного физического сервера).

Приоритетный сервер подымает локацию и инициирует соединение websocket с ней
Приоритетный сервер подымает локацию и инициирует соединение websocket с ней
Соседняя локация на которой никого нет поднялась и приняла запрос на соединение с приоритетным сервером (где авторизовался игрок)
Соседняя локация на которой никого нет поднялась и приняла запрос на соединение с приоритетным сервером (где авторизовался игрок)

Наш сервер где мы играем получает пакеты от соседних локаций что там происходит (тем сам обладает пониманием кто там есть) и уже ретранслирует всем клиентам игрокам, а так же рассылает пакеты соседним локациям что происходит у него.

Граница нескольких сервер-локаций
Граница нескольких сервер-локаций
У меня родилась идея что таким образом можно управлять беспилотниками на огромной территории

Осталось реализовать функционал перехода между серверами (они могут быть физически разными машинами). Идея следующая:

  • Игрок отправляет на сервер команду на выход

  • Сервер сохраняет игрока в бд

  • Сервер убирает из массива существ находящихся на нем игрока, рассылаем всем команду что игрок удаляется с сервера

  • Клиенты получают команду что игрок отключается, ждут пару секунд и убирают со сцены данный «прафаб» (в Unity игровые сущности называются префабами)

  • Если за те пару секунд что клиенты ждут удаление префаба он появился в другой сервер локации — мы анимируем плавный переход границы

В самой панели разработчика клиентской части (в настоящий момент использую Unity) локации и находящиеся в них существа (префабы) выглядят следующим образом.

Группа слоев Map — содержит графику текущей (center) локации и соседней (left)
Группа слоев Map — содержит графику текущей (center) локации и соседней (left)
Группа слоев World — содержит прафабы текущей (center) локации и соседней (left)
Группа слоев World — содержит прафабы текущей (center) локации и соседней (left)

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

В завершении хочу сказать следующее: в очередной раз ища поддержки у нашего Российского государства на развитие проекта (я все делаю один из личных средств) столкнулся с критикой вида: «один человек ничего не сможет — надо поддерживать компании т.к. у них есть команды«, а в свою очередь представители бизнеса игровой индустрии заявляют что это долго и над подобными проектами трудятся сотни сотрудников западных компаний — куда нам до них. Тем самым сдаваясь еще не начав.

Я искренне верю что если у одного человека есть идея и стремление ее решить — он добьется успеха со временем.

Если вам интересно следить за реализацией проекта (адрес my‑fantasy.ru) — вы можете подписаться на меня и быть в курсе выхода новых статей.

Комментарии (6)


  1. IgorRJ
    03.06.2023 15:47
    -9

    Из заголовка статьи:

     Открытый бесшовной мира 

    Ну прям и не знаю, что это. Наверное, великий и могучая русским языка?


    1. webrobot Автор
      03.06.2023 15:47
      +4

      это описка - исправил


  1. nikolz
    03.06.2023 15:47

    Чем Ваша реализация отличается от реализации бесшовного мира в облаке, либо на кластере?

    Почему бы не отдать функции выделения ресурсов ОС, а бесшовный мир строить в предположении, что нет ограничений вычислительных ресурсов?


    1. webrobot Автор
      03.06.2023 15:47
      +1

      Я не совсем понял ваш вопрос.

      Данный сервис - это авторитарный сервер и с ним можно работать по API в разных движках (unity, unreal engine , godot и др). Тк сервер авторитарный в нем содержится все информация о коллайдерах, вычисляются все механики и он рассылает пакеты которые интерпретирует клиент (изменяет полоску жизней, двигает существ и тд). Сервер работает только с массивами данных.

      Такие авторитарные сервера могут быть объединены в некий пул физических серверов и между ними можно переходить и в идеале это на клиенте не должно быть заметно что игрок разлогинелся в одном сервере и залогинелся в другом


  1. MANAB
    03.06.2023 15:47

    По идее бесшовность и распределение по физическим машинам нужна для динамического управления нагрузкой на сервер. Тогда в разные моменты времени каждый сервер обрабатывает разные размеры карт. У вас такое заложено?

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


    1. webrobot Автор
      03.06.2023 15:47

      Заложено и реализовано. Есть сервер который обсчитывает физику и взаимодействует с websocket сервером . Физически они находятся на одной машине только это 2 разных процесса работающие на отдельных ядрах процессора (в будущем к серверу обсчитывающему физику планирую подключить вычисления на GPU).

      Чат пока не реализован но это уже клиент будет соединятся с дополнительным websocket сервером (тк к игре это относится косвенно)