ソースのようなエンジンはエンティティをどのように処理しますか?


9

ソースエンジン(およびその前任者、goldsrc、quake's)では、ゲームオブジェクトは2つのタイプ(ワールドとエンティティ)に分かれています。世界はマップジオメトリで、エンティティはプレーヤー、パーティクル、サウンド、スコアなどです(ソースエンジンの場合)。

すべてのエンティティには、そのエンティティのすべてのロジックを実行するthink関数があります。

したがって、処理する必要のあるものがすべてthink関数を含む基本クラスからのものである場合、ゲームエンジンはリストにすべてを格納し、すべてのフレームでループしてその関数を呼び出すことができます。

一見すると、このアイデアは合理的ですが、ゲームに多くのエンティティがある場合は、リソースが多すぎる可能性があります。

では、Sourceなどのエンジンは、ゲームオブジェクトの処理(処理、更新、描画など)をどのように行うのでしょうか。


2
なぜそれはどうして重要なの<some commercial engine>ですか?
共産主義者のアヒル

8
@共産主義のアヒル、ここでの本当の問題は、成功したエンジンがどのようにしてそれを学べるのかという
11

回答:


5

まあ、それを行うための他の方法には非常に多くありません-あなたがしようとしている必要がありを通じて、コールループにthink()数フレームごとたら、少なくともすべてのエンティティのために。

エンティティを独自のスレッドに配置することもできますが、その場合、状態同期の悪夢全体が発生します。これは間違いなく価値がありません。

一見すると、このアイデアは合理的ですが、ゲームに多くのエンティティがある場合は、リソースが多すぎる可能性があります。

これが、ソースエンジンが一度に存在できるエンティティの数に厳しい制限を課している理由です。4096エンティティのうち、半分(2048)しかネットワークに接続できません。これらの制限のいずれかを超えると、ゲームがクラッシュします。

そのため、マップを作成するときに、約800を超えるエンティティを使用しないことをお勧めします。


2 ^ 12関数呼び出しは、各フレームのBIG番号のままですか?
JulioC

@ジュリオ:まあ、60 fpsのときは1秒あたり246kの関数呼び出しです。これは多くのことですが、今日のハードウェアでは確実に実行できます。ただし、これは、ソースエンジンがクラッシュする前に許可される絶対最大値であることを覚えておいてください。通常、マップ上に存在するエンティティははるかに少なくなります。
BlueRaja-ダニープフルフフト

5
エンティティには次の思考時間があり、think関数はすべてのエンティティではなく、すべてのフレームで呼び出されるわけではありません。地震2の最小思考時間は0.1(100ミリ秒)で、エンティティ処理では10 fpsしかなかったことを覚えています。
bcsanches

「エンティティを独自のスレッドに置くこともできますが、その場合、状態同期の悪夢が完全になくなります。これは間違いなく価値がありません。」:あなたは、それはそれだけの価値はないと思う場合は、これらのキルゾーン4枚のスライドをチェックde.slideshare.net/jrouwe/...
タラ

3

あなたが言及するこれらのステップは、おそらく別のエンジンで行われます。単純なゲームエンジンは通常、1つのパスでそれらを使用するだけです。あなたのシーケンス

for each object
    do physics
    do game logic
    draw

なる

call physics subsystem
call game logic subsystem
call drawing subsystem

物理エンジンが位置とサイズを処理します。

Game Logic Engineは、Physics Engineが変更したもの(ウェイポイントを妨害する可能性がある...)、キャラクターの目標およびキャラクターが行うべき動作を解釈、スケジュールされたスクリプトを実行します(このシンク関数)。

描画エンジンは、どのオブジェクトが表示されているかを描画し、Quakeエンジンはここで一種のチートをしているため、彼はどのオブジェクトが表示されているかを知っています(描画セクションを参照)。

あなたへの私のアドバイスは、シミュレーションがゲームエンジンではなくどのように行われるかを研究することです。ゲーム開発に関連する巨大なポップカルチャーがあり、ゲームエンジンは命令型言語で作成されています(伝統と速度のため)。ですから、良い教科書(理論ではなく)を入手し、エンジンやパズルを何時間も見ていたのではなく、エンジン(実践)を見る方が私にとってより賢明でした。

物理

すべてのエンティティを反復処理して{think、draw}を実行するという概念全体が問題を引き起こす可能性があります。衝突などがあります。私はバルブがHavokを持っていると信じています。Havokが十分に正確な物理を処理していると思います。

考える

Think関数は、ゲームの時間がnextthinkの時間と等しいときに実行されます。これはQuakeエンジンでこのように機能し、QuakeエンジンはHalf Lifeエンジンの基本です。毎回実行されるわけではありません。

内部的には、エンティティのリストを繰り返し処理して、think関数を呼び出す時間が経過したかどうかを確認するだけです。時間の複雑さはO(N)になります。Nはエンティティの数です。

非常に多数のエンティティがある場合は、それがfpsをどの程度改善するかを測定する必要があります。アムダールの法則により、目に見えないスピードアップになる可能性があることに注意してください。つまり、すべての項目を反復処理し、1つの数値を減らして確認するだけです。

エンティティをnextthinkで並べ替えることでスピードアップします(エンティティへのポインタのリストを作成し、毎回それを並べ替えます。エンティティの配列ではなく、エンティティはnextthinkをいつでも変更する可能性があるため、配列に再配置するとO(N)がO(N)になります1)リスト内)。

LinuxのO(1)スケジューラも確認する必要があります。

ドロー

エンジンは、カメラがある領域からほぼ見えるものを描画します。ゲームレベルはツリーに分割され、領域はそのツリーの葉です。詳細については気にしません...したがって、エンティティが表示されている場合は、一連の表示されているエンティティに入れられて描画されます。

それらは、潜在的に目に見える領域である領域を格納します。これは「潜在的に表示されるセット」、略してPVSと呼ばれます。PVSの視覚化があり、緑のカプセルがプレーヤーであり、彼の周りには彼のPVSが含むものがレンダリングされています。


2

したがって、処理する必要のあるものがすべてthink関数を含む基本クラスからのものである場合、ゲームエンジンはリストにすべてを格納し、すべてのフレームでループしてその関数を呼び出すことができます。

一見すると、このアイデアは合理的ですが、ゲームに多くのエンティティがある場合は、リソースが多すぎる可能性があります。

実際にすべてを1つの大きなリストに入れるのは、通常は望ましいことではありません。たとえば、タイプに基づいてエンティティをリストにグループ化する場合は、処理を複数のスレッドに分散することをお勧めします。たとえば、シミュレーション段階でFooタイプのすべてのエンティティが他のエンティティと相互作用しないことがわかっている場合は、それらを完全にオフロードできます。それらがいくつかの大きな特異なリスト全体に意地悪に散らばっている場合、これははるかに困難になります。

その時点で、必ずしも共通の基本クラスからすべてを派生させる必要はありません。ソースは、そうでなければその点でデータとして実装される可能性のあるものに対する継承の乱用でかなり外に行きます。

もちろん、他のコアへの作業のオフロードを開始した場合でも、フレームごとに処理できるエンティティの数には常に上限があります。それを回避する方法はありません。実装でその制限が何であるかを理解し、それを軽減するための手順を実行するだけです(それらを必要としないオブジェクトの処理フェーズの適切なカリング、オブジェクトの過度な粒度の回避など)。 cetera)。


1

あなたが考慮しなければならないのは、これまでの答えの一連の思考の後に続くことは、あなたのパフォーマンスはこれらの思考関数をいつどのように呼び出すかにも影響するということです。

ソースエンジンに投稿したリンクを見ると、エンティティごとに思考時間とさまざまな思考コンテキストを設定できること、また誰かがすでに指摘している明らかなハードリミットに加えて、これがより高いパフォーマンスを達成するための鍵となることを読むことができますエンティティの数が多い場合、複数の実行フレームを介してパフォーマンスのハングリー処理を分散する段階的な更新を作成するか、現在のコンテキストに応じて不要な処理を除外します(つまり、遠すぎるエンティティやプレーヤーの認識を超えるエンティティは必要ありません)プレイヤーの近くにいるキャラクターと同じレベルの「詳細を考えて」は、2マイル離れたキャラクターが鼻をつまんでいるのを見ることはありません)。

また、特定のゲームロジックと状況に応じて、さらに特定のレベルの最適化があります。


「プレイヤーは2マイル離れたところにいるキャラクターが鼻をつまんでいるのを見ることはありません」ハハ!しかし、仮想関数の使用が非常に遅いことを誰も指摘していないのはなぜですか?
Tara
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.