Wie kann ich Dialogbäume in mein Spiel implementieren?

51

Was ist der beste Weg, um ein Dialogbaumsystem in mein Spiel zu implementieren? Ich möchte, dass ein NPC dem Spieler verschiedene Antworten gibt. Einige werden möglicherweise nur angezeigt, wenn der Spieler einen Gegenstand hat oder ein vorheriges Ereignis aufgetreten ist.

Bryan Denny
quelle
2
Der BOUNTY ist speziell für gute Ideen zum Umgang mit Übersetzungen von Triggerphrasen und NPC-Texten gedacht. Damit der NPC je nach Spieler, der die Unterhaltung begonnen hat, verschiedene Sprachen verstehen und sprechen kann. Selbst mit dem Building-Block-Ansatz in gamedev.stackexchange.com/questions/31/… scheint es keine gute Idee zu sein, Logik in den Text-Repositorys zu haben. Das Aufteilen macht es jedoch sehr viel schwieriger, den Code zu verstehen.
Hendrik Brummermann

Antworten:

17

Dialogbäume sollten mit XML erstellt werden. Sie speichern die Bedingungen für die Antworten und die Antwort in verschachtelten Bäumen mit einem Verweis auf eine Skriptdatei, wenn Sie etwas Komplexeres tun müssen.

Sie sollten die Skripte und Dialoge getrennt halten, insbesondere wenn Sie ein Rollenspiel zusammenstellen, das eine Menge Konversationen enthält. Sie können dann eine Bibliothek wie simpleXML verwenden, um die XML-Datei zu lesen.

Es gibt eine ähnliche Frage zu SO mit einem Beispiel: https://stackoverflow.com/questions/372915/game-logic-in-xml-files

Fuchs
quelle
+1 für XML. Viel besser als das Einbetten in den Code selbst, ermöglicht Änderungen, ohne den Code neu zu kompilieren, und ist ein Standardformat, das von einigen leistungsstarken Editoren gelesen werden kann.
AttackingHobo
34
XML ist nur ein Format (und, IMO, ein schlechtes). In Wirklichkeit lautet die Antwort: "Erstellen Sie eine kleine Domänensprache, die grundlegende Logik und Abläufe enthält, aber in erster Linie aus Ihrem Dialog besteht, und analysieren Sie diesen." Auf diese allgemeine Weise stimme ich dieser Antwort zu.
Ipsquiggle
5
Genau, XML ist nur der Container, den Sie genauso gut (und definitiv besser lesbar und vom Menschen bearbeitbar) mit Lua oder anderen Skriptsprachen implementieren können.
LearnCocos2D
4
XML ist teuer in der Analyse und beansprucht viel Speicher. Es ist in Ordnung, es als Speicherformat zu verwenden, aber ich würde ein Dienstprogramm schreiben, das die Dialogbäume in ein Binärformat konvertiert, das zur Laufzeit verwendet wird. Wenn Sie auf einem PC arbeiten und sich nicht um die Speichernutzung kümmern, ist dies möglicherweise in Ordnung. Auf jeder anderen Plattform werden Sie jedoch von den Speicherkosten entlastet.
BigSandwich
1
-1 für XML. Ich bin mit @Ipsquiggle und @BigSandwich
o0 'einverstanden.
20

Ich würde eine Einbettung einer Skriptsprache wie Lua oder Ruby und die Codierung von Dialoginteraktionen untersuchen.

So könnte ein Dialogskript aussehen:

switch showDialog "Why don't you just leave me along!", "Okay", "But I found your dog!"
    case 1:
        showDialog "And stay gone!"
    case 2:
        if playerHasObject "dog"
            showDialog "Thank you!"
        else
            showDialog "Liar!"

Dies funktioniert auch gut für die Codierung von KI und anderen einfachen Dingen, die zur Laufzeit optimiert werden können. Sie können sogar einen in Ihre Anwendung integrierten Editor hinzufügen, der beim Ausführen von Debug (oder als Osterei) aufgerufen werden kann.

BarrettJ
quelle
1
Ich bevorzuge dies direktem XML, da Sie Logik hinzufügen können. Aber ich würde sagen, der Text selbst sollte wahrscheinlich eher in XML als im Code sein. (einfacher zu bearbeiten, in andere Sprachen zu lokalisieren usw.).
Iain
Wenn Sie eine Lokalisierung / einfachere Bearbeitung benötigen, können Sie den Text in eine Funktion umbrechen, die den eingeschlossenen Text in eine separate Datei schreibt, wie z. B. die Funktion / das Makro tr (QString) in Qt. pepper.troll.no/s60prereleases/doc/linguist-hellotr.html
Nailer
Was hindert Sie daran, Attribute oder zusätzliche Tags in der XML zu verwenden, um die Logik hier zu simulieren?
Lathomas64
16

Im Spiel Stendhal verwenden wir eine Finite-State-Maschine, um NPCs zu implementieren.

Das folgende Diagramm zeigt ein kleines Beispiel aus dem Tutorial zum Schreiben von Quests .

FSM mit den Zuständen IDLE, ATTENDING und QUEST_OFFERED

Zu Beginn befindet sich der NPC im Leerlauf und kann herumlaufen. Ein Spieler kann ein Gespräch beginnen, indem er "Hallo" sagt. Der NPC wechselt in den Status "Teilnahme". In diesem Zustand beantwortet es Fragen zu seinem "Job" und bietet etwas Spiel "Hilfe" an. Der Spieler kann nach einer Quest fragen und der NPC geht zu QUEST_OFFERED und wartet darauf, dass der Spieler diese akzeptiert ("ja") oder ablehnt ("nein").

Wir haben eine Reihe von Bedingungen definiert , die Übergängen zugeordnet werden können. Zum Beispiel ist das Abschließen einer Quest möglicherweise nur möglich, wenn eine PlayerHasItemWithHimCondition erfüllt ist.

Nachdem ein Übergang ausgeführt wurde, kann der NPC Text sagen und / oder eine Aktion ausführen. Ähnlich wie bei den Bedingungen haben wir eine Reihe wiederverwendbarer Aktionen wie EquipItemAction definiert, mit denen ein Spieler eine Questbelohnung erhält.

Mit AndCondition , OrCondition und NotCondition können mehrere Bedingungen kombiniert werden . Normalerweise gibt es eine Reihe von Aktionen, die nach Abschluss der Quest ausgeführt werden müssen, daher gibt es auch eine MultipleActions- Klasse.

Während die eigentliche Implementierung in Stendhal unter der Schwierigkeit leidet, nicht ohne weiteres in andere (menschliche) Sprachen übersetzbar zu sein, finde ich das allgemeine Konzept gut.

Hendrik Brummermann
quelle
5

Sie können einen Blick auf das Dlgedit- Tool der Open Source-RPG-Engine Adonthell werfen . Es ist sehr fortgeschritten und sollte alles enthalten, was Sie brauchen (einschließlich Quellen;))

Koonsolo
quelle
5

Ich denke, für das Hinzufügen von Übersetzungen könnten Sie immer noch XML für die Logik verwenden, wie oben angegeben . Wenn Sie in diese Art von Komplexität geraten, sollten Sie Ihr eigenes Dialogwerkzeug schreiben. Ihr Dialogtext wird als Schlüssel zu einer Datenbank gespeichert, die Sie je nach der Sprache, die Sie anzeigen möchten, austauschen können.

Zum Beispiel könnten Sie haben:

<dialogue id="101" condition="!npc.carsFixed">
  <message>Localize.FixMyCar</message>
  <choices>
    <choice condition="hero.carFixingSkill > 5" priority="7" id="Localize.Sure">
      <command>hero.carFixingSkills += 1</command>
      <command>npc.carFixed = true</command>
      <command>hero.playSmokeAnimation()</command>
      <command>nextDialogue = 104</command>
    </choice>
    <choice condition="hero.carFixingSkill <= 5" id="Localize.CantFix">
      <command>nextDialogue = 105</command>
    </choice>
    <choice id="Localize.FixYourself">
      <command>npc.likesHero -= 1</command>
    </choice>
  </choices>
</dialogue>

Dann müsste der Quest-Text-Renderer "Localize.FixMyCar" durch den entsprechend übersetzten Text ersetzen.

Ihr Tool zeigt das, was der Player sehen würde, in einer auswählbaren Sprache neben dem bearbeitbaren unformatierten XML an.

In ähnlicher Weise könnten Sie so etwas aus dem Beispiel verwenden, auf das Sie verwiesen haben :

npc.add(ConversationStates.ATTENDING,
        ConversationPhrases.QUEST_MESSAGES, 
        null,
        ConversationStates.QUEST_OFFERED, 
        Localization[ "BringMeABeer" ],
        null);

Wenn Ihre Schlüssel aussagekräftig genug sind, sollte es kein Problem sein, nicht den vollständigen Text zu haben.

So etwas könnte auch nützlich sein:

Localization[ "<Location>.<NPC_name>.<Dialogue_text_key>" ];
toddw
quelle
4

Daten treiben Ihre Charaktere mit LUA-Skripten oder sogar XML-Dateien an. Wenn Sie mit einem NPC interagieren, greifen Sie auf die angehängte Datei zu, lesen Sie sie ein, passen Sie sie auf eventuell ausgelöste Spielvariablen an und erstellen Sie die gültige Antwort.

Der größte Vorteil dieser Vorgehensweise besteht darin, dass Sie den Dialog problemlos bearbeiten, neue Zeichen hinzufügen usw. Sie vermeiden außerdem, Ihre Codebasis mit einer speziellen Logik bei der Behandlung jedes einzelnen Falls durcheinander zu bringen.

David McGraw
quelle
1
Es ist Lua, nicht LUA. :)
RCIX
2
Ich habe es nur für dich getan, Mann. ;)
David McGraw
4

Wenn Sie XML verwenden, stellen Sie sicher, dass Sie ein kleines Tool zum Bearbeiten der XML-Datei erstellen. Sonst wirst du verrückt.

zooropa
quelle
Wenn es bereits kein Werkzeug zum Bearbeiten gibt, ist es sinnlos, es zunächst zu verwenden: Erstellen Sie auch Ihr eigenes Format!
o0 '.
3

Verwenden Sie ChatMapper, wenn Sie über einen ziemlich umfangreichen Satz von Dialogfeldern verfügen . Sie haben eine kostenlose Vollversion und das Tool ermöglicht es Ihnen, Ihre Dialogbäume in XML zu exportieren. Ich benutze es und es ist eine hervorragende Möglichkeit, komplexe Dialogbäume zu visualisieren und zu organisieren.


quelle
1

Wenn Ihre Dialoge komplex sind, ist das Wichtigste, was Sie für die Implementierung von Dialogen benötigen, eine Möglichkeit, die Komplexität Ihrer Interaktion zu verstehen. Ich empfehle einen Node-Editor, um dies zu visualisieren, obwohl ich keine guten offenen Systeme zu empfehlen habe.

Aaron Brady
quelle
1

Ich denke, dass Sie Ihre eigene Skriptsprache verwenden, um diese Art von Spiel zu steuern (wenn nicht, sollten Sie dies tun). Erweitern Sie dann Ihr Skript auch für die Handhabung von Dialogen.
Sie können während der Erstellung der Dialoglogik mit anderen Spielvariablen arbeiten. Game Engines sind wie Lego. Sie haben nur Bausteine ​​programmiert und Skript verwendet sie. Es spielt keine Rolle, ob Sie einen Skriptinterpreter oder Compiler erstellen. Aber ein Skript ist immer nützlich.

samboush
quelle
0

Einfacher Automat könnte tun:

(dialogueline_id, condition) -> (next_id, response)

Es könnte ungefähr so ​​aussehen:

(1, troll is hungry?) -> (2, say "troll be hungry")
(2, player has bananas?) -> (3, say "hey, you have bananas!")
(3, ) -> (-1, (say "i like bananas, i take them and eat, you may pass, bye", remove bananas, feed the troll))
(2, player does not have bananas?) -> (-1, say "go away!!!")

Im Spiel finden Sie ID und versuchen, ID und die Bedingung abzugleichen.

Sie müssen die Bedingungen und Aktionen modellieren. Durch Objekte, Funktionszeiger, XML ...

Guter Dialogeditor wird auch nützlich sein.

user712092
quelle