コンピュータエンターテインメント協会(CESA)は、8月24日~26日の期間、オンラインにて、国内最大のゲーム開発者向けカンファレンス「コンピュータ・エンターテインメント・デベロッパーズ・カンファレンス 2021」(CEDEC 2021)を開催した。
本稿では、8月25日に行われた、ポケラボ・ゲーム事業本部 エンジニアマネージャーの中原雄一氏による講演「Google Cloud Firestore を利用した「複数人リアルタイム通信対戦の観戦機能」開発事例」をレポートしていく。
本講演では、『シノアリス』で人気のギルド同士の複数人リアルタイム通信対戦「コロシアム」を観戦するためのシステム(リアルタイム観戦/後から観戦、今年リリース予定)について、その開発・運用事例を共有。「コロシアム」がどのようなシステムで実装されており、そのシステムと Google Cloud Firestore を組み合わせ、どのように観戦機能を実現したのかを紹介した。なお、「コロシアム」の概要については以下の通り。
今回、観戦機能を開発することになった経緯として中原氏は、「上位ギルドのバトル内容が見たい!」といったユーザーの声や「コロシアムの処理を変更したが見た目に悪影響がでていないか?」などの確認のため、また「お客様からのお問い合わせの際、実際にどのような誤解を与えていたのか?」などの再現確認のツールとして、この観戦機能のニーズが高まったためと解説。
「データを貯められること」、「データ変更をリアルタイムに反映できること」、「コロシアムに影響がでないこと」という3つの技術方針を掲げて開発がスタートすることとなった。
この条件の中で注目したのが、今回、取り上げた「Google Cloud Firestore」となる。
続いて、コロシアムのシステムをどういった流れで構成しているのかを紹介。
クライアントアプリとして使用しているのは「Unity」で、バージョンは「2018.4.2f1」で、Android・iOS・Windows向けにアプリをリリースしている。
サーバーサイドはAWSを採用。「Apache/PHP(7.0)」、「MySQL」、「Memcached」「CDN(Akamai)」を使用している。
また、ポケラボで自作しているリアルタイム通信サーバー(通称「Reflector」)はJavaで動かしており、クライアントとソケット通信を行って常時接続を実現している。この「Reflector」では、Appサーバーが提供するHTTPサービスを定期的に実行して、その結果をクライアントに転送する、ないしはクライアントからのメッセージをAPPサーバーに転送、そのレスポンスを転送するという機能を持っている。データストアとしてはHazelcastを利用しており、ゲームルームという単位で対戦ごとのデータを所持している。
データの流れとしては、まずReflectorからAppサーバーが提供する現在の状態を取得するHTTPサービスを実行する。Appサーバーは、現在の状態をReflectorに返却。そして、Reflector がAppサーバーから返却された現在の状態をClientへ転送する。その情報を受けたそれぞれのClient端末は、現在の状態を元に画面同期を行う。これを定間隔で実行することで全てのゲーム画面で同期を取っていると解説した。
もう1点、Client側からアプリケーションへの流れについては、まず武器を使用するなどユーザーの行動に応じてメッセージをReflectorに送信。それを受けたReflectorは、Appサーバーが提供するユーザーの行動を登録するHTTPサービスを実行する。その中でAppサーバーは、リクエストを受けた通りユーザーの行動に基づいた処理を実行、結果をReflectorへ返却。Appサーバーから返却された結果をReflectorが全てのClient端末へ転送するという流れとなっている。最後に、Reflectorから転送された情報を受けたClientは、現在の状態を元に画面同期が行われるというわけだ。
主に定期通信によって定期的に画面を同期することと、ユーザーの行動に応じてメッセージが飛び交うというシステムをとっている。ここまでが既存のコロシアムを運用するためのシステムとなっている。
次に、ここからFirestoreをどのように導入したかという話を展開した。
まずFirestoreを用意し、先に挙げられた2つのサービス「Reflectorから現在の情報を定期的に取得する機能」、「ユーザーごとに応じてAppサーバーに行動を登録する機能」、このリクエストにフックする形でその結果をReflectorに返却すると共にFirestoreに書き込む。Firestoreの方にはデータが徐々に蓄積され、それをClientに組み込まれているFirebaseを経由してClientの画面が同期されるという仕組みとなっていると説明した。
▲クライアントアプリは比較的古めのバージョンを採用している。理由として、Version7辺りからiOS10以上のサポートとなったが、『シノアリス』はiOS9もサポートしている関係上このバージョンとなっていると中原氏は述べた。
また、認証方法については、サーバーとクライアントに関して、それぞれ以下のように行っている。
続いて、Firestore上にどのようにデータ構造を用意したのかという話に移っていく。
Cloud FirestoreはNoSQLドキュメント指向データベースとなっており、SQLデータベースとは違い、テーブルや行はない。各データは「ドキュメント」に格納し、それが「コレクション」にまとめられるという仕様となっている。また、Firestore上のデータ構造には制限があり、それが以下となる。
観戦機能において用意したコレクションは「コロシアムの基本情報」、「ユーザーの行動履歴」、「対戦状況履歴」の3つ。
「コロシアムの基本情報」は対戦開始時に作成される。どういった対戦が行われたかを記録する「対戦情報」、ギルドの名前や所持ポイント、全体の強さなどの「ギルド情報」、所属メンバーや個人の強さが分かる「ギルドメンバー情報」、コロシアム中に発生するイベントの情報が書き込まれた「バトル中イベント情報」の4つで構成されている。これらはデータの形こそ全く異なる情報となっているが、コロシアムの基本情報というコレクションの中にひとまとめにされている。
「ユーザーの行動履歴」は、ユーザー1行動につき1ドキュメントが追加される。こちらはドキュメントのフォーマットが同じで、ユーザーID・行動タイプ・行動した時間・攻撃対象・与えたダメージ量など、画面で表示するためのドキュメントをユーザーの行動履歴としてコレクションしている。
3つ目の「対戦状況履歴」は、約1秒毎に1ドキュメントを「現在の対戦状態」として追加。「現在の対戦状態」には、全ユーザーのHP・それぞれのギルドのイノチ獲得量・現在のコンボ数・バトル中イベント発動状態などが記録されている。そのため、「対戦状況履歴」にコレクションされたドキュメントを全て見ていくとどういった戦歴で対戦が進んでいったのかが確認できる。
主に上記3つのコレクションで運営しているが、先に挙げた制限より、データベースあたりの最大書き込み回数/秒が上限を超えてしまうことが発覚。
この課題を解決するための対策として以下の4つを挙げた。
この中から『シノアリス』では対策1の「シャーディングする」を採用。リリースまでの残り時間が少なかったため、お手軽かつ確実な方法を選択したと理由を述べた。どれくらい対戦が行われるかという想定もしやすかったことから、各種制限を超えないように事前準備で設計したことで問題も起きなかったという。
なお、PHPからFirestoreへのwrite時、一定のコストがかかり、結果としてResponse timeの悪化が見られたことを今後の課題として挙げた。
最後に、Firestoreの導入とデータ構造・性能、課題について以下のようにまとめて講演の締めとした。
また、『シノアリス』に関しては今回、他に2つのセッションレポートを掲載しているので、そちらも併せてチェックしてほしい。
【関連記事】
・【CEDEC 2021】『シノアリス』で実施した”ユーザーVS運営”の「コロシアム」イベントはどのようにして生まれたのか CPU戦を楽しんでもらうための工夫をポケラボが紹介!
・【CEDEC 2021】真のグローバル版を実現した『シノアリス』が「ワールド統合」の裏側を大公開! 24時間に渡るメンテナンスで起きたトラブルや解決法も紹介
(取材・文 編集部:山岡広樹)