共同モンスターレイドを作成する
複数のメンバーが同じモンスターを攻撃し、体力が0になるまで結果を共有する、リアルタイムのレイドを構成します。Webspaceの共通のshared-resourceプロセッサーが、攻撃、体力の変更、行動ごとの報酬を、サーバーでまとめて処理します。
始める前に
- スキーマとAPIをデプロイする権限が必要です。
- リアルタイム機能の
sendとreceiveの権限を、使用するメンバーに付与する必要があります。 - レイド対象を作成するAPIは、管理者だけが使用できるように構成します。
完成済みのスキーマから始める
共同リソースゲームのスキーマ(.sfn)をダウンロードできます。このファイルには、このドキュメントで使用する3つのテーブルのカラムと権限、shared-resourceプロセッサーの設定が入っています。 すべての言語版で同じファイルを使用し、ファイル内のテーブルとカラムの説明は英語で提供します。
- ファイルをダウンロードして、チームフォルダまたは個人フォルダにアップロードし、スキーマエディタで開きます。
APIビルドのデプロイ設定で、データベース識別子を確認します。デフォルト値のresource_gameが既存のデータベースと重複しないように、monster_raid_team_aのような新しい識別子に変更します。- 権限とプロセッサーの設定を確認してから、スキーマをデプロイします。
このファイルは、共同リソースのバックエンド構造の例です。includeClientがfalseであるため、ゲーム画面は自動的には作成されず、初期のモンスターデータも含まれていません。以下のAPIとWebSocketイベントを使用する画面を別途作成し、レイド対象も作成する必要があります。
データを3つのテーブルに分ける
共同リソースの構造では、次の3種類のデータを分離します。
| テーブル | 保存内容 |
|---|---|
game_resources | モンスターコード、状態、現在・最大の体力、バージョン、報酬アイテム |
game_actions | 行動ID、攻撃したメンバー、適用されたダメージ、結果の体力、報酬の数量 |
game_inventory | メンバーごとのアイテムと累積数量 |
game_actionsの行動IDは、再試行を区別します。同じ行動IDをもう一度送信しても、体力と報酬が2回反映されることはありません。
リアルタイムプロセッサーを設定する
リアルタイム機能をオンにし、イベントプロセッサーとしてshared-resourceを選択します。デフォルトのテーブル名を使用する場合、プロセッサーの設定は次の構造になります。
{
"resourcesTable": "game_resources",
"actionsTable": "game_actions",
"inventoryTable": "game_inventory",
"actionPower": 1,
"rewardPerAction": 1,
"maxClientAmount": 1,
"broadcast": "namespace"
}
broadcastがnamespaceの場合は、同じWebspaceのリアルタイム名前空間に接続しているクライアントが、結果イベントを一緒に受け取ります。actorの場合は、行動したメンバーにだけ結果を送信します。
レイド対象を作成する
管理者権限でgame_resources/createを呼び出して、モンスターを作成します。
{
"code": "RAID-1",
"kind": "monster",
"status": "active",
"current_value": 10000,
"max_value": 10000,
"version": 0,
"reward_item_code": "monster-core"
}
画面を開くときに、game_resourcesの照会APIから現在の体力とバージョンを読み取ります。新しく接続したときや、接続が復旧した後にも、REST APIを照会し直せば、現在のサーバーの状態に画面を合わせることができます。
WebSocketで攻撃を送信する
ログインしたメンバーが、リアルタイム接続を購読してからresource-game.actイベントを送信します。
{
"type": "webspace:send",
"data": {
"dbName": "monster_raid_team_a",
"event": "resource-game.act",
"payload": {
"actionId": "attack-00000001",
"resourceCode": "RAID-1",
"amount": 1
}
}
}
dbNameには、デプロイの際に指定したデータベース識別子を使用します。
actionIdは、英字、数字、_、-を組み合わせた8~80文字の値にします。amountを省略すると1になり、値を送信する場合は、プロセッサーのmaxClientAmountの範囲内の整数を使用します。
サーバーは、処理が終わった後にresource-game.action-appliedを送信します。
{
"actionId": "attack-00000001",
"resourceId": 1,
"currentValue": 9999,
"version": 1,
"rewardQuantity": 1,
"duplicate": false
}
画面は、この結果を受け取った後にのみ体力を変更します。クライアントがresource-game.action-appliedを直接送信するリクエストは拒否されます。
体力と報酬を表示する
resourceIdが、現在表示しているモンスターのものであることを確認します。versionが、前の結果より大きいことを確認します。currentValueで体力の表示を更新します。currentValueが0の場合は、共同討伐の完了状態を表示します。- 個人のアイテムは、
game_inventory/listで照会し直します。
game_inventoryには、メンバー本人のデータだけを読み取れる所有者権限を適用します。結果イベントのrewardQuantityだけで、ほかのメンバーの保有量を推定することはしません。
注意事項
- 攻撃力と報酬は、クライアントの値ではなく、サーバーのプロセッサー設定で決まります。
- リソースの変更、行動の記録、報酬の付与は、1つのトランザクションで処理されます。
- 現在の共通構造は、行動ごとの報酬を提供します。討伐ランキングや、討伐者専用の報酬は、別途設計する必要があります。
- 応答が遅れても、成功したとはみなしません。同じ
actionIdで再確認すれば、重複して適用されることを防げます。