リアルタイムFPSゲームでサーバーに送信するもの


23

ローカルプレイヤーの位置をサーバーに伝える正しい方法は何ですか?一部のドキュメントでは、入力が生成されるたびに送信する方が良いと述べています。また、いくつかの文書は、クライアントが一定の間隔で位置を送信すると述べています。

入力を送信するアプローチでは、プレーヤーが方向キーを押している場合はどうすればよいですか?つまり、すべてのフレームでサーバーにパッケージを送信する必要があります。多すぎませんか?また、マウス入力からのプレーヤーの回転もあります。以下に例を示します。

http://www.gabrielgambetta.com/fpm_live.html

固定間隔アプローチで位置を送信するのはどうですか。サーバーに送信するメッセージが少なすぎます。ただし、応答性も低下します。

それで、どちらの方が良いですか?

回答:


19

簡単な答え:チートするか、それほど正確にしないでください!

シューティングゲームをオンラインでプレイしたことがある場合、サーバーへの接続が悪いと、いわゆる「ラバーバンディング」が発生する可能性が高くなります。

これは、クライアントが時々自分の位置を修正するために発生します。

基本的に、両側で何が起こるか:

  • サーバーはあなたの動きを追跡し、期待どおりに更新をクライアントに送信します。これらは常に完全な更新である必要はありません。xフレームごとに完全な更新が行われ、他のすべてのフレームでは新しい速度ベクトルのみが送信されます(変更がある場合)。

  • 独自のクライアントを使用すると、自由に移動できますが、サーバーによって提供される更新を使用して、位置を修正/調整します。これにより、フレームごとに位置を更新しなくても、ゲームの応答性が確保されます。

しかし、入力はどのように処理されますか?クライアントはあなたの位置を「私はそこに移動しました。」サーバーに送ります。サーバーはこの更新を確認し(たとえば、そこにすばやく移動できるはずですか?)、有効な場合は移動します(または更新を拒否すると「ゴムバンディング」が発生します)。

そのため、固定間隔のアプローチが機能する可能性が高く、十分です。

ただし、入力を送信し、両側で動きを処理する場合でも、「ボタンはまだ押されています」を送信する必要がないことに注意してください。代わりに、ボタンが押されたときに1つのイベントを送信し、ボタンが離されたときに別のイベントを送信します。


5
はい、ボタンの押下とリリースを追跡できます。しかし、マウス入力はどうでしょうか?それは常に変化しています。
syloc

6
「代わりに、ボタンが押されたときに1つのイベントを送信し、ボタンが離されたときに別のイベントを送信します。」-確かに、ゲームのルールに応じて、「リリース時」イベントが最終的に強制されることを確認するために、チェックを行う必要があります。たとえば、Rainbow Six Vegas 2マルチプレイヤーでは、プレイヤーが銃を発砲し始めることができ、(残念ながら一般的な)バグにより「発砲停止」メッセージがサーバーに届かないことがあります。これにより、試合の残りの間、銃声が無限ループにとどまります。ほんの一例に注意してください。youtu.be/GOQIbLCy7m8?t=9m10s
マイクバクスター

@syloc:クライアント側で処理し、移動が有効/可能かどうかをサーバーに判断させます(テレポートハックなどを防止するため)。
マリオ

@sylocマウスの間隔を設定するだけですが、余分な帯域幅を節約するために、クライアント側で変更が行われているかどうかを確認します。マウスが動かない期間がある場合は、それについてメッセージを送信し続ける必要はありません。
agweber

私の仕事の1つで、ダイヤルアップの位置の更新の欠落に対するスプリングの動作を最適化するエンジニアを実際に狂気に駆り立てました(13年前)。今、私はこの問題に悩まされている帯域幅が多く、途方もなく低レイテンシーのゲームを見ています。
アンドンM.コールマン

5

あなたがまだの場合は、私はあなたがこれらの二つの深いが、分かりやすい記事を読むことをお勧め:https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networkinghttp://fabiensanglard.net/quake3/network.php

これらは、「固定間隔」パケット送信を使用することが推奨される理由を説明しています。簡単に言えば、実際には、サーバーから送信されるパケットにとって主に重要です。

パケットの送信には固定コストがあり、ネットワークパケットの最大サイズは約1.5 KBです。たとえば、サーバーのプレイヤーが16人いる場合、各フレームでプレイヤーの動きを計算すると、ナイーブコードは動きの解像度ごとに各プレイヤーに更新パケットを送信できるため、16 * 16 = 256パケットです。30のフレームレートがある場合、それは7680パケットです。

より良い方法は、フレームの各開始点にバッファーを作成し、16の計算された位置の更新を連結してから、16のプレーヤーに送信することです。

同じ結果を得るために、秒単位で480パケットのみを送信するようになりました。

プレーヤーからサーバーへの場合、それは同じパケットで最大データを送信する必要があることを意味します。見えた位置、このフレームと呼ばれるアクションなど。

あなたの質問の2番目の部分について-私はラグ感覚を減らすために選択した方法は、各フレームでこの情報をサーバーに送信することでした:

  • プレーヤーの実際の現在の位置(サーバー側とプレーヤー側の位置があまり同期されていないかどうかを確認するためにサーバーによって使用されます)。

  • 1秒でのプレーヤーの推定位置:クライアントによって計算されます:プレーヤーがマウスの方向を変更せず、キーボードが現在の状態のまま1秒間プレーヤーがいる場合 (衝突は気にしません)プレイヤーが動いていない場合、1秒での推定位置は現在の位置です。

  • 彼が見ている位置。

サーバーはこの情報を受け取るたびに、将来の位置と見た位置を更新し、プレーヤーエンティティは最終的にその将来の位置に向かって移動します。

プレイヤーが正確に同期されることはありませんが、入力応答は即座に行われ(私にとって最も重要です)、予測された位置は私にとって十分に正確であることがわかりました。


「プレイヤーが決して正確に同期されることはありません」ここでの正確さのレベルは実際のゲーム(プレイ)に依存することを言及することも重要だと思います。たとえば、エンティティをクリックして選択するだけの古典的なMMOでは、ほとんどすべてに対して完璧な精度は必要ありませんが、完璧な同期に適したシューティングゲームでは不可欠です。
マリオ

正しい考えの人は誰もFPSにTCPを使用しません。むしろ、TCPのオーバーヘッドを被るよりも、複雑な再シーケンスとデータグラムの欠落を処理したいと考えています。
アンドンM.コールマン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.