Carpathian Treasures: Code Walkthrough
Carpathian Treasures: Code Walkthrough
This guide is for developers who are new to the game code. It explains the job of each function in Carpathian Treasures, when it is used, and what it passes along. It also gives a source-structure map of all game packages currently under games/ so the Carpathian implementation can be understood in the context of the repository's shared pattern.
This is a code guide, not a description of unimplemented features. For game rules, payout values, symbol distribution, and math-sheet terms, see the gameplay guide. For the pack/bootstrap, HTTP, game-core, SDK, and RGS call flow, see the shared runtime architecture guide. For certified build artifacts, hash verification, RNG-trace packaging, and request-body Base64 decoding, see certification and request encoding.
1. How Game Packages Are Organized
The inspected game packages share a common set of core files. The names describe typical responsibilities, not a promise that every game's code is identical.
| File or folder | Usual responsibility |
|---|---|
src/plugin.ts | Implements the SDK game-plugin contract. Adapts host inputs and outputs, loads math data, and delegates game work. |
src/engine.ts | Coordinates a round: chooses the relevant math section, generates or modifies the board, and calls game logic. |
src/logic.ts | Calculates game rules such as line wins, clusters, cascades, features, and totals. |
src/interfaces.ts | Defines game-specific input, math, and result types shared by that game's files. |
src/maths/ | Stores the game's mode-specific math JSON, such as reel strips, paytables, and probability tables. |
src/index.ts | Exposes the plugin class and the types the pack or shared game core needs to import. |
All 13 current game packages contain this core set and implement the SDK's ISlotGamePlugin contract. Some add helper modules for game-specific mechanics. This is an observed repository pattern; follow the target game's existing structure when adding code.
| Game package | Additional source modules observed |
|---|---|
bookofstorms | None beyond the core set |
bookofstormslightningwin | cheat-logic.ts, feature-trigger-check.ts |
carpathiantreasures | None beyond the core set |
empireofgold | None beyond the core set |
empireofgoldnewconquest | symbol-change.ts |
frostedmarketbonanza | symbol-conversion.ts |
houseofcards | house-board.ts |
jokercharge | config.ts, cheat-logic.ts |
meowmeowmeow | cheat-logic.ts, feature-helpers.ts |
minedash | cheat-logic.ts, stone-meter.ts |
pigstyle | cheat-logic.ts, pigstyle-helpers.ts |
royale81 | None beyond the core set |
sweetsalon | None beyond the core set |
Those extra modules are local to their games. Do not assume a mechanic in one game is part of the shared game contract just because another package has a similarly named helper.
2. Carpathian Treasures Round Flow
The main path for a normal spin is:
flowchart TD
A[Host calls plugin.spin] --> B[Plugin selects cached R4 math]
B --> C[Engine executeSpin]
C --> D[SDK generateReelView]
D --> E[Logic spin]
E --> F[Resolve expanding wilds and evaluate paylines]
F --> G[Calculate scatter and bonus-symbol pays]
G --> H[Plugin builds SDK spin output]
The startup path is separate: the host calls onLoad, which loads the math JSON into a cache. init later reads the cached paytable. A simulator can also ask for the reel-stop data saved by the most recent spin.
3. Plugin: Host-Facing Adapter
The plugin implements the SDK contract. Its job is to translate host-level inputs into game-engine inputs and package game results into the shared output shapes. It should not own the detailed reel or payout algorithm.
| Function | Why it exists and when it is used | What it does / returns |
|---|---|---|
onLoad() | Called when the pack starts, before game requests are handled. | Reads each declared math mode from src/maths/ and stores parsed JSON in mathCache. Loading once avoids reading the file for every spin. |
getMath(mode) | Internal helper called by init, spin, and feature. | Returns the cached config for a mode. Throws a descriptive error if that mode was not loaded, so a bad mode fails at the boundary rather than deeper in scoring. |
init(input) | Called when a client/session initializes this game. | Selects the requested math mode and returns its paytable as payTable. It does not generate a board. |
spin(input) | Called for a normal base-game spin. | Gets math, normalizes the optional development-only extraData.combination, calls engine.executeSpin, then maps the result into ISpinOutput: total win, trigger flag, gameData, and base/bonus summaries. |
feature(input) | Called by the host when continuing a feature round. | Passes the previous result and feature input to engine.executeFeature, then returns IFeatureOutput. In this game the engine returns the previous result unchanged, so no new feature spin occurs and the output is complete. |
getLastSpinSimData() | Called by the simulator, not by a normal client spin response. | Delegates to the engine and returns the saved reel stops for simulation analysis. |
feature exists because the shared plugin interface supports games with feature rounds. Its presence does not mean every game implements a playable feature; check the engine and logic for the actual behavior.
4. Engine: Round Orchestration
The engine is the middle layer between the plugin and game rules. It prepares the board, uses shared SDK helpers where appropriate, and delegates scoring to CarpathianTreasuresLogic.
| Function | Why it exists and when it is used | What it does / returns |
|---|---|---|
executeSpin(input, math) | Called by plugin.spin for every normal spin. | Reads layout, optionally accepts a valid development-mode stop combination, and calls generateReelView with BG.ReelSet_1. Saves the generated stops, then calls logic.spin with the bet, board, and math config. Returns the completed SpinResult. |
getLastSpinSimData() | Called by the plugin's simulator hook after a spin. | Wraps the engine's saved reel stops in the SDK's ISimSpinData shape. It does not generate another spin. |
executeFeature(input, math) | Called by plugin.feature when the host requests a feature step. | Currently returns a shallow copy of previousSpinResult. _math is unused because this milestone has no free-spin or bonus-round logic. |
generateReelView is an SDK function, not a Carpathian function. It draws one stop per reel, then selects consecutive strip entries for visible rows. Keeping this generic work in the SDK avoids duplicating reel construction in each game.
5. Logic: Game Rules and Payouts
CarpathianTreasuresLogic owns this game's score calculation. It uses SDK arithmetic and win-line helpers, while keeping Carpathian-specific choices such as symbol IDs and payout configuration in the math JSON.
| Function | Why it exists and when it is used | What it does / returns |
|---|---|---|
spin(input) | Called by engine.executeSpin after a board has been generated. | Coordinates scoring: resolves wild expansion, converts SDK line wins into the game's result shape, counts scatter and bonus symbols, scales those pays by bet/base bet, sums the totals, and returns SpinResult. |
resolveWildExpansion(input) | Private helper called by spin before line payouts are finalized. | Finds reels containing WD, presents those columns as wilds to the line calculator, and identifies which candidate reels were actually used by winning line positions. Returns the display expandedReelView, expanded column indices, and SDK line result. |
findPositions(reelView, symbol) | Private helper called by spin for scatter and bonus positions. | Scans the column-major board and returns every matching coordinate as [column, row]. |
countSymbol(reelView, symbol) | Private helper called by spin to count bonus symbols. | Scans all visible cells and returns the number matching the requested symbol. That count selects the bonus-symbol paytable entry. |
The SDK's calculateWinLines function evaluates the configured line paths and returns winning line details and a total. Carpathian passes isColumnMajor: true, its symbol payout table, and payoutMode: 'baseBet'. The SDK arithmetic helpers add, multiply, and divide are used to combine and scale payout values.
Wild-expansion detail
resolveWildExpansion treats any column containing a wild as a candidate expanded column during line evaluation. It uses a Proxy to make cells in that column read as WD without first modifying the original reel view. After line calculation, only candidate columns used by a winning line are represented as fully expanded in expandedReelView and listed in wildExpandedReels. This separates the evaluation view from the original generated board.
6. Interfaces and Exports
These files describe how the pieces fit together without performing a spin themselves.
| File / type | Purpose |
|---|---|
interfaces.ts / SpinResult | Defines the game-specific result, including both reel views, wins, positions, totals, and feature continuation fields. |
interfaces.ts / GameSpinInput | Defines the inputs the plugin passes to executeSpin, including bet, mode, and optional development data. |
interfaces.ts / GameFeatureInput | Defines feature-engine inputs, including the previous spin result. |
interfaces.ts / CarpathianTreasuresMathConfig | Gives TypeScript a shape for the R4 JSON. It declares three reel sets and selector weights even though this engine currently reads only BG.ReelSet_1. |
index.ts | Exports CarpathianTreasuresPlugin for package registration and SpinResult as a type for the shared game core. |
The SDK's ISlotGamePlugin is the common host-facing contract. ISpinInput, ISpinOutput, IFeatureInput, and related types come from the SDK; the game-specific result remains in this package and is carried as generic gameData.
7. Where to Make a Change
| Change requested | Start here |
|---|---|
| Change reel strips, paylines, symbol pays, or layout values | src/maths/carpathian-treasures-R4.json |
| Change which math fields have compile-time types | src/interfaces.ts |
| Change how a normal round generates its board | src/engine.ts and, for shared reel behavior, the SDK reel generator |
| Change line/scatter/bonus payout rules or wild expansion | src/logic.ts |
| Change how the game is loaded or how inputs/outputs are adapted | src/plugin.ts |
| Change what the game package exports | src/index.ts |
Before editing a rule, check whether the desired behavior is already in the math JSON, this game's logic, or a shared SDK helper. Keep game-specific rules in the game package and only change shared SDK code when the behavior is genuinely common across games.
8. HTTP Request Keys
The HTTP controller receives request DTOs. These are not the same shape as the inputs passed to a game plugin: GameService handles session lookup, RGS calls, and shared fields before it calls the plugin.
POST /games/init
| Root key | Required? | Use |
|---|---|---|
gameId | Yes | Selects the registered game plugin. |
token | Yes | RGS player-session token. The core uses it for RGS calls; it is not passed to the game plugin. |
deviceType | No | Sent to RGS during initialization, for example desktop. |
extraData | No | Optional game-specific object. The current core init path does not pass it to Carpathian's plugin.init. |
POST /games/spin
| Root key | Required? | Use |
|---|---|---|
gameId | Yes | Selects the game plugin. |
token | Yes | Identifies the RGS session for debit, update, or credit. Not passed to the plugin. |
betAmount | Yes | Wager in minor currency units. The core submits it to RGS and passes it to the plugin. |
buyBonus | No | Object containing feature; tells the core which bonus to request from RGS and sets the buy-bonus bet type. |
usePromo | No | Explicitly asks RGS to use an eligible Promo FreeSpins award on this spin. Core/RGS concern; not passed to the game plugin. |
extraData | No | Game-specific values. Core merges in RGS-owned progressData before passing it to the plugin. |
epoch | No | Session concurrency version returned by init and sent back to RGS with the debit request. |
POST /games/feature
| Root key | Required? | Use |
|---|---|---|
gameId | Yes | Selects the game plugin. |
token | Yes | Lets the core load the saved round and settle it with RGS. Not passed to the plugin. |
extraData | No | Game-specific data for this feature step. |
selection | No | Player choice for pick-style features. Carpathian does not currently use it. |
epoch | No | Session concurrency version used when the core loads the saved round. |
The spin DTO converts betAmount to a number, can convert string usePromo to a boolean, normalizes empty buyBonus objects to absent, and parses epoch as a number. The feature DTO also parses epoch. Request validation happens before GameService handles the request.
9. Core-to-Plugin Keys
The SDK interfaces define a shared contract. A game's plugin only receives the values the core chooses to pass; it does not receive the whole HTTP body or raw RGS session.
| Plugin method | Shared input keys | Meaning and Carpathian use |
|---|---|---|
init(input) | gameMode, optional extraData | Core passes RGS-selected gameMode; Carpathian uses it to choose cached math. The current core path does not forward init extraData. |
spin(input) | gameMode, betAmount, devMode, isBuyBonus, optional buyBonus, rgsMaxWin, optional extraData | Carpathian uses gameMode, betAmount, devMode, and extraData.combination. It currently ignores isBuyBonus and buyBonus. rgsMaxWin is renamed to the engine input maxWin but is not consumed by the current spin logic. |
feature(input) | previousSpinResult, gameMode, betAmount, devMode, isBuyBonus, optional buyBonus, rgsMaxWin, optional selection, optional extraData | Core reconstructs these from the saved RGS round plus the current request. Carpathian's feature engine currently uses only previousSpinResult and returns it unchanged. |
For a spin, the core gets gameMode, allowCheat, maxWin, and progressData from RGS after debit. It derives devMode from allowCheat. It overwrites extraData.progressData with the RGS value, so client input cannot supply or replace persisted game state. gameId, token, usePromo, and epoch are handled by the core/RGS flow and are not game-plugin input keys.
Plugin output keys
These are the values returned by a game's plugin before GameService builds the HTTP response:
| Plugin method | Output key | Use |
|---|---|---|
init | payTable | Paytable for the selected game mode; required by the SDK contract. |
init | gameData | Optional game-specific initialization data. Carpathian does not currently return it. |
spin | totalWin | Total spin win; core uses it to decide and request the RGS credit amount. |
spin | featureTriggered | Tells the core whether to leave the round open and persist state, or settle it immediately. |
spin | gameData | Game-specific spin result passed through to the API response and RGS round state. |
spin | baseWinAmount | Optional base-game-only amount for market-specific reporting. |
spin | bonusWinAmount | Optional cumulative feature/bonus-round amount for market-specific reporting. |
spin | bonusRoundCount | Optional number of feature sub-spins for market-specific reporting. |
feature | totalWin, gameData, reporting amounts | Same roles as spin output, for the accumulated feature flow. |
feature | featureComplete | Tells the core whether to credit and close the round or persist the continuing feature state. |
Carpathian currently sets featureTriggered to false, reports zero bonus amount/count, and returns nextFeature: null in gameData. Its feature output is completed immediately because no feature round is implemented.
10. Response Keys and Global Settings
HTTP response envelope
The controller wraps successful endpoint data in ApiResponseDto:
| Root key | Use |
|---|---|
success | true for a successful response. |
statusCode | HTTP status code, normally 200 for these success responses. |
message | Human-readable operation message. |
data | Endpoint-specific init, spin, or feature response. |
extensions | Optional structured error details: name, code, public, and, when enabled for development, context, logLevel, stack, internal, and prevErrorMessage. |
metadata | Optional pagination data: totalItems, page, limit, and morePages; not normally used for game operations. |
The health endpoint is an exception: it returns { status, games } directly rather than using the standard envelope.
Init data
| Root key | Use |
|---|---|
unfinishedInfo | Saved unfinished round details from RGS, or null when there is no unfinished round. |
gameInfo | Game identity and game-provided configuration for the client. |
playerInfo | Frontend-friendly player and bet limits mapped from RGS init data. |
betType | Bet type associated with the unfinished round, or null. |
preferences | Player preferences returned by RGS, defaulting to an empty object. |
opCnf | Operator configuration (operatorConfig) returned by RGS, defaulting to an empty object. This is the closest current init key to “global settings”; there is no single globalSettings field in these contracts. |
rtp | RGS-provided RTP configuration/values, defaulting to an empty object. This is separate from the game's paytable and from the gameMode math-file selection. |
promoInfo | Optional active promotion state returned by RGS. |
epoch | Optional session concurrency value that the client echoes on applicable later requests. |
gameInfo contains gameId, devMode, payTable, and optional gameData. Carpathian provides the paytable; the core sets devMode and may merge RGS progressData into gameData for games that use persisted progression.
playerInfo is built by getPlayerInfo, which renames selected RGS fields for the client:
playerInfo key | Source / use |
|---|---|
playerId | RGS userId; player identifier for the client. |
currencyCode | RGS currency. |
balance | Current RGS balance. |
language | Player language/locale. |
maxPayout | RGS maxWin. |
maxBet, minBet, defaultBet | Allowed and default wager values. |
bbMaxWin, bbMaxBet, bbBetMultiplierSettings | Buy-bonus limits and multipliers. The optional maximum bet is only present when supplied by RGS. |
possibleBets | Allowed bet amounts. |
buyFeature | Whether the player/operator supports buying a feature. |
allowCheat | Whether development cheats are allowed; core converts this to plugin devMode. |
homeURL, depositUrl | Navigation/payment URLs from RGS; depositUrl is optional. |
Other RGS init fields such as platformId, operatorId, brandId, and externalPlayerId are not copied into this playerInfo mapping. RGS progressData is instead carried as game data where applicable.
The raw RGS init response also contains playerName, which this core mapping does not currently expose. Its other fields are used as follows:
| Raw RGS init key | Core use |
|---|---|
gameMode | Passed to plugin init to select the game's math mode. |
preferences | Passed through as the init response's player preferences. |
operatorConfig | Passed through as init response opCnf. |
rtp | Passed through as the separate init response rtp object. |
promoInfo | Passed through as the init response promotion state. |
epoch | Returned to the client for concurrency control on later requests. |
progressData | Merged into init gameInfo.gameData when present; after debit, supplied to game plugin extraData. |
balance, currency, userId, maxWin | Mapped to playerInfo.balance, currencyCode, playerId, and maxPayout respectively. |
maxBet, minBet, defaultBet, possibleBets | Mapped to the corresponding client bet limits. |
buyFeature, bbMaxWin, bbMaxBet, bbBetMultiplierSettings | Mapped to buy-feature availability and buy-bonus limits/settings. |
language, homeURL, depositUrl, allowCheat | Mapped to player display/navigation data and cheat permission; depositUrl and allowCheat are optional. |
externalPlayerId, playerName, platformId, operatorId, brandId | Present in the raw RGS type but not copied by getPlayerInfo into the current init response. |
When present, promoInfo has its own keys: promoId identifies the award, status indicates its lifecycle state, playCount and remainingPlayCount describe awarded/remaining spins, betAmount is the promo wager, totalWin is the running promo win, and skipCount records skipped spins.
Spin data
| Root key | Use |
|---|---|
gameId | Game that produced the result. |
roundId | Core-generated identifier tying debit, result persistence, and credit together. |
closed | true when the round is settled; false while a triggered feature round remains open. |
result | Game-specific gameData returned by the plugin. |
playerInfo | Player ID plus balance and end time when the core receives them from RGS. |
promoInfo | Optional promotion state returned by RGS after update or credit. |
Feature data
| Root key | Use |
|---|---|
gameId | Game that produced the feature result. |
closed | Whether the feature sequence is complete and has been credited. |
betType | RGS bet type for the saved round, such as base or buy-bonus. |
playerInfo | Player ID plus balance and end time when supplied after settlement. |
result | Updated game-specific feature result. |
promoInfo | Optional promotion state returned by RGS. |
Inside result: feature state and featureData
The HTTP response's result contains the game's SpinResult. If a game has a feature, the feature state is usually in result.featureResults, an array because a round can contain more than one feature (for example, a queued feature or a feature chain). A typical shape is:
{
"nextFeature": "freespins",
"featureResults": [
{
"featureType": "freespins",
"featureSubType": "Green",
"currentCount": 0,
"totalCount": 8,
"currentWin": 0,
"totalWin": 0,
"retrigger": false,
"retriggerCount": 0,
"closed": false,
"featureTriggerPositions": [[1, 2]],
"featureData": { "gameSpecificState": "..." },
"spinResults": []
}
]
}
This is an illustrative shape only. Keys are optional, and the exact fields and meanings depend on the game and featureType/featureSubType. The SDK deliberately treats gameData and feature data as generic; read the selected game's interfaces.ts and the code that creates/updates featureResults to know its real schema.
| Feature field | Usual meaning | Important qualification |
|---|---|---|
nextFeature | The next operation the client/core should execute, or null when no feature is pending. Some games also have nextFeatureSubType. | It is a root SpinResult field, not the same as one feature entry's closed. It is often the better round-continuation signal when features can be queued. |
featureResults | Current/persisted feature entries for this spin cycle. | It is an array; do not assume [0] is always the only active entry. Games such as House of Cards can queue multiple entries. |
featureType | Broad operation category, commonly freespins, pickFeature, or respins. | Names are game-defined values carried through a common structural role. |
featureSubType | Specific branch or variant, such as Red, Green, FG2, or a named House feature. | May be absent. It distinguishes mechanics that share a featureType. |
featureTriggerPositions | Cells that caused/identify the feature trigger. | Coordinate format can vary by game; inspect its type before treating positions as [column,row] or flat indices. |
currentCount / totalCount | Progress count and planned/awarded count, often current free spins versus total spins. | The unit is game-specific: it may count picks, spins, or other feature steps. |
currentWin / totalWin | Current step's win and a running/cumulative feature total. | Some games seed totalWin with the triggering base-spin win; others keep separate feature-only totals. Check the game code before deriving bonus-only amounts. |
retrigger / retriggerCount | Whether the current step awarded more feature steps, and how many. | Some games use pendingFeature at the root instead; counters can be maintained in more than one place. |
closed | Whether this feature entry is complete. | A closed entry can coexist with an open/queued next entry; it does not always mean the entire round is over. |
isAborted / maxCapReached | Indicates early termination, commonly because a win cap ended the feature. | Optional and not present in every game's type. |
queued | A feature is prepared but waits for another feature to finish first. | Specific to games with staged/queued features; currently used by House of Cards. |
spinResults | Per-step history or the latest feature-spin entry, often with board, wins, and modifiers. | Persistence code may trim this array; some plugins deliberately retain only the latest entry. |
featureData | Additional state needed by that game's feature: selected symbol, board, picks, sticky cells, or feature configuration. | It is not a universal object and is not always present. It may be essential to calculate the next feature call. Do not delete or reshape it without tracing the full feature lifecycle. |
Other nearby SpinResult fields have separate jobs:
| Spin-result field | Meaning |
|---|---|
nextFeatureSubType | Optional branch detail paired with nextFeature; used by games that route multiple subtypes through one feature endpoint. |
pendingFeature | Remaining feature steps, such as free spins or respins. Some games use the feature entry's counts instead; do not assume both are synchronized. |
reelModifiers | Describes board changes for client presentation/replay, such as added wilds, symbol conversion, expansion, nudge, or sticky-wild carry. The concrete fields depend on the modifier's type. |
progressData | Game-defined state persisted by RGS across requests/sessions, such as Mine Dash's stone meters or Joker Charge's sticky base-game cells. It is not the same as a feature's in-round featureData. |
baseWin / totalWin | Usually preserves the trigger/base result separately from the accumulated round total, but exact accounting varies by game. |
maxCapReached / maxWin | Cap status and effective cap information when supplied by the game. |
Common modifier type values include symbolExpansion and lightningStrike (Book of Storms variants), symbolChangeApplied (New Conquest), nudgeFeature and symbolConversionApplied (Frosted Market Bonanza), stoneFired (Mine Dash), bonusWildsAdd and stickyWildCarry (PigStyle), and addWildFeatureTriggered (Royale81). Read that game's modifier interface before consuming its fields. Modifiers explain what changed and often include an initialReelView; the current/settled board and feature state remain in their own fields.
There are several different completion flags. The plugin's featureComplete tells GameService whether to credit and close the feature round. The HTTP response's closed reports whether the RGS round is settled. A nested featureResults[n].closed reports whether that one feature entry is complete. They are related, but they are not interchangeable.
featureData by game
This inventory describes the feature payloads declared/constructed by the game packages in this workspace. It is a reference to help you recognize other games' state; it does not mean Carpathian Treasures has these fields. Optional keys are only present for the relevant branch/stage.
| Game | Feature-state payload and use |
|---|---|
| Book of Storms | Does not use a featureData object in its current FeatureResult. The feature entry carries bookSymbol, trigger positions, spinResults, counters, wins, and lifecycle flags directly. bookSymbol selects the free-game reel set. |
| Book of Storms Lightning Win | Same broad structure as Book of Storms, plus featureVariant to distinguish the Normal/Lightning trigger branch. The saved book symbol and variant determine the feature path. |
| Carpathian Treasures | No feature entries are currently emitted: featureResults is empty and nextFeature is null. |
| Empire of Gold | Does not define featureData in the current feature type. Feature counters, retrigger flags, multiplier state, and spinResults are stored on the entry; ante and other continuing state live on the root result. |
| Empire of Gold: New Conquest | Same feature-state pattern as Empire of Gold. The symbol-change presentation detail is a root reelModifiers entry, not featureData. |
| Frosted Market Bonanza | Does not define a featureData object in its current feature type. The entry uses counters and spinResults; pendingFeature, ante, multiplier/cascade state, and modifiers are stored on the root result/cascade entries. |
| House of Cards: pick feature | featureData.prizeType says whether the result is an xBet award or another feature; prizeValue identifies the outcome; ownWin is the wheel's contribution. Optional board and initialReelView seed/animate a follow-on board feature. |
| House of Cards: House/free spins | featureData.board stores cell tiers; initialSpinCount records the starting count; houseOnlyWin tracks the House-stage contribution separately from the wheel award. queued on the feature entry can hold a second feature for later. |
| Joker Charge | featureData.holdField stores landed/locked cells and their values; modifierMultipliers stores per-cell bumps; modifierRow stores the last row of modifiers; mysteryPositions and mysteryReveals record close-time reveals; triggerAnimation and metamorphicSymbolPosition support presentation. The outer pendingFeature is the remaining respin count. |
| Meow Meow Meow: Red | featureData.pickResults stores each pick (selection, jackpotTier, multiplier, win, isWinningPick); jackpotWin stores the Red feature payout. |
| Meow Meow Meow: Blue | featureData.prizeType, prizeValue, and ownWin store the wheel outcome and its contribution. When Blue awards Green, optional initialSpinCount and interfaceSize carry Green setup already rolled by Blue. |
| Meow Meow Meow: Green | featureData.initialSpinCount and interfaceSize define the feature setup; greenOnlyWin and greenCoinsCollected track Green-specific progress. Per-spin board/win data is in spinResults. |
| Mine Dash | Its feature entry stores totalCount, currentCount, currentWin, totalWin, closed, and trigger positions directly; the stone-meter state is root progressData.stoneState, not featureData. |
| PigStyle | featureData.baseWin preserves the triggering base-spin win. reelView, wildMultipliers, and positionsModifiedWithWc are working state for the next free-spin calculation; the reel view is padded/row-major internally. Displayed per-spin entries are reshaped separately. |
| Royale81 | No feature is currently implemented; the feature result type is minimal and has no featureData. |
| Sweet Salon | No featureData object in the current feature entry. Counters/history are on the feature result, while ante, pending count, cascade data, and multipliers are elsewhere in the spin result. |
The table is a guide to the current TypeScript contracts, not a frozen cross-game API. A feature response can include additional game-specific fields. When assigned to a different game, start at its SpinResult/FeatureResult types, then follow the plugin's feature() call into the engine/logic code that reads and writes the state.
The feature's per-spin entry shape is also game-specific. Common examples include a board (reelView), that step's winLines, spinWin/totalWin, cascade history (cascadeData), modifier data, and the current step number. Book of Storms records free-spin board/wild/expansion wins; cluster games record cascade boards, winning clusters, scatters, and multipliers; House of Cards records dropped board cells and ways wins; PigStyle records the variable-height view and wild multipliers. These entries are history/state for a particular game's feature, not a uniform SDK object.
For the exact compile-time contract, see each package's interface: Book of Storms, Book of Storms Lightning Win, Empire of Gold, New Conquest, Frosted Market Bonanza, House of Cards, Joker Charge, Meow Meow Meow, Mine Dash, PigStyle, Royale81, and Sweet Salon. Carpathian's own result types are in its interfaces.
Global and persisted data in practice
preferences, opCnf, rtp, promoInfo, epoch, and playerInfo are core/RGS-level response fields, not fields inside Carpathian's SpinResult. The game plugin does not currently read these init response fields directly. The core uses RGS session values to select the game mode, enforce the player session and wager flow, decide development mode, preserve round state, and construct the client response. Individual keys inside opCnf and preferences are operator/client-defined; consult their owning contract before assigning a game-specific meaning.
11. How the Repository Runs a Game
The code path crosses several layers. Knowing who owns each step helps you find the right file and avoids putting RGS or HTTP behavior into pure game logic.
apps/pack-alpha/src/app.module.tsconstructs the pack's game plugin instances and passes them toGameCoreModule.register.GamePluginLoaderService.onModuleInitcalls each plugin'sonLoad, injects a logger when supported, and indexes it bygameId.GameControllervalidates the endpoint route and delegates toGameService.GameServiceresolves the plugin, performs session/debit/credit/persistence calls with RGS, and maps the SDK contract to the HTTP response.- The game plugin adapts inputs, the game engine orchestrates the round, and game logic computes game-specific outcomes.
- Shared SDK functions provide common operations such as reel generation, weighted draws, scoring helpers, and win caps.
| Directory | Why it exists / when game code reaches it |
|---|---|
apps/pack-alpha/ | A runnable pack: registers the game plugins. A game package is not available to the pack until it is included in its plugin list and pack game manifest. |
games/<game>/src/ | Game-owned rules, plugin adapter, engine, types, and helpers. Keep rules that apply to only one game here. |
games/<game>/src/maths/ | The mode-specific math JSON loaded by that game's plugin. |
libs/sdk/ | Shared plugin/request/response types, errors, RNG wrapper, and game-agnostic helpers. Games import this directly. |
libs/game-core/ | Shared HTTP controller, DTO validation, plugin loading, and orchestration around plugin calls. |
libs/rgs-client/ | RGS session, debit, last-spin, result-update, and credit requests. |
libs/http-client/ | HTTP transport used by the RGS client, including connection pooling and retry behavior. |
libs/shared-nestjs/ | Shared NestJS configuration, monitoring/logging, decryption integration, and the API response wrapper. |
infra/ | Deployment/runtime infrastructure. It is not called by game spin functions; it configures where/how the service runs. |
The game packages import the SDK and Node fs/path; they do not import NestJS. The pack/core layers own HTTP, RGS, and process lifecycle concerns.
Core functions to know
| Function | Responsibility |
|---|---|
GameCoreModule.register(plugins) | Wires configuration, monitoring, RGS, the loader, service, and controller into a pack module. |
GamePluginLoaderService.onModuleInit() | Loads every registered plugin and its math before requests can use it. |
GamePluginLoaderService.getPlugin(gameId) | Finds the registered game adapter; throws when the game ID is unknown. |
GamePluginLoaderService.getAvailableGameIds() | Supplies the game list for health checks. |
GamePluginLoaderService.onModuleDestroy() | Calls optional plugin cleanup and clears the registry. |
GameController.healthCheck/init/spin/feature | Exposes the HTTP endpoints and wraps successful service data with ApiResponseDto.success. |
GameService.init(input) | Calls RGS init, derives dev permission, initializes the plugin, loads unfinished-round state when supported, and builds init data. |
GameService.spin(input) | Generates a round ID, debits via RGS, builds trusted plugin inputs, runs the game, then persists an open feature or credits a completed round. |
GameService.feature(input) | Loads persisted round state, calls the plugin feature method, then updates or credits the RGS round based on completion. |
GameService.healthCheck() | Returns service status and registered game IDs. |
generateUUid() | Creates the round ID that ties an RGS debit, saved result, and credit together. |
isCheatAllowed(allowCheat) | Converts RGS cheat permission into the core's devMode flag. |
isRecord(gameData) | Checks plugin output is object-shaped before the core persists or returns it. |
RgsService.init/loadLastSpin/debit/updateResult/credit | Performs the named RGS operations. Debit and credit are monetary calls and disable retries; update is an idempotent persistence call and can retry. |
RgsService.validateToken/postRgs/handleRgsError | Validates session tokens, performs/logs HTTP requests, and maps transport failures to platform errors. |
getPlayerInfo(playerData) | Maps selected raw RGS player fields into the client-facing playerInfo shape; the response-key tables above show the mapping. |
ApiResponseDto.success(data, message, statusCode) / error(...) | Builds the common HTTP success or error envelope. |
RGS environment configuration
RgsConfigService reads settings registered under the rgs namespace. RGS_URL is required; the remaining values have defaults in libs/rgs-client/src/config/configuration.ts.
| Environment key | Use | Default |
|---|---|---|
RGS_URL | RGS base URL. | Required |
RGS_POOL_CONNECTIONS | HTTP connection pool size. | 100 |
RGS_POOL_KEEP_ALIVE_TIMEOUT | Keep-alive duration in milliseconds. | 60000 |
RGS_POOL_PIPELINING | HTTP pipelining factor. | 1 |
RGS_POOL_CLIENT_TTL | Pooled client lifetime in milliseconds. | 30000 |
RGS_REQUEST_TIMEOUT | RGS request timeout in milliseconds. | 10000 |
RGS_RETRY_MAX_ATTEMPTS | Retry attempts for retryable RGS operations. | 3 |
RGS_RETRY_BASE_DELAY_MS | Starting backoff delay in milliseconds. | 200 |
These are service deployment settings, not game math values and not opCnf. Do not add game-specific rules to them.
RgsConfigService exposes these as getters (url, poolConnections, poolKeepAliveTimeout, poolPipelining, poolClientTtl, requestTimeout, retryMaxAttempts, and retryBaseDelayMs) so RgsService does not read environment variables throughout request code.
12. Shared SDK Functions Used by Games
These are reusable operations imported by game packages. They do not decide an individual game's complete rules; the game supplies the math and options.
| SDK function/module | Use case |
|---|---|
rng | Shared RNG service instance used by SDK helpers and games for random draws. |
generateReelView | Given strips, rows, and columns, draws one stop per reel and builds the visible board. |
getRandomValue | Draws from the SDK's parallel [values, weights] table shape. |
selectWeightedRandom | Draws a value from [value, weight] pairs. |
deepCopy | Makes a JSON-compatible copy when a feature must update a saved result without sharing nested references. |
selectReelSet | Chooses a reel-set name from configured weights and returns its strips. |
add, subtract, multiply, divide | Performs payout arithmetic through BigNumber to reduce floating-point errors. |
calculateWinLines | Evaluates configured line paths, symbol substitution, payout rules, and win positions. |
getPayoutForSymbol | Reads a symbol's payout entry for a requested match count; used by custom line evaluators. |
calculateWaysWins | Enumerates winning symbol paths across consecutive reels for ways games. |
applyWinCap | Applies the game-configured and optional RGS maximum win limits. |
groupSymbolPositions | Counts symbols and returns their positions; cluster games often use it as a first pass. It does not itself detect adjacency. |
detectAdjacentClusters | Flood-fills neighboring matching cells for games that need connected clusters. |
removeWinningSymbols | Copies a board and removes winning positions before a tumble/cascade refill. |
cascadeRefillReelView | Refills removed cells using the game's cascade/bracket weight configuration. |
replaceStackSymbols | Replaces stack placeholders with weighted symbols from the selected math section. |
selectRandomPositions | Selects unique positions from a supplied eligible-position list. |
findZeroBasedPosition, findRowColumn, findAllIndexes | Convert board coordinates/flat indexes or find repeated values in arrays. |
isScatter, transposeAndFill | Recognizes scatter symbols and reshapes/pads a generated matrix. |
Use the shared helper when its semantics match the game rule. Some games intentionally implement custom logic (for example PigStyle's variable-height reel/payline model or Royale81's wild-multiplied ways); do not replace custom behavior with an SDK helper just because the names look similar.
13. Function Map Across All Game Packages
The following map was checked against every TypeScript source file under the 13 registered games/*/src/ packages. It lists each game-specific runtime function and its purpose. Functions with the same name in different games are separate implementations unless explicitly described as sharing a role. interfaces.ts and index.ts primarily declare types and exports rather than round-processing functions.
Shared plugin methods
Each package implements the shared plugin lifecycle described in Plugin: Host-Facing Adapter: onLoad, init, spin, feature, and getMath. The common purpose is the same, but the details vary: onLoad may pre-parse math; init may return extra gameData; spin/feature normalize game-specific values and compute feature reporting; and getMath returns the selected cache entry. Optional or game-specific plugin methods are listed under their game below. Joker Charge has no simulator hook because its engine does not use reel stops.
Book of Storms
Sources: engine, logic, plugin.
executeSpin: chooses BG or buy-bonus trigger math, makes the board, adds buy-bonus wilds when needed, calculates the trigger result, and chooses/persists the free-spin book symbol.executeFeature: uses the stored book symbol and trigger state to choose the correct free-game reel set, generates the feature board, and callsrunFeature.getLastSpinSimData: exposes the last reel stops to the simulator.parseWinLineDefs: converts math-file comma-separated line positions to number arrays.countWilds: counts WD symbols and records their coordinates.mapWinLines: converts SDK wins to the game's result shape and applies its minimum match-count rule for high/low symbols.countSymbol: counts one symbol and identifies which columns contain it.buildExpandedReelView: fills each selected column with the expanding symbol for feature presentation/evaluation.buildLineWin: constructs a line result with amount, symbol, count, and both flat/matrix coordinates.evaluateLineWin: compares a wild-only H1 payout with a wild-substituted symbol payout and returns the better valid win.spin: scores paylines, wild scatter pay, book-symbol expansion in free spins, feature triggers/retriggers, totals, and win caps.runFeature: executes one free spin and updates the persisted feature count, retriggers, cumulative wins, and cap/closed state.selectBookSymbol: weighted selection of the book symbol that defines the free-game reel set.addWildsForBuyBonus: copies the board and adds the requested wild count to distinct columns.
Book of Storms Lightning Win
Sources: engine, logic, feature-trigger-check, cheat-logic, plugin.
executeSpin: chooses the base/buy-bonus trigger strips; applies buy-bonus wilds or the normal/lightning trigger-check branch; passes the board to scoring and attaches animation modifiers/book symbol.executeFeature: resumes free spins using the persisted trigger variant/book symbol and its corresponding reel strips.getLastSpinSimData: reports the last stops.parseWinLineDefs,countWilds,mapWinLines,countSymbol,buildExpandedReelView,buildLineWin,evaluateLineWin,spin,runFeature,selectBookSymbol,addWildsForBuyBonus: serve the same responsibilities as the same-named Book of Storms logic functions, with this game's Lightning feature variant and modifiers included in scoring/state.injectWilds: places a requested number of wilds in different unused columns and reports positions.performFeatureTriggerCheck: decides no-trigger, normal-trigger, or lightning-trigger behavior from feature math; injects natural/lightning wilds and captures the pre-strike board for the visual modifier.BookOfStormsLightningWinCheatLogic.selectBookSymbol: uses a development-forced book symbol when set; otherwise delegates to weighted production selection.buildDevModeOverrides: creates the feature/wild/book forcing object only whendevModeis true.
Empire of Gold
Sources: engine, logic, plugin.
executeSpin: chooses BG, ANTE, or buy-bonus trigger math; validates optional forced stops; applies buy-bonus scatter placement or ante stack replacement; then calls cascade scoring.executeFeature: selects FG or buy-bonus free-game math and delegates one free-spin state update torunFeature.getLastSpinSimData: returns base-spin reel stops.spin: finds paying symbol clusters, awards bonus-symbol multipliers, repeatedly removes/refills winning clusters, counts scatter triggers, updates totals/multipliers, and applies win caps.runFeature: generates and scores one free spin, handles retriggers and accumulated free-spin multipliers, updates the persisted feature state, and closes/caps the feature.
Empire of Gold: New Conquest
Sources: engine, logic, symbol-change, plugin.
setLogger(engine/plugin): passes the shared monitoring service into the engine and its feature helper.executeSpin: chooses BG/ANTE/buy-bonus math, generates and modifies the board, applies the passive symbol-change hook for BG/ANTE, then invokes cascade scoring.executeFeature: chooses FG/BB math and resumes the accumulated free-spin round.getLastSpinSimData: returns base-spin stops.spin/runFeature: use the Empire of Gold cascade, bonus multiplier, trigger, retrigger, and cap flow, with optional forced bonus multiplier and logger messages.applySymbolChange: selects low/high symbols, checks the combined-count gate and trigger weight, replaces matching low cells with the high symbol, and returns both the changed board and result metadata.
Frosted Market Bonanza
Sources: engine, logic, symbol-conversion, plugin.
executeSpin: selects BG/ANTE/buy-bonus strips, runs the scoring pipeline, and may re-run scoring on a converted board after a non-winning BG/ANTE spin without a nudge.executeFeature: delegates persisted free-spin state torunFeature.getLastSpinSimData: returns reel stops.spin: applies buy-bonus scatter placement and stack-symbol resolution; evaluates cluster cascades; assigns free-spin bomb multipliers; handles scatters, nudge, totals, caps, and result cleanup.runFeature: selects the free-spin math/reel set, callsspinFreeGame, updates retriggers and accumulated wins, and applies cumulative caps.spinFreeGame: generates a feature board from already selected strips and scores it as a free spin.applySymbolConversion: selects low/high symbols, applies its count/trigger gates, replaces low symbols, and returns the changed positions/initial board for the modifier.
House of Cards
Sources: engine, logic, house-board, plugin.
executeSpin: draws the feature branch, chooses/records its reel set, generates a board, and delegates scoring.getLastSpinSimData: returns reel stops and selected reel set.executeFeature: delegates the persisted pick/House state machine.findPositions: lists coordinates for a requested symbol.injectSymbols: randomly fills eligible cells without overwriting excluded positions.forceSymbolCount: normalizes a dev-forced symbol count by removing or injecting symbols.mapToWinLines: converts SDK ways results into this game's win-line representation.requireTriggerPositions: rejects corrupt feature state without trigger positions instead of silently building an empty board.evaluateWays: invokes the SDK ways calculator with this game's layout, wild, and paytable.capWin: applies configured and RGS win caps.nextFeatureFields: builds the result's feature type/subtype fields consistently.spin: injects Buzz Saws/Hard Hats, scores ways, selects triggered features, and queues simultaneous features when needed.runFeature: dispatches to House free spins or resolves the Buzz Saw pick wheel based on persisted feature state.executeBSFeature: resolves the wheel outcome as a jackpot or seeds a Buzz Saw, Mega Hat, or Mansion feature board.executeHouseFeature: upgrades the persisted board, plays/scorers a House spin, checks retrigger/cap/closure, and activates queued features.resolveHouseReelSelection: prepares weighted reel sets, with separate selection for Mansion.buildBSFeatureResult/buildHouseFeatureResult: create the initial persisted result structures for the pick wheel or House free spins.emptyBoard: allocates the flattened house-board state.indicesWithState: finds board cells at a requested level.indexToPosition: converts a flattened index to[column, row].toValueWeight: converts[value, weight]entries into the SDK's parallel-array weight format.requireCountTable: validates the count-specific board-weight table.drawDropCount: draws a count and caps placed cells to available positions.fillCells: draws and writes a tier's selected board cells while preserving both requested and placed counts.cascadeUpgrade: promotes an existing board cell when repeat drops occur, or awards the full-board multiplier.upgradeTier(local helper inapplyBoardUpgrade): applies a forced count of tier promotions in the game's priority order while tracking unplaced drops.applyBoardUpgrade: applies weighted or dev-forced Hard Hat tier upgrades and reports placed/landed counts and board awards.seedBuzzSaw: moves Buzz Saw positions across board cells, upgrading each touched tier.seedMansion: seeds Buzz Saw positions directly as max-tier board cells.seedMegaHat: selects/forces hat placement, updates eligible board cells, and overlays hats onto the generated reel view.resolveFrameValue: converts a numeric or jackpot-tier frame entry into a bet-scaled award.revealHouse: draws and sums values for every occupied cell when the House board reveals.buildDevModeOverrides: packages development-only trigger/outcome/board controls for the engine.
Joker Charge
Sources: engine, logic, cheat-logic, config, plugin.
Joker Charge is table-driven and has no reel strips or reel-stop simulator path; its board is built from decision weights.
setLogger: attaches monitoring to the engine.executeSpin: validates active paylines, carries sticky state only when bet/paylines are unchanged, decides base vs. bonus entry, and returns either a base board or a new respin feature state.renderHoldField: turns stored hold cells into the display grid.executeFeature: adds a hold-spin result, runs modifier-row effects, reveals mysteries at close, totals cell/jackpot values, and applies the cap.ACTIVE_LINE_ROWS: maps the active-payline choice to the rows considered active.symbolNames: gets the allowed symbol names from weight tables for validating cheats.forcedGrid: validates a development-forced grid against the layout and allowed symbols.resolveBaseTrigger: selects base game vs. bonus game from the active-payline weight table.fillBaseGameBoard: preserves sticky symbols and fills active/inactive rows from their distinct weights.collectStickyCells: extracts persistent sticky symbols to store in progress data.resolveMetamorphicTrigger: rolls the metamorphic display decision and optional added count; it does not change base-game payout.resolveBonusEntry: creates active/inactive/sticky hold cells and applies the initial modifier row.buildMetamorphicSymbolPosition: determines which newly added active cells the metamorphic animation highlights.runHoldSpin: fills unlocked cells, resets or decrements respins, and closes on full board or exhausted respins.resolveModifierRow: applies per-column or whole-field multiplier/tier modifiers.revealMysteries: resolves Mystery/Mystery Jackpot cells only when the bonus closes.resolveValue: looks up a symbol's bet-scaled value.resolveBoostValue: snapshots the value of symbols a Boost collects.buildHoldFieldCell: normalizes sticky/mystery symbols and calculates the cell's stored value.- Cheat overrides
resolveBaseTrigger,resolveMetamorphicTrigger,fillBaseGameBoard,resolveBonusEntry,runHoldSpin,resolveModifierRow, andrevealMysteries: use validated development overrides, otherwise call the production implementation. inScope: local cheat/logic predicate that selects one column or the whole hold field for modifier application.buildDevModeOverrides: parses only development-authorized forced values fromextraData.JokerChargeConfig: supplies the fixed layout, respin count, and maximum/base-bet constants used by the game.
Meow Meow Meow
Sources: engine, logic, feature-helpers, cheat-logic, plugin.
executeSpin: selects BG/ANTE math and weighted reel set, optionally forces ReelSet_1 in dev mode, then delegates board modifiers/scoring.getLastSpinSimData: returns stop indices and selected reel set.executeFeature: dispatches the persisted RED, BLUE, or GREEN feature to logic.spin: adds weighted wilds and symbol overlays, calculates ways and scatter payouts, caps the win, and initializes the triggered feature state.runFeature: resumes GREEN when it is open; otherwise dispatches RED pick, BLUE wheel, or GREEN free spin.executeRedFeature: resolves one coin pick per call, checks category-of-three wins, accumulates/caps the award, and closes the pick feature when resolved.executeBlueFeature: resolves a wheel prize, closes BLUE, and signals a subsequent RED/GREEN feature when awarded.buildInitialFeatureResult: creates the persisted initial state for RED, BLUE, or GREEN.resolveSymbolOverlay: rolls feature trigger/type/color and places scatters/coins, or places ambient non-trigger symbols.nextFeatureFields: maps RED/BLUE/GREEN colors to the shared feature type/subtype fields.placeSymbols: chooses eligible cells and places symbols, respecting exclusions and optional unique-reel rules.addWilds: draws and places the round's weighted wild count.mapToWinLines: converts SDK ways wins into this game's display/result shape.executeGreenSpin: performs one green free spin: wilds/coins, ways scoring, and cap delta.executeGreenFeature: initializes/resumes GREEN, chooses its board dimensions/reel set, accounts for retriggers, wins, and closure.- Cheat
resolveSymbolOverlay: forces a trigger/type/color/count only in dev mode. - Cheat
executeRedFeature: forces a valid jackpot category while preserving normal pick-state/cap handling. - Cheat
executeBlueFeature: forces a wheel prize while preserving the normal result/state shape. categoryOf: removes a numeric tier suffix to group RED picks by jackpot category.parseCombination: accepts array or comma-separated reel stops only in dev mode.buildDevModeOverrides: gathers game-specific forced trigger, symbol, and feature values only in dev mode.
Mine Dash
Sources: engine, logic, stone-meter, cheat-logic, plugin.
setLogger: passes monitoring into the engine.executeSpin: selects a weighted BG reel set, uses ReelSet_2 for valid forced stops, then executes stone and line logic.getLastSpinSimData: returns reel stops and selected reel set.executeFeature: generates a free-game view and resumes the saved free-spin state; stone collection advances only on base spins.resolveStoneOutcome: advances the persisted stone meters and returns a fired stone/position when a meter triggers.spin: applies a fired stone's board effect, places ambient wilds, calculates line wins, awards mystery/free spins, saves stone state, and caps the result.runFeature: applies stack replacement/wilds and line scoring to one free spin, then updates the saved counter and total.placeWilds: places wilds on shuffled eligible cells, protecting feature cells when requested.parsePositions: converts a comma-delimited math position string to indices.stoneSymbolFor/megawinStoneSymbol: render the current stone or banked MEGAWIN symbol name.stampPositions: writes a selected symbol at flattened positions.calculateLineWin/mapWinLines: call the SDK line calculator and map wins to game results.executeMultiFeature: builds the guaranteed-win board for a MULTI stone.executeWildsFeature: builds the tier-specific WILDS board and records its before/after modifier.executeMegawinFeature: creates the selected OAK combination and collects it into the winning row.executeMysteryFeature: draws and returns the flat mystery award and modifier.freshMeter/initialStoneState: create an empty meter or a new player's complete stone state.advanceStones: makes the stone selection, trigger, value, and pip updates on a copied state; a hit on pip five fires and resets that stone.validForcedValues: finds values that the real stone math tables can draw, for safe dev forcing.forceStoneFire/forceStoneLand: dev-only helpers to force a stone to fire now or land without firing.maxTier: keeps the best banked tier (numeric max, or symbol rank by five-of-a-kind pay).STONE_SELECTION_TO_KEY,STONE_MATH_KEY,STONE_RESERVED_REEL,STONE_KEYS: map sheet names, game keys, and reserved reels consistently.- Cheat
resolveStoneOutcome: delegates normally or uses the validated force-fire/force-land helper. parseCombination/buildDevModeOverrides: validate dev stop inputs and package stone overrides.
PigStyle
Sources: engine, logic, pigstyle-helpers, cheat-logic, plugin.
PigStyle uses variable-height reels. Its custom helper owns generation and path expansion; its intermediate board is padded row-major for scoring and converted to jagged column-major output for the client.
executeSpin/executeFeature: choose production or cheat logic, invoke base/feature logic, and preserve simulator detail.getLastSpinSimData/getLastReelGenDetails: return stops, reel type, and selected row pattern.spin/runFeature: initialize a result and dispatch base-game scoring or feature continuation.runBaseGame: builds variable-height reels, derives symbols/wild multipliers, scores paths, caps wins, and records scatter triggers.selectReelSet: chooses the weighted base reel or the buy-bonus precomputed stop record; free games select their section's reel.selectRowPattern: chooses a row-height pattern, or uses the saved buy-bonus pattern.selectReelStopPosition: draws a stop or reuses the precomputed buy-bonus stop.selectRowLength: draws each reel height from the selected pattern or uses the buy-bonus record.addFGWilds: selects eligible middle-reel cells for feature wilds and returns display/flat positions.findWildMultipliers: draws a multiplier for each wild and records values greater than one.checkFeatureTrigger: creates the initial feature-selection state after 3+ scatters.continueFeature: processes the selection step or one FG1/FG2 free spin, updating state and caps.mathSection: maps platform feature names such asBuyBonusFG1to math JSON sectionsBB1/BB2.getAllSymbols: reads a requested count of consecutive strip symbols with wraparound.convertMatrixToObj: creates flat-index, symbol, column, wild, and scatter lookups for scoring.createMatrixFromColumns: pads column data into a row-major matrix.getBetAmounts: converts total bet using the configured base-bet divisor.findMiddlePositions: lists nonblank, nonwild cells eligible for feature wild placement.buildPigStyleReelView: runs the decision points in fixed order to select reel, pattern, stop, and height; returns the board and simulator metadata.toJaggedReelView: removes padding and returns variable-height columns for the client.convertNumber: parses flattened path positions.populatePaylinesLeftToRight: recursively forms all left-to-right cell paths from the eligible cells on each reel.calculatePigStyleWinLines: finds matching paths, deduplicates identical paths, applies wild multipliers, and sums wins.playFG2: generates an FG2 board, carries/repositions prior sticky wilds when heights change, then adds new wilds and multipliers.- Cheat overrides
selectReelSet,selectRowPattern,selectReelStopPosition,selectRowLength,addFGWilds, andfindWildMultipliers: replace only those decision points when valid dev cheats are supplied. buildSpinDevModeCheat/buildSharedCheat: parse spin-only or spin-and-feature dev controls;maxRowCountfinds the tallest valid forced board.
Royale81
Sources: engine, logic, plugin.
executeSpin: selects weighted BG strips, uses ReelSet_1 for dev overrides, and passes the selected set/forced wild options into logic.getLastSpinSimData: returns the selected set and stops.executeFeature: currently returns the prior result unchanged; there is no feature round in this implementation.spin: adds regular/feature wilds, calculates ways payouts, builds the feature modifier, and applies the maximum win cap.addWilds: draws normal wilds and optional triggered feature wilds, snapshots the display board between placements, and tracks added positions.getWildPositions: lists all wild cells on the final board.calculateWaysWins: enumerates left-to-right symbol/wild matches and applies the game's 2x multiplier for each wild in a path.cartesianProduct: expands per-reel match choices into all possible ways paths.buildDevModeOverrides(plugin): parses only explicit dev-mode wild controls.
Sweet Salon
Sources: engine, logic, plugin.
executeSpin: chooses BG/ANTE/buy-bonus strips, generates the board, and delegates base-game scoring.getLastSpinSimData: returns reel stops.executeFeature: passes saved round state and dev-only feature choices torunFeature.spin: applies buy-bonus scatter placement and stack replacement; scores cluster cascades, free-spin bomb multipliers/retriggers, scatter pay, totals, and caps.runFeature: chooses the free-game type/reel set, scores one free spin, adds its multiplier/win to saved state, and closes when pending spins or caps are exhausted.spinFreeGame: generates one free-spin board from the selected strips and invokesspinin free-game mode.buildDevModeOverridesis not separate in this plugin; it parses the optional forced multiplier and reel combination inline inspin/feature.
14. Shared Runtime Settings vs. Game Math
Use these boundaries when deciding where a new value belongs:
- Math JSON: game-mode data such as layout, symbols, reel strips, weights, paytable, lines, and feature rules.
- Plugin input/output: the SDK contract values passed by the core, plus this game's
gameDataresult. - RGS/player response: session, bet limits, balance, promo state,
rtp,opCnf, andepochvalues. - Environment configuration: service-level connection/retry settings such as
RGS_URLand the RGS pool/timeouts. - SDK helpers: algorithms shared across games; use only when their behavior matches the game's rule.
- Pack/core/RGS layers: plugin registration, HTTP, persistence, debit/credit, logging, and response envelopes.
This distinction matters because identically named data can have different owners. For example, RGS rtp response data is not the same thing as the plugin's gameMode, and neither one substitutes for the game's paytable or reel weights.
15. Related Sources
- Gameplay guide
- Plugin
- Engine
- Logic
- Interfaces
- Package exports
- SDK plugin contract
- SDK spin input/output types
- Game request DTOs
- Game service orchestration
- Game controller and HTTP envelope
- Response contracts
- RGS player and session contract
- Player-info mapping
- HTTP response wrapper
- Plugin registry and lifecycle
- Core module registration
- Pack game registration
- RGS service configuration
- SDK arithmetic helpers
- SDK weighted-draw helpers
- SDK reel-set selector
- SDK ways calculator
- SDK cascade refill
- SDK cluster helpers
- SDK stack-symbol replacement
- SDK win-cap helper
- SDK exports
- SDK reel generator
- SDK win-line calculator