### 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) ```