Reference documentation

Publishing Reference

Publishing ties local workspace content to the live Playdrop catalogue.

Updated May 22, 2026

Publishing Reference

Publishing ties local workspace content to the live Playdrop catalogue.

Use this page for:

  • catalogue.json
  • versioning and lifecycle
  • listing metadata
  • media guidance for icons, heroes, screenshots, and video

Creator Basics

Before you publish anything, keep four launch rules in mind:

  • you keep ownership of what you upload
  • app IAP is split 50 / 50 between the creator and PlayDrop
  • creator earnings are paid in PlayDrop credits only
  • credits cannot be cashed out at launch

Creators also choose how other people may use their content:

  • Closed: nobody else can reuse or remix it through PlayDrop
  • PlayDrop License: other creators can use and remix it on PlayDrop only, with attribution and subject to platform rules
  • Open: use a standard open license. For apps this means MIT. For assets and packs this means CC0

Catalogue JSON

catalogue.json is the local source of truth for publishable Playdrop content.

Top-level shape

json example

{
  "apps": [],
  "assets": [],
  "assetPacks": []
}

App example

json example

{
  "name": "my-app",
  "version": "1.0.0",
  "license": "PLAYDROP",
  "file": "dist/index.html",
  "type": "GAME",
  "displayName": "My App",
  "description": "One sentence about what the player does",
  "authMode": "OPTIONAL",
  "controllerMode": "SUPPORTED",
  "previewable": true,
  "achievements": [
    {
      "key": "first_finish",
      "displayName": "First Finish",
      "description": "Finish one run"
    }
  ],
  "leaderboards": [
    {
      "key": "fastest_lap",
      "displayName": "Fastest Lap",
      "scoreType": "TIME_MS",
      "sort": "ASC"
    }
  ]
}

App owned assets

Apps may register reusable catalogue assets directly inside the app entry with ownedAssets.

Use this when:

  • the game should load catalogue assets instead of bundling every file in ./assets/...
  • you want other creators or other apps to reuse the same assets
  • republishing the app should reuse unchanged asset revisions instead of creating duplicates

Example:

json example

{
  "name": "starter-kit-3d-platformer",
  "version": "1.1.0",
  "license": "PLAYDROP",
  "file": "dist/index.html",
  "type": "DEMO",
  "ownedAssets": [
    {
      "name": "starter-kit-3d-platformer-character",
      "license": "PLAYDROP",
      "runtimeKey": "character",
      "displayName": "Starter Kit Character",
      "description": "Main player character for the starter kit platformer.",
      "category": "MODEL_3D",
      "subcategory": "humanoid",
      "format": "GLB",
      "visibility": "PUBLIC",
      "tags": ["theme/fantasy", "asset-type/character"],
      "files": {
        "primary": "assets/models/character.glb"
      }
    },
    {
      "name": "starter-kit-3d-platformer-level",
      "license": "PLAYDROP",
      "runtimeKey": "level",
      "category": "CUSTOM",
      "format": "CUSTOM",
      "assetSpec": "asset-spec:playdrop/level@1.0.0",
      "visibility": "PUBLIC",
      "files": {
        "primary": "assets/levels/level-1.json"
      }
    }
  ]
}

runtimeKey is the in-game lookup key. In the app runtime, resolve registered assets with:

ts example

const character = sdk.assets.resolveAppAsset('character');
const allAssets = sdk.assets.listAppAssets();

Rules:

  • use ownedAssets, not embeddedAssets
  • use runtimeKey for app-side lookup
  • add displayName, description, and tags when you want owned assets to be discoverable in the catalogue
  • set subcategory for normal asset categories
  • omit subcategory for CUSTOM
  • unchanged ownedAssets reuse the existing asset revision on republish
  • changed ownedAssets create a new asset revision
  • published runtime asset file URLs are stable public URLs so the game can load them through normal browser caching

App publishing is session-based.

  • playdrop project publish initializes an app upload session, uploads the app bundle and owned assets, then finalizes the session
  • direct POST /creators/:creator/apps/:name/versions uploads are no longer part of the supported client workflow

App hosting modes

Apps can either be hosted on Playdrop or hosted elsewhere.

  • HOSTED: the app files live in your Playdrop workspace and the app entry points at a local file such as dist/index.html
  • EXTERNAL: the game already lives at a public HTTPS URL and Playdrop stores the catalogue entry, listing metadata, and store media while launching the external game URL

If you provide externalUrl, Playdrop treats the app as EXTERNAL.

External app example

json example

{
  "name": "my-external-game",
  "version": "1.0.0",
  "license": "PLAYDROP",
  "type": "GAME",
  "displayName": "My External Game",
  "description": "Arcade game already hosted on our own site",
  "visibility": "PUBLIC",
  "hostingMode": "EXTERNAL",
  "externalUrl": "https://example.com/games/my-external-game/",
  "listing": {
    "icon": "listing/icon.png",
    "heroLandscape": "listing/hero-landscape.png",
    "screenshotsLandscape": [
      "listing/screenshots/landscape/1.png"
    ]
  }
}

Use HOSTED when Playdrop should publish the app files from your workspace. Use EXTERNAL when the game should stay hosted at its current public URL.

Asset example

json example

{
  "name": "sword-icon",
  "license": "CC0",
  "displayName": "Sword Icon",
  "description": "Inventory icon",
  "category": "IMAGE",
  "subcategory": "generic",
  "format": "PNG",
  "visibility": "PUBLIC",
  "files": {
    "primary": "assets/sword-icon.png",
    "preview": "assets/sword-icon-preview.png"
  }
}

Pack example

json example

{
  "name": "starter-pack",
  "version": "1.0.0",
  "license": "CC0",
  "displayName": "Starter Pack",
  "description": "Core starter assets",
  "visibility": "PUBLIC",
  "assets": [
    "asset:playdrop/sword-icon@r1",
    "asset:playdrop/shield-icon@r2"
  ]
}

Packs support the same ownedAssets contract for local assets, and unchanged owned assets are reused there too.

License field

In catalogue.json, use the exact stored value:

  • apps: CLOSED, PLAYDROP, or MIT
  • assets and packs: CLOSED, PLAYDROP, or CC0

If you omit license, PlayDrop defaults to PLAYDROP.

The web app presents three creator-facing choices:

  • Closed
  • PlayDrop License
  • Open

Open maps to MIT for apps and CC0 for assets and packs.

Visibility and license are different

Public visibility does not automatically mean public source, remixing, or off-PlayDrop reuse.

  • visibility answers "who can discover or open this listing?"
  • license answers "what can other people do with this content?"

An app, asset, or pack can be public and still be Closed.

Creator FAQ

Do I still own my work if I publish on PlayDrop?

Yes. You keep ownership of your content. The license you choose only controls what other people may do with it through PlayDrop.

What does the PlayDrop License mean?

It means other creators can use and remix your work on PlayDrop only. They must keep attribution and lineage back to the original work. Blatant copies, impersonation, and attribution stripping are still against platform rules.

Can people download my source just because my listing is public?

No. Source download and remix access follow the license and the available PlayDrop surface, not just visibility.

How do creator earnings work at launch?

For app IAP processed in PlayDrop credits, the player pays the full price, the creator earns 50% in PlayDrop credits, and PlayDrop keeps 50%.

Can I cash out credits?

No. Credits cannot be cashed out at launch.

Validate and publish:

bash example

playdrop project validate .
playdrop project publish .

For hosted apps, the runtime contract is still the same: load the Playdrop SDK, call playdrop.init(), and call sdk.host.ready(). playdrop project validate now starts the app inside the real PlayDrop /dev host before upload and fails if hosted startup breaks, so missing SDK wiring is caught before the artifact is published.

Versioning and Lifecycle

Playdrop content is versioned by object type:

  • apps use semantic versions such as 1.0.0
  • assets use revisions such as r1
  • packs use semantic versions such as 1.0.0

Use explicit versions when you need deterministic remixing, stable audit history, repeatable promotion, or controlled current-version changes.

Inspect versions:

bash example

playdrop versions browse playdrop/app/hangingout
playdrop versions browse playdrop/asset/sample-asset
playdrop versions browse playdrop/pack/starter-pack

Listing Metadata

Listing metadata is how creators explain catalogue content clearly.

At minimum, each listing should make these obvious:

  • what the content is
  • who it is for
  • what a player or creator can do with it
  • why the current version matters

Good:

text example

Topdown Drift
Arcade racing game where the player chains short drift boosts across compact tracks.

Weak:

text example

My Game
Cool game.

Media Guidelines

Use media to remove ambiguity from a listing quickly.

For apps:

  • icon: recognizable at small sizes
  • hero image: strongest high-level frame of the experience
  • screenshots: show actual gameplay or creator workflow
  • video: optional, but useful when motion or pacing matters

For assets and packs:

  • use previews that show the asset clearly
  • avoid unrelated decoration that hides what the content actually is
  • for packs, show the pack identity, not just one item without context