サーバー側入力


9

現在私のゲームでは、クライアントはレンダラーにすぎません。入力状態が変更されると、クライアントはサーバーにパケットを送信し、プレーヤーが入力を処理しているかのようにプレーヤーを移動しますが、サーバーは最終的な判断を下します。

これは、1つの大きな問題を除いて、通常は非常にうまく機能します。基本的に、プレーヤーが崖に向かってエッジに向かって歩いていて、エッジから出る直前に停止する場合、場合によっては1秒後に、エッジからテレポートされます。これは、サーバーが情報を処理した後で、「Wを押すのをやめた」パケットが送信されるためです。

ここに私が何を意味するかを理解するのに役立つラグダイアグラムがあります:http : //i.imgur.com/Prr8K.png

サーバーが処理するフレームごとに "W Pressed"パケットを送信するだけでもかまいませんが、これは帯域幅のコストがかかるソリューションのようです。

どんな助けでもありがたいです!

回答:


5

サーバーは最終的な判断を下しますが、クライアントが入力および位置として送信するものを検証および正常性チェックすることでそれを行う必要があります。あなたがしているのはプレーヤーをすぐに動かすことであり、あなたのコードで作成する期待はクライアントが本当のポジションであるということなので、私はこれを言います。

一般的にはうまくいくと思いますが、そうではありません。補足:クライアントはレンダラーにすぎないと言った後、サーバーのメッセージなしで移動するためのローカルコントロールをすぐにクライアントに与えます。両方の方法を使用することはできません。サーバーが移動するように指示するまで待つか、自分の位置をある程度制御し、サーバーを使用してチートを確認します。

回答が1秒に達していることをお知らせします。これは500msのレイテンシであり、あらゆる種類のアクションゲームにとっては途方もなく大きいものです。このターンアラウンドに非常に時間がかかる理由を見つけてください。コマンドキューのバックアップから、すぐに処理されないことから、帯域幅のフラッディング、または多くのパケットの損失の原因となるデーモンまで、さまざまなことが考えられます。

私が起こるべきだと思うのは

client sends a move + position update
server gets it t+latency time later
server verifies and sends out info to all clients
client receives this at (t+latency + latency)

ここでトリッキーな部分は、クライアントがそれ自体に関するメッセージを受信した場合、そのメッセージが「無効な移動、代わりにXYZに移動する」などのメッセージでない限り、ほとんど無視する必要があるということです。そのメッセージがあなたが情報を得ている他の誰かのクライアントのためのものであるなら、あなたはそれがどこにあるかのように見えるように時間内にフォワードを外挿する必要があります。


クライアントは自分の位置をまったく送信しません。単に予測/補間するだけです。それが端にあると考えると、それが端から落ちる理由です。また、ラグが1秒であると私が言った場所はわかりません。これは、8ミリ秒(ローカルテスト)から100ミリ秒(インターネット経由)に近いものです。私は定期的に完全なポジションの更新を送信するため、プレイヤーは後でセットバックしていると言いました。クライアントがそうであると考える位置を、押されたキーと一緒に送信し、サーバーがそれが可能かどうかを確認する必要があることを理解して私は正しいですか?
トーマス

「時々、彼はテレポートされるだろう」とは、私が時間を得た大きな遅延を暗示した。レスポンシブアクションゲームの場合、はい、クライアントが再生し、サーバーが時間をかけて再生し、不正行為があったかどうかをクライアントに通知します。オンラインマルチプレーヤーゲームでは、他の人が(サーバーから来た)位置をシフトするのがほとんどですが、自分の位置がサーバーの直接修正によって変わることはほとんどありません。他の人はあなたがポジション変えるなどを見る...
Patrick Hughes

しかし、これでもプレーヤーがサーバーの端から落ちるのではないでしょうか?フレームごとにパケットを送信しない限り、サーバーはプレーヤーが約32ミリ秒移動していると見なすことができます。(私は3フレームごとにのみパケットを送信します)。または、サーバーでの入力をまったくシミュレートせず、位置が押された入力の範囲内にあるかどうかを確認するだけであることを示唆していますか?
トーマス

サーバーはクライアントから報告された無効な動きのみを修正するため、クライアント自体が端を越えて運転しない限り、「崖から落ちた」というメッセージは送信されません。このフィードバックループでは、サーバーが、クライアントの世界観とその中での自分の位置を修正します。動きはさわやかでプレーヤーに反応します。ワールドオブジェクトとのやり取りなどの他のアクションには、サーバーがクライアントに何が起こったのかを伝えるのを待機し、ボックスをクリックして応答を待機することが含まれますが、ここでは動きについて話しているだけです。
Patrick Hughes

それは私が現在行っていることとよく似ています。サーバーに位置を送信し、サーバーにプレーヤーがその位置に移動できたかどうかを検証させます。これはもっとヒューリスティックなアプローチのようですが、私の意見では、サーバーに期間を決定させるので、ほとんど効果的ではないでしょう。各パケットでタイムスタンプを送信できますか?それは問題を根絶すると思います。HaloとSourceエンジンを使用するゲームはそれを使用していると思います。
トーマス

0

私はあなたの質問を次のように理解しています:

「転送」ボタンを押し始めるとサーバーがパケットを受け取り、「転送」ボタンを最後に離したときに別のパケットを受け取ります。したがって、サーバー上の実際の動きは、プレーヤーがクライアント側で表現しているものに対して、実際のゲームで約100ミリ秒「遅すぎる」ので始まり、終わります。そのため、プレーヤーが10秒移動したい場合、x >= 1オンラインではなく10.x秒移動する可能性があります。

これは、プレイヤーの意図したとおりにゲームの世界でプレイヤーの意志を表現せず、ユーザーエクスペリエンスをかなり低下させるので、悪いデザイン戦略です。

私がお勧めする解決策は、プレーヤーが取った歩数と方向を示すパケットを(できるだけ頻繁に)送信することです。サーバーは、正当性チェックに合格すると、新しいプレーヤーの場所でゲームの世界を更新します。そのため、プレイヤーは高い精度で移動し、高い棚から落ちることを回避できます。

代わりの方法は、過去1秒間のプレーヤーの位置を記憶し、ボタンが離された時間に遡って位置を修正することです。昔のラバーバンド効果を生み出すように聞こえます(別の理由のみ)。

したがって、基本的には、どのボタンが押されたか、ボタンが押された実際のゲーム時間、その後、どのボタンが離されたのか、正確な時間のパケットを送信する必要があります。


パトリックに言ったように、解決策はヒューリスティックなアプローチのほうが多いと思います。サーバーが "The Man"である代わりに、サーバーはクライアントデータの有効性をチェックします。もちろん、これは、遅延やその他のネットワークの問題によって誤検知が発生しないように、ある程度の余裕を持たせる必要があります。
トーマス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.