[レポート]Unity+AWSによるマネージドなゲームサーバ運用 #AmazonGameTech #AmznGameTechJP

2019.11.20

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Unity+AWSによるマネージドなゲームサーバ運用

2019年11月20日(水)にアマゾン目黒オフィスでアマゾンウェブサービス社の自社イベント「Amazon Game Developers Conference」が開催されました。

本記事は、セッション「Unity+AWSによるマネージドなゲームサーバ運用」をレポートします。

スピーカー

株式会社ミクシィ ゲームエンジニア 小端 みより 氏

セッション概要

一般的なリレー通信によるマルチプレイの実装は、敷居が低い一方でチート耐性の低さや大人数に対応できないなどの問題があります。 弊社ではより本格的なマルチプレイゲーム開発のためのゲームサーバをUnityで実装し、チート耐性と大人数、大規模なゲームプレイを両立する取り組みを行っており、その実装例および、GameLiftやLambdaといったAWSの強力かつマネージドなソリューションによって運用するお話をさせて頂きたいと思います。

レポート

これまでのマルチプレイ実装

クライアント処理型

P2P型の通信モデルで、サーバーは原則的にロジックに関与しない

リレーサーバーを用いたマルチプレイ実装

  • その一方で、クライアント処理だからチート対策が大変

  • 通信もP2Pだと不安定になりがち

  • 実装が複雑化しやすく、大人数/大規模なタイトル開発は難しい

専用サーバー開発を開発

サーバー実装はクライアントと言語が違うイメージ(Goとか)

クライアント処理の手軽さに及ばないなどのイメージがある。

Unity Server = Unityで実装

言語はC#

Animation, Physics, AIをそのまま活用することもできる

サーバーとクライアントを同時に単一プロジェクトで開発することも可能

→クライアントエンジニアとサーバーサイドエンジニアみたいに分けなくてもOK

目標を高めに設定

  • アクション性の高いオンラインマルチゲーム

  • サーバーとクライアントを単一Unityプロジェクト

  • サーバーはLinux クライアントはIOS/Android

  • サーバーはクラウドで20人以上の同時接続

サーバー集中処理型とは?

  • 入力が非同期的に行われて、サーバーが入力に基づいてゲームを更新する

  • サーバーは一定期間ごとにクライアントに結果を送信する、シンプルな設計

  • 設計がシンプルにできるメリット

懸念点

  • シンプルな実装だけど、ネットワーク遅延の影響が大きい

  • アクションゲームならゲームとして成立するの?

どうやって解決したか

→結論: ネットワーク遅延の影響が大きくなるから高品質なゲームインフラが必要

→Amazon Game Liftだと解決するかも?

Game Lift とは

  • ゲームサーバー特化のマネージドサービス

  • デプロイするだけでサーバーのプロセス起動/監視、スケーリングをまるっとやってくれる

  • AWSインフラなので、「高品質なゲームインフラ」、通信レイテンシを下げて高可用性。

  • リアルタイムサーバー(新機能)

→JavaScriptによる簡易的な実装

  • 「カスタムゲームサーバー」(今回話す内容) →従来型のゲームサーバーで、本格的なゲーム開発に適する

カスタムゲームサーバー

GameLift Server SDKの導入

SDKをビルドしてUnityにDLLをインポート

GameLift Server APIの呼び出し/コールバック処理実装

セッションやヘルスチェックのコールバック処理などの実装が必要

ドキュメント

GameLiftのコールバックは別スレッドで実行されるが、Unityはシングルスレッドなので、コールバック処理内でUnityのコードを利用したい場合はDispatch処理を行いう必要がある

UnitySynchronizationContextを使う

// メインスレッド
mySncContext = UnitySynchronizationContext.Current

// 別スレッド
mySncContext.Post(MyCallback, params)

Unityでサーバーをビルドする場合、WindowsとLinuxを選択するが、Linuxの方が安くて早くていい。

Linux EC2インスタンスではGPUをサポートしてない

GPUを使おうとしてクラッシュするのでBuildOptions.EnableHeadlessModeをする

buildOptions += BuildOptions.EnableHeadlessMode;

Game Liftへサーバーをデプロイ

AWS CLIを利用してGame Liftをデプロイする。

カスタムゲームサーバービルドを Amazon GameLift にアップロードする

デプロイすると、ビルド一覧に表示され、フリートの作成をする

フリートとは?

  • ビルドに紐づいてるEC2インスタンス群

  • EC2インスタンス状で複数サーバープロセスが起動する、スケーリングはEC2インスタンス単位

EC2インスタンスタイプは様々なものがあるが、Spotインスタンスを利用するとAWS内の余っているリソースを活用するため、安く使える。

サーバープロセスの起動パス、起動パラメータ(引数)、同時プロセスの設定が可能

ポート開放、ソースIPの設定をする。

GameLift上のサーバーを利用する

どうやってGame Clientから使うのか?

AWS SDKを使って GameLift ServiceAPIのCreateGameSession, CreatePlayerSession, SearchGameSessionなどを利用してGameLift上で動いているサーバーに接続する。

C#版も動いているので、Unityから叩くこともできる。

→相性問題、セキュリティー上の問題などもあるからバックエンドで実装することが望ましい

AWS Lambdaを利用してバックエンドを実装することができる。

関数単位の実装ができ、サーバーを意識する必要はない。

Ruby/Python/C#などの複数言語も利用可能。

Visual Studio プラグインもある。

Lambdaを直接AWSにデプロイ、テストをできる

AWS Toolkit for Visual Studio

API GatewayとLambdaを利用して、RESTAPIを簡単に実装できる。

そのほか

Debug.Logの出力

GameLiftのサーバーログ保存機能がある。

→ゲームセッション単位で保存と出力

Debug.LogをGameLiftに送ることもできる。

(まとめ)

UnityとAWSの組み合わせの相性が良い、オンラインマルチプレイ開発の比較的簡単に開発運用ができる

オンラインマルチプレイ開発の敷居が下がり、新しいゲーム性を持つタイトルが生まれるかも

まとめ

近年リアルタイム通信が必要なゲームが増えてきましたが、Game Liftを活用することで、簡単に安く高可用性なAWSインフラをゲーム向けに展開する具体的な例を聞けてとても面白かったです!