Wie funktionieren Dialogbäume?

20

Das heißt, was hängt mit was zusammen und wie bewegt man sich zwischen den Sprachzeilen, wenn eine Nebenkonversation endet?

Wenn Sie Beispiele für einen grundlegenden Dialogfeldbaum in C # haben, stellen Sie diese bitte bereit.

user1306322
quelle
Ich denke, es wäre toll, ein dialog-treeEtikett zu haben .
user1306322
Nach Codebeispielen zu fragen, wird normalerweise nicht gut aufgenommen.
MichaelHouse
Wenn es einige Codebeispiele für den Dialogbaum 101 gibt, die es wert sind, geteilt zu werden, kann dies nicht schaden.
user1306322
Das Problem ist, dass es auf dieser Site darum geht, korrekte Antworten auf Fragen zu erhalten. Es ist nicht zum Sammeln von Codebeispielen gedacht.
MichaelHouse
Deshalb beginnt der Satz mit "wenn". Was ich aber verlange, ist die Erklärung, wie Dialogzeilen auf eine Weise miteinander verbunden werden, die effizient in Code übersetzt werden kann. Immerhin werde ich es in C # schreiben.
user1306322

Antworten:

24

Der Name "Dialogbaum" ist etwas irreführend - es handelt sich normalerweise um einfach gerichtete Grafiken , nicht nur um Bäume . Die grundlegende Datenstruktur solcher Graphen besteht normalerweise aus einer Art "Daten" für die Knoten, die die Punkte darstellen, an denen wir uns in der Konversation befinden, und Verknüpfungen von diesen zu anderen Knoten, die darstellen, was von den Teilnehmern gesagt und getan wird und optional Bedingungen, um die Sichtbarkeit zu beschränken, oder Skripts, um verschiedene zusätzliche Aktionen auszuführen. In der Regel ist einer der Knoten der Standardstartknoten (typische Bezeichnungen hierfür sind "ROOT", "START" und "GREETING"), und Knoten, von denen keine gültigen Links ausgehen, beenden die Konversation.

In den meisten Fällen wird der Graph im Speicher als eine Liste von NodeDatenstrukturen dargestellt, die jeweils mindestens eine ID und eine Liste von 0 ... n LinkDatenstrukturen aufweisen. Die Liste kann lokal für den NPC oder global sein. Der zweite Fall ist vorzuziehen, wenn Sie viele allgemeine NPCs haben, mit denen Sie zur Information sprechen können, die jedoch selbst keine spezifischen Konversationen anbieten. Das System selbst findet den Start-Konversationsknoten für den NPC, merkt sich seine ID als aktuelle Konversations-ID, zeigt die aktuell gültigen Links an, aus denen der Spieler auswählen kann (oder "[Konversation beenden]", wenn keine gültigen Links vorhanden sind) und wartet Eingang. Wenn der Player einen Link auswählt, werden die zugehörigen Dialogzeilen angezeigt und alle zugehörigen Skripts ausgeführt.

Anstatt komplexe Regeln und Bedingungen für Links zu haben, können Sie stattdessen eine einfache "gültige" boolesche Variable verwenden, die entweder über die Skripte anderer Konversationslinks (einschließlich des Standardknotens vom Startknoten) oder von außerhalb geändert werden kann Mechanismen. Im Allgemeinen ist dieser Ansatz einfacher, aber nur für Spiele mit sehr wenigen derartigen Gesprächen geeignet, da er die Logik von "Wann ist diese Reaktion möglich?" weg von den Antwortdaten selbst.


Beachten Sie, dass die hier beschriebene Struktur sich geringfügig von der von Byte56 unterscheidet, da die Knoten keine Dialogzeilen benötigen. Die Links können sie alle haben. In der grundlegendsten Variante ergibt dies die folgende Struktur.

Bildbeschreibung hier eingeben

Martin Sojka
quelle
+1 Um Regeln und Bedingungen auf Links zu erwähnen, reicht eine einfache gerichtete Grafik oft nicht aus, und die Dinge können kompliziert werden, wenn Sie anfangen, diese zu benötigen.
Laurent Couvidou
+1 Mir gefällt diese Struktur besser. Allerdings würde ich es nicht als ersten Durchgang empfehlen. Ich würde mit etwas Einfacherem beginnen. Es ist sicherlich ein besseres Ziel, um zu schießen.
MichaelHouse
+1 Für eine sehr detaillierte Antwort. Dies könnte sich später als nützlich für mich erweisen.
Marton
Dieses Bild hat mir sehr geholfen, aber ich muss mich fragen, warum DialogueLine vom Link getrennt ist. Hätte nicht jeder Link einen eigenen Antworttext? Und wohin würde der Text des NPC gehen? Wäre es nicht sinnvoll, es im Knoten zu haben?
Kyle Baran
@Danjen In dieser Struktur kann ein Link mehrere Dialogzeilen haben, möglicherweise mit unterschiedlichen Zeichen, bis die nächste Dialogauswahl angezeigt wird. Hier geht auch der NPC-Text hin. Wenn sich die Zeilen wiederholen, können verschiedene Verknüpfungen DialogueLines gemeinsam nutzen, möglicherweise in ihrer Liste (Vektor) neu anordnen, Teile durch andere Zeilen ersetzen, Interjektionen hinzufügen und so weiter.
Martin Sojka
16

Dialogbäume werden mit einer gerichteten Diagrammstruktur erstellt .

Bildbeschreibung hier eingeben

Der Graph wird basierend auf den Dialogentscheidungen des Spielers durchlaufen. Die dem Benutzer zur Verfügung gestellten Dialogoptionen stammen von den Kanten, die die Pfade zu anderen Dialogknoten definieren.

Gerichtete Graphen sind eine grundlegende Datenstruktur. Sie können leicht implementiert werden und Sie werden es wahrscheinlich selbst implementieren wollen. Da Sie das Diagramm an Ihre Dialoganforderungen anpassen möchten.

Einige der Knoten müssen möglicherweise spezielle Bedingungen erfüllen, um angezeigt zu werden. Zum Beispiel würde der Spieler eine Fertigkeit im Sprechen über X benötigen. Oder der Spieler muss Mission Z abgeschlossen haben, bevor er einen Zweig des Dialogs durchlaufen kann. Oder sie müssen 4 Mal etwas fragen, bevor der NPC es mit ihnen bespricht. Diese Funktionen sind an Ihr Spiel angepasst. Erwähnenswert bei der Implementierung der Knoten- und Kantenüberquerung. Natürlich ist es immer am besten, mit der einfachsten Form zu beginnen und von dort aus aufzubauen.

MichaelHouse
quelle
Ich kann einfach nicht herausfinden, was in Fällen wie "Newton-Ärger" in diesem Bild zu tun ist. Wie man die Reihenfolge dieser Zeilen im Code festlegt, ohne sie zu wiederholen.
user1306322
Sie werden oft feststellen , dass Dialog kann wiederholt werden. Es ist normalerweise nur auf irgendeine Weise markiert, damit der Benutzer weiß, dass er diesen Dialogpfad bereits gewählt hat. Sie können an Ihren Rändern eine Markierung anbringen, die angibt, ob sie zuvor ausgewählt wurden. Es liegt also an Ihnen, den Benutzern zu erlauben, es erneut auszuwählen (um sich selbst zu aktualisieren) oder es nicht anzuzeigen.
MichaelHouse
1
Normalerweise würde dies nicht mit der Bestellung von Codezeilen geschehen, sondern über die Referenzen in der Datenstruktur.
Kylotan
7

Ich habe ein einfaches Dialogbaum-System erstellt: http://iki.fi/sol/d3/ Die "Engine" selbst ist derzeit normal c, aber die vom Editor erzeugten Daten sind in jeder Sprache recht einfach zu verwenden. Das Tool gibt XML, JSON und ein benutzerdefiniertes Binärformat aus.

Das Hauptkonzept ist ziemlich einfach:

Sie befinden sich in einem Labyrinth von verwinkelten kleinen Passagen, die alle gleich sind

Jeder Knoten (den ich wie im obigen Beispiel "Karte" nenne) des Dialogs besteht aus Fragetext und null oder mehr Antworten. Jede der Antworten führt zu einer anderen Karte.

Es gibt auch ein Tag-System, bei dem dem Benutzer bestimmte Antworten nur angezeigt werden, wenn ein Tag festgelegt wurde (oder kein Tag festgelegt wurde). Durch das Eingeben einer Karte werden bestimmte Tags festgelegt (oder deaktiviert).

Das ist so ziemlich alles, was man für jeden Dialog in einem Spiel braucht. Der "Fragentext" kann reiner Text sein oder ein Skript, um die Animation zu steuern oder so weiter.

Jari Komppa
quelle
4

Sie können TreeSharp und Verhaltensbäume verwenden, um ein Dialogsystem zu modellieren. TreeSharp ist eine Bibliothek, die eine einfache Implementierung eines Verhaltensbaums bietet. IA Bots für Wow sind damit fertig, also ist es ausgereift ... :)

Meine Implementierung verfügt über Knoten, auf denen Sie zwischen Antworten wählen können. Jede Antwort kann mit einem Dialog oder einer Aktion oder einer Abfolge von Aktionen oder einem Knoten verbunden werden, auf dem Sie zu einem anderen Dialog wechseln können ... oder was Sie möchten ...

Ich habe Brainiac Editor verwendet, um es visuell zu machen ... aber am Ende erzeugt es C # -Code basierend auf Treesharp ...

http://www.youtube.com/watch?v=6uGg6bUYyUU

Blau
quelle
2

Sie möchten einen gerichteten (möglicherweise zyklischen) Graphen.

Sie modellieren die Knoten als Objekte, und alle ausgehenden Pfeile im Knoten eines Diagramms werden auch als separate Objekte modelliert. Der Knoten verfügt über eine Liste ausgehender Pfeile, und jedes "Pfeil" -Objekt verfügt über einen anzuzeigenden Text und einen Verweis auf das Ziel. Ich bin mir nicht sicher, aber ich denke, in C # werden Objekte immer referenziert. Erstellen Sie also zuerst die Objekte und fügen Sie dann beim Erstellen der Pfeilobjekte dasselbe Objekt in das Zielfeld von zwei Pfeilen ein. (In C ++ würden Sie einen Referenz- oder Zeigertyp, Node & oder Node *, verwenden.)

Zum Laden von Dingen wie diesem von der Festplatte gibt man normalerweise jedem Knoten eine eindeutige ID-Nummer und lädt dann alle Knoten in ein Array, in dem der Index diese eindeutige Nummer ist. Dann werden die Pfeile serialisiert, indem die Nummer und nicht das eigentliche Objekt ausgeschrieben wird.

Wenn Sie einen Pfeil laden, verwenden Sie das Array und die ID, um einen Verweis auf den Knoten abzurufen, auf den er verweist. Wenn Sie das Objekt zweimal ausgeschrieben hätten, würden Sie zwei separate Objekte erhalten, die einfach identisch aussehen, was wahrscheinlich nicht das ist, was Sie wollten.

Das Verarbeiten eines Dialogbaums wird sehr einfach. Sie setzen einfach den Wurzelknoten in eine currentNodeVariable, zeigen das Ganze irgendwie an, und wenn Sie eine Auswahl treffen, setzen Sie es rootNodeauf das Ziel des Pfeils. Im Pseudocode:

Node&    currentNode = dialogTree.node[0];
while( currentNode != END_CONVERSATION_PSEUDO_NODE )
{
    stage.displayNode( currentNode );
    currentNode = stage.waitForUserToChoose();
}
Geschicklichkeit
quelle
1

Vor kurzem musste ich so etwas mit Node entwickeln und entschied mich für eine sehr einfache Textdateistruktur, um einen gerichteten Graphen von Konversationsknoten darzustellen.

Sie können den resultierenden Code und das Textformat unter folgender Adresse sehen:

https://github.com/scottbw/dialoguejs

Es unterstützt (noch) keine Bedingungen oder Ereignisauslöser, ist aber wahrscheinlich für viele Spieleentwickler einfach genug, um damit zu beginnen.

(Der Code selbst in der GPL, übrigens)

Scott Wilson
quelle
Die Frage fragt nach C #.
Seth Battin
Tut mir leid.
Scott Wilson