Créer le paquet d’un jeu PlayDrop avec catalogue.json et .play
Organisez un dossier, ZIP ou .play compilé avec catalogue.json à la racine, déclarez médias de fiche et serveurs, puis envoyez avec prepare_catalogue_upload.
Un paquet, c’est le résultat compilé d’un jeu accompagné d’un catalogue.json qui le décrit. C’est la voie pour toutes les fonctionnalités de PlayDrop : plusieurs fichiers, le SDK, les images et vidéos de fiche, les classements, les succès, les ressources et un serveur hébergé. Envoyez-le depuis votre app d’IA sous forme de dossier, de ZIP ou de fichier .play.
Organisez le dossier
Placez catalogue.json à la racine, à côté du jeu compilé. Les chemins du catalogue sont relatifs à ce fichier.
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.mjsUn fichier .play est ce dossier compressé en ZIP avec catalogue.json à la racine de l’archive, et non dans un dossier englobant, puis renommé en .play. Il ne contient que des fichiers compilés : pas de node_modules, pas de fichiers de mappage source que vous ne voulez pas rendre publics, pas de fichiers .env. Laissez le projet source à la personne que vous aidez ; PlayDrop ne peut pas le restituer.
Rédigez catalogue.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"] }
}]
}fileest le chemin exact de la page qui démarre le jeu. Sans ce champ, l’entrée est par défaut<name>.html, et nonindex.html.versionest une nouvelle version sémantique à chaque envoi du même jeu.surfaceTargetsliste les surfaces que vous avez testées ;primarySurfaceest celle pour laquelle le jeu est conçu.- Les médias de fiche, les icônes de succès et l’entrée du serveur sont rattachés au catalogue : un fichier sous
listing/qu’aucun champ ne référence n’est pas un média de fiche, et les fichiers qu’aucune app ne revendique sont refusés avant toute publication. server.entrydésigne un seul bundle de module ES compilé ; consultez serveurs de jeu temps réel.
Tous les champs et leurs limites figurent dans la référence catalogue.json. Il n’y a aucun champ de version du catalogue à définir.
Envoyez un dossier
Appelez prepare_catalogue_upload avec un nouveau requestId, expectedCurrentVersion (null pour un nouveau jeu), l’objet catalogue complet et un descripteur par fichier. Les petits fichiers texte peuvent être intégrés avec text. Tous les autres fichiers sont des envois signés : calculez en local leur taille, leur SHA-256 (64 caractères hexadécimaux en minuscules) et leur MD5 en base64 à partir des octets exacts. Cette requête pour un jeu à deux fichiers est complète ; remplacez les deux valeurs d’empreinte provisoires de l’icône par ses vraies valeurs.
{
"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 réponse indique une URL d’envoi et des en-têtes pour listing/icon.png. Envoyez-y par PUT les octets exacts de l’icône avec tous les en-têtes renvoyés, puis appelez complete_catalogue_upload avec le même requestId. L’url du reçu ouvre la version privée.
Envoyez un ZIP ou un .play
- Les agents qui ont accès à un système de fichiers décompressent l’archive en local et l’envoient comme un dossier, comme ci-dessus.
- ChatGPT passe dans
archivel’archive qu’il a résolue depuis la conversation, avec ses vraisdownload_urletfile_id, sanscataloguenifiles. L’archive peut faire jusqu’à 20 MiB compressée.
Les archives doivent être des fichiers ZIP ordinaires : pas de chiffrement, de volumes multiples, de ZIP64, de liens symboliques, de chemins en double, de chemins absolus ni de ... Les fichiers vides et les fichiers catalogue.json imbriqués sont refusés.
Limites
512 fichiers ou entrées d’archive (catalogue.json et répertoires compris), 50 MiB par fichier, 200 MiB décompressés et 1 MiB de JSON de catalogue. Le bundle d’un serveur hébergé fait 2 MiB au maximum.
Mettez à jour un paquet
Consultez list_games, conservez le name de chaque app, augmentez sa version et définissez expectedCurrentVersion sur la version publiée actuelle. Envoyez une copie complète : chaque fichier et chaque champ que la nouvelle version doit avoir. Les fichiers inchangés d’une version conservée peuvent être envoyés avec reuse: { gameId, version, path } au lieu de leurs octets. Les clés des classements et des succès ne peuvent être ni supprimées ni changer de type ; retirez-en une avec "status": "RETIRED".
Ressources que le connecteur ne peut pas encore envoyer
PlayDrop exécute les modèles 3D exécutables (ressources MODEL_3D de sous-catégorie procedural ou au format CUSTOM) dans ses propres outils, mais le connecteur les refuse, car l’API ne peut pas valider leur code. Figez-les dans un format pris en charge, ou référencez une ressource déjà publiée sur PlayDrop. Les images et feuilles de sprites procédurales figées sont acceptées. Consultez ressources de jeu.