Reference for the four built-in win evaluation methods — Lines, Ways, Cluster, and Scatter — including wild substitution, multiplier strategies, and the win_data structure.
Use this file to discover all available pages before exploring further.
The Stake Engine Math SDK provides four win evaluation methods. You select one by setting config.win_type in your GameConfig, then call the corresponding function from within run_spin() or run_freespin().All four methods return the same win_data structure, so wallet manager updates and event emission are consistent regardless of which method you use.
win_data = { "totalWin": float, # sum of all wins for this board state "wins": [ { "symbol": str, # winning symbol name "kind": int, # number of matching symbols "win": float, # payout amount (after multipliers) "positions": list, # [{"reel": int, "row": int}, ...] "meta": dict, # method-specific extra data }, ... ]}
The positions key is required for the predefined win event functions to correctly adjust row numbers when padding symbols are in use.
The resulting meta dict includes multiplier, winWithoutMult, globalMult, and lineMultiplier (for lines) or symbolMult and ways (for ways), giving the frontend full detail to display the win breakdown.
self.win_data = Lines.get_lines( board=self.board, config=self.config, wild_key="wild", # attribute name for wild symbols wild_sym="W", # symbol name for wild-only wins multiplier_method="symbol", global_multiplier=self.global_mult,)self.win_manager.update_spinwin(self.win_data["totalWin"])Lines.emit_linewin_events(self)
Wilds substitute for any non-wild symbol. When a payline begins with one or more wilds followed by a non-wild symbol, the engine evaluates both the wild-only win and the substituted win, taking whichever pays more:
Payline [W, W, W, L4, L4] evaluates (3, "W") vs (5, "L4") and keeps the higher payout.
Wilds on the first reel do not trigger substitution — only wild-then-symbol sequences from left to right are evaluated. A common approach is to define wild symbols to pay only for complete lines (e.g. 5-of-a-kind wilds only), avoiding ambiguous comparisons.
Ways games pay for like-symbols (or wilds) appearing on consecutive reels, regardless of row. The total number of winning combinations — “ways” — is the product of the symbol count on each consecutive reel.The maximum possible ways for a board is num_rows[0] × num_rows[1] × ... × num_rows[n-1].
For each symbol, the engine counts how many positions it occupies per reel and multiplies across consecutive reels:
Board:L5 H1 L4 L4 L4L1 H4 L3 H2 L4H1 H1 H1 L3 H3
For symbol H1: reel 1 has 1, reel 2 has 2, reel 3 has 1 → 1 × 2 × 1 = 2 ways. Payout is config.paytable[(3, "H1")] × 2.When a symbol carries a multiplier attribute, the symbol strategy adds the multiplier value to the reel count instead of counting the symbol once:
H1 on reel 3 has a 3x multiplier → reel count becomes 3 instead of 1Total ways: 1 × 2 × 3 = 6 ways
Ways games do not account for wild symbols on the first reel.
"meta": { "ways": int, # total number of winning ways "globalMult": int, # global multiplier applied "winWithoutMult": float, # base win before global multiplier "symbolMult": int, # cumulative symbol multiplier contribution}
Cluster games pay when a group of adjacent like-symbols (sharing a reel or row edge — diagonals do not count) meets or exceeds a minimum cluster size. A minimum of 5 symbols is typical.
Cluster games commonly use a tumble mechanic. Winning symbols are marked with explode = True by evaluate_clusters(). After emitting events, call tumble_game_board() to remove them and fill vacant positions from the reelstrip above:
gamestate.py
# Initial evaluationself.win_data = Cluster.get_cluster_data( config=self.config, board=self.board, global_multiplier=self.global_multiplier,)self.win_manager.update_spinwin(self.win_data["totalWin"])self.emit_tumble_win_events()# Continue tumbling while wins exist and wincap not hitwhile self.win_data["totalWin"] > 0 and not self.wincap_triggered: self.tumble_game_board() self.win_data = Cluster.get_cluster_data( config=self.config, board=self.board, global_multiplier=self.global_multiplier, ) self.win_manager.update_spinwin(self.win_data["totalWin"]) self.emit_tumble_win_events()
Clusters are found using a Breadth-First Search (BFS) algorithm. Wild symbols can contribute to multiple clusters simultaneously, including clusters of different symbols.
"meta": { "globalMult": int, # global multiplier applied "clusterMult": int, # sum of multiplier attributes in the cluster "winWithoutMult": float, # base paytable payout "overlay": { "reel": int, # reel of the win-amount overlay position "row": int, # row of the win-amount overlay position }}
The overlay position is the board cell closest to the centre-of-mass of the winning cluster, used by the frontend to position the win-amount display.
Scatter-pays games award wins based on the total count of a symbol anywhere on the board. Symbols do not need to be adjacent or on a payline. A minimum count of 8 is typical, though this is defined in your paytable.
"meta": { "globalMult": int, # global multiplier applied "clusterMult": int, # sum of multiplier attributes on winning positions "winWithoutMult": float, # base paytable payout "overlay": { "reel": int, # reel of the win-amount overlay position "row": int, # row of the win-amount overlay position }}