Epoch rewards

How plays become a weight, the weight a share of the vault, and the share claimable ETH: the 24-hour vault, the formula, settlement and claims.

Every trade of the $SANDBOX token pays a creator fee that accrues as ETH in the Sandbox contract’s vault. Every 24 hours, the vault’s balance is split between the most played maps of the last 24 hours, pro rata to their weight, and each game’s share is claimable by its creator. The loop: build, get played, get paid.

Current status

Coming soon The contract is not deployed and the token not launched yet. Plays are already counted and the standings of the current 24 hours are visible on the Builders page; payouts start with the contract.
The Builders page
The Builders page: live standings of the current 24 hours.

The vault

There is no emission and no budget decided in advance. The vault is simply the ETH the contract holds: the token’s creator fees, harvested from Pons, plus any ETH sent to it. Every 24 hours the operator settles the weights of the window that just closed, and the vault’s balance is split pro rata between the games in those standings. What is settled is set aside (reserved) until it is claimed; what comes in afterwards feeds the next window.

The 24-hour epoch

An epoch lasts 24 hours, counted from the contract’s genesis (the time it was deployed). Epoch n covers [genesis + n × 24 h, genesis + (n + 1) × 24 h). Each recorded run is filed under the epoch of its timestamp: the games that get paid are the ones that were played in the last 24 hours, and the standings start again from zero every day. Until the contract is deployed, the site counts epochs from a fixed date (21 September 2026, 00:00 UTC).

A game’s weight

The weight does not depend on scores, only on how many runs were played and by whom. For one game and one 24-hour epoch:

formulaText
signed = Σ over wallets of min(signed plays of that wallet, 10)
anon   = min(0.1 × anonymous plays, 0.2 × signed)
weight = round((signed + anon) × 100)
  • Each wallet counts at most 10 plays per game per epoch: replaying in a loop does not inflate the weight.
  • An anonymous run is worth a tenth, and all anonymous runs together cannot exceed 20 % of the signed weight.
  • The factor 100 and rounding give an integer, which is what the contract expects.

A wallet is needed to play

A published game only starts with a wallet connected: a Connect wallet to play button replaces Play until one is. This is the anti-bot rule that makes play counts mean something: every run is tied to a wallet before the cap of 10 applies. See Playing and leaderboards.

Worked example

A game receives the following runs in one 24-hour epoch:

PlayerRunsCounted
0xA…2510
0xB…44
0xC…11
anonymous300min(30, 0.2 × 15 = 3) = 3
Weight(15 + 3) × 100 = 1800

If the vault holds 0.5 ETH at settlement and the total weight of all settled games is 6000, this game gets 0.5 × 1800 / 6000 = 0.15 ETH.

What does not count

Showcase templates never count. Only games published on-chain (numeric id) can be settled: draft-registry games show in the standings but are skipped at settlement.

From played game to claimed ETH

  1. Fees come in

    Anyone can call harvest() to pull the creator fees Pons holds for the token into the vault. The contract also accepts any ETH sent to it directly.
  2. The 24 hours are up

    Only a finished epoch can be settled; the current one cannot.
  3. The operator settles

    Every day, the operator computes the weights of the window that just closed with the formula above and calls settle(epoch, gameIds, weights, amount) once per epoch, with 1 to 200 games (the heaviest) and an amount no larger than the vault’s ETH not yet reserved.
  4. Anyone claims

    claim(epoch, gameId) or claimMany(epoch, gameIds) can be called by anyone; the share amount × weight / totalWeight is always paid to the game’s current creator. pending(epoch, gameId) previews the amount. Nothing expires overnight: several days’ shares can be claimed in one go.
  5. After 90 days

    What is still unclaimed 90 days after settlement can be sent to the treasury by the owner (sweepUnclaimed); claims for that epoch are then closed.

Following the standings

The Builders page shows the standings of the current 24 hours and of the previous day, with each game’s weight, players and plays, and past settlements. The same data is public:

GET/api/season
response (abridged)JSON
{
  "live": true,
  "epoch": 3,
  "start": 1790208000000,
  "end": 1790294400000,
  "current": [{ "id": "12", "title": "…", "creator": "0x…", "mode": "race", "weight": 1800, "players": 3, "plays": 330 }],
  "previous": [],
  "settlements": [],
  "treasury": { "balance": "…", "reserved": "…", "epoch": 3 }
}

Full reference: HTTP API.

Why this design

  • Scores are easy to forge in a game that runs on the player’s machine; play counts capped per wallet much less so.
  • The 10-plays-per-wallet cap favours games played by many people over games played a lot by a few.
  • Playing a published game needs a connected wallet: to manufacture plays you have to manufacture wallets.
  • Anonymous runs count a little, so players without a wallet are not ignored, but their share is capped.
  • A 24-hour window pays what is being played now: a game that works today is paid tomorrow, and nobody waits a week.
  • The contract owner cannot withdraw the vault’s ETH: the only exits are claims, tips and the 90-day sweep.

What next