# catalogue.json: ข้อมูลเมตาและการแปลของเกม PlayDrop

เอกสารอ้างอิงสำหรับชื่อเกม คำอธิบาย แท็กประเภท ภาพและวิดีโอของหน้าเกม คำแปล และฟิลด์เซิร์ฟเวอร์แบบไม่บังคับในรูปแบบ PlayDrop Connector

Source: https://www.playdrop.ai/th/create/learn/catalogue-json

[PlayDrop Connector](https://www.playdrop.ai/th/create/connectors) ส่งข้อมูลเมตา `catalogue.json` ของคุณไปพร้อมกับไฟล์เกม ไม่ต้องใช้เครื่องมือบรรทัดคำสั่ง PlayDrop Cloud ดูแลข้อมูลเมตานี้ให้เกม Studio

## อัปโหลดส่วนตัวแบบสมบูรณ์ด้วย prepare_catalogue_upload

นี่คือคำขอ `prepare_catalogue_upload` แบบสมบูรณ์สำหรับเกมส่วนตัวใหม่ แทนที่ HTML ตัวอย่างด้วยเกมที่คุณสร้างไว้ และใช้ `requestId` ที่ไม่ซ้ำกันสำหรับการอัปโหลดแต่ละครั้ง ออบเจ็กต์ `catalogue` คือเนื้อหาของ `catalogue.json` ส่วน `files` และ `expectedCurrentVersion` เป็นของคำขอเครื่องมือ อยู่นอกออบเจ็กต์นั้น

```json
{
  "requestId": "my-game-v1-unique-request",
  "catalogue": {
    "apps": [
      {
        "name": "my-game",
        "displayName": "My Game",
        "file": "index.html",
        "version": "1.0.0",
        "visibility": "PRIVATE",
        "authMode": "OPTIONAL",
        "surfaceTargets": {
          "desktop": true,
          "mobileLandscape": false,
          "mobilePortrait": false
        }
      }
    ]
  },
  "expectedCurrentVersion": {
    "my-game": null
  },
  "files": [
    {
      "path": "index.html",
      "text": "<!doctype html><html><head><title>My Game</title></head><body><button onclick=\"this.textContent=Number(this.textContent)+1\">0</button></body></html>"
    }
  ]
}
```

`apps[].file` ต้องตรงกับ `files[].path` ทุกตัวอักษร หากไม่ระบุ `file` รายการจะใช้ค่าเริ่มต้นเป็น `<name>.html` ไม่ใช่ `index.html` `surfaceTargets` เป็นออบเจ็กต์ที่มีค่าบูลีน `desktop`, `mobileLandscape` และ `mobilePortrait` เปิดอย่างน้อยหนึ่งแบบที่คุณทดสอบแล้ว ระบุเวอร์ชันและการมองเห็นอย่างชัดเจน ตัวอย่างใช้ไฟล์ข้อความแบบอินไลน์ ไฟล์แนบหรือการอัปโหลดไบต์แบบมีลายเซ็นใช้พาธเดียวกันได้

หลังเตรียมแล้ว ส่งไบต์ของไฟล์ที่ขอ และเรียก `complete_catalogue_upload` ด้วย `requestId` เดิม เปิดเวอร์ชันส่วนตัวเพื่อทดสอบ สำหรับการอัปเดต อ่าน `list_games` คง `name` เดิม ระบุ `version` ใหม่และสแนปช็อตเต็ม และตั้ง `expectedCurrentVersion[name]` เป็นเวอร์ชันสาธารณะปัจจุบันที่เซิร์ฟเวอร์ส่งกลับมา (หรือ `null` หากไม่มี) นี่คือการตรวจสอบความขัดแย้ง ไม่ใช่เวอร์ชันที่กำลังอัปโหลด ลองอัปโหลดที่ถูกขัดจังหวะอีกครั้งด้วย ID คำขอเดิม เผยแพร่เวอร์ชันที่ทดสอบและเก็บไว้ด้วย `publish_game_version` เมื่อพร้อม

## ตัวอย่างความเข้ากันได้แบบเกมเดียวรุ่นเก่า

ตัวอย่างด้านล่างเป็นรูปแบบเกมเดียวรุ่นเก่า การอัปโหลดแคตตาล็อกเต็มยังรองรับหลายเกม แอสเซ็ต แพ็ก และสเปกด้วย ถามคอนเนกเตอร์เพื่อดูสคีมาปัจจุบัน การอัปเดตแต่ละครั้งต้องส่งสแนปช็อตเต็มพร้อมการมองเห็นและเวอร์ชันที่ระบุชัดเจน รายการแคตตาล็อกที่ไม่ได้ใส่จะไม่ถูกลบ

คง slug ตัวพิมพ์เล็กให้คงที่เมื่ออัปเดต เพิ่มชื่อที่แสดง คำอธิบายที่ถูกต้อง การควบคุม ภาษาต้นฉบับ และแท็กที่รู้จักตามต้องการ ตัวอย่างด้านล่างใช้แท็กประเภทแพลตฟอร์มเมอร์ที่มีอยู่

```json
{
  "apps": [{
    "name": "moon-jump",
    "displayName": "Moon Jump",
    "description": "Jump between lunar platforms and reach the finish.",
    "controls": "Arrow keys to move. Space to jump.",
    "sourceLocale": "en",
    "tags": ["game-genre/platformer"]
  }]
}
```

## ฟิลด์ที่รองรับและขีดจำกัด

`name`: ตัวอักษรพิมพ์เล็ก ตัวเลข หรือขีดกลาง 1–100 ตัว ขึ้นต้นด้วยตัวอักษรหรือตัวเลข `displayName`: ชื่อที่ไม่ว่าง `subtitle`: ไม่เกิน 120 ตัวอักษร `description`: Markdown ไม่เกิน 3,000 ตัวอักษร โดยไม่มีหัวข้อ H1 สื่อฝัง หรือตาราง `inspirationPrompt`: ข้อความธรรมดาบรรทัดเดียวไม่เกิน 400 ตัวอักษร ขีดจำกัดข้อความนับเป็นหน่วยโค้ด UTF-16 ของ JavaScript

ฟิลด์ที่ไม่บังคับได้แก่ `controls`, `releaseNotes`, `makingOf`, `emoji`, `color`, `sourceRepository`, `license`, `tags`, `sourceLocale`, `listingLocalizations`, `listingMedia` และ `server` แท็กใช้การอ้างอิง `group-slug/tag-slug` ที่มีอยู่ ไม่เกิน 20 แท็กที่ไม่ซ้ำกัน `server` ระบุห้อง Colyseus ของ `server.js` ที่อัปโหลด เช่น `"server": { "rooms": ["game"] }` ดู [SDK ฝั่งเซิร์ฟเวอร์](https://www.playdrop.ai/th/create/learn/server-sdk) ถามคอนเนกเตอร์เพื่อดูค่าสัญญาอนุญาตที่ยอมรับในปัจจุบันและกฎของฟิลด์ทั้งหมดก่อนเผยแพร่ คำแนะนำสำหรับแอปเนทีฟแบบไม่บังคับ: `prefetch` ระบุไฟล์ที่อัปโหลดซึ่งแอป PlayDrop บน iOS, macOS และ Android ดาวน์โหลดได้ก่อนเล่น เช่น `"prefetch": { "required": ["game.js"], "optional": ["music.mp3"] }` (หน้าเริ่มต้นรวมอยู่เสมอ) และ `"offlineSupported": true` ให้แอปเหล่านั้นเสนอการเล่นเกมแบบออฟไลน์เมื่อเก็บไฟล์ที่จำเป็นแล้ว ค่าที่ไม่ถูกต้องจะถูกละเว้นและไม่ขัดขวางการอัปโหลด เว็บไซต์โหลดเกมตามปกติ

เกม Instant: ตั้ง `"instant": true` เมื่อเกมเล่นได้ภายใน 2 วินาทีจากไฟล์เริ่มต้นไม่เกิน 10 MB (หน้าเริ่มต้นบวก `prefetch.required` หรือทุกไฟล์ที่อัปโหลดเมื่อไม่ได้ระบุ) เกม Instant มีป้ายสายฟ้าและเล่นในฟีด Instant ของแอป PlayDrop บนโทรศัพท์ ใส่ด่านที่ลึกขึ้นและส่วนเสริมใน `prefetch.optional` ทำการคอมไพล์เชเดอร์และการอุ่นเครื่องอื่นให้เสร็จก่อนเรียก `ready()` ทำให้ตัวอย่างแสดงเกมเพลย์ไม่ใช่หน้าจอชื่อเรื่อง และอนุญาตผู้เยี่ยมชม (`authMode` เป็น `OPTIONAL` หรือ `NONE`) เพื่อให้ทุกคนเห็นเกมในฟีด PlayDrop ตรวจสอบขนาดตอนอัปโหลดและถอนป้ายจากเวอร์ชันที่โทรศัพท์เริ่มช้า เกมที่ไม่ผ่านเกณฑ์ยังคงถูกเผยแพร่

## ภาพและวิดีโอของหน้าเกม

อัปโหลดสื่อของหน้าเกมเป็นไฟล์ข้าง `index.html` ตั้งชื่อตามพาธ: `listing/icon.png`, `listing/hero-landscape.png` (16:9) และ `listing/hero-portrait.png` (9:16) โดยมีชื่อเกมอยู่ในภาพ ภาพหน้าจอ เช่น `listing/screenshots/landscape/0.png` และวิดีโอ `listing/videos/landscape/0.mp4` (ตัวอย่างหนัง) และ `listing/videos/portrait/0.mp4` (ทีเซอร์สำหรับมือถือ) วิดีโอเล่นแบบไม่มีเสียงบนการ์ดเกมและหน้าเกม ตัวอย่างหนังบนคอมพิวเตอร์และทีวี และทีเซอร์บนโทรศัพท์ จึงเป็นวิธีที่เร็วที่สุดในการแสดงเกมเพลย์และดึงการเล่นครั้งแรก ภาพเป็น PNG และวิดีโอเป็น MP4

## แปลหน้าเกมอย่างถูกต้อง

เผยแพร่ภาษาอังกฤษพร้อมภาษาของคุณเองเสมอเมื่อต่างกัน ตั้ง `sourceLocale` เป็นภาษาต้นฉบับ `listingLocalizations` รองรับภาษาอังกฤษ ฝรั่งเศส เยอรมัน สเปน โปรตุเกสบราซิล อินโดนีเซีย ญี่ปุ่น เกาหลี จีนตัวเต็ม และจีนตัวย่อ แต่ละคำแปลต้องมี `locale` และ `displayName` เมื่ออัปโหลดพร้อมต้นฉบับ PlayDrop จะกรอก `sourceHash` ให้ อัปโหลดภาพที่แปลแล้วไว้ใต้ `listing/locales/<locale>/` เช่น `listing/locales/fr/hero-landscape.png` พร้อมชื่อภาษาฝรั่งเศส ระบบจะจับคู่กับคำแปลโดยอัตโนมัติ รีเฟรชคำแปลหลังต้นฉบับเปลี่ยน การแปลหน้าเกมไม่ได้แปลตัวเกม

## ผู้เล่น ปาร์ตี้ และคอนโทรลเลอร์

ประกาศวิธีเล่นเกมของคุณด้วย `types`, `party`, `controller` และ `roomVoice` ในรายการเกมแต่ละรายการ:

```json
{
  "types": ["solo", "online", "party"],
  "party": { "local": [1, 2, 3, 4], "online": [1, 2, 3, 4] },
  "controller": { "support": "optional", "type": "simpler" },
  "roomVoice": true
}
```

`types` รวม `solo` (เล่นคนเดียวได้) `online` (เล่นกับผู้อื่นผ่านเครือข่าย) และ `party` (กลุ่มเล่นด้วยกัน) `party.local` ระบุจำนวนคนที่เล่นบนหน้าจอเดียวได้อย่างแน่ชัด `party.online` ระบุขนาดกลุ่มเพื่อน สูงสุด 4 ที่เข้าสู่การเล่นออนไลน์ด้วยกันได้ ไม่ใช่ความจุห้อง ขนาดต้องตรงเป๊ะ: `[2, 4]` ไม่รวม 3 `party` ต้องมีประเภท `party`, `party.online` ต้องมี `online` และเลข 1 ใน `party.local` ต้องมี `solo` `roomVoice: true` เปิดแชทเสียงของห้องและต้องมี `online`

`controller.support` เป็น `off` (ค่าเริ่มต้นเมื่อไม่ระบุ `controller`) `optional` หรือ `required` เมื่อไม่ใช่ `off` `controller.type` ระบุการควบคุมขั้นต่ำที่เกมต้องใช้:

- `any`: ทิศทาง ยืนยัน และยกเลิก; ทุกคอนโทรลเลอร์ใช้ได้ รวมถึงรีโมต
- `simpler`: อนาล็อกสติ๊กหนึ่งตัว ปุ่มหน้าสี่ปุ่ม และเมนู; คอนโทรลเลอร์บนโทรศัพท์ของ PlayDrop และเกมแพดมาตรฐานเข้าเกณฑ์
- `standard`: D-pad สติ๊กกดได้สองตัว ปุ่มหน้าสี่ปุ่ม ปุ่มไหล่สองปุ่ม ทริกเกอร์สองตัว และเมนู
- `custom`: สงวนไว้สำหรับการควบคุมบนโทรศัพท์เฉพาะเกม ยังใช้ไม่ได้

เมื่อเปิดรองรับคอนโทรลเลอร์ ทุกจำนวนผู้เล่นในเครื่องที่ประกาศต้องเล่นด้วยคอนโทรลเลอร์ได้ อ่านอินพุตคอนโทรลเลอร์ผ่าน [SDK](https://www.playdrop.ai/th/create/learn/sdk) เกมที่มีอยู่อาจคง `players` และ `controllerMode` ไว้ ซึ่งยังทำงานอยู่ แต่เกมใหม่ใช้ฟิลด์เหล่านี้ และหนึ่งรายการผสมทั้งสองแบบไม่ได้ โฮสต์เลือกการเล่นในเครื่องหรือออนไลน์ ไม่ใช่ทั้งสองอย่าง การประกาศเหล่านี้คงอยู่ผ่านการอัปโหลดจาก Cloud, CLI และ MCP เวอร์ชันส่วนตัวที่เก็บไว้ และการเผยแพร่ ความพร้อมใช้งานยังขึ้นกับการเปิดตัวของแพลตฟอร์มและบิลด์ของโฮสต์

สำหรับการอัปโหลดเซิร์ฟเวอร์ MCP ให้ส่งบันเดิล ESM `.mjs`/`.js` ที่สร้างแล้วเป็นตัวบรรยาย `SERVER` และชี้ `server.entry` ไปที่ไฟล์นั้น โปรเจกต์ซอร์สสำหรับ Cloud/CLI คงจุดเข้า TypeScript ไว้ PlayDrop จัดหารันไทม์ Colyseus และ SDK ฝั่งเซิร์ฟเวอร์ ห้ามใส่ข้อมูลรับรองผู้ให้บริการเสียงในเกมเด็ดขาด

