Всем привет! Меня зовут Максим и я хочу рассказать вам историю создания проекта Wasteland Wars. Надеюсь, вам будет интересно, и, возможно, что-нибудь из этого сможет помочь вам избежать моих ошибок.
Выбор платформы
Telegram – очень нестандартная платформа для создания онлайн игр. Тем более, когда речь заходит о ММОРПГ. Мне стало интересно, возможно ли вообще создать качественный продукт на этой платформе, а если да – будет ли вообще востребованность в нем. Так, в июне 2017-го года я начал разработку Wasteland Wars.
Виральность
В первые дни разработки было решено собрать фокус-группу из своих знакомых для теста игры. Как-никак, имея дело с ММО, тестировать в одиночку было проблематично. Так я запустил закрытый бета-тест игры, сделав доступ к боту по одноразовым ключам. Сгенерировав таких 10 штук, я разослал их своим знакомым в ТГ. Реферальная система уже была добавлена к этому моменту, хоть и не работала по факту в виду закрытости тестирования. Ее суть в том, что за каждого зарегистрированного в игре человека по твоей реф. Ссылке, игрок получает +1 к максимальному запасу выносливости и немного крышек (местная валюта) на карманные расходы. Это привело к тому, что спустя 2 недели с начала ЗБТ, в нем принимало участие уже 50 человек, а мои личные сообщения были забиты просьбами людей дать им еще 1-2-10 ключей для своих друзей. Вместо того, чтобы постоянно генерировать новые ключи, я принял решение сосредоточиться на исправлении найденных в тестировании багов и запустить открытый бета-тест, отменив регистрацию по ключам. За первый день ОБТ в игре зарегистрировалось 120 человек. Спустя месяц суточный онлайн составлял 200-250 человек в день, а общее количество зарегистрированных игроков приближалось к 800. И все это без каких-либо движений с моей стороны по пиару игры, игра становилась известной исключительно благодаря сарафанному радио и реферальной системе.
Особенности проекта, понравившиеся игрокам
Игроки во время тестирования отмечали крайне необычный для такого формата жанр игры, полноценные ПВП сражения и систему прокачки игрока без классических очков навыков и системы level-up’ов. Но, что стало для меня неожиданностью – больше всего люди хвалили игровые тексты, особенно отмечая качество юмора, отсылки к массовой культуре и атмосферные ситуации, контрастирующие с черным юмором своей драматичностью.
Технические нюансы
Первые сложности, связанные с платформой Bot API, возникли в первые же дни разработки. У Telegram есть 2 основные системы для связи их ботов с вашим сервером: так называемые Long Polling и Webhooks. Первая подразумевает, что ваш сервер будет с определенным интервалом постоянно опрашивать Telegram на предмет наличия новых запросов, и при наличии таких — обрабатывать, возвращая ответ Bot API. Второй же чуть более сложен в реализации – он заключается в том, что ваш сервер как-бы говорит Telegram «если у тебя появятся какие-то запросы – кидай их вот на этот адрес». Соответственно, для реализации бота на технологии Webhooks необходим постоянный IP адрес и обязательно SSL сертификат, хотя бы самоподписанный. Начав разработку на основе Long Polling, я в начале не заметил никаких проблем, связанных с этим методом. Однако спустя сутки беспрерывной работы, бот неожиданно упал. Telegram начал возвращать ошибку при получении запроса. Как оказалось, эта проблема преследует абсолютно все боты на основе Long Polling – телеграм закрывает обработку запросов от бота спустя какое-то время, из-за чего приходится его постоянно перезагружать. Сперва я решил попробовать автоматизировать процесс «реанимации» бота, написав cron-скриптик для проверки пульса процесса и перезапуска, если пациент не реагировал на тыканье палкой. Однако этот процесс постоянных перезапусков доставлял неудобства игрокам, т.к. занимал какое-то время, а так же сбрасывал текущие таймеры в игре. В итоге проект был перенесен на Webhooks, и данная проблема сразу же исчезла.
Дальше в плане сложностей от самого Bot API все было спокойно. До одного момента.
Проект набирал масштабы, наращивал аудиторию и постоянно развивался. В один момент бот неожиданно начал «подтупливать» при получении запроса. А точнее, появилась задержка в ответе бота игроку. Первым делом я полез на сервер, думая что он перестал справляться с растущим количеством запросов. Но нет, нагрузка на сервер не превышала 30% в пиковые моменты, не наблюдалось проблем со свободной памятью, не было никаких ошибок и предупреждений в логе системы. Но тормоза продолжали расти. Как оказалось, бот стал упираться в лимит Bot API по количеству одновременных запросов к нему. В первое время, я успешно уменьшал и оптимизировал работу бота, чтобы снизить это количество. Однако по мере распространеия игры в массы, стало очевидно: очень скоро бот упрется в этот потолок и никакие оптимизации с моей стороны не помогут. Тогда было решено написать в поддержку Telegram с просьбой увеличить лимиты конкретно для моего бота. И к моему огромному удивлению, они ответили уже на следующий день, а лимит был увеличен, хоть новый порог они и не назвали. Кроме того, они сообщили мне, что бот упирается в лимит по конкретному типу запросов – Callback на т.н. Inline-кнопки. Это клавиатура в Telegram, которая отображается под конкретным сообщением. На текстовые запросы (в том числе и с обычных кнопок) лимит значительно выше, а так же нет ограничения в 15 секунд на ответ от сервера. Проблема была в том, что 70% интерфейса игры было построено на Inline-кнопках. Мне пришлось практически полностью его переработать, чтобы избавиться от этого зла, такого удобного и красивого.
Следующая проблема, с которой столкнулся проект, крылась уже в моей среде разработки и коде. А конкретно, в Python 3 и в том, как он работает с потоками. Каждый новый поток в Python 3 создается вместе с переменными окружения, занимая большое количество памяти. В игре полно таймеров (2 минуты на переход между локациями, ожидание битвы и т.д.), и запуская их в отдельных потоках, создавалась утечка памяти. По мере роста онлайна игры, утечка достигла каких-то безумных масштабов, сжирая всю возможную оперативную память и подкачивая оставшуюся память SSD сервера. Разумеется, проблема была решена созданием очередей таймеров, обрабатывающихся в одном потоке для каждого типа.
Визуальная часть в текстовой игре
Одной из ключевых особенностей Wasteland Wars относительно остальных похожих игр в Telegram стало введение визуальной части. В игру был добавлен интерактивный аватар персонажа, а так же визуальное отображение каждого элемента экипировки в игре. Как в полноразмерных РПГ на игровых платформах, игрок может одевать своего персонажа в разную броню, давать ему разное оружие, а затем видеть все изменения визуально. Чуть позже я развил эту идею, теперь при встрече другого игрока в игре выводится так же его аватар – так появляется возможность не зная прокачки противника, оценить его опасность по внешнему виду. Помимо экипировки, на аватаре так же отображаются «Маски» — их можно купить за донат, они не дают никакого преимущества игроку, но изменяют его вид в аватаре. Кроме того, в игре появилась полноценная интерактивная карта. По мере нахождения какой-либо локации, она добавляется игроку на карту.
Все изображения выводятся в довольно низком разрешении, достаточном для понимания их контента. Это связано с тем, что аватары и карты собираются из множества разных элементов для каждого игрока, и при большом количестве одновременных запросов их сборка в высоком разрешении может существенно нагрузить игровой сервер.
Планы по развитию проекта
В данный момент игра переписывается на Go – этот язык, как оказалось, гораздо лучше подходит для разработки такого проекта. Наличие собственного веб-сервера в Go и его скорость работы позволила мне начать создание собственного API для проекта, чтобы отвязать его от одной единственной платформы в Telegram. API позволит получать и обрабатывать запросы с любого клиента, а вся логика будет обрабатываться только на сервере.
Таким образом, разработка клиента под любую платформу будет максимально простой, как и сам клиент, это позволит избежать многих ограничений Telegram, сложностей с его блокировкой, а так же привлечь большое количество новой аудитории в игру.
Автор: maksimgazizov