PlayDrop
PlayDrop could not load

A required part of the page failed to download. Try loading it again.

STYLESHEET_ERROR
PlayDrop logoPlayDrop Studio
PlayDrop logoPlayDrop Studio
CreatePlayTradeEarnLearnConnectorsCommunitySupport
catalogue.json
Documentation

Start here

OverviewYour first game

Create with Cloud

Cloud creationPublish & importPlans & generationsCredits & rewards

Connect your agent

All connectorsClaudeChatGPTClaude CodeCodexCursorGeminiAntigravityGrok BuildGrok BotGrok ChatLovableReplit

Technical reference

Game filescatalogue.jsonClient SDKServer SDKTroubleshootingFAQ
Documentationcatalogue.json
Technical reference

catalogue.json: PlayDrop game metadata and localization

Reference for game titles, descriptions, genre tags, listing images and videos, translations and the optional server field in the PlayDrop Connector format.

PlayDrop Connector sends your catalogue.json metadata alongside the game files; no command-line tool is needed. PlayDrop Cloud maintains this metadata for Studio games.

Complete private upload with prepare_catalogue_upload

json
{
  "requestId": "my-game-v1-unique-request",
  "catalogue": {
    "apps": [
      {
        "name": "my-game",
        "displayName": "My Game",
        "file": "index.html",
        "version": "1.0.0",
        "visibility": "PRIVATE",
        "authMode": "OPTIONAL",
        "tags": ["game-genre/puzzle"],
        "types": ["solo"],
        "controller": { "support": "off" },
        "surfaceTargets": {
          "desktop": true,
          "mobileLandscape": false,
          "mobilePortrait": false
        }
      }
    ]
  },
  "expectedCurrentVersion": {
    "my-game": null
  },
  "files": [
    {
      "path": "index.html",
      "text": "<!doctype html><html><head><title>My Game</title></head><body><button onclick=\"this.textContent=Number(this.textContent)+1\">0</button></body></html>"
    }
  ]
}

This is a complete prepare_catalogue_upload request for a new private game. Replace the example HTML with your built game and use a unique requestId for each intended upload. The catalogue object is the content of catalogue.json; files and expectedCurrentVersion belong to the tool request, outside that object.

apps[].file must exactly match a files[].path. If file is omitted, the entry defaults to <name>.html, not index.html. surfaceTargets is an object with desktop, mobileLandscape and mobilePortrait booleans; enable at least one surface you have tested. Declare the version and visibility explicitly. The example uses an inline text file; attachments or signed byte uploads can use the same path.

After preparing, send any requested file bytes and call complete_catalogue_upload with the same requestId. Open the private version to test it. For an update, read list_games, keep the same name, provide a new version and the full snapshot, and set expectedCurrentVersion[name] to the current public version returned by the server (or null if none). It is a conflict check, not the version being uploaded. Retry interrupted uploads with their original request ID. Publish the tested retained version with publish_game_version when ready.

Legacy single-game compatibility example

The example below is the legacy single-game shape. Full catalogue uploads also support multiple games, assets, packs and specs; ask the connector for the current schema. Each update supplies a complete snapshot with explicit visibility and version. Omitted catalogue items are not deleted.

Keep the lowercase slug stable when updating. Add a display title, an accurate description, controls, the source language and known tags as needed. The example below uses the existing platformer genre tag.

json
{
  "apps": [{
    "name": "moon-jump",
    "displayName": "Moon Jump",
    "description": "Jump between lunar platforms and reach the finish.",
    "controls": "Arrow keys to move. Space to jump.",
    "sourceLocale": "en",
    "players": { "solo": true },
    "controllerMode": "UNSUPPORTED",
    "tags": ["game-genre/platformer"]
  }]
}

Supported fields and limits

name: 1–100 lowercase letters, digits or hyphens, beginning with a letter or digit. displayName: nonempty title. subtitle: aim for 4–8 words and about 60 characters; 120 is the hard maximum. description: up to 3,000 characters of Markdown, without H1 headings, embedded media or tables. inspirationPrompt: up to 400 characters of single-line plain text. Text limits count JavaScript UTF-16 code units.

New game uploads declare a genre (design.genre or a genre tag), player modes and controller support explicitly. Prefer a recognized specific category tag alongside the genre. Optional fields include controls, releaseNotes, makingOf, emoji, color, sourceRepository, license, tags, sourceLocale, listingLocalizations, listingMedia and server. Tags use existing group-slug/tag-slug references, with at most 20 unique tags. server lists the Colyseus rooms of an uploaded server.js, for example "server": { "rooms": ["game"] }; see the server SDK. Ask the connector for current accepted license values and full field rules before publication. Optional native app hints: prefetch lists uploaded files that PlayDrop's iOS, macOS and Android apps can download before play, for example "prefetch": { "required": ["game.js"], "optional": ["music.mp3"] } (the entry page is always included), and "offlineSupported": true lets those apps offer the game offline once its required files are stored. Invalid values are ignored and never block an upload; websites load games as usual.

Instant games must support mobile portrait with "primarySurface": "MOBILE_PORTRAIT" and allow guests (authMode OPTIONAL or NONE). Set "instant": true when playable within 2 seconds from at most 10 MiB of startup files (the entry page plus prefetch.required, or every uploaded file when none are listed). Instant games carry the lightning badge and play in the Instant feed of PlayDrop's phone apps. Put deeper levels and extras in prefetch.optional, finish shader compiling and other warm-up before calling ready(), make the preview show gameplay rather than a title screen. PlayDrop checks the size at upload and removes the badge from versions that phones start slowly; a game that misses the bar is still published.

Listing images and videos

Upload listing media as files next to index.html, named by path: listing/icon.png, listing/hero-landscape.png (16:9) and listing/hero-portrait.png (9:16) with the game title in the art, screenshots such as listing/screenshots/landscape/0.png, and videos listing/videos/landscape/0.mp4 (the trailer) and listing/videos/portrait/0.mp4 (the mobile teaser). For Instant marketing, produce portrait gameplay video before a landscape trailer; video is not required for Instant eligibility. Listing videos play silently. Images are PNG and videos MP4.

Translate the listing accurately

Default to English plus your own language when different; expand languages only with broader marketing. Set sourceLocale to the original language. listingLocalizations accepts the current supported PlayDrop interface locales; do not restrict it to the original ten. Each translation needs locale and displayName; when you upload it with its source, PlayDrop fills in sourceHash. Upload translated art under listing/locales/<locale>/, for example listing/locales/fr/hero-landscape.png with the French title; it is matched to its translation automatically. Refresh translations after source changes. Listing translation does not translate the game itself.

Players, parties and controllers

Declare how your game is played with types, party, controller and roomVoice on each game entry:

json
{
  "types": ["solo", "online", "party"],
  "party": { "local": [1, 2, 3, 4], "online": [1, 2, 3, 4] },
  "controller": { "support": "optional", "type": "simpler" },
  "roomVoice": true
}

types combines solo (playable alone), online (played with others over the network) and party (a group playing together). party.local lists the exact numbers of people who can play on one screen; party.online lists the friend-group sizes, up to 4, that can enter online together, not the room capacity. Sizes are exact: [2, 4] excludes 3. party requires the party type, party.online requires online, and a 1 in party.local requires solo. roomVoice: true turns on room voice and requires online.

Declare controller.support explicitly as off, optional or required on new uploads; older versions retain their compatibility defaults. When it is not off, controller.type names the minimum controls the game needs:

  • any: directions, Confirm and Cancel; every controller works, including remotes.
  • simpler: one analog stick, four face buttons and Menu; PlayDrop phone controllers and standard gamepads qualify.
  • standard: D-pad, two clickable sticks, four face buttons, two shoulder buttons, two triggers and Menu.
  • custom: reserved for game-specific phone controls; not available yet.

With controller support on, every declared local count must be playable with controllers; read controller input through the SDK. Existing games may keep players and controllerMode, which still work, but new games use these fields, and one entry cannot mix both. The host selects local or online play, never both. These declarations survive Cloud, CLI and MCP uploads, retained private versions and publication. Availability also depends on the platform rollout and host build.

For MCP server uploads, provide a built ESM .mjs/.js bundle as a SERVER descriptor and point server.entry at it. Source projects for Cloud/CLI retain their TypeScript entry. PlayDrop supplies the Colyseus and server SDK runtime; never include voice provider credentials in a game.

PreviousAdd your own game: HTML, folder, .zip or .playNextPlayDrop client SDK for browser games
View Markdown
EnglishFrançaisDeutsch日本語한국어EspañolPortuguês (Brasil)Bahasa Indonesia繁體中文简体中文ItalianoPolskiNederlandsSvenskaNorsk bokmålSuomiTürkçeไทยTiếng Việtالعربية

On this page

Complete private upload with prepare_catalogue_uploadLegacy single-game compatibility exampleSupported fields and limitsListing images and videosTranslate the listing accuratelyPlayers, parties and controllers
View Markdown