> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/StakeEngine/math-sdk/llms.txt
> Use this file to discover all available pages before exploring further.

# Game Format

> What the Stake Engine game format requires: static pre-computed simulation files, books in JSONL format, and lookup tables in CSV format.

## Overview

<Note>
  Stake Engine requires games to consist entirely of **static, pre-computed files**. There is no server-side game logic executed at play time. All possible game outcomes must be generated ahead of time and stored in compressed files before a game can be published.
</Note>

When a betting round is initiated, the RGS selects a simulation number at a frequency proportional to its weight in the lookup table, then returns the pre-computed events for that simulation through the `play/` API. The math SDK handles generating all of these files from your game logic.

***

## Books format

Books are JSONL files (one JSON object per line) stored in `library/books/` (uncompressed) or `library/books_compressed/` (compressed). Each line represents a single simulation result, keyed by simulation ID.

Each simulation object has the following structure:

```json theme={null}
{
    "id": 58,
    "payoutMultiplier": 10,
    "events": [
        {
            "index": 0,
            "type": "reveal",
            "board": [...],
            "paddingPositions": [...],
            "gameType": "basegame",
            "anticipation": [...]
        },
        {
            "index": 1,
            "type": "winInfo",
            "totalWin": 10,
            "wins": [
                {
                    "symbol": "L5",
                    "kind": 3,
                    "win": 10,
                    "positions": [...],
                    "meta": {}
                }
            ]
        },
        {
            "index": 2,
            "type": "setWin",
            "amount": 10,
            "winLevel": 2
        },
        {
            "index": 3,
            "type": "setTotalWin",
            "amount": 10
        },
        {
            "index": 4,
            "type": "finalWin",
            "amount": 10
        }
    ],
    "criteria": "basegame",
    "baseGameWins": 0.1,
    "freeGameWins": 0.0
}
```

This example is simulation 58 from the `0_0_lines` sample game. The `events` array tells the frontend which symbols to reveal, the winning positions and amounts, and how to update the win counters. The `payoutMultiplier` is the final payout amount for the round.

Each event has an `index` (its position in the sequence), a `type` string identifier, and additional fields carrying the state snapshot for that moment in the round.

***

## Lookup table format

Lookup tables are stored as CSV files in `library/lookup_tables/`. They summarise the payout for every simulation and are consumed by the optimization algorithm to adjust selection weights so the game achieves its target RTP.

| Column       | Type    | Description                                                                                   |
| ------------ | ------- | --------------------------------------------------------------------------------------------- |
| `Simulation` | `int`   | Simulation number (matches the `id` in the books file)                                        |
| `Weight`     | `int`   | Selection weight; all simulations start at `1` and are modified by the optimization algorithm |
| `Payout`     | `float` | Final payout multiplier for the round                                                         |

Example row: `58,1,10` — simulation 58, weight 1, payout multiplier 10×. This matches the `payoutMultiplier` value in the books file for the same simulation.

File naming follows the convention:

* `lookUpTable_<mode>.csv` — initial table generated by the simulator
* `lookUpTable_<mode>_0.csv` — optimized table with adjusted weights
* `lookUpTableIdToCriteria_<mode>.csv` — maps each simulation to its distribution criteria (e.g. max-win, 0-win, freegame)
* `lookUpTableSegmented_<mode>.csv` — breaks down which game type (basegame/freegame) contributed to the final payout

***

## The `play/` API response

When a player initiates a round, the RGS:

1. Reads the lookup table for the active bet mode.
2. Selects a simulation number at random, weighted proportionally by each row's `Weight` value.
3. Retrieves the corresponding entry from the books file.
4. Returns the `events` array in the API response body.

The frontend receives only the `events` array. It must handle every event type in the sequence to render the full round correctly.

***

## Compressed vs uncompressed format

The `compression` flag in `run.py` controls the output format:

| Value   | Output location             | File extension | Use case                                  |
| ------- | --------------------------- | -------------- | ----------------------------------------- |
| `False` | `library/books/`            | `.json`        | Development and debugging; human-readable |
| `True`  | `library/books_compressed/` | `.json.zst`    | Production; required for RGS publication  |

<Warning>
  Running a large number of simulations (above 10,000) with `compression = False` will produce very large files and trigger a warning. Use uncompressed output only when inspecting simulation results during development.
</Warning>

***

## Publishing to the RGS

All files required for RGS publication are written to `library/publish_files/`. This folder contains the books, lookup tables, and an index file. Even if you generate your math results outside of this SDK, you must provide files in a compatible format in this folder structure to upload via the Admin Control Panel (ACP).
