On Github Cultrarius / ECS-Vortrag
Michael Galetzka / michael.galetzka@disy.net
Wer kennt es?
Wer hat es schon benutzt?
Wir bauen ein neues 3D Fantasy-Computerspiel mit Drachen, Einhörnern, etc.
Wie würde eine passende Architektur aussehen?
GameObject |-PhysicsObject | |-StaticObject | | |-SceneLight | | |-Tree | |-MoveableObject | |-Bullet | |-GameCharacter | |-Unicorn (eat grass, make rainbows, ...) | |-Dragon (breathe fire, eat unicorns, ...) |-ParticleEmitter |-ScriptObject |-UtilityObject
Bisher waren Lichter vom Typ StaticObject.
Lichter sind ab jetzt MoveableObject statt StaticObject → schlechter optimierbar, hat nun unnötige Methoden
Alternative: ein zweites Licht als MoveableObject erstellen → Code Duplikation oder zumindest Overhead
Unsere Einhörner sind nicht majestätisch genug!
Neue getLightEmitters Methode für GameCharacter? → viel Overhead und fette API
Wir "hacken" ein bewegliches Licht, welches dem Einhorn folgt
DEAL WITH IT
Unser Produzent will für den Plot eine neue Kreatur: den Unidragon (Kreuzung Unicorn/Dragon)
Err… Refactoring?
Inheritance over Composition!
Unklare und schnell wechselnde Anforderungen
Viele verschiedene (mehr oder weniger unabhängige) Akteure ⇒ Vermischung der Zuständigkeiten
Entities haben keine Daten und kein Verhalten, sind nur Namen
Components beinhalten ALLE Daten für die Entities, keine Logik
Die komplette Logik ist in Systems enthalten, die über vordefinierte Filter mit Entities versorgt werden
Entities sind der Primärschlüssel (= ID)
Components sind die einzelnen Spalten (=Daten)
Systems können über Abfragen die für sie wichtigen Zeilen bearbeiten
Components: Position Velocity Mesh (Wireframe) Textures LightEmission PhysicsInfo (elasticity, mass, roughness, etc.) Particle Emission Systems: PhysicsSystem (movement, constraints) ScriptSystem RenderSystem ParticleSystem AnimationSystem
Licht-Entities bekommen eine Velocity-Component angehängt
Evtl. muss das RenderSystem angepasst werden
Einhorn-Entities bekommen eine LightEmission-Component angehängt.
Neue Kreatur-spezifische Components erzeugen (Mesh, Texture, Script, …).
Archetypen, Templates, Factories oder ähnliches notwendig bei komplexeren Projekten
Oft nur schwer in bereits bestehende Systeme integrierbar
Naive Implementierung ist sehr langsam
Debugging ist schwerer (dadurch dass es keine Klassen gibt, fällt es schwer, einzelne Entities wiederzuerkennen und zu verfolgen)
Debuggen ist einfacher (es gibt nur einen Ort für die Logik)
Klare Trennung zwischen Daten, Akteuren und Verhalten
Extrem einfach, neue Features sauber in ein bestehendes System einzufügen → sehr gut für Prototyping geeignet
Einfaches einbinden von third-party Libs möglich
Data-Driven Design!
Lightning FAST (Cache optimiert; kommt natürlich auf Implementierung an)
Komponenten können gepoolt werden
Einfaches Multithreading möglich (ein Thread pro System)
Einfache Serialisierung aller Daten
Ashley (Java)
Artemis-ODB (Java)
Artemis Port (C++)
Artemis C# Port (C#)
EntityX (C++)
anax (C++)
Entitas (C#)
ECS werden seit Jahren erfolgreich in der Spieleentwicklung eingesetzt.
Gutes Architekturpattern um mit sehr dynamischen Anforderungen umzugehen.
Für bestehende Systeme lohnt sich der Umbau oft nicht, bei Neuentwicklungen sollte man aber darüber nachdenken :)