# Paketera ett PlayDrop-spel med catalogue.json och .play

Lägg upp en byggd spelmapp, ZIP eller .play med catalogue.json i roten, deklarera media för spelsidan och servrar och ladda upp med prepare_catalogue_upload.

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

Ett paket är det byggda resultatet av ett spel plus en `catalogue.json` som beskriver det. Det är vägen till alla PlayDrop-funktioner: flera filer, SDK:t, bilder och videor för spelsidan, topplistor, prestationer, assets och en hostad server. Ladda upp det från din AI-app som en mapp, en ZIP eller en `.play`-fil.

## Lägg upp mappen

Lägg `catalogue.json` i roten, bredvid det byggda spelet. Sökvägar i katalogen är relativa till den.

```
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
```

En `.play`-fil är den här mappen packad som ZIP med `catalogue.json` i arkivets rot, inte i en omslutande mapp, och omdöpt till `.play`. Den innehåller bara byggda filer: inga `node_modules`, inga source maps som du inte vill göra offentliga och inga `.env`-filer. Låt källprojektet stanna hos din användare; PlayDrop kan inte lämna tillbaka det.

## Skriv catalogue.json

```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` är den exakta sökvägen till sidan som startar spelet. Utan den blir startsidan som standard `<name>.html`, inte `index.html`.
- `version` är en ny semantisk version för varje uppladdning av samma spel.
- `surfaceTargets` listar de ytor du har testat; `primarySurface` är den som spelet är gjort för.
- Katalogen gör anspråk på media för spelsidan, ikoner för prestationer och serverns startfil: en fil under `listing/` som inget fält refererar till är inte media för spelsidan, och filer som ingen app gör anspråk på avvisas innan något publiceras.
- `server.entry` pekar på en byggd ES-modul i en enda fil; se [spelservrar i realtid](https://www.playdrop.ai/sv/create/learn/game-servers).

Alla fält och deras gränser finns i [referensen för catalogue.json](https://www.playdrop.ai/sv/create/learn/catalogue-json). Det finns inget versionsfält för katalogen att ange.

## Ladda upp en mapp

Skicka `prepare_catalogue_upload` med ett nytt `requestId`, `expectedCurrentVersion` (`null` för ett nytt spel), hela katalogobjektet och en beskrivning per fil. Små textfiler kan skickas inline som `text`. Alla andra filer är signerade uppladdningar: beräkna storlek, SHA-256 (64 hexadecimala tecken med gemener) och MD5 i base64 lokalt från exakt de byte som skickas. Den här förfrågan för ett spel med två filer är komplett; ersätt de två platshållarna för kontrollsummor på ikonen med ikonens riktiga värden.

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

Svaret innehåller en uppladdnings-URL och headers för `listing/icon.png`. Gör PUT med ikonens exakta byte dit med alla returnerade headers och anropa sedan `complete_catalogue_upload` med samma `requestId`. Kvittots `url` öppnar den privata versionen.

## Ladda upp en ZIP eller .play

- **Agenter med ett filsystem** packar upp arkivet lokalt och laddar upp det som en mapp, som ovan.
- **ChatGPT** skickar arkivet som den löste upp från konversationen som `archive`, med dess riktiga `download_url` och `file_id`, och utan `catalogue` eller `files`. Arkivet får vara upp till 20 MiB komprimerat.

Arkiv måste vara vanliga ZIP-filer: ingen kryptering, inga flera volymer, ingen ZIP64, inga symboliska länkar, inga dubbla sökvägar, inga absoluta sökvägar och ingen `..`. Tomma filer och nästlade catalogue.json-filer avvisas.

## Gränser

512 filer eller arkivposter (inklusive catalogue.json och mappar), 50 MiB per fil, 200 MiB uppackat och 1 MiB katalog-JSON. Den byggda filen för en hostad server är högst 2 MiB.

## Uppdatera ett paket

Läs `list_games`, behåll varje apps `name`, höj dess `version` och sätt `expectedCurrentVersion` till den aktuella publicerade versionen. Skicka hela ögonblicksbilden: alla filer och fält som den nya versionen ska ha. Oförändrade filer från en bevarad version kan skickas med `reuse: { gameId, version, path }` i stället för deras byte. Nycklar för topplistor och prestationer kan inte tas bort eller byta typ; pensionera en med `"status": "RETIRED"`.

## Assets som connectorn inte kan ladda upp än

PlayDrop kör körbara 3D-modeller (`MODEL_3D`-assets med underkategorin `procedural` eller formatet `CUSTOM`) i sina egna verktyg, men connectorn avvisar dem eftersom API:et inte kan validera deras kod. Baka dem till ett format som stöds, eller referera till en asset som redan är publicerad på PlayDrop. Bakade procedurella bilder och spritesheets accepteras. Se [spelassets](https://www.playdrop.ai/sv/create/learn/game-assets).

## Relaterade guider

- [catalogue.json](https://www.playdrop.ai/sv/create/learn/catalogue-json): Fälten i catalogue.json för PlayDrop-spel: identitet, spelsida, spellägen, ytor, inloggning, Instant, förladdning, media, översättningar, poäng och servrar.
- [Publicera från din AI-app](https://www.playdrop.ai/sv/create/learn/mcp-publishing): Så publicerar AI-agenter på PlayDrop via MCP: den enkla vägen och paketvägen, privat testning, publish_game_version, uppdateringar, gränser och felhantering.
- [Bilder och video för spelsidan](https://www.playdrop.ai/sv/create/learn/listing-assets): Bilder och videor som ett PlayDrop-spels sida kan ha, deras sökvägar, format och orientering, och hur du gör bilder som fungerar i flöden, sök och delningar.
- [Spelservrar i realtid](https://www.playdrop.ai/sv/create/learn/game-servers): Kör en hostad Colyseus 0.17-server med en MongoDB-databas för ditt spel, anslut från webbläsaren med SDK:t, testa med två spelare och känn till gränserna.
