Когда в Telegram начали появляться первые кликер-игры вроде Notcoin, стало ясно: мессенджер идеально подходит для лёгких и социальных игровых проектов. Никаких установок, просто открыл ссылку и играешь.

До MoonTap у меня уже был опыт в смежных областях: я занимался разработкой криптообменника, работал с Web3, интегрировал bitcoind и другие ноды. Это дало понимание того, как устроены транзакции, работа с блокчейном и распределённые системы.

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

В статье расскажу о том, как я реализовал проект технически: от выбора Rust для бэкенда до Canvas анимации на фронте и интеграции с Telegram WebApp API.

Немного про бэкграунд

До MoonTap я в основном писал бэкенд на Node.js: NestJS, Mongoose, Redis, BullMQ - привычный стек, с которым легко и быстро собирать сервисы.

Параллельно я поглядывал на Rust: делал на нём вспомогательные утилитки, пробовал Axum и Diesel, в общем, хелоуворлдил :D

MoonTap стал первым серьёзным проектом, где я решил использовать Rust как основной язык для бэкенда.

Почему:

хотелось проверить Rust на реальной продакшн нагрузке

нужен был очень быстрый ws сервер для десятков тысяч игроков

хотелось попробовать серьёзный стек, а не очередной стильномодномолодёжный MERN

Архитектура проекта

Фронтенд

Telegram WebApp на Vue 3 + Vite + TailwindCSS. Весь UI главного экрана рисуется в canvas.
Так же canvas использовал для красивого фона для карточек тасок. (Возможно избыточно, но в процессе рабработки угорел по canvas). Все остальное обычные vue компоненты.

Как это выглядит

Бэкенд

Всего 5 сервисов

Сервис

Описание

Технология

auth

Проверяет initData от Telegram WebApp, удостоверяется, что запрос действительно пришёл из Telegram, и что пользователь не заблокирован. В ответ выдаёт короткоживущий JWT для подключения к ws серверу

Rust

ws-backend

Поддерживает ws подключения игроков, принимает игровые события (клики, бустеры, задания), кладёт их в очередь и возвращает обновлённое состояние

Rust

tg-bot

Собственно, сам бот телеграм

Node.js

subscribe-checker

Проверяет факт подписки на тг канал

Rust

adv

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

Rust

Если интересны пакеты которые я использовал с радостью скину toml и json файлы.

Почему не Node.js

Конечно, игру можно было бы собрать и на NestJS + Redis + Postgres, и это работало бы. Но Rust даёт ощутимые плюсы:

меньше потребление памяти при большом количестве ws соединений

низкие задержки благодаря Tokio

типобезопасность: многие ошибки ловятся ещё на этапе компиляции, а не в рантайме

Хранилище

PostgreSQL для основной логики и Redis для временных данных, кэша и очередей.

Балансировщик

В качестве балансировщика используется nginx, который по алгоритму round robin распределяет подключения между ws серверами.

Пока это простое решение, но оно работает надёжно. Возможно, знатоки в комментариях подскажут более оптимальные подходы для highload нагрузки, так как я не позиционирую себя как devops специалиста.

Модель данных

База данных выглядит так:

Таблица

За что отвечает

users

профиль игрока: баланс, энергия, уровень

boosters

справочник бустеров (с JSON-описанием эффектов)

user_boosters

активированные бустеры и их таймеры

referrals

кто кого пригласил (и факт награждения)

tasks

список заданий

user_tasks

прогресс игрока по задачам

user_history

лог действий (для аналитики и откатов)

subscribe_checks

проверки подписки на каналы

Такое разделение позволяет расширять механику без изменения кода - достаточно добавить новые бустеры или задания в БД.

Масштабирование

Один инстанс сервера выдерживает десятки тысяч ws подключений
покажет время, может быть я ошибаюсь

Запускаю по 6 инстансов (по числу CPU)

Nginx балансирует входящие соединения

Redis выступает как шина для синхронизации и очередей

Итоги

MoonTap стал для меня проектом-переходом: от привычного Node.js к Rust. Я убедился, что Rust подходит не только для системного кода, но и для реальных highload бэкендов.

Telegram WebApp оказался идеальной платформой для лёгких игр: вход через мессенджер, встроенная реферальная механика и готовая аудитория. Rust же дал стабильность и производительность, которые сложно выжать из Node.js на больших нагрузках.

MoonTap - это эксперимент, который показал: Rust + Postgres + Redis + Vue/Canvas отлично работают вместе, если хочется собрать real-time игру прямо внутри Telegram.

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

Ссылка на игру

Комментарии (2)


  1. Asantasan
    30.08.2025 11:05

    Хоть убейте, но зачем тут вэбсокеты? Вполне можно собирать батчи из кликов и отправлять уже их. А на фронте использовать optimistic ui концепцию. При отправке батча получать реальное состояние и синхронить его с состоянием на клиенте.

    Деление на сервисы с описанными вами областями ответственности тоже вызывает вопросы, но я не бэкенд разработчик, поэтому не мне судить.


  1. Jijiki
    30.08.2025 11:05

    классно если действие дало опыта, игры в телеграмме достаточно специфичное удовольствие всегда интересно запускать саму игру, и тут как бы не пришлось учиться по новой ради какого-то кликера, в тот же момент если бы можно было пойти по альтернативному пути, то можно было бы обойти телеграм в угоду своей программки с кликером (building-an-android-app-with-rust-and-sdl2/)

    я себе так пазл делал на телефон(но на С++) иногда посматриваю на телефоне, но там порт с ПК, на самом деле ничего сложного, есть библиотеки которые перегоняют код на андроид