Skip to main content
GameState is the central object that runs a single simulation round. It owns the current board, win data, event book, and all per-spin mutable state. Every game you build subclasses GameState (or its parent chain) and implements run_spin() as the simulation entry point.

Class hierarchy

GameState properties

list[list[Symbol]]
The active board after the most recent draw_board() call. Indexed as board[reel][row]. Each entry is a Symbol object with a .name attribute and any special properties set by assign_special_sym_function.
string
Current game phase. Starts as config.basegame_type (default "basegame") and switches to config.freegame_type (default "freegame") when reset_fs_spin() is called.
bool
Controls the simulation retry loop in run_spin(). Set to True before the loop begins; reset to False by reset_book(). Set back to True by check_repeat() when distribution criteria are not satisfied.
dict
Populated by the win evaluation step each spin. Structure:
WinManager
Tracks cumulative, spin, base-game, and free-game win amounts. Updated via win_manager.update_spinwin() and win_manager.update_gametype_wins().
GameConfig
Reference to the GameConfig instance passed at construction. Read-only during simulation.
int
Current free spin index (0-based). Incremented by update_freespin() at the start of each free spin.
int
Total free spins awarded this round (including retriggers). Set by update_freespin_amount() and incremented by update_fs_retrigger_amt().
Book
Stores all events emitted during the current simulation. Passed to imprint_wins() at the end of the round to persist it in the library.
int
Running global multiplier value, starting at 1. Incremented by update_global_mult().
bool
Set to True by evaluate_wincap() when the running win reaches config.wincap. Prevents further win events from being emitted.
string
The distribution criteria label assigned to the current simulation number (e.g. "basegame", "freegame", "winCap"). Assigned by the simulation runner before run_spin() is called.

Key methods

reset_seed(sim)

Seeds the Python random module with sim + 1. Call this as the first line of run_spin() so that every simulation number is fully reproducible.

reset_book()

Resets all per-spin state: clears the board, creates a new Book, zeroes win_data, resets win_manager, sets repeat = False, resets fs, tot_fs, global_multiplier, and wincap_triggered. Call this at the start of each retry loop iteration.

check_repeat()

Checks whether the completed simulation satisfies the active distribution’s win_criteria and force_freegame constraints. Sets self.repeat = True if any constraint fails. Call this at the end of the spin loop, after evaluate_finalwin().

imprint_wins()

Saves the completed simulation to self.library and flushes temp_wins (recorded events) to self.recorded_events. Call this once after the retry loop exits.

update_final_win()

Computes the final payout multiplier (clamped to wincap), splits it into base-game and free-game portions, and writes values onto self.book. Raises AssertionError if base + free game wins do not match the total. Called inside evaluate_finalwin().

record(description)

Appends an event descriptor to temp_wins for tracking distributions. Typically called when a free spin trigger or other trackable event occurs:
Data is written to the force/ output files and consumed by the optimization algorithm to identify which simulations belong to which event type.

run_spin() — simulation entry point

run_spin(sim, simulation_seed=None) is an abstract method in GeneralGameState that you must implement in your GameState class. The simulation runner calls it once per simulation number.
gamestate.py
Each iteration of the while self.repeat loop is a complete spin attempt. reset_book() resets repeat to False; check_repeat() sets it back to True only if a constraint is violated. The loop continues until the spin satisfies all distribution criteria.

run_freespin()

Also abstract. Implement alongside run_spin() for games with free spin features:
gamestate.py

create_books()

src/state/run_sims.py
The main simulation driver. Allocates distribution criteria to simulation numbers, launches multi-threaded workers, and writes all output files.
GameState
Instantiated GameState object.
GameConfig
The game configuration object.
dict
Maps bet mode names to simulation counts: {"base": 1000000, "bonus": 100000}.
int
Number of simulations per thread batch. Typical value: 50000.
int
Number of parallel worker processes.
bool
When True, output books are written as .jsonl.zst (Zstandard compressed). When False, plain .jsonl files are written — useful during development.
bool
When True, runs a single-threaded cProfile pass and generates a flame graph. threads must equal 1 when profiling.
num_sim_args values must satisfy n % (threads × batch_size) == 0 when n > batch_size². Set any mode’s value to 0 to skip it during a run.

generate_configs()

src/write_data/write_configs.py
Produces all configuration files required by the RGS and frontend after simulations complete: Call generate_configs() once after create_books() completes:
run.py