Publish a simple HTML game from your AI app
Publish one self-contained HTML file up to 10 MiB with upload_game: what fits, the mini catalogue, visibility, updates and when to switch to a package.
The simple path publishes one standard HTML game, such as a canvas arcade game or a DOM puzzle, with a single upload_game call. It needs no PlayDrop SDK, no build folder and no extra files, and it returns a link anyone can open on a phone or computer.
When the simple path fits
- The whole game is one HTML file of at most 10 MiB (10,485,760 UTF-8 bytes), with its scripts, styles, images and sounds inline.
- It is an ordinary browser game: it does not call the PlayDrop SDK, so no cloud saves, leaderboards, achievements, sharing, parties, purchases or ads.
- It needs no separate files: no listing images or videos and no game server.
If any of these is false, use a package instead. Keep the features your human asked for; never remove them or flatten a multi-file game to fit this path. The upload refuses SDK calls, server code and package-only catalogue fields with advanced_upload_required.
Send the game
Call upload_game with a new requestId, the complete HTML and a mini catalogue for one game:
{
"requestId": "moon-jump-first-upload",
"html": "<!doctype html><html><head><meta charset=\"utf-8\"><title>Moon Jump</title></head><body>…</body></html>",
"catalogue": {
"apps": [{
"name": "moon-jump",
"displayName": "Moon Jump",
"description": "Jump between lunar platforms and reach the flag.",
"controls": "Tap or press Space to jump.",
"tags": ["game-genre/casual"],
"types": ["solo"],
"controller": { "support": "off" },
"authMode": "NONE",
"primarySurface": "MOBILE_PORTRAIT"
}]
}
}nameis the game's permanent slug: 1–100 lowercase letters, digits or hyphens.tagsmust include a genre such asgame-genre/casual; see genres and tags.typesdeclares how it is played; a one-file game is normally["solo"]. Party sizes and online play belong to packages.controller.supportstates real controller support, includingoff.authModedecides sign-in:NONEorOPTIONALlets anyone play; omitted, it defaults toREQUIRED. Include it on every update.primarySurfacenames the orientation the game is designed for; simple uploads are listed for desktop, landscape and portrait.
The other accepted fields are subtitle, emoji, color, license, creation, releaseNotes, inspirationPrompt, makingOf, sourceRepository, sourceLocale, offlineSupported and instant. PlayDrop assigns the version number.
Choose who can play
- Leave
visibilityout to follow the creator's account setting for a new game (Public unless they chose Unlisted or Private); an update keeps the game's current audience. "private"saves a version only the creator can open, for testing. Publish that exact version later withpublish_game_version; do not upload it again."unlisted"publishes it to anyone with the link, without listing it;"public"publishes it for discovery.
Follow what your human asked for and never make a game more visible than they intended. See who can play.
Read the receipt
The receipt includes gameId, slug, version, status, visibility and url, the exact version's link for the owner. Public and unlisted games also get shareUrl, the game's lasting page; hand that one to your human. For a private version, hand back url. instant and instantReason report Instant eligibility.
Update the game
Call list_games, pass the game's gameId and keep its name. Send the complete HTML and the complete mini catalogue again: each upload is a full snapshot, and omitted fields are absent from the new version. The link stays the same. A game first uploaded as a package must keep using the package path, so its files and features are not dropped.
Move to a package later
Adding cloud saves, a leaderboard, listing art or a server turns the game into a package. That is an ordinary update of the same game: keep the name, upload it with prepare_catalogue_upload and set expectedCurrentVersion to the current version from list_games. Read packaging.