# Empaqueta un juego de PlayDrop con catalogue.json y .play

Organiza una carpeta, ZIP o .play compilado con catalogue.json en la raíz, declara medios de la ficha y servidores, y súbelo con prepare_catalogue_upload.

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

Un paquete es el resultado compilado de un juego más un `catalogue.json` que lo describe. Es la vía para todas las funciones de PlayDrop: varios archivos, el SDK, imágenes y vídeos de la ficha, clasificaciones, logros, recursos y un servidor alojado. Súbelo desde tu app de IA como carpeta, como ZIP o como archivo `.play`.

## Organiza la carpeta

Pon `catalogue.json` en la raíz, junto al juego compilado. Las rutas del catálogo son relativas a él.

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

Un archivo `.play` es esta carpeta comprimida en ZIP con `catalogue.json` en la raíz del archivo, no dentro de una carpeta contenedora, y renombrada a `.play`. Solo contiene archivos compilados: ni `node_modules`, ni mapas de código fuente que no quieras hacer públicos, ni archivos `.env`. El proyecto fuente se queda con tu usuario; PlayDrop no puede devolverlo.

## Escribe 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` es la ruta exacta de la página que inicia el juego. Sin ella, la entrada es `<name>.html` por defecto, no `index.html`.
- `version` es una nueva versión semántica en cada subida del mismo juego.
- `surfaceTargets` enumera las pantallas que has probado; `primarySurface` es aquella para la que está diseñado el juego.
- Las imágenes y vídeos de la ficha, los iconos de los logros y la entrada del servidor los reclama el catálogo: un archivo dentro de `listing/` al que ningún campo hace referencia no forma parte de la ficha, y los archivos que ninguna app reclama se rechazan antes de publicar nada.
- `server.entry` apunta a un único módulo ES compilado; consulta [servidores de juego en tiempo real](https://www.playdrop.ai/es/create/learn/game-servers).

Todos los campos y sus límites están en la [referencia de catalogue.json](https://www.playdrop.ai/es/create/learn/catalogue-json). No hay que indicar ningún campo de versión del catálogo.

## Sube una carpeta

Envía `prepare_catalogue_upload` con un nuevo `requestId`, `expectedCurrentVersion` (`null` para un juego nuevo), el objeto completo del catálogo y un descriptor por archivo. Los archivos de texto pequeños pueden ir como `text` en línea. Todos los demás archivos son subidas firmadas: calcula en local su tamaño, su SHA-256 (64 caracteres hexadecimales en minúsculas) y su MD5 en base64 a partir de los bytes exactos. Esta solicitud para un juego de dos archivos está completa; sustituye los dos marcadores de resumen del icono por sus valores reales.

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

La respuesta indica una URL de subida y unas cabeceras para `listing/icon.png`. Haz PUT de los bytes exactos del icono a esa URL con todas las cabeceras devueltas y, después, llama a `complete_catalogue_upload` con el mismo `requestId`. La `url` del recibo abre la versión privada.

## Sube un ZIP o un .play

- **Los agentes con sistema de archivos** descomprimen el archivo en local y lo suben como carpeta, como se explica arriba.
- **ChatGPT** pasa como `archive` el archivo comprimido que resolvió de la conversación, con sus `download_url` y `file_id` reales, y sin `catalogue` ni `files`. El archivo puede ocupar hasta 20 MiB comprimido.

Los archivos comprimidos deben ser ZIP normales: sin cifrado, varios volúmenes, ZIP64, enlaces simbólicos, rutas duplicadas, rutas absolutas ni `..`. Se rechazan los archivos vacíos y los catalogue.json anidados.

## Límites

512 archivos o entradas de archivo comprimido (incluidos catalogue.json y los directorios), 50 MiB por archivo, 200 MiB descomprimidos y 1 MiB de JSON del catálogo. El módulo de un servidor alojado ocupa 2 MiB como máximo.

## Actualiza un paquete

Lee `list_games`, conserva el `name` de cada app, sube su `version` y establece `expectedCurrentVersion` con la versión publicada actual. Envía la instantánea completa: todos los archivos y campos que deba tener la nueva versión. Los archivos sin cambios de una versión conservada se pueden enviar con `reuse: { gameId, version, path }` en lugar de sus bytes. Las claves de las clasificaciones y los logros no se pueden eliminar ni cambiar de tipo; retíralas con `"status": "RETIRED"`.

## Recursos que el conector todavía no puede subir

PlayDrop ejecuta modelos 3D ejecutables (recursos `MODEL_3D` con la subcategoría `procedural` o el formato `CUSTOM`) en sus propias herramientas, pero el conector los rechaza porque la API no puede validar su código. Hornéalos en un formato compatible o haz referencia a un recurso ya publicado en PlayDrop. Se aceptan las imágenes y hojas de sprites procedurales ya horneadas. Consulta [recursos de juego](https://www.playdrop.ai/es/create/learn/game-assets).

## Guías relacionadas

- [catalogue.json](https://www.playdrop.ai/es/create/learn/catalogue-json): Campos de catalogue.json que usan los juegos: identidad, ficha, modos, pantallas, sesión, instantáneo, precarga, medios, idiomas, puntuaciones y servidores.
- [Publicar desde tu app de IA](https://www.playdrop.ai/es/create/learn/mcp-publishing): Cómo publican los agentes de IA en PlayDrop mediante MCP: vía simple y paquete, pruebas privadas, publish_game_version, actualizaciones, límites y errores.
- [Imágenes y vídeo de la ficha](https://www.playdrop.ai/es/create/learn/listing-assets): Qué imágenes y vídeos puede tener la ficha de un juego, rutas, formatos y orientaciones, y cómo crear imágenes eficaces en feeds, búsqueda y enlaces.
- [Servidores en tiempo real](https://www.playdrop.ai/es/create/learn/game-servers): Ejecuta un servidor Colyseus 0.17 alojado con base de datos MongoDB, conéctate desde el navegador con el SDK, prueba con dos jugadores y conoce los límites.
