¿Cómo funcionan los árboles de diálogo?

20

Es decir, ¿qué está conectado a qué y cómo moverse entre líneas de discurso cuando termina una subconversación?

Si tiene algún ejemplo de un árbol de diálogo básico en C #, publíquelo.

usuario1306322
fuente
Creo que sería genial tener dialog-treeetiqueta.
user1306322
Pedir muestras de código no suele considerarse favorablemente.
MichaelHouse
Si hay algunos ejemplos de código del árbol de diálogo 101 que vale la pena compartir, no podría hacer daño.
user1306322
El problema es que este sitio trata de obtener respuestas correctas a las preguntas. No es para recolectar muestras de código.
MichaelHouse
Es por eso que la oración comienza con "si". Pero lo que estoy pidiendo es la explicación sobre cómo las líneas de diálogo se conectan entre sí de una manera que se puede traducir eficientemente al código. Después de todo lo voy a escribir en C #.
user1306322

Respuestas:

24

El nombre "árbol de diálogo" es un poco engañoso: generalmente son gráficos simples dirigidos , no solo árboles . La estructura de datos básica de tales gráficos generalmente consiste en algún tipo de "datos" para los nodos, que representan los puntos en los que nos encontramos en la conversación, y enlaces desde ellos a otros nodos, que representan lo que dicen y hacen los participantes. y opcionalmente tienen condiciones para limitar su visibilidad o secuencias de comandos para realizar varias acciones adicionales. Por lo general, uno de los nodos es el nodo de inicio predeterminado (las etiquetas típicas para eso son "ROOT", "START" y "GREETING"), y los nodos que no tienen enlaces válidos que terminan la conversación.

En la mayoría de los casos, el gráfico se representa en la memoria como una lista de Nodeestructuras de datos, cada una con al menos un ID y una lista de 0..n Linkestructuras de datos. La lista puede ser local para el NPC o global; Se prefiere el segundo caso si tiene muchos NPC genéricos con los que se puede hablar para obtener información, pero no ofrece conversaciones específicas por sí mismos. El sistema mismo encuentra el nodo de conversación inicial para el NPC, recuerda su ID como la ID de conversación actual, presenta los enlaces actualmente válidos para que el jugador elija (o "[finalizar conversación]" si no hay enlaces válidos) y espera entrada. Cuando el jugador elige un enlace, se muestran las líneas de diálogo asociadas y se ejecutan los scripts asociados.

En lugar de tener reglas y condiciones complejas en los enlaces, puede pasar con una variable booleana "válida" simple, que luego se puede cambiar desde los scripts de otros enlaces de conversación (incluido el predeterminado desde el nodo inicial) o desde afuera mecanismos. En general, este enfoque es más simple pero solo adecuado para juegos con muy pocas conversaciones, ya que mueve la lógica de "¿Cuándo es posible esta respuesta?" lejos de los datos de respuesta en sí.


Tenga en cuenta que la estructura que describo aquí es ligeramente diferente de la de Byte56 en que los nodos no necesitan tener líneas de diálogo; los enlaces pueden tenerlos a todos. En la variante más básica, esto se traduce en la siguiente estructura.

ingrese la descripción de la imagen aquí

Martin Sojka
fuente
+1 Para mencionar las reglas y condiciones en los enlaces, un gráfico dirigido simple a menudo no es suficiente, y las cosas pueden complicarse cuando empiezas a necesitarlas.
Laurent Couvidou
+1 Me gusta más esa estructura. Sin embargo, no lo recomendaría como primer paso. Comenzaría con algo más simple. Sin duda es un mejor objetivo para disparar.
MichaelHouse
+1 Para una respuesta muy detallada. Esto podría ser útil para mí más tarde.
Marton
Esta imagen me ha sido muy útil, pero tengo que preguntarme por qué DialogueLine está separada del enlace. ¿No tendría cada enlace su propio texto de respuesta? ¿Y a dónde iría el texto del NPC? ¿No tendría sentido tenerlo en el nodo?
Kyle Baran
@Danjen En esta estructura, un enlace puede tener múltiples líneas de diálogo, posiblemente de diferentes personajes, hasta que aparezca la siguiente opción de diálogo. Aquí también es donde va el texto de la APN. Cuando las líneas se repiten, diferentes enlaces pueden compartir líneas de diálogo, posiblemente reordenándolas en su lista (Vector), reemplazando partes de ellas con diferentes líneas, agregando interjecciones, etc.
Martin Sojka
16

Los árboles de diálogo se crean con un estructura gráfica dirigida .

ingrese la descripción de la imagen aquí

El gráfico se recorre en función de las decisiones de diálogo que toma el jugador. Las opciones de diálogo proporcionadas al usuario provienen de los bordes que definen las rutas a otros nodos de diálogo.

Los gráficos dirigidos son una estructura de datos básica. Se pueden implementar fácilmente y es probable que desee implementarlo usted mismo. Como querrá adaptar el gráfico a sus necesidades de diálogo.

Algunos de los nodos pueden necesitar que se cumplan condiciones especiales para poder aparecer. Por ejemplo, el jugador requeriría una habilidad en el habla por encima de X. O el jugador debe haber completado la misión Z antes de poder avanzar una rama del diálogo. O necesitan preguntar algo 4 veces antes de que el NPC lo discuta con ellos. Estas características serán personalizadas para tu juego. Pero vale la pena mencionar cuando está implementando el nodo y el recorrido transversal. Por supuesto, siempre es mejor comenzar con la forma más simple y construir desde allí.

MichaelHouse
fuente
Simplemente no puedo entender qué hacer en casos como "problemas de Newton" en esta imagen. Como cómo establecer el orden de esas líneas en el código sin repetirlas.
user1306322
A menudo encontrará que el diálogo puede repetirse. Por lo general, solo está marcado de alguna manera para que el usuario sepa que ya eligió esa ruta de diálogo. Puede colocar una bandera en sus bordes que indique si se han seleccionado antes. Por lo tanto, depende de usted permitir que los usuarios lo seleccionen nuevamente (para actualizarse) o no mostrarlo.
MichaelHouse
1
Normalmente no se haría ordenando líneas de código, sino a través de las referencias en la estructura de datos.
Kylotan
7

He creado un sistema de diálogo simple: http://iki.fi/sol/d3/ el "motor" en sí es actualmente c simple, pero los datos producidos por el editor son bastante simples de usar en cualquier idioma. La herramienta genera XML, JSON y un formato binario personalizado.

El concepto principal es bastante simple:

Estás en un laberinto de pequeños pasajes sinuosos, todos iguales

Cada nodo (que llamo "tarjeta", como con el análogo anterior) del diálogo consta de texto de pregunta y cero o más respuestas. Cada una de las respuestas lleva a otra tarjeta.

También hay un sistema de etiquetas en el que ciertas respuestas se muestran al usuario solo si se establece una etiqueta (o no se establece una etiqueta). Ingresar una tarjeta establece (o desarma) las etiquetas especificadas.

Esto es prácticamente todo lo que uno necesita hacer sobre cualquier tipo de diálogo en un juego. El "texto de la pregunta" puede ser texto sin formato, o puede ser un script para generar animación o cualquier otra cosa.

Jari Komppa
fuente
4

Puede usar TreeSharp y árboles de comportamiento para modelar un sistema de diálogo. TreeSharp es una biblioteca que proporciona una implementación de árbol de comportamiento simple. Los robots IA para wow ya terminaron con esto, así que es maduro ... :)

Mi implementación tiene nodos que permiten elegir entre respuestas, y cada respuesta se puede unir al diálogo o una acción, o una secuencia de acciones, o un nodo que permite ir a otro diálogo ... o lo que quieras ...

He usado el editor Brainiac para hacerlo visualmente ... pero al final produce un código C # basado en el enfoque de los árboles ...

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

Blau
fuente
2

Desea un gráfico dirigido (posiblemente cíclico).

Modelaría los nodos como objetos, y todas las flechas salientes en el nodo de un gráfico también se modelarán como objetos separados. El nodo tiene una lista de flechas salientes, y cada objeto de "flecha" tiene un texto para mostrar y una referencia al destino. No estoy seguro, pero creo que en C # los objetos siempre están referenciados, por lo que solo debe crear los objetos primero, y luego, cuando cree los objetos de flecha, conecte el mismo objeto en el campo de destino de dos flechas. (En C ++ usaría una referencia o tipo de puntero, Nodo y / o Nodo *)

Para cargar cosas como esta desde el disco, uno generalmente le da a cada nodo un número de identificación único, luego carga todos los nodos en una matriz donde el índice es ese número único. Luego, las flechas se serializan escribiendo el número, no el objeto real.

Cuando carga una flecha, utiliza la matriz y la ID para obtener una referencia al nodo al que apunta. Si escribiera el objeto dos veces, obtendría dos objetos separados que solo se ven idénticos, lo que probablemente no sea lo que quería.

Procesar un árbol de diálogo se vuelve muy simple. Simplemente coloca el nodo raíz en una currentNodevariable, muestra todo de alguna manera, luego, cuando se realiza una elección, se establece rootNodeen el destino de la flecha. En pseudocódigo:

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

Recientemente tuve que desarrollar algo como esto usando Node, y opté por una estructura de archivo de texto muy básica para representar un gráfico dirigido de nodos de conversación.

Puede ver el código resultante y el formato de texto en:

https://github.com/scottbw/dialoguejs

No es compatible con condiciones o desencadenantes de eventos (todavía), pero probablemente sea lo suficientemente simple para comenzar con muchos desarrolladores de juegos.

(El código en sí mismo en GPL, por cierto)

Scott Wilson
fuente
La pregunta pide C #.
Seth Battin
D'oh, perdón por eso.
Scott Wilson el