### Run make setup
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/general_overview.md
Sets up and activates a Python virtual environment, installs packages from requirements.txt, and installs an editable math-sdk module.
```sh
make setup
```
--------------------------------
### Using UI and Modals components
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/ui.md
Example of integrating the UI and Modals components from the provided packages. It shows how to use the UI component with gameName and logo snippets, and the Modals component with a version snippet. The packages are functional but not beautiful, and are recommended as a starting point for building your own UI.
```svelte
{#snippet gameName()}
{/snippet}
{#snippet logo()}
{/snippet}
{#snippet version()}
{/snippet}
```
--------------------------------
### List installed packages
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/general_overview.md
Lists installed packages to verify the installation.
```sh
python3 -m pip list
```
--------------------------------
### Install nvm and Node.js 18.18.0
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/get_started.md
Download and install nvm, then use it to install Node.js version 18.18.0. Verify the installation by checking the node version, which should print 'v18.18.0'.
```bash
# Download and install nvm:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
# in lieu of restarting the shell
\. "$HOME/.nvm/nvm.sh"
# Download and install Node.js:
nvm install 18.18.0
# Verify the node versions. Should print "v18.18.0".
node -v
```
--------------------------------
### Setup the engine with make setup
Source: https://github.com/engineio/math-sdk/blob/main/README.md
Run this command to set up the engine. It requires Python 3.12 or later, PIP, and optionally Rust/Cargo if the optimization algorithm is used.
```sh
make setup
```
--------------------------------
### Install dependencies
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/get_started.md
Install project dependencies using pnpm.
```bash
pnpm install
```
--------------------------------
### setContext() example for Svelte context setup
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/context.md
Sets four major contexts (event emitter, xstate, layout, app) at the entry level component of a Svelte app. Called in files like `apps/lines/src/routes/+page.svelte` or `apps/lines/src/stories/ComponentsGame.stories.svelte`. Different apps and packages require different contexts.
```typescript
// context.ts - Example of setContext in apps
export const setContext = () => {
setContextEventEmitter({ eventEmitter });
setContextXstate({ stateXstate, stateXstateDerived });
setContextLayout({ stateLayout, stateLayoutDerived });
setContextApp({ stateApp });
};
```
--------------------------------
### Install dependencies with pip
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/general_overview.md
Installs dependencies from requirements.txt using pip.
```sh
python3 -m pip install -r requirements.txt
```
--------------------------------
### index.json example for 2-mode game
Source: https://github.com/engineio/math-sdk/blob/main/docs/rgs_docs/data_format.md
Concrete example of index.json for a game with two modes (base and bonus), each with its own cost, events file, and weights file.
```json
{
"modes": [
{
"name": "base",
"cost": 1.0,
"events": "books_base.jsonl.zst",
"weights": "lookUpTable_base_0.csv"
},
{
"name": "bonus",
"cost": 100.0,
"events": "books_bonus.jsonl.zst",
"weights": "lookUpTable_bonus_0.csv"
}
]
}
```
--------------------------------
### Install Rust and Cargo
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/general_overview.md
Installs Rust and Cargo via rustup, required for the optimization algorithm.
```sh
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```
--------------------------------
### Run example game with python3
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/quickstart.md
Alternative way to run the 0_0_lines game by calling the script directly after activating the virtual environment. Produces the same output files as the make command.
```sh
python3 games/0_0_lines/run.py
```
--------------------------------
### Run example game with make
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/quickstart.md
Runs the 0_0_lines game using default settings via make. Outputs all required files for the RGS, including books, lookup-tables, and index file in library/publish_files/.
```sh
make run GAME=0_0_lines
```
--------------------------------
### Install pnpm 10.5.0
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/get_started.md
Install pnpm version 10.5.0 globally using npm and verify the installation. The version command should print 'v10.5.0'.
```bash
# Install pnpm
npm install pnpm@10.5.0 -g
# Verify the pnpm versions. Should print "v10.5.0"
pnpm -v
```
--------------------------------
### Bet Levels JSON Example
Source: https://github.com/engineio/math-sdk/blob/main/docs/rgs_docs/RGS.md
Example of the betLevels configuration object returned by the wallet authenticate endpoint. It shows the minBet, maxBet, stepBet, and an array of betLevels. The comments indicate the dollar value of some levels.
```json
{
"minBet": 100000,
"maxBet": 1000000000,
"stepBet": 10000,
"betLevels": [
100000, // $0.10
200000,
400000,
600000,
...
1000000000 // $1000
]
}
```
--------------------------------
### Example board for ways calculation
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/source_section/ways_info.md
Example board layout used to illustrate the ways calculation. The board has 3 rows and 5 columns, and the example shows a multiplier of 3x on the H1 symbol on reel 3, resulting in 6 ways for H1.
```sh
L5 H1 L4 L4 L4
L1 H4 L3 H2 L4
H1 H1 H1 L3 H3
```
--------------------------------
### Example output of formatting script
Source: https://github.com/engineio/math-sdk/blob/main/docs/books_formatting.md
Shows the console output when the formatting script runs, including progress messages and the total lines processed.
```text
Formatting books files...
Formatting: games/0_0_tower_defense/library/books/books_bonus.jsonl
✅ Formatted: games/0_0_tower_defense/library/books/books_bonus.jsonl (100 lines processed)
Formatting: games/0_0_tower_defense/library/books/books_base.jsonl
✅ Formatted: games/0_0_tower_defense/library/books/books_base.jsonl (100 lines processed)
Books formatting complete! (200 total lines processed)
```
--------------------------------
### Example win entry with meta (win-lines)
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/gamestate_section/win_info.md
Shows the structure of a win entry in the wins list, including symbol, kind, win amount, positions, and meta information like lineIndex and multipliers.
```python
'wins': {
'symbol': 'H1',
'kind': 5,
'win': 300,
'positions': [{'reel':1, 'row':1}, ...],
'meta':{
'lineIndex': 12,
'multiplier': 10,
'winWithoutMult': 30,
'globalMult': 1,
'lineMultiplier': 10
}
}
```
--------------------------------
### BetMode example for bonus/buy feature (Python)
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/gamestate_section/configuration_section/betmode_overview.md
Example BetMode configuration from the 'lines' game for a bonus/buy feature. Sets cost, RTP, max_win, and distribution conditions including reel weights, scatter triggers, and mult_values. The auto_close_disabled flag is False, is_feature is False, and is_buybonus is True.
```python
BetMode(
name="bonus",
cost=100.0,
rtp=self.rtp,
max_win=self.wincap,
auto_close_disabled=False,
is_feature=False,
is_buybonus=True,
distributions=[
Distribution(
criteria="wincap",
quota=0.001,
win_criteria=self.wincap,
conditions={
"reel_weights": {
self.basegame_type: {"BR0": 1},
self.freegame_type: {"FR0": 1},
},
"mult_values": {
self.basegame_type: {1: 1},
self.freegame_type: {2: 10, 3: 20, 4: 50, 5: 60, 10: 100, 20: 90, 50: 50},
},
"scatter_triggers": {4: 1, 5: 2},
"force_wincap": True,
"force_freegame": True,
},
),
Distribution(
criteria="freegame",
quota=0.999,
conditions={
"reel_weights": {
self.basegame_type: {"BR0": 1},
self.freegame_type: {"FR0": 1},
},
"scatter_triggers": {3: 20, 4: 10, 5: 2},
"mult_values": {
self.basegame_type: {1: 1},
self.freegame_type: {2: 10, 3: 20, 4: 50, 5: 60, 10: 100, 20: 90, 50: 50},
},
"force_wincap": False,
"force_freegame": True,
},
),
],
)
```
--------------------------------
### Typical run_spin() win handling
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/gamestate_section/win_info.md
Example of calculating wins, updating the wallet manager, and emitting win events in a gamestate run_spin() function.
```python
self.win_data = self.get_lines()
self.win_manager.update_spinwin(self.win_data["totalWin"])
self.emit_linewin_events()
```
--------------------------------
### Anticipation array example
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/source_section/board_info.md
Shows the anticipation array format for a 5-reel game when 3 Scatters are needed and 2 are revealed. Values count upwards from 0 in +1 increments.
```python
self.anticipation = [0, 0, 1, 2, 3]
```
--------------------------------
### package.json for /apps/lines
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/file_struct.md
Example of the package.json file for the lines app, showing the module name used with the --filter flag.
```json
{
"name": "lines",
...
}
```
--------------------------------
### CSV example rows
Source: https://github.com/engineio/math-sdk/blob/main/docs/rgs_docs/data_format.md
Example rows of the CSV lookup table with uint64 values for simulation number, round probability, and payout multiplier.
```csv
1,199895486317,0
2,25668581149,20
3,126752606,140
...
```
--------------------------------
### Create gameActor finite state machine with xstate setup and createActor
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/context.md
Creates the gameActor finite state machine in createGameActor.svelte.ts using xstate's setup and createActor. Defines states for rendering, idle, bet, autoBet, resumeBet, and forceResult, with actors for each operation.
```typescript
// createGameActor.svelte.ts
import { setup, createActor } from 'xstate';
...
const gameMachine = setup({
actors: {
bet: intermediateMachines.bet,
autoBet: intermediateMachines.autoBet,
resumeBet: intermediateMachines.resumeBet,
forceResult: intermediateMachines.forceResult,
},
}).createMachine({
initial: 'rendering',
states: {
[STATE_RENDERING]: stateRendering,
[STATE_IDLE]: stateIdle,
[STATE_BET]: stateBet,
[STATE_AUTOBET]: stateAutoBet,
[STATE_RESUME_BET]: stateResumeBet,
[STATE_FORCE_RESULT]: stateForceResult,
},
});
const gameActor = createActor(gameMachine);
```
--------------------------------
### Example of a base game book (base_books.ts)
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/flowchart.md
JSON structure of a book returned from RGS, containing id, payoutMultiplier, events array, criteria, baseGameWins, and freeGameWins. The events array includes reveal, setTotalWin, and finalWin events.
```json
// base_books.ts - Example of a base game book
{
id: 1,
payoutMultiplier: 0.0,
events: [
{
index: 0,
type: 'reveal',
board: [
[{ name: 'L2' }, { name: 'L1' }, { name: 'L4' }, { name: 'H2' }, { name: 'L1' }],
[{ name: 'H1' }, { name: 'L5' }, { name: 'L2' }, { name: 'H3' }, { name: 'L4' }],
[{ name: 'L3' }, { name: 'L5' }, { name: 'L3' }, { name: 'H4' }, { name: 'L4' }],
[{ name: 'H4' }, { name: 'H3' }, { name: 'L4' }, { name: 'L5' }, { name: 'L1' }],
[{ name: 'H3' }, { name: 'L3' }, { name: 'L3' }, { name: 'H1' }, { name: 'H1' }],
],
paddingPositions: [216, 205, 195, 16, 65],
gameType: 'basegame',
anticipation: [0, 0, 0, 0, 0],
},
{ index: 1, type: 'setTotalWin', amount: 0 },
{ index: 2, type: 'finalWin', amount: 0 },
],
criteria: '0',
baseGameWins: 0.0,
freeGameWins: 0.0,
}
```
--------------------------------
### Example force_record_.json output
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/gamestate_section/force_info.md
Shows the structure of the force_record_.json file with entries containing a search key, timesTriggered count, and bookIds array.
```json
[
{
"search": {
"gametype": "basegame",
"kind": 5,
"symbol": "scatter"
},
"timesTriggered": 22134,
"bookIds": [
7,
12,
....
]
},
{
"search": {
"gametype": "basegame",
"kind": 6,
"symbol": "scatter"
},
"timesTriggered": 1196,
"bookIds": [
9,
10
...
]
},
...
]
```
--------------------------------
### Install package in editable mode
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/general_overview.md
Installs the package in editable mode for development, allowing source changes to take effect without reinstallation.
```sh
python3 -m pip install -e .
```
--------------------------------
### Example simulation output for simulation 58
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/quickstart.md
JSON output from library/books/books_base.jsonl for simulation 58. Shows events like reveal, winInfo, setWin, setTotalWin, and finalWin, along with payoutMultiplier and criteria. The payoutMultiplier corresponds to the lookup table value.
```json
{
"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
}
```
--------------------------------
### emitterEvent example
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/flowchart.md
An example of an emitterEvent object with type 'freeSpinCounterUpdate' and fields current and total.
```json
// bookEventHandlerMap.ts - Example of an emitterEvent
{
type: 'freeSpinCounterUpdate',
current: undefined,
total: bookEvent.totalFs,
}
```
--------------------------------
### TumbleBoard.svelte - Example of task-breakdown
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/task_bd.md
Shows the Svelte component subscribing to the individual emitterEvents (tumbleBoardShow, tumbleBoardHide, etc.) that make up the tumbleBoard bookEvent. This demonstrates how the atomic tasks are handled in the UI component.
```svelte
// TumbleBoard.svelte - Example of task-breakdown
context.eventEmitter.subscribeOnMount({
tumbleBoardShow: () => {},
tumbleBoardHide: () => {},
tumbleBoardInit: () => {},
tumbleBoardReset: () => {},
tumbleBoardExplode: () => {},
tumbleBoardRemoveExploded: () => {},
tumbleBoardSlideDown: () => {},
});
```
--------------------------------
### Example of a setTotalWin bookEvent (base_books.ts)
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/flowchart.md
JSON structure of a bookEvent with type 'setTotalWin', containing index and amount.
```json
// base_books.ts - Example of a setTotalWin bookEvent
{ index: 1, type: 'setTotalWin', amount: 0 },
```
--------------------------------
### Game round JSON example
Source: https://github.com/engineio/math-sdk/blob/main/docs/rgs_docs/data_format.md
Example of a minimum game round in JSON format before compression, showing the required id, events, and payoutMultiplier fields. The payoutMultiplier of 1150 corresponds to an 11.5x payout for a base game round costing 1.0x.
```json
{
"id": 1,
"events": [{}, ...],
"payoutMultiplier": 1150
}
```
--------------------------------
### Storybook story for Game component
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/file_struct.md
Storybook example showing the same pattern as the entry file: setContext() is called before rendering inside a StoryLocale.
```svelte
// ComponentsGame.stories.svelte
```
--------------------------------
### Record line-win in Lines class
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/utils_section/utilities.md
Example of recording a line-win within the Lines class, using the gamestate.record() function with the required keys.
```python
def record_line(kind: int, symbol: str, mult: int, gametype: str) -> None:
"""Force file description for line-win."""
gamestate.record({"kind": kind, "symbol": symbol, "mult": mult, "gametype": gametype})
```
--------------------------------
### Synchronous broadcast and subscribe
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/flowchart.md
Example of broadcasting an event synchronously with eventEmitter.broadcast and subscribing with subscribeOnMount in a Svelte component.
```typescript
// bookEventHandlerMap.ts - Example of broadcast
eventEmitter.broadcast({
type: 'freeSpinCounterUpdate',
current: undefined,
total: bookEvent.totalFs,
});
```
```svelte
// FreeSpinCounter.svelte - Example of receiving
context.eventEmitter.subscribeOnMount({
...,
freeSpinCounterUpdate: (emitterEvent) => {
if (emitterEvent.current !== undefined) current = emitterEvent.current;
if (emitterEvent.total !== undefined) total = emitterEvent.total;
},
...,
});
```
--------------------------------
### Asynchronous broadcast and subscribe
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/flowchart.md
Example of broadcasting an event asynchronously with eventEmitter.broadcastAsync and subscribing with an async handler in a Svelte component.
```typescript
// bookEventHandlerMap.ts - Example of broadcastAsync
await eventEmitter.broadcastAsync({
type: 'freeSpinIntroUpdate',
totalFreeSpins: bookEvent.totalFs,
});
```
```svelte
// FreeSpinIntro.svelte - Example of receiving
context.eventEmitter.subscribeOnMount({
...,
freeSpinIntroUpdate: async (emitterEvent) => {
freeSpinsFromEvent = emitterEvent.totalFreeSpins;
await waitForResolve((resolve) => (oncomplete = resolve));
},
...,
});
```
--------------------------------
### bookEventHandlerMap.ts - Example of task-breakdown
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/task_bd.md
Shows how the tumbleBoard bookEvent is broken down into smaller emitterEvents (tumbleBoardShow, tumbleBoardInit, etc.) in the event handler map. This allows step-by-step implementation and testing of each atomic task.
```typescript
// bookEventHandlerMap.ts - Example of task-breakdown
{
...,
tumbleBoard: async (bookEvent: BookEventOfType<'tumbleBoard'>) => {
eventEmitter.broadcast({ type: 'tumbleBoardShow' });
eventEmitter.broadcast({ type: 'tumbleBoardInit', addingBoard: bookEvent.newSymbols });
await eventEmitter.broadcastAsync({
type: 'tumbleBoardExplode',
explodingPositions: bookEvent.explodingSymbols,
});
eventEmitter.broadcast({ type: 'tumbleBoardRemoveExploded' });
await eventEmitter.broadcastAsync({ type: 'tumbleBoardSlideDown' });
eventEmitter.broadcast({
type: 'boardSettle',
board: stateGameDerived
.tumbleBoardCombined()
.map((tumbleReel) => tumbleReel.map((tumbleSymbol) => tumbleSymbol.rawSymbol)),
});
eventEmitter.broadcast({ type: 'tumbleBoardReset' });
eventEmitter.broadcast({ type: 'tumbleBoardHide' });
},
...,
}
```
--------------------------------
### Emitting an event after a game action
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/gamestate_section/events_info.md
Shows an example of importing and calling an event update function after a board transformation. The event should be emitted immediately to provide a snapshot of the game state.
```python
from src.Events.Events import update_freespin_event
run_spin():
...
update_freespin_event(self)
....
```
--------------------------------
### Example of a 'reveal' bookEvent (base_books.ts)
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/flowchart.md
JSON structure of a bookEvent with type 'reveal', containing index, board, paddingPositions, gameType, and anticipation.
```json
// base_books.ts - Example of a "reveal" bookEvent
{
index: 0,
type: 'reveal',
board: [
[{ name: 'L2' }, { name: 'L1' }, { name: 'L4' }, { name: 'H2' }, { name: 'L1' }],
[{ name: 'H1' }, { name: 'L5' }, { name: 'L2' }, { name: 'H3' }, { name: 'L4' }],
[{ name: 'L3' }, { name: 'L5' }, { name: 'L3' }, { name: 'H4' }, { name: 'L4' }],
[{ name: 'H4' }, { name: 'H3' }, { name: 'L4' }, { name: 'L5' }, { name: 'L1' }],
[{ name: 'H3' }, { name: 'L3' }, { name: 'L3' }, { name: 'H1' }, { name: 'H1' }],
],
paddingPositions: [216, 205, 195, 16, 65],
gameType: 'basegame',
anticipation: [0, 0, 0, 0, 0],
}
```
--------------------------------
### Terminal output showing RTP per thread
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/quickstart.md
Example terminal output printed when each simulation thread finishes, showing the total RTP and breakdown between base game and free game. The RTP is higher than expected due to forced max-win simulations.
```shell
Thread 0 finished with 1.632 RTP. [baseGame: 0.043, freeGame: 1.588]
```
--------------------------------
### Run storybook for a module
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/get_started.md
Run the storybook for a specific module using the --filter flag with the module name from package.json. The example uses 'lines' as the module name.
```bash
pnpm run storybook --filter=lines
```
--------------------------------
### FreeSpinCounter.svelte emitterEventHandlers
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/flowchart.md
Example from FreeSpinCounter.svelte showing the EmitterEventFreeSpinCounter type definition and the eventEmitter.subscribeOnMount call with handlers for show, hide, and update events. Each handler performs a minimal job, following the Single Responsibility Principle.
```svelte
// FreeSpinCounter.svelte and its emitterEventHandlers
...
```
--------------------------------
### bookEventHandlerMap with updateFreeSpin handler
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/flowchart.md
Example of a bookEventHandlerMap entry for the 'updateFreeSpin' bookEvent, broadcasting two events: 'freeSpinCounterShow' and 'freeSpinCounterUpdate'.
```typescript
// bookEventHandlerMap.ts - Example of "updateFreeSpin" bookEventHandler
export const bookEventHandlerMap: BookEventHandlerMap = {
...,
updateFreeSpin: async (bookEvent: BookEventOfType<'updateFreeSpin'>) => {
eventEmitter.broadcast({ type: 'freeSpinCounterShow' });
eventEmitter.broadcast({
type: 'freeSpinCounterUpdate',
current: bookEvent.amount,
total: bookEvent.total,
});
},
...,
}
```
--------------------------------
### run_freespin_from_base() recording scatter event
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/gamestate_section/force_info.md
Example of recording a custom event when a freespin is triggered from base game. Calls self.record() with a dictionary containing the count of scatter symbols, the symbol name, and the game type.
```python
def run_freespin_from_base(self, scatter_key: str = "scatter") -> None:
self.record(
{
"kind": self.count_special_symbols(scatter_key),
"symbol": scatter_key,
"gametype": self.gametype,
}
)
self.update_freespin_amount()
self.run_freespin()
```
--------------------------------
### Event format example
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/gamestate_section/events_info.md
Shows the required structure of an event object with index, type, and custom fields. The index tracks the event number, type is a unique identifier, and fields can be any data type.
```python
event = {
"index": [int],
"type": [str],
"": [T],
...
"": [T]
}
```
--------------------------------
### Reelstrip dictionary and CSV loading
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/gamestate_section/configuration_section/config_overview.md
Stores reelstrips as a dictionary in self.config.reels and loads them from CSV files using read_reels_csv(). The example shows how to iterate over a mapping of reel keys to filenames and populate the reels dictionary.
```python
reels = {"BR0": "BR0.csv", "FR0": "FR0.csv"}
self.reels = {}
for r, f in reels.items():
self.reels[r] = self.read_reels_csv(str.join("/", [self.reels_path, f]))
```
--------------------------------
### Example JSON structure of a Book
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/overview_section/state_overview.md
Shows the JSON schema for a Book object, which includes an integer id, float payoutMultiplier, an array of events, a criteria string, and float baseGameWins and freeGameWins. Use this structure when serializing or deserializing simulation results.
```json
[
{
"id": int,
"payoutMultiplier": float,
"events": [ {}, {}, {} ],
"criteria": str,
"baseGameWins": float,
"freeGameWins": float
}
]
```
--------------------------------
### Reel weight conditions for multiple reelstrips
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/gamestate_section/configuration_section/config_overview.md
Defines reel weight conditions for each game-type, allowing weighted selection of reelstrips. The example shows a conditions dictionary with reel_weights for basegame and freegame types.
```python
conditions={
"reel_weights": {self.basegame_type: {"BR0": 2, "BR1": 1}, self.freegame_type: {"FR0":5, "FR1": 1}},
},
```
--------------------------------
### Ways calculation with multiplier
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/source_section/ways_info.md
Shows the calculation of total ways for the H1 symbol given the example board. The multiplier value multiplies the number of ways, leading to a payout of 6 ways.
```sh
(1) * (2) * (3) = 6 ways
```
--------------------------------
### Python reset_book method
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/overview_section/state_overview.md
Resets the book to a clean state at the start of a simulation, setting the id to sim+1, payoutMultiplier to 0.0, events to an empty list, and criteria to self.criteria. Call this method before running a new simulation to ensure no stale data.
```python
def reset_book(self) -> None:
self.book = {
"id": self.sim + 1,
"payoutMultiplier": 0.0,
"events": [],
"criteria": self.criteria,
}
```
--------------------------------
### Run simulations with create_books and generate_configs
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/overview_section/game_format.md
Entry point for running simulations. Sets simulation parameters (threads, batching size, compression, profiling), creates a GameConfig and GameState, then calls create_books to allocate win criteria and generate output files, and generate_configs to produce configuration files.
```python
if __name__ == "__main__":
num_threads = 1
rust_threaeds = 20
batching_size = 50000
compression = False
profiling = False
num_sim_args = {
"base": int(10),
"bonus": int(10),
}
config = GameConfig()
gamestate = GameState(config)
create_books(
gamestate,
config,
num_sim_args,
batching_size,
num_threads,
compression,
profiling,
)
generate_configs(gamestate)
```
--------------------------------
### Entry +page.svelte for apps/lines
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/file_struct.md
Entry file for the sample game apps/lines. Sets the Svelte context at the entry level so children can access it, then renders the Game component.
```svelte
// +page.svelte
```
--------------------------------
### Clone the repository
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/get_started.md
Clone the repository to your local machine and navigate into the web-sdk directory.
```bash
git clone
cd web-sdk
```
--------------------------------
### Define optimization parameters with OptimizationSetup
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/optimization_section/optimization_algorithm.md
Defines the optimization parameters dictionary for a game mode. Keys are betmode names, and each value contains conditions, scaling, and parameters. The order of conditions keys matters because simulation IDs are assigned sequentially.
```python
opt_params = : {
"conditions": ...
"scaling": ...
"parameters:
}
```
--------------------------------
### Run simulation with formatting
Source: https://github.com/engineio/math-sdk/blob/main/docs/books_formatting.md
Command to run the simulation, which triggers automatic formatting of books files after completion.
```bash
make run GAME=0_0_tower_defense
```
--------------------------------
### Type definition for BookEventUpdateGlobalMult
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/steps.md
Add this type to typesBookEvent.ts and include it in the BookEvent union type to get TypeScript intellisense.
```typescript
// typesBookEvent.ts
type BookEventUpdateGlobalMult = {
index: number;
type: 'updateGlobalMult';
globalMult: number;
};
export type BookEvent =
| ...
| BookEventUpdateGlobalMult
| ...
;
```
--------------------------------
### Configure simulation parameters in run.py
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/quickstart.md
Settings to simulate 100 results without compression for inspection. Uses 1 thread, disables optimization and analysis. The num_sim_args values correspond to running run_spin() 100 times for base and bonus modes.
```python
num_threads = 1
compression = False
num_sim_args = {
"base": 100,
"bonus": 100,
}
run_conditions = {
"run_sims": True,
"run_optimization": False,
"run_analysis": False
}
```
--------------------------------
### Configure simulation and run conditions
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/quickstart.md
Sets the number of simulations per mode (base and bonus) to 10,000 and enables simulation, optimization, and analysis while disabling data upload. Use this to run a batch of simulations with the specified parameters.
```python
num_sim_args = {
"base": int(1e4),
"bonus": int(1e4),
}
run_conditions = {
"run_sims": True,
"run_optimization": True,
"run_analysis": True,
"upload_data": False,
}
```
--------------------------------
### Simulate player balances over spins
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/optimization_section/distribution_optimization.pdf
Initializes an empty list for final balances, then for each player, simulates a series of spins, updating the balance by subtracting bet cost and adding payout, and records the balance after each spin.
```python
final_balance = []
for player in range(n_players):
balance = starting_balance
spin_balance = []
for spin in range(N_spins):
balance -= bet_cost
payout = weighted_random_draw(payouts, weights)
balance += payout
spin_balance.append(balance)
final_balance.append(spin_balance)
```
--------------------------------
### Before formatting (raw JSONL)
Source: https://github.com/engineio/math-sdk/blob/main/docs/books_formatting.md
Shows the raw JSONL content before formatting, with a compact single-line structure.
```json
{"id": 1, "events": [{"type": "reveal", "board": [[{"name": "L1"}, {"name": "H1"}]]}]}
```
--------------------------------
### Run optimization for game modes with OptimizationExecution
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/optimization_section/optimization_algorithm.md
Specifies which game modes to optimize and runs the Rust binary for each. The OptimizationExecution class generates math_config.json and setup.txt files before execution.
```python
optimization_modes_to_run = ["base", "bonus"]
OptimizationExecution().run_all_modes(config, optimization_modes_to_run, rust_threads)
```
--------------------------------
### Create virtual environment
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/general_overview.md
Creates a virtual environment named 'env' using Python 3.12 or later.
```sh
python3 -m venv env
```
--------------------------------
### Activate virtual environment on Windows
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/general_overview.md
Activates the virtual environment on Windows.
```sh
env\Scripts\activate.bat
```
--------------------------------
### Game directory structure
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/overview_section/game_struct.md
Recommended folder and file layout for a game, copied from the games/template folder. Sub-folders under library/ are auto-generated if missing. readme.txt holds developer notes.
```text
game/
├── library/
|----- books/
|----- books_compressed/
|----- configs/
|----- forces/
|----- lookup_tables/
├── reels/
├── readme.txt
├── run.py
├── game_config.py
├── game_executables.py
├── game_calculations.py
├── game_events.py
├── game_override.py
└── gamestate.py
```
--------------------------------
### Build Rust binary with cargo build --release
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/optimization_section/optimization_algorithm.md
Compiles the Rust optimization algorithm into a release binary. Run this when executing the program for the first time or after modifying main.rs.
```sh
cargo build --release
```
--------------------------------
### Disable BetButton using stateXstateDerived.isPlaying()
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/context.md
Example of using stateXstateDerived.isPlaying() to disable a UI button during gameplay. Imports getContext from '../context' and uses the context's stateXstateDerived to control the disabled prop.
```svelte
// BetButton.svelte - Example of interaction between xstate and UI
```
--------------------------------
### Run make run with game ID
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/general_overview.md
Executes the run.py file for a specific game after setting relevant parameters.
```sh
make run GAME=
```
--------------------------------
### Monorepo directory structure
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/file_struct.md
Shows the monorepo layout with /apps containing individual game folders and /packages containing shared modules.
```text
root
|_apps
| |_cluster
| |_lines
| |_price
| |_scatter
| |_ways
|
|_packages
|_config-*
|_constants-*
|_state-*
|_utils-*
|_components-*
|_pixi-*
```
--------------------------------
### Balance Display and Game Wrapper Styles
Source: https://github.com/engineio/math-sdk/blob/main/docs/simple_example/css.txt
Styles for the balance display, game wrapper, and game content containers.
```css
.balance-display {
font-size: 1.5rem;
font-weight: bold;
color: white;
margin: 0.5rem
}
.game-wrapper {
display: flex;
justify-content: center;
align-items: flex-start;
gap: 4rem;
padding: 2rem;
}
.game-content {
display: flex;
flex-direction: column;
align-items: center;
gap: 1rem;
}
```
--------------------------------
### Import local packages with workspace:* in /apps/lines/package.json
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/file_struct.md
Shows how to reference local monorepo packages as dependencies using the workspace:* protocol in a package.json file. Use this when adding local packages to an app or another local package without publishing to npm.
```json
{
"name": "lines",
...,
"devDependencies": {
...,
"config-ts": "workspace:*",
},
"dependencies": {
...,
"pixi-svelte": "workspace:*",
"constants-shared": "workspace:*",
"state-shared": "workspace:*",
"utils-shared": "workspace:*",
"components-shared": "workspace:*",
}
}
```
--------------------------------
### GameConfig class for setting game parameters
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/overview_section/game_format.md
Defines the GameConfig class that sets all game parameters in its __init__() function, including game_id, provider_number, working_name, wincap, win_type, rtp, num_reels, num_rows, paytable, include_padding, special_symbols, freespin_triggers, reels, and bet_modes. All required fields from the Config class should be filled out explicitly for each new game.
```python
class GameConfig(Config):
def __init__(self):
super().__init__()
self.game_id = ""
self.provider_number = 0
self.working_name = ""
self.wincap = 0
self.win_type = "lines"
self.rtp = 0
self.num_reels = 0
self.num_rows = [0] * self.num_reels
self.paytable = {
(kind, symbol): payout,
}
self.include_padding = True
self.special_symbols = {"property": ["sym_name"],...}
self.freespin_triggers = {
}
self.reels = {}
self.bet_modes = []
```
--------------------------------
### Clone Math SDK repository
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/general_overview.md
Clone the Math SDK repository using SSH.
```sh
git@github.com:StakeEngine/math-sdk.git
```
--------------------------------
### POST /wallet/play
Source: https://github.com/engineio/math-sdk/blob/main/docs/rgs_docs/RGS.md
Initiates a game round and debits the bet amount from the player's balance.
```APIDOC
## [POST] /wallet/play
### Description
Initiates a game round and debits the bet amount from the player's balance.
### Method
POST
### Endpoint
/wallet/play
### Parameters
#### Request Body
- **amount** (number) - Required - The bet amount to debit.
- **sessionID** (string) - Required - The session identifier.
- **mode** (string) - Required - The bet mode (e.g., "BASE").
### Request Example
{
"amount": 100000,
"sessionID": "xxxxxxx",
"mode": "BASE"
}
### Response
#### Success Response (200)
- **balance** (object) - The player's current balance.
- **balance.amount** (number) - The balance amount.
- **balance.currency** (string) - The currency code.
- **round** (object) - The round information.
#### Response Example
{
"balance": {
"amount": 100000,
"currency": "USD"
},
"round": { ... }
}
```
--------------------------------
### Display the board with print_board()
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/gamestate_section/syms_board_section/board_info.md
Call print_board() on a Board instance to display a correctly oriented printout of all symbol names. The output shows a 5x3 grid of symbol names.
```python
self.print_board(self.board) ->
```
```sh
L5 L3 L4 L4 L4
L3 H4 L3 H1 L4
L3 H1 S L3 H1
```
--------------------------------
### Run app in DEV mode with pnpm
Source: https://github.com/engineio/math-sdk/blob/main/docs/fe_docs/file_struct.md
Runs the lines app in DEV mode instead of the storybook. Replace 'lines' with the module name from the app's package.json.
```bash
pnpm run dev --filter=lines
```
--------------------------------
### run_spin() base game loop in GameState
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/overview_section/game_format.md
Entry point for any simulation. Seeds the RNG with the simulation number, then loops until betmode distribution criteria are satisfied, drawing a board, evaluating wins, updating the wallet manager, emitting events, and optionally running the freegame. Ends by saving the simulation result with imprint_wins().
```python
def run_spin(self, sim):
self.reset_seed(sim) #seed the RNG with the simulation number
self.repeat = True
while self.repeat:
self.reset_book() #reset local variables
self.draw_board() #rraw board from reelstrips
#evaluate win_data
#update win_manager
#emit relevant events
self.win_manager.update_gametype_wins(self.gametype) #update cumulative basegame wins
if self.check_fs_condition(): #check scatter conditions
self.run_freespin_from_base() #run freegame
self.evaluate_finalwin()
self.check_repeat() #Verify betmode distribution conditions are satisfied
self.imprint_wins() #save simulation result
```
--------------------------------
### Overlay meta structure
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/gamestate_section/win_info.md
Shows the overlay key included in the meta tag for cluster and scatter pay sample games, containing reel and row positions.
```python
'meta': {
...
'overlay': {'reel': [int], 'row': [int]}
}
```
--------------------------------
### After formatting (pretty-printed JSON)
Source: https://github.com/engineio/math-sdk/blob/main/docs/books_formatting.md
Shows the formatted JSON with 2-space indentation, keeping simple name objects like {"name": "L1"} compact on single lines.
```json
{
"id": 1,
"events": [
{
"type": "reveal",
"board": [
[
{"name": "L1"},
{"name": "H1"}
]
]
}
]
}
```
--------------------------------
### Activate virtual environment on macOS
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/general_overview.md
Activates the virtual environment on macOS.
```sh
source env/bin/activate
```
--------------------------------
### Base HTML and Body Styles
Source: https://github.com/engineio/math-sdk/blob/main/docs/simple_example/css.txt
Sets the height, display, padding, font, color, and background for the body, and styles the h1 heading.
```css
html,
body {
height: 100%;
}
body {
display: grid;
place-content: center;
padding: 2rem;
font-family: sans-serif;
color: var(--txt-1);
background-color: var(--bg-1);
}
h1 {
font-size: 4rem;
text-align: center;
text-transform: capitalize;
}
```
--------------------------------
### Test package import
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/general_overview.md
Tests the package import in a Python interactive session.
```sh
python
>>> import your_package_name
```
--------------------------------
### win_data structure initialization
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/gamestate_section/win_info.md
Defines the win_data dictionary structure used to store total win and list of win entries. This is the return value for all win calculation functions.
```python
win_data = {
'totalWin': [float],
'wins': [List[Dict]]
}
```
--------------------------------
### Force record JSON keys format
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/utils_section/utilities.md
Format for the keys in a force_record_.json file, where wins are recorded with symbol name and number of symbols in the win.
```python
'symbol': '',
'kind' : ''
```
--------------------------------
### Balance Request - HTTP Method
Source: https://github.com/engineio/math-sdk/blob/main/docs/rgs_docs/RGS.md
HTTP POST method for the /wallet/balance endpoint.
```http
POST /wallet/balance
```
--------------------------------
### record() method appending description and book_id to temp_wins
Source: https://github.com/engineio/math-sdk/blob/main/docs/math_docs/gamestate_section/force_info.md
Defines the record() method that appends the description dictionary and the current book_id to self.temp_wins. Called whenever a custom event should be recorded.
```python
def record(self, description: dict) -> None:
self.temp_wins.append(description)
self.temp_wins.append(self.book_id)
```