Amazon GameLift と Agones それぞれの特徴を横並びで見てみよう

[AWS for Games Advent Calendar 2023](https://qiita.com/advent-calendar/2023/aws-for-games) の 2日目の記事です。

皆さん、マルチプレイヤーゲーム開発、してますか？
マルチプレイヤーゲームではプレイヤー間でネットワーク通信が必要ですが、その通信を中継するサーバーは専用ゲームサーバーと呼ばれます。「マルチプレイヤーゲームのための専用ゲームサーバーをホスティングするためのサービス」としてAWSでは[Amazon GameLift](https://aws.amazon.com/jp/gamelift/)を提供していますが、kubernetes上で動作するOSSであるAgonesをAmazon EKS(Elastic Kubernetes Service)のクラスターへデプロイして利用するという方法もあります。

この記事は、Amazon GameLiftとAgonesのどちらかしか知らない、あるいはどちらもなんとなくは知っているけど詳しいことはあまり、、という方に向けて、それぞれの概要を横並びで把握できることを目的とします。

※（わかる方向けの注釈）本記事内で特に言及なくGameLiftと言った場合、GameLift FleetIQでもGameLift Anywhereでもない、StandardなGameLift (managed EC2 fleet)の機能を指すこととします。

※専用ゲームサーバーとは何か？については、[Agones公式ドキュメントの必要な事前知識のページの情報](https://agones.dev/site/docs/prerequisite-knowledge/#dedicated-game-servers)がとても参考になるので是非ご確認ください。

## TL;DR

**Agonesが向いているケース**

- kubernetesの構築運用は自前で可能
- kubernetesのエコシステムを活用したい
- 柔軟な機能性が欲しい
- 小さなゲームサーバーでリソース有効活用したい

**GameLiftが向いているケース**

- インフラやゲームサーバー管理の機能はマネージド機能を活用して、アプリ開発に集中したい
- マッチメイキングもマネージド機能で使いたい
- スポットインスタンスを活用したコスト最適化を容易に行いたい
- 容易にグローバル展開したい

## GameLiftとAgonesの各種リソースについて

まずGameLiftとAgonesのリソースについて確認します。概ね対応付けができ、以下のようなイメージになります。

![image (27).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20539/42c3b755-4c04-bdce-013e-2b27f57d8cdf.png)
![image (28).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20539/2a906ec1-6bbc-659b-4999-24a020a85dff.png)

主要な部分だけ説明します。
- Fleet
    - ゲームサーバーのグループのイメージで、スケーリングのまとまった単位になります。コンピュートリソースの実体は、GameLiftの場合はサービス側が管理しているEC2インスタンス、Agonesの場合はkubernetesクラスタ―のノード、つまりEKSの場合はEC2インスタンスとなります。
- GameServer
    - 実際にサーバーアプリが動くプロセスです。GameLiftの場合はサーバーアプリのプロセス、Agonesの場合はGameServerというリソース（実体はPodのようなもの）になります。
- ゲームサーバーアロケーション
    - ゲームサーバーから一つ選択してプレイヤーが接続してゲームを開始できるようにする処理です。GameLiftの場合は [CreateGameSession](https://docs.aws.amazon.com/gamelift/latest/apireference/API_CreateGameSession.html) や [StartGameSessionPlacement](https://docs.aws.amazon.com/gamelift/latest/apireference/API_StartGameSessionPlacement.html) といったAPIを介してゲームセッションを確保します。Agonesでは[GameServerAllocation](https://agones.dev/site/docs/reference/gameserverallocation/)というリソースの作成という形で確保します。
- マッチメイキング
    - マルチプレイヤーゲームでは一緒にプレイするプレイヤーをマッチングするためのマッチメイキングを組むことが多いです。この場合は、マッチングしたプレイヤーらがプレイするためのゲームセッションをゲームサーバーアロケーションで確保するイメージです。

## GameLiftもAgonesもやってくれること

### ゲームサーバーのスケーリング管理

ゲームサーバーにプレイヤーが接続し実際にプレイが開始した後、接続を受け入れられるゲームサーバーの数が少なくなってきたら、新たにゲームサーバーのプロセスを立ち上げることでスケールアウトが可能です。また、プレイが終了してプレイヤーが誰も接続していないゲームサーバーは終了してスケールインできます。これらのスケールアウト・インのトリガーの管理と、トリガー判断のためのメトリクス取得・監視を行ってくれます。GameLiftでは[Fleetのオートスケーリング設定](https://docs.aws.amazon.com/gamelift/latest/developerguide/fleets-autoscaling.html)にて、Agonesでは[Fleet Autoscaler](https://agones.dev/site/docs/reference/fleetautoscaler/)にて設定できます。

### ゲームセッション配置の最適化（パッキング）

ゲームサーバーが動作する下回りのインスタンスのスケーリングを考えたとき、効率よくスケールインするためには、ゲームサーバーが動作するインスタンスをなるべくまとめる配置戦略が有効です。これをパッキングと言ったりしますが、GameLiftもAgonesもパッキングを意識した配置戦略をとってくれます。

### ゲームサーバーの終了保護

ゲームサーバーはプレイヤーがまだゲームを遊んでいたら終了してはいけないので、スケールインから保護する必要があります。GameLiftもAgonesも保護の仕組みを提供してくれます。

## GameLiftにメリットがありそうなところ

### スポットインスタンスの活用

EC2のスポットインスタンスは、AWSの空きキャパシティを活用することで通常のインスタンス（オンデマンドインスタンス）に比べて最大90%低い単価で利用できる購入オプションです。ただし高い割引率のトレードオフとして、強制的な中断が発生する可能性があります。専用ゲームサーバーは、プレイヤーが接続している間は基本的に中断が許されないため通常スポットインスタンスを活用するのは難しいですが、セッションベースのゲームのように一回のプレイ時間が短め（数分～60分以内など）であればリスクを抑えつつ利用できる可能性があります。
GameLiftにはFleetIQという機能があり、できるだけ中断可能性の低いインスタンスにゲームセッションを配置する機能を持っています。これにより中断リスクを最小限に抑えながらスポットインスタンスを利用したコスト最低化が可能です。
Agonesでもスポットインスタンスの利用自体は可能です。Karpenterを使うことでオンデマンド・スポットインスタンス混在のクラスタを組むことができます。Karpenterを使うとノードのスケーリング高速化も狙えます。Karpenter + AgonesについてはSpring_MTさんによる昨年のアドベントカレンダー記事「[KarpenterとGraviton2を使った大規模ゲーム向けAgones on EKS を立ち上げるサンプル multi-cluster-allocation-demo-for-agones-on-eks の紹介](https://spring-mt.hatenablog.com/entry/2022/12/18/221726)」もご確認ください。

### フリートのマルチリージョン対応

マルチプレイヤーゲームをグローバル展開する場合、複数のリージョンにゲームサーバーを配置して、レイテンシをベースに最適なリージョンのゲームサーバーを選択するとプレイヤー体験が向上します。GameLiftは[Multi-location fleets](https://docs.aws.amazon.com/gamelift/latest/developerguide/gamelift-regions.html)の機能を提供しており、複数のリージョンをフリートに含めることが可能です。Agonesでも[ping service](https://agones.dev/site/docs/guides/ping-service/)でレイテンシを測り、[Multi-cluster Allocation](https://agones.dev/site/docs/advanced/multi-cluster-allocation/)で複数クラスタへのAllocationを管理できるようにすることで同様のことが実現できるかもしれませんが、私自身まだしっかり調査できていません。いずれにせよこの点は、現時点ではGameLiftのほうがシンプルに構成できそうです。

### マッチメイキングサービス

GameLiftではFlexMatchというマッチメイキングのためのマネージドサービスも提供されています。GameLift（のmanaged EC2 fleet）を利用するとFlexMatchも無料で利用できるため、マッチメイキングも含めて開発・運用負荷を下げたい場合はメリットのある選択肢となります。
参考記事：[Amazon GameLift FlexMatch であのゲームやこのゲームと同じマッチメイキングをやってみた](https://aws.amazon.com/jp/builders-flash/202212/gamelift-flexmatch)

Agonesにはマッチメイキング機能は含まれていないので、別のサービスと組み合わせて利用することになります。[Open Match](https://open-match.dev/site/)という同じくk8s上で利用できるOSSのマッチメイキングサービスをご存じの方も多いと思います。また、GameLiftのFlexMatchは単独（standalone）での利用も可能なので、Agonesと組み合わせての利用もアリです。（ただしFlexMatch(standalone)の利用料は別途発生します）
参考記事：[Amazon GameLift FlexMatch でマッチメイキング“だけ”動かしてみる](https://qiita.com/oreo367/items/059ea0cfd9ad04ef82da)

### プレイヤーセッションの管理

GameLiftではゲームセッションの管理だけでなく、ゲームセッションに接続するプレイヤーのセッション管理も行えます。プレイヤーセッション管理機能があることで、ゲームセッションに接続しようとするユーザーの検証や許可・拒否の判断を入れることができたり、プレイヤーのメタデータをもとにゲームセッションの配置先を調整したりと、高度な管理が可能となります。（参考：[How players connect to games](https://docs.aws.amazon.com/gamelift/latest/developerguide/game-sessions-intro.html)）

Agonesでも[PlayerTracking](https://agones.dev/site/docs/guides/player-tracking/
)の機能がありますが、2023/12時点でAlpha機能である点に注意です。

## Agonesにメリットがありそうなところ

### コンテナでのデプロイ

Agonesはk8s上のサービスなので、サーバーアプリのビルド・テスト・デプロイもコンテナの文化に則って行えます。コンテナでの開発に慣れたdeveloperにとってはメリットです。
なおStandardなGameLiftでは現状コンテナは使えませんが、[GameLift FleetIQ](https://docs.aws.amazon.com/gamelift/latest/fleetiqguide/gsg-intro.html)や[GameLift Anywhere](https://aws.amazon.com/jp/blogs/news/introducing-amazon-gamelift-anywhere-run-your-game-servers-on-your-own-infrastructure/)というオプションとAmazon ECSを組み合わせて構成することでコンテナも利用できると考えられます。

### OSSであること

AgonesはOSSなので、ユーザー自身がコントリビュートすることで主体的に機能改善できるのはメリットです。

### リソース効率

GameLiftでは、2023/12時点では、下回りのEC2インスタンス一台につき最大50ゲームサーバープロセスまでという制限があります。また一つのゲームセッションに同時接続可能なプレイヤー数は200までとなっています。（参考：[Amazon GameLift endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/gamelift.html#limits_gamelift)）
Agonesにはこういった制限は基本的になく、使う側の構成次第で調整できます。この観点から、一つのゲームサーバープロセスがあまりリソースを消費しない軽いものだったら、Agonesの方が集約率を高められ、高いリソース効率を達成できる可能性があります。

## その他

### 対応SDK

2023/12時点でGameLiftが対応している言語はC++(Unreal Engine含む), C#(.NET6, Unity含む), Goとなっています。C# .NET6やGoに対応したことで、軽量なサーバーでの利用や[MagicOnion](https://github.com/Cysharp/MagicOnion)との統合も可能になりました。
AgonesはUnreal Engine, Unity, C++, C#, Node.js, Go, Rust, RESTに対応しています。RESTに対応しているので非対応言語でのラッパーの独自作成も容易ですし、protoファイルが提供されているので[gRPCのSDK生成も可能](https://agones.dev/site/docs/guides/client-sdks/)になっているため、SDKの幅広さがメリットと言えそうです。

### 運用性（ゲームサーバーのデプロイの仕組み、監視のための各種メトリクスの収集、ログ収集の仕組みなど）

Agonesの場合、これらはk8sのエコシステムに乗っかります。k8sの運用にすでに慣れている場合はナレッジ流用できるためAgones利用におけるメリットとなりますが、逆に慣れていないとハードルが高くなる要因にもなり得ます。
GameLiftの場合はこれらも、GameLiftおよび他のAWSサービスとの連携という形でマネージドな機能が提供されます。

アップデート運用についても、Agonesの場合はk8sとAgones両方のアップデート運用が必要になります。GameLiftの場合は、アップデート運用としては、アプリに組み込むSDKのバージョンを上げる形になるので、アプリのアップデート運用に含まれます。

## まとめ

GameLiftとAgonesそれぞれの特徴を横並びで見てみました。細かい点もありましたが、選定観点として大きいのはやはり、"k8s上での運用"をどう捉えるか、どのくらいマネージド機能を活用したいか、といった点になりそうです。構築運用負荷と柔軟性のトレードオフをどう選択するかとも言えそうです。
本記事はあくまで2023/12時点での状況をまとめたものであり、どちらのサービス（プロダクト）も今後も継続して発展していくことと思いますので、それぞれのアップデートから目が離せませんね。

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