Спецификация · алгоритмы · администрирование · руководство по развитию
| URL | Что это |
|---|---|
| / | Лобби: карточки тем, 🏆 лидеры дня, 💎 джекпот |
| /demo | Игра, тема по умолчанию — Wild Patrik (классика) |
| /demo?theme=centavra | Centavra — sci-fi тема с каскадами |
ℹ️ Centavra здесь — вторая тема этого же движка
(каталог themes/centavra/: свой арт + своя математика v2.0.0), а не отдельный проект.
Не путать с одноимённым проектом centavra-mission-spin (bottle/, порты :3005/:5002) — тот к slot-engine не относится. | |
| /admin | Админка (пароль, см. раздел 02) |
| /spec.html | Этот документ |
| /production.html | Продакшн & промо: стандарты рекламных ассетов, ТЗ для генерации, дорожная карта |
| /investors.html | Для инвесторов: двухмодельный конвейер (Opus 4.8 × Fable 5), кто что построил, остаток Roadmap |
| /strategy.html | Стратегия выхода: рынок, монетизация (USDT vs лицензия), блокчейн/provably-fair, география, поэтапная де-рисковка |
| /investor-deck.html | Инвестор-дек: 3 экрана 16:9 (PDF: /slot-engine-investor-deck.pdf) |
http://127.0.0.1:3006 — pm2 slot-engine, каталог .nexthttp://127.0.0.1:3007 — npm run dev, каталог .next-devslot_engine (пароль в .env).env — вне git; не читать, не печататьНикогда не занимать :3006 dev-сервером и не удалять .next при живом pm2.
Рестарт прода — pm2 restart slot-engine только после npm run build.
cd slot-engine
npm run dev # dev-сервер :3007
npm run ci # lint + 66 unit + прод-сборка (зелёное = можно коммитить)
npm run e2e # 25 Playwright-тестов (сам поднимает dev-сервер)
npm run build && pm2 restart slot-engine # деплой на :3006
npm run simulate:rtp -- --config wild-patrik --spins 1000000 --seed 777 # RTP-отчёт
npm run simulate:rtp -- --config centavra --spins 200000 --seed 777 --force-bonus # цена бонуса
npm run validate:assets -- --theme wild-patrik # контракт ассетов
Вход: открыть /admin → редирект на /admin/login → ввести пароль.
Пароль хранится в переменной ADMIN_PASSWORD файла .env на сервере (в этом документе
и в git его нет — это секрет). После входа ставится подписанная HMAC-кука; middleware закрывает
все /admin/* и /api/math/*; если пароль в .env не задан — админка отвечает 503.
| Раздел | Что умеет |
|---|---|
/admin | Дашборд: статистика по дням (спины, ставки, выигрыши, фактический RTP), топ-выигрыши |
/admin/rounds | Все раунды с пагинацией: ставка, выигрыш, скаттеры, FS, кап |
/admin/rounds/[id] | Разбор споров: полный исход раунда с картинками сетки — базовое окно, каждая линия, цепочка фриспинов, каскады |
/admin/simulations | История RTP-симуляций + кнопка «Запустить симуляцию» (тема + число спинов, живой результат) |
/admin/configs | Версии математики тем (что записано в БД при спинах) |
/admin/validation | Отчёты валидатора ассетов |
/admin/errors | Лог ошибок из audit_logs (type=error) |
⚠️ Известная гоча: параллельные IDE-агенты дважды ломали
src/middleware.ts, вставляя node:crypto — middleware работает в edge-runtime,
можно только crypto.subtle. Если build падает с «Unhandled scheme node:» — проверять этот файл первым.
| Эндпоинт | Назначение | |
|---|---|---|
| POST | /api/session | Новая анонимная сессия, стартовый баланс 1000 демо-кредитов |
| GET | /api/session?sessionId= | Состояние: баланс, купленные анлоки |
| POST | /api/spin | Спин: {sessionId, bet, themeId, buyBonus?} → окно, линии, фриспины, каскады, джекпот, баланс. Единственный источник исходов. |
| POST | /api/gamble | Риск-игра ×2: {sessionId, roundId, action: red|black|collect} |
| POST | /api/unlock | Покупка фич за демо-кредиты (например premium_sound = 300) |
| GET | /api/history?sessionId= | Последние раунды игрока (модалка 🕘) |
| GET | /api/leaderboard?sessionId= | 🏆 Топ-10 дня + своё место (sessionId опционален) |
| GET | /api/jackpot | 💎 Текущий промо-пул для тикера |
| GET | /api/themes | Список тем: ставки, ставка по умолчанию |
| ADMIN | /api/math/simulate | Запуск симуляции из админки (закрыт middleware) |
Все мутации — за rate-limit'ом (token-bucket: 3 спина/с на сессию, 10/с на IP). Лишние поля в теле запроса отбрасываются zod-схемами — «передать желаемый исход» с клиента невозможно (есть e2e-тест ровно на это).
crypto.randomInt (CSPRNG ОС, без modulo-bias). Никакого Math.random в исходах.src/server/math с пакетом server-only — фронт физически не может её импортировать.Round + полный RoundResult.detail (окно, линии, фриспины, каскады) — любой спор разбирается в админке по картинке.reelsFs.json, опционально)RTP регулируется составом лент (сколько раз каждый символ встречается
на каждой ленте — таблица COUNTS в scripts/calibrate-math.ts) и значениями пэйтейбла. Вероятности
честно вытекают из лент — никаких «подкруток» исхода после генерации.
Включение каскадов подняло «сырой» RTP до 133.78% — пэйтейбл Centavra перекалиброван (×0.71) обратно к цели: 94.85% @1M. Wild Patrik не тронут: контрольный прогон ровно 95.20%.
После любого выигрыша: угадай цвет карты — выигрыш удваивается, не угадал — сгорает.
До 5 шагов (потом автозабор). Честные 50/50 на crypto-RNG,
EV-нейтральна — RTP игры не меняет, только дисперсию.
Исход решает сервер (POST /api/gamble); карта (масть/ранг) — производная исхода для показа.
Новый спин = молчаливый collect. Защита от гонок — оптимистичный guard по номеру шага.
Мгновенный вход во фриспины за 27× ставки. Реализация — rejection-sampling: сервер перебрасывает стопы до 3+ скаттеров, что сохраняет натуральное условное распределение 3/4/5 скаттеров. Цена откалибрована симулятором: EV покупки ≈ 25.5× ставки → RTP покупки 94.61% (классика) / 94.11% (каскады) — в полосе цели. Кнопка с подтверждением, цена видна до покупки.
Общий прогрессивный промо-пул поверх RTP тем: растёт на 2% каждой ставки всех игроков
(бухгалтерия казино — у игрока ничего не списывается), сид 500, потолок 5000.
Шанс дропа растёт с пулом: p = 1/D, D = clamp(CAP·100/pool, 2, 2000); у потолка — гарантия.
Атомарный клейм исключает двойную выплату при одновременных спинах. Выигрыш не входит в totalWin и лидерборд.
Топ-10 за день по множителю лучшего раунда: score = (totalWin + риск-игра) / (ставка | цена бонуса);
один игрок — одна строка; своё место вне топа приходит отдельной строкой. Ники — анонимные, стабильные,
из хеша userId («Шериф-742»), без персональных данных. Сброс в полночь. Плюс: история раундов 🕘,
ачивки-тосты, анлок премиум-звука за демо-кредиты, автоплей со стоп-условиями, турбо, fullscreen, мобильный портрет.
| Тема | Math | Механика | RTP @1M (seed 777) | Hit | Волатильность | Buy-bonus RTP |
|---|---|---|---|---|---|---|
| Wild Patrik | v1.1.0 | классика, 10 линий | 95.20% | 27.33% | 4.19 (medium) | 94.61% @27× |
| Centavra | v2.0.0 | каскады ×1/2/3/5 | 94.85% | 27.33% | 4.32 (medium) | 94.11% @27× |
/api/spin и CLI-симулятор — отчёт по определению соответствует продакшн-исходам.--force-bonus).reports/rtp-*.json|md (распределение множителей, топ-выигрыши, частота FS, σ).themes/<тема>/math/*.json — оба прогона для этой темы обязательны (см. AGENTS.md).themes/<id>/math/*.json| Файл / поле | Что регулирует | После правки |
|---|---|---|
reels.json | Состав лент = вероятности символов (главный регулятор RTP/волатильности) | оба RTP-прогона обязательны |
paytable.json | Выплаты за серии символов (множители ставки на линию) | |
gameConfig.json: scatterPays, freeSpins, freeSpinMultiplier, maxWinX, maxFreeSpinsPerRound | Скаттеры, фриспины, кап | |
gameConfig.json: buyBonus.priceX · cascades.multipliers | Цена покупки бонуса · лестница каскадов (убрать поле = выключить фичу) | |
gameConfig.json: allowedBets, defaultBet | Линейка ставок (каждая должна делиться на 10 линий) | достаточно ci |
reelsFs.json (опционально) | Отдельные «утяжелённые» ленты для фриспинов | оба RTP-прогона |
При изменении математики поднимайте version — она пишется в каждый раунд (mathVersion), что позволяет разбирать старые споры по старым правилам.
spin/service.tsSTART_BALANCE (1000), UNLOCK_PRICES (premium_sound 300)math/gamble.tsGAMBLE_MAX_STEPS (5)server/jackpot.tsJACKPOT_SEED (500), JACKPOT_CAP (5000), взнос 2%server/rateLimit.tsserver/leaderboard.tsthemes/<id>/ с manifest + math + арт; лобби и ?theme= подхватывают автоматически; ассеты проверяет validate:assets.themes/<id>/sounds/*.ogg (CC0) за анлок.scripts/build-atlas.ts (12 файлов → 1 запрос).themes/wild-patrik/ не менять — внешний сертификационный контракт (113 файлов).Слот — игра с фиксированным отрицательным матожиданием для игрока (RTP ≈ 95% < 100%): не существует стратегии, обыгрывающей дистанцию. Исход каждого спина независим, «горячих/холодных» полос нет. Что игрок реально контролирует:
| Решение | Эффект на матожидание | Эффект на дисперсию / опыт |
|---|---|---|
| Размер ставки | не меняет RTP | масштабирует и выигрыши, и проигрыши |
| Риск-игра ×2 | нейтрально (честные 50/50) | резко повышает дисперсию; «лесенка» до ×32 |
| Buy Bonus | RTP покупки ~94.1–94.6% — чуть ниже базовой игры | гарантированное событие, концентрированная дисперсия |
| Выбор темы | 95.20% vs 94.85% — практически равны | каскады дают более «цепочечные» выигрыши |
| Автоплей-стопы | не меняет | дисциплина: стоп на фриспинах / большом выигрыше |
| Тайминг спина у джекпота | пул у потолка → шанс растёт (промо-пул) | единственный «+EV момент», и он намеренно прозрачен в тикере |
Этот раздел — также чек-лист честности продукта: всё перечисленное видно игроку (цены, шансы, тикер), ничего не скрыто. В демо проигрыш = ноль реальных денег; новая сессия бесплатно даёт 1000 кредитов.
.next-dev/.next) — dev-сервер не может «съесть» BUILD_ID прода.slot-engine/
├─ src/server/math/ # ЧИСТАЯ математика: rng, reels, paylines, evaluateSpin,
│ # cascade, gamble, playRound, simulateRtp (server-only)
├─ src/server/ # spin/service (транзакции), jackpot, leaderboard, rateLimit, db
├─ src/app/api/ # session, spin, gamble, unlock, history, leaderboard, jackpot, themes
├─ src/app/demo/ # игровая страница (React, презентация исходов)
├─ src/app/admin/ # админка (дашборд, раунды, симуляции, конфиги, ошибки)
├─ src/game/engine/ # Pixi: SlotRenderer, ReelController, AnimationController, SymbolMap
├─ src/game/sound/ # WebAudio: синтез + сэмпл-пак
├─ src/middleware.ts # HMAC-защита админки (edge-runtime! только crypto.subtle)
├─ themes/<id>/ # manifest, math/*.json, арт, звуки — контракт темы
├─ scripts/ # simulate-rtp, calibrate-math, validate-assets, build-atlas, sync-themes
├─ prisma/ # схема + миграции (users/sessions/balances/rounds/audit/jackpot)
├─ tests/ e2e/ # vitest + Playwright
└─ README ARCHITECTURE MATH_MODEL SECURITY ACCEPTANCE DEPLOYMENT AGENTS LICENSES
Документы-первоисточники: AGENTS.md (правила для агентов и эталоны),
MATH_MODEL.md (модель и симуляции), SECURITY.md (границы демо), ACCEPTANCE.md (критерии приёмки 12/12).
Развёрнутая версия с привязкой «фича → какие ассеты генерировать», стандартами рекламных форматов (push-сети класса Kadam, баннеры, видео) и ТЗ-промптами — в парном документе /production.html.
src/game/** не импортирует @/server/**.