re:Invent 2024: Star Wars: HuntersがGameLiftで実現した次世代ゲーム運用
はじめに
海外の様々な講演を日本語記事に書き起こすことで、隠れた良質な情報をもっと身近なものに。そんなコンセプトで進める本企画で今回取り上げるプレゼンテーションはこちら!
📖 AWS re:Invent 2024 - How Star Wars: Hunters got to the next level with Amazon GameLift (GAM308)
この動画では、Star Wars: Huntersのローンチを成功に導いたAmazon GameLiftの活用事例が紹介されています。GameLiftのFlexMatchを用いたマッチメイキング、マルチリージョンフリートによるグローバル展開、EC2 Spot Instancesの活用によるコスト最適化など、具体的な実装方法が解説されています。特に、1インスタンスあたり4つのゲームサーバーを配置する設計や、マッチメイキングシミュレーターを用いたルール調整など、実践的な知見が共有されています。また、FleetDeployerと呼ばれる独自ツールの開発により、スタジオ全体でGameLiftリソースを効率的に管理できた点も詳しく説明されています。最後に、GameLift Anywhereを使用したローカル開発環境の構築方法についても言及されています。
※ 画像をクリックすると、動画中の該当シーンに遷移します。
re:Invent 2024関連の書き起こし記事については、こちらのSpreadsheet に情報をまとめています。合わせてご確認ください!
本編
Star Wars: Huntersの開発背景とゲーム概要
こんにちは。GameLiftのHead of ProductのChristinaです。本日はStar Wars: Huntersチームと一緒に参加しています。過去1、2年にわたって彼らと一緒にこのプロジェクトに携わってきましたが、彼ら自身の話を皆様にお聞きいただけることを大変嬉しく思います。AWS三大イベントへようこそ。
早速本題に入らせていただきます。マルチプレイヤーゲームの発売日を想像してみてください。皆さん良い仕事をされました。ゲームは素晴らしく、プレイも快適で、お祝いムード一色です。キッチンではみんながシャンパンを飲んでケーキを食べ、至る所に風船が飾られています。ストレスなんて全くありません。ただし、サーバーやインフラに関わっている人たちにとっては、そうもいかないかもしれません。今度はプレイヤーの立場になって考えてみましょう。待ちに待ったゲームをスマートフォンにダウンロードし、キャラクターとスキンを選んでプレイボタンを押します。そして待ちます。さらに待ちます。もっと待ちます。そしてエラーメッセージが表示されます:「マッチメイキングに失敗しました」「サーバーが見つかりません」。これは発売日としては最悪のシナリオです。プレイヤーならゲームを削除し、SNSに良くない投稿をして、二度とプレイしないかもしれません。サーバーチームにとっては、ゲームの成功への責任が自分たちの肩にのしかかってくるような気持ちになります。
本日は、Amazon GameLiftを使用してこのような発売日の不安をどのように解消するかについてお話しします。 マルチプレイヤーゲームの要件とGameLiftのリソースについて説明し、Chris Vodakが実装の過程について、そしてAWSのSteve Phillipsが推奨事項についてお話しします。 Chrisと私はZyngaに所属しており、具体的にはCSR2やDawn of Titansを制作したZynga内のNaturalMotionというスタジオの一員です。本日はStar Wars: Huntersについてお話しします。Huntersは私たちにとって初めての試みでした。初のコンソールゲームであり、リアルタイムのクロスプラットフォームゲームです。そのため、多くの課題に直面することになりました。
マルチプレイヤーゲームの課題とAmazon GameLiftの活用
本題に入る前に、前シーズンのトレーラーを少しご覧いただきましょう。ストームトルーパーが好きな人もいれば、ライトセーバーが好きな人もいます。惑星エンドアのイウォークが好きな方は、このトレーラーが気に入るかもしれません。 楽しかったですね。ご覧いただいたように、これがStar Wars: Huntersです。ティーザートレーラーを見ていただければ一目瞭然だったと思います。 4対4のアリーナベースの戦闘ゲームです。キャラクタークラスベースのゲームで、他のプレイヤーと対戦することが全てです。マルチプレイヤーゲームであり、それが今日のトピックです。
サーバーやインフラの観点から見て、私たちとプレイヤーが重視するのは、ゲームが公平であることです。つまり、自分より極端に上手な相手や下手な相手とマッチングされないということです。プレイヤーは同じ地域のプレイヤーと対戦することで、同様に低いレイテンシーでゲームを楽しめることを望んでいます。そして、ゲームを待つ時間があまりに長くなることも避けたいところです。
これはどのように実装されているのでしょうか? まず、様々な属性を持つプレイヤーたちが存在します。これらの属性には暗黙的なものと明示的なものがあり、Matchmakerがそれらを管理します。Matchmakerは単純な先着順でプレイヤーを扱うわけではありません。プレイヤープールを見て、適切な時間内に、スキルレベルが近く、同じタイプのゲームをプレイしたいプレイヤーを見つけ出します。Huntersの場合は8人のプレイヤーが見つかると、それらのプレイヤーをServer Placementアルゴリズムに送ります。 Server Placementは、世界中にあるGame Serverの中から、利用可能なサーバーを見つけ出し、そのサーバーにプレイヤーを割り当てます。
次に、サーバーについてですが、これは完全なAuthoritative Serverです。つまり、各クライアントで起こるすべての動作をシミュレートする必要があります。例えば、私が角を曲がって誰かに撃たれそうになった時に身を隠した場合、デバイスやネットワーク接続の速度に関係なく、私のマシンでも相手のマシンでもその動作が正確に反映される必要があります。 Huntersについて以前お話ししなかったことですが、私たちはマルチプラットフォーム対応です。iOS、Android、Nintendo Switchに対応しており、来年初めにはPCでもEarly Accessとしてリリースする予定です。ぜひ来年、PC版のHuntersをダウンロードしてください。サーバーの話に戻りますと、私たちは同じゲームコードをLinuxベースのサーバーにもコンパイルしています。このゲームコードは、すべてのシミュレーション作業を行うため、かなり重いものです。また、サーバーあたりのプレイヤー数も少なくなっています。サーバー対プレイヤーの比率が非常に低いのです。Webサーバーの場合、数千人のユーザーを扱うことができ、通常は他のユーザーと同じサーバーにいる必要はありません。ゲームサーバーと通信するだけでよいのです。しかし私たちの場合、8人のプレイヤーを同一のサーバーに配置する必要があります。
Amazon GameLiftリソースの詳細と運用管理
私たちは多数のサーバーを持っており、すべてのプレイヤーに対して低レイテンシーを確保する必要があるため、これらのサーバーを世界中に地理的に分散させる必要があります。 これらが私たちの要件でした。そして、どのエンジニアリングチームでもそうするように、私たちもプロトタイプの構築を始めました。 Platform Serviceがあり、これについては後ほどChrisが詳しく説明します。Platformはマッチ前にゲームとやり取りを行い、ショップやプレイするマップの選択などを処理します。 先ほど説明したMatchmaking Serverがあり、Server Orchestratorがあります。これはASGを制御します - これらはインスタンスで、 Linuxサーバーを含むインスタンスが起動したり停止したりします。
このシステムを本番環境で使用することは可能だったでしょうか?確かに、完全に構築すれば可能だったかもしれません。しかし、何年もの間、これらのMatchmakingやOrchestrationサーバーのメンテナンスに依存したいと思うでしょうか?さらに、これらがゲームの単一障害点となることを考えると、あまり良い選択とは言えません。私たちはエンジニアリングの努力を、ゲーム自体や後ほど説明する社内ツールの開発に集中させたいと考えました。そこで、必要な機能が理解できた時点でこのソリューションを廃止し、 Amazon GameLiftを採用することにしました。GameLiftを選んだ主な理由は、 Amazonが世界中に持つサーバーを活用できるグローバルなプレゼンスと、コスト最適化です。Spot Fleetのような、より安価な機能を簡単に利用できます。私たちにとって決定的だった機能はMatchmakingです。 エンジニアリング以外のチームでも、プレイヤーのマッチング方法を簡単に修正できる、データ駆動型のMatchmakingが標準で提供されているのです。
GameLiftを使用している今、その実装方法についてお話ししたいと思います。会場の中でGameLiftを使用したことがある方は手を挙げていただけますか?数人いらっしゃいますね。では、 GameLift内で利用可能なリソースと、それらがどのように連携してマルチプレイヤーゲームを実現しているかについて説明していきます。まず、 FlexMatch Rulesetがあります。これはJSONファイルで、プレイヤーがマッチに参加するまでの待機時間や、スキルレベルの近さなど、ルールの定義が含まれています。次に、 Configですが、これは基本的にこのRulesetと、これから説明する下流のサーバーとを結びつけるための接着剤のような役割を果たします。
Huntersでは、本番環境でこれらのルールを迅速に置き換えられるようにしたいと考えていました。開発の観点からは、エンジニアだけでなく誰でもこれらのファイルを修正できるため、ソースコードリポジトリ内で正しいことを確認する必要がありました。そこで、有効なJSONであるかを検証する投稿後のルール検証チェックを実装しました。これは簡単な作業ですが、さらにGameLiftのエンドポイントにファイルを送信して、有効なルールファイルであるかを確認します。有効でない場合は、ユーザーに通知が行きます。 次に、Game Buildオブジェクトについてです。Packerのようなツールを使用してサーバーイメージを管理した経験がある方なら、スナップショットを作成する前にイメージを準備する必要があることをご存知でしょう。これらは、そのスナップショットに含まれるファイル - バイナリ、スクリプト、そして非バイナリファイルも含みます。
Huntersの場合、まずJenkinsビルドファームからコンパイルされたLinuxサーバーバイナリから始めます。 後ほど説明するAgentを追加し、Parameter Storeファイルも用意します。Stagingと開発環境のどちらにデプロイするかに応じて、 異なるサービスエンドポイントでパラメータ化されたファイルを使用します。これらすべてをまとめてアーカイブし、S3に送信します。 そのバケットに保存されると、GameLiftに登録され、これがGameLiftビルド、つまりサーバーの旅の始まりとなります。
次に実際のゲームを実行する必要があります。これはGameLiftインスタンス上で行われます。このインスタンスには、ゲームサーバーの1つ以上のインスタンスが含まれます。現在、1から50のサーバーを実行できますが、実行するサーバーの数は、ゲームがどれだけCPUを使用するかによって大きく異なります。インスタンス上で1つのサーバーだけを実行するのは、コストが高くなってしまうため避けるべきです。逆に、詰め込みすぎると、1つのゲームサーバーのCPU使用率が急上昇した際に、他のすべてのゲームサーバーに影響を与えるリスクがあります。リアルタイムマルチプレイヤーゲームをプレイしている場合、サーバーのCPUが制限されると、フレームドロップが発生して明らかに気付くため、これは好ましくありません。Huntersのインスタンスでは、 インスタンスあたり4から8のゲームサーバーを実行しており、これが外部プレイヤーが接続する対象となります。
これはパブリックインスタンスで、 内部プロセスをサポートする補助的なサービスでバックアップしています。GameLiftは CloudWatchメトリクスを標準で提供していますが、私たちは独自のAgentもマシン上で実行しており、後で必要になる可能性のある追加情報を収集してPrometheusに送信しています。 また、カスタムのロギングAgentも用意しています。GameLiftは標準で、各ゲームセッションの完了時にログを含むテキストファイルを提供する機能を備えていますが、私たちは大規模な運用を行っていたため、ログ集約サービスを確実に持つ必要があり、インスタンスからすべてのログをOpenSearchに送信しています。
開発中は、本番環境でクラッシュが発生することがあります。できるだけクラッシュは避けたいものですが、発生する可能性はあります。 そこで、Goで書かれたカスタムレポートAgentをマシン上に配置し、コアダンプが検出されると、それをS3バケットとクラッシュ集約サービスに送信します。ここで重要だったのは、スロットリングロジックを組み込むことでした。ローンチ時にゲームサーバーがクラッシュし、1000台のゲームサーバーが同時にクラッシュして、それぞれ約1ギガバイトのコアダンプをS3に送信するような事態が発生すると、請求額が非常に高額になってしまいます。
FleetDeployerツールの開発と活用
これは1つのインスタンスの例ですが、多くのプレイヤーがいる場合は、1つのインスタンス分以上のサーバーが必要になるでしょう。ここで Fleet の出番となります。EC2を使用したことがある方なら、Auto Scaling Groupをご存知かもしれません。Fleet は Auto Scaling Group に似ており、ノードの最小数、最大数、目標数を設定し、プレイヤーの需要に応じて時間とともに増減します。 Fleet にはスケーリングルール、必要な余裕度、スケーリングのタイミングなどのパラメータを設定します。インスタンスの価格モデルとしてはオンデマンドや Spot インスタンスがあり、C5などのインスタンスサイズも選択できます。GameLift Fleet の私のお気に入りの機能は、マルチリージョン対応であることです。
世界中のどのリージョンでリソースを実行しているかを把握するのは本当に大変です。GameLift では、us-east-1などのホームリージョンで Fleet を起動し、チェックボックスにチェックを入れるだけで、約30分で世界の反対側でもゲームを利用できるようになります。 これらの Fleet の運用はやや複雑で、実行するインスタンス数の決定についてよく質問を受けます。Hunters の開発時の場合、必要な数のインスタンスを持つ単一の Fleet から始めることができましたが、それでも制限はありました。この例では、C5.large のオンデマンド Fleet を実行していますが、 多くのサーバーを実行しているため、財務部門からコスト最適化を求められるかもしれません。
Spot インスタンスを使用することでコストを最適化できます。Hunters のようなゲームは、マッチの長さが短く、GameLift は終了間近のインスタンスにセッションを配置しないほど賢いため、Spot インスタンスの理想的な候補となります。もう1つの考慮点はインスタンスの多様性です。例えば、Cyber Monday で同じ Amazon リージョンの小売業者が すべての C5 インスタンスを使用している場合、C6i.large のような異なるインスタンスを使用することで、インスタンスの利用不可能性を減らすことができます。Hunters では、約12の異なる Fleet を実行しており、古いインスタンスと新しいインスタンスの両方を使用して、インスタンスの可用性を確保しています。
これらの数値を計算するために、 ap-south-2 でのサーバー容量を決定する必要がある仮想的なシナリオを考えてみましょう。プロダクトチームは、このリージョンで 16,000人の同時接続プレイヤーを見込んでいます。16,000人の同時接続プレイヤーがいて、理想的なケースでは1サーバーあたり8人のプレイヤーとすると、 2,000のゲームサーバーが必要になります。1インスタンスあたり4つのゲームサーバーを実行すると、 500インスタンスが必要になります。そして、C5.large と C6i.large で50-50の分割を行います。最後に、 オンデマンドと Spot インスタンスの割合を決定します。どれだけ保守的にするかによって、インスタンスの可用性を保証するために100%オンデマンドを選択するか、スケーリングの制限を許容できる場合は90-100% Spot を選択することもできます。
そして、ここでC6i.large についても同様の計算を行います。これが Fleet の計算方法であり、このマトリックスに適用する方法です。これらの数値は ap-south-2 向けのものであり、各リージョンで同様の計算を行うことになります。このプロセスはやや手間がかかります。 そのため、私たちはツールを開発しました。各リージョンで予想される数値を入力できる Fleet サイジングカリキュレーターを用意しています。また、これまでに収集した履歴データを参照して、シーズン1、シーズン2、シーズン3のローンチ時の状況を確認し、次のシーズンのスケーリングにそれらの制限を適用することもできます。このツールは、Spot とオンデマンドの比率を50%、80%、20%などに設定した場合のコスト見積もりも行います。
さて、今日の数学的な話はここまでにして、Game Session Queueという単純な概念についてお話ししましょう。 このGame Session Queueは、先ほど説明したすべてのFleetを集約するものです。8人のプレイヤーグループをQueueに入れたいという話をしましたが、この8人のプレイヤーがGame Session Queueに入り、ポリシーに応じて、どのサーバーにプレイヤーを配置するかを決定します。これらがHuntersで使用している Amazon GameLiftのリソースです。利用可能なすべてのリソースを使用しているわけではありません。Aliasは使用していませんが、現状のもので十分に機能しています。単一のBuildに対して、各タイプのリソースを1つだけ使用しているわけではないことがお分かりいただけると思います。先ほど説明したように複数のFleetがあり、複数のRulesetを持つこともあります。これらのRulesetは異なるQueueを表しています。Huntersをプレイする際には、カジュアルQueue、より競技性の高いランクQueue、そしてHuttBallのような特別イベントのQueueがあります。
これらのサーバーを運用しながら、何が起きているのかを理解しようとしています。 最も基本的なレベルでは、インスタンス上で何が動いているのか、CPUの状態はどうか、その他のサーバーメトリクスはどうなっているのかを確認します。これにより、各インスタンスで実行するゲームサーバーの数に関するパッキングの問題が解決されます。より全体的な視点では、Chrisが話す予定のマッチメイキング時間などを見ることもあります。Fleet使用率も確認できます。コストは非常に重要な要素で、Fleetが十分に活用されていないことや、空のインスタンスが多すぎることに気付くかもしれません。そういった場合は、短期的に調整するか、次のシーズンのローンチに向けて調整を行います。
また、インベントリ数も管理しています。必ずしもコストによって制限されているわけではありませんが、デフォルトでは1つのアカウントにつき1リージョンあたり約30のQueueという制限があります。そのため、追加リクエストを出す必要があるか、不必要に使用していないかを確認するために、これらを追跡する必要があります。Configsや Rulesetsの数などのリソースをカウントしています。また、ロードテストを通じて、1秒あたりのトランザクション数も監視しています。これは、ローンチ日に多くのプレイヤーがアクセスした際に、AWSによるスロットリングのしきい値を超えないようにするためです。
では、これらのメトリクスをどのように収集しているのでしょうか? Prometheus、Amazon CloudWatch、過去のイベント呼び出しを確認するためのAWS CloudTrail、そしてPrometheusのために独自に作成したスクレイパーを使用しています。GrafanaとCloudWatchにダッシュボードがあり、その一部はBuildごとに自動生成されます。また、問題が発生した場合はAlert Managerに送信して担当者に通知が行くようになっています。これが、Fleetの構築方法と使用方法についてのエンジニアリングの観点からの説明です。
Star Wars: Huntersの実装プロセスとアーキテクチャ
では、NaturalMotionスタジオは実際にどのようにして「マルチプレイヤーゲームをプレイしよう」と言えるのでしょうか?Fleetやデプロイメントを行う理由は様々です。開発者が変更をテストする場合もあれば、マップチームが新しいレベルを作成してマルチプレイヤーモードでテストする必要がある場合もあります。あるいは、本番環境やソフトローンチに向けたデプロイメントかもしれません。スタジオのメンバーにはプライベートマルチプレイヤーゲームなどを使用してプレイしてほしいのですが、Linuxサーバーやは何か、Amazon GameLiftとは何か、Amazonコンソールとは何かを理解する必要はありません。実際、スタジオの全員にコンソールへのログインを許可するのは危険です。そこで、FleetDeployerというツールを開発しました。これはスタジオとAmazon GameLift APIの間に位置するもので、基本的にはウェブサイトとAPIで、誰でも使用できます。先ほど説明したすべてのリソースがありますが、FleetDeployerはそれらを1つの小さなオブジェクトにまとめています。
外部から見ると、これを「Deployment Group」と呼んでいます。FleetDeployerのユーザーとしては、Deploymentがあるということだけを知っていればいいのです。その中に10個や20個のリソースがあることは気にする必要はありません。Deploymentはそれらのリソースのインベントリであり、私たちは追加のメタデータでそれに注釈を付けています。ここに示されているメタデータの例には、説明文やオーナーなどが含まれています。
興味深いことに、時間ベースのメタデータもあります。ユーザーはFleetDeployerにログインして、「Build 123を作成したので、このBuildのFleetを立ち上げて」というように指示することができます。すると、FleetDeployerはAmazon GameLiftを監視し、そのFleetが準備できたタイミングを把握します。これを行う理由は、ほとんどのリソースは即座に利用可能になりますが、Fleetの場合は立ち上げに30分から40分ほどかかるためです。立ち上がるまで待ち、準備ができたらSlackでユーザーに通知します。また、Build 123がマルチプレイヤーゲームのプレイヤーを受け入れる準備ができたことを、Platform Servicesにも通知します。
Scheduled Scale-upも可能です。これは本番環境ではそれほど必要ありませんが、社内のプレイテストでは重宝します。例えば、月曜日の10時30分にテストFleetで0人から200人のプレイヤーを対象としたプレイテストがある場合、5分前にScale-upしてインスタンスを準備しておきます。Scale-downも行い、Scheduled Shutdownも設定できます。カンファレンスのデモ用のFleetを週末に停止したり、デフォルトで24時間プレイされていないFleetを自動的にシャットダウンしたりできます。これは非常に役立っています。開発のピーク時には、1日に20〜30のBuildがマルチプレイヤーテストされており、Build当たり10〜20のリソースがあったため、300〜500ものリソースが存在していました。リソースのシャットダウンを依頼して回る代わりに、これらのリソースを自動的にScale-downして解放できるようになりました。
これがFleetDeployerですが、どのように動作するのでしょうか?これは私たちが開発した.NET CoreアプリケーションでAmazon Elastic Kubernetes Service上で動作しています。多くのサービスを利用していますが、特に重要なのはAmazon GameLift APIです。GameLift APIは非常に柔軟で、コンソールでできることはすべてAPIで実行できるため、コンソールにログインする必要がほとんどありません。これはドロップダウンを使用してFleetを作成する例です。説明を設定し、タイムアウトを設定できます。ツール内でもいくつかのメトリクスを確認できますが、多くの場合はGrafanaにリンクしています。これはDeploymentのリスト表示の例です。
FleetDeployerはZynga内でのみ利用可能ですが、GameLiftの使用を検討している方々に、なぜGameLiftの周りにツールを構築する必要があるのか、より使いやすいツールにするにはどうすればよいのかを理解する参考になれば幸いです。プレローンチと、ストレスを感じないようにしたいローンチ当日について最後にまとめると、開発からソフトローンチ、本番環境まで同じワークフローを使用することが重要です。私たちはFleetDeployerを使用していますが、何を使うにしても、最初から一貫して使用することで早期にバグを発見できます。ダッシュボードを設定し、プロセス全体を通してロードテストを行います。このロードテストにより、デプロイメントプロセスが機能することを確認し、ダッシュボードに必要な情報が表示されていることを確認できます。
注意点として、リージョンのトランザクション処理能力の上限を確認するためにロードテストを実施する場合は、本番サーバーと同じリージョンで行わないようにしてください。先ほど説明した事前割り当ての件について、これらの計算を行い、その数値をAmazonに提供して、ローンチ日までにフリートをスケールアップする必要があります。必須ではありませんが、予防措置として、私たちは十分な空きフリート容量を確保するためにフリートを事前にウォームアップしています。これにより、新シーズンの開始時やトレーラーの公開時に、プレイヤーがゲームに参加できる準備が整います。最後に、GameLiftのパートナーと相談することをお勧めします - 彼らは皆さんが思いつかなかったアドバイスをくれるかもしれませんし、TPSやインスタンス使用率などについて質問してくれるかもしれません。
さて、GameLift自体についての内部的な視点からの説明は以上です。ここからは実装についてお話しするため、Chrisにバトンタッチしたいと思います。
ゲームローンチの成功と課題
これから開発プロセスと、Unreal Engine内でのAmazon GameLiftの実際の使用方法、そして私たちのプラットフォームサービスについてお話しします。ただし、詳細なコードの説明は行いません。必要な要素の概要を簡単に説明させていただきます。
まず最初に、Amazon GameLiftの統合ポイントについて説明します。Unrealゲームサーバー自体での実装だけが必要です。実装が必要な関数とコールバックがいくつかあります。私たちの場合、マッチメイキングの中心的な通信ポイントとしてプラットフォームサービスも使用しています。ゲームクライアント自体は、実質的にGameLiftの存在を意識する必要はありません。マッチメイキングの方法とサーバー情報の取得方法を知っているだけで十分です。
Unrealサーバーの統合には、いくつかの関数とコールバックの実装が必要です。まず最初にInitSDKがあります - GameLiftと通信できるようにする必要があります。ProcessReadyは、UnrealゲームサーバーがGameLiftにセッションのホスト準備が整ったことを通知するものです。起動には1分ほどかかることがありますが、完了すると準備完了の通知を送り返します。OnStartGameSessionは実際にゲームセッションを開始するためのコールバックで、ActivateGameSessionはゲームセッションがプレイヤーを受け入れる準備が整ったことをGameLiftに通知するためのものです。
ProcessEndingはサーバーがシャットダウンすることをGameLiftに通知し、OnProcessTerminateはUnrealゲームサーバーに対して差し迫ったシャットダウンを通知するために使用されるコールバックです。私たちはSpot Instancesを使用しているため、必要に応じてゲームサーバーをシャットダウンできる必要があります。また、ヘルスチェックの失敗時にも使用されます。 OnHealthCheckは、ゲームサーバーの状態がすべて正常に動作しているかをGameLiftに通知するために実装できるコールバックで、何か問題が発生した場合にGameLiftがサーバーを終了できるようにします。
AcceptPlayerSessionとRemovePlayerSessionは、プレイヤーセッションについてGameLiftと確認を行うだけのものです。Acceptはそのプレイヤーが本当にそこにいるべき人かを検証し、Removeはプレイヤーが何らかの理由で退出したことをGameLiftに知らせます。 Huntersでは実装しなかったオプショナルな機能の1つにGetComputeCertificateがあります。ネットワークトラフィックを暗号化したい場合に使用できます。私たちも確かに暗号化は行っていますが、別のアプローチを選択しました。
次の主要な接点はAmazon SNSです。FlexMatchのマッチメイキングリクエストを送信すると、FlexMatchは様々な更新についてSNS通知を返します。私たちのPlatform Servicesでは、これらすべての異なるイベントを監視しています。 最初の1つは分かりやすいMatchmakingSearchingで、そしてMatchmakingSucceededにはマッチとサーバー情報が含まれています。 MatchmakingTimedOutは、ルールが厳しすぎる場合やマッチが見つからない場合に発生する可能性があります。ルールセットには、30秒後や60秒後に異なるパラメータを許容するという拡張ルールを含めることができますが、タイムアウトは存在します。これらすべてを経てもマッチングが成功しない場合、そのチケットに対してマッチメイキングタイムアウトが発生します。
MatchmakingCancelledはキャンセルAPIから来るもので、MatchmakingFailedは一般的な「何か問題が発生した」という通知です。過去2年間で私が見たのは2回だけで、非常にまれです。 Huntersでは使用していませんが、プレイヤーがマッチを承認することも可能です。PotentialMatchCreatedは常に発行されますが、AcceptMatchはマッチが承認された場合、AcceptMatchCompletedは全員が承認してマッチの準備が整ったことを意味します。
私たちのPlatform Servicesの統合には、ルールセット、通知ターゲット、キューを備えたMatchmakerが含まれています。これらすべてがAmazon SNSを通じてPlatform Servicesに送られ、Platform Servicesがクライアントにそれを送信するための接着剤の役割を果たします。クライアントは、マッチが成立すると、Unrealゲームサーバーに接続できるようになります。 実際のフローは、クライアントが起動してすぐにレイテンシーをチェックすることから始まります。FlexMatchに送信する様々なリージョンに対するプレイヤーのレイテンシーを示すために、何らかのレイテンシー計算が必要なので、Pingサーバーを用意しています。
まずクライアントは、全リージョンのレイテンシーを取得するためにそれらのサーバーにPingを送ります。次に、カジュアルキュー、ランクキュー、特別イベントなどの現在アクティブなMatchmaking設定を取得します。これらを取得してプレイヤーに表示します。プレイヤーが選択を行うと、Matchmakingが開始され、そのリクエストは私たちのPlatform Servicesに送られます。
Platform Servicesは、レーティングやマップ選択などのデータを追加し、それをFlexMatchに送信します。FlexMatchからの更新は、Amazon SNSを通じてPlatform Servicesに戻され、さらにクライアントに送り返されます。これによりクライアントはゲームサーバーに接続できるようになります。
Star Wars: Huntersのアーキテクチャ図を見てみましょう。一番下の中央にゲームクライアントがあります。最初にPingサーバーにレイテンシーチェックを送信し、Platform Serviceからマッチ設定を取得し、Matchmakingを開始します。MatchmakingはFlexMatchに送られ、ステータスはSNSを通じてPlatform Servicesに戻り、その結果がゲームクライアントに送り返されます。Unrealゲームサーバーがマッチを開始する際、Platform Servicesを呼び出してアンロック済みコンテンツ、モード情報、設定情報などのプレイヤー情報を取得します。
マッチが終了すると、ゲームサーバーはその情報をPlatform Servicesに送り返し、Platform Servicesはそれを処理して報酬を配布し、その情報をクライアントに送信します。補足として、私たちのPlatform ServicesはキャッシュにElastiCache Redis、データベースにAurora PostgreSQLを使用しており、また一部のZyngaのゲームサービスも利用しています。
これで、ローンチの成功についてお話しできます。私はこれまで何度かゲームのローンチに関わってきましたが、Star Wars: Huntersは私が携わった中で最もスムーズなローンチだったと言えるでしょう。 スケーリングはプレイヤーの需要に応えることができ、キャパシティ不足でプレイヤーがゲームをプレイできないという恐ろしい状況を避けてスタートを切ることができました。ローンチ週には十分なキャパシティを確保でき、それ以降も問題は発生していません。
ローンチ期間中、私たちはスケーリングを活用してコストの最適化を図ることができました。当初の見積もりには調整が必要だったため、目標とするコストレベルまで調整することができました。また、私たちの想定が正確ではないことが判明し、マッチメイキングの所要時間を改善したいと考えた際には、マッチメイキングルールをその場で調整することができました。さらに、Amazon GameLiftチームから素晴らしいサポートを受けることができました。
Amazon GameLift活用の推奨事項と今後の展望
Star Wars: Huntersは、今年6月4日の正式ローンチの前にソフトローンチ期間を設けていました。メトリクスを見ると、現在のプレイヤーセッション数が分かります。左側のソフトローンチ時の数字では、ほんの少数のプレイヤーしか参加していませんでした。ローンチに向けて段階的に拡大していく中で、プレイヤーセッション数は劇的に増加しました。アクティブなゲームセッションも同様のパターンを示しています。グラフの急激な変動は、表示のために3つの異なる集計システムを使用していることによるものです。
FlexMatchの通知ステータスについて、緑色は「検索中」を表しており、マッチを探そうとしたすべてのプレイヤーを示しています。これが急激に上昇しているのが分かります。完了したマッチの数は、検索中のプレイヤー8人に対して1マッチが成立するため、より小さな数値となっています。キャンセルの数も表示されていますが、失敗やタイムアウトの数は非常に少なく、グラフにはほとんど表示されていません。
ローンチを成功に導いた主要な機能には、先ほど触れたマルチリージョンフリートがあります。私たちが展開したいと考えていたすべてのリージョンへのスケールアウトと展開が容易で、管理も簡単でした。多くのリージョンに展開していたため、キャパシティの問題は一切ありませんでした。一部のフリートでEC2 Spot Instancesが利用可能だったことで、これらすべてのフリートを展開することができ、コストの最適化にも役立ちました。これにより、オンデマンドの料金を気にしたり、Reserved Instancesのコストを計算したりすることなく、希望するすべてのリージョンでキャパシティを確保することができました。
私たちは主にAmazon CloudWatchメトリクスを使用してマッチメイキングのメトリクスを監視しています。これはFlexMatchに多くのメトリクスが組み込まれているためです。これによって、マッチメイキングの状況を監視し、想定通りに進んでいないことを発見することができました。また、Amazon GameLiftに関する他の組み込みメトリクスもすべて利用可能です。
先ほども何度か申し上げましたが、FlexMatchは私たちにとって重要な機能でした。マッチメイキングのルールをその場で変更でき、エンジニアでない人でもルールセットを見て理解できることは、非常に大きなメリットでした。このような成功を収めましたが、もちろん課題もありました。 マッチメイキングのルールが期待通りの結果を出してくれなかったのです。最初の数週間は、望ましい結果を得るためにマッチメイキングの要件を徹底的に微調整しました。
複数のテストサイクルを実施する必要があり、そのためにマッチメイキングシミュレーターという社内ツールを開発しました。このツールは、テスト用ルールセットを使用してFlexMatchマッチメーカーの設定全体を起動します。実際のプロダクション環境のプレイヤーから得られたテレメトリーに基づいてチケットを送信し、それをマッチメイキングシミュレーターに反映させて結果を監視し、望ましいレスポンスタイムを達成できるようにルールを調整します。これらはすべてFleetDeployerツールを通じてデプロイされます。
Amazon GameLiftチームのサポートなしでは、これらの成功は達成できませんでした。彼らは私たちがAmazon GameLiftを使用することを決めた時点から、ゲーム開発のライフサイクル全体を通じて私たちと関わってくれました。アーキテクチャレビューを何度も行い、様々な機能や特殊な動作についての質疑応答のための会議も数多く開催しました。彼らは常に時間を取って回答し、Huntersに最適な方法は何か、私たちが何をすべきかを一緒に考えてくれました。ローンチに向けて、適切なクォータと制限が設定されているかを確認するための広範なテストを実施しました。彼らは各リージョンで適切なクォータを設定するのを手伝ってくれ、何か問題が発生した場合に備えてSlackやウォールームで待機してくれました。ありがたいことに、緊急で連絡を取る必要は一度もありませんでした。
Amazon GameLiftの使用を検討されている方々へ、作業を始める前に考慮すべきいくつかの推奨事項をお伝えして締めくくりたいと思います。その一つが、Adrianも言及していたマルチリージョナルフリートのレイテンシーに関する考慮事項です。ゲームにとって許容できるレイテンシーは何かという根本的な質問に答える必要があります。Huntersではこの点について多くの時間を費やし、最終的に許容範囲を決定しました。私たちのゲームはリアルタイムシューターなので要件は具体的でしたが、マルチプレイヤーのターン制ストラテジーゲームであれば、状況は異なるかもしれません。
マッチメイキングの目標とデータ要件について考慮してください。何に基づいてマッチメイキングを行いたいのか、プレイヤー体験にとって何が重要か、そしてそれを実装するために必要なデータは利用可能かということです。レーティングでマッチメイキングを行いたいと言うのは簡単ですが、そのレーティングをどのように計算し、何を考慮に入れるかを考える必要があります。また、ゲームに適したインスタンスタイプとゲームセッションのキャパシティはどれくらいかも考慮が必要です。Huntersでは広範なテストを行い、1インスタンスに4つのゲームサーバーを配置することが適切だと判断しました。これはゲームごとに異なります。私たちは比較的小規模な4対4のシューターですが、1マッチに60人のプレイヤーがいる場合は、1インスタンスに1つのゲームセッションしか配置できないかもしれません。
最後に、Amazon GameLiftの統合についてどの部分を取り入れるか検討する必要があります。私たちはAmazon GameLiftとFlexMatchの両方を全面的に採用しましたが、FlexMatchは必須ではありません。Amazon GameLiftだけを使用することも可能です。Amazon GameLiftを使用する際は、オプションのAPIリストの中からどのAPIを使用するか、何が必要で何が不要かを決める必要があります。また、将来のテスト方法についても考慮が必要です。Janeが本番環境に向けてLoad Testingについて言及しましたが、私たちはこれらのサービスに完全に依存しない構成にしていたため、完全なGame Fleetを立ち上げてテストすることができました。それでは、Steveに引き継ぎたいと思います。
Star Wars: Huntersのローンチから得られた教訓の一つとして、ローカルでAmazon GameLiftに似た環境でテストできる機能が必要だということでした。これはHunterチームには当時利用できませんでしたが、現在はGameLift Anywhereにより、ローカルテスト環境のセットアップが可能になり、ローカルワークステーションをFleet Compute Sourceとして指定し、GameLift Managed Fleetへの移行も容易になりました。Anywhereフリートのセットアップは、ローカルワークステーションをFleet Compute Sourceとして指定し、そのワークステーションを登録するだけで、そのGame Sessionをテスト用にレプリケートできます。GameLift Managed Fleetへの移行準備ができたら、GameLift Anywhereフリートのパラメータを削除して、デプロイ済みのビルドを使用するGameLift Managed Fleetを使用するようサーバーコールを1つ変更するだけです。
GameLiftチームは、今後のゲーム開発においてローカル開発にGameLift Anywhereを使用する予定です。GameLiftを始めるには、UnityまたはUnrealのプラグインをインストールします。スタンドアロンのプラグインが利用可能で、ゲームをビルドするために必要なライブラリがすべて含まれています。C++、C#、またはGoでカスタムゲームエンジンを構築する場合は、ローカルゲーム開発をサポートするSDKが利用可能です。先ほど述べたように、GameLift Anywhereを使用できます。また、開発中はコンソールを使用して、テスト環境でのメトリクス、セッション、プレイヤーの使用状況を追跡できます。
GameLiftを試してみたい場合は、GameLiftフリートのデプロイとキューの構築を通じてサービスの実践的な経験が得られるワークショップが用意されています。直接GameLiftの使用を開始したい場合は、プラグインやSDKを使用してフリートをデプロイし、GitHubにあるGameLiftツールキットを活用できます。このツールキットには、サンプルゲームスクリプトやGameLiftで発生する可能性のある様々な問題を解決するためのコード例が含まれています。また、フリートへのビルドデプロイ用の高速ビルドアップデートツールも含まれています。以上で本日の発表を終わります。ありがとうございました。re:Inventモバイルアプリでアンケートにご協力ください。正式なQ&Aセッションは行いませんが、私たちは今からここで質問にお答えできます。
※ こちらの記事は Amazon Bedrock を利用することで全て自動で作成しています。
※ 生成AI記事によるインターネット汚染の懸念を踏まえ、本記事ではセッション動画を情報量をほぼ変化させずに文字と画像に変換することで、できるだけオリジナルコンテンツそのものの価値を維持しつつ、多言語でのAccessibilityやGooglabilityを高められればと考えています。
Discussion