Skip to content

RGS Math Servers

The RGS (Remote Game Server) and its associated Math Server are the backend engines that determine game outcomes. Every bet, every win, every multiplier — they all come from the math server. Your game client never decides outcomes; it receives them and renders the result.

Architecture

RGS architecture diagram

How it works:

  1. The Proxy Server authenticates the player through GammaStack (Rollerz) and receives a token, user ID, and balance.
  2. The Game Client sends its internal client code (game ID) to the proxy and receives back a session ID and the math server endpoint.
  3. The game client communicates directly with the Math Server using the session ID — opening games, placing bets, and collecting winnings.
  4. The RGS sits between the proxy and math server, handling session management, wallet operations, and round finalization.

The SDK abstracts all of this behind simple methods like openGame(), placeBet(), and collect(). As a game developer, you call these methods and receive structured results — you never need to manage sessions, request counters, or raw HTTP calls yourself.

Launch URL parameters

When a host platform (e.g. Rollerz) launches your game inside an iframe, it appends two URL parameters that the SDK reads automatically — your code never touches URLSearchParams:

ParameterPurposeFallback when absent
?server=Math server URL for this launch — overrides the provider's server-side defaultThe provider's env-configured server URL (GO3_SERVER_URL, STEPPER_SERVER_URL, etc.)
?session=Session token issued by Reelsoft for this playerA UUID minted by the SDK and persisted in sessionStorage — survives refreshes of the same tab; reset on a new tab or closed/reopened browser

Both values ride in the open request body. The SDK Server passes body.sessionId to the math server's opengame call (and prefers body.serverUrl over the env default for outbound routing). It then stores both on the session record on first contact and reuses them for every subsequent placebet / nextaction / collect — your game code never sends them again.

For GP specifically, the launch URL wins over any explicit openGame({ serverUrl }) argument — host-driven launches always trump in-code defaults.

Host-driven ?server= is allowlist-gated

Because ?server= reaches the SDK server through a request body rather than a vetted env var, outbound POSTs are gated on MATH_SERVER_ALLOWED_HOSTS (comma-separated host[:port] list). Unset = passthrough (local dev only); production deployments must set it to the trusted math-server hosts. Requests to any other host throw disallowed math-server host: <host>. Redirects are refused (redirect: 'error') so a 302 can't laundry the check.

RGS API contract

All communication with the math server uses HTTPS POST with JSON request/response bodies. The SDK handles this for you, but understanding the contract is useful for building mocks or debugging.

The /gameevent endpoint

All game methods (opengame, placebet, collect, etc.) must be served on the /gameevent path — for example, https://your-math-server.com/gameevent.

The SDK server's postToProvider function automatically appends /gameevent to whatever server URL is configured in the environment variable (e.g. GO3_SERVER_URL). This means:

  • Using an existing Reelsoft math server? This just works — Reelsoft's contract requires /gameevent because other methods exist in parallel on the same server.
  • Building your own RGS or mock? You must serve all game methods at the /gameevent path, or the SDK server will not be able to reach them.

Core methods

MethodPurposeWhen to call
opengameStart a session. Returns config, bet levels, balance, feature flags.On game load
placebetPlace a bet and receive the math result. Returns the full "play script" for animations.When the player bets
nextactionAdvance a multi-step round. The client sends an actionCode (CONTINUE or CASH_OUT) and receives the updated round state.After placebet in step-based games (e.g. Stepper)
collectFinalize the round and settle winnings with the wallet.After all animations complete (single-outcome games like Go3)

Not all games use every method

Go3 / Rippin Rumble: placebetcollect. The round resolves in one step. Stepper: placebetnextaction (repeated) → round ends on crash or cash-out. No separate collect call — settlement happens inside nextaction.

Supporting methods

MethodPurpose
checkfreebetCheck if the player has free bets available (Stepper)
readhistoryFetch the player's recent rounds (paginated)
readreplayFetch math data for a previous round (within current session)
openreplayLoad and replay any completed round (standalone)

Key concepts

  • requestCounter — Incremented with every request (except opengame). Prevents duplicate processing from network issues. The opengame response returns lastRequestCounter to resume from.
  • nextAction — The server tells the client what to do next (e.g. ["COLLECT"], ["CONTINUE"], ["CONTINUE", "CASH_OUT"]). Always follow this — do not invent actions.
  • All amounts are raw (in cents) — The math server returns all monetary values in the smallest currency unit (e.g. 10000 = $100.00 USD). The SDK passes these through unchanged — it never converts or scales them. To display amounts to the player, use formatAmount() from the framework, which handles the cents-to-display conversion using the currency object from opengame.
  • chipLevels / betLevels and defaultBet — Always use server-provided values, never hardcode. Some math servers use betLevels instead of chipLevels (e.g. Stepper).
  • featureFlags — Jurisdiction-specific settings like AUTO_PLAY, BUY_FEATURE, POWER_BET. Respect these in your UI.
  • session — Included in every response. Contains play time, round count, and win/loss — required for display in some jurisdictions.

opengame

FieldTypeExampleDescription
methodstring"opengame"Method name
sessionIdstring"RRTEST286030..."From the &session= query parameter
internalClientCodestring"RIPPIN_RUMBLE"Hardcoded game identifier — must match the endpoint
languagestring"en"(optional) Two-char ISO code

placebet

FieldTypeExampleDescription
methodstring"placebet"Method name
sessionIdstring"RRTEST701258..."Same session ID from opengame
requestCounternumber1Incremented counter
betsarray[{ "betType": "BASE", "betAmount": 50 }]Array of bet objects (typically one)
bets[].betTypestring"BASE"Game-specific. Go3/Rippin Rumble: "BASE", "BOOSTED". Stepper: "BEGINNER", "EASY", "MEDIUM", "HARD", "INSANE"
bets[].betAmountnumber1000Bet amount in cents
testCasestring"RARE4"(mock only) Force a specific test outcome

nextaction

Used by multi-step games (e.g. Stepper/ChickenX) to advance a round one step. After placebet returns nextAction: ["CONTINUE"], the client calls nextaction repeatedly — each call either advances the ladder (SAFE) or ends the round (CRASH). The player can also cash out at any step after the first.

FieldTypeExampleDescription
methodstring"nextaction"Method name
sessionIdstring"7626712703577953783"Same session ID from opengame
requestCounternumber3Incremented counter
roundIdstring"7626712755930766164"The roundId returned by placebet
actionCodestring"CONTINUE""CONTINUE" (take next step) or "CASH_OUT" (collect current payout)
languagestring"en"(optional) Two-char ISO code

Round endings via nextaction:

  • CRASH — A CONTINUE action reveals a crash. roundEnded: true, totalWinAmount: 0, all remaining steps show "CRASH".
  • CASH_OUT — The player sends actionCode: "CASH_OUT". roundEnded: true, totalWinAmount equals the current payout. Remaining steps are revealed (showing what would have happened).

First step is mandatory

After placebet, the only available action is ["CONTINUE"] — the player must take the first step. CASH_OUT becomes available after at least one successful step returns nextAction: ["CONTINUE", "CASH_OUT"].

collect

FieldTypeExampleDescription
methodstring"collect"Method name
sessionIdstring"RRTEST709235..."Same session ID from opengame
requestCounternumber2Incremented counter
roundIdstring"MOCK485868094"The roundId returned by placebet

readhistory

FieldTypeExampleDescription
methodstring"readhistory"Method name
sessionIdstring"RRTEST286030..."Same session ID from opengame
requestCounternumber3Incremented counter
pageNumbernumber0Zero-based page index

readreplay

FieldTypeExampleDescription
methodstring"readreplay"Method name
sessionIdstring"RRTEST286030..."Same session ID from opengame
requestCounternumber4Incremented counter
roundIdstring"MOCK789790722"Round ID from readhistory

openreplay

FieldTypeExampleDescription
methodstring"openreplay"Method name
roundIdstring"MOCK789790722"From the &replay= query parameter
internalClientCodestring"RIPPIN_RUMBLE"Game identifier

Important

  • Go3 / Rippin Rumble: If the server indicates nextAction=["COLLECT"], you must call collect after animations end. If you don't, the round stays open and the player never receives the payout.
  • Stepper: There is no separate collect call. Rounds are settled automatically when they end via nextaction — either by crash or cash-out. The SDK's stepper.collect() method sends a CASH_OUT action internally.

Error codes

CodeNameHTTPAction
101BAD_REQUEST400Close game
201ACCESS_DENIED401Close game
202RESTRICTED_LOCATION401Show location error, close
207SESSION_NOT_FOUND404Close game
208SESSION_EXPIRED403Show "Session expired", close
301NOT_SUFFICIENT_FUNDS402Let player lower bet or quit
302PLAYER_BLOCKED403Close game
401OUT_OF_SYNCH403Soft reset (re-run opengame)
500INTERNAL_ERROR500Soft reset, then quit if persistent
501COMMUNICATION_FAILURE500Soft reset, then quit if persistent
503SERVICE_DISABLED503Soft reset, then quit if persistent

Building your own RGS mock

You can build a local mock math server for development and testing. Your mock needs to implement the core methods for your game type and return responses that follow the contract above.

For single-outcome games (Go3, Rippin Rumble):

  1. opengame — Return config with chipLevels, currency, defaultBet, and balance.
  2. placebet — Accept a bet, generate a math result, return it in math.details.
  3. collect — Accept a roundId, return an updated balance.

For step-based games (Stepper):

  1. opengame — Return config with betLevels, currency, defaultBet, balance, and extraData.payouts.
  2. placebet — Accept a difficulty-based betType, generate the step ladder, return it in math.details.steps.
  3. nextaction — Accept roundId + actionCode (CONTINUE or CASH_OUT), advance the step, return updated ladder with outcomes.

Your mock must serve all methods on a single POST /gameevent endpoint — the SDK server automatically appends /gameevent to the configured server URL. For example, if your mock runs on http://localhost:3000, the SDK server will send requests to http://localhost:3000/gameevent.

This is useful for:

  • Developing without network access
  • Testing specific edge cases (empty results, max wins, errors)
  • Running automated tests against deterministic outcomes

Coming soon: Generic provider

A generic provider is in development that will let you point the SDK at any local mock server without modifying the SDK itself. You'll be able to define your own math schema and connect it directly — no custom provider code needed.

Adding a new math server

Want a custom math model for your game? The process involves:

  1. Define the math — Specify the game mechanics, payout tables, RTP targets, and result structure.
  2. Implement in Java — The math engine is built as a Java service following the RGS contract.
  3. Deploy — The math server is deployed to the RGS infrastructure.
  4. Connect with RGS — Session management, wallet integration, and round lifecycle are wired up.
  5. Implement SDK provider — A new provider is added to the SDK so game clients can call openGame(), placeBet(), collect(), and any game-specific methods (e.g. step()) against the new math.

TIP

You don't need to do any of this yourself. The Rollerz team handles the entire pipeline. To start the process, reach out to us:

We'll work with you to define the math model and get it live.