クライアント側の予測で移動オブジェクトを補正する方法は?


11

Star Controlのようなmeleeをサポートするゲームサーバーを実装しています。船を飛ばして射撃し、動きを動かすための超単純な速度/加速/減衰物理学を備えています。

ここに画像の説明を入力してください

私は、Valve、Gafferon、Gambettaを読み、クライアント予測のためにGambettaのアルゴリズムを実装しました。

ここに画像の説明を入力してください

クライアント予測は、サーバーからの位置を更新することでプレーヤー船に作用し、サーバーで未処理の入力をプレーヤー船に再適用します。

残念ながら、私のゲームではうまく機能しません。ガンベッタの例では、すでに移動しているオブジェクトや段階的に更新されるコマンドは考慮されていないという事実と関係があると思います。(「ステップ」とは、フレームを意味します)。そのため、私のゲームでは、プレイヤーは(すでに動いている)船を加速するために押し上げます。船はクライアント上で動き続け、コマンドをサーバーに送信し、通常は次のステップでサーバーからワールドスナップショットを受信します。私はもっ​​と何かを得ます:

ここに画像の説明を入力してください

playerコマンドはクライアントのステップ3で実行されますが、サーバーではサーバーのステップ5でのみ実行されます。クライアントのステップ6でクライアントが世界のスナップショットを受信するまでに、特に高速の場合、予測はかなりずれます。

問題の核心は、クライアントがステップ5でコマンドを実行するのに対し、サーバーはステップ6でコマンドを実行することです。コマンドを使用してクライアントステップを送信し、サーバーをロールバックしてクライアントタイムステップを使用してコマンドを再実行することを検討しました。ただし、ロールバック以降に受信したコマンドがどうなるか、送信されたステップを変更することによってクライアントを不正に利用する方法など、他の多くの問題が発生する可能性があります。

このようなGoogleの動画を読んだり見たりすると、別のアプローチが言及されています。このアプローチでは、プレーヤーの位置をスナップショットの位置に合わせて徐々に変更します。

私の質問:

  • Gambettaのアルゴリズムを一定のステップ移動で機能させることができますか?それとも概念的に私のゲームと互換性がないのですか?

  • ステップを徐々に補間するのは正しい方法ですか?もしそうなら、サーバーから受信したばかりのオブジェクトと一致するように、クライアントの位置から既に移動しているオブジェクトをどのように補間しますか?

  • これらの方法、段階的補間、Gambettaのアルゴリズムは連携して機能しますか、それとも相互に排他的ですか?


私は同じことをしていて、まったく同じ問題に遭遇しました。速度を追加してサーバーの状態を適用し、入力を再適用するとすぐに、すでに処理された速度の変更が取り除かれました。最後に受信したメッセージ以降、すべての更新を再適用しようとしていますが、まだスムーズではありません。これに対する解決策を見つけたことがありますか?
MakuraYami 2016

@MakuraYamiはい-解決策を説明する記事を書き始めました。間もなく更新されます!
OpherV 2016

私は自分のプロジェクトにもっと取り組み、使用可能な解決策とこの問題について話しているいくつかのより良いリソースを見つけました。さらに議論したり、ソリューションを比較したりするなど、興味があります。連絡先を教えてください:)
MakuraYami

@makurayami Gmailでのユーザー名
OpherV 2016

回答:


5

私がこの質問をしてから6か月間、私はこの正確な問題(およびその他の多くの問題)に対処するための完全なオープンソースゲームサーバーを開発することになりました。http//lance.gg

ここに画像の説明を入力してください

関係する研究開発により、私は自分の質問に答えることができます。

  • Gambettaのアルゴリズムを一定のステップ移動で機能させることができますか?それとも概念的に私のゲームと互換性がないのですか?

    エンティティの動きが(クライアントのPOVから)確定的でない場合、Gambettaのアルゴリズムは機能しません。エンティティが物理や他のプレイヤーによる入力なしに影響を受ける可能性がある場合、たとえば、より精巧なアプローチをとる必要があります。

  • ステップを徐々に補間するのは正しい方法ですか?もしそうなら、サーバーから受信したばかりのオブジェクトと一致するように、クライアントの位置から既に移動しているオブジェクトをどのように補間しますか?

    これは、クライアントがサーバー更新を調整するという別のトピックに触れています。段階的な補間は機能しますが、問題のような非常に速いペースのゲームでは、実際に外挿を実装することをお勧めします

  • これらの方法、段階的補間、Gambettaのアルゴリズムは連携して機能しますか、それとも相互に排他的ですか?

    それらは一緒に動作できますが、エンティティの動きがクライアントのPOVから確定的である場合に限られます。したがって、エンティティが挿入やドラッグなどの物理学または疑似物理学の影響を受けている場合は機能しません。


1

あなたのゲームはタイムステップで考えるには「リアルタイム」すぎるようです。ゲームが「ターンベース」であると見なせる場合にのみ、「ターン」の観点から考えます。それ以外の場合は、ターンまたはステップの考えを放棄します。その後、すべてが簡単になります:)

プレーヤーのローカル予測を行い、他のエンティティのみを補間することに注意してください(シリーズの3番目の記事で説明)。すでに移動していたオブジェクトのサーバー更新を処理する方法は、サーバー側の調整です。これは、2番目の記事(リンク先の記事)の下半分で説明されています。

お役に立てれば :)


明確にするために-「ステップ」とは、1秒あたり60回実行される「フレーム」を意味します。実際のゲームの進行とレンダリングを区別するために、これをステップと呼びます(フレームではありません)。理想的には、どちらも1秒あたり60で同期されます。見事に機能するサーバー側調整のバージョンをすでに実装しました。この質問は、プレイヤーの船にのみ言及しています-プレイヤーのコマンドに関係なく(慣性のために)常に動いています。それが私の難点です。それについて何か考えはありますか?:)
OpherV 2016年

フレームはステップとは異なります。ステップは一定の予測可能な順序で移動します。フレームは可変時間移動するため、進行にはそのフレームのデルタ時間を掛ける必要があります。
Tealr 2016年

@Tealr確かに、「ステップ」という用語を最初に使用したのはそのためです。「ステップ」の使用はターンベースのゲームに限定されず、私のゲームではステップは正確に1であることを明確にしたかっただけです。 / 60秒/レンダリングに関係なく。
OpherV 2016年

自分自身の実験で注意する点は、1/60です。は非常に高速であり、1x1を超える参加のほとんどのオンラインゲームは1/10秒で機能します。更新またはその近辺。
Patrick Hughes
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.