7

以前にマルチプレイヤー ゲームを設計したことがありますが、学習/チャレンジ用の MMORPG アーキテクチャを作成したいと考えました。単一のサーバーで数百 (または数千) の同時プレイヤーをシミュレートしたいと考えています。

これまでのところ、サーバー上のすべてのゲーム オブジェクトをできるだけ頻繁かつ迅速に更新するための適切な方法を見つけるという問題に直面していることを除けば、これまでのところ非常に良好です。

ゲーム オブジェクトとは、すべてのプレイヤー、モブ、弾丸を意味します。

問題は、処理を高速化するためにすべてのプレイヤー、モブ、弾丸がサーバー側メモリのコレクションに保存され、衝突のチェック、ヘルスの更新、動きの更新などのためにそれらすべてを反復処理するのに時間がかかりすぎることです。 .

1000 人のプレイヤーがいて、全世界に 10000 のモブがいて、すべてのプレイヤーとクリーチャーが、弾丸などの他の 5 つのゲーム オブジェクト (それ以上でもそれ以下でもない) を作成する責任があるとしましょう。

これにより、(1000 + 10000) * 5 = 55000 個のゲーム オブジェクトがコレクションに含まれます。

4 GB RAM を搭載したデュアルコア HT i5 では、すべてのオブジェクトを繰り返し処理して更新すると、永遠に (数分) かかります。これは間違っています。

反復すると、コードは次のようになります (疑似):

for(int i = 0; i < gameobjects.Count; i++) {
  for(int j = 0; j < gameobjects.Count; j++) {
      // logic to verify if gameobjects[i] is in range of
      // gameobjects[j]
  }
}

最適化として、ゲーム オブジェクトを異なるゾーンとコレクションに分割することを考えていますが、すべてのオブジェクトを毎秒数回更新する必要があるという問題は解決しません。

サーバー側ですべてのゲーム オブジェクトを更新するにはどうすればよいですか? 興味深いゲーム デザイン パターンを見つけるために徹底的に検索しましたが、これまでのところ結果はありません。:(

前もって感謝します!

4

3 に答える 3

4

デザインを一新し、イベントベースのデザインを実装します。これには多くの利点があります。明らかな利点の 1 つは、実際に対話しているオブジェクトのみを更新する必要があることです。MMO ゲームでは常に大部分のゲーム オブジェクトがアイドル状態であるか、まったく表示されないためです。

どのプレイヤー画面にも表示されないオブジェクトを計算する必要がある理由はありません。それは正気ではなく、おそらく余裕のないサーバー ファームが必要です。代わりに、動きを予測しようとすることができます。または、現在相互作用していないすべてのオブジェクトのリストを保存し、これらをあまり頻繁に更新しません。

プレイヤーがオブジェクトを見ることができない場合は、ユニットをスムーズに移動させる代わりに、ユニットを遠くにテレポートさせることができます。基本的に、オブジェクトが移動できる限られた領域内でユニットを非常に長い距離移動します。オブジェクトがプレイヤーに見えなくても、オブジェクトが自由に動いているように見せる。通常、これは、新しいプレイヤーがゾーンに出入りしたときにイベントとしてトリガーされます。

これは、前回の更新からの時間を計算するだけで実現でき、オブジェクトがプレーヤーに表示されているかのように、オブジェクトが移動した距離を予測できます。これは、計算がはるかに簡単になるため、ルートが設定されているオブジェクトまたは NPC に特に役立ちます。

于 2013-04-28T15:19:03.170 に答える
2

あなたのコードは、すべての N 個のオブジェクトをチェックしているだけでなく、オブジェクトのすべての可能な相互作用をチェックしているため、実行速度が遅く、サンプルで N^2 の計算 = 3 025 000 000 が必要です。

このチェック回数を減らす 1 つの方法は、ゲーム ワールド内のオブジェクトをグリッドに配置することです。これにより、同じセルまたは整列されたセルにないオブジェクトは互いに相互作用できなくなります。

また、現在のコードは各インタラクションを 2 回チェックします。これは、内側のサイクルで i からループを開始することで簡単に修正できます。

for(int i = 0; i < gameobjects.Count; i++) 
  for(int j = i; j < gameobjects.Count; j++) 
于 2013-04-28T15:13:51.503 に答える
0

55,000 個のオブジェクトをループするのに遅すぎることはありません。明らかに、これらのオブジェクトに対してあまりにも多くのことを頻繁に行っており、おそらく常に行うべきではないことを行っています。

たとえば、モブの周りにプレイヤーがいない場合、それは本当に計算されるべきでしょうか? (森で誰もいない木が倒れたら、本当に音はするの?)

また、ループごとに多くのオブジェクトを更新する必要がない場合もあります。たとえば、プレーヤーは計算をクライアントに任せ、1 ~ 2 秒ごとに 1 回だけ「検証」することができます。すべてのプレーヤーの衝突をクライアントにダンプすると、サーバーのワークロードの処理がはるかに簡単になります。プレイヤーの弾丸またはレイキャストについても同じことが言えます。その見返りとして、プレイヤーにとってゲームがより流動的になります。

パスをたどるときの Mob は衝突をテストする必要がありますか、それともパスのノードで十分ですか?

すべてのオブジェクトを他のすべてのオブジェクトに対してテストするのはひどいものです。すべての Mob と他のすべての Mob をテストする必要がありますか、それとも特定のタイプまたは派閥のみをテストする必要がありますか? あなたの世界を小さなゾーンに分割して、その中のモブのみをその中のオブジェクトに対してテストすることはできますか?

MMO サーバーのコードを適切に機能させるために、膨大な作業が行われています。行われた最適化は、時には正気ではありませんが、それが機能する限り.

于 2013-04-28T15:11:10.317 に答える