Мы сделали свою игру в Telegram со строительством башни из серверов
Делимся инструкцией, как повторить ее или любую другую игру в мессенджере.
В 2016 году в Telegram появились игровые боты — чат-боты с простыми HTML5-играми (запускаются прямо на странице браузера), в которые можно поиграть с собеседником, в группах или в приватных чатах. Создать собственную игру может каждый пользователь мессенджера — это бесплатно и, по заверениям разработчиков Telegram, очень быстро: на их создание уйдет всего 3–5 часов.
Мы решили разобраться, что представляют собой игровые боты и зачем они нужны. А в процессе создали собственную корпоративную игру со стройкой самой высокой серверной стойки в мире.
Как казуальным играм в мессенджере удалось найти место в мире кинематографичных игр для ПК и консолей
Простые игры, подобные тем, которые предлагает Telegram, появились еще в ICQ и сразу завоевали любовь пользователей (некоторые скучают по ним до сих пор). Игры в Telegram по набору функций недалеко ушли от предшественников: они не устанавливаются на смартфон, а запускаются напрямую в браузере клиента (будут работать на ПК, iPhone 4 и новее и Android версии 4.4 или выше).
Преимущество простых игр в мессенджере — низкий порог входа и простота геймплея: с управлением разберется даже дедуля. Найти игры можно через бота Gamee или перейдя по ссылке конкретной игры — например, вот такой с дровосеком. Перед запуском бот предложит поделиться игрой в личном чате (даже с самим собой) или беседе на несколько человек — сыграть в большинство игр можно как одному, так и в компании.
В большинстве игр цель одна — набрать как можно больше очков и обойти по результатам своих друзей. Для каждого чата своя турнирная таблица. Когда в игре появляется новый лидер, все участники чата получают уведомление.
По условиям, с которыми вы должны согласиться перед созданием, нельзя монетизировать игры или оставлять внутри ссылки на сторонние ресурсы. Но это еще не значит, что игра в мессенджере может существовать только как пет-проект, сделанный от скуки.
Пофантазировали, как еще можно применить игрового бота:
- Как рекламный спецпроект. Разработать тематическую игру, в которой потенциальные покупатели могут выиграть приз, скажем, решив непростую головоломку. Если взять за основу знакомую многим механику с трубами, то сервис такси может запутать дорожки, а сервис доставки цветов — лианы растений.
- Как корпоративный или обучающий тренажер. Составить викторину на проверку изученного, например, по итогам онбординга, в которой новичку предстоит за ограниченное время ответить на несколько вопросов о компании.
- Как нестандартный подарок. Собрать для именинника игру-пазл с поздравительной открыткой.
Мы решили протестировать разработку телеграм-игр на первом примере. В рамках эксперимента сделали простой кликер со строительством башни из наших серверов. Запускайте игру в нашем чате сразу или прежде прочитайте статью — в ней мы описываем процесс подготовки дизайна и разработки игры и оставляем все необходимые для повторения нашего опыта компоненты.
Дизайн — как может выглядеть игра и какие ограничения накладывает мессенджер
Если коротко, никаких специальных условий выполнять не нужно — дизайн игры для мессенджера ничем не отличается от обычной HTML5-игры. Проследить стоит разве что за весом картинок — фона и игровых элементов: слишком тяжелые объекты затормозят загрузку и игровой процесс. Поэтому, например, между растровыми и векторными изображениями стоит выбрать последние.
Специфических ограничений по весу картинок у Telegram нет. Если ваша игра легко прогрузилась в обычном браузере, она будет без проблем работать и в браузере мессенджера.
Мы решили реализовать идею игры в духе Tower Bloxx — построить из наших серверов самую высокую серверную стойку. Для теста игровых ботов не хотелось разбираться с физикой, чтобы блоки на кране и сама башня раскачивались натуралистично. Поэтому сложности мы добавили летающим туда-сюда Тирексом — бренд-персонажем Selectel.
По задумке, стройка башни начинается в подземном ЦОДе, затем он сменяется видами города, а после 50 блоков — космосом. Фон у нас вышел почти в 23 000 пикселей, и с его отрисовкой не справилась часть Android-смартфонов во время тестирования — его пришлось разрезать на четыре части.
Окно мессенджера может растягиваться, поэтому ваша игра должна быть адаптивной и работать с любыми разрешениями, как любые современные сайты. Для слишком больших окон можно добавить небольшие поля (мы так и сделали), потому что рендеринг изображений на больших экранах мог отнять слишком много ресурсов.
Разработка — что под капотом у игрового телеграм-бота
Игры в Telegram можно создать с использованием любых технологий и библиотек, доступных в браузере. Можно написать крестики-нолики на чистом JavaScript или использовать WebGL-библиотеки и работать с 3D-графикой.
Мы воспользовались движком Pixi.js — нам он показался удобным для работы с объектами и их столкновениями. У Pixi.js довольно подробная документация, с которой сможет разобраться любой фронтенд-разработчик. Даже тот, у которого не было опыта создания игр (как у нас).
В движении крана нам все-таки пришлось использовать растровую графику: с векторными анимациями (lottie-файлами или другими видами svg-анимации) наш игровой движок работать не умеет, а анимировать по частям движения двух частей крана кодом довольно долго. Поэтому мы заанимировали это движение отдельно и вставили уже готовую анимацию.
Чтобы сделать это, нам пришлось разобраться со спрайт-листами — наборами всех элементов графики. Спрайт — это, по сути, любая картинка, в нашем случае это один кадр анимации. Загружать 30 картинок каждую отдельным файлом дольше и ресурсозатратнее, чем загрузить одну картинку с несколькими спрайтами.
Чтобы игра заработала с Telegram, она должна быть доступна через интернет и должна отправлять очки в API Telegram. Для этого нужно создать веб-сервер, который:
- получает новые сообщения из Telegram;
- отдает игру с отмеченным идентификатором игрока;
- принимает от фронтенда очки игрока и отправляет их в API.
Этот код можно переиспользовать для любой игры с минимальными изменениями.
Объединяем фронт и бэк
Теперь нужно сделать так, чтобы в конце игры очки пользователя отправлялись с фронтенда на бэкенд. Наша игра будет доступна по адресу t-rex-game.ru, и на бэкенде уже реализован роут по адресу /highscore/, принимающий очки. Поэтому из игры нам нужно просто отправить запрос https://t-rex-game.ru/highscore/${score}/?id=${id} с подставленными очками и идентификатором пользователя.
Идентификатор пользователя мы передаем в ссылке на саму игру, остается лишь сохранить его себе на время, чтобы вернуть обратно уже с количеством очков. Все общение на фронтенде занимает около десятка строк.
Кроме самой игры нам понадобятся:
- Сервер, с которого пользователи будут подгружать игру и на котором будет поднят телеграм-бот. Поднимем бюджетный вариант на Selectel за 700 рублей в месяц.
- SSL-сертификат. Telegram работает с играми по протоколу HTTPS, поэтому нам нужен сертификат для безопасного общения, привязанный к конкретному домену или поддомену. Его получим бесплатно с Let’s Encrypt.
Теперь подробнее о каждом пункте.
Поднимаем сервер в Selectel
Регистрируемся на selectel.ru и пополняем баланс. Для игры не нужен мощный сервер, поэтому воспользуемся линейкой Shared Line — это недорогие облачные серверы для решения небольших задач, на размещение игры в течение месяца мы потратим чуть более 700 рублей.
На панели управления выбираем раздел «Облачная платформа» и создаем новый сервер.
Серверы Shared Line сейчас доступны в Санкт-Петербурге, Москве и на нашей зарубежной площадке — в пулах ru-1b, ru-3b, ru-9a, ru-2c, ru-7a и nl-1a. От расположения сервера зависит скорость доступа пользователей из разных городов. В нашу игру будут играть по всей России, поэтому выбрать можно любой из подходящих пулов в Москве или Санкт-Петербурге.
Подходящая нам ОС — Ubuntu 20.04, однако можно выбрать одну из большого списка, либо загрузить свой образ ISO или виртуальной машины.
Выбираем фиксированную конфигурацию сервера из линейки Shared Line — это облачные серверы с возможностью оплаты только части ядра. Доля vCPU отражает гарантированную производительность сервера, при этом реальный уровень может оказаться выше в зависимости от нагрузки на хост. У нас всего пара процессов (о них ниже в статье), поэтому хватит и одного ядра, но доступного хотя бы на 50%. А даже если этого не хватит — сменить конфигурацию сервера можно в любой момент.
Завершаем настройку — выбираем размер диска (мы не собираемся хранить много файлов, а для ОС и кода хватит 5–10 Гб), выбираем один публичный IP и запоминаем пароль от root-пользователя либо загружаем публичный SSH-ключ.
Нажимаем на кнопку «Создать сервер» и ждем меньше 30 секунд, пока сервер не установится и его статус не сменится на Active.
Мы получили IP-адрес сервера — теперь к нему можно подключиться по SSH командой ssh root@<ip-адрес> или нажав справа на иконку терминала — тогда он откроется прямо в браузере.
Подключим к нему домен. В настройках DNS-хостинга вашего домена указываем A-запись на нужный домен или поддомен со значением в виде IP-адреса нового сервера. Если у вас новый домен и еще нет DNS-хостинга, вы можете подключить бесплатный DNS-хостинг прямо на панели управления.
Подключаемся к серверу по SSH либо через консоль на сайте vds.selectel.ru и настраиваем ngnix — быстрый веб-сервер, который возьмет на себя работу с SSL:
Запускаем nginx:
Переходим в папку с конфигурацией сервера и создаем файл конфигурации:
Теперь этот файл нужно открыть любым текстовым редактором (например, Nano, вот так: nano nodeapp.conf) и добавить в него настройки сервера, заменив example.com на нужный вам домен:
Сохраняем файл. Теперь ngnix будет перенаправлять все запросы к нашему домену на 3000 порт, по которому отвечает бэкенд, который мы создали выше (но еще не запустили).
Проверяем, что в конфигурации нет ошибок:
Получаем ответ «syntax is ok» и «test is successful», перезапускаем nginx:
Сгенерируем бесплатный SSL-сертификат от Let’s Encrypt, чтобы наша игра была доступна через HTTPS. Воспользуемся утилитой Certbot, устанавливаем ее:
И генерируем сертификат:
Готово, теперь наш сервер отвечает по HTTPS. Осталось настроить несколько переменных и запустить его. Поднимем бота, который по запросу будет запускать игру с сервера.
Создаем бота в Telegram
Пишем t.me/botfather — это служебный бот Telegram для создания других ботов. Первая команда, которая нам нужна, — /newbot, следуем инструкциям и получаем access-токен.
Включим возможность делиться игрой с друзьями через inline-запросы:
И наконец, создаем игру командой /newgame. Принимаем условия создания игр, добавляем название, описание, обложку (картинка 640×360 с любым содержанием), превью (гифка того же размера, необязательна) и название игры, которое пригодится нам позже.
Настраиваем сервер и объединяем составляющие
Устанавливаем Docker — систему контейнеризации, которая позволит нам создать Docker-контейнер для нашего кода, чтобы не разбираться с установкой node.js, npm и зависимостей, все запустится почти само собой.
Далее из нашего репозитория вам понадобятся env.example, Dockerfile, index.json и package.json. Копируем их на сервер.
Открываем env.example, подставляем в него токен, выданный BotFather, ссылку на наш фронтенд, доступный из интернета, и ID игры, который мы сообщили BotFather. Переименовываем env.example в .env (mv env.example .env).
Не забываем в своем фронтенд-коде настроить отправку очков на нужный домен, у нас это делается заменой одной строки с адресом.
Создаем Docker-образ приложения:
Точка в конце — путь до папки с нашими файлами, если мы находимся в ней, то путь до нее — это как раз «.».
Запускаем приложение:
Готово!
Тестируем игру
В бета-версию мы дали поиграть коллегам — чтобы отловить баги и доработать игровой процесс. В первой версии игра оказалась слишком простой: тираннозавр летал на одном уровне, с одной скоростью и интервалами. Мы ускорили помеху и сделали ее менее предсказуемой, а затем протестировали снова:
На этом результате мы остановились, и вторая версия стала финальной — заглядывайте протестировать самостоятельно. Среди самых увлеченных тестировщиков в этом чате (тех, кто построит башню выше 100 этажей) мы разыграем 10 наборов мерча Selectel.
Результаты подведем 22 ноября 2022 года на канале Selectel (подписка на канал — одно из условий участия в конкурсе). Полные правила — здесь.
Где храните рейтинг игроков?
Кирилл, здравствуйте!
Рейтинг игроков хранится в самом телеграме, мы отправляем его сразу в сообщение с игрой. Для иллюстрации прикрепляю скриншот, который мы использовали в статье.
Для конкурса мы добавили свою прослойку для хранения очков, для обычных игр она не нужна, поэтому ее нет в нашем открытом репозитории.
Я имел в виду у себя на серверах, просто таблица в ДБ?
Очки пользователей хранить необязательно — в коде видно, что они отправляются напрямую в телеграм, чтобы не тратить память на сервере