Skip to content

Mini-Games ​

Run browser-based games inside your customer app that convert gameplay scores into loyalty points.

What It Is ​

A mini-game is a script the customer app loads and runs. Playing costs a life, finishing a run produces a score, and the score converts to loyalty points at a rate you set. Each brand configures its own games, rates and limits.

What You Can Do With It ​

Give customers a daily reason to open the app ​

Free lives refill every 24 hours, so there is always something to come back for without spending points.

Config: daily_base_lives: 2, lives_reset_ttl_seconds: 86400

Create a points sink ​

Let customers spend points on extra plays, pulling balance back out of circulation.

Config: points_per_life: 100, lives_per_purchase: 1, and a max_lives ceiling so they cannot stockpile.

Cap your exposure ​

Bound what any customer can earn, per run and per day, so a scoring bug or an exploit cannot drain your points budget.

Config: point_cap_per_session for one run, point_cap_per_reset_duration for the whole window.

Run a scoreboard competition ​

Rank customers by their best score for a game and reward the top of the board.

Config: nothing extra — highest_score is tracked automatically and the leaderboard endpoint returns rankings.

How It Works ​

Customer opens game
        │
        ├─► Has a life available?
        │   ├─ NO  → must buy one with points (or wait for the daily reset)
        │   └─ YES → one life is deducted, a session is created
        │
        ├─► Customer plays, session records a score
        │
        └─► Score converts to points
            ├─ raw    = floor(score × score_to_points_ratio)
            ├─ capped = min(raw, point_cap_per_session)
            └─ final  = min(capped, remaining allowance in the reset window)

The Lives Economy ​

Customers hold two separate pools of lives.

PoolFieldBehaviour
Free daily livesbase_livesRefills to daily_base_lives once lives_reset_ttl_seconds has elapsed (default 24 hours). Does not carry over — it is a reset, not an accrual.
Purchased liveslives_redeemedBought with loyalty points. Carries forward indefinitely.

A customer's available total is base_lives + lives_redeemed.

Free lives are spent first

Starting a session always consumes a free life before touching purchased ones, so customers never burn points while free lives remain.

Buying lives ​

Customers spend points to top up:

  • points_per_life — points charged per purchase
  • lives_per_purchase — lives granted per purchase
  • max_lives — hard ceiling; a purchase is rejected if it would push base_lives + lives_redeemed above this

The purchase is recorded in the customer's loyalty transaction history.

Score Conversion and Caps ​

Three settings control how generous a game is.

SettingFieldEffect
Conversion ratescore_to_points_ratioPoints per unit of score. The result is rounded down.
Per-session cappoint_cap_per_sessionMaximum points a single run can award, regardless of score.
Window cappoint_cap_per_reset_durationMaximum points awarded across the whole reset window. Points already awarded in the window are subtracted from what a new session can earn.

A session therefore awards min(floor(score × ratio), point_cap_per_session, remaining window allowance).

Set auto_award_points to control whether points are granted automatically when a session completes, or held for processing.

Session Lifecycle ​

Each play creates a session row that moves through these states:

StatusMeaning
pendingSession created, score not yet submitted
processingScore received, points being calculated
awardedPoints granted to the customer
failedConversion or award failed

Sessions retain the score and the points awarded, so a run can be audited after the fact.

Configuration Reference ​

FieldPurpose
nameDisplay name in the customer app
activeWhether the game is playable
src_scriptThe game script the app loads
score_to_points_ratioPoints per unit of score
points_per_lifePoint cost of one life purchase
lives_per_purchaseLives granted per purchase
daily_base_livesFree lives granted each reset
max_livesCeiling on total held lives
lives_reset_ttl_secondsSeconds between free-life resets (default 86400)
auto_award_pointsGrant points automatically on session completion
point_cap_per_sessionMaximum points from one run
point_cap_per_reset_durationMaximum points across one reset window

Leaderboards ​

Each customer's highest_score is tracked per game, and their leaderboard position is returned alongside their profile. Only the best score is retained — individual sessions do not appear on the leaderboard.

Customer-Facing Endpoints ​

Available under both web and mobile route prefixes:

MethodEndpointPurpose
GETmini-game/userThe customer's state for one game — lives, highest score, leaderboard position
GETmini-game/user/allThe same across every active game
GETmini-game/leaderboardRanked scores for a game
POSTmini-game/sessionStart a run; deducts a life and returns a session
POSTmini-game/scoreSubmit a score for a session
POSTmini-game/score-conversionPreview the points a score would yield
POSTmini-game/consume-pointsSpend points to buy lives

Best Practices ​

  • Set the caps before launching. point_cap_per_session is the only thing standing between a scoring bug and an unbounded point payout.
  • Model the daily economy. daily_base_lives multiplied by the per-session cap is the most points a customer can earn per day without spending — check that number against your margins.
  • Keep max_lives close to daily_base_lives. A high ceiling lets customers stockpile purchased lives and burst-earn against the window cap.
  • Use active to retire a game rather than deleting it, so historical sessions and leaderboard history stay intact.

Batch platform, Shopify app and API documentation