¿Cómo puedo implementar árboles de diálogo en mi juego?

51

¿Cuál es la mejor manera de implementar un sistema de árbol de diálogo en mi juego? Quiero que un NPC le dé al jugador diferentes conjuntos de respuestas, algunas de las cuales solo pueden aparecer cuando el jugador tiene un elemento o se ha producido un evento anterior.

Bryan Denny
fuente
2
BOUNTY es especialmente para buenas ideas sobre cómo manejar las traducciones de frases desencadenantes y texto NPC. Para que el NPC pueda entender y hablar diferentes idiomas según el jugador que inició la conversación. Incluso con el enfoque de bloques de construcción en gamedev.stackexchange.com/questions/31/… , no parece ser una buena idea tener lógica dentro de los repositorios de texto. Pero dividirlos hace que sea mucho más difícil entender el código.
Hendrik Brummermann

Respuestas:

17

Los árboles de diálogo deben hacerse usando XML. Almacena las condiciones para las respuestas y la respuesta en árboles anidados con una referencia a un archivo de script si necesita hacer algo más complejo.

Debe mantener los scripts y el diálogo separados, especialmente si está armando un juego de rol que tiene una tonelada métrica de conversaciones. Luego puede usar una biblioteca como simpleXML para leer el archivo XML.

Hay una pregunta similar sobre SO con un ejemplo: https://stackoverflow.com/questions/372915/game-logic-in-xml-files

zorro
fuente
+1 para XML. Mucho mejor que incrustar en el código en sí mismo, permite cambios sin volver a compilar el código, y es un formato estándar que pueden leer algunos editores potentes.
AttackingHobo
34
XML es solo un formato (y, en mi opinión, uno malo). Realmente lo que dice esta respuesta es: "Cree un lenguaje de dominio pequeño que contenga lógica y flujos básicos, pero que principalmente consista en su diálogo y analícelo". De esa manera general, estoy de acuerdo con esta respuesta.
Ipsquiggle
55
Exactamente, XML es solo el contenedor, usted también puede (y definitivamente más legible y editable por humanos) implementar esto usando Lua u otros lenguajes de secuencias de comandos.
LearnCocos2D
44
XML es costoso de analizar y ocupa MUCHA memoria. Está bien usarlo como formato de almacenamiento, pero escribiría una utilidad que convierta los árboles de diálogo a un formato binario que se usa en tiempo de ejecución. Si está en una PC y no le importa el uso de su memoria, puede estar bien, pero en cualquier otra plataforma, el costo de la memoria lo agobiará.
BigSandwich
1
-1 para XML. Estoy de acuerdo con @Ipsquiggle y @BigSandwich
o0 '.
20

Me gustaría ver un lenguaje de scripts incrustado como lua o ruby ​​y codificar interacciones de diálogo en eso.

Por lo tanto, un script de diálogo podría verse así:

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!"

Esto también funciona bien para codificar IA y otras cosas simples que son útiles para ajustar durante el tiempo de ejecución. Incluso puede agregar un editor integrado en su aplicación que se puede invocar cuando se ejecuta en depuración (o como un huevo de Pascua).

BarrettJ
fuente
1
Prefiero esto a XML directo, ya que puede agregar lógica. Pero yo diría que el texto en sí probablemente debería estar en XML en lugar de en el código. (más fácil de editar, localizar a otros idiomas, etc.)
Iain
si necesita localización / edición más fácil, puede ajustar el texto en una función que escriba el texto adjunto en un archivo separado como la función / macro tr (QString) en Qt. pepper.troll.no/s60prereleases/doc/linguist-hellotr.html
clavadora
¿Qué le impide usar atributos o etiquetas adicionales en el xml para simular la lógica aquí?
lathomas64
16

En el juego Stendhal usamos una máquina de estados finitos para implementar NPC.

El siguiente diagrama muestra un pequeño ejemplo del tutorial sobre cómo escribir misiones .

FSM con estados IDLE, ATTENDING y QUEST_OFFERED

Al principio, el NPC está en un estado inactivo y puede estar caminando. Un jugador puede iniciar una conversación diciendo "hola" y el NPC pasará al estado ASISTENTE. En este estado, responde a preguntas sobre su "trabajo" y ofrece algunos juegos de "ayuda". El jugador puede solicitar una misión y el NPC pasará al estado QUEST_OFFERED esperando que el jugador lo acepte ("sí") o lo rechace ("no").

Hemos definido un conjunto de condiciones que se pueden adjuntar a las transiciones. Por ejemplo, completar una misión solo puede ser posible si se cumple un PlayerHasItemWithHimCondition .

Después de ejecutar una transición, el NPC puede decir algo de texto y / o ejecutar una acción. De manera similar a las condiciones, hemos definido un conjunto reutilizable de acciones como EquipItemAction que se utiliza para otorgar una recompensa de misión a un jugador.

Se pueden combinar múltiples condiciones usando AndCondition , OrCondition y NotCondition . Por lo general, hay una serie de acciones que se deben realizar al completar la misión, por lo que también hay una clase MultipleActions .

Si bien la implementación real en Stendhal adolece de no ser traducible en otros idiomas (humanos) fácilmente, creo que el concepto general es bueno.

Hendrik Brummermann
fuente
5

Puede echar un vistazo a la herramienta Dlgedit del motor de RPG de código abierto Adonthell . Es muy avanzado y debe contener todo lo que necesita (incluidas las fuentes;))

Koonsolo
fuente
5

Creo que para agregar traducciones, aún podría usar XML para la lógica como se indicó anteriormente . Cuando te encuentres con ese tipo de complejidad, debes escribir tu propia herramienta de diálogo. Su texto de diálogo se almacenaría como una clave para una base de datos que podría intercambiar según el idioma que desea mostrar.

Por ejemplo, podrías tener:

<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>

Luego, el renderizador de texto de búsqueda reemplazará "Localize.FixMyCar" por el texto traducido adecuadamente.

Su herramienta mostraría lo que el jugador vería en un idioma seleccionable junto con el XML sin editar editable.

Del mismo modo, podría usar algo como esto en el ejemplo al que hizo referencia :

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

Si sus claves son lo suficientemente descriptivas, no tener el texto completo no debería ser un problema.

Algo como esto también podría ser útil:

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

Los datos conducen a tus personajes con scripts LUA o incluso archivos XML. Cuando interactúas con un NPC, toma el archivo que está adjunto, léelo, ajústalo a las variables del juego que puedan haberse activado y crea la respuesta válida.

La mayor ganancia de hacerlo de esta manera es que puede ingresar y manipular fácilmente el diálogo, agregar nuevos caracteres, etc. También evita el desorden de su base de código con una lógica especial en el manejo de cada caso.

David McGraw
fuente
1
Es Lua, no LUA. :)
RCIX
2
Lo hice solo por ti, hombre. ;)
David McGraw el
4

Si usa XML, asegúrese de crear una pequeña herramienta para editar el archivo XML. Te volverás loco de lo contrario.

zooropa
fuente
Si ya no hay una herramienta para editarlo, entonces no tiene sentido usarlo en primer lugar: ¡cree su propio formato también!
o0 '.
3

Si tiene un conjunto bastante profundo de árboles de diálogo, use ChatMapper . Tienen una versión gratuita con todas las funciones y la herramienta le permite exportar sus árboles de diálogo a XML. Lo he estado usando y es una excelente manera de visualizar y organizar complejos árboles de diálogo.


fuente
1

Si sus diálogos son de alguna complejidad, lo más importante que necesitará para la implementación del diálogo es una forma de comprender la complejidad de su interacción. Recomiendo un editor de nodos de algún tipo para visualizar esto, aunque no tengo ningún buen sistema abierto para recomendar.

Aaron Brady
fuente
1

Creo que usas tu propio lenguaje de script para dirigir este tipo de juego (si no, deberías). Luego expande tu script para el manejo de diálogos también.
Puedes trabajar con otras variables del juego durante la creación de la lógica de los diálogos. Los motores de juego son como Lego. Usted programó solo ladrillos y el script los usa. No importa si crea algún intérprete de guiones o compilador. Pero el guión siempre es útil.

samboush
fuente
0

El autómata simple podría hacer:

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

Podría verse más o menos así:

(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!!!")

En el juego, encuentra la identificación e intenta hacer coincidir la identificación y la condición.

Necesita modelar las condiciones y acciones. Por objetos, punteros de función, XML ...

Un buen editor de diálogo también será útil.

usuario712092
fuente