37

Node.jsで Web マルチプレイヤー ゲームを作成することを考えています。これは、バックエンドとフロントエンドで同じ言語を使用することを意味します。それはリアルタイムで、各「部屋」に最大約20人になるので、いくつかの考えがあります:

  1. すべてのユーザーが同じ時間に同じものを見ることができるように、すべてのユーザー間の遅延をどのように補正しますか? 私は、各プレイヤーの平均 ping 時間を追跡し、最も遅いプレイヤーを見つけ、他のクライアントにそれぞれの遅延時間 (ミリ秒単位) を通知して、全員が可能な限り同期されるようにすることを考えています。

  2. バックエンドだけでなくフロントエンドでもゲーム コードを実行することを考えています (両方のエンドで JavaScript を使用しているため)。そうすれば、ゲームはフロントエンドでスムーズに実行され、同期が発生したときにわずかな不具合しか発生しません。また、不正行為者がバックエンド ゲームに同期されるため、フロントエンドの JavaScript ハッキングが最小限に抑えられます。

  3. Should I receive player actions through the socket (keypresses), inform all other clients of the other players' actions and in the mean time 'playing' the game in the backend and send synchronisation information to everyone of the entire game state every once in a while to synchronise them?

What do you think? Are there more stuff I should consider or pay attention to?

Please post any thoughts or links to documentation or articles regarding multiplayer gaming.


EDIT: These are useful:

4

4 に答える 4

27

1 - 不可能です。メッセージがクライアントに到着するまでにかかる正確な時間はわかりません。測定した値が、次に送信するメッセージに適用されるとは限りません。あなたができる最善のことは概算ですが、人々はわずかに異なるもの、または同じものをわずかに異なる時間に見ることを常に想定する必要があります. 現在の状態を全員に送信し、補間/補外を使用してゲームプレイをスムーズにすることをお勧めします。これにより、全員が過去数ミリ秒のゲームを見ることができ、遅延はプレイヤー間および時間の経過とともに変化します。一般に、これが大きな問題になることはめったにありません。サーバー上の過去の状態を本当にバッファリングしたい場合は、それらの間を補間し、異なる古いデータをさまざまな人に送信して、彼らが見ているものを同期させることができます.

2 - 一般的な方法は、サーバー上でシミュレーションを実行し、定期的な (小さな) 状態の更新をクライアントに送信することです。クライアントは通常、独自のシミュレーションを実行し、独自の予測/補間された状態とサーバーが送信している信頼できる状態をブレンドする方法を持っています。ユーザー入力以外のすべての決定は、サーバー側で行う必要があります。最終的に、これらをブレンドする方法は、滑らかな外観と正確な状態との間のトレードオフに過ぎないため、外観上の決定を下す必要があります。

3 - 通常、クライアントはキープレスを論理アクションに変換する必要があります。サーバーはキーを気にしません。その論理アクションをサーバーに送信すると、必要に応じて他のクライアントにブロードキャストできます。通常、ここで何もする必要はありませんが、アクションによって引き起こされた関連する変更は通常、ゲームの状態を変更するだけなので、その状態の通常のブロードキャストで送信されます。

于 2010-06-28T11:19:03.383 に答える
1

最善の方法は、すべてのオブジェクトを 1 つの場所、つまりサーバーだけで追跡することです。誰もがサーバーからの情報を「実際に発生する」よりも 1 回の移動時間遅れて見ることになり、人々のコマンドがサーバーに登録されるまでに 1 回の移動が必要になります。これを回避する方法は本当にありません。一部のアプリケーションでは、サーバーの応答を待たずに自分の動きをすぐにシミュレートすることが実用的ですが、これは間違いなくタイミング プログラミングの悪夢につながり、人々は通常、お互いが「遅れている」のを見ることになります。衝突検出はほとんど不可能です。

これの最終的な影響は、コマンドを入力してから実際に実行されるまでの動作が遅くなることですが、人々がこれに対処する方法を学び、それを補うために少し早くコマンドを入力しようとすることを願っています. 接続が遅いと、テンポの速いリアルタイム ゲームはまったく不可能です。

于 2010-07-02T14:13:01.773 に答える
1
  1. これを行うのは非常に難しく、「最も遅い」同期に多くの問題が見られます。クライアントが「最終的に一貫性がある」ように、これを緩めることはできますか?

  2. いいですね。

  3. フロントエンドからバックエンドに短いアクション イベントを送信し、バックエンドでゲーム ステートを変更して、ゲーム ステート変更イベントをクライアントに発行し、必要なイベントのみを適切なサブスクライバーに送信することに細心の注意を払います。この時点で、一致していないように見える、または偽物/ハッキングのように見えるイベントを破棄できます。

于 2010-06-22T13:26:26.860 に答える
0

典型的なアプローチの 1 つは、サーバーにロックされた同じフレームレートですべてのクライアントを強制的に実行しようとしないことです。代わりに、頻繁に更新を送信して、クライアントが新しい更新を受け取るたびに更新できるようにします。

通常、クライアントは短期間で物事がどのように進んでいるかを予測し、サーバーからの更新によって修正されます。時間補正も適用できます。たとえば、サーバーが「プレイヤー 2 は速度 V で移動している P にいる」と伝えた場合、最近の ping に基づいてそのメッセージがどれくらい古いかを知り、位置を からPに修正することができP + x*Dます。

于 2010-07-01T10:47:19.953 に答える