Problem mit der Verarbeitung von Komponentenpools - Entitätssubsystem


8

Architekturbeschreibung

Ich erstelle (entwerfe) ein Entitätssystem und bin auf viele Probleme gestoßen. Ich versuche, es so datenorientiert und effizient wie möglich zu halten. Meine Komponenten sind POD-Strukturen (genauer gesagt ein Array von Bytes), die in homogenen Pools zugeordnet sind. Jeder Pool verfügt über einen ComponentDescriptor - er enthält nur Komponentennamen, Feldtypen und Feldnamen.

Die Entität ist nur ein Zeiger auf ein Array von Komponenten (wobei die Adresse wie eine Entitäts-ID wirkt). EntityPrototype enthält den Entitätsnamen und ein Array von Komponentennamen. Schließlich Subsystem (System oder Prozessor), das auf Komponentenpools arbeitet.

Tatsächliches Problem

Das Problem ist, dass einige Komponenten von anderen abhängen (Modell, Sprite, PhysicalBody, Animation hängt von der Transformationskomponente ab), was bei der Verarbeitung viele Probleme verursacht.

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

Es gibt keine Möglichkeit, sie mithilfe von Indizes zu verarbeiten. Ich arbeite 3 Tage daran und habe noch keine Ideen. In früheren Entwürfen war TransformComponent an die Entität gebunden - aber es war keine gute Idee. Können Sie mir einige Ratschläge geben, wie man sie verarbeitet? Oder sollte ich vielleicht das Gesamtdesign ändern? Vielleicht sollte ich Pools von Entites (Pools von Komponentenpools) erstellen - aber ich denke, es wird ein Albtraum für CPU-Caches.

Vielen Dank


Multiplayer? (Es ist relevant)
Jonathan Dickinson

Antworten:


2

Haftungsausschluss: Rein von meinem Systemklassenwissen abgehen.

Ich dachte ursprünglich, warum nicht einfach eine Hash-Funktion für die Entitäts-ID für Ihren Index verwenden?

Auf diese Weise würden Sie bekommen

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

Oder es waren jedoch die Entitäten, die zufällig platziert wurden. Sie können Pools für alle Komponenten und für Entitäten haben und den Entitätspool als "Master" verwenden, sodass Kollisionen mit dem Entitätsarray verglichen werden. Aber natürlich haben Sie das Problem, Komponenten und Einheiten zu recyceln.

Wenn Ihr Spieldesign dies zulässt, können Sie vorausplanen, wohin die einzelnen Entitätstypen gehen, um ein möglichst effizientes Packen zu erhalten. Angenommen, die Entitäten 0-20 sind für Panzer reserviert, die Entitäten 21-30 für Häuser und 31-60 für BGTrees. Sie sind möglicherweise nicht in der Lage, unendlich viele Baddos effizient zu erzeugen, und beeinträchtigen die Dynamik von Komponentensystemen, aber dies würde das Problem lösen. Ich sehe keinen Weg, deinen Kuchen zu haben und ihn auch zu essen.

Ich habe darüber nachgedacht, wie Sie den Render-Durchgang möglicherweise beschleunigen können, wenn Sie einen haben RenderingComponent, der alle Daten enthält, die das Rendering-System benötigt, damit es nur eine Reihe dieser Dinge durchblasen kann, aber dann gibt es einen Overhead beim Kopieren von Daten. Jedes Mal, wenn Sie einen Zeiger dereferenzieren, denken Sie darüber nach, ob er sich noch im Cache befindet oder nicht.

Wenn Sie ein superschnelles Spiel wollen, würde ich sagen, planen Sie Ihre Zuteilung. Wenn Sie eine flexible Spielarchitektur wünschen, rollen Sie die Hashtabellen und Zeichenfolgen-IDs aus. Jedes Mal, wenn Sie Flexibilität wünschen, müssen Sie eine Abstraktion erstellen, was zu einem Overhead führt.

TL; DR;
Basierend auf dem, was Sie beschrieben haben, würde ich eine höhere Ebene RenderComponentmit Zeigern auf Spriteund TransformKomponenten erstellen und ihr die erforderlichen Referenzen geben, wenn Sie die Entität initialisieren.

(Entschuldigung für jede wahrgenommene Wanderung, ich habe auch in meinem System darüber nachgedacht, also war dies eine Gelegenheit, darüber nachzudenken.)


Ich weiß nicht, ob Hash-Maps so effektiv sind. Ich möchte ein Entitätssystem haben, in dem Subsysteme DOD-Funktionen enthalten wie: void update(u32 n, PhysicalBodyComponents* bodys, Transform* transforms)Ich möchte an vielen Eingaben arbeiten und diese Funktion auf mehrere Kerne aufteilen. Ist es mit Hashmaps möglich?
Mani3xis

Die Hashmaps sind lediglich eine Möglichkeit, Beziehungen zwischen Entitäten und Komponenten zu identifizieren. Dies hängt davon ab, wie Ihr Spiel eingerichtet ist, aber ich sehe keinen effizienten Weg, um sicherzustellen, dass Ihr bodysund Ihr transformsArray in einer Reihe stehen. Dies ist nur etwas, das Sie nicht umgehen können, ohne entweder eine Abstraktionsebene hinzuzufügen oder Ihre Zuordnung zu planen. Ich habe das Gefühl, nicht über das Fachwissen zu verfügen, um über die Skalierung auf mehrere Kerne zu sprechen. Vielleicht finden Sie eine Frage zum Einfädeln und Skalieren oder schreiben Sie Ihre eigene.
michael.bartnett

Die Skalierung ist einfach, wenn Funktionen an linearen Arrays arbeiten. Ich kann für jeden Kern einen Bereich einrichten und ihn einfach ausführen. Deshalb versuche ich, Hashmaps zu vermeiden. Ich werde versuchen, dieses Entitätssystem neu zu gestalten. Ich muss sehr vorsichtig mit Caches sein - PS2 hat sehr begrenzten RAM usw. Übrigens: Nichts ist unmöglich :)
mani3xis

Nichts ist unmöglich, aber nicht alles ist machbar;). Sie können nach Einfachheit und Eleganz der Implementierung, Ausführungsgeschwindigkeit und Speicherverbrauch streben: Wählen Sie zwei aus. Wenn Sie Ihre Lösung gefunden haben, senden Sie sie bitte als Antwort. Ich bin sicher, dass ich nicht der einzige bin, der sie sehen möchte.
michael.bartnett
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.