Discrete-outcomes vs real-time math
Два архитектурных подхода к тому, где живёт математика слота: всё посчитано заранее или считается на каждый спин. Этот выбор фундаментально влияет на cert-процесс, replay, infra-cost, persistent-фичи и стоимость итерации math.
Note
Подробный разбор и заметки по портированию идиом — в research-документе по Stake math-sdk. Эта страница — короткая выжимка-хаб.
Вариант A — Precomputed discrete outcomes
Студия описывает правила в коде, гоняет миллионы симуляций оффлайн, на выходе получает immutable артефакты:
books_<mode>.jsonl.zst— каждая строка — один сыгранный раунд ({id, payoutMultiplier, events:[...]}).lookUpTable_<mode>.csv—simulation_id, weight, payout(uint64).index.json— карта режимов на файлы.
RGS на проде на каждый /play:
- Weighted sample
simulation_idиз CSV для текущего bet-mode. - Достаёт
eventsиз.jsonl.zstпоid→ отдаёт фронту. - Списывает
payoutMultiplier × betчерез wallet.
Реализация: см. Stake Engine math-sdk.
Вариант B — Real-time math на бэке
Классическая схема: на каждый /play бэк дёргает CSPRNG, считает stop-позиции по reelstrip, evaluate wins, формирует events. Никаких precomputed артефактов.
Алгоритмы win-evaluation те же (lines / ways / cluster / scatter) — это универсальные процедуры, не привязаны к подходу.
Сравнение
| Критерий | A — Precomputed | B — Real-time |
|---|---|---|
| Cert математики | Файл-артефакт + hash + полный цикл RTP | Code review RNG + reelstrips + симуляции pre-deploy |
| Replay раунда | Тривиален (id → книга) | Нужно логировать seed/state |
| Гарантия RTP | Контрактная по выборке | Сходится в пределе, локально дрейфует |
Latency на /play | Минимум (CSV sample + JSON read) | Зависит от сложности math |
| Storage published | Десятки–сотни MB на mode | Конфиги + reelstrips (kB) |
| Persistent meta-state (миссии, прогрессии) | Плохо ложится | Естественно |
| Live progressive jackpots | Нет (вне модели) | Да |
| Стоимость итерации math | Высокая (re-simulate + re-publish) | Низкая (deploy конфига) |
| Probability quantization | Дискретна (uint64 веса) | Дробная |
| Vendor-lock RGS-формата | Высокий (Stake) | Свой |
Гибрид (наш выбор)
Real-time на проде + math-sdk-style симуляционный pipeline в CI:
- Один codebase правил игры в TypeScript:
GameConfig, BetMode + Distribution,runSpin(seed). - Тот же код в двух режимах:
- simulate — батч спинов с фиксированными seed-ами, сегментацией по criteria/quotas, генерацией внутренних «books» и статистик для cert/регрессий. Артефакт CI.
- serve —
/playдёргаетrunSpin(seed); реальный CSPRNG (см. Seedable PRNG для симуляции, CSPRNG для прода).
- Pre-deploy CI считает RTP/HF/volatility и diff с baseline. Красная сборка, если RTP уезжает >0.1pp без явного апдейта таргета.
- Лаборатории сабмитим: код + reelstrips + результат симуляций (CI-артефакты). Это близко к тому, что хотят GLI/eCOGRA/UKGC.
- Если когда-то захотим публиковаться на Stake Engine — добавим writer-адаптер из нашего runtime в
books.jsonl.zst+lookUpTable.csv+index.json.
Когда что выбирать
Чистый precomputed (A) оправдан, если:
- Публикуемся на готовой precomputed-платформе (Stake Engine).
- Игра полностью stateless по раундам (нет миссий между спинами, нет джекпотов).
- Готовы платить полным re-publish за каждый math-патч.
Чистый real-time (B) оправдан, если:
- Свой RGS, контролируем формат и cert-процесс.
- Persistent meta или live-фичи (jackpots, tournaments, quests).
- Хотим быстро итерировать math и A/B тестить.
Гибрид (наш кейс) оправдан, если:
- Real-time продакшен, но методология симуляции нужна для cert и регрессий.
- Хотим оставить дверь для precomputed-публикации отдельных режимов (например, buy-bonus) или платформ.