Đóng gói game PlayDrop với catalogue.json và .play
Sắp xếp thư mục game đã dựng, tệp ZIP hoặc .play có catalogue.json ở thư mục gốc, khai báo media giới thiệu, máy chủ, rồi tải lên bằng prepare_catalogue_upload.
Một gói là bản dựng của game cộng với một catalogue.json mô tả nó. Đây là cách dùng được cho mọi tính năng PlayDrop: nhiều tệp, SDK, hình ảnh và video giới thiệu, bảng xếp hạng, thành tích, tài nguyên và máy chủ được lưu trữ. Hãy tải gói lên từ ứng dụng AI của bạn dưới dạng một thư mục, một tệp ZIP hoặc một tệp .play.
Sắp xếp thư mục
Đặt catalogue.json ở thư mục gốc, cạnh game đã dựng. Các đường dẫn trong catalogue là tương đối so với tệp này.
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.mjsMột tệp .play là thư mục này được nén ZIP với catalogue.json ở gốc tệp nén, không nằm trong một thư mục bao ngoài, rồi đổi đuôi thành .play. Nó chỉ chứa tệp đã dựng: không có node_modules, source map bạn không muốn công khai hay tệp .env. Hãy để người dùng của bạn giữ dự án mã nguồn; PlayDrop không thể trả lại nó.
Viết 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"] }
}]
}filelà đường dẫn chính xác của trang khởi động game. Nếu không có trường này, trang vào mặc định là<name>.html, không phảiindex.html.versionlà một phiên bản ngữ nghĩa mới cho mỗi lần tải lên cùng một game.surfaceTargetsliệt kê các loại màn hình bạn đã thử;primarySurfacelà loại màn hình chính mà game được thiết kế để chơi.- Media giới thiệu, biểu tượng thành tích và tệp vào của máy chủ phải được khai báo trong catalogue: một tệp trong
listing/mà không trường nào tham chiếu thì không phải media giới thiệu, và các tệp không thuộc ứng dụng nào sẽ bị từ chối trước khi bất cứ thứ gì được xuất bản. server.entrytrỏ tới một bundle module ES đã dựng; xem máy chủ game thời gian thực.
Mọi trường và giới hạn của chúng có trong tài liệu tham khảo catalogue.json. Không có trường phiên bản catalogue nào cần đặt.
Tải lên một thư mục
Gửi prepare_catalogue_upload với một requestId mới, expectedCurrentVersion (null cho game mới), toàn bộ đối tượng catalogue và mỗi tệp một bộ mô tả. Các tệp văn bản nhỏ có thể dùng text nội tuyến. Mọi tệp khác là tải lên có chữ ký: hãy tính kích thước, SHA-256 (64 ký tự hex viết thường) và MD5 dạng base64 trên máy từ chính xác các byte của tệp. Yêu cầu dưới đây cho một game hai tệp là hoàn chỉnh; hãy thay hai giá trị giữ chỗ của mã băm trên biểu tượng bằng giá trị thật của biểu tượng.
{
"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" }
]
}Phản hồi liệt kê một URL tải lên và các header cho listing/icon.png. PUT chính xác các byte của biểu tượng lên đó kèm mọi header được trả về, rồi gọi complete_catalogue_upload với cùng requestId. url của biên nhận mở phiên bản riêng tư.
Tải lên tệp ZIP hoặc .play
- Agent có hệ thống tệp giải nén tệp nén trên máy và tải lên dưới dạng thư mục, như trên.
- ChatGPT truyền tệp nén mà nó đã phân giải từ cuộc trò chuyện dưới dạng
archive, vớidownload_urlvàfile_idthật, và không cócataloguehayfiles. Tệp nén có thể lên đến 20 MiB khi nén.
Tệp nén phải là tệp ZIP thông thường: không mã hóa, không chia nhiều phần, không ZIP64, không liên kết tượng trưng, không đường dẫn trùng lặp, không đường dẫn tuyệt đối hay ... Tệp rỗng và các tệp catalogue.json lồng bên trong đều bị từ chối.
Giới hạn
512 tệp hoặc mục trong tệp nén (kể cả catalogue.json và các thư mục), 50 MiB mỗi tệp, 200 MiB khi giải nén và 1 MiB JSON catalogue. Bundle của máy chủ được lưu trữ tối đa 2 MiB.
Cập nhật một gói
Đọc list_games, giữ nguyên name của từng ứng dụng, tăng version của nó và đặt expectedCurrentVersion bằng phiên bản đang xuất bản. Gửi bản chụp đầy đủ: mọi tệp và trường mà phiên bản mới cần có. Các tệp không đổi của một phiên bản được lưu giữ có thể được gửi bằng reuse: { gameId, version, path } thay vì gửi các byte của chúng. Không thể xóa hay đổi loại của khóa bảng xếp hạng và thành tích; hãy ngừng dùng một khóa bằng "status": "RETIRED".
Tài nguyên connector chưa tải lên được
PlayDrop chạy mô hình 3D thực thi được (tài nguyên MODEL_3D có danh mục con procedural hoặc định dạng CUSTOM) trong các công cụ riêng của nó, nhưng connector từ chối chúng vì API không thể xác thực mã của chúng. Hãy bake chúng sang một định dạng được hỗ trợ, hoặc tham chiếu một tài nguyên đã được xuất bản trên PlayDrop. Hình ảnh và spritesheet procedural đã bake vẫn được chấp nhận. Xem tài nguyên game.