ネットワーク遅延入門
サーバーとクライアント間の距離、パケットホップ、サーバーの ティックと更新レートその他多くの問題がマルチプレイヤーのラグを引き起こします。
オンラインゲームには、ジッター、ラウンドトリップタイム(RTT)、パケットロスなど、シングルプレイヤーやLANのみのゲームでは心配する必要のない問題があります。
クライアントとサーバー間の情報の送受信やキューイングに何らかの遅延が生じると、ゲームプレイに支障をきたす可能性がある。定義と問題点の詳細については、こちらのガイドを参照されたい。
レイテンシーの問題にうまく対処するには、以下の要素の優先順位と関係を考慮する必要がある:
1.セキュリティ
2.反応性
3.正確さと一貫性
どのソリューションも完璧ではないし、レイテンシーの問題にアプローチするどの方法にも長所と短所がある。重要なのは、自分のプレーに最も適した方法を見つけることであり、このガイドはその決断を下す方法を理解するのに役立つだろう。
Authorityは、クライアントとサーバーの関係において、誰がオブジェクトに対して最終的なゲームプレイの決定を下す権利を持っているかを定義する。選択するオーソリティ・モデルは、ゲームのネットワーク遅延に影響します。
多人数参加型ゲームには2つの権限タイプがあり、それぞれにセキュリティ、反応性、一貫性との関係がある:
- サーバー権限:より安全で、反応も少なく、同期の問題もない。
- クライアントの権限:安全性が低く、反応が鈍く、同期の問題が発生する可能性がある。
クライアント側に存在するコードはすべて改ざん可能であり、プレイヤーはサーバーに送信される偽のネットワークメッセージを偽造することができる。
これがゲーム内でどのように見えるかを知りたければ、ある距離からインプを殺すことができないゲームの例を考えてみよう。
クライアント側のロジックで、10メートル以上離れたインプは殺せないように指定しているのに、「インプを殺す」メッセージがサーバー側の距離をチェックしないサーバーRPCだとすると、プレイヤーはクライアント側のロジックをバイパスするために、そのネットワークメッセージを偽造することができます。
残念ながら、あなたのゲームを妨害しようとする人は常にいるので、クライアントを完全に信用することはできないと常に心に留めておくべきだ。かわいそうなインプたちやゲームをプレイしている他のすべての人たちのためにも、サーバーにはクライアントからのプレイヤーのアクションを検証するロジックが必要です。
権威モデルと待ち時間
選択するオーソリティ・モデルは、ゲームのネットワーク遅延に影響します。ここで、2つの権威のタイプと、安全性、反応性、一貫性との関係を見直してみよう。
サーバーオーソリティーゲームは、最終的なゲームプレイの決定がすべてサーバーによって実行される。
セキュリティ
キャラクターの体力や位置などの重要なデータは、不正行為者が手を出せないように、サーバーの権威性を確保することができます。その場合、データの値に関する最終決定権はサーバーにある。
一貫性✅。
サーバーオーソリティのゲームの利点は、あなたの世界の一貫性です。ゲームプレイの決定はすべてネットワーク上の同じノード(サーバー)が行うので、これらの決定が同時に行われていることを確認できる。
反応性🚫。
サーバー権限の問題は、サーバーがワールドを更新するように指示するのを待つことになることだ。しかし、サーバーの信頼性を維持しながらこの問題を解決するために使用できるパターンがありますので、ご期待ください。
クライアントが権威を持つゲームでは、世界の状態を共有するためのサーバーはあるが、クライアントは自分の現実を所有し、それを押し付ける。
反応性✅。
クライアント・オーソリティ・モデルは、ユーザーやそのデバイスを信頼している場合によく使われる。クライアント自身がすべての重要なゲームプレイの決定を行っているので、ユーザー入力の結果をすぐに表示することができる。
一貫性
クライアントが権威を持つ試合では、同期の問題が発生する可能性がある。古い情報を使ってクライアントに権威ある判断をさせると、非同期や物理オブジェクトの重なりなど、そのような問題が発生する。
セキュリティー
悪意のあるプレイヤーはゲームに勝つためにメッセージを偽造することができるからだ。
サーバーオーソリティゲームにおけるレイテンシー問題の解決
マルチプレイヤー開発のベストプラクティスは、一貫性とセキュリティのためにサーバーの権威モデルを採用することです。これらのゲームでレイテンシーを管理するための4つの重要な戦略について説明しよう。
機能を設計する際には、サーバー権限をデフォルトとして使用し、次にどの機能が反応性を必要とし、セキュリティや世界の一貫性に大きな影響を与えないかを特定する。
ユーザー入力が良い例だ。ユーザーはすでに自分の入力を所有しているため(私は自分のキー押下を所有しており、サーバーは私に「Wキーを押していない」と言うことはできない)、ユーザーの入力データは簡単にクライアント主導にすることができる。
FPSゲームでは、ルックディレクションはクライアントの意向に左右されやすい。クライアントは、マウスの動きの代わりに視線の方向をサーバーに送信する。どこを見るかを修正するのは奇妙な感じがするし、そのためのセキュリティにも課題がある。
予測することで、ゲームサーバーの権威を保ちつつ、反応性を保つことができる。クライアントは、アクションの結果が出るまで完全なRTTを待つ代わりに、プレイヤーのトリガー入力を予測するゲームプレイコードをシミュレートして実行します。
予測に誤差が生じた場合、「和解」が必要となる。クライアントは予測したポジションの履歴を保持し、サーバーの権威であるため、クライアントはサーバーからのポジションを受信する。クライアントは、過去に予測したポジションがサーバーから送られてくる古いポジションと合っているかどうかを検証する。
そして、クライアントは矛盾を検出し、サーバーの権威ある位置に従って位置を修正することができる。
注:この方法は、現時点ではNetcode for GameObjectsでは完全にサポートされていません。
クライアントサイド(予測付き)とサーバーサイドの両方で、サーバーに権威あるゲームプレイコードを実行させない理由は複数ある。しかし、どのようにすれば、投球が応答的に感じられ、クライアントが自分の入力に対して何かが反応するのを見るまでに完全なRTTを待つ必要がなくなるのだろうか?
ラグ隠しのためによく使われるトリックは、ゲームプレイに影響を与えないアニメーション、サウンド、VFXをプレイヤーの入力で即座にトリガーすることです。
もしサーバーの状態が違えば、クライアント側で起こる最悪の事態は、素早くも役に立たないアニメーションを再生してしまうことだ。アニメーションを終了させるのも、キャンセルするのも簡単だ。これは、アクションキャスティングまたはアクション先読みと呼ばれる。
サーバーの巻き戻しは、サーバーの信頼性を維持するための、クライアント主導のセキュリティチェック機能です。
クライアントは入力と一緒に、サーバーに「時刻tにターゲットにヒットしました」というメッセージを送る。時刻t+RTT/2でこれを受信したサーバーは、時刻t-RTTでシミュレーションを巻き戻し、ショットを検証し、最新の時刻でワールドを修正する(つまりターゲットを殺す)。これにより、プレイヤーは、安全性とサーバーの権威を保ちながら、世界が一貫しているように感じることができる。
注:サーバーによるゲーム状態の巻き戻しはすべて同じフレームで行われ、これはプレーヤーには見えない。これはサーバー側のチェックであり、クライアントが何をすべきかを指示していることを検証するためのものである。
注:この方法は、現時点ではNetcode for GameObjectsでは完全にサポートされていません。
多人数参加型ゲームの構築は挑戦的な試みだが、同時にエキサイティングなものでもある。次のバトルロワイヤルスマッシュヒットを作るにせよ、居心地の良いオンラインCo-opを作るにせよ、レイテンシーのニュアンスとその管理方法を理解することは不可欠である。
マルチプレイヤー・ドキュメンテーションをチェックして、次のプロジェクトを今すぐ始めましょう。