mizzdev

Пикабушник
поставил 96 плюсов и 8 минусов
Награды:
5 лет на Пикабу
529 рейтинг 46 подписчиков 8 подписок 4 поста 3 в горячем

Nail Crusher: Как я мобильную игру до релиза доводил

Nail Crusher: Как я мобильную игру до релиза доводил Gamedev, iOS, Android, Инди, Разработка игр, Мобильные игры, Игрострой, Видео, Длиннопост

Название игры: Nail Crusher

Жанр игры: Аркада

Платформы выпуска: Android (Play Market, 4pda.ru), iOS (iPhone, iPad на iTunes App Store)


Всем привет! Сегодня я хотел бы рассказать о том, как из идеи может родиться более-менее сносная игра под смартфоны и планшеты, а так же о возможных подводных камнях при разработке и выпуске.

Nail Crusher: Как я мобильную игру до релиза доводил Gamedev, iOS, Android, Инди, Разработка игр, Мобильные игры, Игрострой, Видео, Длиннопост
Предисловие


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


Я хотел начать с чего-то простого до безобразия. Проблема была в том, что все уже давно привыкли к минимализму типа "Flappy Bird" и "2048", потому я решил, то в этой нише потягаться не получится. Тем не менее, я понимал, что простая игра должна быть аркадной и поэтому за основу я взял именно один из таких аркадных жанров - кликер.


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

"Анализ рынка" (ха-ха)


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

Выбор инструментария


Дальше нужно было выбрать - на чем же я буду делать игру? Среди вариантов было:


- Java + Android SDK (для ведра) / XCode для (iOS)

- Unity (под все платформы)

- Game Maker Studio (под все платформы)


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


Юнити - довольно перспективная вещь: гибкость, простота освоения, тоже в наличии SDK. Круто, но о таких вещах как, скажем, шейдеры, можно забыть на бесплатной версии. А у меня в связи с фин. положением на тот момент был "стол голод доширак". Ладно, вру, "доширак" я в Украине не видел, зато есть отечественный аналог - "Мивина". Хотелось бы поменьше расходник.


И тут я вспомнил, что у друга есть лицензия на Game Maker - прогу, которая имеет достаточную гибкость и простоту при работе с 2D и кроссплатформенна, правда для экспорта на что либо кроме винды надо покупать лицензию. Так как она имелась у друга в распоряжении, было решено сделать игру на Free версии, а собрать под мобильные с машины друга. Как я понял уже потом, перед релизом - подружить игру на ГМ с внешними сервисами - это реально адский чэллендж. Но на тот момент я об этом не знал и радостно принялся писать игру.

Первое демо


Уже в первую ночь я быстро набросал страшненький прототип основной идеи:

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

Я вывел тестовую инфу на экран и заставил гвозди появляться в соотношении 4:2:1, собственно чтобы проверить адекватность распределения, я и выводил общее количество созданных гвоздей.


Снимал при помощи полезнейшей программы - Bandicam. Очень гибкая в своем классе, и не накладывает особых ограничений при бесплатном использовании.

Второе демо


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


Интерфейс в мобильных играх - отдельная больная тема, кстати. Разрешений экранов много, соотношений сторон - много. В итоге я сделал игру чисто под вертикальную ориентацию экрана (т.е. уклон больше в сторону телефонов, чем планшетов). Совет для новичков - когда делаете интерфейс, не привязывайтесь к абсолютным пикселям игрового окна. Постарайтесь задавать размеры, отступы вашей графики в процентах от высоты/ширины экрана, которые меняются от устройства к устройству. Так вы сэкономите кучу времени и нервов, поверьте.

Третье демо


Дальше я подумал, и понял, что пора вводить возможность проигрыша игрока. Решил, что не стоит придумывать велосипед и банально дал 5 жизней игроку. Пропустил гвоздь - пропала жизнь. Нет жизней - обратно в главное меню. Ну и более-менее начала у меня в голове формироваться цветовая "атмосфера" игры.

Четвертое демо


Я постепенно понимаю что мои шрифты - дно, да и вообще с графикой всё худо. Переделывать начал с кнопок, цветовую палитру для которых составил при помощи специальных сервисов в интернете (например, Paletton). Фоны, как потом я понял после пары опросов желающих, просто ущербные, да и вообще я "фотошоп мастер". Но радовало то, что основа геймплея игры работала как надо, и в планах у меня было сделать магазин апгрейдов за внутриигровые очки и таблицу рекордов. Попутно добавляю еще больше всплывающих надписей. Как оказалось - не зря.

Пятое демо (предрелиз)


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

Подготовка к релизу


Было очевидно, что рецепт затягивающей игры - разнообразие контента. Костяк игры был в принципе готов, и я приступил к увеличению разнообразия в игре. Я ввел дополнительно 4 вида гвоздей:

- Взрывные (при забивании наносят урон окружающим гвоздям)

- Хроно-гвозди (при забивании заставляют доску двигаться в обратном направлении на несколько секунд, давая игроку передышку)

- Гвозди жизни (+1 жизнь при забивании)

- Гвоздь-босс (редко попадается, нужно несколько десятков тапов, чтобы забить)


Такой бестиарий в итоге сделал игру гораздо интереснее, учитывая что доска ускорялась со временем.


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


Наконец, я, не без сторонней помощи, довел графику до гораздо более достойного уровня (пример: первый скриншот этого поста) и нарисовал красивые иконки для игры.


Настало время собирать под мобильные устройства. Этот процесс включал в себя привязку к AdMob, Appodeal (рекламные платформы), Google Analytics, Google Play Services для андроид и сервисам iTunes, а так же оформление приложений в маркетах, сборку бинарников и отправку их на модерацию.


Ребят, это было жестко. Очень жестко. Некоторые SDK зависели друг от друга, конфликтовали между собой, компилятор выдавал десятки ошибок, танцы с бубном заменили мне утреннюю зарядку. Например, когда я подключал аналитику и рекламу одновременно, они ругались друг на друга и отказывались собираться. Лечилось это всё томным поиском старых версий SDK, которые работали еще адекватно (это я потом узнал, что для сервисов не редкость выбрасывать в публичный доступ забагованные SDK). Думаю, программисты поймут.


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


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


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



Ссылочка для пользователей Android


Ссылочка для пользователей iOS


Всем огромное спасибо за внимание!

Показать полностью 2 5

[Engines of Delight] Распределенные сетевые соединения

[Engines of Delight] Распределенные сетевые соединения Перевод, Онлайн-игры, Архитектура по, Mizzdev, Engines of delight, Мультиплеер, IT, Gamedev, Длиннопост

И снова здравствуйте, дорогие читатели! Я продолжаю перевод цикла статей о шаблонах проектирования игровых серверов из блога Engines of Delight. Конечно жаль, что предыдущий перевод вызвал относительно мало интереса, но, как говорится, первый блин комом.


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


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

[Engines of Delight] Распределенные сетевые соединения Перевод, Онлайн-игры, Архитектура по, Mizzdev, Engines of delight, Мультиплеер, IT, Gamedev, Длиннопост

1. Вы обслуживаете ваш сервер: регулярно платите аренду, правите мелкие баги и осуществляете техподдержу в случае чего. Никаких нововведений вы не делаете, аудиторию не расширяете. Вы просто сидите и получаете доход на некотором фиксированном уровне. Особо рекламой не занимаетесь. Вкратце, пускаете всё на самотёк. И это работает. Игра набирает некоторую, часто небольшую популярность (ее уровень зависит от многого - качества игры, первоначальной рекламы, рынка и пр.), держится на некотором уровне и затем плавно спадает. В какой-то момент продолжать поддержку игры становится нерентабельно - доходов от игроков не хватает даже чтобы покрыть расходы на обслуживание. Это тот момент, когда вам следует смириться и свернуть проект. В конечном итоге все онлайн игры встречают свой конец, рано или поздно. Вы переключаетесь на другие проекты, если не сделали этого до закрытия. Если такая бизнес-модель для вас подходит, то проблем вообще никаких, если же мириться с таким раскладом вам не хочется, то...


2. Вы стараетесь привлечь больше игроков. Проводите маркетинг, раскручиваете в соц.сетях, запустили сайт, раскручиваете его в поисковиках, предлагаете обзорщикам ознакомиться с вашим продуктом. Путей много, в общем то. Хорошо, количество игроков начало расти, всем всё нравится, ваш месячный доход растёт, но потом, почему то онлайн расти перестает, несмотря на приложенные усилия на брендинг. Люди начинают жаловаться: лагает, играть невозможно. Как следствие - отток игроков. Как это объяснить? Давайте взглянем на график (который построил на основе замеров производительности своего монолитного игрового сервера переводчик этой статьи и ваш скромный слуга):

[Engines of Delight] Распределенные сетевые соединения Перевод, Онлайн-игры, Архитектура по, Mizzdev, Engines of delight, Мультиплеер, IT, Gamedev, Длиннопост

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

Приближаемся к отметке в 700 игроков. В среднем, всё еще хорошо, но вот среднеквадратичное отклонение предательски увеличилось, то есть некоторые моменты времени пакетов стало приходить меньше, а в некоторые - наоборот больше. Это свидетельствует о появлении задержек, или лагов от англ. lag - запаздывание.

Дальше - хуже. Задержи растут, так как аппаратное обеспечение машины, на которой запущен сервер, уже не справляется с нагрузкой. Слишком много тактов процессора тратится на то, чтобы обслужить всех. Посмотрим хотя бы на график зависимости промежутка времени между двумя измерениями количества пакетов, при том, что в норме оно должно равняться (как было задано) 500 миллисекундам:

[Engines of Delight] Распределенные сетевые соединения Перевод, Онлайн-игры, Архитектура по, Mizzdev, Engines of delight, Мультиплеер, IT, Gamedev, Длиннопост

Как видим, первые "тревожные звоночки" проявляются уже при трёхстах игроках. Этого мы сначала не можем не заметить, но после того как вовсю проявится экспоненциальный рост задержке, то становится поздно и мы возвращаемся к сценарию в первом пункте. Если у нас имеется один жирнющий монолитный сервер, то выход только один - арендовать/купить более мощное "железо". И так делают на практике. Это называется вертикальное масштабирование. Только вот есть у такого метода предел. Чем больше надо мощности, тем дороже в итоге будет стоить апгрейд. И скорость роста цены с ростом количества игроков просто непристойная. Плюс ко всему во время "переезда" сервера на новые мощности сервер придется вырубить. В один момент станет слишком накладно наращивать мощность и вы опять скатываетесь к ситуации первого пункта.


3. Игроки нуждаются в нововведениях. Вы это понимаете и постоянно захотите выпускать обновления, добавлять новые фичи, править баланс, открывать для игроков новые локации, да и просто делать всё чуточку лучше и сочнее для вашей аудитории. Поначалу ваша команда нормально с этим справляется, патчи выходят - доход держится. Однако, дьявол кроется в деталях - с каждым новым патчем наверняка чуть-чуть нарушится целостность архитектуры сервера, как программного продукта. Когда срочно (допустим, ко дню праздника) надо ввести "фичу", вашим программистам придется прибегать к "костылям" - своеобразным заплаткам в коде, которые призваны решать проблему быстро, но не очень правильно со стороны качества кода. И эти костыли имеют свойство накапливаться. Как следствие - ваш элегантный серверный код со временем превращается в кучу мусора, в которой с каждым разом становится всё сложнее разобраться. Всё больше человеко-часов надо будет потратить для очередного апдейта, а нанимать больший штат для поддержки этого всего не особо эффективно. Как следствие, выпускать обновления становится накладно и вам придется выпускать их реже. В конечном итоге вы опять возвратитесь к пункту 1.


Что же делать, если мы хотим избежать такого вот конца, когда продукт "пожирает сам себя"? Проблема в пункте №3 является сложной, но решаемой. О ней мы поговорим в следующих статьях, а сейчас я расскажу как решить проблему с пункта №2, то есть как мы сможем позволить себе больше игроков.

Постановка задачи


Как увеличить максимальное количество игроков на сервере?


Допустим, нам требуется построить архитектуру сервера для массовой многопользовательской онлайн игры (MMO) с учётом того, что игровой дизайн предусматривает формирование игрового опыта на за счет одновременного взаимодействия большого количества игроков в едином виртуальном мире. Для этого мы можем применить такой шаблон, как Distributed Network Connections, или "распределенные сетевые соединения".

По сути нам надо создать помимо нашего "игрового сервера" еще один сервер, который назовем "шлюзовым сервером" (англ. connection server). Его предназначение - прием и управление TCP соединениями от клиентов к серверу и мультиплексирование сетевого трафика от клиента к серверу и обратно. В англоязычной терминологии можно встретить такие названия, как connection server, user server, gateway server, front-end server, player server и прочие.


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


Посмотрите на общение с монолитом:

[Engines of Delight] Распределенные сетевые соединения Перевод, Онлайн-игры, Архитектура по, Mizzdev, Engines of delight, Мультиплеер, IT, Gamedev, Длиннопост

А теперь сравните с новой схемой:

[Engines of Delight] Распределенные сетевые соединения Перевод, Онлайн-игры, Архитектура по, Mizzdev, Engines of delight, Мультиплеер, IT, Gamedev, Длиннопост

Шлюзовый сервер является своего рода "ретранслятором", что берет нагрузку поддержания соединений на себя, обременяя игровой всего лишь одним каналом связи, вместо тысяч. Тем самым почти все свои драгоценные такты процессора игровой сервер сможет тратить на действительно полезные со стороны гейплея вещи - игровую логику. А шлюзовый сервер пусть уж там занимается сам поддержкой тысяч соединений и не лезет в премудрости игрового процесса. Все в выигрыше!


Но это не все достоинства шлюзового сервера. Помимо сброса нагрузки теперь он нам позволяет не ограничиваться одним игровым сервером. Теперь мы можем масштабировать сервер не только ввысь (вертикально) а и вшырь (горизонтально), добавляя или убирая из нашей теперь уже распределенной (поскольку она распределяет обязанности) сети игровые и шлюзовые сервера, в зависимости от текущего онлайна и/или нашей платежеспособности.


На картинке ниже - один из способов обеспечения нужного нам результата:

[Engines of Delight] Распределенные сетевые соединения Перевод, Онлайн-игры, Архитектура по, Mizzdev, Engines of delight, Мультиплеер, IT, Gamedev, Длиннопост

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


Важно! Клиенты не обязаны, а в идеале и не могут знать о внутренней структуре вашей сети. Следовательно, у клиентской программы нет сведений о существовании вообще чего либо позади шлюзовых серверов. Не нарушайте это правило, так как в лучшем случае это приведет к тому, что любое изменение архитектуры вашей сети потребует крупных переделок клиентской программы, а в худшем - откроет огромную уязвимость для DDoS атак (Distributed Denial of Service), поскольку злоумышленники смогут управлять потоком данных и обрушить шквал нагрузки на наиболее слабые узлы сети ваших серверов. В идеальном случае после подключения клиент всегда должен думать, что общается напрямую с монолитом.


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

- Выбирает случайный сервер из списка

- Выбирает "по кругу" (round-robin) - пример такого распределения на картинке выше

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


Вне зависимости от способа привязки, каждый игровой сервер изолирован друг от друга. По сути - это независимые виртуальные миры. Игроки с разных игровых серверов не могут взаимодействовать между собой. Это как если бы вы подключали их к двум разным монолитам. Это весьма серьезное ограничение для MMO игр, но и его можно обойти. Если не терпится узнать как, можете прочесть на языке оригинала статьи Map-Centric Game Server, а затем Seamless World Game Server. Если можете потерпеть, то ждите, пока я переведу :).


А что если мы сделаем не только множество игровых серверов, а и множество шлюзовых?

[Engines of Delight] Распределенные сетевые соединения Перевод, Онлайн-игры, Архитектура по, Mizzdev, Engines of delight, Мультиплеер, IT, Gamedev, Длиннопост

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

Кстати говоря, я указал (потому что так было написано в оригинальной статье), что цель шлюзового сервера - управление TCP соединениями. Это не совсем так. На самом деле этот паттерн может работать с любым протоколом с контролем состояния (англ. stateful), будь это TCP, Reliable UDP с эмуляцией сессий, Websockets и любые им подобные. Главное, чтобы протокол поддерживал постоянно открытым соединение между двумя точками (клиент и сервер). Для HTTP этот паттерн бесполезен. То есть если вы делаете браузерную игру, которая для того, чтобы послать сообщение серверу, каждый раз открывает соединение и закрывает его в конце передачи, то выигрыша в производительности от распределенных сетевых соединений вы не получите. Пикабушник @Longtrain этот вопрос задал еще до начала моих переводов, за что ему отдельное спасибо. Если вы решили построить коммуникации на чем то подобном, весь наш паттерн превращается в обыкновенную балансировку нагрузки между монолитами. Например, можно подсоединить несколько монолитов к Nginx, который будет перенаправлять каждый запрос от клиентов на случайно выбранный сервер. Без какой либо постоянной привязки игрока. Вообще все представленные паттерны, о которых я рассказал и расскажу, вырождаются в намного более простые схемы в случае с HTTP, поскольку мы не испытываем нагрузки от долговременного поддержания соединения между игроком и сервером. Микросервисная архитектура вам в помощь.


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

Общие советы по проектированию шлюзового сервера


1. Шлюзовый сервер должен всецело заниматься вопросами управления состоянием соединений клиентов и сеансов соединений, а также доставкой сообщений нужным серверам и клиентам. В обязанности так же может входить шифрование/дешифровка и кодирование/декодирование потока данных между шлюзом и клиентом.

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

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

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

5. Ограничьтесь хранением только состояниям клиентского соединения. Не храните никаких данных игроков, значимых для геймплея.

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

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

8. При желании вы можете придумать/поискать систему динамического масштабирования, которая бы позволила вам добавлять/убирать сервера "на лету", без перезапуска всей сети. Тут надо прояснить чуть-чуть. Для того, чтобы открыть соединение к игровым серверам, шлюз должен иметь список их ip адресов и портов. Простейшим вариантом является предоставление этого списка в текстовом файле, который шлюз будет считывать при запуске - в этом случае для любого изменения количества игровых серверов надо перезапустить всю сеть. Если же шлюз может постоянно получать этот список извне в реальном времени и на основании него открывать и закрывать соединения с игровыми серверами, то это уже можно назвать системой динамического масштабирования. Можете поискать по запросу "service resolving".

Что получаем в результате?


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

Логическое обоснование паттерна


Создание и поддержка новых TCP соединений сильно "бьет" по загрузке процессора и оперативной памяти. Нагрузка на них растет линейно (O(N)) от количества игроков. Декодирование и дешифровка пакетов дает еще большую вычислительную нагрузку. Сложность превращается в O(N*M), где N - количество клиентов, а M - количество пакетов, полученных каждым клиентом.


В большинстве MMO игр присутствуют ходьба, прыжки, бег, бой и прочие действия, то возникают вследствие повторяющегося ввода от игроков. Это приводит к появлению постоянного плотного потока сообщений с каждым клиентов. Частью "M" в формуле O(N*M) становится уже невозможно пренебрегать. При попытке справится с такой нагрузкой внутри того же процесса (программы/физической машины), на котором обрабатывается игровая логика, мы расплачиваемся ценой комфорта игроков. Однако, если мы отделим эту часть работы от остальной части игры, мы выиграем сразу в двух позициях: в общей вместимости серверов при тех же мощностях и в гибкости их масштабирования.


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


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

Автор оригинала: Mattew Walker

Ссылка на оригинал: https://gameserverarchitecture.com/2015/10/pattern-distributed-network-connections/

Показать полностью 7

[Engines of Delight] Монолитная архитектура сервера

[Engines of Delight] Монолитная архитектура сервера Перевод, Онлайн-игры, Архитектура по, Mizzdev, Engines of delight, Мультиплеер, Игродел, Gamedev, Длиннопост

Постановка задачи


Итак, наша цель - создать сервер для сетевой игры с клиент-серверной моделью.


Прим. пер.: зачем вообще было выделять тот факт, что модель - клиент-серверная? Разве это не очевидно? Вот вам ответ - кроме клиент-серверной модели сетевых игр есть еще так называемые модели p2p (peer-to-peer), где каждый клиент связан со всеми остальными прямым соединением и каждый клиент рассылает свое внутреннее состояние остальным. Эта модель была исторически первой, но в силу недостатков стала пережитком времени и сейчас практически не используется, поэтому (по моему скромному мнению) работа с такой моделью сетевого взаимодействия рассматриваться в этом цикле статей не будет. Однако, любопытные всегда могут погуглить :)


Мы стремимся проработать игру так, чтобы максимально вовлечь игрока в игровой процесс, укладываясь при этом в определенные ограничения - как технические, так и по бюджету. По сути от нас требуется найти баланс между богатством игровых фич в онлайн игре, количеством игроков онлайн, погруженностью игроков в нашу игру (англ. immersion) и размером/сложностью игрового мира. Найдя правильный баланс мы облегчаем реализацию сервера, его разворачивание и поддержку.


Прим. пер: думаю, стоит разъяснить термин "разворачивание":

Разворачивание (англ. deployment), или в простонародье деплой - процесс, что заключается в приведении всего программного и аппаратного обеспечения в рабочее состояние в определенном окружении. Включает в себя - установку, настройку, запуск, тестирование и внесение изменений.


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


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

Знакомьтесь - монолитная архитектура!

[Engines of Delight] Монолитная архитектура сервера Перевод, Онлайн-игры, Архитектура по, Mizzdev, Engines of delight, Мультиплеер, Игродел, Gamedev, Длиннопост

На картинке - монолитная архитектура для игры в жанре First Person Shooter

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

[Engines of Delight] Монолитная архитектура сервера Перевод, Онлайн-игры, Архитектура по, Mizzdev, Engines of delight, Мультиплеер, Игродел, Gamedev, Длиннопост

На картинке - монолитная архитектура для игры в жанре Multiplayer Massive Online Role Play Game (MMORPG)

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

В каких случаях имеет смысл использовать монолитную архитектуру?


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

2. Для всех разработчиков критично иметь возможность запустить сервер и протестировать его у себя на личном компьютере вне зависимости от наличия сети.

3. Минимальные возможности по созданию инструментов для дальнейшей поддержки проекта.

4. Приходится экономить на расходах на аренду мощностей, содержание сети и содержание команды разработки.

5. Нужно обеспечить максимальную простоту разворачивания сервера, возможно даже предоставляя эту возможность третьим лицам, в том числе игрокам.

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

7. Вас устраивает тот факт, что для увеличения количества игровой аудитории вам придется разворачивать больше серверов на большем количестве машин (что после определенного придела становится всё накладнее - прим. пер.).

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

9. У вас нет возможности постоянно добавлять новые фичи, либо изменять существующие без того, чтобы испортить впечатления от игры в целом.

Что получаем в результате?


На выходе у нас цельное (англ. stand-alone - имеется в виду, что представляет собой единую программу, например .exe файл в системах семейства Windows - прим. пер.) приложение, которое легко разворачивается и успешно справляется с первоначально поставленными целями игрового дизайна. Вместимость серверов по количеству игроков легко (на первых порах) можно расширить увеличением мощности железа. Если же надо постоянно добавлять новые фичи и наращивать вместимость, постоянно повышая максимальный онлайн, скорее всего, лучше перейти к более сложным распределенным архитектурам (о них в следующих длиннопостах - прим. пер.), либо вообще начать с чистого листа.

Логическое обоснование паттерна


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


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

Какие известные игры имеют монолитные сервера?


- FPS: Quake 2, Unreal Tournament, Counter Strike, Battlefield, Call of Duty

- Игры в жанре MOBA (Multiplayer Online Battle Arena)

- Очень маленькие MMO игры с ограниченной аудиторией

Всем спасибо за внимание! В следующем переводе я расскажу, о том, как превратить монолит в распределенную архитектуру, как это всё дело масштабируется при очень небольших накладных расходах, по сравнению с монолитом. Этот паттерн гораздо сложнее монолита, поэтому разъяснений будет от меня намного больше  - я постараюсь дать максимальное понимание того, как это осуществляется на практике. Дам советы по тому, как такие системы тестируются на работоспособность перед деплоем в продакшн. Некоторые вещи не смогу, правда, включить в следующую статью, например о бенчмарках (тестах производительности) - это отдельная, объемная тема, стоящая отдельного поста. А пока не стесняйтесь задавать свои вопросы в комментариях!


Автор оригинала: Mattew Walker

Ссылка на оригинал: https://gameserverarchitecture.com/2015/10/pattern-monolithic-architecture/

Показать полностью 2

Перевод статей о разработке онлайн игр, а также их архитектуре

Привет, Пикабу!


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


Многие из подписчиков этого сообщества наверняка хотя бы раз задумывались о разработке онлайн игры. Но до фактического выпуска "доживают", как правило, лишь немногие проекты. Очень немногие. Большая часть, конечно, забрасывает эту затею, едва прикинув масштабы работ, изначально пытавшись замахнуться на "убийцу ВоВки, линейки и иже с ними". Думаю, не стоит объяснять очевидную провальность таких идей в зародыше.


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


Расскажу чуть о себе: вот уже почти 6 месяцев я занимаюсь разработкой мобильной онлайн игры. Не один, конечно - рядом со мной есть парочка таких же отчаянных ребят. У всех нас есть опыт разработки синглплеерных игр, в том числе коммерчески успешных. Но когда мы решили посмотреть в сторону мультиплеера - мы понимали, что это будет та еще задача. У нас не было опыта с разработкой сетевых приложений. Одно дело написать клиент, а совершенно другое - спроектировать сервер, который будет держать несколько тысяч человек и более. Нет, мы не планировали делать ММО - наша игра задумывалась очень простой по сравнению с мейнстримовыми продуктами. Но даже так мы понимали всю тяжесть предстоящих работ. Очень помог нам тот факт, что раньше я работал в веб-студии на фронтенде. То есть поверхностное представление о том, как оно всё по сети работает я имел. Но, одно дело верстать, писать JS код для браузера и садить это всё добро на CMS и совершенно другое - работать над игровым сервером. И я стал искать инфу - начиная от всяких видеоуроков на ютубе, заканчивая книгами и академическими статьями по конкретным темам. О самой игре рассказывать не буду, всё таки не пиарить ее я сюда пришел, да и есть для этого более подходящие средства, чем Пикабу, но на отдельные вопросы с радостью отвечу в комментариях. Далее пойдет речь именно об информации, что помогла воплотить нам нашу задумку в жизнь.


После месяцев скитаний по сети я наткнулся на блог "Engines of Delight" (gameserverarchitecture.com). Ведет его замечательный человек, которого зовут Мэттью Уолкер - человек с более, чем 25-ю годами опыта разработки сетевых игр. На данном ресурсе пролит свет на многие аспекты создания серверов для игр. Конечно, для полного понимания статей там крайне желательно знать хотя бы основы, такие как понятия Клиент/Сервер, как установить соединение между ними и организовать минимальный обмен пакетами. Лично для меня этот блог стал своеобразной библией построения сервера.


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

- Шаблоны проектирования игровых серверов (монолиты, распределенные сетевые соединения, балансировка нагрузки на стороне клиента, разбивка на региональные сервера, разбивка серверов по функциональности, сервера открытого игрового мира)

- Глоссарий терминов сетевой разработки

- Видеопрезентации о сетевых сервисах

- Ссылки на полезные ресурсы по темам


Я хотел бы перевести эти статьи на русский для русскоязычного сообщества, я уверен, что кому-то это поможет в разработке собственных проектов. О некоторых вещах в оригинальных статьях было рассказано, по моему мнению расплывчато, поэтому по возможности буду дополнять своими примечаниями и разъяснениями. Плюс ко всему многие из содержащихся там идей я сам в итоге применял, поэтому не стесняйтесь спрашивать в комментариях по поводу трудных моментов - с радостью отвечу. А то, чего не знаю, по возможности спрошу у самого автора оригинальных статей. К счастью, я с ним уже довольно таки общаюсь. Друзья, насколько полезными для вас будет ознакомиться с переведенными статьями на эту тему? Всё таки это выйдет больше чем на один длиннопост и я хотел бы, чтобы это было не зря.


Простите, что так сумбурно вышло :)

Показать полностью
Отличная работа, все прочитано!