-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Änderung des Komponentensystems: Einführung von Interfaces #252
Comments
Es steht eigentlich soweit hier Im Grunde werden den Entitäten durch Interfaces Eigenschaften gegeben so dass sie gefiltert und über die Komponenten der Entitäten berechnet werden bzw. gezeichnet oder mit dem Player interagieren können. Dadurch könnten unter anderem die Simulationskomponenten wegfallen. Abhängig von der letztendlichen Umsetzung des Multiplayers könnte das auch für Remotekontroller hergenommen werden. |
Wir hatten uns eigentlich, als wir die Komponenten eingeführt haben, bewusst gegen interfaces entschieden. Und damit gegen ein system wie z.b. bei Unity. Interfaces haben den entscheidenden Nachteil das sie nicht Dynamisch verwendet werden können. Wie hast du dir das mit Mod's gedacht ? Beispiel ein Mod fügt die Eigentschaft "blau" hinzu. Wie bekommst du das Interface in den Player, was ist deine idee dazu? Und was ist wenn morgen ich den mod nicht mehr will was passiert dann mit der Eigenschaft? Außerdem wird bei Interfaces immer die Funktionalitäten aus Reflections benötigt wohingegen Objekte auf herkömmliche Weise durchsucht werden können. |
Geanu das ist das Problem. Mit Interfaces können Extensions nur eigene Entities erstellen und erweitern, aber nur "Eigenschaften" aus anderen Extensions konsumieren. Bereits bestehenden Entities aus anderen Erweiterungen können nachträglich nicht mehr erweitert werden (da die implemntierten Interfaces zur Compilezeit bekannt sein müssen. Diese Beschränkung besteht bei dem derzeit verwendeten System aus Komponenten und EntityExtendern nicht, dieses ist damit flexibler. Was stört dich denn geanu am bisherigen System, was bei deinem Interface-System besser ist, @HierGibtEsDrachen? |
Versteh ich jetzt nicht ganz ?? Die Interfaces sollen Basisfunktionalitäten bereitstellen und Eigenschaften vermitteln die eine Vereinheitlichung ermöglichen. Bildlich ausgedrückt: Client und Entitäten sollen wie Zahnräder ineinander greifen. An dieser Stelle muss aber noch gesagt werden das Beliebige Erweiterungen von fremden Entitäten nur bedingt wünschenswert sind, wenn Wauzi anfängt mit mir zu Handeln suche ich die nächste Telefonzelle^^ Hier muss noch geklärt werden wie die Komponenten selbst organisiert werden. Ein Modder will eventuell sein eigenes Inventar für den Spieler implementieren mit eigener UI weil im der Standart nicht gefällt. Das würde ich dann auch über Interfaces oder Basisklassen machen. Allein schon weil der IGameService die Kenntnisse benötigt, wenn er Methoden bereitstellen will wie z.B. TakeBlock oder ähnliches. Entitäten können: Die Interaktion Das Rendern Die Bewegung (Kontrollierbarkeit) |
solche Dinge würde ich trotzdem ungern mit Interfaces verallgemeinern, sondern auch mit entsprechenden Flags oder gar FlagComponenten, denn mit Interfaces verbaut man sich die Inlinebarkeit noch schlimmer als bei C++(welches immerhin zur Compilezeit evtl. erkennt ob es immer dasselbe Objekt ist und dann inlinen kann), C# inlined Dinge aus einem Interface Grundsätzlich gar nicht. |
Also, hier muss ich julian wieder recht geben, zum einen was Julian sagt zum anderen Das Komponentensystem bedarf ein Redesign bzw. ein neues Konzept überarbeitung. Und Interfaces will man ja nicht Pauschal verbieten aber ich weis nicht ob wir hier nicht gerade aneinander vorbeireden. Der Vorteil an den Komponenten ist aktuell die einfachheit und Flexibilität. Ich mache dir einfach mal ein Beispiel: Wir haben 3 Mods Bei einem Komponenten System wie es aktuell ansätze hatt würde jeder Mod einfach eine Komponente zu einer grund Entität hinzufügen. Bei einem Update kann man einfach einmal überalle Komponenten gehen. Bzw. klassische vergleichsoperationen verwenden um eine bestimmte Komponente zu suchen. Möchte ich einen Mod nicht mehr in dem Fall B dann wird die Komponente einfach nicht mehr hinzugefügt die Sache ist durch. Weiterer Vorteil, wir können z.b. Komponenten nach reihenfolge sortieren vor der Ausführung so das eine Herachie entsteht. Und wie julian als Idee einbrachte liese sich jede komponente mit einer uniqe ID versehen auf die z.b. referenziert werden könnte in dem man in einem Objekt nur die ID hält. Im falle von Interfaces sehen die oben genannten Funktionalitäten schwieriger aus, ich sage nicht unmöglich. Sicher bequemer zu Programmieren sind Interfaces, flexiebler aber Komponenten. |
Ahja meine mal gelesen zu haben das Aufrufe durch Interfaces immer (oder meistens) langsamer sind als virtual Calls. Ansonsten gebe ich dir vollkommen Recht mit deiner Aussage. Dein Beispiel steht mit dem was ich machen will nicht in Konflikt. :) Dein Beispiel ist nach meiner Meinung eine legetime Verwendung weil es tatsächlich eine Erweiterung ist, dennoch bin ich der Meinung das zu hohe Granularität (siehe ButtComponent) nicht immer hilfreich ist! Und damit alles nicht von jedem Modder 1000000 mal selber geschrieben werden muss kommen noch die IGameService´s hinzu die Standartimplementierungen anbieten etc... Ich will die Komponenten nicht abschaffen, Ich will es verbessern :P Bei meinem dritten PR gab es die Komponenten ja auch noch, halt nur anders :) |
das wollen wir aber und virtual calls sind auch langsam können auch nicht inlined werden, das ist genau dasselbe. Deshalb weg von dem StandardOOP zeugs verändern würde ich das ganze System später sowieso, Was deine IGameService anbelangt kann ich noch nicht viel sagen ist noch in zu kleinem Rahmen, aber dagegen wehr ich mich erstmal nicht. Ansonsten glaub ich fast, dass die meisten immer noch nicht ganz verstehen(mich eingeschlossen) wo du denn jetzt überall deine Interfaces einbringen willst. Deshalb wäre mal ne mündliche Erklärung mit Bild(TeamViewer+TeamSpeak) denke ich mal ziemlich sinnvoll |
der satz mit den 4 fragezeichen in meinem vorherigen beitrag sollte das glaub ich klar machen :) |
Die Mods müssen sich in diesem Fall sowieso gegenseitig referenzieren. Sonst müsste in der OctoAwesonme.dll ein Interface für jedes erdenkliche Werkzeug befinden. Dann kommt ein Modder und will einen SuperDuperSpaceBagger2000 integrieren und es gibt keine Interface dafür, nach dem andere Mods filtern können. Abhängigkeiten sind ja geplant (#207) Mod A: Klasse Schwert, implementiert IEntity und wird dem Spiel registriert. Registriert auch noch gleich eine Geht also auch mit Komponenten. Natürlich haben die Komponenten auch Basisklassen bzw. Interfaces, die der Client kennen muss (sonst geht echts nichts). |
aber eine Component kann auch von Mod XYZ kommen und von Mod B hinzugefügt werden um dann von Mod C manipuliert/verwendet zu werden, ohne dass Mod C etwas von Mod B weiß, also nicht unbedingt eine Referenz. |
@ManuelHu genau davon rede ich (hab nie gesagt ich will eure Komponenten Entfernern siehe weiter oben fett gedruckt :P) Ich kann einfach nicht verstehen wie die Aussage:
so falsch verstanden werden kann :(
Und die Finale Frage: Und das Referenzieren von Mods muss NICHT implementiert werden die Reference im Projekt schafft der Modder auch alleine. code zur laufzeit generieren und compilieren ? habe ich keine erfahrung mit aber noch generischer geht es glaub ich wirklich nicht mehr. vllt. mit einer AI die den Code für einen schreibt ^^ |
Also um genauzu sein hätte ich gerne etwas, was viel mehr eine Code Injection macht vmtl. mittels Mono.Cecil, wodurch wir dann eben verhindern können dass er über den interface weg gehen muss und somit dafür sorgen, dass das ganze mit bestmöglicher Performance funktioniert. Basisfunktionalität, was braucht eine Komponente für eine Funktionalität, die für alle gilt, oder eine Entität? Und das Filtern geht eben nicht nach Interfaces, sondern nach Komponenten. Du suchst nach Komponenten nicht die eine Entität hat oder eben auch nicht und nicht nach Interfaces? |
Woher weiß der Client den das Komponente xyz eine RenderKomponenten ist. Und wenn es halt keine gibt oder die Entity das Interface nicht implementiert (kann auch bei der Entity direkt implementiert werden braucht man keine Komponenten fürs Rendern, höchstens als Statespace) dann wird sie halt nicht gerendert.
(oder so kann das zeug nicht auswendig :P)
Und wenn ihr das so nicht haben wollt, dann sagt einfach die Idee ist Mist und damit hat es sich :P Gegen deinen Vorschlag hab ich nichts einzuwenden aber dann könnte auch hergegangen werden und die Simulation dynamisch bevor der Server startet zugeschnitten und optimiert aus den Extensions (die für den Server gelten und für den Server vorhanden sein müssen und zwar bis ein Admin das gegenteil sagt und den Server neu startet) generiert werden. Es werden quasi Entity Klassen gebaut die alle Methoden und Properties der Componenten inne haben. Eine Anpassung der Populator usw. ist dann eben auch erforderlich. Dann schiebt der Server anstelle von X Assemblies eine Assembly über die Leitung zum Client. |
Beim starten werden erstmal aus allen Assemblies alle Komponententypen zusammengesucht, das kann entweder über ein Attribut passieren oder von mir aus auch über ein leeres IComponent interface(das nur zum erkennen der Komponenten ist)... Wenn man dann alle hat, dann sortiert man diese anhand einer GUID z.b. sodass bei Server und Client diesselben IDs herauskommen(Client-Only-Components werden ganz ans ende sortiert). Jede Entity bekommt dann ein Array
wenn ne Component null ist, dann ist die natürlich einfach nicht teil dieser Entität. Man hat zwar etwas speicher overhead, aber das ist nicht allzu viel, jede Component ist einfach nur ne Referenz. Perf ist da wichtiger... Wer Rendern will muss auf eine Assembly verweisen die Rendern kann, und diese hat dann eine RenderComponent, davon kann es dann natürlich entsprechend unterschiedliche Komponenten für unterschiedliche Render arten geben... Wichtig ist dabei die Components kommen aus einem Pool, und dabei gäbe es zwei Ideen: |
Klar, das stimmt schon. Wenn aber die referenzierte Assembly fehlt gibts ne Exception zur Laufzweit, wenn zum ersten Mal ein Typ daraus verwendet wird. Wenn man zusätzlich deklariert (z.B. via Attribute an der Extension-Klasse), was für Extensions referenziert werden, kann man solche Extensions gleich beim Laden ausschließen. |
Ich persönlich könnte mir auch noch Vorstellen einfach gewisse dinge den Komponenten selbst zu überlassen. So dass einfach bei einem Update jede komponente zyklisch aufgerufen wird. Für den Build prozess den jubsel vorschlägt muss man aber nicht auf Interfaces setzen da wären Attributes eigentlich bequemer von der Programmierung her. Bei der Variante die mir im Kopfschwebte wäre die Mod referenzierung auch weich gewesen. @jvbsl hast du so ein Komponentensystem schon mal ausprobiert? |
@ManuelHu sorry wenns ein bisschen hart war. |
Ich habs noch nicht umgesetzt, aber die Grundidee ist von sebastian gestohlen mit nen paar Änderungen eben dann. Und bei Sebastian hats ziemlich gut funktioniert... Großartig umdenken muss man eigentlich denke nicht, oder überseh ich da etwas? |
warum du das wollte ja ich machen ^^ hätte noch eine frage: ist zwar offtopic aber hier geht es ja auch darum etwas zu lernen :) |
bevor ich es vergessen, hier noch ein kleiner nachtrag @ManuelHu |
Ja ja klar, die gibts. Aber da eine Assembly theoretisch mehrere Extension-Klassen beinhalten kann und diese einzeln aktiviert/daktiviert werden können, kann es auch zu SItuationen kommen, dass eine Extension die Funktionalität einer anderen Extensions braucht, deren Assembly zwar existiert und geladen ist, aber die selbst nicht instanziert ist. |
Wie in PR #249 bereits erwähnt hatt @HierGibtEsDrachen vorgeschlagen das Komponentensystem zu ändern und Interfaces anstelle des bisherigen system zu verwenden.
Am besten erläutert er das mal selber. Ich denke wir können durchaus dieses Thema mal besprechen.
The text was updated successfully, but these errors were encountered: