AWS再入門ブログリレー Amazon GameLift 編

2020.08.19

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

当エントリは弊社コンサルティング部による『AWS 再入門ブログリレー 2020』の 12日目のエントリです。

このブログリレーの企画は、普段 AWS サービスについて最新のネタ・深い/細かいテーマを主に書き連ねてきたメンバーの手によって、 今一度初心に返って、基本的な部分を見つめ直してみよう、解説してみようというコンセプトが含まれています。

AWS をこれから学ぼう!という方にとっては文字通りの入門記事として、またすでに AWS を活用されている方にとっても AWS サービスの再発見や 2020 年のサービスアップデートのキャッチアップの場となればと考えておりますので、ぜひ最後までお付合い頂ければ幸いです。

では、さっそくいってみましょう。12日目のテーマは『Amazon GameLift』です。

Amazon GameLift とは?

GameLiftとは、AWSが提供するマルチプレイヤー向けのマネージド型ゲームサーバサービスになります。
その名の通り、ゲームに特化したサービスになっており、特に複数人のプレイヤーが同じルームに参加して一緒にプレイするゲームに向いています。

マルチプレイ向けのネットワークアーキテクチャとして、クライアントがホスト機能を兼ねつつクライアント同士通信を行う「P2P方式」と、ホストとして専用サーバを用意してゲームを制御しつつ、全てのクライアントを接続させる「クライアントサーバ方式」がありますが、GameLiftは「クライアントサーバ方式」のサーバリソースを管理するサービスになります。

また、GameLiftはマネージドサービスのため、開発者はゲームサーバをプレイヤーの増加に合わせて拡張したり、高可用性を考慮した構成を考える必要が無くなるため、ゲーム開発に専念することが出来ます。

サーバホスティング方式

GameLiftを使用する上で、まず以下2つのゲームサーバホスティング方法があります。

  • カスタムゲームサーバ
  • リアルタイムゲームサーバ

まずは、これらの違いを見ていきましょう。

カスタムゲームサーバについて

カスタムゲームサーバはゲームエンジンを使用してサーバのビルドバイナリを開発し、ゲームサーバに詳細なゲームロジックを実装するようなケースに向いている方法です。

カスタムゲームサーバ方式では、主に以下のコンポーネントがあります。

・ ゲームサーバ
GameLiftによってホスティングされるゲームサーバの事。
カスタムゲームサーバはGameLiftとやり取りを行うため、Amazon GameLift Server SDK を使用して実装する必要があります。
開発言語として C# , C++ for Unreal Engine , C++ をサポートしており、ゲームエンジンではUnity , Unreal Engine , Amazon Lumberyard , C++ C#のライブラリをサポートするエンジン等、主要なゲームエンジンをサポートしています。

・ ゲームセッション
プレイヤーの接続先となるゲームサーバのインスタンスの事。

・ GameLiftサービス
ゲームサーバのリソースを管理するコアサービスの事。
プレイヤー数に合わせリソースを調整したり、ゲームセッションを追加で作成したりします。

・ ゲームクライアント
デバイスで実行されているゲームソフトウェアの事。
ゲームクライアントはセッションに参加する際、ゲームサーバに直接接続を行いますが、自前で実装する必要があります。

・ クライアントサービス
ゲームクライアントとGameLiftサービス間の通信を仲介するサービスの事。
AWS SDKを使用してGameLiftサービスとのやり取りを実装する必要があります。
また、GameLiftサービスからの情報をゲームクライアントへ渡す処理も実装が必要になります。

各コンポーネントは、以下の図のようなやり取りが行われています。

画像引用先 : 20191009 AWS Black Belt Online Amazon GameLiftより

①,② : ゲームクライアントはゲームサーバに接続するため、クライアントサービスを経由してGameLiftサービスにリクエストを送信

③ : GameLiftサービスはリクエストを元にゲームサーバを作成

④,⑤ : ゲームサーバの準備が整い、ゲームセッションが作成された後、セッション情報をクライアントサービス経由でゲームクライアントに送信

⑥ : 取得したセッション情報を元にゲームサーバへ直接接続

以上が、カスタムゲームサーバ方式でのアーキテクチャとなります。

コンポーネントのフレームワーク

上記一部コンポーネントでは、コンポーネント間のやり取りを実装する必要がありますが、GameLiftではそれらを一種のフレームワークのように定めており、このフレームワークに則り実装を進めることでマルチプレイヤーゲームに必要な通信を実装することが可能となっています。

・サーバプロセス起動 / ヘルスチェック時
画像引用先 : 20191009 AWS Black Belt Online Amazon GameLiftより
・サーバプロセス起動時、GameLiftサービスはゲームサーバに対して起動命令を伝える
・ゲームサーバは起動命令を受け取った後、Server SDKの初期化を行い、プロセスの準備が完了したことをServer SDK経由でGameLiftサービスに伝える
・GameLiftサービスはプロセス情報を受け取ると、サーバの状態をアクティブと認識
・その後、GameLiftサービスはゲームサーバに対して定期的にヘルスチェックを実施

・ゲーム開始時

画像引用先 : 20191009 AWS Black Belt Online Amazon GameLiftより
・クライアントサービスでGameLift SDK初期化
・クライアントサービスからGameLiftサービスに対して、AWS SDK経由でセッションをリクエスト
・リクエストを受けたGameLiftサービスはゲームセッションを作成、コールバックとしてゲームサーバはServer SDK経由でセッション情報を送信

・プレイヤー追加時

画像引用先 : 20191009 AWS Black Belt Online Amazon GameLiftより
・クライアントサービスがGameLiftサービスに対してプレイヤーセッションをリクエスト
・リクエストを受けたGameLiftサービスは対象のセッションの状態を確認した上で、セッションのオブジェクト情報を返答
・クライアントサービスがオブジェクト情報をゲームクライアントに渡し、ゲームクライアントはオブジェクト情報を元にゲームサーバに接続
・ゲームサーバはGameLiftサービスに対してServer SDK経由でプレイヤーIDを送信
・GameLiftサービスはプレイヤーIDを受け取ると、プレイヤーセッションはアクティブとを認識

・プレイヤー離脱 / ゲーム停止 / サーバのシャットダウン時

画像引用先 : 20191009 AWS Black Belt Online Amazon GameLiftより
・各操作を行った場合、ゲームサーバからServer SDK経由でGameLiftサービスに情報を送信

カスタムゲームサーバのビルド更新(デプロイ)

カスタムゲームサーバのビルドを更新する場合、ローカル環境のファイルもしくはS3にアップロードしたファイルをAWS CLIでGameLiftにアップロードする必要があります。GameLiftにビルドをアップロードすると、ビルドレコードとして登録されます。
注意したいのが、カスタムゲームサーバではビルドを更新する場合、フリート(後述)も新規にデプロイする必要があります。フリートには固有のフリートIDが割り当てられており、フリートIDをクライアントサービスで使用している場合は再度取得する必要があります。

画像引用先 : 20191009 AWS Black Belt Online Amazon GameLiftより

リアルタイムゲームサーバについて

リアルタイムゲームサーバはカスタムゲームサーバと比べて、アーキテクチャで大きく異なる点としては以下2点になります。
・リアルタイムゲームサーバを数行のNode.jsベースのJavaScriptで実装可能
・ゲームクライアントからリアルタイムゲームサーバへ接続する方法は、Realtime Clinet SDK(C#)で提供

画像引用先 : 20191009 AWS Black Belt Online Amazon GameLiftより

以上の事から、リアルタイムゲームサーバは通信方式に悩まされず迅速にゲームサーバを立ち上げたい場合や、複雑なロジックを必要としないゲームジャンル(カードゲーム等のターン制)に向いている方法になります。

リアルタイムゲームサーバのスクリプト更新(デプロイ)

リアルタイムゲームサーバでは、初回デプロイ時はもちろんフリートの作成は必要になりますが、更新する際にはフリートのデプロイが不要になっています。
新しいスクリプトに更新、反映後のゲームセッションは新しいスクリプトで実行され、更新前のゲームセッションには影響はありません。

画像引用先 : 20191009 AWS Black Belt Online Amazon GameLiftより

ホスティングリソース

次にGameLiftで管理されているホスティングリソースについての説明になります。

フリート

フリートとは、ゲームサーバをデプロイしてゲームセッションをホスティングするEC2インスタンス群形式のホスティングリソースになります。

フリートはゲームの要件に合わせ、以下設計要素を設定していきます。

・オペレーティングシステム
ゲームサーバのOSはデプロイするビルドに合わせ Windows / Amazon Linux から自動的に適用されます。
カスタムゲームサーバビルドは、Windows / Amazon Linux で作成できますが、リアルタイムゲームサーバのスクリプトは Amazon Linux のみとなります。

・インスタンスタイプ
各フリートで使用されるインスタンスタイプを設定します。
インスタンスタイプはフリート作成後に変更することは出来ないため、ゲームサーバビルドのコンピューティング要件や、各インスタンスで実行するプロセス数によって決め、需要に合わせインスタンス数で調整するのが良さそうです。

・フリートタイプ
オンデマンドインスタンス、もしくはスポットインスタンスのどちらかを指定します。 EC2同様、これらは可用性とコストを考慮して選択する必要があります。

スポットインスタンスを選択した場合、キュー(後述)を使用してゲームセッションを配置する仕組みが必須となります。キューを使用することで、FleetIQという機能によってレイテンシーやコスト、中断の可用性が低いインスタンスを使用してゲームセッションを配置します。

・TLS証明書の生成
フリートでTLS証明書の生成を有効/無効で選択します。有効となっている場合はTLS証明書を取得し、それを使用してクライアント/サーバ間の通信を暗号化することが出来ますが、フリートのスケーリングにかかる応答時間が長くなる可能性もあります。

・プロセス管理
各インスタンス毎に実行するゲームサーバプロセスを指定しています。フリート毎に最低1つのサーバプロセスを指定する必要があり、ビルドに複数のプロセスファイルがある場合は、それぞれ設定が必要です。
プロセスを指定する際に必要な情報は以下になります。
起動パス :
ビルドのゲーム実行可能ファイルのパスを入力します。Windowsの場合はC:\Game、Linuxの場合/local/gameから始める必要があります。

起動パラメータ :
起動時にプロセスに渡す値を記入します。

同時プロセス :
指定したプロセスを同時に幾つ実行させるかを指定します。使用しているSDKで制限が異なり、GameLift SDK v2.xは 1 、GameLift SDK v3.x以降は 50 まで指定できます。

・ゲームセッションアクティベーション
各インスタンスで許可されるゲームセッションのアクティベーション数と、新規ゲームセッションがアクティベーションするまでに許容する時間を制限します。
同時ゲームセッション数を制限することで、リソースへの負荷を軽減させ、ゲームサーバや他セッションのパフォーマンス影響を回避することが出来ます。

・EC2ポート容量
プロセスに対するインバウンドトラフィックのアクセス許可を定義できます。

・スケーリングポリシー
フリートは2種類のスケーリングポリシーによってAutoScalingを設定できます。
ターゲット追跡 :
フリートメトリクスの「使用可能なゲームセッションの割合」からインスタンスのスケーリングを行います。
「使用可能なゲームセッションの割合」とはゲームセッションに使用していないサーバのプロセス数の割合となっており、ゲームセッションのバッファを意味します。

ルールベースのスケーリング :
フリートメトリクスを用いた評価式でスケーリングを行います。
ターゲット追跡に比べて限定的なスケーリングルールとなるため、ターゲット追跡の補助という形で設定すると効果的。

エイリアス

エイリアスはフリート固有のフリートIDをエイリアスIDに置き換えることが出来る仕組みになります。
クライアントからゲームセッションに接続する際にフリートIDを使用している場合、フリートが置き換わった場合にフリートIDも変更されてしまいます。そういった場面でエイリアスに置き換えておくことで、クライアント側の更新が不要となります。

画像引用先 : 20191009 AWS Black Belt Online Amazon GameLiftより

エイリアスには2種類のルーティング方法があります。

・シンプルエイリアス
エイリアスに指定されたフリートIDにルーティングを行います。

画像引用先 : 20191009 AWS Black Belt Online Amazon GameLiftより

・ターミナルエイリアス
ターミナルエイリアスはフリートにルーティングは行わず、代わりにクライアント側に終了メッセージを返すことで、クライアント側に更新を促したり、フリートへの新規接続を防ぐことができます。

画像引用先 : 20191009 AWS Black Belt Online Amazon GameLiftより

キュー

キューとは、複数リージョンに跨りゲームセッションを配置するフリート、もしくはエイリアスの候補リストになります。クライアントからゲームサーバに接続する際に、フリートIDやエイリアス以外に、キューも使用することが出来ます。

キューは FeetIQ と呼ばれる仕組みによってプレイヤーとのレイテンシーやリージョンの優先順位の設定、フリートでスポットインスタンスを利用している場合はコストや中断率等を考慮してゲームセッションの配置先を選択します。

画像引用先 : 20191009 AWS Black Belt Online Amazon GameLiftより

FlexMatch

FlexMatchとは、GameLiftで使用できるカスタマイズ可能なマッチメイキングシステムの事です。
マルチプレイヤーゲームではマッチメイキングを行う際に、レベルの近いプレイヤー同士をマッチングさせたり、チーム同士の人数差が出ないようにマッチングさせたり等、ゲームの仕様に合わせたマッチメイキングが実現できます。

画像引用先 : 20191009 AWS Black Belt Online Amazon GameLiftより

サンプルゲームの起動

GameLiftにはカスタムゲームサーバ、リアルタイムゲームサーバでそれぞれサンプルのゲームが提供されています。今回はカスタムゲームサーバのサンプルゲームを試してみました。

カスタムゲームサーバのサンプルゲームは非常に簡単に体験することが出来ます。
まず、AWSマネージドコンソールで GameLift を開き、GameLiftのメニューから「カスタムゲームサーバサンプル」を開くとサンプルゲームを起動させるまでのステップが表示されるので、それらを行っていきます。

ステップ4Bin64.Release\MultiplayerProjectLauncher.exe を起動し、プレイヤーセッショントークンを生成してゲーム内で入力することで、サンプルゲームのセッションに参加することが出来ました。

ステップ5で作成したフリートのダッシュボードを確認すると、メトリクスにプレイヤーセッション数やアクティブなゲームセッション数が表示されていることがわかります。

最後に

以上、『AWS 再入門ブログリレー 2020』の 12日目のエントリ『Amazon GameLift』編でした。今回サンプルゲームとしてカスタムゲームサーバのサンプルを試してみましたが、リアルタイムゲームサーバのサンプルはより実践的なものとなっています。もし興味がある方はこちらを参考にやってみてください!私も時間を見つけて試してみたいと思います。
明日 (8/20) は たぬき さんの「AWS Chatbot」の予定です。お楽しみに!!