So implementieren Sie ein komponentenbasiertes System für Elemente in einem Webspiel


7

Lesen mehrerer anderer Fragen und Antworten zur Verwendung eines komponentenbasierten Systems zum Definieren von Elementen Ich möchte eines für die Elemente und Zaubersprüche in einem in PHP geschriebenen Webspiel verwenden. Ich bin nur bei der Implementierung festgefahren.

Ich werde ein in dieser Reihe vorgeschlagenes DB-Schema verwenden (Teil 5 beschreibt das Schema).
http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/

Dies bedeutet, dass ich eine Elementtabelle mit allgemeinen Elementeigenschaften habe, eine Tabelle, in der alle Komponenten für ein Element aufgelistet sind, und schließlich Datensätze in jeder Komponententabelle, aus der das Element besteht.

Angenommen, ich kann die ersten beiden zusammen in einer einzigen Abfrage auswählen, werde ich dennoch N Abfragen für jeden Komponententyp durchführen. Ich bin damit einverstanden, weil ich die Daten in Memcache zwischenspeichern und dort zuerst überprüfen kann, bevor ich irgendwelche Abfragen mache. Ich muss die Elemente bei jeder Anforderung aufbauen, in der sie verwendet werden, damit die Implementierung schlank sein muss, auch wenn sie aus dem Memcache abgerufen werden.

Aber genau dort bin ich zuversichtlich, ein Komponentensystem für meine Artikel zu implementieren. Ich denke, ich müsste Attribute und Verhaltensweisen von jeder verwendeten Komponente in den Container bringen. Ich bin mir einfach nicht sicher, wie ich das effektiv machen soll, und schreibe nicht viel spezialisierten Code, um mit jeder Komponente umzugehen.

Beispielsweise muss eine AttackComponent möglicherweise wissen, wie Ziele innerhalb eines Kampfkontexts gefiltert werden, und möglicherweise auch ein Angriffsverhalten bereitstellen. Derselbe Gegenstand kann auch eine UsableComponent haben, die es ermöglicht, den Gegenstand zu verwenden und einen Effekt auf eine andere Gruppe von Zielen anzuwenden, die unterschiedlich aus demselben Kampfkontext gefiltert wurden. Dann ist nicht jeder Teil eines Elements ein aktiver Teil. Eine AttributeBonusComponent muss möglicherweise nur aktiviert werden, wenn sich das Element in einem ausgerüsteten Zustand befindet oder wenn die Seite mit den Artikeldetails angezeigt wird.

Wie soll ich letztendlich alle Komponenten zusammen in den Container bringen, damit ich die richtige Liste der Ziele erhalte, wenn ich einen Gegenstand als Waffe verwende? Wissen Sie, wann eine Waffe auch als Gegenstand verwendet werden kann? Oder um die Boni, die der Gegenstand bietet, auf ein Charakterobjekt anzuwenden?

Ich habe das Gefühl, dass ich zu weit in das Kaninchenloch gegangen bin und die einfache Lösung vor mir nicht erfassen kann. (Wenn das überhaupt Sinn macht.)

Wenn ich von hier aus die beste Antwort umsetzen würde, hätte ich das Gefühl, viele der gleichen Fragen zu haben.
Modellieren mehrerer "Verwendungen" (z. B. Waffe) für verwendbares Inventar / Objekt / Gegenstände (z. B. Katana) in einer relationalen Datenbank

Antworten:


4

Es sieht so aus, als würden Sie relationale Modellierung verwenden. Es gibt eine alternative Methode: die Modellierung von Eigenschaften / Prototypen, mit der Steve Yegge sein "ultimativ erweiterbares" MMORPG Wyvern erstellt hat . Grundsätzlich wird jedes Spielobjekt als einzelner Blob gespeichert (nur eine Abfrage pro Objekt), der nach dem Abrufen in eine Eigenschaftsliste analysiert wird. Die Flexibilität von Eigenschaftslisten ermöglicht es verschiedenen Spielobjekten, je nach Bedarf unterschiedliche Eigenschaften zu haben.

Das Universal Design Pattern von Yegge befasst sich eingehend mit der Modellierung von Eigenschaften / Prototypen. Steves Blog-Beiträge sind in der Regel ziemlich lang, daher werde ich versuchen, Sie auf die relevanten Abschnitte zu verweisen und die für Ihre Frage relevanten Punkte zusammenzufassen:

  1. Wyvern verwendet eine Implementierung des Eigenschaftenmusters. Ein Spielobjekt ist im Grunde eine Tasche mit beliebigen Eigenschaften. Jedes Objekt kann als Prototyp für jedes andere Objekt dienen, was zu einer erstaunlichen Flexibilität ohne Ende führt.
  2. Persistierende Eigenschaftslisten. Es gibt verschiedene Methoden zum Serialisieren und Speichern von Eigenschaftslisten. Wyvern verwendet eine Datenbank, "die die XML-serialisierte Eigenschaftsliste in eine Text- / Clob-Spalte verschiebt und die zwanzig oder dreißig Felder, die für Abfragen in ihren eigenen Spalten benötigt werden, denormalisiert."
  3. Der Datenspeicher von Eigenschaftslisten benötigt jetzt eine Methode zum Abfragen. Steve macht mehrere Vorschläge. Einfache textbasierte Abfragen funktionieren für hierarchische Daten nicht gut. XML-Datenbanken oder JavaScript / JSON + jQuery könnten Antworten auf dieses Problem sein.

1
Ich hörte fast auf zu lesen, als Sie einen Blob vorschlugen und dachten, Ihre Antwort würde MongoDB oder eine andere NoSQL-Lösung vorschlagen. Stattdessen bietet es eine andere Richtung als Komponenten. Sicher, dieser Ansatz könnte in NoSQL besser funktionieren, aber hier gibt es viel mehr als nur die Antwort "NoSQL verwenden".
Landstander

4

Ich würde ein Hook-System (einen Mechanismus, mit dem Rückrufe zu spezifizierbaren Funktionen zu einem Objekt hinzugefügt und daraus entfernt werden können, wenn Ereignisse auftreten) auf dem Container implementieren und Komponenten die entsprechenden Hooks einrichten lassen, wenn sie hinzugefügt werden, und sie abbauen, wenn sie entfernt werden. Zum Beispiel könnte die AttributeBonusComponent verwenden atEquipund atUnequipHaken , um seine Bonus hinzuzufügen und zu entfernen, könnte die AttackComponent Werte schaffen pollForTargetsund pollForAttackBehaviorsHaken, und die UsableComponent sprechen kann pollForUseBehaviors.

Der Container hat also nur ein abstraktes Verständnis der Arten von Informationen, die von ihm angefordert werden können, und der Art und Weise, wie mit ihnen interagiert werden kann, und die Komponenten sind dafür verantwortlich, zu definieren, wie sie mit diesen interagieren.


2

Es hört sich so an, als würden Sie den Sinn eines solchen Entitätssystems verfehlen. Wenn Sie "jedes Mal alle Komponenten laden", profitieren Sie fast nicht davon.

Sie sollten es so einrichten, dass alle Daten, die für eine bestimmte Operationsklasse benötigt werden (z. B. zum "Auflösen von Angriffen"), in einer einzigen Komponente zusammengefasst sind.

Stellen Sie sich im Wesentlichen vor, Sie müssen den Hauptcode für einen Teil Ihres Spiels schreiben, einschließlich der wichtigsten Sonderfälle, und Sie möchten angeben, welche Daten vom Anfang dieses Codes bis zum Ende benötigt werden. Das ist eine Komponente (Sie können sie in kleinere Komponenten aufteilen, aber nur, wenn Sie dies benötigen, da einige Teile später von anderem Code (wieder) verwendet werden).

Wenn Sie dann Sonderfälle haben, haben Sie die Wahl, Ihre Hauptkomponente zu bearbeiten (im Allgemeinen: nicht) oder zusätzliche Komponenten zu erfinden, mit denen alle vorhandenen Entitäten und der gesamte vorhandene Code unverändert weiterarbeiten können.


Ich gebe nicht vor, das Komponentensystem zu verstehen. Ein Teil meiner Verwirrung besteht darin, es in einer zustandslosen Umgebung zu verwenden, und ich denke / baue immer noch die Verbindung zwischen den in Artikeln oft erwähnten Physik-, Render- und Eingabekomponenten in Teile eines Frameworks oder Skripts auf.
Landstander

1

Beachten Sie die Regeln für die Optimierung !

  1. Tu es nicht.
  2. Noch nicht (nur für Experten).

Beispielsweise muss eine AttackComponent möglicherweise wissen, wie Ziele innerhalb eines Kampfkontexts gefiltert werden, und möglicherweise auch ein Angriffsverhalten bereitstellen. Derselbe Gegenstand kann auch eine UsableComponent haben, die es ermöglicht, den Gegenstand zu verwenden und einen Effekt auf eine andere Gruppe von Zielen anzuwenden, die unterschiedlich aus demselben Kampfkontext gefiltert wurden. Dann ist nicht jeder Teil eines Elements ein aktiver Teil. Eine AttributeBonusComponent muss möglicherweise nur aktiviert werden, wenn sich das Element in einem ausgerüsteten Zustand befindet oder wenn die Seite mit den Artikeldetails angezeigt wird.

Ist es wirklich ein Problem, wenn Sie alle Komponenten (AttackComponent, UsableComponent, AttributeBonusComponent) laden, auch wenn alle bis auf eine nicht verwendet werden?


Ich hätte klarer sein sollen. Ich beabsichtige, alle Komponenten jedes Mal zu laden, wenn ich den Artikel benötige. Die Attributmodifikatoren sind keine aktiven Teile wie das Zurückgeben einer Liste von Zielen durch den Gegenstand, wenn bestimmte Daten angegeben werden, sondern wenden nur einige Zahlen an, wenn der Gegenstand ausgerüstet ist. Natürlich könnte ich auch daran denken, dass alles falsch ist.
Landstander

1

"Ich habe das Gefühl, ich bin zu weit in das Kaninchenloch gegangen."

Ja genau. Komponentenbasierte Systeme befinden sich noch in der Modeerscheinungsphase, in der keine Einigung darüber besteht, wie sie am besten verwendet werden können. Mehrere sachkundige und kompetente Personen haben Artikel veröffentlicht, in denen ihre Verwendung vorgeschlagen wird, aber jeder ist sich nicht einig darüber, wie Sie sie zusammenbauen, wie sie kommunizieren und so weiter.

Meine persönliche Meinung ist, dass das relationale Modell, mit dem Sie verknüpft sind, für den täglichen Gebrauch viel zu abstrakt ist.

Stattdessen würde ich mir Ihr eigenes Design genauer ansehen und herausfinden, welche gemeinsamen Aspekte der Funktionalität herausgerechnet werden können, um austauschbare Komponenten zu bilden. Das wird wahrscheinlich viel fruchtbarer sein, als zu versuchen, Ihr Spiel in eine vorgefasste Vorstellung davon zu bringen, welche Komponenten sein sollten.


Ich würde zustimmen, dass es an Übereinstimmung mangelt, welcher Implementierungsstil vorteilhafter ist als der nächste, aber angesichts der Anzahl sehr erfolgreicher Motoren, die Komponentensysteme verwenden, würde ich es kaum als "Modeerscheinung" bezeichnen.
Kynth

Es gibt wirklich nicht so viele Motoren, die solche Systeme verwenden, sicherlich nicht genug, um die Anzahl der Leute zu rechtfertigen, die daran interessiert sind, sie herzustellen. (Das einzige, an das ich momentan denken kann, ist Unity.) Dies ist überhaupt keine Kritik an dem Ansatz, sondern nur eine Reflexion über das derzeit unverhältnismäßige Interesse an diesem Thema im Verhältnis zur Menge der funktionierenden Software, die es tatsächlich verwendet.
Kylotan

0

Soweit ich die referenzierte Artikelserie zu Entity Systems verstehe, ist Ihr "Artikel" mit Komponenten geladen. Und eine Komponente ist eine Liste von Referenzen. Folgen Sie Ihrem Beispiel: AttackComponent enthält Verweise darauf, wie der "Gegenstand" angreift. Die AttackTargetComponent enthält Verweise auf Mechanismen zum Abrufen einer Liste von Zielen. und so weiter. Wenn Ihr "Gegenstand" ein oder mehrere Ziele angreift, verwendet er die AttackComponent und die AttackTargetComponent oder löst eine externe Methode aus, die auf dem Gegenstand (und seinen Komponenten) basiert. Vielen Dank, dass Sie diese Artikel geteilt haben.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.