Мой опыт создания инкрементальной игры о горнодобыче Кузбасса с детальным обзором архитектуры, мер безопасности и модели монетизации.
80% кода было сгенерировано при помощи Vibe-кодинга, но это сложнее, чем выглядит.
💡 Задумка проекта
Я вырос в Кемеровской области — угольной мекке России. Задумка проста: сделать современную idle-игру, где все шахты и рудники настоящие, а управление ими отражает реальные данные региона.
Основные параметры:
- Дата старта: 22 августа 2025
- Версия: 1.8.0
- Стек: Impact.js, PHP 7.4+, MySQL 8.0, Telegram WebApp API
- Платформы: Telegram Mini Apps, VK Mini Apps, Web
- Архитектура: клиент-сервер с авторитетным сервером
Концепция:
- Старт на Антоновском руднике в Рудничном
- Эволюция до легендарной Распадской шахты
- 15 реальных месторождений с историей
- Образовательный элемент: игроки узнают об экономике региона
🛠️ Технический стек
Impact.js, PHP 8+, MySQL 8.0, Telegram WebApp API
Почему Impact.js
- Canvas-рендеринг — плавная анимация даже на слабых устройствах
- Система Entity — удобное управление игровыми объектами
- Встроенная физика — реалистичные движения рабочих и лифта
- Низкий вес — моментальная загрузка в мессенджерах
⚠️ Сложности: Impact.js устарел, документация неполная, приходилось разбираться на лету.
🏗️ Схема проекта
Доменные имена
| Домен | Назначение | Технологии |
|---|---|---|
| game.kuzbass-empire.ru | Игра (Telegram/VK Mini Apps) | Impact.js, PHP API |
| kuzbass-empire.ru | Лендинг и личный кабинет | PHP, HTML/CSS, REST API |
Серверная часть
Все запросы проходят через единый шлюз /api/v1.php, что скрывает внутреннюю структуру и упрощает защиту.
POST /api/v1.php
{
"action": "buy_upgrade",
"user_id": "kuzbassANJ8112",
"session_token": "kuztokenJjksa119",
"price": 777
}
// Шлюз перенаправляет на соответствующий обработчик:
api/buy_upgrade.handler.php
Всего 12 модулей для разных операций: загрузка/сохранение прогресса, проверка сессии, покупки, обмен валют и др.
Плюсы: легко расширять, централизованная обработка ошибок, защита от утечек структуры API.
🗄️ База данных
Авторитетный серверный подход: все важные данные хранятся и проверяются на сервере.
| Таблица | Назначение |
|---|---|
| userz_kuzb | Профили игроков (ID, имя, статус) |
| game_savez_kuzb | Прогресс (JSON + отдельные поля) |
| auth_tokenz_kuzb | OAuth-токены |
| referralz_kuzb | Реферальная система с milestone |
| cheat_attemptz_kuzb | Лог попыток читерства |
| kuzbass_transactionz_kuzb | История покупок Кузбиков |
| activity_logz_kuzb | Аудит действий пользователя |
| leaderboard_kuzb | Кэш рейтинга |
| game_settingz_kuzb | Настройки экономики |
| depositz_kuzb | Справочник месторождений |
Гибридное хранение прогресса
CREATE TABLE `game_savez_kuzb` (
`user_id` INT PRIMARY KEY,
`save_data` TEXT, -- полный JSON
`cash` DOUBLE, -- дублируется для быстрых выборок
`kuzbass` DOUBLE, -- премиум-валюта
`income_per_hour` DOUBLE,
`investors_count` INT,
`total_earned` DOUBLE,
`admin_updated` TINYINT
);
- Быстрые выборки рейтинга без парсинга JSON
- Индексы на ключевых полях
- Сверка JSON и полей на сервере для безопасности
🔐 Многоуровневая защита
Server-Authoritative
Клиент лишь отображает результат, все решения принимает сервер.
// Неправильно:
player.money -= 1000; saveToServer(player);
// Правильно:
const res = await buyUpgrade(price);
if (res.success) player.money = res.new_cash;
Сессии
Каждый игрок получает 64-символьный токен. Все запросы проверяют его соответствие.
- Блокировка IDOR — недоступен чужой профиль
- Старая сессия аннулируется при входе с нового устройства
Античит
Клиент:
- Детект открытых DevTools
- Мониторинг localStorage/sessionStorage
- Ловля вызова скрытых функций
Сервер:
- Проверка реального заработка за период
- Анализ последовательности действий
- Автоблокировка после 5 попыток читерства
- Уведомления админам и игроку
Скрытие API
// .htaccess возвращает 404 вместо 403
RewriteRule ^.*\.php$ - [R=404,L]
// Единая точка входа
POST /api/v1.php
// Проверка Referer
RewriteCond %{HTTP_REFERER} !^https://([a-z0-9-]+\.)?kuzbass-empire\.ru
🎮 Игровая механика
Основной цикл
- Добыча ресурсов на шахтах
- Подъём лифтом
- Продажа со склада
- Реинвестиции в улучшения
Bottleneck: производительность ограничена минимальным звеном: шахты, лифт или склад.
const realIncome = Math.min(shaftProduction, elevatorCap, warehouseCap);
Игроки учатся балансировать все элементы системы.
Престиж (IPO)
investorsGain = Math.floor(
Math.pow(lifetimeEarning/divisor, power) -
Math.pow(startingLifetime/divisor, power)
);
incomeBonus = investors * 0.02;
Параметры хранятся в БД и настраиваются динамически.
🔑 Собственный OAuth через бота
Из-за ограничения Telegram Login Widget была создана собственная OAuth-система с deeplink:
1. Генерация токена (TTL 5 мин)
2. Открытие бота: t.me/bot?start=TOKEN
3. Бот подтверждает связь с telegram_id
4. Сайт/игра опрашивают статус (каждые 2 сек)
5. При подтверждении — вход
- Токен одноразовый
- Привязка к IP и User-Agent
- Опция «Запомнить устройство»
💰 Монетизация
Кузбики (премиум-валюта)
- 100 за регистрацию
- 250 за реферала (10 000 монет)
- Покупка через ЮMoney и FreeKassa
Использование:
- Сброс перезарядки менеджера (10 Кузбиков)
- Конвертация в игровые монеты (1:1000)
Отложенные начисления
// Callback платёжки
$user['pending'] += amount;
// Проверка в игре
if (pending > 0) {
$user['kuzbass'] += pending;
pending = 0;
}
Защита от гонок: нельзя потратить валюту до полной обработки платежа.
📱 Кросс-платформенность
Telegram Mini Apps
- Авторизация через initDataUnsafe
- Тема под системные настройки
- Вибрация при действиях
- Кастомизация header/bottombar
VK Mini Apps
const isVK = location.search.includes('vk_');
if (isVK) {
vkBridge.send('VKWebAppInit');
}
Единая серверная часть, только фронтенд отличается.
🛡️ Борьба с читерами
Проблемы
- Открытый JavaScript-код
- Доступ к переменным в памяти
- Возможность повторять сетевые запросы
Решения
Серверная валидация, защита от гонок, привязка сессии и контроль каждой операции.
⚡ Оптимизация
Автосохранение
setInterval(() => sendHeartbeat(time), 30000);
setInterval(() => saveGame(data), 10000);
Нагрузка на БД снизилась на 66%.
Бандлинг
// scripts-bundle.php
$files = ['reset.js', ...];
Время загрузки сократилось с 3.2 с до 0.8 с.
Capture Phase для UI
element.addEventListener('click', handler, true);
🎨 Улучшение интерфейса
Заменил Canvas-попапы на HTML-слои для адаптивности и современного вида.
const origSpawn = ig.game.spawnEntity;
ig.game.spawnEntity = (cls, x, y, settings) => {
if (cls.name === 'EntityUpgradeController') {
openUpgradeSheet();
return { kill: () => {}, _wasReplaced: true };
}
return origSpawn.call(this, cls, x, y, settings);
};
💳 Платёжные интеграции
| Функция | ЮMoney | FreeKassa |
|---|---|---|
| Банковские карты | МИР, Visa, MC | нет |
| Э-кошельки | ЮMoney | нет |
| Криптовалюта | нет | BTC, ETH, USDT, TON |
| Подпись callback | SHA-256 | MD5 |
Выбранные сервисы позволяют принимать платежи как физлицо. FreeKassa требует от 1000 ₽, ЮMoney — гибкие лимиты.
- Включение/выключение
- Бонусы за пополнение
- Минимальные/максимальные суммы
📊 Аналитика
Все действия логируются в таблице activity_logz_kuzb.
- Онлайн-пользователи в реальном времени
- Статистика транзакций
- Графики ежедневной активности
- Детали по каждому игроку
🚀 Масштабирование
Динамические настройки
// game_settingz_kuzb
- mine_price_coef: 1.40
- manager_skill_duration: 120
- max_offline_hours: 24
- referral_bonus: 100
- exchange_rate: 1000
Изменения применяются мгновенно без деплоя.
Расширяемость месторождений
const shafts = window.DEPOSITS_DATA.length || 15;
while (session.Mines.length < shafts) {
session.Mines.push({ level:0, ... });
}
🐛 Проблемы и решения
Откат баланса
await saveGameToServer();
await delay(500);
const res = await buyUpgrade(price);
player.money = res.new_cash;
Платёжные формы на iOS
const form = document.createElement('form');
form.method = 'POST';
form.action = paymentURL;
form.target = '_blank';
document.body.appendChild(form);
form.submit();
Пауза при UI
Переопределил функцию pauseGame и отслеживаю её каждые 50 мс.
🎯 Итоги
- Глубокие механики и стратегическая глубина
- Надёжная многоуровневая безопасность
- Две платформы: Telegram и VK
- Две платёжные системы
- Реферальная программа
- Гибкая админ-панель
- Образовательный формат с реальными месторождениями
Вывод: даже на устаревшем движке можно создать современную, безопасную и стильную игру при грамотной архитектуре и внимании к деталям.
🚀 Доступно:
Telegram: @kuzbass_empire_bot
VK: vk.com/app54256088
Сайт: kuzbass-empire.ru



