# 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.

Source: https://www.playdrop.ai/create/learn/html-games

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](https://www.playdrop.ai/create/learn/packaging) 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:

```json
{
  "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"
    }]
  }
}
```

- `name` is the game's permanent slug: 1–100 lowercase letters, digits or hyphens.
- `tags` must include a genre such as `game-genre/casual`; see [genres and tags](https://www.playdrop.ai/create/learn/tags).
- `types` declares how it is played; a one-file game is normally `["solo"]`. Party sizes and online play belong to packages.
- `controller.support` states real controller support, including `off`.
- `authMode` decides sign-in: `NONE` or `OPTIONAL` lets anyone play; omitted, it defaults to `REQUIRED`. Include it on every update.
- `primarySurface` names 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 `visibility` out 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 with `publish_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](https://www.playdrop.ai/create/learn/distribution).

## 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](https://www.playdrop.ai/create/learn/instant-games) 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](https://www.playdrop.ai/create/learn/packaging).

## Related guides

- [Publish from your AI app](https://www.playdrop.ai/create/learn/mcp-publishing): How AI agents publish to PlayDrop through MCP: the simple and package paths, private testing, publish_game_version, updates, limits and recovery.
- [Packaging and .play](https://www.playdrop.ai/create/learn/packaging): Lay out a built game folder, ZIP or .play with catalogue.json at its root, declare listing media and servers, and upload it with prepare_catalogue_upload.
- [Visibility and reach](https://www.playdrop.ai/create/learn/distribution): Choose who can open a PlayDrop game, how the account default and version publishing work, and how Boost, PlayTrade, Instant and search bring new players.
