Closed AMatutat closed 1 year ago
@AHeinisch kannst du das mal kritisch durchdenken?
Das Iterieren über einzelne Komponenten klingt erst gut, bis man sich bereits unsere aktuellen Filter anschaut. Hier einmal unsere aktuellen Systeme und ihre Komponenten: | System | Komponenten |
---|---|---|
AISystem | AIComponent | |
CollisionSystem | HitboxComponent | |
DrawSystem | AnimationComponent PositionComponent |
|
Healthsystem | HealthComponent AnimationComponent |
|
PlayerSystem | PlayableComponent VelocityComponent |
|
ProjectileSystem | ProjectileComponent PositionComponent VelocityComponent |
|
SkillSystem | SkillComponent | |
VelocitySystem | VelocityComponent PositionComponent AnimationComponent |
|
XPSystem | XPComponent |
Dadurch muss bei den meisten Systemen nochmal gefiltert werden und sichergestellt werden, dass die anderen Komponenten auch noch verfügbar sind.
Mir ist dabei dann die Idee gekommen, wenn ein System entweder eine Validierungsmethode zur Verfügung stellt und diese dann im ECS benutzt wird um eine speziell vorbereitete Liste für ein System baut bzw. aktuell hält. Damit würde z.b. das ProjectileSystem nicht nochmal filtern müssen.
Außerdem gibt es das Problem aktuell meldet sich beim ECS nur die Entität an und rein theoretisch muss beim ECS dann auch bekannt gegeben werden, sobald sich eine Entität ändert (Komponente hinzugefügt oder entfernt) sonst gewinnen wir hier nichts.
Idee | Vorteile | Nachteile |
---|---|---|
ECS verwaltet nur Entitäten und gibt auch nur Entitäten heraus | einfach zu verwalten | jedes System muss erneut filtern |
ECS verwaltet nur Komponenten und gibt an sich nur diese heraus | Systeme die nur eine Komponente nutzen müssen nicht mehr filtern ECS kann immer noch recht einfach implementiert sein |
Entitäten an sich nur über Komponenten zu erreichen Systeme mit mehr als einer Komponente müssen erneut filtern, ob die gegebenen Komponenten mit weiteren passenden Komponenten verbunden sind(selbe, wenn Entitäten gegeben wären) |
ECS verwaltet Entitäten und verwaltet Systemlisten | jedes System hat passende Listen vorhanden kein massives Filtern | schwerer zu implementieren jedes System brauch eigene Liste von Entitäten Jede Änderung muss vom ECS verwaltet werden (entfernen von Komponenten bzw. hinzufügen) |
Was alles angefasst werden muss, um sowohl auf Komponente oder Systemlisten umgestellt wird. Entity.addComponent() sowie removeComponent() müssen jeweils erweitert werden, sodass sie entweder nur über das ECS gestartet werden oder dass sie sich beim ECS als verändert melden. Die Systeme müssen alle angefasst werden, damit die speziellen Listen angefragt werden, anstelle von allen Entitäten. Die Komponenten an sich müssten hiervon unverändert bleiben.
Der Aufwand geschätzt (wahrscheinlich sehr unpräzise)
Dies wäre hier jetzt erstmal so wie ich es mir vorstelle es umgebaut werden muss.
aktuell 4 systems mit nur einer component - für diese würde sich das filtern erledigen, da direkt über gane ausgeliefert.
aktuell 5 systems mit zwei oder drei components. diese würden sich das filtern nach der hauptcomponent sparen (würde vom game direkt geliefert), nur noch ein extra filter nach der zweiten component.
klingt für mich in beiden fällen nach einer massiven zeitersparnis.
aber man müsste einen verlässlichen weg finden, dass eine entität tatsächlich immer sauber registriert ist, auch wenn jemand components hinzufügt oder entfernt. das muss einfach und "idiotensicher" sein.
@AMatutat @AHeinisch schaut mal https://github.com/libgdx/ashley/wiki/Framework-overview an. das ist das in libgdx eingebaute(?!) ecs.
die haben eine "family", um ähnliche entities gezielt behandeln zu können => spart arbeit in den systems.
außerdem haben die einen "componentmapper", mit dem man schnell über components einer entität iterieren kann.
halte ich beides für gute konzepte. bitte prüfen und übertragen.
@AMatutat @AHeinisch schaut mal https://github.com/libgdx/ashley/wiki/Framework-overview an. das ist das in libgdx eingebaute(?!) ecs.
die haben eine "family", um ähnliche entities gezielt behandeln zu können => spart arbeit in den systems.
außerdem haben die einen "componentmapper", mit dem man schnell über components einer entität iterieren kann.
halte ich beides für gute konzepte. bitte prüfen und übertragen.
Ich würde mich da mal einlesen und gucken, ob und wie viel Arbeit das umbauen wäre.
nicht "umbauen", sondern eher "ergänzen" mit blick auf die diskussion oben, ob wir vielleicht in game lieber components halten/verwalten sollen statt entities (oder zusätzlich).
@AMatutat Bitte die Erkenntnisse als Zusammenfassung im nächsten Meeting vorstellen und diskutieren, falls möglich gleich auch mit vorbereiteten Handlungsempfehlungen.
Zusammenfassung/Was wir jetzt machen:
Die Systeme werden um einen Filter erweitert und speichern sich die Menge an Entitäten auf denen sie agieren eigenständig ab. Dafür melden sich Entitäten beim hinzufügen/löschen von Components beim Game
, dieses gibt die Information dann an die Systeme weiter.
Wenn Entitäten gelöscht werden, werden vorher alle Components entfernt (daher fliegt die Entität aus den Mengen der Systeme)
System
erweitern
Set entities
zum speichern der Entitäten im VerantwortungsbereichConsumer<Entity>
accept
Methode fügt/entfernt Entitäten anhand der Components zum Set (hinzu)
Game
erweiternvoid updateEntity(Entity entity
, welche für jedes System die accpet
aufruft.Entity
erweitern
dropAllComponent
MethodeGame#updateEntity
, wenn ein Component hinzugefügt/entfernt wird. @AHeinisch danke für die aufbereitung
In mehren Diskussionen kam die Idee auf, anstelle einer Collection an Entities in Game zu speichern könnten mehrere Collections (für jeden Component-Typ eine) in Game gespeichert werden. Systeme könnten so schneller auf die für sie wichtigen Components zugreifen und können für sie uninteressante Entitäten ignorieren
Für mich wäre ein entscheidender Punkt, dass die Collections für die Components in Game automatisch angelegt werden. Im Konstruktor von
Component
würde ich sowas wieGame.addComponent(this)
aufrufen wollen und. inGame.addComponents
müsste dann irgendwie sowas stehenIst das stimmig?