# Máy chủ game PlayDrop: Colyseus, MongoDB và SDK server

Chơi nhiều người được lưu trữ cho game PlayDrop: tải lên server.js Colyseus với MongoDB, thử bằng Người chơi thử, và dùng SDK server tùy chọn cho bạn bè và AI.

Source: https://www.playdrop.ai/vi/create/learn/server-sdk

Máy chủ game là tùy chọn. Game của bạn có thể gọi bất kỳ máy chủ nào bạn tự chạy. Nếu muốn, PlayDrop lưu trữ một máy chủ Colyseus chuẩn với cơ sở dữ liệu MongoDB cho game của bạn: hãy tải lên dưới dạng `server.js` cạnh `index.html` qua [PlayDrop Connector](https://www.playdrop.ai/vi/create/connectors), hoặc nhờ [PlayDrop Cloud](https://www.playdrop.ai/vi/create) tạo nó. Gói `@playdrop/server` cũng là tùy chọn.

## Viết một máy chủ Colyseus chuẩn

Xuất một bản đồ `rooms` từ `server.js` và liệt kê tên các phòng của nó trong [catalogue.json](https://www.playdrop.ai/vi/create/learn/catalogue-json) dưới dạng `"server": { "rooms": ["game"] }`. PlayDrop chạy máy chủ, vì vậy đừng tự khởi động một máy chủ. Lưu dữ liệu bằng driver MongoDB chuẩn qua `PLAYDROP_MONGO_URL`, bên trong vòng đời của phòng.

```js
import { Room, defineRoom } from "colyseus";
import { MongoClient } from "mongodb";

class GameRoom extends Room {
  async onCreate() {
    this.mongo = new MongoClient(process.env.PLAYDROP_MONGO_URL);
    await this.mongo.connect();
  }
  onJoin(client) {
    // client.auth is the verified PlayDrop player, for example client.auth.userId.
  }
  async onDispose() { await this.mongo?.close(); }
}

export const rooms = { game: defineRoom(GameRoom) };
```

## Quy tắc máy chủ được lưu trữ

- Colyseus 0.17 (`colyseus` 0.17.10, `@colyseus/schema` 4.0.30), driver MongoDB 7.5 và Node 22.
- Một module ES khép kín tối đa 2 MiB. Nó chỉ được import `colyseus`, `@colyseus/core`, `@colyseus/schema`, `mongodb` và `@playdrop/server`; hãy gộp mọi mã khác vào tệp.
- Tối đa 2 loại phòng, 8 người chơi mỗi phòng, 4 giờ mỗi phòng, 30 tin nhắn mỗi giây cho mỗi người chơi và 512 KiB mỗi tin nhắn.
- Máy chủ không có truy cập internet: chỉ có thể truy cập MongoDB và các dịch vụ của PlayDrop.
- Người chơi phải đăng nhập. PlayDrop xác minh từng người chơi khi họ tham gia; đừng triển khai `onAuth`.
- Một cơ sở dữ liệu MongoDB cho mỗi game, được giữ qua các phiên bản và tính vào hạn mức dung lượng của bạn. Không bao giờ gửi thông tin xác thực của nó đến trình duyệt.

## Kết nối trình duyệt và thử

Trong trình duyệt, `sdk.multiplayer.getConnection()` từ [SDK client](https://www.playdrop.ai/vi/create/learn/sdk) trả về địa chỉ máy chủ và token của người chơi; hãy tham gia bằng client Colyseus (`@colyseus/sdk` 0.17). Trong lúc phát triển, hãy chạy Colyseus 0.17 và MongoDB 8 cục bộ và kết nối trực tiếp đến máy chủ cục bộ của bạn. Để thử máy chủ được lưu trữ, hãy tải lên một phiên bản riêng tư, rồi mở `https://www.playdrop.ai/create/games/<slug>/test?v=<version>&player=1` và cùng liên kết đó với `player=2` trong cửa sổ thứ hai: mỗi cửa sổ chơi như một tài khoản thử nghiệm riêng. Hãy chuyển phiên bản sang công khai từ trang game khi mọi thứ ổn.

## SDK server tùy chọn: bạn bè và AI

`@playdrop/server` thêm `playdrop.social` (bạn bè đang chơi game này và thẻ game trong PlayDrop Chat) và `playdrop.ai` (tạo văn bản, hình ảnh, 3D, video, âm thanh, giọng nói và nhạc do nhà sáng tạo trả phí). Các lệnh gọi này chỉ hoạt động với game đã tải lên, không hoạt động khi phát triển cục bộ. Hãy tải media riêng tư đã tạo về máy chủ bằng `playdrop.ai.tasks.downloadFile` và chỉ gửi các byte đến đúng người chơi; yêu cầu giọng nói chấp nhận tối đa 40 từ.

## Nhóm chơi và thoại phòng

`await playdrop.social.getParty(client.auth)` đọc thành viên nhóm chơi hiện được ủy quyền. Nó không lộ chat nhóm hay hoạt động trong game khác, và không cấp quyền quản lý nhóm. Các API xã hội hiện có giữ nguyên hành vi.

Một catalogue khai báo `roomVoice: true` bắt đầu với chính sách cả phòng; không cần lệnh gọi máy chủ nào cho mặc định đó. Để tùy chỉnh, hãy gắn `const platform = playdrop.multiplayer.forRoom(this)` với phòng Colyseus thực tế. Dùng `platform.voice.setPolicy("all" | "team" | "proximity" | "off", { range: 20 })`, `setTeam(client.auth, teamId)`, `setAudience(client.auth, audience)` và `updatePositions([{ player: client.auth, position: { x, y, z } }])`. Truyền null để xóa ghi đè của đội hoặc người chơi. Chế độ khoảng cách cần vị trí chính thức, mới nhất.

Runtime đáng tin cậy gộp các thay đổi về điều kiện, đặt chỗ cho các thành viên theo sau của nhóm chơi đã được chấp nhận sau lần tham gia thông thường của trưởng nhóm, và dọn dẹp quyền. Game không bao giờ gửi âm thanh, thông tin xác thực của nhà cung cấp hay yêu cầu micro. Giữ cùng một phòng qua các vòng. Hãy dùng Người chơi thử riêng tư hiện có với một nhà sáng tạo đủ điều kiện để thử tích hợp trước khi xuất bản; riêng việc xuất bản không bật việc triển khai.
