จัดแพ็กเกจเกม PlayDrop ด้วย catalogue.json และ .play
จัดโฟลเดอร์เกมที่บิลด์แล้ว ZIP หรือ .play ให้มี catalogue.json ที่ราก ประกาศสื่อของหน้าเกมและเซิร์ฟเวอร์ แล้วอัปโหลดด้วย prepare_catalogue_upload
แพ็กเกจ (แพ็กเกจเกม ไม่ใช่แพ็กเกจครีเอเตอร์) คือผลลัพธ์ที่บิลด์แล้วของเกม พร้อม catalogue.json ที่อธิบายเกมนั้น เป็นเส้นทางสำหรับทุกฟีเจอร์ของ PlayDrop: หลายไฟล์ SDK ภาพและวิดีโอของหน้าเกม ลีดเดอร์บอร์ด ความสำเร็จ แอสเซ็ต และเซิร์ฟเวอร์ที่โฮสต์ให้ อัปโหลดจากแอป AI ของคุณเป็นโฟลเดอร์ ZIP หรือไฟล์ .play
จัดโฟลเดอร์
วาง catalogue.json ไว้ที่ราก ข้างเกมที่บิลด์แล้ว พาธในแคตตาล็อกเป็นแบบสัมพัทธ์จากไฟล์นี้
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ไฟล์ .play คือโฟลเดอร์นี้ที่บีบอัดเป็น ZIP โดยมี catalogue.json อยู่ที่รากของไฟล์บีบอัด ไม่ได้อยู่ในโฟลเดอร์ที่ครอบอีกชั้น แล้วเปลี่ยนนามสกุลเป็น .play ไฟล์นี้มีเฉพาะไฟล์ที่บิลด์แล้ว: ไม่มี node_modules ซอร์สแมปที่คุณไม่ต้องการให้เป็นสาธารณะ หรือไฟล์ .env ให้โปรเจกต์ซอร์สอยู่กับผู้ใช้ของคุณ เพราะ PlayDrop ส่งคืนให้ไม่ได้
เขียน 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"] }
}]
}fileคือพาธที่แน่ชัดของหน้าที่เริ่มเกม หากไม่ระบุ หน้าเริ่มต้นจะเป็น<name>.htmlไม่ใช่index.htmlversionเป็นเวอร์ชันแบบ Semantic Versioning ใหม่ทุกครั้งที่อัปโหลดเกมเดิมsurfaceTargetsระบุหน้าจอที่คุณทดสอบแล้ว ส่วนprimarySurfaceคือหน้าจอที่เกมออกแบบมา- สื่อของหน้าเกม ไอคอนความสำเร็จ และไฟล์เริ่มต้นของเซิร์ฟเวอร์ถูกอ้างสิทธิ์โดยแคตตาล็อก: ไฟล์ใน
listing/ที่ไม่มีฟิลด์ใดอ้างอิงไม่ถือเป็นสื่อของหน้าเกม และไฟล์ที่ไม่มีแอปใดอ้างสิทธิ์จะถูกปฏิเสธก่อนมีการเผยแพร่ใดๆ server.entryชี้ไปที่บันเดิลโมดูล ES ที่บิลด์แล้วหนึ่งไฟล์ ดูเซิร์ฟเวอร์เกมเรียลไทม์
ทุกฟิลด์และขีดจำกัดอยู่ในเอกสารอ้างอิง catalogue.json ไม่มีฟิลด์เวอร์ชันของแคตตาล็อกที่ต้องตั้ง
อัปโหลดโฟลเดอร์
ส่ง prepare_catalogue_upload พร้อม requestId ใหม่ expectedCurrentVersion (null สำหรับเกมใหม่) ออบเจ็กต์แคตตาล็อกฉบับสมบูรณ์ และตัวอธิบายหนึ่งรายการต่อไฟล์ ไฟล์ข้อความขนาดเล็กใส่เป็น text แบบอินไลน์ได้ ไฟล์อื่นทั้งหมดเป็นการอัปโหลดแบบมีลายเซ็น: คำนวณขนาด SHA-256 (เลขฐานสิบหกตัวพิมพ์เล็ก 64 ตัว) และ MD5 แบบ base64 ในเครื่องจากไบต์ที่ตรงกันทุกประการ คำขอนี้สำหรับเกมสองไฟล์ครบถ้วนแล้ว ให้แทนที่ตัวยึดตำแหน่งของค่าแฮชสองตัวในไอคอนด้วยค่าจริงของไอคอน
{
"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" }
]
}คำตอบจะมี URL สำหรับอัปโหลดและเฮดเดอร์ของ listing/icon.png PUT ไบต์ของไอคอนที่ตรงกันทุกประการไปที่ URL นั้นพร้อมทุกเฮดเดอร์ที่ได้รับ แล้วเรียก complete_catalogue_upload ด้วย requestId เดิม url ในใบยืนยันจะเปิดเวอร์ชันส่วนตัว
อัปโหลด ZIP หรือ .play
- เอเจนต์ที่มีระบบไฟล์ แตกไฟล์บีบอัดในเครื่องแล้วอัปโหลดเป็นโฟลเดอร์ตามด้านบน
- ChatGPT ส่งไฟล์บีบอัดที่ระบุได้จากบทสนทนาเป็น
archiveพร้อมdownload_urlและfile_idจริง โดยไม่มีcatalogueหรือfilesไฟล์บีบอัดมีขนาดได้สูงสุด 20 MiB เมื่อบีบอัด
ไฟล์บีบอัดต้องเป็นไฟล์ ZIP ธรรมดา: ไม่มีการเข้ารหัส ไม่แบ่งหลายส่วน ไม่ใช่ ZIP64 ไม่มีลิงก์สัญลักษณ์ พาธซ้ำ พาธแบบสัมบูรณ์ หรือ .. ไฟล์ว่างและ catalogue.json ที่ซ้อนอยู่ในโฟลเดอร์จะถูกปฏิเสธ
ขีดจำกัด
ไฟล์หรือรายการในไฟล์บีบอัด 512 รายการ (รวม catalogue.json และไดเรกทอรี) 50 MiB ต่อไฟล์ 200 MiB เมื่อแตกไฟล์ และ JSON ของแคตตาล็อก 1 MiB บันเดิลเซิร์ฟเวอร์ที่โฮสต์ให้มีขนาดไม่เกิน 2 MiB
อัปเดตแพ็กเกจ
อ่าน list_games คง name ของแต่ละแอปไว้ เพิ่ม version และตั้ง expectedCurrentVersion เป็นเวอร์ชันที่เผยแพร่ปัจจุบัน ส่งสแนปช็อตเต็ม: ทุกไฟล์และทุกฟิลด์ที่เวอร์ชันใหม่ควรมี ไฟล์ที่ไม่เปลี่ยนจากเวอร์ชันที่เก็บไว้ส่งด้วย reuse: { gameId, version, path } แทนไบต์ของไฟล์ได้ คีย์ลีดเดอร์บอร์ดและความสำเร็จลบไม่ได้และเปลี่ยนชนิดไม่ได้ ให้เลิกใช้ด้วย "status": "RETIRED"
แอสเซ็ตที่คอนเนกเตอร์ยังอัปโหลดไม่ได้
PlayDrop รันโมเดล 3D ที่รันโค้ดได้ (แอสเซ็ต MODEL_3D ที่มีหมวดย่อย procedural หรือรูปแบบ CUSTOM) ในเครื่องมือของตัวเอง แต่คอนเนกเตอร์จะปฏิเสธ เพราะ API ตรวจสอบโค้ดของโมเดลเหล่านี้ไม่ได้ ให้แปลงเป็นรูปแบบที่รองรับ หรืออ้างอิงแอสเซ็ตที่เผยแพร่บน PlayDrop แล้ว ภาพและสไปรต์ชีตแบบโพรซีเจอรัลที่แปลงเป็นไฟล์สำเร็จรูปแล้วรับได้ ดูแอสเซ็ตเกม