# Spakuj grę PlayDrop z catalogue.json i .play

Zbudowana gra w folderze, ZIP lub .play z catalogue.json w katalogu głównym: media strony gry, serwery i przesyłanie przez prepare_catalogue_upload.

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

Pakiet to zbudowana gra wraz z opisującym ją plikiem `catalogue.json`. Ta ścieżka obsługuje każdą funkcję PlayDrop: wiele plików, SDK, obrazy i filmy strony gry, rankingi, osiągnięcia, zasoby i hostowany serwer. Prześlij go z aplikacji AI jako folder, ZIP lub plik `.play`.

## Przygotuj folder

Umieść `catalogue.json` w katalogu głównym, obok zbudowanej gry. Ścieżki w katalogu są względne wobec niego.

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

Plik `.play` to ten folder spakowany do ZIP z `catalogue.json` w katalogu głównym archiwum, a nie w folderze nadrzędnym, ze zmienioną nazwą na `.play`. Zawiera tylko zbudowane pliki: bez `node_modules`, map źródeł, których nie chcesz upubliczniać, ani plików `.env`. Projekt źródłowy zostaje u twojego użytkownika; PlayDrop nie może go zwrócić.

## Napisz 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` to dokładna ścieżka strony, która uruchamia grę. Bez niego wpis domyślnie przyjmuje `<name>.html`, a nie `index.html`.
- `version` to nowa wersja semantyczna przy każdym przesłaniu tej samej gry.
- `surfaceTargets` wymienia przetestowane powierzchnie; `primarySurface` to ta, dla której zaprojektowano grę.
- Multimedia strony gry, ikony osiągnięć i plik wejściowy serwera są przypisywane przez katalog: plik w folderze `listing/`, do którego nie odwołuje się żadne pole, nie jest multimediami strony gry, a pliki nieprzypisane do żadnej aplikacji są odrzucane, zanim cokolwiek zostanie opublikowane.
- `server.entry` wskazuje jeden zbudowany plik modułu ES ze spakowanymi zależnościami; zobacz [serwery gier czasu rzeczywistego](https://www.playdrop.ai/pl/create/learn/game-servers).

Wszystkie pola i ich limity opisuje [dokumentacja catalogue.json](https://www.playdrop.ai/pl/create/learn/catalogue-json). Nie ma pola wersji katalogu do ustawienia.

## Prześlij folder

Wyślij `prepare_catalogue_upload` z nowym `requestId`, `expectedCurrentVersion` (`null` dla nowej gry), kompletnym obiektem katalogu i po jednym deskryptorze na plik. Małe pliki tekstowe mogą być wbudowane jako `text`. Każdy inny plik jest przesyłany przez podpisany adres URL: oblicz lokalnie jego rozmiar, SHA-256 (64 małe znaki szesnastkowe) i MD5 w base64 z dokładnych bajtów. To żądanie dla gry z dwóch plików jest kompletne; zastąp dwa symbole zastępcze skrótów przy ikonie prawdziwymi wartościami ikony.

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

Odpowiedź podaje adres przesyłania i nagłówki dla `listing/icon.png`. Wyślij tam metodą PUT dokładne bajty ikony ze wszystkimi zwróconymi nagłówkami, a potem wywołaj `complete_catalogue_upload` z tym samym `requestId`. `url` z potwierdzenia przesłania otwiera wersję prywatną.

## Prześlij ZIP lub .play

- **Agenci z dostępem do systemu plików** rozpakowują archiwum lokalnie i przesyłają je jako folder, jak powyżej.
- **ChatGPT** przekazuje archiwum rozwiązane z rozmowy jako `archive`, z jego prawdziwymi `download_url` i `file_id`, bez `catalogue` ani `files`. Archiwum może mieć do 20 MiB po kompresji.

Archiwa muszą być zwykłymi plikami ZIP: bez szyfrowania, wielu woluminów, ZIP64, dowiązań symbolicznych, zduplikowanych ścieżek, ścieżek bezwzględnych ani `..`. Puste pliki i zagnieżdżone pliki catalogue.json są odrzucane.

## Limity

512 plików lub wpisów archiwum (wliczając catalogue.json i katalogi), 50 MiB na plik, 200 MiB po rozpakowaniu i 1 MiB JSON katalogu. Zbudowany plik hostowanego serwera ma najwyżej 2 MiB.

## Zaktualizuj pakiet

Odczytaj `list_games`, zachowaj `name` każdej aplikacji, podnieś jej `version` i ustaw `expectedCurrentVersion` na bieżącą opublikowaną wersję. Wyślij pełną migawkę: każdy plik i każde pole, które ma mieć nowa wersja. Niezmienione pliki zachowanej wersji można wysłać przez `reuse: { gameId, version, path }` zamiast ich bajtów. Kluczy rankingów i osiągnięć nie można usunąć, a ich typ nie może się zmienić; wycofaj klucz przez `"status": "RETIRED"`.

## Zasoby, których konektor jeszcze nie prześle

PlayDrop uruchamia wykonywalne modele 3D (zasoby `MODEL_3D` z podkategorią `procedural` lub w formacie `CUSTOM`) we własnych narzędziach, ale konektor je odrzuca, ponieważ API nie może zweryfikować ich kodu. Wypal je do obsługiwanego formatu albo odwołaj się do zasobu już opublikowanego w PlayDrop. Wypalone obrazy proceduralne i arkusze sprite'ów są akceptowane. Zobacz [zasoby gry](https://www.playdrop.ai/pl/create/learn/game-assets).

## Powiązane poradniki

- [catalogue.json](https://www.playdrop.ai/pl/create/learn/catalogue-json): Pola catalogue.json gier PlayDrop: tożsamość, strona gry, tryby gry, powierzchnie, logowanie, Instant, wstępne ładowanie, media, tłumaczenia, wyniki i serwery.
- [Publikuj z aplikacji AI](https://www.playdrop.ai/pl/create/learn/mcp-publishing): Jak agenci AI publikują w PlayDrop przez MCP: prosta ścieżka i pakiety, prywatne testy, publish_game_version, aktualizacje, limity i odzyskiwanie po błędach.
- [Grafika i wideo strony gry](https://www.playdrop.ai/pl/create/learn/listing-assets): Obrazy i filmy strony gry PlayDrop: ścieżki, formaty i orientacje oraz jak tworzyć grafikę, która działa w kanałach, wyszukiwarce i podglądach linków.
- [Serwery czasu rzeczywistego](https://www.playdrop.ai/pl/create/learn/game-servers): Uruchom hostowany serwer Colyseus 0.17 z bazą MongoDB dla swojej gry, łącz się z przeglądarki przez SDK, testuj z dwoma graczami i poznaj limity.
