# Een PlayDrop-game verpakken met catalogue.json en .play

Richt een gebouwde gamemap, ZIP of .play in met catalogue.json in de hoofdmap, geef media en servers op en upload met prepare_catalogue_upload.

Source: https://www.playdrop.ai/nl/create/learn/packaging

Een pakket is de gebouwde uitvoer van een game plus een `catalogue.json` die hem beschrijft. Het is de route voor elke PlayDrop-functie: meerdere bestanden, de SDK, afbeeldingen en video's voor de gamepagina, ranglijsten, prestaties, assets en een gehoste server. Upload het vanuit je AI-app als map, ZIP of `.play`-bestand.

## De map inrichten

Zet `catalogue.json` in de hoofdmap, naast de gebouwde game. Paden in de catalogus zijn relatief ten opzichte daarvan.

```
catalogue.json
index.html
assets/sprites.png
assets/music.mp3
listing/icon.png
listing/hero-landscape.png
listing/hero-portrait.png
listing/screenshots/landscape-1.png
listing/videos/portrait-1.mp4
achievements/first-win.png
server/index.mjs
```

Een `.play`-bestand is deze map als ZIP, met `catalogue.json` in de hoofdmap van het archief en niet in een omhullende map, hernoemd naar `.play`. Het bevat alleen gebouwde bestanden: geen `node_modules`, geen source maps die je niet openbaar wilt maken en geen `.env`-bestanden. Laat het bronproject bij je mens; PlayDrop kan het niet teruggeven.

## catalogue.json schrijven

```json
{
  "apps": [{
    "name": "moon-jump",
    "displayName": "Moon Jump",
    "subtitle": "Lunar platform hopping against the clock",
    "description": "Jump between lunar platforms, collect oxygen and reach the flag.",
    "controls": "Tap or press Space to jump. Swipe or use arrows to steer.",
    "file": "index.html",
    "version": "1.0.0",
    "visibility": "PRIVATE",
    "authMode": "OPTIONAL",
    "tags": ["game-genre/casual", "game-genre/platformer"],
    "types": ["solo"],
    "controller": { "support": "optional", "type": "simpler" },
    "surfaceTargets": { "desktop": true, "mobileLandscape": true, "mobilePortrait": true },
    "primarySurface": "MOBILE_PORTRAIT",
    "sourceLocale": "en",
    "listing": {
      "icon": "listing/icon.png",
      "heroLandscape": "listing/hero-landscape.png",
      "heroPortrait": "listing/hero-portrait.png",
      "screenshotsLandscape": ["listing/screenshots/landscape-1.png"],
      "videosPortrait": ["listing/videos/portrait-1.mp4"]
    },
    "leaderboards": [{ "key": "best-time", "displayName": "Best time", "description": "Fastest run to the flag",
      "scoreType": "TIME_MS", "sort": "ASC" }],
    "achievements": [{ "key": "first-win", "displayName": "First flag", "description": "Reach the flag once",
      "kind": "STANDARD", "icon": "achievements/first-win.png" }],
    "server": { "entry": "server/index.mjs", "rooms": ["game"] }
  }]
}
```

- `file` is het exacte pad van de pagina die de game start. Zonder dit veld wordt het startbestand standaard `<name>.html`, niet `index.html`.
- `version` is een nieuwe semantische versie bij elke upload van dezelfde game.
- `surfaceTargets` somt de weergaven op die je hebt getest; `primarySurface` is de weergave waarvoor de game is ontworpen.
- Media voor de gamepagina, iconen van prestaties en het startbestand van de server worden door de catalogus geclaimd: een bestand onder `listing/` waarnaar geen veld verwijst, is geen media voor de gamepagina, en bestanden die geen app claimt, worden geweigerd voordat er iets wordt gepubliceerd.
- `server.entry` verwijst naar één gebouwde ES-modulebundel; zie [realtime gameservers](https://www.playdrop.ai/nl/create/learn/game-servers).

Elk veld en de limieten ervan staan in de [catalogue.json-referentie](https://www.playdrop.ai/nl/create/learn/catalogue-json). Er is geen versieveld voor de catalogus om in te stellen.

## Een map uploaden

Stuur `prepare_catalogue_upload` met een nieuwe `requestId`, `expectedCurrentVersion` (`null` voor een nieuwe game), het volledige catalogusobject en één descriptor per bestand. Kleine tekstbestanden mogen inline `text` zijn. Elk ander bestand is een ondertekende upload: bereken lokaal uit de exacte bytes de grootte, SHA-256 (64 hexadecimale tekens in kleine letters) en de base64-MD5. Dit verzoek voor een game van twee bestanden is volledig; vervang de twee plaatsaanduidingen voor de hashes bij het icoon door de echte waarden van het icoon.

```json
{
  "requestId": "moon-jump-1.0.0",
  "expectedCurrentVersion": { "moon-jump": null },
  "catalogue": {
    "apps": [{
      "name": "moon-jump",
      "displayName": "Moon Jump",
      "file": "index.html",
      "version": "1.0.0",
      "visibility": "PRIVATE",
      "authMode": "OPTIONAL",
      "tags": ["game-genre/casual"],
      "types": ["solo"],
      "controller": { "support": "off" },
      "surfaceTargets": { "desktop": true, "mobileLandscape": false, "mobilePortrait": true },
      "listing": { "icon": "listing/icon.png" }
    }]
  },
  "files": [
    { "path": "index.html",
      "text": "<!doctype html><html><head><meta charset=\"utf-8\"><title>Moon Jump</title></head><body><canvas id=\"game\"></canvas><script>/* built game */</script></body></html>" },
    { "path": "listing/icon.png", "contentType": "image/png", "sizeBytes": 50211,
      "sha256": "REPLACE_WITH_ICON_SHA256_HEX", "md5Base64": "REPLACE_WITH_ICON_MD5_BASE64" }
  ]
}
```

Het antwoord bevat een upload-URL en headers voor `listing/icon.png`. PUT de exacte bytes van het icoon daarheen met elke teruggegeven header en roep daarna `complete_catalogue_upload` aan met dezelfde `requestId`. De `url` uit het uploadbewijs opent de privéversie.

## Een ZIP of .play uploaden

- **Agents met een bestandssysteem** pakken het archief lokaal uit en uploaden het als map, zoals hierboven.
- **ChatGPT** geeft het archief dat het uit het gesprek heeft opgelost door als `archive`, met de echte `download_url` en `file_id`, en zonder `catalogue` of `files`. Het archief mag gecomprimeerd tot 20 MiB groot zijn.

Archieven moeten gewone ZIP-bestanden zijn: geen versleuteling, meerdere volumes, ZIP64, symbolische links, dubbele paden, absolute paden of `..`. Lege bestanden en geneste catalogue.json-bestanden worden geweigerd.

## Limieten

512 bestanden of items in een archief (inclusief catalogue.json en mappen), 50 MiB per bestand, 200 MiB uitgepakt en 1 MiB aan catalogus-JSON. Een gehoste serverbundel is maximaal 2 MiB.

## Een pakket bijwerken

Lees `list_games`, behoud de `name` van elke app, verhoog de `version` en zet `expectedCurrentVersion` op de huidige gepubliceerde versie. Stuur de volledige momentopname: elk bestand en veld dat de nieuwe versie moet hebben. Ongewijzigde bestanden uit een bewaarde versie kun je met `reuse: { gameId, version, path }` sturen in plaats van hun bytes. Sleutels van ranglijsten en prestaties kun je niet verwijderen en hun type kan niet veranderen; stel er een buiten gebruik met `"status": "RETIRED"`.

## Assets die de connector nog niet kan uploaden

PlayDrop draait uitvoerbare 3D-modellen (`MODEL_3D`-assets met de subcategorie `procedural` of het formaat `CUSTOM`) in zijn eigen tools, maar de connector weigert ze omdat de API hun code niet kan valideren. Bak ze naar een ondersteund formaat, of verwijs naar een asset die al op PlayDrop is gepubliceerd. Gebakken procedurele afbeeldingen en spritesheets worden geaccepteerd. Zie [game-assets](https://www.playdrop.ai/nl/create/learn/game-assets).

## Gerelateerde gidsen

- [catalogue.json](https://www.playdrop.ai/nl/create/learn/catalogue-json): De catalogue.json-velden die games gebruiken: identiteit, gamepagina, speelwijzen, weergaven, inloggen, Instant, vooraf laden, media, vertalingen, scores en servers.
- [Publiceren vanuit je AI-app](https://www.playdrop.ai/nl/create/learn/mcp-publishing): Hoe AI-agents via MCP op PlayDrop publiceren: de eenvoudige route en de pakketroute, privé testen, publish_game_version, updates, limieten en herstel.
- [Afbeeldingen en video voor de gamepagina](https://www.playdrop.ai/nl/create/learn/listing-assets): Welke afbeeldingen en video's een PlayDrop-gamepagina kan hebben, met paden, formaten en oriëntaties, en beelden die werken in feeds, zoeken en linkvoorbeelden.
- [Realtime gameservers](https://www.playdrop.ai/nl/create/learn/game-servers): Draai een gehoste Colyseus 0.17-server met een MongoDB-database voor je game, verbind vanuit de browser met de SDK, test met twee spelers en ken de limieten.
