# Empacote um jogo do PlayDrop com catalogue.json e .play

Organize uma pasta, ZIP ou .play compilado com o catalogue.json na raiz, declare a mídia da listagem e os servidores e envie com prepare_catalogue_upload.

Source: https://www.playdrop.ai/pt-br/create/learn/packaging

Um pacote é o resultado compilado de um jogo mais um `catalogue.json` que o descreve. É o caminho para todos os recursos do PlayDrop: vários arquivos, o SDK, imagens e vídeos da listagem, placares, conquistas, assets e um servidor hospedado. Envie-o pelo seu app de IA como uma pasta, um ZIP ou um arquivo `.play`.

## Organize a pasta

Coloque o `catalogue.json` na raiz, ao lado do jogo compilado. Os caminhos no catálogo são relativos a ele.

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

Um arquivo `.play` é esta pasta compactada em ZIP, com o `catalogue.json` na raiz do arquivo, e não dentro de uma pasta extra, e renomeada para `.play`. Ele contém só arquivos compilados: nada de `node_modules`, de mapas de código-fonte que você não quer tornar públicos ou de arquivos `.env`. O projeto-fonte fica com a pessoa com quem você trabalha; o PlayDrop não pode devolvê-lo.

## Escreva o 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` é o caminho exato da página que inicia o jogo. Sem ele, o padrão da entrada é `<name>.html`, e não `index.html`.
- `version` é uma nova versão semântica a cada envio do mesmo jogo.
- `surfaceTargets` lista as superfícies que você testou; `primarySurface` é aquela para a qual o jogo foi pensado.
- A mídia da listagem, os ícones das conquistas e a entrada do servidor são reivindicados pelo catálogo: um arquivo em `listing/` que nenhum campo referencia não é mídia da listagem, e os arquivos que nenhum app reivindica são recusados antes de qualquer publicação.
- `server.entry` aponta para um único módulo ES compilado e empacotado; veja [servidores de jogo em tempo real](https://www.playdrop.ai/pt-br/create/learn/game-servers).

Todos os campos e seus limites estão na [referência do catalogue.json](https://www.playdrop.ai/pt-br/create/learn/catalogue-json). Não há campo de versão do catálogo para definir.

## Envie uma pasta

Envie `prepare_catalogue_upload` com um novo `requestId`, `expectedCurrentVersion` (`null` para um jogo novo), o objeto completo do catálogo e um descritor por arquivo. Arquivos de texto pequenos podem ir como `text` embutido. Todos os outros arquivos são envios assinados: calcule localmente o tamanho, o SHA-256 (64 caracteres hexadecimais minúsculos) e o MD5 em base64 a partir dos bytes exatos. Esta solicitação para um jogo de dois arquivos está completa; substitua os dois marcadores de resumo do ícone pelos valores reais dele.

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

A resposta lista uma URL de envio e os cabeçalhos para `listing/icon.png`. Faça o PUT dos bytes exatos do ícone nessa URL, com todos os cabeçalhos retornados, e depois chame `complete_catalogue_upload` com o mesmo `requestId`. A `url` do recibo abre a versão privada.

## Envie um ZIP ou .play

- **Agentes com sistema de arquivos** descompactam o arquivo localmente e o enviam como pasta, como acima.
- **O ChatGPT** passa como `archive` o arquivo compactado que resolveu a partir da conversa, com os `download_url` e `file_id` reais, sem `catalogue` nem `files`. O arquivo pode ter até 20 MiB compactado.

Os arquivos compactados precisam ser ZIPs comuns: sem criptografia, vários volumes, ZIP64, links simbólicos, caminhos duplicados, caminhos absolutos ou `..`. Arquivos vazios e arquivos catalogue.json aninhados são recusados.

## Limites

512 arquivos ou entradas do arquivo compactado (incluindo o catalogue.json e os diretórios), 50 MiB por arquivo, 200 MiB descompactados e 1 MiB de JSON do catálogo. O módulo empacotado de um servidor hospedado tem no máximo 2 MiB.

## Atualize um pacote

Leia `list_games`, mantenha o `name` de cada app, aumente a `version` dele e defina `expectedCurrentVersion` como a versão publicada atual. Envie a versão completa: todos os arquivos e campos que a nova versão deve ter. Os arquivos sem alterações de uma versão mantida podem ser enviados com `reuse: { gameId, version, path }` em vez dos bytes. As chaves de placares e conquistas não podem ser removidas nem mudar de tipo; aposente uma delas com `"status": "RETIRED"`.

## Assets que o conector ainda não consegue enviar

O PlayDrop roda modelos 3D executáveis (assets `MODEL_3D` com a subcategoria `procedural` ou o formato `CUSTOM`) nas próprias ferramentas, mas o conector os recusa porque a API não consegue validar o código deles. Converta-os em arquivos fixos (bake) em um formato compatível ou faça referência a um asset já publicado no PlayDrop. Imagens e spritesheets procedurais já convertidas são aceitas. Veja [assets de jogo](https://www.playdrop.ai/pt-br/create/learn/game-assets).

## Guias relacionados

- [catalogue.json](https://www.playdrop.ai/pt-br/create/learn/catalogue-json): Os campos do catalogue.json que os jogos do PlayDrop usam: identidade, listagem, modos de jogo, superfícies, login, Instantâneo, pré-carregamento, mídia, traduções, pontuações e servidores.
- [Publicar pelo seu app de IA](https://www.playdrop.ai/pt-br/create/learn/mcp-publishing): Como agentes de IA publicam no PlayDrop por MCP: caminho simples e de pacote, testes privados, publish_game_version, atualizações, limites e recuperação.
- [Arte e vídeo da listagem](https://www.playdrop.ai/pt-br/create/learn/listing-assets): Imagens e vídeos da listagem no PlayDrop: caminhos, formatos e orientações, e como criar arte que funcione em feeds, na busca e em prévias de links.
- [Servidores em tempo real](https://www.playdrop.ai/pt-br/create/learn/game-servers): Rode um servidor Colyseus 0.17 hospedado com um banco MongoDB para o seu jogo, conecte o navegador com o SDK, teste com dois jogadores e conheça os limites.
