The configuration layer defines everything the simulation engine needs to know about a game before any spin runs: board dimensions, paytable, reel strips, special symbols, win caps, and bet modes. Two classes make up this layer —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.
Config (the SDK base class) and GameConfig (your game-specific subclass).
Config
Config lives in src/config/config.py and is never instantiated directly. It sets safe default values for every field the engine requires, constructs output paths, and provides utility methods for reading reel CSVs and verifying paytable ranges.
What Config provides:
- Win level thresholds for
standardandendFeaturekeys, consumed bysetWinandfreeSpinEndevents. construct_paths()— buildsreels_path,library_path, andpublish_pathfromgame_id.read_reels_csv(file_path)— reads a comma-separated reel strip file and returns a list of reel columns.validate_reel_symbols(reel_strip)— raisesRuntimeErrorif any reel symbol is not registered inall_valid_sym_names.convert_range_table(pay_group)— expands a range-keyed paytable ({((min, max), symbol): value}) into the flat{(kind, symbol): value}format required byself.paytable.
GameConfig
GameConfig inherits Config and is the file you create for each game. All required fields must be assigned in __init__ after calling super().__init__().
game_config.py
GameConfig fields
Required fields
Unique identifier for the game. Used to construct all output file paths. Must match the directory name under
games/.Numeric provider identifier. Written into the backend config file consumed by the RGS.
Human-readable game title. Written into the backend config as
workingName.Maximum win cap expressed as a bet multiplier (e.g.
5000 means 5000×). All win events and final payouts are clamped to this value.Win evaluation method. Accepted values:
"lines", "ways", "cluster", "scatter". Determines which calculation module is appropriate for this game.Target return-to-player as a decimal (e.g.
0.97 for 97%). Must be less than 1.0.Total number of reels on the board.
Number of visible rows on each reel. Must have exactly
num_reels entries.Maps For cluster or cascade games where a range of cluster sizes share the same payout, define
(kind, symbol_name) tuples to payout multipliers.kind— number of matching symbols required for this pay.symbol_name— string name exactly as it appears on the reel strip.
pay_group and expand it:Maps attribute names to lists of symbol names that carry that attribute.A symbol is valid only if its name appears in
paytable or special_symbols. Any unlisted symbol found on a reel strip raises RuntimeError during loading.Optional fields
Required for
win_type = "lines" games. Maps payline identifiers to ordered lists of row indices per reel.Defines how many free spins are awarded for each scatter count, separately for base and free game.
Loaded reel strip data, keyed by reel set identifier. Populate using
read_reels_csv().Ordered list of
BetMode instances. At minimum, include a "base" mode. Feature or buy-bonus modes are added as additional entries.BetMode
BetMode lives in src/config/betmode.py. Each instance represents one purchasable bet option.
Identifier used to select this mode at runtime (e.g.
"base", "bonus").Bet cost multiplier relative to 1 unit.
1.0 is the standard cost; buy-bonus modes are typically higher (e.g. 100.0).Target RTP for this mode as a decimal. Must be less than
1.0.Per-mode win cap multiplier. Overrides
config.wincap during simulation of this mode.When
True, this mode includes a feature game (e.g. free spins). Exposed in the frontend config.When
True, this mode is a buy-bonus entry point. Exposed in the frontend config.When
False, the RGS automatically calls /endround on 0× payouts. Set to True for feature modes where the player must be able to resume an interrupted bet.Simulation criteria assigned to this mode. See Distribution below.
Distribution
Distribution lives in src/config/distributions.py. Each instance defines one simulation criteria bucket — a label, a proportion of total simulations, and the reel/feature conditions the engine must satisfy.
Human-readable label for this bucket (e.g.
"basegame", "freegame", "winCap", "0"). Written into book output and lookup table files.Proportion of total simulations allocated to this criteria. All quotas within a
BetMode must sum to 1.0.Alternative to
quota. Allocates an exact number of simulations to this criteria. Mutually exclusive with quota.If set, the simulation is retried until its final payout multiplier exactly matches this value. Use
0.0 to force zero-win simulations or self.wincap to force max-win simulations.Key-value conditions applied to every simulation in this criteria. Always required:
Methods
read_reels_csv()
convert_range_table()
pay_group dict into the flat (kind, symbol): payout format required by self.paytable. Raises RuntimeError if any cluster-size ranges overlap.
get_distribution_conditions()
Called on aBetMode instance to retrieve the conditions dict for a named criteria:
