Dungeon-CampusMinden / Dungeon

The "Dungeon" is a tool to gamify classroom content and integrate it into a 2D Rogue-Like role-playing game.
MIT License
15 stars 36 forks source link

[GAME] Game.entities durch Game.components ersetzen? #517

Closed AMatutat closed 1 year ago

AMatutat commented 1 year ago

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 Componentwürde ich sowas wie Game.addComponent(this)aufrufen wollen und. in Game.addComponents müsste dann irgendwie sowas stehen

HashMap <Class,List> components; //ist das sinnig? 
...
static void addComponent(Component c) {
  if(components.contains(c.class) components.get(c.class).add(c);

else {
  List <c.class> newComponentList = new ArrayList<>();  //oder wieder Set?
  newComponentList.add(c);
  components.add(c.class, newComponentList);

  }
}

Ist das stimmig?

AMatutat commented 1 year ago

@AHeinisch kannst du das mal kritisch durchdenken?

AHeinisch commented 1 year ago
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.

cagix commented 1 year ago

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.

cagix commented 1 year ago

@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.

AHeinisch commented 1 year ago

@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.

cagix commented 1 year ago

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).

cagix commented 1 year ago

@AMatutat Bitte die Erkenntnisse als Zusammenfassung im nächsten Meeting vorstellen und diskutieren, falls möglich gleich auch mit vorbereiteten Handlungsempfehlungen.

AMatutat commented 1 year ago

Zusammenfassung/Was wir jetzt machen:

TldR

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)

Todos

AMatutat commented 1 year ago

@AHeinisch danke für die aufbereitung