← 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 who has played your game, not an automated check. The automated checks decide whether it is worth a person's time.

Everything up to that point is yours, needs nobody, and can be done as often as you like.


Two things, not one

The single most useful thing to understand about publishing here is that it is two separate acts, and they belong to different people:

Who does it What it is
Publishing a version You Recording what you uploaded. Nobody reviews it, nobody approves it, and no player sees it
Going live An operator Putting a version in front of players, taking real stakes

You can publish version 2, 3 and 4 while players are on version 1. Versions are yours — they are a record of your own work, and you make as many as you like. Only the live pointer is a decision about the platform, and only an operator moves it.

A game's status

Every game carries one:

Status What it means Who sets it
draft Started, and not in front of anybody. Where every game begins Created here on the first publish
staged Deliberately held off the catalogue. Same visibility as draft Operator
live In the catalogue, taking real stakes, on one named version Operator
retired Taken off the catalogue. Earnings already made are unaffected Operator

There is no submitted and no approved. A game is not frozen while somebody looks at it, because there is nothing to freeze — an operator reviews a version, which is immutable by construction, and you carry on working on the next one while they do.

What players can and cannot reach

A game that is not live is in no catalogue, and asking for its page directly returns "no such game". That is not a filter that could have a bug in it: the catalogue is a collection containing live games and nothing else, so a game that is not live was never in the list to be filtered out of.

Two people are the exception: you, and operators. Either can open a game that is not live and play it, on the player site, exactly as a player would see it — and it cannot take a stake, because every path that charges somebody reads the live catalogue.

So the honest summary is: a game you have published is fully playable by you, invisible to everybody else, and incapable of costing anyone money until an operator says so.


1. Develop

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

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 plays your rules 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

Upload through the developer portal, file by file. Everything about your files is measured from the bytes rather than taken from the form — the thumbnail's dimensions, the expanded bundle size, the engine it was built with — so a rejection 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.

A zip is accepted as a convenience and is unpacked, with every path checked before anything is written. One file at a time is usually easier: you can see what is there and replace one file without re-uploading the rest.

4. Publish a version

Publish records what you uploaded as a version. That is all it does. Nothing is in front of anybody, and nobody has been asked for anything.

Then play it, from your game's page. It opens on the player site, reachable only by you and operators, and it cannot take a stake. This is the cheapest bug-finding available to you — do it before asking anybody to look.

For a two-player game you need somebody on the other side: another operator, or an operator and you. You will be put in the same match.

5. Ask for it to go live

Send for review, on the game's page. Say anything an operator should know.

An operator will:

  • play your game, on the same page you just did
  • 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

Then they either approve it — live immediately, on the version you asked about, no deploy and no release — or decline it with a reason.

A decline always carries a reason, because the platform refuses one without. It is a list of what to change, not a verdict. Publish a new version and ask again; the request always concerns your newest version, so a fix and a re-ask are one motion.

You are told either way, and the answer is on your game's page whether you read the notification or not.

The question an operator is actually asking is not "does it work". It is "can a player make it pay out when it should not". A game that works perfectly and can be cheated is worse than one that crashes.


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 and publish — it becomes a new version alongside the live one, which players stay on
  4. Play it yourself
  5. Send for review; an operator moves the live pointer to it

Restoring an earlier version publishes a copy of it as a new one. It never moves the live pointer backwards: a pool already in flight is pinned to the version it started on and its runs are scored against that version's rules, so reusing a version number would score those runs against rules nobody played under.

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 a disputed result months later is checked against the rules it was played under.

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.