[2020/12/30 追記] Playfabのマルチプレイヤーサーバー2.0は無料プランからでも使える旨を修正
前置きの前置き
この前、仕事でUnityでMLAPIにGameLiftを統合して接続するという事をやりました。
GameLiftは個人で使うようなサービスではないからか、ネット上にあまり情報が無く、調べるのが大変でした。公式のドキュメントはありますが、UnityとかAWSのドキュメントってなんだか分からん専門用語が飛び交って、意味不明過ぎるといつも思うんですが、どうでしょうか。
だから、いつもはとりあえずサンプル動かしてみて、はあはあなるほどね。って動きを見て理解するしかないのですが、GameLiftはUnityのサンプルはあるっちゃるのですが、かなり微妙なシロモノなので見てもよく分かりませんでした。
「Amazonはこんな訳分らんドキュメントとサンプルしか用意しないで、ホントにサービスを使わせる気があるのかよ!」と何度も思いました。
そういうわけで、せっかく苦労してGameLiftの使い方を理解できたので、記事に書いておけば他の人の参考になるかなと考えました。
話が長くなりそうなので、いくつかの章に分けるつもりですが、GameLiftの概要の説明から初めて、最終的にはMLAPIにGameLiftを統合するとこの解説まで書けたらいいなと思ってます。
GameLiftとは
この記事を読んでる時点でGameLiftが何なのかは分かってる人が多いと思いますが、一応書きます。
GameLiftはゲームを運用するのに専用サーバをホスティングするためのサービスです。
GameLiftに適しているゲームは、FortniteやFall Guysなどの、短時間の試合単位でマルチプレイを行うタイプのゲームです。マイクラやARKのような、サーバが建ちっぱなしで遊ぶタイプのゲームは向いてません。
GameLiftを使う理由
なんでGameLiftとか使わなアカンの?という事を説明するために、もしGameLiftみたいなサービスが無かったらどうなるか?を考えてみます。
例えば、あなたがFall Guysのような60人バトルロイヤルゲームを作ったとしましょう。このようなゲームはマルチプレイでしか遊べず、プレイヤーは常にゲーム会社がホストしてるサーバに入って試合を楽しみます。サーバはUnityのヘッドレスサーバービルドによる専用サーバを使用します。
ゲームのピーク時には6000人が同時にアクセスしてくるので、あなたはEC2インスタンスを100台立てて、それぞれのインスタンスに60人がアクセスして試合を行うようにセットアップしました。
それはいいですが、ピーク時以外は数百人しかアクセスしなかったりするので、ほとんどの時間は無駄なサーバ代を払ってる事になります。
逆に、有名vTuberが実況プレイした影響で、数万人のユーザーが一度に押し寄せたらどうしましょう?サーバーがパンクして、繋がらないユーザーから苦情が殺到してしまいます。
これは問題ですね。
GameLiftを使えば解決します。
サーバーをホストしてるEC2インスタンスをオートスケールしてくれるので、ユーザーが増えたらインスタンスを増やして、ユーザーが少ないときはインスタンスを減らしてくれます。
結果的に、かかる費用を最小限に抑えて、ユーザーが殺到しても問題なく動作するサーバ環境を簡単に構築できます。
バトルロイヤルとサンドボックスの違い
FortniteやFall Guysのようなバトルロイヤルゲームでは、サーバーに接続してマルチプレイで遊ぶことが前提になってます。そもそもシングルプレイで遊ぶという選択肢はありません。
さらに、競技性のあるゲームなので、ゲーム会社自らがホストしている専用サーバを使う選択肢しか用意されてません。公式専用サーバならチートは不可能だからです。(まあサーバ側でのチートを防止したとしても、クライアントだけでできちゃうチートもありますが。例えば壁を透けさせて敵の位置を丸見えにしちゃうようなチートです。クライアント側のチートを防ぐには、クライアントPCに常駐するタイプのアンチチートソフトが使われます。原神でスパイウェア疑惑で炎上したヤツや、FortniteではEasy Anti-Cheat、ArkではBattleEyeというソフトが使われてます)
ですので、バトルロイヤルゲームでは、GameLiftのような専用サーバをオートスケールしてくれるシステムを用意しないと、公式サーバに入れないユーザはそのゲームで遊ぶこと自体が不可能になってしまいます。
それに対して、ARKのようなサンドボックスゲームでは、必ずしもマルチプレイで遊ばなくても、シングルプレイでも遊べます。
公式の専用サーバも用意されていますが、競技性が強いゲームではないので、ユーザが独自に建てた非公式の専用サーバも利用できます。
Arkでは公式専用サーバが1175部屋も建ってます!
また、P2P(リッスンサーバ)でも遊べます。
非公式の専用サーバやP2Pではサーバ管理者やホストがチートし放題に思えますが、そういうのって内輪で遊んでるわけなので、そこでチートしたら次から仲間外れにされてるだけなので、特に問題は無いでしょう。
公式専用サーバでチートして暴れたらそれは荒らしなので問題になります。サーバ側のチートはそもそも専用サーバなので起きませんが、クライアント側のチートはBattleEyeで防ぎます。(非公式サーバを建てる時はBattleEyeのインストールが必須かどうかを選択できます)
ARKのようなサンドボックスゲームではマルチプレイはオプションなので、GameLiftを使ってまでマルチプレイを保証する必要は無いかもしれません。
GameLiftのコスト
AWSの料金ってややこしすぎて意味不明なので私は個人的にはAWS使いたくないなという気にさせられます。
Amazonが言うにはGameLiftの料金は簡単、分かりやすいとの事ですが、実際いくらかかるのか調べるのに苦労しました。
まあ要するに、初期費用とか基本料金とかは一切かかりませんし、使ったEC2インスタンス分の料金だけ払えばいいという事です。
料金表はこちら。
ややこしいのは、まずGameLift or FleetIQという2択があり、Linux or Windowという2択があり、スポットインスタンスとオンデマンドインスタンスという2択があり、どれを見ればええねん?っていう。
とりあえず見とけばいいのはGameLiftのLinuxのオンデマンドの奴です。
リージョンが米国東部で、c5.largeというインスタンスの場合の料金は、毎時0.109ドルと書かれています。一か月連続稼働した場合は78.5ドルです。
つまりこれがGameLift使用時の料金です。
ただし、一見するとGameLiftを使うフィーはタダで、EC2インスタンスの料金だけ払えば良さそうに見えますが、実はインスタンス料金自体にすでにフィーが乗ってます。GameLiftを使わずに普通にEC2でc5.largeを使った時の料金は、毎時0.085ドルで、一か月あたり61.2ドル。GameLiftの方が2割ほどフィーが上積みされてます。
ただ、GameLiftのインスタンスは固定でEBSのストレージが50GB積まれていて、それもコミコミの料金です。それでも普通にEC2使うよりはちょっとGameLiftの方が高いという事です。
あと、データの転送料金は別途かかります。米国東部リージョンで、1GBあたり0.09ドルです。
それと、ゲームサーバをGameLiftにアップしますが、これは実際にはS3に上がるようなので、S3のストレージ代がかかるようです。まあこれは些細な金額でしょう。
GameLiftにはFleetIQやFlexMatchといった機能がありますが、こうした機能はGameLiftの一部なので、使用しても別料金とかはかかりません。
ゲームサーバの転送料金っていくら?
サーバの転送料って実際いくらくらいかかるんでしょうか?そんなにちゃんとゲームサーバの運営をやった事無いので分かりませんが、ざっくり試算する事はできます。
100人のプレイヤーが同じ部屋に入ってて、全員が30日間ぶっ通しでプレイしてる状況を想定してみます。かなり極端な例ですが、ARKのようなゲームでは普通に100人サーバとかありますし、あり得なくは無いかも?
秒間20回、自キャラの座標と回転(vector3とQuaternionでfloat7個で28バイト)を同期するとします。
28バイト×秒間20回×100人が送信×100人に送信×60秒×60分×24時間×30日=14.5TB
GameLiftの転送料が0.09ドル/GBなので、毎月1305ドルもかかる事になります!
たけえ!
なんでこんなに高くなるんだろうと考えてみましたが、やはり同じ部屋に100人入れるというのが多すぎますね。
ゲームの通信量って、プレイヤーの数に対して理論上O(n²)で増えてしまいます。何故なら、部屋に100人いる場合は100人のデータを100人に対して送信する必要があるからです。
例えば、同じ100人だとしても、50人の部屋2つに分割すれば、通信量は半分に減ります。
Fortniteは100人が同じ部屋に入れますが、プレイヤーから見えているオブジェクトだけを優先して同期するなどの最適化を行っているので、通信量を節約しています。フィールドが広いので、同じ画面に同時に映るのはせいぜい数人です。
Fall Guysは全員が同じ画面に映っちゃったりしますが、最大でも60人なので、ギリギリ何とかなってます。それに、60人なのは最初だけで、どんどん減っていきますしね。
もしもあなたが、100人が同じ画面に映り続けるようなゲームを考えている場合は、通信量の観点から言えば、仕様を見直した方がいいかもしれないですね。どっちみち、画面内に100人もいたらゴチャゴチャしすぎてゲームとして成立しない可能性があります。
ARKのようなタイプのゲームでは、同じ部屋に100人入れたりしますし、何時間でも遊べちゃうので、通信量的にしんどそうですね。
でも、上述したように、ARKはGameLift使う必要は無さそうですし、別にEC2にこだわる必要もありません。
通信料がぼったくりみたいに高いのは、AWSを使ってるからで、VPSを使えば通信料は基本的に無料です。ARKならVPSを借りまくってサーバーホストする形もアリかもしれません。
ただし、VPSは通信料がかからない分、通信品質が保証されてるわけではありません。家のネット回線と同じように、速かったり遅かったりします。AWSは高いだけあって、どんだけ通信量が立て込んでも、それなりにスケールする仕組みになってそうです。
あまり実際のサーバー運用経験が無いのでハッキリした事は言えませんが、通信料を惜しんでVPSにしたけど、回線速度でトラブって、かえって損をした。という事もあり得るかもしれません。
AWS公式によるバトルロイヤルゲームのサーバ費用の試算
AWS公式が、もしバトロワ的なゲームをAWSとGameLiftを使って運営したら、毎月いくらくらいかかるのかを試算してくれてます。
その額、13,951ドル!毎月150万円ほどかかるという事です!
別の記事でも、GameLiftは個人開発ゲームで使うには荷が重いという話をしましたが、もし個人開発でバトロワ作ってそれがバズッたりしたら、サーバ代が大変な事になるのがお分かりいただけますでしょうか。
会社の偉い人が軽いノリで「バトロワ作りたい」とか言い出したらこれを見せて、こんだけサーバ代を払う覚悟があるのか確認しましょう。
DAU2万人で月150万円のサーバ代って事は、DAUが2500万人のFortniteは単純計算で年間225億円のサーバ代がかかる事になります!ヒエ~。でもFortniteの年間売り上げは2000億円だから全然払えるんですね。
GameLiftとPlayfab比較
MicrosoftのPlayfabにもAWSのGameLiftと同じような専用サーバホスティングサービスがあります。
どっちがオトクなのか、ざっくり料金比較してみたいと思います。
初期費用
GameLiftは初期費用、基本料金などは一切かかりません。
Playfabは、専用サーバをホストするためには、有料プランに加入する必要があります。一番安いスタンダードプランで月額99ドルです。さらに、タイトル毎にプランがあるので、タイトルが分かれるごとに99ドル払うハメになるのが厄介です。
[2020/12/30 追記] Playfabのマルチプレイヤーサーバー2.0が有料プランじゃないと使えないのは、パブリックプレビューの時の話で、2020年4月に正式リリースされてからは無料プランからでも使えるようになってました。(クレカ情報登録が必須)
無料枠
GameLiftには、AWS会員登録後、1年間は無料枠が付いてます。c5.largeインスタンスが月125時間まで無料。通信料は月15GBまで無料(AWS全体で)です。
Playfabも有料プランに加入すれば、無料枠があります。Av2インスタンスが月750時間、Fv2インスタンスが月750時間まで無料です。ただし米国東部リージョンのみ。月750時間あれば、1台だけなら無料枠で起動しっぱなしにできます。通信料は月10GBまで無料です。
インスタンス費用(米国東部リージョン)
GameLiftでc5.largeというインスタンスを例に取ると、1時間当たり0.109ドルです。1カ月連続稼働で78.5ドルほど。ただし、スポットインスタンスなら、料金は常に変動してるものの、この記事を書いてる時の料金で、1時間当たり0.03888ドル、1カ月連続稼働で28ドルほどです。
Playfabで同じくらいのスペックのA2v2というインスタンスを例に取ると、1時間当たり0.09ドルです。1カ月連続稼働で64.8ドル。
つまり、GameLiftよりPlayfabの方が少し安そうです。ただし、世の中良く出来てると思いますが、スポットインスタンスを使えばGameLiftの方が安くなります。
スポットインスタンスって何じゃ?という話は後述します。
通信費用(米国東部リージョン)
GameLiftは1GBあたり0.09ドルです。(10TBまでの場合)
Playfabは1GBあたり0.05ドルです。
その他の懸念
費用以外の比較ポイントとして、GameLiftはそれ単体で使えますが、Playfabの専用サーバホスティングは、Playfabサービスの一部として提供されているという点があります。
これにはメリットとデメリットが考えられます。
メリットは、Playfabのユーザ認証などと連携して簡単に使えそうなところです。ただし、それはゲームのバックエンドにPlayfabを使用する場合に限られるでしょう。
デメリットは、バックエンドがPlayfabに縛られてしまいそうなところです。GameLiftなら、バックエンドをPlayfabからやっぱりFirebaseに乗り換えよう。みたいな事もできると思います。
ですから、むしろゲームのバックエンドはPlayfabを使うけど、全部をplayfabに依存はしたくないから、専用サーバホスティングだけはGameLiftを使うという選択肢さえ考えられるかもしれません。
スポットインスタンスとFleetIQ
EC2のインスタンスにはオンデマンドインスタンスとスポットインスタンスの2種類があります。
オンデマンドインスタンスというのは普通のインスタンスです、じゃあスポットインスタンスとは何か?
スポットインスタンス=空き部屋の間借り
例えば、あなたが今、引っ越し先を探してるとします。親戚に賃貸マンションのオーナーがいて、「今ちょうど空き部屋があるから、入居者が決まるまで激安家賃で住んでていいよ」と言ってくれました。
安く住める代わりに、入居者が決まったらすぐさま立ち退きするハメになります。
要するにこれがスポットインスタンスです。
EC2インスタンスの在庫には限りがあります。とは言え、十分な在庫が用意されているので、基本的には在庫が尽きる事はありません。
しかし、Amazonからすると、余ってる在庫を遊ばせているのは勿体ないです。せっかくなので、安く間借りさせよう。そう考えたAmazonが用意したのがスポットインスタンスです。
つまり、スポットインスタンスはオンデマンドより安く使える代わりに、もし在庫が埋まっちゃったときは、すぐさま立ち退きさせられるハメになります。
ですので、Webページをホストしてるような、ずっと起動してないとこまるような使い方には向いてませんが、ちょっと短時間の計算処理を行いたいみたいな使い方にはスポットインスタンスは最適です。
つまり、数分間の試合につかうだけのGameLiftサーバはスポットインスタンスの使い道として、もってこいという事になります。
また、スポットインスタンスの料金は常に変動しています。在庫が余ってるインスタンスタイプほど安くなるというわけです。
めっちゃ賢いFleetIQ
でも、いくらゲームサーバがスポットインスタンスに向いていると言っても、プレイ中のゲームがいい所で立ち退き要求が来てゲームが中断されたらユーザーはイラッとします。
スポットインスタンスの立ち退き要求が来たら、シャットダウンまで2分間の猶予しかありません。そんな短時間で都合よく試合終了できません。
ですので、できる限り立ち退きは避けたいところです。そこでAmazonが作ったのがFleetIQという仕組みです。
FleetIQは、インスタンスを建てる時に、なるべく安くてなるべく立ち退きしないで済みそうなインスタンスタイプを自動的に選ぶことで、安く、中断しづらいスポットインスタンスでのサーバ運用を実現します。
FleetIQを使うためには、キューというものを使って、キューに色んなインスタンスタイプのスポットインスタンスのフリートを突っ込んでおきます。(フリートが何なのかは後述)
そうすることで、FleetIQはサーバのスケールアウトで新しくインスタンスを建てる時に、キュー内のフリートから一番コスパが高そうでかつ一番在庫が余ってて安全そうなインスタンスタイプを選択します。
さらに、すでに建ってるインスタンスについても、なんかもうすぐ立ち退き要求来そうだな…というのを察知したら、今やってる試合が終わり次第、インスタンスを閉じてくれたりもします。
このように、適切にキューを設定しておけば、FleetIQが頑張ってくれるので、実際のとあるゲームでは立ち退き要求があったのは全体のたった0.004%だったそうです。こちらの記事によれば。
GameLiftの仕組み
さて、いよいよ実際にUnityで作ったゲームをGameLiftで動かすために、実際のサーバーとクライアントの動きを説明します。
GameLift公式ドキュメントから引用しましたが、サーバーとクライアントの相互作用を説明した図がこれです。
正直言って、最初にこの図を見た時は、まったく意味不明でした。サンプルを動かして、コードを見て、動作を理解してからあらためてこの図を見直して、ようやく意味が分かりました。
今の時点でこれだけ理解して欲しいのは、GameLiftの動作はクライアントとゲームサーバーとGameLiftサービスの3者のやり取りで行われるという事です。
Unityで作ったゲームで言えば、クライアントというのは要するにゲームアプリを指します。ゲームサーバーというのはゲームアプリと同じプロジェクトからビルドしたヘッドレスサーバービルドです。GameLiftサービスというのはまあそのままの意味で、GameLiftを管理しているサービスです。
この際なのでついでに説明すると、クライアントにはGameLiftサービスとやり取りするために、AWSSDKを組み込む必要があり、同様にゲームサーバーにはServerSDKを組み込む必要があります。まあUnityだとクライアントもサーバーも同じプロジェクトなので、そこに両方入れます。
さて、この図を説明するのに、ホテルの例え話をしてみます。
クライアントというのは、ホテルに泊まりたいお客様です。ゲームサーバーというのは、ホテルの部屋です。GameLiftサービスというのは、ホテルのフロントです。
まずはじめに、ホテルにやって来たクライアントは、GameLiftサービスに、「今日泊まりたいんだけど、空いてる部屋無い?」と訊きます。これが、SearchGameSession()です。ゲームセッションって何じゃ?というと、部屋の事です。さっき、ゲームサーバーも部屋の事だって言ってたじゃねえか!と思うかもしれませんが、1つのゲームサーバーの中に複数のゲームセッションがあったりするので、厳密に言えばゲームサーバーはホテルの棟で、ゲームセッションがホテルの部屋と例えた方が正しいかも。
空いてる部屋があればいいですが、無い場合もあります。無いと言われたら、クライアントは「無いなら今作れや!」と言います。無茶な話ですが、これはGameLiftという魔法のホテルなので、部屋が無くなってもいくらでも新しく作れます。これがCreateGameSession()です。
とにかく部屋が見つかったら、GameLiftサービスは、GameSessionオブジェクトをクライアントに渡してくれます。これはまあ部屋の番号みたいなもんです。
クライアントはここで忘れずにGameLiftサービスにプレイヤーセッションも作ってもらいます。プレイヤーセッションって何じゃ?というと、ホテルの話で言えば、ベッドの番号みたいなもんです。このホテルは相部屋前提なので、あらかじめベッドも予約しておかないと後で揉めます。これがCreatePlayerSession()です。
ベッドの予約ができたら、GameLiftサービスは、サーバーのIPアドレスとポート番号、それとプレイヤーセッションIDをクライアントに渡してくれます。IPとポート番号は部屋の鍵みたいなもんです。プレイヤーセッションIDはベッドの予約番号みたいなもんです。
ここまで来れば、後はクライアントは部屋に行って入るだけです。IPとポート番号を使ってゲームサーバーに接続します。そしてプレイヤーセッションIDを渡して認証します。
これでようやく部屋に入れました。マルチプレイゲームが始まったという事です。
めでたしめでたし。
FlexMatch
私も使った事がないので、今回の記事では触れませんが、GameLiftにはFlexMatchというマッチメイキング機能があります。
FlexMatchを使うと、色々な条件が設定できて、同じくらいの腕前の人とか、同じくらいのレイテンシーの人同士でマッチングするようにできます。
あと、Amazonはチーターを隔離してチーター同士で争わせるやばい蠱毒の特許も取っているので、そういうのもFlexMatchで実現できるかも?
ちなみにFlexMatchを使わない場合はどうなるかというと、単に参加プレイヤーは空いてる部屋に適当にどんどん案内されるだけです。
それと、FlexMatchは元々GameLiftの機能の一部でしたが、これだけを切り出して単体でのサービス提供も始まりました。
GameLiftのマッチング機能であるFlexMatchが単体での機能提供を開始するアップデートが発表されました!
GameLiftとGameLift FleetIQ
ただでさえややこしい話を、これ以上ややこしくしたくないのですが、一応説明しておきます。
先ほどGameLiftの機能の一部であるFleetIQについて説明しましたが、最近になって、GameLiftからFleetIQだけを切り出した別サービスのGameLift FleetIQというものが始まりました。クソややこしいですね。
元々GameLiftはフルマネージドサービスと言って、面倒くさい事は全部やってくれるサービスです。その代わりに、ユーザーの自由度は低くなってます。
GameLift FleetIQではゲームサーバの管理部分を自前でやる事になります。手間がかかりますが、その分自由度が高いです。具体的に何が嬉しいのか?というと、例えばDockerのコンテナをゲームサーバに使えたりします。Unityのゲームサーバは単に実行すればいいだけですが、色々事前に環境構築が必要なゲームサーバもあります。そういう場合はDockerコンテナを使える方が便利です。
GameLift FleetIQはわれわれの何を解決してくれるものなのか?
Agones
ややこしいついでにAgonesの話もします。もはやGameLiftとは関係ない話なので読み飛ばしてもいいです。
Agonesというのはgoogleが開発しているOSSで、これを使えばGameLiftと同じような事が出来ます。
とは言えどうせ動かす環境はAWSとかなので、じゃあGameLift使えばいいじゃねえかと思われるかもしれませんが、Agonesのメリットは、自由度が高い事です。GameLift FleetIQも自由度が高いという事でしたが、Agonesはさらに自由度が高いです。というかソースが全部あるわけなので、ソースを弄れば細かい挙動まですべて制御できます。
しかし、その分使うのは相当面倒というわけです。
つまり、GameLift→GameLift FleetIQ→Agonesという順番で自由度が高くなっていきます。そして使う手間や難易度も高くなります。使い分けしましょう。
AgonesはKubernetesのプラグインなのでKubernetesと一緒に使います。Kubernetesって何じゃ?というと、Dockerとかを管理するものです。
つまり、Kubernetesを使えばDockerコンテナをオートスケールさせる事ができます。しかし、Kubernetesだけだとゲームサーバが今プレイ中かどうか判断できないので、スケールインでインスタンスを閉じる判断ができません。ですのでプレイ中のゲームサーバを保護するのがAgonesというわけです。
リアルタイムサーバーとカスタムサーバー
私としてはこれ以上話をややこしくするのはまったく心外なのですが、一応これについても説明する必要があるでしょう。
GameLiftのゲームサーバーにはリアルタイムサーバーとカスタムサーバーの2種類があります。
Unityでヘッドレスサーバービルドで用意したゲームサーバーは”カスタムサーバー”です。今回の記事で扱うのはこちらです。
じゃあ”リアルタイムサーバー”って何?というと、なんかGameLift側で用意された、javascriptで書けるサーバーです。
カスタムサーバーとリアルタイムサーバーの話は相当紛らわしいので気を付けましょう。リアルタイムサーバーなんて私的にはまったく眼中にありませんが、ググって出てきた記事をよく読むとこっちの話をしてたりするので厄介です。
例えばこの記事で触れられてる「Mega Frog Race」というサンプルは、たしかにUnityでGameLiftを使ってるのですが、リアルタイムサーバーを使ってるので、カスタムサーバーとは話が違います。
GameLift RealtimeServer SampleGame「MegaFrogRace」を動かしてみた ~ローカル対戦編~
つづく
今回の記事では、GameLiftの概要、用語説明、大まかな動作の説明などを行いました。
また続きの記事を書くつもりですが、次回の記事ではGameLiftのUnityサンプルを動かしてみる記事にする予定です。
ためになるリンク
公式ドキュメントはチンプンカンプンですが、それとは別に、GameLiftの無料学習コースが用意されてるので、見ておくと役に立つかもです。これもかなり良く分からんですが、ドキュメントよりはマシな気がします。このページの下の方から見れます。
【レポート】Unity+AWSによるマネージドなゲームサーバ運用
ゲーム開発者向けサービス「Amazon GameLift」の基礎知識
Unity multiplayer game on GameLift #1