クライアント/サーバーリアルタイムビデオゲームで高速なコンピューターを扱う方法


15

socket.ioを使用して最初のオンラインゲームを作成していますが、agar.ioやdiep.ioのようなリアルタイムのマルチプレイヤーゲームになりたいです。

しかし、すべてのコンピューターを同じ速度で動作させる方法を見つけようとする問題に遭遇しました。

モデルには3つのアイデアがありますが、どれも正しいとは思えません。通常のビデオゲームではどのようにそれが行われるのでしょうか。(私のアイデアを読むことをスキップできます;私が抱えている問題を見る方法を与えてくれます。)

  1. サーバーは、クライアントが自分で実行できるようにし、サーバーに更新を渡し、サーバーから残りのクライアントに更新をブロードキャストします。これには、一部のコンピューターが他のコンピューターよりも速く動作し、更新が速くなり、画面上をより速く移動できるという問題があります。

  2. 更新するタイミングをサーバーにクライアントに伝えます。次に、最後のクライアントが応答するまで待機し(ある人が遅いコンピューターを使用している場合のひどい考え)、最初のクライアントが応答するまで待機し(再び、各フレームの前に通信を待機します)、またはできるだけ早く送信します(これは、 1)と同じ問題に遭遇するようです。

  3. ゲームの開始時に、サーバーにクライアントに更新の速さを伝えてもらいます。これは、クライアントがその期間の間の移動を制限する責任があることを意味します。たとえば、その期間内に誰かがなんとかボタンを2回押すことができた場合、ボタンを押すイベントは1つしか送信されません。これには、一部のアクション(ダブルボタンを押すなど)が無視され、サーバーのクロックと一致しない可能性のあるクライアントのクロックに相互作用が依存するという問題があります。サーバーは、各クライアントを追跡し、更新が正しい時間に送信されていることを確認する必要があります。

私はいくつかの調査を行いましたが、私が読んだ記事は、クライアントが他のクライアントよりも速く更新を送信した場合の対処方法を具体的に扱っていないようです。

私の特定のケースでは、キーボードの速度が速い人を扱っています(彼らのコンピューターは他のコンピューターよりも多くのキーボード更新を送信します)。

プログラマは通常、これにどのように対処しますか?


1
私の経験では、そうではありません。これがゲーマーマシンが存在する理由です。自動的なものの利点を持って投げ芸術炎の状態のための5壮大を支払うものはまだコモドール64の使用
ロバート・ハーヴェイ

1
私のゲームプレイは、最低公分母でプレイしなければならないため、遅く見えるでしょうか?ゲームサーバーがテンポを設定するように思えますが、それを維持するかどうかはクライアント次第です。
JeffO

3
私は質問を誤解しているかもしれませんが、ティックベースのクライアントおよびサーバーモデルを使用することはおそらくあなたが求めていることです。gamedev.stackexchange.com/questions/81608/… 基本的には、X時間ごとに入力とロジックのみを処理するだけです(通常は60Hzロジックの1/60など、1 / N秒)
Christopher Wirt

4
質問をもう少し詳しく読んだ後、ゲームのクライアントの側面に集中しすぎているようです。「公正な」マルチプレイヤーゲームが必要な場合、サーバーは信頼できるものでなければなりません。クライアントに発生するすべてがサーバーによって検証または実行されることを意味します。次に、おそらく上記のティックベースのシステムを使用して、ここから物事を制限します。
クリストファー・ウィート

1
ああ、リアルタイムのネットコード。ゲーム開発の最も深い、最も暗い場所。船へようこそ、仲間!
T.サー-モニカーの復帰

回答:


8

あなたの3番目のアイデアは、この種の問題に対する業界のソリューションとして私が考えるものに最も近いようです。

あなたが説明しているものは、一般にTicksと呼ばれます。各ティックでは、固定された数のアクションが各クライアントに対して順番に処理されます。多くの場合、ゲームサーバーは可能な場合、いくつかの並行アクションを行いますが、これははるかに複雑な問題です。

ティックは、1 / N秒(Nは1秒あたりのティック数、またはTickrate)の形式になる可能性があります。このティックレートは、ユースケースに応じて、非常に頻繁または非常にまれです。私の個人的な提案は、もっと必要なことが確かでない限り、1秒あたり60ティックを超えるティックレートを避けることです。おそらくしないでしょう:)

アクションはアトミックでなければなりません。たとえば、slither.ioで、移動するなどのアクションは、ヒットしたプレーヤーがすでに移動していない限り、チェーンを壊すなどの処理をすぐに実行しないでください。これはピクセルレベルの何かにとって些細なことのように思えるかもしれませんが、タイルベースの動きを扱っている場合、それはより明白になり、公平性を保証します。プレーヤーAがタイルX、Yに移動し、プレーヤーBが現在そのタイル上にある場合、ティックの終わりまでに、プレーヤーBがそのタイル上にいることを確認する必要があります。

さらに、サーバー側で個別に実行されない限り、クライアント側で計算を行わないでください。これは物理学で複雑で高価になります(多くのゲームは、このために他の多くのアクションやイベントより物理学の低いティックレートを選択します)

参考のために、ゲームサーバーとマルチプレイヤーネットワーキングについての独自の理解を補足するためのリンクを紹介します。

最後に、公平を期してサーバーを台無しにしないでください。ゲームが不公平になる原因となる悪用がある場合は、それらを修正します。それがより良いコンピューターがわずかな利点を持っているという問題なら、私はそれがそれほど大したことではないと言うでしょう。


3
@ProQ良いネットコードを書くことは簡単ではないことに注意する価値があります!アプリが最初からうまく動作せず、ネットコードがひどい場合は、あきらめないでください。日常生活でそれをしている人でさえ、問題を抱えています。それだけでそのハード!
T.サー-モニカーの復活

0

次のシステムは、すべてのクライアントとサーバーがいつでもほぼ同じゲーム状態を共有するようにします。

クライアントとサーバーの両方でゲームの状態を把握します。

クライアントがコマンド(マウス、キーボードなどの入力)を使用しようとする場合、有効であればゲームの状態を確認します。

の場合、コマンドを送信クライアントで実行せずにサーバーに送信します。

サーバーがコマンドを受信すると、有効であればゲームの状態を確認します。

そうである場合、サーバー上での実行が終了する予定の日付より後の正確な日付ですべてのクライアントにコマンドを送信し、コマンドに要求されたアクションをクライアントに送信する最小時間に等しい遅延の後に実行します。その後、日付を記録します。これは、将来の予測に役立ちます。時間の変動が大きすぎる場合は、ゲームシステムの時間をより決定的にします。

クライアントがサーバーからコマンドを受信すると、コマンドの要求するアクションをすぐに実行し、それが有効である場合はゲームの状態を確認し、現在の日付を見て、受信した日付予測と比較します。有効でない場合、クライアントは同期していません。(同様の接続を持つすべてのクライアントが同時に受信します)

日付が前の場合、前の手順で問題が発生したため、修正します。日付が少し後の場合、何もしません。日付が後の場合、クライアントは同期していません。つまり、クライアントが遅れすぎています。

クライアントが同期していない場合は、サーバーのゲーム全体のコピーを要求し、そのコピーを使用します。頻繁に発生する場合は、コマンドを送信するよりもコストが高いため、修正してください。

クライアントでは、他に何もする必要がない場合にのみ、画面上に表示します。単純なシナリオでは、レンダリング関数は現在のゲーム状態のみを入力として受け取ります。

さらに、予測システムを使用してコマンドをグループ化し、差分のみをレンダリングするなどして、alotを最適化できます。

検証は異なる必要があります。たとえば、コマンドリクエスト/時間単位を制限するのはサーバー次第です。


0

これがあなたが使用しているライブラリまたは環境の問題であるかどうかはわかりませんが、あなたはそれに完全に間違っていると思います。

大多数のマルチプレイヤーゲームでは、実際の計算を行うのはサーバーのみです。クライアントは、実際のパフォーマンスの問題のみが3Dグラフィックスを描画しているダムIOマシンです。そして、その場合、クライアントが20 FPSまたは200 FPSで実行できるかどうかは問題ではありません。それは視覚にのみ影響するからです。つまり、「クライアントの更新」にはまったく意味がありません。クライアントは、サーバーが計算するものを「予測」しようとするかもしれませんが、それはゲームプレイの感覚を滑らかにするためだけであり、ゲームプレイ自体に実際の影響はありません。

より速いキーボード速度

それが何を意味するのかさえ知りません。ほとんどの人は、ローエンドキーボードの速度についていくことすらできないので、プレーヤーのパフォーマンスにどのように影響しますか?

そうでなければ、質問は非常に広範であるように思われ、代わりに、あなたが持っていないかもしれない「一般的な」問題を補おうとするのではなく、単一の実際の問題に焦点を当てるべきです。


キーボード速度の高速化とは、タイピングではなく、「進む」キーまたは「シュート」キーを押した場合に送信できるコマンドの数です。
gbjbaanb

@gbjbaanbそして、それはどのように問題ですか?押されたコマンドとリリースされたコマンドのみに注意する必要があります。更新の速さを気にする必要はありません。
陶酔

OPのようにすべてのイベントを処理するかどうかはクライアントで気になります。したがって、wを押すと、少し先に進み、キーボードが他の人よりも速くなり、それらより速くなります。最後にしたいことは、前進するためにキーを押し続けなければならないレースゲームを作ることです!
gbjbaanb

@gbjbaanbいいえ。それは間違っています。サーバーは「プレイヤーが前進している」ことを認識しており、その後、1/60秒ごとにすべてのプレイヤーの位置を、プレイヤーが前進しているかどうかに基づいて更新します。これがすべてのゲームの仕組みです。更新ループはゲーム内のすべてのエンティティで同じであり、更新はUIからのイベントに基づいていません。
陶酔

1
いいえ、それはOPの理解ではなかったので、彼がそれを尋ねた理由であり、あなたが「私はそれが何を意味するのかさえ知りません」と言った理由です。OPの立場を理解していれば、彼の質問は理にかなっています。OPがクライアントからイベントが配信される速さに完全に基づいてゲームループで動作するようにゲームをコーディングしている場合、それが彼の求めていることです。彼のデザインがほとんどの標準で間違っているかどうかに関係なく。
gbjbaanb
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.