見出し画像

ネットワークを通じたマルチプレイについて

前置き

最近ではゲーム開発においてネットワークの要素は欠かせない要素になってきています。

一言にネットワークの要素といっても様々な要素があります。
・DLCや配信による追加コンテンツ対応
・ユーザーのセーブデータ管理
・ガチャやログインボーナス等の処理
・プラットフォームサービスやSNS等外部サービスとの連携
・サービス運営でお客様サポート等を行うために必要な諸々の話
・ネットワークを通じたマルチプレイ
等々…

今回はネットワークを通じたマルチプレイの話をしたいと思います。
モバイルゲームでは、実装しているタイトルもあれば、ないタイトルもあると思いますが、ネットワークのマルチプレイはやはり大きなフューチャーでしょう。

ここでは仮に「4人でダンジョンに潜るアクションRPG」という形で話を進めていきたいと思います。

マッチング機能

まずは一緒に探検する4人をマッチングさせる必要があります。
そのためにはマッチングサーバーと呼ばれるマッチング機能をサーバー側に作成する必要があります。

マッチングする際には高いリアルタイム性は求めません。
ですので、マッチングのリクエストや、リクエスト後のステータス確認についてはHTTP系の通信を用いて、定期的にサーバーに状況を確認しに行く形で実装されているでしょう。

画像1

イメージとしてはこんな感じで定期的に催促していきます。

同じルームに入ってプレイする4人が決まってしまえば、マッチングサーバーの仕事はおしまいです。
マッチング終了したときに、対戦用の別サーバーがあるなら別サーバーの情報をクライアントに渡して、あとは任せてしまいます。

※またマッチングと一言で言っても色々な要件、やり方があります。
・誰かがHostとなってルームを立ち上げる形 or サーバーにリクエストしたら適当にマッチングしてくれる形
・ランクや強さが近い人とのマッチング or フリーでマッチング
・フレンドと一緒にプレイできるようにマッチング
等々です。
(マッチングの周りは地味に特許も多いので注意も必要です)

ネットワークのつなぎ方…

対戦が始まった時にもネットワークのつなぎ方は色々なつなぎ方があります。

画像3

画像5

スマートフォン同士がサーバーを介さず直接P2Pでつなぐ事も出来ます。
しかし、同じWifiにつなぐなどの同一ネットワークにない状況下で、スマホ同士を直接つなぐためにはNAT越えというのをしなければなりません。

また距離が近くにいるユーザーであっても、同じWifiでつながっているみたいなシチュエーションもほとんどないので、モバイルのゲームの殆どはこのようにスマートフォン同士を直接つなぐことはないでしょう。

画像5

スマートフォン同士を繋げられないので、サーバーを介して繋げます。
この時ホストと呼ばれるゲームの主な進行役がいます。
進行役を務めるので、この人がいなくなると誰か代わりを立てないとゲームが進行出来なくなってしまうという形になります。
この誰かがホストの役を引き継ぐわけですが、この処理は色々とトラブルが多くてなかなかに大変です。なので、ホストがいなくなったらゲームの進行を中断してしまうというケースも少なくないでしょう。

画像5

またスマートフォン同士直接つなげていたように、サーバーを単に中継器としてスマートフォン同士をつなげてしまうというのもあります。

画像6

サーバーがゲームの進行役をしているというケースです。おそらく最近はこれが多く選ばれているでしょう。
特にバトルロワイヤルのようなゲームだと、途中で誰が脱落するかもわからないので、サーバー側で進行役をしないと中々難しいという所があるからです。

TCP?UDP?

またスマートフォン同士をどうやってつなぐか?といった課題以外にも繋ぎ方の方式も選択肢があります。

大きくTCPとUDPという二つの方式があります。
サクッと紹介するとこの二つはこんな感じになります。

■TCPの特性として下記になります。
・到達保証
・順番保障
・その代わり遅い

■UDPの特性は下記になります
・送ったデータがロスすることがある
・順番通りとは限らない
・けど早い

これまで紹介してきたAPIサーバーとのやり取りなどのHTTP通信は基本的にTCPの上に構築された通信プロトコルです。

TCPではしつこい位何度も「データ届いた?届いたよね?届いてないなら送るよ。」というやり取りを相互にすることでデータの到達を保証していますが、UDPではデータは投げたら投げっぱなしで放置します。

大きく分けるとこの二つがあり、リアルタイム性が要求されるようなゲームの場合UDPが選択されます。

※UDP上に信頼性をある程度担保できるような通信を構築しているRUDPというのがあります。
TCPほどじゃない形で信頼度のあるやりとりをするRUDPは、二つの良いとこどりみたいな方式もあり、実際の所はこれを選択している人が多いとは思います。

何を同期するのか?誰が何を処理するのか?

ネットワークのつなぎ方、ネットワークの接続方法以外にも重要な事があります。
それは、何をデータとして送るのか?ホスト側で何を処理するのか?どこまで処理するのか?という大事な点です。

キー同期処理

キーの操作をお互いに送り合ってしまって、自分+残り3人のキー操作入力が4人で同期してしまえば、4人プレイを実現できますよねという考え方です。

キャプチャ

青い二重線が手元で操作、黄色い点線がネットワークで送るキー入力です。
こうやって4人分のキー入力があれば、4人分の操作が出来ますよね。そして、それが4カ所で同じように動くという形です。

この方法のメリットはキー入力だけですので、一度構築すればかなりいろんなゲームに応用できることです。
ただし、キー入力が一致するならゲームの進行が完全に再現できるようになっている必要があります。可変フレームレートや、環境によって変わってしまう物理エンジンを持つゲームエンジンとの相性は良くありません。また乱数にも気を使わないといけません。

デメリットは、4人分全員のキー入力が揃ってからゲームを進行させる必要がある事です。
自分はすぐに入力が反映されますが、他の3人はネットワーク上で送られてくるので遅延します。遅延を考慮すると、自分自身のキー入力もわざと遅延させなければいけません。
さらに、一人ネットワークの都合が悪くなると、ゲームを進行できるまで待ち続けなければなりません。
またこの方式では、すべてのクライアントが同期して動く事を前提としていますので、ゲームの途中参加も実装が難しいです。

ステート同期

プレイヤーが操作しているキャラクターの座標やステートなどを互いに送り合い、状態を同期する仕組みです。

ボスなどのプレイヤーキャラ以外は、ホストや担当のクライアントを立ててロジックを動かし、状態を他の人に同期するという仕組みです。

画像8

手元で管理しているキャラクターは、コントローラーで操作したり、AI処理を行います。
黄色い点線は手元のキャラクターの状態を送信したり、他の人の端末で管理しているオブジェクトに対して処理呼び出しを行ったりといった事を行います。(「あなたが管理しているモンスターにダメージ与えたんで、HP減算処理とかを宜しく」みたいな感じでリモートで処理呼び出し(RPC)します)

この方法のメリットは、ネットワーク接続状態が悪い人がいても、その人の動きがカクツクくらいですみます。
この方法のデメリットは、ネットワークでは、データが届くまでにラグがあります。そのラグのせいでお互いの手元で状況のズレが発生します。
そのズレの結果によって問題が起きてしまうケースがあり、仕様上工夫が必要になるケースが出てきます。
例えば、「ボスへの最後の一撃を与えた人にボーナスがある」と言うようにした場合、手元で最後の一撃を与えたはずなのですが、ネットワーク上では別の誰かが実は先に一撃を与えていて、ラグによって自分の方が先だと思い込んでしまうなどです。

またネットワーク上に送れるデータ量も限りがあります。すべてを丸ごと同期と言うのは出来ません。
キャラクターのどの情報を同期するか?優先度はどの位で同期してほしいか等をコントロールしなければなりません。

Dedicatedサーバーロジック(サーバー集約処理型)

クライアントは定期的にキー入力情報をサーバーに送って、キャラクターを動かすなどの処理をサーバー側で行ってしまいます。
クライアントではサーバーから定期的に受け取るキャラクターなどのステート情報を元に表示を行うのみという形の処理になっています。

画像9

ネットワークには遅延があります。
入力を送ってサーバーで実行して情報がクライアントに戻ってくるまでにはラグがあります。またサーバー側では4人全員のコマンドがそろって実行されることが望ましいです。
このギャップを埋めるためには図のようにクライアントはサーバーより少し先の未来を予測によって実現しています。

画像10

自身のキャラクターだけは手元のキー入力があるのでサーバーと大きくずれることなく実行し、他の人のキャラクターなどは予測によって動かします。

ちなみに、この方式ではクライアントからサーバーにデータを送るのが予想より遅れてしまった場合には、サーバー側はデータを待たず勝手に入力を予測してゲームを実行してしまいます。その際にズレが生じたら、クライアント側では自分の操作しているキャラクターはサーバー側の情報を元に強制的に合わせられてしまいます。
良い品質のネットワーク接続ならば、予測幅が狭まりますし、キー入力が遅れてサーバー側に無視される可能性も減ります。そのため、良い品質のネットワーク接続がゲーム進行に有利になってきます。

この方法のメリットはサーバー側でゲームロジックを動かす形になりますので、ローカルでのチートをある程度防ぐことが出来ます。

デメリットとしては、サーバーマシンに高いコンピューティング能力を求められてしまうので、コストが少し高めについてしまいます。

またステート同期と同様に同期する情報をコントロールする必要があります。最近のバトルロワイヤル系ゲームでは、遠方に離れたキャラクターの情報の同期をほとんど行わない等の工夫が取り入れられています。

この処理の詳細を知りたいという方は、GDCのOverWatchの講演も参考にしていただければと思います。

参考情報

参考ですが、この辺りは2010年にSEGAの節政さんのセッションが凄い参考になると思います。

Cedeliは登録は無償で過去のセッションのスライドが閲覧できます。

また、こちらは4Gamersに記事にもなっています。

2010年の発表ですが、かなり良いものです。
オンラインマルチプレイを作りたい方には是非見てもらいたい資料です。

そんな感じで長くなりましたが、マルチプレイの話をしました。

どうマッチングするのか?どうやってネットワークでつなげるのか?繋げる方式?送るデータ等々様々なやり方があり、作りたいゲームや状況に合わせて選択していただく形になります。

この記事が気に入ったらサポートをしてみませんか?