# catalogue.json: metadane i lokalizacja gier PlayDrop

Opis tytułów gier, opisów, tagów gatunków, obrazów i filmów strony gry, tłumaczeń oraz opcjonalnego pola server w formacie PlayDrop Connector.

Source: https://www.playdrop.ai/pl/create/learn/catalogue-json

[PlayDrop Connector](https://www.playdrop.ai/pl/create/connectors) wysyła metadane `catalogue.json` razem z plikami gry; nie jest potrzebne żadne narzędzie wiersza poleceń. PlayDrop Cloud utrzymuje te metadane dla gier ze Studio.

## Kompletne prywatne przesłanie przez prepare_catalogue_upload

To kompletne żądanie `prepare_catalogue_upload` dla nowej gry prywatnej. Zastąp przykładowy HTML swoją zbudowaną grą i użyj unikalnego `requestId` dla każdego zamierzonego przesłania. Obiekt `catalogue` to zawartość `catalogue.json`; `files` i `expectedCurrentVersion` należą do żądania narzędzia, poza tym obiektem.

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

`apps[].file` musi dokładnie odpowiadać `files[].path`. Jeśli pominiesz `file`, wpis domyślnie przyjmuje `<name>.html`, a nie `index.html`. `surfaceTargets` to obiekt z wartościami logicznymi `desktop`, `mobileLandscape` i `mobilePortrait`; włącz co najmniej jedną przetestowaną powierzchnię. Zadeklaruj wprost wersję i widoczność. Przykład używa wbudowanego pliku tekstowego; załączniki lub podpisane przesyłanie bajtów mogą korzystać z tej samej ścieżki.

Po przygotowaniu wyślij żądane bajty plików i wywołaj `complete_catalogue_upload` z tym samym `requestId`. Otwórz prywatną wersję, aby ją przetestować. Przy aktualizacji odczytaj `list_games`, zachowaj to samo `name`, podaj nową `version` i pełną migawkę oraz ustaw `expectedCurrentVersion[name]` na bieżącą wersję publiczną zwróconą przez serwer (lub `null`, jeśli jej nie ma). To sprawdzenie konfliktu, a nie przesyłana wersja. Ponów przerwane przesyłania z ich oryginalnym ID żądania. Gdy będzie gotowa, opublikuj przetestowaną zachowaną wersję przez `publish_game_version`.

## Przykład zgodności ze starym formatem pojedynczej gry

Poniższy przykład to stary kształt pojedynczej gry. Pełne przesłania katalogu obsługują też wiele gier, zasobów, pakietów i specyfikacji; zapytaj konektor o aktualny schemat. Każda aktualizacja dostarcza pełną migawkę z jawną widocznością i wersją. Pominięte elementy katalogu nie są usuwane.

Zachowaj stały slug z małych liter przy aktualizacji. Dodaj tytuł wyświetlany, dokładny opis, sterowanie, język źródłowy i znane tagi według potrzeb. Poniższy przykład używa istniejącego tagu gatunku platformówki.

```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",
    "tags": ["game-genre/platformer"]
  }]
}
```

## Obsługiwane pola i limity

`name`: 1–100 małych liter, cyfr lub myślników, zaczynając od litery lub cyfry. `displayName`: niepusty tytuł. `subtitle`: do 120 znaków. `description`: do 3000 znaków Markdown, bez nagłówków H1, osadzonych multimediów i tabel. `inspirationPrompt`: do 400 znaków jednowierszowego zwykłego tekstu. Limity tekstu liczą jednostki kodu UTF-16 JavaScriptu.

Pola opcjonalne to m.in. `controls`, `releaseNotes`, `makingOf`, `emoji`, `color`, `sourceRepository`, `license`, `tags`, `sourceLocale`, `listingLocalizations`, `listingMedia` i `server`. Tagi używają istniejących odwołań `group-slug/tag-slug`, maksymalnie 20 unikalnych tagów. `server` wymienia pokoje Colyseus z przesłanego `server.js`, na przykład `"server": { "rooms": ["game"] }`; zobacz [SDK serwera](https://www.playdrop.ai/pl/create/learn/server-sdk). Przed publikacją zapytaj konektor o aktualnie akceptowane wartości licencji i pełne zasady pól. Opcjonalne wskazówki dla aplikacji natywnych: `prefetch` wymienia przesłane pliki, które aplikacje PlayDrop na iOS, macOS i Androida mogą pobrać przed grą, na przykład `"prefetch": { "required": ["game.js"], "optional": ["music.mp3"] }` (strona wejściowa jest zawsze dołączona), a `"offlineSupported": true` pozwala tym aplikacjom oferować grę offline po zapisaniu wymaganych plików. Nieprawidłowe wartości są ignorowane i nigdy nie blokują przesłania; strony internetowe ładują gry jak zwykle.

Gry Instant: ustaw `"instant": true`, gdy grę da się uruchomić w ciągu 2 sekund z co najwyżej 10 MB plików startowych (strona wejściowa plus `prefetch.required`, a gdy ich nie podano, wszystkie przesłane pliki). Gry Instant dostają odznakę błyskawicy i działają w kanale Instant w aplikacjach PlayDrop na telefony. Głębsze poziomy i dodatki umieść w `prefetch.optional`, zakończ kompilację shaderów i inne rozgrzewanie przed wywołaniem `ready()`, spraw, by podgląd pokazywał rozgrywkę, a nie ekran tytułowy, i zezwól gościom (`authMode` `OPTIONAL` lub `NONE`), aby każdy widział grę w kanale. PlayDrop sprawdza rozmiar przy przesłaniu i usuwa odznakę z wersji, które na telefonach startują wolno; gra, która nie spełnia wymagań, nadal jest publikowana.

## Obrazy i filmy strony gry

Prześlij multimedia strony gry jako pliki obok `index.html`, nazwane ścieżką: `listing/icon.png`, `listing/hero-landscape.png` (16:9) i `listing/hero-portrait.png` (9:16) z tytułem gry w grafice, zrzuty ekranu, takie jak `listing/screenshots/landscape/0.png`, oraz filmy `listing/videos/landscape/0.mp4` (zwiastun) i `listing/videos/portrait/0.mp4` (zapowiedź mobilna). Filmy odtwarzają się bez dźwięku na kartach gier i stronie gry, zwiastun na komputerach i telewizorach, a zapowiedź na telefonach, więc to najszybszy sposób na pokazanie rozgrywki i zdobycie pierwszej rozgrywki. Obrazy to PNG, a filmy to MP4.

## Tłumacz stronę gry dokładnie

Zawsze publikuj angielski oraz własny język, jeśli jest inny. Ustaw `sourceLocale` na język oryginału. `listingLocalizations` obsługuje angielski, francuski, niemiecki, hiszpański, portugalski brazylijski, indonezyjski, japoński, koreański, chiński tradycyjny i chiński uproszczony. Każde tłumaczenie wymaga `locale` i `displayName`; gdy prześlesz je ze źródłem, PlayDrop uzupełni `sourceHash`. Prześlij przetłumaczoną grafikę w `listing/locales/<locale>/`, na przykład `listing/locales/fr/hero-landscape.png` z francuskim tytułem; zostanie automatycznie dopasowana do swojego tłumaczenia. Odśwież tłumaczenia po zmianach źródła. Tłumaczenie strony gry nie tłumaczy samej gry.

## Gracze, grupy i kontrolery

Zadeklaruj, jak gra się w twoją grę, za pomocą `types`, `party`, `controller` i `roomVoice` w każdym wpisie gry:

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

`types` łączy `solo` (grywalne w pojedynkę), `online` (gra z innymi przez sieć) i `party` (grupa grająca razem). `party.local` wymienia dokładne liczby osób, które mogą grać na jednym ekranie; `party.online` wymienia rozmiary grup znajomych, do 4, które mogą wejść online razem, a nie pojemność pokoju. Rozmiary są dokładne: `[2, 4]` wyklucza 3. `party` wymaga typu `party`, `party.online` wymaga `online`, a 1 w `party.local` wymaga `solo`. `roomVoice: true` włącza głos pokoju i wymaga `online`.

`controller.support` to `off` (domyślnie, gdy pominięto `controller`), `optional` lub `required`. Gdy nie jest `off`, `controller.type` nazywa minimalne sterowanie, którego potrzebuje gra:

- `any`: kierunki, Confirm i Cancel; działa każdy kontroler, także piloty.
- `simpler`: jeden drążek analogowy, cztery przyciski czołowe i Menu; kwalifikują się kontrolery PlayDrop na telefonie i standardowe gamepady.
- `standard`: krzyżak, dwa klikalne drążki, cztery przyciski czołowe, dwa przyciski ramieniowe, dwa spusty i Menu.
- `custom`: zarezerwowane dla sterowania na telefonie specyficznego dla gry; jeszcze niedostępne.

Przy włączonej obsłudze kontrolerów każda zadeklarowana liczba lokalna musi być grywalna z kontrolerami; odczytuj wejście kontrolera przez [SDK](https://www.playdrop.ai/pl/create/learn/sdk). Istniejące gry mogą zachować `players` i `controllerMode`, które nadal działają, ale nowe gry używają tych pól, a jeden wpis nie może mieszać obu. Host wybiera grę lokalną lub online, nigdy obu naraz. Te deklaracje przetrwają przesyłania z Cloud, CLI i MCP, zachowane prywatne wersje oraz publikację. Dostępność zależy też od wdrożenia platformy i wersji hosta.

Przy przesyłaniu serwera przez MCP dostarcz zbudowany pakiet ESM `.mjs`/`.js` jako deskryptor `SERVER` i wskaż go w `server.entry`. Projekty źródłowe dla Cloud/CLI zachowują swój wpis TypeScript. PlayDrop zapewnia środowisko Colyseus i SDK serwera; nigdy nie umieszczaj w grze danych uwierzytelniających dostawcy głosu.
