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.
- Build the new version
- Certify locally
- Upload and publish — it becomes a new version alongside the live one, which players stay on
- Play it yourself
- 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.
Related
- Getting started — the path end to end
- Trust model — what your game may and may not decide
- Writing the server rules — the half that decides outcomes
- Determinism — proving your rules are reproducible
- Building a client — for a front end, not a game
- Server API reference — every RPC, and who may call it
- Engine guides: Excalibur.js · Phaser · Defold
