GameLift FleetIQはわれわれの何を解決してくれるものなのか？

本ブログ記事は[AWS & Game Advent Calendar 2020](https://qiita.com/advent-calendar/2020/aws-game)の12/1分の記事です。

2020/08/27にリリースされた、Amazon GameLift FleetIQをご存知でしょうか？そもそもGameLiftって何？と思われる方が多いかもしれません。

最近では、日本の各ゲーム会社からもどんどん新しいオンラインマルチのタイトルがリリースされていますが、そんなゲームを開発している方々に一度チェックしていただきたいサービスになります。

GameLift FleetIQは昔からあったGameLiftの一部の機能を切り出したものになりますが、今回はそのGameLift FleetIQにスコープをしぼってざっくりと解説します。


## そもそもAmazon GameLiftとはどんなサービスなのか？

Amazon GameLiftは、AWSのサービスの一つでマルチプレイオンラインゲームに必要となる専用ゲームサーバーを管理するためにいろいろな機能を提供しているAWSの１サービスです。プレイヤー同士が対戦・協力するために一箇所に集まるための場を提供しているサーバーを専用ゲームサーバーと呼びます。このサーバー上で稼働するプロセスは、よくあるステートレスなWebアプリケーションとは異なり、ステートをサーバー内で保持(=ステートフル)し、複数のゲームクライアントからの永続的なネットワーク接続を直接受け付けます。専用ゲームサーバーではゲームクライアントに対し、プレイ可能なゲームプロセスに直接ネットワーク接続してもらうためのIPを伝える必要があります。そのためには、どのプロセスが利用可能なのか、そのプロセスが稼働しているゲームサーバーのIPアドレスやプロセスのポート番号など、ステータス情報などの管理が必要で、プレイヤーからのリクエストに応じて利用できるゲームプロセスをクライアントにレスポンスする必要があります。

![game_server.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32775/f0f7e6e2-fdc0-a53c-a4a9-06b5b54c6961.png)

AWSだとこの手の機能はコントロールプレーンとよばれ、もし自前する場合は専用ゲームサーバーとゲームクライアントに対するAPIやステータスを管理するためのDBなどを実装する必要がありますが、AWSのGameLiftではサービスとしてこれらの機能をマネージドとして提供しています。

また、プレイヤー数によってゲームサーバーをスケールさせる必要もあります。スケールアウトはシンプルにサーバーを追加するだけですが、スケールインはどうでしょう？ゲームプレイ中にさくっとインスタンスを削除するわけにはいかないので、そのような状況を避けるための安全な仕組みが必要になります。具体的には、削除予定のインスタンスに新しいプレイヤーを割り当てない、プレイ中のゲームが終了するまで待つ(ドレイニング）、そしてそもそも効率的にサーバを削除できるようになるべく特定のゲームサーバーにゲームを割り当てていく（いろんなゲームサーバーにゲームが散らばって配置されることでサーバーが削除しにくい状況になることを防ぐ）などの制御が必要になります。そしてこれらのスケールに関する機能もGameLiftが提供しています。

以上はGameLiftのフリート管理と呼ばれますが、それ以外にもマルチプレイオンラインゲームを提供するために必要なマッチメイキングなどの便利機能も用意されています。

ゲームの中でも特定のユースケースをターゲットとしている点で、GameLiftはAWSの中でユニークなサービスです。

## そしてGameLift FleetIQとは？

本記事の本題となるGameLift FleetIQは、前述したAmazon GameLiftのフリート管理と一緒にまるごと独立して切り出したものです。

前述のGameLiftは専用ゲームサーバー上で動くプロセス(GameLiftではビルドと呼ぶ)はC++, C#, Node.js(リアルタイムサーバーという機能)のみをサポートしており、さらにGameLiftが提供するデプロイ機構を利用します。この仕様はUnreal EngineやUnityなどのゲームエンジンを利用してサーバー側のコードを開発する場合などでは充分ですが、最近だとサーバーはクライアントとは別のプログラム言語を利用したい！コンテナを利用したい！などの要件も多くなってきました。そのため、ゲームサーバー上で稼働するプロセスの言語や形態を問わず、ユーザ側が自由にプロセスのデプロイもできるように柔軟性を高めつつ、かつGameLiftのフリート管理のメリットであるマネージドなコントロールプレーンを提供するためにGameLift FleetIQが生まれました。

AgonesなどのOSSでもこのようなコントロールプレーンの機能を提供していたりしますが、さらにFleetIQにはAWSならではの価値を提供してくれるうれしい機能があります。それはスポットインスタンスの活用です。

スポットインスタントとは、使われていない余剰インスタンスを通常のオンデマンド価格に比べ最大90%も安く利用できるメニューです。価格が安いのは非常に魅力的ですが、余剰インスタンスを利用しているという性質上、インスタンスの需要が増えてくると稼働中に中断というイベントが発生し、２分後に停止されることがあります。この中断のリスク回避のために、複数のインスタンスタイプを設定して中断を局所化したり、中断したときに自動でリカバリできるようなテクニックが推奨されています。しかし、このテクニックでは中断したときに別のインスタンスタイプでスポットインスタンスとして起動するということはできますが、そもそも中断自体を防いだり、頻度を下げたりすることはできません。

クライアントから常時接続を受け付けているようなステートフルなゲームサーバーでスポットインスタンスを利用すると、この中断による割り込みによってプレイヤーがゲームプレイ中に強制的に追い出されてしまうなど深刻なユーザエクスペリエンスの低下につながる可能性があり、スポットインスタンスの利用は難しいという話を良く聞きます。中断までに2分間の猶予はありますが、ほとんどの場合は１ゲームあたり2分以上のプレイ時間であるため、その間にゲームを終わらせることも難しいです。

このように、ゲームサーバーのコストは下げたい、でもスポットを使うことは難しい、もうオンデマンド使うしかないか.....という状況をGameLift FleetIQは中断しにくいスポットインスタンスを選択するというユニークなアプローチで解決しています。

GameLiftではスポットインスタンスの中断率をヒューリスティックに予測するという機能が備わっており、あらかじめ設定したインスタンスタイプのリストの中から将来の中断発生率が低く、かつコストがインスタンスを起動してくれるというすぐれものです。新しいインスタンス起動時はもちろん、プレイヤーのリクエストをなるべく安全で安いインスタンスに誘導し、中断率が高そうなインスタンスはゲームの終了を待って削除、新しい安全なインスタンスを起動するというすぐれものです。このFleetIQによってゲームサーバーの平均コストを下げることができます。

どれくらいの中断発生率なのか？についてはこちらの[ブログ記事](https://aws.amazon.com/jp/blogs/news/2020-gamelift-update-preview/)で実際のユーザの方からコメントいただいています。

> 同様に、PanzerdogのCEOであるAlexey Sazonov氏は、次のように述べています。“Amazon GameLiftとスポットインスタンスを併用することで、ゲーム「Tacticool」のローンチを加速させ、コストを削減することができました。私たちは1,800万回以上のゲームセッションの中、中断を経験したのはわずか 0.004% であり、専用サーバにおける優れたプレイヤー体験を維持ながら大幅なコスト削減を実現できました。”

ということで、GameLift FleetIQとは、専用ゲームサーバーのステータスなどの面倒な管理もやってくれて、加えてゲームサーバーで利用が難しいとされてきたスポットインスタンスも使えるすぐれものであると言えると思います。

専用ゲームサーバーの管理は[Agones](https://agones.dev/site/)などでもやってくれると思いますが、そのサーバーのスケーリングやプレイヤーに対するゲームの割当もスポットインスタンスの落ちにくさと価格を見ながらよしなにやってくれるところがこのサービスの魅力だと思っています。

## GameLift FleetIQのオペレーション

必要最低限のオペレーションをこちらに書いてみました。APIのコール元がそれぞれ異なることに注意してください。補足として、GameLift上ではゲームサーバー上で起動するゲームプロセスのことを"Game Server"と呼んでおり、API名にあるGameLiftのGameServerもプロセスのことを指しています。

![GameLift_FleetIQ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32775/2a0582e6-565c-4305-6a08-aad6e4a49ddc.png)


**環境準備：**まず、専用ゲームサーバーをまとめて管理するゲームサーバーグループを作ります。通常はAdministrator(管理者)が操作を行います。ゲームサーバーグループはAWSのAuto Scaling Groupをラップしているものです。数を指定することで必要な数のゲームサーバーのインスタンスが起動します。

**ゲームサーバーの起動：**ゲームサーバーのインスタンスが起動によりゲームプロセスが起動、完了したらRegisterGameServer()をコールし、GameLiftに対してプレイヤーを受付可能な状態であることを通知します。このとき、ゲームサーバーのIPとプロセスがListenしているポートをコネクション情報として付与します。

**ゲームプレイ開始時：**ご自身のゲームのマッチメイキングなどの機能をもっている部分をゲームバックエンドとし、プレイヤーからのリクエストをもとに、ゲームプロセスをアサインするためのリクエストClaimGameServer()をコールします。GameLiftからは利用可能なゲームプロセスのIPとポートがレスポンスとして返答されます。

**ゲームプレイ中：**プレイヤーがゲームを開始したら、ゲームプロセスから自身が利用中であることを知らせるためにUpdateGameServer()をコールします。（その後1分以内ごとに定期的にステータスをアップデートする必要があります。）

**ゲームプレイ終了時：**ゲームプロセスは結果などを永続化したあと、DeregisterGameServer()をコールしてゲームサーバーのリストから自身を削除。もしプロセスをリサイクルする場合は再度RegisterGameServer()をコール。

上記以外にもAPIが用意されています。くわしくは[こちら](https://docs.aws.amazon.com/gamelift/latest/fleetiqguide/reference-awssdk-fleetiq.html)。

## 注意点

GameLift FleetIQを利用する前に知っておいていただきたい注意点となります。

- FleetIQによって中断率が低い安全なインスタンスを選択してくれますが、中断しないわけではありません。中断はするということ前提で、割り込みが発生したときにサーバーの情報を退避するとか、プレイヤーに通知するなどの処理は必要です。
- FleetIQはすべてのインスタンスタイプに対応しているわけではありません。現在対応しているインスタンスタイプは、GameLiftが対応しているc4, c5/c5a, r4, r5/r5a, m4, m5/m5aになります。
- GameLift FleetIQの操作はすべてCLIもしくはSDKからのみとなります。マネージメントコンソールには対応していません。。。

## GameLiftやGameLift FleetIQとは別の選択肢

GameLiftやGameLift FleetIQとは別の選択肢を取ったほうがいいユースケースを考察してみます。

コンテナであれば、こちらのようにECS/Fargateを利用してそもそもコンテナを実行するインスタンスレイヤーを意識しない方法もありかと思います。ただし、ECSのTaskとして動作するゲームプロセスの管理はこちらの例のように自前で実装する必要があります。(ちょうど今日ブログが出てました）

[Game Server Hosting on AWS Fargate](https://aws.amazon.com/jp/blogs/gametech/game-server-hosting-on-aws-fargate/)
[AWS Samples: Fargate Game Servers](https://github.com/aws-samples/fargate-game-servers)

MMORPGのように1つのゲームプロセスでホストするプレイヤー数が多く、かつネットワーク接続時間も比較的長時間であるようなものはそもそもGameLiftは向いていません。MMORPGではサーバーをエリアごとに垂直分割するケースが多く、プレイヤーの行動によって接続するサーバーが変化することが多いでしょう。しかし、クエストなどで一時的に複数のプレイヤーが特定のゲーム部屋に集まるようなときには利用できそうです。

## おすすめコンテンツ

GameLift FleetIQを利用する前にチェックいただきたいコンテンツを紹介します。

[Game Tech Learning Path: Using GameLift FleetIQ for Game Servers(日本語版)](https://www.aws.training/Details/eLearning?id=63149)
90分のトレーニングコンテンツです。非常に詳しく書かれているので、GameLift FleetIQの利用を検討されている方はまずこちらをご覧ください。無料です。

[公式ドキュメント：GameLift FleetIQガイド](https://docs.aws.amazon.com/ja_jp/gamelift/latest/developerguide/gsg-intro.html)
GameLift FleetIQの細かい仕様はこちらで確認してください。

[GameLiftサンプル(五目ならべ）](https://github.com/aws-samples/aws-gamelift-sample)
五目並べを題材にしたGameLiftの実装サンプルです。ゲームバックエンドもAPI GatewayやLambdaを使ったサーバレス構成で、マルチプレイオンラインゲームのシステム全体について学習することができます。

[GameLiftサンプル(Unity)](https://github.com/aws-samples/amazon-gamelift-unity)
Unityに特化したGameLiftの実装サンプルです。Unity Projectがそのまま利用できます。

## さいごに

いかがでしたでしょうか？最近良く聞かれるGameLift FleetIQの概要について専用ゲームサーバーのフリート管理という観点で解説してみました。詳しい実装などについてはお気軽にAWSのソリューションアーキテクトにお問い合わせください。


(免責) 本記事の内容はあくまでも個人の意見であり、所属する企業や団体は関係ございません。