Comment fonctionnent les arborescences de dialogue?

20

Autrement dit, qu'est-ce qui est lié à quoi et comment se déplacer entre les lignes de discours lorsqu'une sous-conversation se termine?

Si vous avez des exemples d'arborescence de dialogue de base en C #, veuillez les publier.

user1306322
la source
Je pense que ce serait génial d'avoir une dialog-treeétiquette.
user1306322
Demander des exemples de code n'est généralement pas considéré favorablement.
MichaelHouse
S'il y a des exemples de code 101 de l'arborescence de dialogue qui valent la peine d'être partagés, cela ne pourrait pas nuire.
user1306322
Le problème est que ce site vise à obtenir des réponses correctes aux questions. Ce n'est pas pour collecter des exemples de code.
MichaelHouse
C'est pourquoi la phrase commence par "si". Mais ce que je demande, c'est l'explication de la façon dont les lignes de dialogue se connectent les unes aux autres d'une manière qui peut être efficacement traduite en code. Après tout, je vais l'écrire en C #.
user1306322

Réponses:

24

Le nom «arbre de dialogue» est un peu trompeur - ce sont généralement de simples graphiques dirigés , pas seulement des arbres . La structure de données de base de ces graphiques consiste généralement en une sorte de «données» pour les nœuds, qui représentent les points où nous en sommes dans la conversation, et des liens entre eux et d'autres nœuds, qui représentent ce qui est dit et fait par les participants. et éventuellement des conditions pour limiter leur visibilité ou des scripts pour effectuer diverses actions supplémentaires. Habituellement, l'un des nœuds est le nœud de départ par défaut (les étiquettes typiques sont "ROOT", "START" et "GREETING"), et les nœuds qui n'ont pas de liens valides menant à partir d'eux mettent fin à la conversation.

Dans la plupart des cas, le graphique est représenté en mémoire sous la forme d'une liste de Nodestructures de données, chacune ayant au moins un ID et une liste de Linkstructures de données 0..n . La liste peut être locale au PNJ ou globale; le deuxième cas est préférable si vous avez beaucoup de PNJ génériques auxquels vous pouvez vous adresser pour obtenir des informations, mais ne proposez pas de conversations spécifiques par eux-mêmes. Le système lui-même trouve le nœud de conversation de départ pour le PNJ, se souvient de son ID en tant qu'ID de conversation actuel, présente les liens actuellement valides pour le joueur (ou "[fin de conversation]" s'il n'y a pas de liens valides) et attend contribution. Lorsque le joueur choisit un lien, les lignes de dialogue associées s'affichent et tous les scripts associés s'exécutent.

Au lieu d'avoir des règles et des conditions complexes sur les liens, vous pouvez plutôt vous débrouiller avec une simple variable booléenne "valide", qui peut ensuite être modifiée à partir des scripts d'autres liens de conversation (y compris celui par défaut du nœud de départ) ou par l'extérieur mécanismes. En général, cette approche est plus simple mais ne convient que pour les jeux avec très peu de conversations de ce type, car elle déplace la logique "Quand cette réponse est-elle possible?" loin des données de réponse elles-mêmes.


Notez que la structure que je décris ici est légèrement différente de celle de Byte56 en ce que les nœuds n'ont pas besoin d'avoir de lignes de dialogue; les liens peuvent les avoir tous. Dans la variante la plus élémentaire, cela se traduit par la structure suivante.

entrez la description de l'image ici

Martin Sojka
la source
+1 Pour mentionner les règles et conditions sur les liens, un simple graphique dirigé ne suffit souvent pas, et les choses peuvent devenir compliquées lorsque vous en avez besoin.
Laurent Couvidou
+1 J'aime mieux cette structure. Cependant, je ne le recommanderais pas comme premier passage. Je commencerais par quelque chose de plus simple. C'est certainement une meilleure cible pour laquelle tirer.
MichaelHouse
+1 Pour une réponse très détaillée. Cela pourrait être utile pour moi plus tard.
Marton
Cette image m'a été très utile, mais je dois me demander pourquoi DialogueLine est distinct du lien? Chaque lien n'aurait-il pas son propre texte de réponse? Et où irait le texte du PNJ? Ne serait-il pas logique de l'avoir dans le nœud?
Kyle Baran
@Danjen Dans cette structure, un lien peut avoir plusieurs DialogueLines, éventuellement de caractères différents, jusqu'à ce que le prochain choix de dialogue apparaisse. C'est également là que va le texte du PNJ. Lorsque les lignes se répètent, différents liens peuvent partager des lignes de dialogue, éventuellement en les réorganisant dans leur liste (vecteur), en remplaçant certaines parties par des lignes différentes, en ajoutant des interjections, etc.
Martin Sojka
16

Les arbres de dialogue sont créés avec une structure graphique dirigée .

entrez la description de l'image ici

Le graphique est parcouru en fonction des décisions de dialogue prises par le joueur. Les options de dialogue fournies à l'utilisateur proviennent des bords qui définissent les chemins d'accès aux autres nœuds de dialogue.

Les graphiques dirigés sont une structure de données de base. Ils peuvent facilement être implémentés et vous voudrez probablement l'implémenter vous-même. Puisque vous voudrez adapter le graphique à vos besoins de dialogue.

Certains nœuds peuvent nécessiter des conditions spéciales pour apparaître. Par exemple, le joueur aurait besoin d'une compétence en parole au-dessus de X. Ou le joueur doit avoir terminé la mission Z avant de pouvoir descendre d'une branche de dialogue. Ou ils doivent demander quelque chose 4 fois avant que le PNJ n'en discute avec eux. Ces fonctionnalités seront personnalisées à votre jeu. Mais méritent d'être mentionnés lorsque vous implémentez la traversée de nœuds et de bords. Bien sûr, il est toujours préférable de commencer par la forme la plus simple et de construire à partir de là.

MichaelHouse
la source
Je ne peux pas comprendre quoi faire dans des cas comme "Newton-trouble" sur cette image. Comme comment définir l'ordre de ces lignes dans le code sans les répéter.
user1306322
Vous constaterez souvent que la boîte de dialogue peut être répétée. Il est généralement marqué d'une manière quelconque afin que l'utilisateur sache qu'il a déjà choisi ce chemin de dialogue. Vous pouvez mettre un drapeau dans vos bords qui indique s'ils ont été sélectionnés auparavant. C'est donc à vous de permettre aux utilisateurs de le sélectionner à nouveau (pour se rafraîchir) ou de ne pas l'afficher.
MichaelHouse
1
Cela ne se ferait normalement pas avec l'ordre des lignes de code, mais via les références dans la structure de données.
Kylotan
7

J'ai construit un système de dialogue simple: http://iki.fi/sol/d3/ le "moteur" lui-même est actuellement simple c, mais les données produites par l'éditeur sont assez simples à utiliser dans n'importe quelle langue. L'outil génère XML, JSON et un format binaire personnalisé.

Le concept principal est assez simple:

Vous êtes dans un dédale de petits passages sinueux, tous pareils

Chaque nœud (que j'appelle "carte", comme avec l'analogue ci-dessus) de la boîte de dialogue se compose d'un texte de question et de zéro ou plusieurs réponses. Chacune des réponses mène à une autre carte.

Il existe également un système de balises où certaines réponses ne sont affichées à l'utilisateur que si une balise est définie (ou si une balise n'est pas définie). La saisie d'une carte définit (ou supprime) les balises spécifiées.

C'est à peu près tout ce dont on a besoin pour faire n'importe quel type de dialogue dans un jeu. Le "texte de la question" peut être du texte brut ou un script pour piloter une animation ou autre.

Jari Komppa
la source
4

Vous pouvez utiliser TreeSharp et des arbres de comportement pour modéliser un système de dialogue. TreeSharp est une bibliothèque qui fournit une implémentation d'arbre de comportement simple. Les IA bots pour wow en ont fini avec ça, donc c'est mature ... :)

Mon implémentation a des nœuds qui permettent de choisir entre les réponses, et chaque réponse peut être jointe pour le dialogue ou une action, ou une séquence d'actions, ou un nœud qui permet d'accéder à une autre boîte de dialogue ... ou ce que vous voulez ...

J'ai utilisé l'éditeur brainiac pour le faire visuellement ... mais à la fin, il produit du code c # basé sur la taille d'arbre ...

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

Blau
la source
2

Vous voulez un graphique dirigé (éventuellement cyclique).

Vous modéliseriez les nœuds en tant qu'objets, et toutes les flèches sortantes du nœud d'un graphique sont également modélisées en tant qu'objets distincts. Le nœud a une liste de flèches sortantes, et chaque objet "flèche" a un texte à afficher et une référence à la destination. Je ne sais pas, mais je pense qu'en C #, les objets sont toujours référencés, vous créez donc d'abord les objets, puis lorsque vous créez les objets fléchés, branchez le même objet dans le champ de destination de deux flèches. (En C ++, vous utiliseriez un type de référence ou de pointeur, Node & ou Node *)

Pour charger des choses comme celle-ci à partir du disque, on attribue généralement à chaque nœud un numéro d'identification unique, puis charge tous les nœuds dans un tableau où l'index est ce numéro unique. Ensuite, les flèches sont sérialisées en écrivant le nombre et non l'objet réel.

Lorsque vous chargez une flèche, vous utilisez le tableau et l'ID pour obtenir une référence au nœud vers lequel il pointe. Si vous écrivez l'objet deux fois, vous obtiendrez deux objets distincts qui semblent identiques, ce qui n'est probablement pas ce que vous vouliez.

Le traitement d'une arborescence de dialogue devient très simple. Vous mettez simplement le nœud racine dans une currentNodevariable, affichez le tout d'une manière ou d'une autre, puis lorsqu'un choix est fait, définissez la rootNodedestination de la flèche. En pseudocode:

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

J'ai récemment dû développer quelque chose comme ça en utilisant Node, et j'ai opté pour une structure de fichier texte très basique pour représenter un graphique dirigé de nœuds de conversation.

Vous pouvez voir le code et le format de texte résultants sur:

https://github.com/scottbw/dialoguejs

Il ne prend pas encore en charge les conditions ou les déclencheurs d'événements, mais est probablement assez simple pour commencer pour de nombreux développeurs de jeux.

(Le code lui-même en GPL, btw)

Scott Wilson
la source
La question demande C #.
Seth Battin
D'oh - désolé pour ça.
Scott Wilson