Feelin Games ロゴ

マルチプレイヤーサーバーの実装

Feelin建築オープンワールドゲームにおける、オンライン・リアルタイム・マルチプレイヤーのサーバーについて紹介します。

Unityでマルチプレイを開発しようとしたとき、迷うのではないでしょうか。Photon Unity Networking 2 (PUN2)、UnityのDedicated Server(専用サーバー)、Unity Gaming Services(いつから使えるの?)、MLAPI、Mirror、モノビットエンジン(Monobit Engine)、Game Server Services(GS2)、いつまで経っても、いまいちはっきりしない。

そんな中において、Feelinでは、Unity/C# > Websocket > Google Cloud Run/Goという構成で、リアルタイム通信を実装しました。

システム構成図

マルチプレイヤーサーバー Google Cloud Platform

Unityゲームクライアントから、 Websocket通信で、GCP(Google Cloud Platform)のCloud Runインスタンスに接続、インメモリ(キャッシュ)とFirestoreをデータベースとしています。ログイン、セッション管理、ルーム管理の前段は、App Engineにて処理を行なっています。この部分は、Cloud Runに統合してもしなくてもどちらでも良いかと考えています。

Cloud Runは、1つのインスタンスで、最大1,000までのWebsocketコネクションが接続できるとのことです。実際、どこまでの数が実力なのかを、今後テストしていきたいと思います。また、1コネクションは最大1時間で切断されます。よって、自動再接続の実装が必要となります。オートスケールができるため、計算上、1インスタンス=1,000プレイヤーのルームを、複数に増やしていくことができます。現在、USリージョンのサーバーとJPリージョンのサーバーのインスタンスを立てており、EUリージョンとその他は必要になった際に追加する予定です。

Cloud Runでは、Go言語にて、サーバーサイドの処理を書いています。Goroutine, Mutex, Rate limiter, Session Cookie、インメモリキャッシュ、Firestoreアクセスなどの機能とともに、各ゲームクライアントからの通信を振り分けています。github.com/gorilla/websocket を使って、Websocketサーバーを実装しています。

Unityクライアント側では、WebsocketSharp (github.com/sta/websocket-sharp)ライブラリーを使って、Websocketクライアントを実装しています。

通信データは、決めたフォーマットのテキストデータを、Bytesにして、送受信しています。送信頻度は、リアルタイム同期時は、4フレーム/秒で、必要がないときは、数分間隔でポーリング送信しています。 なお、マルチプレイ同期ということで、10フレーム/秒やそれ以上にすることも考えられますが、今はその必要がないため、4フレーム/秒でリーズナブルとなっています。

その実力は?

Feelin マルチプレイヤーデモ

このGIFアニメは、先のプレイヤーの位置をUSサーバーに送信し、USサーバーから返ってきた値を、後のプレイヤーの位置表示に使ったものです。 実は、たったの4フレーム/秒の同期であり、キャラクターは、ターゲット位置に向けた単純なスムージング処理を施しています。 Feelinにおいては、ある程度の同期遅延も許容できるため、最もバランスが取れた仕組みとなりました。

なお、最も効率的であろうgRPCも最初に検討しましたが、Unity C#、IL2CPP後のgRPC動作について、確認できなかったため、枯れた=確実性のあるWebsocketを採用しました。パフォーマンスとしては特段課題はないと感じています。

Google Cloud Platformをクラウドインフラとして使用しています。シンプルにシステム構築することができます。また、フリー枠があり、一定のプレイヤーに達するまでは、かなり低コストで済むことなるでしょう。

リアルタイム通信としてのソースコードはさほど多くなくシンプルに実装できたと考えています。 上述のリアルタイム通信のエンジンではなく、本システム構成で構築するのも一つの手であるということを提案したいと思います。 なお、ゲームロジックのためのコードの方は、どんどん増えて行くことでしょう。なんせオープンワールドのあらゆる振る舞いをコーディングしようとしていますからw。 今後、マルチプレイ実装について、深掘りして書き足していこうと思います。お楽しみに。Twitterフォローでウォッチしてくださいね! 辻ユウキ

Tweet