コンポーネントプールの問題の処理-エンティティサブシステム


8

アーキテクチャの説明

エンティティシステムを作成(設計)していて、多くの問題に遭遇しました。私はそれを可能な限りデータ指向で効率的に保つようにしています。私のコンポーネントは、同種のプールに割り当てられたPOD構造(正確にはバイトの配列)です。各プールにはComponentDescriptorがあります。コンポーネント名、フィールドタイプ、フィールド名のみが含まれています。

エンティティは、コンポーネントの配列へのポインタにすぎません(アドレスはエンティティIDのように機能します)。EntityPrototypeには、エンティティ名とコンポーネント名の配列が含まれています。最後に、コンポーネントプールで機能するサブシステム(システムまたはプロセッサ)。

実際の問題

問題は、いくつかのコンポーネントが他のコンポーネントに依存していることです(モデル、スプライト、PhysicalBody、アニメーションは変換コンポーネントに依存します)。これは、コンポーネントの処理に関して多くの問題を引き起こします。

For example, lets define some entities using [S]prite, [P]hysicalBody and [H]ealth:
Tank:   Transform, Sprite, PhysicalBody
BgTree: Transform, Sprite
House:  Transform, Sprite, Health

and create 4 Tanks, 5 BgTrees and 2 Houses and my pools will look like:

TTTTTTTTTTT // Transform pool
SSSSSSSSSSS // Sprite pool
PPPP        // PhysicalBody pool
HH          // Health component

インデックスを使用してそれらを処理する方法はありません。3日間かけて作業を行っていますが、まだアイデアはありません。以前の設計では、TransformComponentはエンティティにバインドされていましたが、それは良い考えではありませんでした。それらの処理方法についてアドバイスをいただけますか?それとも、全体的なデザインを変更する必要がありますか?エンティティのプール(コンポーネントプールのプール)を作成する必要があるかもしれませんが、CPUキャッシュの悪夢になると思います。

ありがとう


マルチプレイヤー?(関連あり)
ジョナサンディキンソン

回答:


2

免責事項:私のシステムクラスの知識から完全に外れます。

私は当初、インデックスのエンティティIDでハッシュ関数を使用しないのはなぜだと思いましたか?

そうすれば

T[A]nk:   Transform, Sprite, PhysicalBody
B[G]Tree: Transform, Sprite
H[O]use:  Transform, Sprite, Health

and create 4 Tanks, 5 BgTrees and 2 Houses and my pools will look like:

OGAGAGGOGGG // Entity pool (letters corresopnding to entity type)
TTTTTTTTTTT // Transform pool
SSSSSSSSSSS // Sprite pool
P P P  P    // PhysicalBody pool
H      H    // Health component

または、偶然に配置されたエンティティでした。すべてのコンポーネントとエンティティのプールを作成し、エンティティプールを「マスター」として使用して、エンティティの配列に対して衝突をチェックすることができます。しかし、もちろん、コンポーネントやエンティティのリサイクルの問題が発生します。

ゲームデザインで許可されている場合は、各タイプのエンティティの配置先を事前に計画して、可能な限り最も効率的なパッキングを実現できます。たとえば、エンティティ0〜20は戦車用に、エンティティ21〜30は家用に、31〜60はBGツリー用に予約されているとします。無限のバッドを効率的に生成することはできないかもしれませんし、コンポーネントシステムのダイナミズムを打ち負かしますが、それで問題は解決します。あなたのケーキを持ってそれを食べる方法も見当たりません。

RenderingComponentレンダリングシステムが必要とするすべてのデータが含まれているため、レンダーパスを高速化する方法を考えていたので、これらの配列を一気に通過できるようになりましたが、データをコピーするオーバーヘッドが発生しました。また、ポインターを逆参照するときはいつでも、それがまだキャッシュにあるかどうかについて考えています。

超高速のゲームが必要な場合は、割り当てを計画してください。柔軟なゲームアーキテクチャが必要な場合は、ハッシュテーブルと文字列IDをロールアウトします。柔軟性が必要なときはいつでも、抽象化を構築する必要があるため、オーバーヘッドが発生します。

TL; DR;
あなたが説明した内容に基づいRenderComponentSpriteTransformコンポーネントへのポインターを使用してより高いレベルを作成し、エンティティを初期化するときに必要な参照を提供します。

(とりとめのないものと認められたことをお詫びします。私もこれについてシステムで考えていたので、これを検討する機会でした)


ハッシュマップがそれほど効果的かどうかはわかりません。サブシステムに次のようなDOD機能が含まれているエンティティシステムが void update(u32 n, PhysicalBodyComponents* bodys, Transform* transforms)必要です。多くの入力で作業し、この機能を複数のコアに分割したいです。ハッシュマップで可能ですか?
mani3xis 2012年

ハッシュマップは、エンティティとコンポーネント間の関係を識別するための単なる方法です。これはゲームのセットアップ方法に依存しますがbodystransformsアレイが整列することを保証するための効率的な方法はありません。これは、抽象化レイヤーを追加したり、割り当てを計画したりしなければ、回避できないものです。マルチコアへのスケーリングについて話す専門知識がないと思います。スレッド化とスケーリングに関する質問を見つけるか、独自に作成してください。
michael.bartnett 2012年

関数が線形配列で動作している場合、スケーリングは簡単です。各コアの範囲を設定して実行するだけです。それが私がハッシュマップを避けようとしている理由です。このエンティティシステムの再設計を試みます。私は、キャッシュ・ミスとは本当に注意しなければならない- PS2はところで、など非常に限られたRAMを持っている:何も不可能です:)
mani3xis

不可能なことは何もありませんが、すべてが可能であるとは限りません;)。実装のシンプルさと優雅さ、実行速度、およびメモリ消費量を追求することができます。2つ選んでください。あなたがあなたの解決策を見つけたら、それを答えとして投稿してください。私がそれを見たいのは私だけではないことは確かです。
michael.bartnett 2012年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.