50

ネットワークゲームの一般的なクライアント/サーバーセットアップで(賢明に)衝突する2台のクライアント制御車両をシミュレートするにはどうすればよいですか?分散ネットワーク物理学を一般的に行う方法(従来のクライアント予測なし)に関するこの著名なブログ投稿を読みましたが、この質問は特に、所有するオブジェクトの衝突を処理する方法に関するものです。

クライアントAがサーバーより20ミリ秒進んでおり、クライアントBがサーバーより300ミリ秒進んでいるとします(遅延と最大ジッターの両方をカウント)。これは、2台の車両が衝突すると、両方のクライアントがもう一方の車両の速度とは反対の方向に、320ミリ秒遅れていると見なすことを意味します。スウェーデンの高速道路で直接対決するということは、16メートル/17.5ヤードの差を意味します。

やってはいけないこと

位置を推定することは事実上不可能です。なぜなら、ユーザー入力からの状態は言うまでもなく、関節とボディが全体にある非常に複雑な車両もあり、それらは線形と角度の位置、速度、加速度を持っているからです。

4

8 に答える 8

12

私は完全な解決策を知りませんし、存在しないような気がします。車両の将来の位置を正確に予測できたとしても、ユーザーがコントロールを操作する方法を予測することはできません。したがって、問題は、クライアント/サーバーの遅延の悪影響を最小限に抑えることに帰着します。それを念頭に置いて、私は最小の驚きの原則の立場からこれに取り組みます(ウィキペディアからの言い換え):

ユーザー インターフェイスの設計において、最小の驚き (または驚き) の原則は、インターフェイスの 2 つの要素が競合するか、あいまいである場合、その動作は、競合が発生したときに人間のユーザーを最も驚かせないものであるべきであると述べています。

この例では、各ユーザーに 2 台の車両が表示されます。自分の、そして別のプレイヤーの。ユーザーは、自分の乗り物が自分の制御とまったく同じように動作することを期待しているため、シミュレーションのその側面を扱うことはできません。ただし、ユーザーは、他のユーザーが自分の車両をどのように制御しているかを正確に知ることはできません。このあいまいさを使用して、ユーザーからラグを隠します。

基本的な考え方は次のとおりです。

  1. サーバーは、差し迫った衝突について決定を下す必要があります。衝突検出アルゴリズムは 100% 完璧である必要はありません。明らかな不一致を避けるために十分に近いものである必要があります。
  2. 2 台の車両が衝突するとサーバーが判断すると、衝突が差し迫っていることを示すメッセージを 2 人のユーザーそれぞれに送信します。
  3. クライアント A では、衝突が確実に発生するように、車両 B の位置が (現実的に) 調整されます。
  4. クライアント B では、衝突が発生することを保証するために、車両 A の位置が (現実的に) 調整されます。
  5. 衝突の余波の間に、必要に応じて各車両の位置を調整して、最終結果がゲームの残りの部分と一致するようにすることができます。この部分はまさに MedicineMan が彼の回答で提案したものです。

このようにして、各ユーザーは自分の車を完全に制御できます。衝突が発生した場合、それは予期しないことではありません。各ユーザーは、他の車両が自分に向かって移動するのを見ることができ、リアルタイムのシミュレーションの感覚が得られます。良い点は、この方法が低遅延条件でうまく反応することです。両方のクライアントがサーバーへの接続の待ち時間が短い場合、調整の量は少なくなります。もちろん、ラグが大きくなるにつれて最終結果は悪化しますが、それは避けられません。ペースの速いアクション ゲームを数秒のラグがある接続でプレイしている場合、完全な体験を得ることはできません。

于 2009-05-07T19:10:00.813 に答える
6

おそらく、あなたができる最善のことは、実際の衝突をリアルタイムで表示するのではなく、物事がリアルタイムで起こっているという錯覚を与えることです。

クライアントはサーバーの背後にあり (ラグ)、サーバーは衝突の結果を表示する必要があるため、おそらくクライアント側でできることは、フラッシュや爆発、またはその他のグラフィックを表示して、ユーザーの注意をそらし、十分に購入することです。衝突の結果を計算するサーバー側の時間。予測が終了したら、プレゼンテーションのためにクライアント側に送り返します。

于 2009-05-07T16:35:30.917 に答える
2

「試してはいけないこと」で答えて申し訳ありませんが、クライアント側で結果を予測することを伴わない解決策は聞いたことがありません。簡単な例を考えてみましょう:

クライアント A は静止しており、クライアント B の車両が崖に近づいているのを見ています。クライアント B の車両は速度を即座に 0 に落とすことができ、崖を越える前の可能な限り最後の瞬間に減速します。

クライアント A がクライアント B の状態をリアルタイムで表示しようとすると、クライアント A は、クライアント B が崖から落ちたと予測するしかありません。これは、プレイヤーのキャラクターが全速力で走っているときにすぐに停止できるように設計された MMORPG でよく見られます。それ以外の場合、クライアント A は、状態の更新が入ったときにクライアント B の状態を表示するだけで済みますが、クライアント A はシナリオでクライアント B とリアルタイムでやり取りできる必要があるため、これは実行できません (私は思います)。

リアルタイム予測のために外挿が可能になるように、衝突モデルを単純化してみていただけますか? いくつかの立方体や球体のように、"関節と体全体" に、プロセッサをあまり使用しない物理モデルを持たせることもできます。衝突検出の効率を改善する方法についてはあまり詳しくありませんが、視覚モデルよりも複雑でないモデルの衝突を検出することによって行われていると思います。

于 2009-05-07T17:26:55.257 に答える
2

「やってはいけないこと」について。あなたは完全に予測する必要があると仮定していますが、複雑な物理学を伴うゲームで完全な解を見つけることは決してありません. 概算は、おそらく実行できる最善の方法です (たとえば、ほとんどの市販の物理エンジンは、形状を物理シーンにキャストし、衝突の最初のポイントを返すことができます)。

たとえば、Glenn (あなたが言及したブログ ポスター) の指導の下、Mercenaries 2 のネットワーク物理のいくつかの重要な部分を実装しました。単一の剛体であっても、必要なすべての物理状態をワイヤにプッシュすることは不可能でした。Havok の物理演算は、フレームごとに接触点を徐々に生成するため、現在の「接触多様体」は、シミュレーションを決定論的に保つために必要な物理状態の一部です。また、データが多すぎます。代わりに、目的のトランスフォームと速度を送信し、フォースとトルクを使用してボディを所定の位置に静かに押し込みました。エラーは避けられないため、適切なエラー修正スキームが必要です。

于 2010-02-14T05:08:27.127 に答える
1

私が最終的にやったのは、単に予測をすべてスキップして、単にこれを行うことでした:

  1. クライアントは自身の立場について非常に多くのことを言います。
  2. サーバーは、(ほとんど) 所有しているクライアントの位置について、別の動的オブジェクト (つまり、静的環境ではない) との「高エネルギー」衝突が発生した場合にのみ、何も言いません。
  3. クライアントはmeshoffset=meshpos-physpos、サーバーから位置の更新を受信すると、meshpos=physpos+meshoffsetフレームごとに設定され、徐々に減少しmeshoffsetます。

ほとんどの場合(低レイテンシの状況では)非常によく見えます。スムーズな遷移を得るためにクォータニオンをスラープする必要さえありません。

予測をスキップすると、待ち時間の長いクライアントにひどい経験を与える可能性がありますが、このインディー ゲームを出荷するつもりなら、これについて考える時間はありません。たまには、十分に機能するが最高に機能する中途半端なソリューションを作成するのは良いことです。;)

編集:最終的に、Glen Fiedler (質問で言及されたブロガー) が Mercenaries 2 に実装した「所有権」機能を追加することになりました: 各クライアントは、しばらく衝突する (動的) オブジェクトの所有権を取得します。そうしないと、待ち時間が長く高速な状況で浸透が深くなるため、これが必要でした。このソリューションは、GDC のビデオ プレゼンテーションを見て思ったのと同じくらいうまく機能し、間違いなくお勧めできます。

于 2010-05-21T07:43:14.570 に答える
0

クライアント側で他のユーザーがどこにいるかを予測し、衝突情報とそれをサーバーにどのように処理したかを予測することに加えて、ラグに対処するためにほとんどのmmoが行うことは、サーバーを「過去」に実行させることです。 。基本的に、これらは最近の入力をバッファリングしますが、過去に.1秒発生したことにのみ反応します。これにより、必要なときに「未来をのぞく」ことができます(つまり、時間枠内で衝突が発生しようとしているときに、バッファリングされた入力を調べて、何が発生するかを確認し、衝突が実際に発生するかどうかを判断できます)。

もちろん、これにより、クライアントに送信するデータとクライアントがそれにどのように反応するかを検討する必要があるため、プログラムがさらに複雑になります。たとえば、「将来の」バッファ全体をクライアントに送信して、実際に発生する可能性のある衝突と発生しない可能性のある衝突をクライアントに確認させることができます。

于 2009-07-09T10:18:32.937 に答える