# PlayDrop のリアルタイムゲームサーバー：Colyseus と MongoDB

MongoDB データベース付きのホスト型 Colyseus 0.17 サーバーでゲームを動かし、ブラウザから SDK で接続し、2人のプレイヤーでテストする方法と制限を説明します。

Source: https://www.playdrop.ai/ja/create/learn/game-servers

PlayDrop は、ゲームのサーバー側をホストできます。専用の MongoDB データベースを備えた標準の Colyseus サーバーで、プレイヤーは検証済み、運用するインフラはありません。リアルタイムの対戦、ターン制のゲーム、共有ワールド、そしてプレイヤーに不正をされては困るあらゆるものに使えます。サーバーは任意です。自分でホストしているサーバーをゲームから呼び出すこともできます。

## サーバーを書く

1つの ES モジュールから `rooms` マップをエクスポートします。サーバーの起動は PlayDrop が行います。PlayDrop が `onJoin` の前に各プレイヤーを検証するため、`listen()` を呼び出したり `onAuth` を定義したりしないでください。

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

class GameRoom extends Room {
  maxClients = 8;
  async onCreate() {
    this.mongo = new MongoClient(process.env.PLAYDROP_MONGO_URL);
    await this.mongo.connect();
    this.onMessage("move", (client, move) => this.applyMove(client.auth.userId, move));
  }
  onJoin(client) {
    // client.auth is the verified PlayDrop player: userId, username, appRole, isTestPlayer…
  }
  async onDispose() { await this.mongo?.close(); }
}

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

MongoDB への接続は、モジュールのトップレベルではなく、必ずルームのライフサイクルの中で行ってください。`PLAYDROP_MONGO_URL` は実行時にしか存在しません。クエリに合わせてインデックスを作成しましょう。

## サーバーを宣言する

サーバーを1つのファイルにバンドルし、カタログでそのファイルを指定します。

```json
{ "server": { "entry": "server/index.mjs", "rooms": ["game"] } }
```

[パッケージ](https://www.playdrop.ai/ja/create/learn/packaging)でアップロードしてください。シンプルな HTML の方法ではサーバーを含められません。

## ホスト型ランタイムのルール

- Node.js 24.22.1 上の Colyseus 0.17（`colyseus` 0.17.10、`@colyseus/schema` 4.0.30）と MongoDB ドライバー 7.5。
- 最大 2 MiB の自己完結した ES モジュール1つ。インポートできるのは `colyseus`、`@colyseus/core`、`@colyseus/schema`、`mongodb`、`@playdrop/server` だけです。それ以外はすべてバンドルしてください。
- ルームの種類は最大2つ、1ルームあたり最大8人、1ルームあたり最大4時間、プレイヤー1人あたり毎秒30メッセージまで、1メッセージあたり最大 512 KiB。
- インターネットにはアクセスできません。接続できるのは MongoDB と PlayDrop のサービスだけです。
- プレイヤーはサインインしている必要があります。
- データベースはゲームごとに1つで、バージョンをまたいで保持され、クリエイターのストレージにカウントされます。そのアドレスや認証情報をブラウザに送るのは絶対にやめてください。

## ブラウザから接続する

```js
const sdk = await playdrop.init();
const room = await sdk.multiplayer.join("game");
room.onStateChange((state) => render(state));
room.send("move", { x: 1 });
```

`join` は PlayDrop のパーティーの席とサインインを処理します。[オンラインパーティー](https://www.playdrop.ai/ja/create/learn/online-party)をご覧ください。より細かく制御したい場合は、`sdk.multiplayer.getConnection()` が、`sdk.libs.colyseus.load()` で読み込む公式 Colyseus クライアント用の `{ endpoint, token, expiresAt }` を返します。

## サーバー SDK

`@playdrop/server` は、信頼できるプラットフォームの呼び出しを追加します。フレンドとゲームカード（`playdrop.social`）、購入の検証（`playdrop.shop`）、クリエイターが費用を負担する AI 生成（`playdrop.ai`）、ルーム音声（`playdrop.multiplayer.forRoom`）です。これらはアップロード済みのゲームでのみ動作します。[サーバー SDK リファレンス](https://www.playdrop.ai/ja/create/learn/server-sdk)をご覧ください。

## テスト

開発中は、Colyseus 0.17 と MongoDB をローカルで動かし、ローカルのクライアントをローカルのサーバーに接続します。ホスト型サーバーをテストするには、非公開バージョンをアップロードして `https://www.playdrop.ai/create/games/<slug>/test?v=<version>&player=1` を開き、2つ目のウィンドウで `player=2` にした同じリンクを開きます。それぞれのウィンドウは、あなたの別々のテストプレイヤーとして遊びます。うまく動いたら、テスト済みのバージョンを `publish_game_version` で公開してください。

切断に備えた設計にしましょう。Colyseus の再接続機能は短い間だけ席を確保します。戻ってきたプレイヤーが続きから遊べるよう、ルームの状態を設計してください。

## 関連ガイド

- [オンラインパーティーと音声](https://www.playdrop.ai/ja/create/learn/online-party): 友達どうしでオンラインで一緒に遊べるようにします。パーティーの人数を宣言し、PlayDrop のパーティー画面を開き、sdk.multiplayer.join で予約済みのルームに参加し、ルーム音声を制御します。
- [サーバー SDK](https://www.playdrop.ai/ja/create/learn/server-sdk): PlayDrop がホストするゲームサーバーのリファレンス：ランタイムのルール、検証済みの PlayDropPlayer、playdrop.social、playdrop.shop、playdrop.ai、playdrop.multiplayer。
- [パッケージ化と .play](https://www.playdrop.ai/ja/create/learn/packaging): ルートに catalogue.json を置いたビルド済みのフォルダー、ZIP、.play を用意し、掲載メディアとサーバーを宣言して、prepare_catalogue_upload でアップロードします。
