Создание онлайн сервера для мобильных многопользовательских, realtime 2D игр (жанра RPG и стратегии) с API на PHP ч. 6

от автора

Правительство РФ анонсировало выделение до $50 млрд для выхода РФ в топ-20 стран—разработчиков Игр к 2030 году. Возможно в скором времени разрабатываемый мной сервис наконец увидит свет

В этой статье я расскажу как сделать архитектуру приложения игрового сервера быстрой и что использует Unity. Эта статья результаты исследований предыдущих так что в ней будет много ссылок на них

Зачем это надо знать ?

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

  1. TCP начинают заменять где это возможно на UDP обуславливая что «так быстрее» …

Действительно быстрее…На 0.02 мс по данным моих исследований (данные приблизительные и сильно зависят от размера пакета и других факторов, но измерения лежат в долях миллисекунды) но на TCP у меня есть механики которые отрабатывают от 0.001мс до 4мс и на фоне этого UDP капля в море даже в шутерах (есть момент в блокировке TCP сообщениями сервера, проверки на получения данных, повторные отправки пакетов, но и не нужно отправлять пакеты в ветке Thread процесса сервера игровых механик о чем пойдет речь ниже)

2. Выбирают Node JS как один из быстрых решений сервера

Да быстрый, но почему ? Несомненно Node JS использует быстрый движок V8 о котором я рассказал в предыдущей статье однако при всей быстроте — это капля в море, а более важно что он использует обертку над websocket (что это такое я так же рассказывал в другой статье) — Socket IO и это не что то присущее только Node JS или Java Script в целом, а некий архитектурный подход в клиент-серверном взаимодействии. Одним из главных его преимуществ является добавление неких каналов «Channel» являющиеся второстепенными websocket серверами в которые вы шлете ОДИН большой пакет со списком кому его отправить, а Channel в свою очередь рассылают ВСЕМ , тем самым ваш игровой сервер тратит время только на отправку одного TCP пакета (условно их может быть несколько , например разным группам пользователей), а время на отправку непосредственно игрокам тратится в другом потоке Thread не тормозя игровой сервер. И этот подход вы можете реализовать на другом языке программирования без изменения стека (я рассказал в одной из первых статей что это большой обман что игровые сервера можно писать только на С++, С#, Go, Node JS и др )

  1. Добавлять все технологии, что на слуху, например:

  • Redis — из статьи про производительность вы знаете что его производительность Perfomance +- 60.000 запросов в секунду, при пропускной способности TCP (Websocket) канала ~1 500 000 (зависит от сервера и его пропускной способности Ethernet) — тем самым вы резко занижаете скорость вашего сервера (есть возможность использовать корутины «Coroutines» и сделать Redis асинхронным если он работает не через socket, а по TCP тем самым не блокируя скрипт…тем не менее постоянное его использование сильно тормозит работу сервера)

  • Добавлять очереди , например Rabbit MQ — я не делал статьи насчет него тк после Redis уже внимательнее отношусь к выбору технологий, но его Perfomance в целом схож с ним

— Так как написать хороший продукт ?

— Как сделать что бы он был быстрый даже при 5000 игроков онлайн ?

— Какие технологии выбрать?

На этот и вопрос я могу сказать  — грамотная архитектура и есть технология!

В своем проекте сервиса для добавления мультиплеера в игры (адрес проекта http://my-fantasy.ru)

60%. Это не Си и не Go но при запуске он компилируется в машинный код 0101010 и работает как и они и нужен для интернет админ панели и установки WebSocket соединения вдобавок поддерживает библиотеки на С++
60%. Это не Си и не Go но при запуске он компилируется в машинный код 0101010 и работает как и они и нужен для интернет админ панели и установки WebSocket соединения вдобавок поддерживает библиотеки на С++
Фреймворк написан с Hello World в России мной на PHP.  Слишком медленные все эти иностранные для проекта и слишком много зависимостей их же библиотек
Фреймворк написан с Hello World в России мной на PHP. Слишком медленные все эти иностранные для проекта и слишком много зависимостей их же библиотек
5%, лишь раз нужно запомнить авторизацию
5%, лишь раз нужно запомнить авторизацию
10%, База подойдет любая, работа с ней асинхронно при входе в игру
10%, База подойдет любая, работа с ней асинхронно при входе в игру

И самое главное — Сущностно-компонентный архитектурный шаблон представленный ниже

Я постараюсь изложить как он работает простым языком:

  1. Ваш игрок (клиент игры) делает запрос на сервер они ставятся в очередь на исполнение в следующем кадре (вам не нужен никакой Rabbit или Laravel с его очередями для этого — достаточно поместить в массив данные)

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

  3. У сервера есть игровые события (Respawn System, Move System и др с картинки) заложенные разработчиком чье количество не меняется в процессе игры (новое событие — новый код в сервере и соответственно его перезапуск).

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

  5. Игрового события (например Move System) запускает цикл while внутри себя и смотрит какие игровые объекты (Entity) сейчас (тк у событий должна быть пауза, например: регенерация раз в 30 секунд) должны исполнить на себе это игровое событие

  6. У каждого игрового объекта есть компоненты (Components с картинки) которые по сути являются данными конкретной сущности (жизни , координаты, и прочее) — так вот любая игровая механика (Move System и др) это смена этих данных (когда изменения передадутся на клиент игроку у него изменится игровой мир: персонаж двинется, количество жизней увеличится, появится вмятина на танке и др)

  7. Если компонент (Components) сложный (не скалярный int string float double bool), например это объект или массив (в php массивом может быть то что в других языках, например в JS, называют объектом, но у которого нет методов ['bar'=>['foo1', 'foo2'...], ...]) то у него есть свойства Properties — нет нужды всегда группировать свойства делая Components как группу с единственным скалярным Properties, поэтому Components может быть как группой свойств, так и одни единственным (например в моем проекте жизни hp — это один компонент, максимальное число жизней hpMax — другой. Эксперименты с группировками скалярных компонентов лишь усложнили мне жизнь работая над кодом демонстрационной версии игры — клиентской части)

Признаюсь честно я об этом архитектурном шаблоне узнал не сразу. Сперва мне пришлось его вывести самому путем долгих экспериментов и у меня был перепутан местами пункт 4 и 5 — сначала в кадре сервера обрабатывались игровые объекты (Entity), а после обрабатывались их игровые события. Это работало отлично, но было весьма медленно тк каждый раз надо было запускать песочницы где выполнялся пользовательский код игровых механик (весьма в моем понимании дополнительные 0.1мс на объект)

Этот архитектурный шаблон используется в таком популярном движке как Unity, вот ссылка на его описание https://docs.unity3d.com/Packages/com.unity.entities@0.0/manual/index.html

Я искренне надеюсь что мои статьи принесут пользу читателю, сэкономят время разработки его сервера, а так же усилия нескольких лет не окажутся напрасными и будут полезными разработчикам РФ так и за рубежом (в настоящий момент я с друзьями из компании ООО Гейм Девс работаю над получением гранта для развития проекта)

Буду признателен за лайк к статье и рекомендации моего творчества заинтересованным людям, так же я выкладываю видео о своих исследованиях в сфере разработки игрового сервера на youtube на русском и английском языке


ссылка на оригинал статьи https://habr.com/ru/post/706678/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *