Всем привет. Пока мои друзья сражаются в «обычных» шутерах или проходят сюжетные RPG, я сижу в тени. Нет, не потому что меня забанили. Просто я смотрю на игры иначе. Я не могу просто играть — мне хочется понять, как они устроены, разобрать их на винтики и собрать заново. Моя страсть — это разработка, но когда речь заходит о досуге с друзьями, на сцену выходит Telegram. Именно здесь, в привычном мессенджере, я нашел идеальный полигон для своих экспериментов. И сегодня я расскажу, как создавать игры для Telegram, в которые, возможно, скоро сыграют и ваши друзья.

Распишу пошаговый разбор процесса: от идеи до работающего бота с оригинальным движком Dino из Chromium

В этой статье я расскажу:

  • Как я взял оригинальный код Chrome Dino и адаптировали его под Telegram

  • Какие проблемы были с BotFather и кнопкой меню

  • Как задеплоил всё на бесплатный хостинг ботов

  • Сколько времени заняло и сколько стоило

Идея была сделать игру для Telegram

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

  • Использовать не упрощённую копию, а оригинальный движок T-Rex Runner из кода Chromium (лицензия BSD)

  • Добавить Telegram-бота с красивым меню, картинкой и кнопками

  • Разместить всё на бесплатном хостинге с HTTPS

  • Прикрутить команды /start, /game и обработку текста

Зачем? Чтобы доказать: полноценный Mini App можно запустить за вечер и бесплатно.

Инструменты

  • Оригинальный код dino.js и dino.css (Copyright 2014 The Chromium Authors)

  • HTML5 Canvas — отрисовка

  • JavaScript — логика

  • Node.js + Express — серверная часть

  • Telegraf — библиотека для Telegram-бота

  • BotHost — бесплатный хостинг ботов с поддержкой Mini-app

Шаг 1. Структура проекта

Создаем каталог Dino-Chrome-Game и внутри неё:

Dino-Chrome-Game/
 │
 ├── public/                 # Все файлы игры
 │   ├── images/             # Картинки игры
 │   │   ├── default_100_percent/   # Для обычных экранов
 │   │   │   ├── 100-disabled.png
 │   │   │   ├── 100-error-offline.png
 │   │   │   └── 100-offline-sprite.png
 │   │   └── default_200_percent/   # Для больших экранов
 │   │       ├── 200-disabled.png
 │   │       ├── 200-error-offline.png
 │   │       └── 200-offline-sprite.png
 │   │
 │   ├── sounds/ # Оригинальные звуки Chrome Dino
 │   │   ├── button-press.mp3 # Звук нажатия
 │   │   ├── hit.mp3 # Звук столкновения
 │   │   └── score-reached.mp3 # Звук рекорда
 │   │
 │   ├── dino.css # Основные стили
 │   ├── dino.js # Оригинальный движок игры
 │   ├── dino.min.css # Минифицированные стили
 │   ├── dino.min.js # Минифицированный движок
 │   └── index.html # Точка входа
 │
 ├── app.js # Сервер + Telegram-бот (Express + Telegraf)
 ├── package.json # Зависимости Node.js
 ├── .env # Токен бота (НИКОМУ НЕ ПОКАЗЫВАТЬ)
 └── README.me # Документация

Шаг 2. index.html — точка входа

Здесь всё максимально близко к оригинальному Chrome Offline Dino.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  <title>T-Rex Runner</title>
  <link rel="stylesheet" href="dino.css">
  <script src="dino.js"></script>
</head>
<body id="t" class="offline">
  <div id="main-frame-error" class="interstitial-wrapper">
    <div id="main-content">
      <div class="icon icon-offline" alt=""></div>
    </div>
  </div>
  <div id="offline-resources">
    <img id="offline-resources-1x" src="data:image/png;base64,...">
    <img id="offline-resources-2x" src="data:image/png;base64,...">
    <template id="audio-resources">
    </template>
  </div>
</body>
</html>

Никакого самописа. Это оригинальный код Chromium, выдернутый из исходников Google Chrome. Работает 1 в 1 как в офлайне браузера.

Шаг 3. dino.js — движок из Chromium

Мы не стали изобретать свой велосипед. Взяли готовый:

  • Runner — главный класс игры

  • Trex — физика прыжков

  • Obstacle — кактусы и птеродактили

  • Horizon — облака, земля, ночной режим

  • DistanceMeter — счёт и рекорды

Весь код — 800+ строк нативного JS. Никаких упрощений. Физика идентична браузерной.

function onDocumentLoad() {
 new Runner('.interstitial-wrapper');
 }

document.addEventListener('DOMContentLoaded', onDocumentLoad);

Запускается автоматически при загрузке страницы.

Шаг 4. style.css — оригинальные стили

Мы сохранили оригинальный дизайн Google:

  • Адаптация под мобилки

  • Тёмная тема (инверсия через класс .inverted)

  • Снакбары, анимации

  • Поддержка arcade-mode

Никакой самодеятельности. Это код, который прошёл ревью в Google.

Шаг 5. Сервер и бот

Вот тут мы отошли от Google и написали своё.

package.json

{
 "name": "telegram-dino-bot",
 "version": "1.0.0",
 "description": "Telegram бот с игрой Dino в Mini App",
 "main": "app.js",
 "scripts": {
 "start": "node app.js",
 "dev": "nodemon app.js"
 },
 "dependencies": {
 "express": "^4.18.2",
 "telegraf": "^4.12.2",
 "dotenv": "^16.0.3",
 "cors": "^2.8.5"
 },
 "devDependencies": {
 "nodemon": "^2.0.22"
 },
 "engines": {
 "node": "16.x"
 }
 }

app.js — серверная часть и бот

Скрытый текст
const express = require('express');
 const { Telegraf } = require('telegraf');
 require('dotenv').config();
 const cors = require('cors');
 const path = require('path');

const app = express();
 const PORT = process.env.PORT || 9256;

app.use(cors());
 app.use(express.json());
 app.use(express.urlencoded({ extended: true }));
 app.use(express.static('public'));

const WEB_APP_URL = 'https://dino.bothost.ru';
 const WELCOME_IMAGE_URL = 'https://radika1.link/2026/02/11/if9e2a3d45127c3e6.jpeg';

const bot = new Telegraf(process.env.BOT_TOKEN);

bot.start(async (ctx) => {
 try {
 await ctx.replyWithPhoto(
 { url: WELCOME_IMAGE_URL },
 {
 caption: '🦖 Добро пожаловать в Dino Chrome Game!\n\n' +
 'Запусти легендарную игру Dino Chrome прямо в Telegram! 🎮\n\n' +
 '🎯 Особенности:\n' +
 '• Высокая скорость игры\n' +
 '• Улучшай свои рекорды\n' +
 '• Весело проводи время!\n\n' +
 'Нажми кнопку "🎮 Играть", чтобы начать!',
 parse_mode: 'Markdown',
 reply_markup: {
 inline_keyboard: [
 [
 {
 text: '🎮 Играть',
 web_app: { url: WEB_APP_URL }
 }
 ],
 [
 {
 text: '🎁 Бесплатный хостинг',
 url: 'https://bothost.ru/'
 },
 {
 text: '📢 Наш канал',
 url: 'https://t.me/bothostru'
 }
 ]
 ]
 }
 }
 );
 } catch (error) {
 console.error('Ошибка:', error);
 await ctx.reply('Произошла ошибка. Попробуйте позже.');
 }
 });
Бот в Telegram
Бот в Telegram

Так выглядит приветственное сообщение бота с кнопками

Мы добавили:

  • Команду /game — отдельный запуск

  • Обработку callback_data для кнопки «Назад»

  • Умный reply на слова «игра», «dino», «🦖»

  • Эндпоинты /bot, /health, /status для мониторинга

Шаг 6. Деплой

6.1. Заливаем код на GitHub

Создали репозиторий любое название, запушили все файлы. Структура строго:

6.2. Деплой бота

Зайти на bothost.ru, войти через Telegram, нажать «Создать бота».

Заполняем форму:

Далее — «Дополнительные настройки»:

  • Указываете поддомен. Пример: myapp.bothost.ru

  • Указываете порт. Пример: 9256

Нажимаем «Создать».

6.3. Настраиваем кнопку меню в BotFather

Открываем @BotFather, команда:

/setmenubutton

Выбираем бота, текст: 🦖 Играть в Dino, URL: https://ваш-поддомен.bothost.ru

6.4. Проверяем

Открываем бота, нажимаем кнопку меню. Оригинальный Chrome Dino запускается внутри Telegram!

Игра в Telegram
Игра в Telegram

Оригинальный Chrome Dino, запущенный внутри Telegram Mini App

Возможные проблемы и их решение

Бот не отвечает

Проверьте, что в .env указан BOT_TOKEN и порт совпадает с тем, что в BotHost.

Игра не на весь экран

Оригинальный Dino не использует Telegram Web App API. Это не баг, а фича. Мы оставили как есть, чтобы сохранить аутентичность.

Если хотите expand — добавьте в index.html:

Мы в своей версии этого не делали, но в статье показываем, как добавить.

Нет звука

В Telegram Mini App звук не работает автоматически. Нужно разрешение пользователя. Мы отключили аудиоресурсы в template — игра всё равно отличная.

Результаты

Мы засекали время:

  • Подготовка репозитория — 10 минут

  • Настройка сервера и бота — 20 минут

  • Деплой на BotHost — 5 минут

  • Отладка — 20 минут

  • Настройка кнопки в BotFather — 2 минуты

Итого: 57 минут от пустого репозитория до работающего бота.

Стоимость:

  • Хостинг — 0 ₽ (бесплатный тариф у хостера)

  • Домен — 0 ₽ (поддомен у хостера)

  • SSL-сертификат — 0 ₽ (автоматически)

  • GitHub — 0 ₽

  • Исходный код Chromium — 0 ₽ (BSD лицензия)

Итого: 0 ₽.

Выводы

  1. Оригинальный код Google можно легально использовать. Лицензия BSD позволяет.

  2. Telegram Mini App — это не всегда про Telegram API. Мы вообще его не использовали, а Mini App работает.

  3. Можно сделать полноценный продукт за час. У нас ушло 57 минут.

Ответы на возможные вопросы

В: А Google не пришлёт DMCA?
О: Нет. Код распространяется под BSD-лицензией. Мы не воруем спрайты, не нарушаем товарные знаки. Это официальный open-source проект Chromium.

В: Почему не использовали Telegram Web App API?
О: Хотели показать, что даже без него можно сделать Mini App. Но в статье мы даём инструкцию, как добавить.

В: А зачем тогда статья про Telegram, если API не используется?
О: Потому что это всё равно Telegram Mini App. Он открывается через WebApp, работает внутри мессенджера, не требует браузера. Это и есть суть.

В: Можно добавить счёт в шапку Telegram?
О: Да, через tg.setHeaderColor(). Мы не делали, но вы можете.

Заключение

Мы сделали то, что хотели: оригинальный Chrome Dino внутри Telegram, бот с красивыми кнопками, исходники в открытом доступе.

Никаких упрощений. Только оригинальный движок Chromium.

Если у вас есть вопросы — пишите в Issues на GitHub. Если хотите повторить — просто копируйте исходный код.

Панель BotHost
Панель BotHost

Управление ботом на бесплатном хостинге BotHost

🔗 Полезные ссылки

Статья написана специально для Хабра. Все исходники открыты, код можно использовать в любых проектах, включая коммерческие. Баги и пожелания — в Issues на GitHub.