Was ist ein angemessener Granularitätsgrad für eine komponentenbasierte Architektur?

26

Ich arbeite an einem Spiel mit einer komponentenbasierten Architektur. A Entitybesitzt eine Reihe von ComponentInstanzen, von denen jede über eine Reihe von SlotInstanzen verfügt, mit denen Werte gespeichert, gesendet und empfangen werden können. Factory-Funktionen wie das PlayerErstellen von Objekten mit den erforderlichen Komponenten und Steckplatzverbindungen.

Ich versuche, die bestmögliche Granularität für Komponenten zu ermitteln. Zum Beispiel gerade jetzt Position, Velocityund Accelerationsind alle einzelnen Komponenten, die in Reihe geschaltet. Velocityund Accelerationkönnte leicht in eine einheitliche DeltaKomponente umgeschrieben werden , oder Position, Velocityund Accelerationkönnte neben solchen Komponenten als Frictionund Gravityin eine monolithische PhysicsKomponente kombiniert werden.

Sollte eine Komponente die geringstmögliche Verantwortung tragen (auf Kosten einer Vielzahl von Verbindungsmöglichkeiten) oder sollten zugehörige Komponenten zu monolithischen Komponenten kombiniert werden (auf Kosten der Flexibilität)? Ich neige mich zu ersteren, aber ich könnte eine zweite Meinung gebrauchen.

Jon Purdy
quelle
Verwenden Sie eine eigene Physik-Engine oder integrieren Sie eine vorhandene?
Den
@Den: Ich schreibe einen Code für Physik , aber es ist keineswegs eine Engine . Nur alltägliche 2D-Kinematik.
Jon Purdy

Antworten:

14

Es gibt eine Grenze zwischen vollständiger Granularität, die zu keiner Verschwendung von Code oder einem blobartigen Zustand führt (weshalb Komponentenarchitekturen bevorzugt werden), und Benutzerfreundlichkeit.

Offensichtlich mögen die Dinge eine haben Position, aber sie sind nicht unbedingt dynamisch (also warum haben Velocityund Acceleration?). Allerdings wird etwas mit a Velocityein sich bewegendes Objekt sein, daher ist es sinnvoll, es auch Accelerationgruppiert zu haben .

Haben Sie einen Fall, in dem v und a benötigt werden, möchten aber keine Physiksimulation für sie? GravityWird es auch einen Punkt geben, wenn es sich nicht um physikalische Objekte handelt?

Gruppe, was Sinn macht.

Die kommunistische Ente
quelle
1
Klingt gerecht. Mein System hat nur eine sehr geringe Zentralisierung: Wenn Entitya Positionund einige Komponenten vorhanden sind, die zur PositionTeilnahme an der Physik beitragen, Entityist das de facto physisch. Ich denke, ich kann nur einige Komponenten für die logische Gruppierung hinzufügen und alle grundlegenden Komponenten in einer Verantwortung zusammenfassen. So das Hinzufügen, sagen wir, ein Movablezu einer Entityhätte die gleiche Wirkung wie das Hinzufügen eines Position, Velocityund Acceleration.
Jon Purdy
6

Um zu vermeiden, dass jede einzelne Variable, die ich vorschlagen würde, durch einen schweren Start verwaltet wird, wählen Sie eine Unterteilung nach Verantwortlichkeit und Refaktor, wenn sich die Situation logisch darstellt. Sie können die ersten Entwürfe auf Papier beginnen. Irgendwann werden diese groben Verantwortungsbereiche die Bausteine ​​Ihrer Einheiten.

Für ein überstürztes Beispiel haben Sie also ein Spiel. Das Spiel teilt sich in Environment + State. Die Umgebung wird in StaticWorld + MovingStuff aufgeteilt. Der Status wird in AIControlled + PlayerControlled aufgeteilt. Die grobe Idee des Schadens teilt sich in TakesDamage + GivesDamage.

Und so weiter.

Ähnlich wie der übliche Ratschlag "Spiele bauen, keine Engines!" Für Anfänger empfehle ich "Build Games, keine ausgefeilten Komponentensysteme!" denn nur mit persönlicher erfahrung mit einem laufspiel wissen sie, ob in zukünftigen arbeiten ein ausgeklügeltes komponentensystem gefragt ist.

Patrick Hughes
quelle
Ich bin kein neuer Entwickler. Wenn ich Komponenten habe, die eher auf Konzepten als auf Verhalten basieren (dh von oben nach unten oder von unten nach oben), ist meine Architektur dann nicht spröder und ausgefeilter? Ich kann jedes gewünschte Verhalten für kleine Komponenten implementieren, aber ich kann nicht immer das gewünschte Verhalten für vorkombinierte Komponenten erzielen. Ganz zu schweigen davon, dass ich nicht alles vorhersagen kann, was ich erreichen möchte, auch nicht in einem Spiel.
Jon Purdy
Der Nachteil von Bottom-up besteht darin, dass die Kommunikation zwischen Komponenten zu einem Problem wird und die Leute dazu neigen, viel zu klein im Maßstab des Modells anzufangen. Ich habe hauptsächlich versucht, vom Super-Mikro wegzulenken. "Xyz ist eine Komponente." "Rotation ist eine Komponente." "Rgb ist eine Komponente."
Patrick Hughes
Meinetwegen. Ich wollte nur sicherstellen, dass ich dich richtig verstanden habe. Mit dem Slot-System, über das ich verfüge, ist die Kommunikation zwischen Komponenten einfach und effizient. Daher sehe ich keine Nachteile für die "Super-Micro" -Skala. Ich beabsichtige nicht, dies in eine eigenständige Engine umzuwandeln, aber wenn ich dies tue, kann ich immer Abstraktionen einführen, wie die Komponentengruppen, die ich in meinem Kommentar zur Antwort von The Communist Duck erwähne.
Jon Purdy
4

Meine Vermutung wäre, Komponenten zu kombinieren, die viel Interaktion haben werden. In Ihrem Fall würde ich die Position in einer einzelnen Komponente halten und die Geschwindigkeit und Beschleunigung in einer Physikkomponente zusammenhalten.

Es hängt jedoch stark von Ihren Spielfunktionen ab (es sei denn, Sie erstellen ein Framework, das kein bestimmtes Spiel im Auge hat).

XGouchet
quelle
2
Das Problem beim Kombinieren von Komponenten mit viel Interaktion besteht darin, dass der andere Teil manchmal nicht benötigt wird.
Die kommunistische Ente
4

Mir ist klar, dass dies eine alte Frage ist, aber vielleicht wird jemand diese Antwort nützlich finden.

Ich glaube, das Systemswird Ihnen helfen, das Konstruieren von Komponenten besser zu verstehen. Systeme existieren in Architekturen, in denen Komponenten, abgesehen von einfachen Get- / Setter- und Hilfsfunktionen, keine eigene Logik enthalten. Systeme arbeiten mit Entitäten, die die Komponentenanforderungen erfüllen. Aus diesem Grund ist es am besten, Komponentendaten so weit zu trennen, wie es sinnvoll ist, diese Daten ohne die anderen Daten zu verarbeiten.

Zum Beispiel könnten Sie einen haben, MovementSystemder die Entities Positionbasierend auf deren aktualisiert Velocity. Dies könnte für einfache Einheiten im Spiel sein. Aber für den Spieler und die Feinde möchten Sie vielleicht eine Bewegung, Accelerationdie verarbeitet wird AcceleratedMovementSystem. Aber für Hindernisse möchten Sie vielleicht Friction. Das Terrain hat möglicherweise auch Reibung, aber keine Geschwindigkeitskomponente. Aber was ist mit Gravity? Füge es einfach hinzu, Spieler, Feind und Hindernis, und erstelle ein GravitySystem, um es zu verarbeiten.

Das Fazit ist, je entkoppelter Sie Componentssind, desto erweiterbarer ist die EntitiesVerwendung Systems.

Edit: Letzte Aussage deutlicher gemacht.

Edit: Ok, ich habe an meinem eigenen System gearbeitet und bin zu dieser Erkenntnis gekommen. Ein Beispiel für die Aufteilung von Position und Geschwindigkeit ist, dass durch die Manipulation der Geschwindigkeit die Position mit einem MovementSystem geändert wird. Infolgedessen benötigt ein 'InputMovementSystem' keine Position, um den Player von Benutzereingaben aus zu bewegen, da das MovementSystem die Änderungen in der Geschwindigkeit aufnimmt, die auf die Position angewendet werden sollen. Zugegeben, es würde immer noch gut funktionieren, sie zusammenzusetzen, aber das ist ein Beispiel dafür, warum das nicht so sein muss.


Ich habe kürzlich einen Blogbeitrag gelesen, der ungefähr so ​​aussah:

"Wenn Sie Daten haben, die mit zwei verschiedenen Komponenten gruppiert werden können, erstellen Sie am besten eine dritte Komponente mit diesen Daten."

Dan H.
quelle