Skip to content

Reporting lifecycle events

Once your game is running inside the operator's iframe, use @moose/game-client-sdk's GameBridge to report its lifecycle back to the operator's shell. This is unrelated to getting the session tokenGameBridge doesn't need the session token at all, it only reports the game's lifecycle to the shell:

ts
import { GameBridge } from '@moose/game-client-sdk'

const bridge = new GameBridge()

bridge.notifyGameLoaded(currentBalanceMinor)

// BET_START/BET_END are a two-phase reveal, not two network moments — a
// server-side spin/settle call typically resolves the whole round
// (including any win) in one response, so notify BET_START only once
// that result is known and you're about to start revealing it:
const result = await submitBet(betAmountMinor) // your own server-side integration (see ./server-integration)
if (result.declined) {
  bridge.notifyBetEnd('declined', betAmountMinor, result.balanceMinor)
  bridge.notifyBalanceExhausted()
} else {
  bridge.notifyBetStart(betAmountMinor, result.balanceMinor - betAmountMinor) // after this wager's debit, before any win
  await playReveal(result) // your own reveal animation, if any — purely cosmetic
  bridge.notifyBetEnd(result.outcome, betAmountMinor, result.balanceMinor, result.winAmountMinor)
}

// player clicked an in-game "back to lobby" control:
bridge.notifyExitGame()

GameBridge's constructor also accepts target (defaults to window.parent) if you need to override where messages are sent — mainly useful for tests; a game running normally inside an operator's iframe should rely on the default.

Bot-detection signals

@moose/game-client-sdk/behavior-reporter's BehaviorReporter collects raw interaction timing in the browser (via the underlying BehaviorCollector) and posts the resulting digest straight to the platform — there's no backend of yours in this path at all. A bot's cadence tends to be fast and unnaturally regular compared to a human player's, which is the signal being reported.

ts
import { BehaviorReporter } from '@moose/game-client-sdk/behavior-reporter'

// ingestUrl is the platform's dedicated behavior-ingestion endpoint —
// a separate base URL from the one you pass ProviderClient, given to
// you by your integration contact. See Environments & base URLs.
const behavior = new BehaviorReporter({ ingestUrl: behaviorIngestUrl, sessionToken })

// Delegate at the document level, scoped to whichever elements you mark
// data-bet-trigger, rather than wiring recordInteraction onto each
// bet-triggering control individually — but don't widen this to every
// click on the page: capturing unrelated clicks (paytable, log, "exit")
// would dilute the interval-timing signal this exists to measure. Pass
// the triggering Event through so a programmatically dispatched click
// (not the real player) can be flagged.
document.addEventListener('click', (event) => {
  if ((event.target as HTMLElement).closest('[data-bet-trigger]')) {
    behavior.recordInteraction(event)
  }
})

spinButton.addEventListener('click', () => placeBet())

Mark every control that actually triggers a bet with data-bet-trigger in your HTML (e.g. <button id="spin-button" data-bet-trigger>) — the delegated listener above picks up all of them, including ones you add later, without you having to remember to wire each one individually.

That's the entire integration — BehaviorReporter flushes on its own timer and on tab-hide/page-unload, posting directly to ingestUrl with the session token as an X-Session-Token header (not a signed call: a browser can't hold your HMAC secret, so this one endpoint authenticates by session token instead). Call behavior.stop() when tearing the game down, to cancel its timer and detach its listeners.

This is a best-effort telemetry signal, not part of the gameplay loop — a failed report is swallowed internally and never surfaces to the player or blocks a bet. See BehaviorReporter in the SDK reference for the exact types.

Full reference

See @moose/game-client-sdk reference for every exported type and method signature, including the protocol module the shell side implements its listener against.