Warum sollte die Entitätskonfiguration außerhalb von Skripten platziert werden?

11

Ich habe viele Spiele gesehen, die die Entitätskomponenten in Skriptdateien definieren, aber wenn sie jede Entität konfigurieren und angeben, welche Komponenten sie enthält, verwenden sie ein anderes Dateiformat (wie XML). Warum machen sie das?

Ich frage hauptsächlich, was die Gründe anderer dafür waren. Ich auch so konfigurieren , meine Einheiten außerhalb von Skripten (obwohl ich wählte JSON nicht XML). Meine Gründe dafür sind, mir die Implementierung von Speicherspielen zu erleichtern und auch, weil ich denke, dass diese Art der Konfiguration besser in XML oder JSON organisiert ist.


@ Christopher Larsens Antwort: Zu lange, um als Kommentar zu posten

Ich fürchte, Sie sind vielleicht ein bisschen vom Thema der Frage abgewichen. Die Probleme, die Sie beschreiben, beziehen sich eher auf hierarchiebasierte Entitäten. Beachten Sie in meiner Frage, dass ich über komponentenbasierte Entitäten gesprochen habe.

Hier ist ein Beispiel dafür, was ich fragen wollte. Im Folgenden finden Sie zwei alternative Möglichkeiten zum Konfigurieren einer Entität: über das Skript und über eine externe JSON-Datei. Meine Frage war, warum so viele Leute es vorziehen, die Entität außerhalb von Skripten zu konfigurieren.

Eine Basisentitätsklasse:

class Entity:
    def __init__(self, name):
        pass
    def addComponent(self, comp):
        pass

Der Skriptansatz:

orc = Entity('Orc')
orc.addComponent(PositionComponent(3.4, 7.9))

Der JSON-Ansatz:

{
    "name" : "Orc",
    "components":
    {
        "PositionComponent": {
            "x" : 3.4,
            "y" : 7.9
        }
    }
}

Ich habe bereits meine Gründe für die Verwendung dieses Ansatzes angegeben, die technisch und organisatorisch sind. Ich wollte wissen, warum so viele andere (nach dem, was ich gesehen habe) dies verwenden.

Paul Manta
quelle

Antworten:

13

Der Hauptvorteil, der mir in den Sinn kommt, ist, dass die Konfiguration von einem Nicht-Programmierer bearbeitet / verwaltet werden kann, ohne dass sie eines der Spielskripte berühren müssen.

Dave Sherohman
quelle
Dies kann erreicht werden, indem einfach zwei Dateien vorhanden sind (gleiche Rechte wie eine .h und dann eine .cpp). Ich frage mich, wer eine Person sein würde, die ein Objekt erstellen möchte (abgesehen davon, dass dieses Nichtstun wie eine Vase aussieht und dieses Nichtstun wie eine Butter aussieht), die auch keine Logik hinzufügen möchte (wie Wenn eine Person mit Pollen von den Blumen in der Vase bedeckt ist, ziehen Sie den Schmetterling an. Vom Menschen lesbar ist großartig und einer meiner Gedanken darüber, warum dies so ist, aber auch hier stelle ich fest, dass JSON, Lua-Tabellen und XML für Nicht-Programmierer alle ein ähnliches Maß an menschlicher Lesbarkeit aufweisen.
James
2
Glest ist ein mit XML modifiziertes Spiel. Viele Nicht-Programmierer machen Mods dafür. Es ist definitiv zugänglicher, XML / JSON als Skript zu haben.
Will
6

Ein Grund, warum ich normalerweise eine Konfigurationsdatei anstelle eines Skripts verwende, ist:

Die einzige Möglichkeit, ein Skript auf Richtigkeit zu überprüfen, z. B. alle Werte anzugeben, besteht darin, es auszuführen.

Das Schreiben von Code, damit Skripte die Werte konfigurieren können, bedeutet das Schreiben von Code zum Erstellen von Skelettobjekten für die Skripte, um die Werte auszufüllen, und das Überprüfen, ob das Skript dies und dergleichen getan hat. Es ist mehr Code und fehlerhafterer Code als das Laden aus einer flachen Konfigurationsdatei, häufig unter Verwendung einer Bibliothek, die eine Art Validierungsmechanismus unterstützt.

Wille
quelle
5
Damals, als die Mainstream-Softwareentwicklung besser war, war dies als das Prinzip der geringsten Leistung bekannt : Heutzutage müssen wir die Gründe verstehen, warum wir nicht die leistungsstärkste, sondern die am wenigsten leistungsstarke Lösung ausgewählt haben. Der Grund dafür ist, dass je weniger mächtig die Sprache ist, desto mehr können Sie mit den in dieser Sprache gespeicherten Daten tun.
1
@ Joe Das beschreibt eigentlich ziemlich gut einen der Gründe, warum ich diesen Ansatz auch benutze. Zuerst habe ich versucht, meine Entitäten in Skripten zu konfigurieren, aber es fiel mir schwer, Speicherspiele zu implementieren (ich konnte die Beziehungen zwischen Komponenten nicht verfolgen). Die Verwendung einer externen Konfigurationsdatei hilft mir sehr.
Paul Manta
Ich sehe dies tatsächlich als umgekehrt. Wenn Sie bereits eine Skriptschnittstelle verwenden, müssen Sie jetzt auch eine Datenüberprüfungsmethode für die Konfigurationsdatei bereitstellen, anstatt die bereits definierte Skriptschnittstelle zu verwenden, um dies für Sie zu tun.
James
2

Die Entitätskonfiguration kann einfach eine Serialisierung einer bestimmten Entität sein. Auf diese Weise können Sie die Ausgabe der Spielbearbeitungs- und Modding-Tools ungefähr so ​​behandeln wie bei einem gespeicherten Spiel. Insbesondere für Spiele, bei denen Sie nicht vorhersagen können, in welchem ​​Zustand sich eine bestimmte Entität während des Spielspeichers befindet - beispielsweise aufgrund ihrer KI oder weil sie teilweise prozedural generiert werden - ist es nützlich, das Ganze ausgeben zu können Daten, die definieren, was eine Entität "ist" (im Gegensatz zu dem, was sie "tut"), als zu speichernder Bytestream.

Martin Sojka
quelle
1

Das von Ihnen beschriebene Muster ist eine Implementierung eines datengesteuerten Systems.

Datengesteuerte Systeme werden häufig in der Spieleentwicklung verwendet, da sie die Kapselung von Inhalten außerhalb der Quelle ermöglichen. Diese externe Darstellung kann dann einfach geändert (und sogar in Echtzeit von einer Anwendung aktualisiert werden, die auf Änderungen wartet), um das Verhalten einer Entität zu ändern.

Sobald die Daten extern definiert sind, haben Sie alle möglichen Möglichkeiten, wie die Designer mit ihnen interagieren, von der direkten Bearbeitung von Textdateien (ugh!) Bis hin zu hoch entwickelten Benutzeroberflächen, die die Auswahl des Designers in einer logischen, konsistenten und sogar auf Richtigkeit überprüften Form (von) leiten die Perspektive der Spielbalance) Weise.

Wenn die Daten direkt in den Code eingebettet wären, würden Änderungen eine Neuerstellung der Anwendung erfordern, die für große Projekte mäßig zeitaufwändig ist, sowie die Zeit, die für die Bereitstellung der Binärdateien erforderlich ist (z. B. müssen neue Binärdateien auf dem bereitgestellt und auf dem installiert werden Server).

Nehmen wir ein Beispiel für eine sterotypische Entität, den "Ork" ...

Eine Möglichkeit zur Implementierung für unseren Ork besteht darin, eine vollständige Beschreibung aller Eigenschaften und der Logik für den Ork in den Code zu schreiben.

  • maxhealth = 10
  • Schaden = 3 Schaden pro Sekunde
  • Ausreißer = wahr
  • außer Kontrolle geraten, wenn = Gesundheit <10
  • aggressiv = wahr

Wenn wir Orks instanziieren, werden alle ihre Werte genau gleich initialisiert (oder sind möglicherweise statisch). Das Problem ist, dass einige Designer mitkommen und sagen werden: "Wir brauchen eine andere Art von Ork für Neulinge, die weniger Gesundheit haben, niemals weglaufen und nicht aggressiv sind. Dadurch können sich neue Spieler daran gewöhnen, ohne die zu kämpfen." erhöhte Schwierigkeit und Verwirrung beim Erlernen des Kampfsystems ".

Großartig, jetzt brauchen Sie eine andere Klasse oder (vielleicht waren wir vorausschauend) passen Sie die Werte an, die wir in die "Fabrik" einspeisen, die Orks erstellt, wenn Sie sie in einem "Neuling" -Bereich erstellen. Also nehmen wir die Änderungen vor und stellen neue Binärdateien bereit. Nur damit Spieletester zurückkommen und sagen, dass die neuen Gesundheitswerte zu niedrig sind, wenn wir die Orks mit einem Schlag töten.

Wenn unsere Systeme datengesteuert waren (und Bonuspunkte für Anwendungen, die das Neuladen unterstützen, wenn Änderungen vorgenommen werden), sind die Änderungen, die erforderlich sind, um den Designer und die Spieletester zufrieden zu stellen, einfache Datenänderungen, ohne dass eine Neukompilierung / Bereitstellung erforderlich ist. Dies macht Designer glücklich, weil sie nicht auf Codeänderungen warten müssen, und es macht Programmierer glücklich, weil wir den Quellcode ständig ändern, um Werte zu optimieren.

Wenn Sie datengesteuerte Systeme auf die Spitze treiben, können Sie alles von Spielstufen, Zaubersprüchen und sogar Quests durch einfache Änderungen an Ihren Daten implementieren, ohne dass Codeänderungen erforderlich sind. Am Ende geht es darum, das Erstellen, Optimieren und Iterieren des Spielinhalts zu vereinfachen.

Christopher Larsen
quelle
2
Skripte sind auch Daten nach den meisten Definitionen
Will
1
-1. Die Frage bezieht sich nicht auf datengesteuertes vs. Hardcodieren, sondern auf dynamisches Scripting vs. statisches Deklarieren.
@ Christopher Ich habe eine lange Antwort in mein OP eingefügt. Bitte probieren Sie es aus.
Paul Manta
0

In Ihrem Beispiel verwenden Sie bereits zwei Skriptsprachen. Dies ist die Art und Weise, wie ich sagen würde, dass sie auf lange Sicht besser funktioniert, aber ich würde vorschlagen, dass Sie die von Ihnen verwendete Skriptsprache vereinheitlichen. Wenn das von Ihnen angegebene Skriptbeispiel in Lua erstellt wurde, würde ich anstelle von Json sagen, dass Sie Luas Tabellen verwenden, um Ihr Objekt aufzubauen. Die Syntax wäre tatsächlich ähnlich und ermöglicht es Ihnen, eine Schnittstelle zum Offenlegen Ihrer Komponenten zu unterstützen.

Zu sagen, warum die Leute es normalerweise in XML und dann in Logik schreiben, ist sinnvoll, wenn Sie es sagen. Hier ist meine Definition des Objekts in Daten. Was ist ein gutes Datenspeicherformat? Es ist fast immer XML (obwohl ich auch mit JSON gehe;). Und wenn sie dann Logik hinzufügen möchten, wird dies entweder codiert oder in eine Skriptdatei eingefügt.

Es ist kein falsches Denken, aber in meinen Augen gehen die Leute einfach nicht zum nächsten Schritt. Schauen Sie sich eine vollständige Sprache an, c / c ++ / c #. Sie können die Objekte und ihre Logik in einer Sprache definieren. Warum nicht dasselbe in Ihrer Skriptoberfläche tun? Es ist fast so, als würden wir unsere Klassen in XML und unsere Methoden in c # definieren, wenn Sie darüber nachdenken. Vielleicht waren ältere Spieleskriptsprachen nicht leistungsfähig genug und es bleibt immer noch so, wie es gemacht wurde.

James
quelle