← All documentation

From your machine to players

How a game gets published, updated, and — if it comes to it — pulled.

Nothing reaches real money without a platform operator approving it. That is a person reviewing your game, not an automated check. The automated checks decide whether it is worth a person's time.


The states

Every game carries a status:

Status What it means Who can set it
draft You are working on it. Editable. You
submitted Sent for review. Frozen — the reviewer sees the bytes you sent. You send it; an operator moves it on
staged Running on staging. Real gameplay, play money only. Operator
approved An operator has reviewed and signed it off. Not yet visible to players. Operator
live In the catalogue, taking real stakes. Operator
retired Removed from the catalogue. Earnings already made are unaffected. Operator

A submission can be sent back to draft at any point before it goes live, and doing so requires notes — you will be told what to fix, not just that it was refused.

Once it is submitted you cannot edit it. That is deliberate: a reviewer must be looking at the same bytes throughout. Withdraw it if you need to change something.

approved and live are separate on purpose. Approval is a judgement about the game; going live is a scheduling decision. Collapsing them would mean a review click puts real money at risk in the same instant.

The platform enforces this: a game configured as enabled while its status is anything other than live fails the build, and a staged game that declares real stakes fails too. Neither is a convention anyone can forget.


1. Develop

Follow your engine's guide: Defold · Excalibur.js · GDevelop

Your bundle needs a manifest.json at its root:

{
  "id": "block-blitz",
  "name": "Block Blitz",
  "category": "async-pool",
  "protocolVersion": 1,
  "entry": "index.html",
  "tickRate": 60,
  "poolSize": 5,
  "config": { "gridSize": 8 }
}

There is no payoutSplit field, and a manifest carrying one is rejected. How a pot is divided is the platform's decision and identical for every game — 1st 60%, 2nd 20%, 3rd 10%, platform 10%. It is refused rather than ignored so that a split you wrote deliberately cannot leave you believing it took effect.

The same applies to stake tiers and the rake: see what the platform decides.

You also need the server rules module — the half that decides outcomes. See writing the server rules.

2. Test it yourself

Run the checks locally before uploading. They are the same ones we run.

# Structure, size, forbidden APIs
pnpm certify path/to/your-bundle

# Determinism — the one that matters
pnpm test

selfTest replays your game repeatedly from several seeds and asserts the score and tick count are identical every time. It also fails a game that never draws from its seed, which would give every pool the same puzzle.

Run the determinism check against your built bundle, not just your source. A build step can introduce non-determinism the source does not have.

3. Upload and submit

Upload through the developer portal. Everything about your files is measured from the bytes rather than taken from the form — the thumbnail's dimensions, the expanded bundle size, the exports in your handler — so a rejection here names the actual measurement:

must be exactly 512×512, but this file is 500×500

The 10MB limit is on the expanded bundle, not the archive. Compressing harder does not help.

When you submit, the game moves to submitted and is frozen. An operator deploys it to staging, where it is fully playable on real infrastructure with play money only. Test it properly there. This is where you find the problems.

4. Ask for review

When you are satisfied, request approval. An operator will:

  • play your game, at least twice
  • check that skill is rewarded and the game is winnable and losable
  • look for ways to farm the score with a trivial repeated action
  • measure load time on a mid-range phone on mobile data
  • read your source, for third-party games — this is not optional
  • confirm nothing about it targets or appeals to under-18s

Expect questions. A rejection at this stage is usually about game design rather than code, and the feedback should tell you which.

5. Going live

An operator moves the game to approved, then schedules live. You will be told when.

Publishing puts your game in the player catalogue immediately — there is no deploy to wait for and no separate release. If it is not visible within a page refresh, that is a fault rather than a delay.


Updating a game

Updates go through the same path. There is no fast lane, including for first-party games.

  1. Build the new version
  2. Certify locally
  3. Upload — it becomes a new version in staging, alongside the live one
  4. Request review
  5. An operator promotes it

Bundles are immutable and content-addressed. Uploading a new version never overwrites the old one, which matters for two reasons: runs already in flight need the version they started on to settle, and the verifier needs it to replay a disputed result months later.

What needs a full review

Change Review needed
Anything affecting scoring or game rules Yes, always
Pool size, tick rate, player counts Yes
New assets, visual changes Lighter review
Bug fix with no scoring impact Lighter review, but still reviewed

Stakes, rake and the payout split are not on this list because they are not yours to change.

If you are unsure, assume yes.


Being pulled

A game can be disabled at any time without warning if it is doing something wrong. The most serious case is non-determinism found in a live game: every run after that point produces results the server cannot verify, so the game is disabled first and investigated afterwards.

If that happens, you will be told what was found and given the chance to fix it. Runs already settled are not reversed unless there is evidence of deliberate manipulation.


Revenue

Third-party games earn 50% of the platform's share of the games they power. Reporting and payouts appear in the developer portal.

You are paid on games played, not on downloads or installs.


Related