# catalogue.json: metadata en lokalisatie van PlayDrop-games

Referentie voor titels, beschrijvingen, genretags, media van de gamepagina, vertalingen en het optionele serverveld in het PlayDrop Connector-formaat.

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

[PlayDrop Connector](https://www.playdrop.ai/nl/create/connectors) stuurt je `catalogue.json`-metadata mee met de gamebestanden; er is geen opdrachtregeltool nodig. PlayDrop Cloud onderhoudt deze metadata voor Studio-games.

## Complete privé-upload met prepare_catalogue_upload

Dit is een volledig `prepare_catalogue_upload`-verzoek voor een nieuwe privégame. Vervang de voorbeeld-HTML door je gebouwde game en gebruik voor elke beoogde upload een unieke `requestId`. Het object `catalogue` is de inhoud van `catalogue.json`; `files` en `expectedCurrentVersion` horen bij het toolverzoek, buiten dat object.

```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` moet exact overeenkomen met een `files[].path`. Laat je `file` weg, dan wordt de standaard voor het item `<name>.html`, niet `index.html`. `surfaceTargets` is een object met de booleans `desktop`, `mobileLandscape` en `mobilePortrait`; zet minstens één weergave aan die je hebt getest. Geef de versie en zichtbaarheid expliciet op. Het voorbeeld gebruikt een inline tekstbestand; bijlagen of ondertekende byte-uploads kunnen hetzelfde pad gebruiken.

Stuur na het voorbereiden de gevraagde bestandsbytes mee en roep `complete_catalogue_upload` aan met dezelfde `requestId`. Open de privéversie om hem te testen. Lees voor een update `list_games`, houd dezelfde `name`, geef een nieuwe `version` en de volledige momentopname op en zet `expectedCurrentVersion[name]` op de huidige openbare versie die de server teruggeeft (of `null` als er geen is). Het is een conflictcontrole, niet de versie die je uploadt. Probeer onderbroken uploads opnieuw met hun oorspronkelijke verzoek-ID. Publiceer de geteste, bewaarde versie met `publish_game_version` als je klaar bent.

## Compatibiliteitsvoorbeeld voor één game (verouderd)

Het onderstaande voorbeeld heeft de oude vorm voor één game. Volledige cataloguploads ondersteunen ook meerdere games, assets, pakketten en specs; vraag de connector om het huidige schema. Elke update levert een complete momentopname met expliciete zichtbaarheid en versie. Weggelaten catalogusitems worden niet verwijderd.

Houd de slug in kleine letters stabiel bij het bijwerken. Voeg indien nodig een weergavetitel, een juiste beschrijving, besturing, de brontaal en bekende tags toe. Het onderstaande voorbeeld gebruikt de bestaande genretag platformer.

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

## Ondersteunde velden en limieten

`name`: 1–100 kleine letters, cijfers of koppeltekens, beginnend met een letter of cijfer. `displayName`: een niet-lege titel. `subtitle`: maximaal 120 tekens. `description`: maximaal 3.000 tekens Markdown, zonder H1-koppen, ingesloten media of tabellen. `inspirationPrompt`: maximaal 400 tekens platte tekst op één regel. Tekstlimieten tellen JavaScript-UTF-16-code-eenheden.

Optionele velden zijn onder meer `controls`, `releaseNotes`, `makingOf`, `emoji`, `color`, `sourceRepository`, `license`, `tags`, `sourceLocale`, `listingLocalizations`, `listingMedia` en `server`. Tags gebruiken bestaande verwijzingen `group-slug/tag-slug`, met maximaal 20 unieke tags. `server` noemt de Colyseus-rooms van een geüploade `server.js`, bijvoorbeeld `"server": { "rooms": ["game"] }`; zie de [server-SDK](https://www.playdrop.ai/nl/create/learn/server-sdk). Vraag de connector om de huidige geaccepteerde licentiewaarden en de volledige veldregels vóór het publiceren. Optionele hints voor native apps: `prefetch` noemt geüploade bestanden die de iOS-, macOS- en Android-apps van PlayDrop vóór het spelen kunnen downloaden, bijvoorbeeld `"prefetch": { "required": ["game.js"], "optional": ["music.mp3"] }` (de startpagina is altijd inbegrepen), en met `"offlineSupported": true` kunnen die apps de game offline aanbieden zodra de vereiste bestanden zijn opgeslagen. Ongeldige waarden worden genegeerd en blokkeren nooit een upload; websites laden games zoals gewoonlijk.

Instant-games: zet `"instant": true` als de game binnen 2 seconden speelbaar is met maximaal 10 MB aan opstartbestanden (de startpagina plus `prefetch.required`, of elk geüpload bestand als er geen zijn opgegeven). Instant-games krijgen de bliksembadge en spelen in de Instant-feed van de telefoonapps van PlayDrop. Zet diepere levels en extra’s in `prefetch.optional`, rond het compileren van shaders en andere opwarming af voordat je `ready()` aanroept, laat de voorvertoning gameplay tonen in plaats van een titelscherm en sta gasten toe (`authMode` `OPTIONAL` of `NONE`) zodat iedereen de game in de feed ziet. PlayDrop controleert de grootte bij het uploaden en haalt de badge weg bij versies die op telefoons traag starten; een game die de lat niet haalt, wordt toch gepubliceerd.

## Afbeeldingen en video’s voor de gamepagina

Upload media voor de gamepagina als bestanden naast `index.html`, benoemd op pad: `listing/icon.png`, `listing/hero-landscape.png` (16:9) en `listing/hero-portrait.png` (9:16) met de gametitel in de art, screenshots zoals `listing/screenshots/landscape/0.png` en video’s `listing/videos/landscape/0.mp4` (de trailer) en `listing/videos/portrait/0.mp4` (de mobiele teaser). Video’s spelen geluidloos op gamekaarten en de gamepagina, de trailer op computers en tv en de teaser op telefoons, dus ze zijn de snelste manier om gameplay te tonen en een eerste play te winnen. Afbeeldingen zijn PNG en video’s MP4.

## Vertaal de gamepagina nauwkeurig

Publiceer altijd Engels plus je eigen taal als die anders is. Zet `sourceLocale` op de oorspronkelijke taal. `listingLocalizations` ondersteunt Engels, Frans, Duits, Spaans, Braziliaans Portugees, Indonesisch, Japans, Koreaans, Traditioneel Chinees en Vereenvoudigd Chinees. Elke vertaling heeft `locale` en `displayName` nodig; als je hem samen met de bron uploadt, vult PlayDrop `sourceHash` in. Upload vertaalde art onder `listing/locales/<locale>/`, bijvoorbeeld `listing/locales/fr/hero-landscape.png` met de Franse titel; die wordt automatisch aan zijn vertaling gekoppeld. Ververs vertalingen na wijzigingen in de bron. Het vertalen van de gamepagina vertaalt de game zelf niet.

## Spelers, groepen en controllers

Geef op hoe je game wordt gespeeld met `types`, `party`, `controller` en `roomVoice` bij elk game-item:

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

`types` combineert `solo` (alleen speelbaar), `online` (met anderen gespeeld via het netwerk) en `party` (een groep die samen speelt). `party.local` noemt de exacte aantallen mensen die op één scherm kunnen spelen; `party.online` noemt de groottes van vriendengroepen, tot 4, die samen online kunnen binnenkomen, niet de capaciteit van de room. Groottes zijn exact: `[2, 4]` sluit 3 uit. `party` vereist het type `party`, `party.online` vereist `online` en een 1 in `party.local` vereist `solo`. `roomVoice: true` zet roomspraak aan en vereist `online`.

`controller.support` is `off` (de standaard als `controller` ontbreekt), `optional` of `required`. Als het niet `off` is, noemt `controller.type` de minimale besturing die de game nodig heeft:

- `any`: richtingen, Confirm en Cancel; elke controller werkt, ook afstandsbedieningen.
- `simpler`: één analoge stick, vier hoofdknoppen en Menu; PlayDrop-telefooncontrollers en standaardgamepads voldoen.
- `standard`: D-pad, twee indrukbare sticks, vier hoofdknoppen, twee schouderknoppen, twee triggers en Menu.
- `custom`: gereserveerd voor gamespecifieke telefoonbesturing; nog niet beschikbaar.

Met controllerondersteuning aan moet elk opgegeven lokaal aantal met controllers speelbaar zijn; lees controllerinvoer via de [SDK](https://www.playdrop.ai/nl/create/learn/sdk). Bestaande games mogen `players` en `controllerMode` houden, die werken nog, maar nieuwe games gebruiken deze velden en één item kan niet beide mengen. De host kiest lokaal of online spelen, nooit beide. Deze opgaven blijven behouden bij uploads via Cloud, CLI en MCP, bewaarde privéversies en publicatie. Beschikbaarheid hangt ook af van de uitrol op het platform en de hostbuild.

Lever voor MCP-serveruploads een gebouwde ESM-bundel `.mjs`/`.js` aan als `SERVER`-descriptor en laat `server.entry` ernaar wijzen. Bronprojecten voor Cloud/CLI behouden hun TypeScript-startpunt. PlayDrop levert de Colyseus- en server-SDK-runtime; neem nooit inloggegevens van spraakaanbieders op in een game.
