Skip to main content

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.

Prerequisites

Before you begin, make sure you have the following installed:
  • Python 3.12 or later — required. Earlier versions are not supported.
  • pip — included with Python 3.12+.
  • Make — recommended for the one-command setup. Available by default on macOS and Linux; install via winget or Chocolatey on Windows.
  • Rust/Cargo — only needed if you plan to run the optimization algorithm. See Installation for details.
1

Clone the repository

Clone the Math SDK to your local machine:
git clone git@github.com:StakeEngine/math-sdk.git
cd math-sdk
2

Run make setup

make setup
This single command does the following in order:
  1. Creates a Python virtual environment at env/.
  2. Upgrades pip inside the environment.
  3. Installs all dependencies listed in requirements.txt (numpy, zstandard, pytest, boto3, xlsxwriter, and more).
  4. Installs the stakeengine package itself in editable mode (pip install -e .), so any changes you make to the source take effect immediately without reinstalling.
When it finishes you will see:
Virtual environment ready.
To activate it, run:
source env/bin/activate
Activate the environment before running any Python commands directly:
source env/bin/activate
make run activates the virtual environment automatically, so you only need to activate manually when running scripts directly.
3

Run the sample lines game

The SDK ships with several example games under games/. Run the 3-reel, 5-reel lines game:
make run GAME=0_0_lines
This executes games/0_0_lines/run.py inside the virtual environment. With the default settings it simulates 10,000 base-game rounds and 10,000 bonus rounds across 10 CPU threads, then runs the optimization algorithm and generates a PAR sheet.You will see per-thread RTP output as each thread completes:
Thread 0 finished with 1.632 RTP. [baseGame: 0.043, freeGame: 1.588]
For a faster first run, open games/0_0_lines/run.py and reduce num_sim_args values to 100 and set compression = False. This produces human-readable JSON output in a few seconds.
4

Inspect the output

All output is written to library/ inside the game directory. The publish-ready files are in library/publish_files/.
library/
├── books/
│   ├── books_base.jsonl          # One JSON object per simulation (uncompressed)
│   └── books_base.jsonl.zst      # Compressed variant for production
├── lookup_tables/
│   ├── lookUpTable_base.csv      # id, weight, payoutMultiplier
│   ├── lookUpTable_base_0.csv    # Optimized weights (after optimization run)
│   └── lookUpTableIdToCriteria_base.csv  # Maps sim ID to criteria label
├── configs/
│   └── game_config.json          # RGS game configuration
└── forces/
    └── force_record_base.json    # Forced-outcome metadata for analysis
Open library/books/books_base.jsonl to inspect individual simulations. Each line is one simulation object. Here is simulation 58 from a 100-simulation uncompressed run:
{
    "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
}
The events array is exactly what the RGS returns in the play/ API response body when this simulation is selected. The frontend SDK consumes these events in order to drive the animation and UI.Open library/lookup_tables/lookUpTable_base.csv and find row 58:
58,1,10
The three columns are simulation ID, selection weight, and payout multiplier. The weight starts at 1 for every simulation; the optimization step adjusts these weights so the weighted-average payout matches your RTP target.

Next steps

Installation

Full system requirements and manual setup instructions.

Game structure

Understand what each file in a game directory does.

Configuration guide

Configure paytables, reel strips, and bet modes for your own game.

Lines game example

A detailed walkthrough of the 0_0_lines sample game.

Build docs developers (and LLMs) love