Это третья и последняя часть серии статей о разработке многопользовательских игр на JavaScript. Вы можете прочитать Часть I и Часть II. В этом посте представлены некоторые основные принципы для тех, кто хочет разработать собственную многопользовательскую игру на JavaScript. Он также представляет Lance.gg, библиотеку с открытым исходным кодом, которую мы разработали в рамках этого процесса.

Не обижусь, если форкнете. Код доступен здесь.

Прежде чем ты начнешь

Итак, вы хотите отправиться в фантастическое путешествие и разработать собственную многопользовательскую игру на JavaScript? здорово. Когда вы начнете, вам нужно будет остановиться на трех основных перекрестках. Во-первых, поймите требования вашей игры; во-вторых, узнайте об игровых архитектурах, используемых в существующих многопользовательских играх; и, наконец, разработайте архитектуру, которая будет соответствовать требованиям вашей игры.

Понимание требований вашей игры

Я хочу сделать шаг назад и поговорить о требованиях к игре. При разработке spaaace нам нужно было точно понимать, какой тип игры мы разрабатываем. В противном случае мы бы далеко не ушли.Вы можете играть в игру онлайн, есть игровой сервер, работающий в Европе, и еще один в США.

Различные типы сетевых игр основаны на существенно разных реализациях сетевой архитектуры. Вы разрабатываете шутер от первого лица? Стратегия в реальном времени? Гоночная игра? Массовая многопользовательская онлайн-игра? Все эти категории имеют существенно разные требования, которые приводят к различным предпочтительным реализациям.

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

Вот список из пяти вопросов, которые, я думаю, будут полезны всем, кто приступает к разработке многопользовательской игры. Они предназначены для помощи в классификации требований. За каждым вопросом следует ответ, который мы получили при разработке игры spaceaace.

  1. Нужна ли игре полнофункциональный физический движок или можно использовать упрощенную псевдофизику?
    В нашей игре не требовался настоящий физический движок, поскольку не было гравитации или ограничений. Нам нужно было только рассчитать позиции на основе скорости и угла ориентации. Если вашей игре нужны ограничения или много стен, вокруг которых можно прыгать, вам может понадобиться подходящий физический движок, такой как cannon.js.
  2. Являются ли позиции игровых объектов дискретными или непрерывными?
    Для spaaace позиции представляют собой непрерывные числа с плавающей запятой. Но в некоторых играх, например, в стратегиях в реальном времени, позиции дискретны. Если игровые объекты можно расположить на невидимой сетке, то их положение дискретно.
  3. Сколько объектов будет транслироваться в любой момент времени?
    Для нас около тысячи, включая ракеты. Обратите внимание, что вопрос относится к сетевым объектам. Например, в вашей игре может быть несколько машин, и каждая машина может включать в себя четыре колеса и другие подкомпоненты — но если это возможно — попробуйте транслировать каждую машину как единое целое.
  4. Должен ли визуальный ответ быть быстрее, чем обычное время проверки связи в Интернете, равное 150 мс?
    Это сложное требование, и, к сожалению, для нас ответ положительный. Однако многие игры смогли обойти это требование, используя оригинальные визуальные эффекты. Например, если пользователь нажимает кнопку ускорения, рассмотрите возможность показа светящегося форсажа в течение 100 мс, прежде чем фактически двигать корабль. Или торопить начальное ускорение на сервере, чтобы «догнать» там, где находится клиент.
  5. Соответствует ли игровая механика детерминированному процессу?
    Этот вопрос очень важен, поскольку детерминированная игра означает, что все клиенты имеют возможность воссоздать точное одно и то же состояние игры при точном вводе данных пользователем на каждом этапе. Это означает, что клиенты могут отправлять входные данные друг другу и пропускать переход на сервер. Это очень заманчиво. Действительно очень заманчиво. Но если вы действительно не знаете, что делаете, вам, вероятно, придется ответить НЕТ на этот вопрос. Детерминированные игровые движки должны использовать математическую библиотеку с фиксированной точкой, чтобы гарантировать, что все результаты вычислений будут детерминированными.

Архитектура игры

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

В нашем случае, учитывая приведенные выше ответы, подходящая архитектура для spaceaace требует предсказания на стороне клиента и упрощенного физического движка. Можно отправлять как входные данные, так и позиции объектов по сети, потому что у нас их не так много. Игровой цикл может быть быстрым 60 Гц, потому что мы используем упрощенную физику, поэтому каждый шаг выполняется менее чем за 16 мс; частота трансляции состояния сервера также может быть высокой, потому что в каждой трансляции отправляется всего несколько килобайт, поэтому я выбрал 10 Гц; наконец, частота цикла рендеринга зависит не от нас, а от тиранического requestAnimationFrame() браузера.

Основными компонентами нашей архитектуры являются:

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

Новая библиотека синхронизации многопользовательской игры: Лэнс

Игровая архитектура, которую мы реализовали в space, основана на принципе разделения задач. Мы хотели изолировать код, относящийся к нашей игре, от кода, который можно было бы использовать в других многопользовательских играх на JavaScript. Это фундаментальное правило привело нас к созданию Lance, независимого от игры многопользовательского сервера. Большая часть проделанной нами работы привела к расширению функциональности Lance.

Мы выпустили Lance как библиотеку с открытым исходным кодом, поэтому я надеюсь, что она будет полезна другим разработчикам игр. В настоящее время Lance реализует множество функций, таких как прогнозирование на стороне клиента, взаимодействие клиент-сервер, сериализация объектов, обработка пошагового смещения и поддержка физических движков. В будущем планируется больше. Узнайте больше об этом на: http://Lance.gg

Литература по многопользовательским играм и физике

Другие ресурсы

Стек разработки, который мы использовали в spaaace, был: nodejs, socket.io, упаковщик WebPack, языковая поддержка es6, PixiJS и Lance.

Это тоже может пригодиться:

Вывод

Вот мои напутствия на тему многопользовательского программирования на JavaScript. Это работает просто отлично. Вы можете создать свою собственную инфраструктуру с помощью socket.io и, возможно, попытаться пойти еще дальше с помощью WebRTC и попробовать P2P-связь. Более того, http://Lance.gg может предоставить вам необходимую инфраструктуру, что позволит вам уделять больше времени важным вещам.

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