【レポート】「Google Cloud Firestore を利用した 複数人リアルタイム通信対戦の観戦機能 開発事例」#CEDEC2021 #classmethod_game

2021.08.25

こんにちは、コンサルティング部の後藤です。

8月24日 - 8月26日の3日間開催されているCEDEC2021に参加しています。今回はその中からポケラボ様のセッション「Google Cloud Firestore を利用した 複数人リアルタイム通信対戦の観戦機能 開発事例」を聴講してきましたので、レポートとなります。

セッション情報

タイトル

Google Cloud Firestore を利用した「複数人リアルタイム通信対戦の観戦機能」開発事例

スピーカー

株式会社ポケラボ ゲーム事業本部 エンジニアマネージャー 中原 雄一

概要

シノアリスで大人気のギルド同士の複数人リアルタイム通信対戦「コロシアム」を観戦するためのシステム(リアルタイム観戦/後から観戦、今年リリース予定)について、その開発・運用事例を共有致します。

「上位ギルドのバトル内容が見たい!」といったお客様の声や「コロシアムの処理を変更したが見た目に悪影響がでていないか?」などの確認のため、また「お客様からのお問い合わせの際、実際にどのような誤解を与えていたのか?」などの再現確認のツールとして、この観戦機能のニーズが高まりました。

本セッションでは、「コロシアム」がどのようなシステムで実装されており、そのシステムと Google Cloud Firestore を組み合わせ、どのように観戦機能を実現したのかを紹介致します。

セッションレポート

本事例のゲームタイトル

本セッションで取り上げられている事例のゲームタイトルは「シノアリス」になります。

シノアリスには最大15人のギルドメンバーが協力して対戦を行う、複数人リアルタイム通信対戦のコンテンツとして「コロシアム」があります。本セッションではそのコロシアムのリアルタイム観戦機能や、リプレイ機能のバックエンド側が紹介されています。

観戦機能の要件

ポケラボ様では観戦機能の要件として、以下のような方針を挙げられていました。

これらの要件を満たすため、シノアリスの観戦機能実装にはGCPのFirestoreが採用されました。AWSにも似たようなサービスとしてAppSyncがありますが、シノアリスでは既存システムでFirebase SDKを使用していたこともあり、方針3のコロシアムに影響が出にくい、既存システムに極力手を入れないという事からFirestoreを選択されたとのこと。

コロシアムのアーキテクチャ

シノアリスではインフラ基盤としてAWSを採用しております。構成としてはクライアントからALBを経由してEC2に接続、配信リソースはS3に格納してAkamai経由で配信をしているそうです。

ReflectorはJavaで独自実装されたリアルタイム通信サーバで、WebSocketでクライアント常時接続を行っています。ReflectorのデータストアとしてHazelcastを採用し、ロビーにいるプレイヤー情報等を保持しているそうです。

Client側で武器等を使用した行動はReflectorにメッセージとして送信され、APPサーバで処理を行い、結果をReflector経由でClientに返答しているそうです。

ここまでが既存のコロシアムシステムのアーキテクチャとして紹介されていました。

Cloud Firestore導入

先程の既存アーキテクチャに対して、観戦機能実装のためのFirestoreを導入した図となります。

Client側の処理をAPPサーバで処理を行い、Reflectorに返答するのと同時に、Firestoreに書き込みを行っているようです。その後、Client側ではFirebase Unity SDKを利用してFirestore上にあるデータを読み取り、観戦を行うそうです。

Cloud Firestore対するアクセス権限について

この時気になる点として、GCP上にあるFirestoreに対して、GCP環境外(AWS)からアクセスする方法が挙げられます。まず、GCP上でFirestoreに対する権限を持ったサービスアカウントを作成し、その秘密鍵をJSONファイルとして保持して、Google Firestore PHPライブラリに持たせることで実行時にサービスアカウントの認証情報を生成できるようにしたとのこと。

Cloud Firestore上のデータ構造に関して

Cloud FirestoreはNo SQLのドキュメント指向データベースとなるため、SQLデータベースと異なりテーブルや行等は存在しません。データ構造としてはデータ、ドキュメント、コレクションにまとめられるそうです。

Firestoreに格納するデータは複数あり、それぞれコレクションとしてまとめていました。

  • コロシアムの基本情報
    • 対戦情報やギルド情報等が記述
    • 対戦開始時に作成される
  • ユーザの行動履歴
    • ユーザ毎の行動情報
      • ユーザIDや攻撃対象、与えたダメージ量等が記述
    • ユーザ1行動につき、1ドキュメント追加される
  • 対戦状況の履歴
    • 全ユーザのHPやコンボ数、バトル中のイベント発動状態等
    • 約1秒毎に1ドキュメント追加される

上記のようなデータをFirestoreに格納するにあたり、Firestoreの制約が引っかかったそうです。

Firestoreではデータベースあたりの最大書き込み回数/秒が10,000(最大10MiB/秒)という制約があるため、1秒毎の対戦状況書き込み等を行っているとすぐに上限に引っかかってしまったそうです。

この制約に対して、ポケラボ様では幾つか対策を考え、結果対策1を選択したそうです。

制約事項を確認しながら、writer数等を抑えて確認を行ったところ、パフォーマンスは特に問題は無かったようです。実際に稼働しているタイトルであったこともあり、対戦数やデータ数は実データをもとにサンプリングが行えたとのことでした。

しかし、PHPからFirestoreに対してWriterする際にResponse timeの悪化が見られ、今後の改善ポイントとなっているそうです。

まとめ

Firestoreの導入に関して、プラグインやSDKが豊富であるため比較的容易に導入が出来たそうです。またデータ保存、同期についても簡単に実現が出来たとのことでした。しかし、NoSQLということもあり複雑なクエリが発行できず、Firestore自体の制約もあるため要件に合うか見極めが必要とのことでした。

最後に

以上でポケラボ様のシノアリス事例「「Google Cloud Firestore を利用した 複数人リアルタイム通信対戦の観戦機能 開発事例」のレポートとなります。以前からシノアリスではインフラ基盤としてAWSを利用していた事は存じていたのですが、観戦機能にはGCPのFirestoreを使用されていることは知りませんでした。基盤がAWSだからAWSのサービスだけに拘らず、GCPでも利用できる部分を使用する構成として、非常に参考になりました。