Ou seja, o que está conectado ao que e como se mover entre as linhas de fala quando uma subconversão termina?
Se você tiver exemplos de uma árvore de diálogo básica em C #, poste-os.
Ou seja, o que está conectado ao que e como se mover entre as linhas de fala quando uma subconversão termina?
Se você tiver exemplos de uma árvore de diálogo básica em C #, poste-os.
Respostas:
O nome "árvore de diálogo" é um pouco enganador - eles geralmente são gráficos direcionados simples , não apenas árvores . A estrutura básica de dados desses gráficos geralmente consiste em algum tipo de "dados" para os nós, que representam os pontos em que estamos na conversa e os vincula a outros nós, que representam o que está sendo dito e feito pelos participantes e, opcionalmente, têm condições para limitar sua visibilidade ou scripts para executar várias ações adicionais. Geralmente, um dos nós é o nó inicial padrão (rótulos típicos para "ROOT", "START" e "GREETING") e nós que não têm links válidos a partir deles encerram a conversa.
Na maioria dos casos, o gráfico é representado na memória como uma lista de Node
estruturas de dados, cada uma tendo pelo menos um ID e uma lista de 0..n Link
estruturas de dados. A lista pode ser local para o NPC ou global; o segundo caso é o preferido se você tiver muitos NPCs genéricos com os quais se pode conversar para obter informações, mas não ofereça conversas específicas por conta própria. O próprio sistema encontra o nó de conversa inicial do NPC, lembra seu ID como o atual, apresenta os links válidos atualmente para o jogador escolher (ou "[encerrar a conversa]" se não houver links válidos) e aguarda entrada. Quando o jogador escolhe um link, as linhas de diálogo associadas são exibidas e todos os scripts associados são executados.
Em vez de ter regras e condições complexas nos links, você pode conviver com uma variável booleana "válida" simples, que pode ser alterada a partir dos scripts de outros links de conversa (incluindo o padrão do nó inicial) ou por fora mecanismos. Em geral, essa abordagem é mais simples, mas adequada apenas para jogos com muito poucas conversas, uma vez que move a lógica de "Quando essa resposta é possível?" longe dos próprios dados de resposta.
Observe que a estrutura que descrevo aqui é um pouco diferente da do Byte56, pois os nós não precisam ter nenhuma linha de diálogo; os links podem ter todos eles. Na variante mais básica, isso se traduz na seguinte estrutura.
As árvores de diálogo são criadas com uma estrutura de gráfico direcionada .
O gráfico é percorrido com base nas decisões de diálogo que o jogador toma. As opções de diálogo fornecidas ao usuário vêm das bordas que definem os caminhos para outros nós da caixa de diálogo.
Os gráficos direcionados são uma estrutura básica de dados. Eles podem ser facilmente implementados e você provavelmente desejará implementá-lo. Como você deseja adaptar o gráfico às suas necessidades de diálogo.
Alguns dos nós podem precisar ter condições especiais atendidas para aparecer. Por exemplo, o jogador exigiria uma habilidade na fala acima de X. Ou o jogador precisa ter completado a missão Z antes de poder avançar um ramo do diálogo. Ou eles precisam perguntar algo 4 vezes antes que o NPC discuta isso com eles. Esses recursos serão personalizados para o seu jogo. Mas vale a pena mencionar quando você estiver implementando o nó e a travessia de borda. Claro que é sempre melhor começar com a forma mais simples e construir a partir daí.
Eu construí um sistema simples de dialogtree: http://iki.fi/sol/d3/ atualmente o "mecanismo" é simples c, mas os dados produzidos pelo editor são bastante simples de usar em qualquer idioma. A ferramenta gera XML, JSON e um formato binário personalizado.
O conceito principal é bem simples:
Cada nó (que chamo de "cartão", como no análogo acima) da caixa de diálogo consiste em texto de pergunta e zero ou mais respostas. Cada uma das respostas leva a outro cartão.
Há também um sistema de tags em que certas respostas são mostradas ao usuário apenas se uma tag estiver definida (ou uma tag não estiver definida). A inserção de um cartão define (ou desativa) as tags especificadas.
Isso é praticamente tudo o que precisamos fazer sobre qualquer tipo de diálogo em um jogo. O "texto da pergunta" pode ser um texto sem formatação ou um script para gerar animação ou outros enfeites.
Você pode usar o TreeSharp e as árvores de comportamento para modelar um sistema de diálogo. TreeSharp é uma biblioteca que fornece uma implementação simples da árvore de comportamento. Os bots IA para wow são feitos com isso, então é maduro ... :)
Minha implementação possui nós que permitem escolher entre respostas, e cada resposta pode ser associada a um diálogo ou uma ação, ou uma sequência de ações, ou um nó que permite ir para outro diálogo ... ou o que você deseja ...
Eu usei o brainiac editor para torná-lo visualmente ... mas no final ele produz código c # baseado em treesharp ...
Você deseja um gráfico direcionado (possivelmente cíclico).
Você modelaria os nós como objetos, e todas as setas de saída no nó de um gráfico também serão modeladas como objetos separados. O nó possui uma lista de setas de saída e cada objeto "seta" possui um texto para exibir e uma referência ao destino. Não tenho certeza, mas acho que os objetos C # sempre são referenciados; portanto, basta criar os objetos primeiro e, em seguida, ao criar os objetos de seta, conecte o mesmo objeto ao campo de destino de duas setas. (Em C ++, você usaria um tipo de referência ou ponteiro, Nó e ou Nó *)
Para carregar coisas como essa do disco, geralmente se atribui a cada nó um número de identificação exclusivo e, em seguida, carrega todos os nós em uma matriz em que o índice é esse número único. Em seguida, as setas são serializadas escrevendo o número, não o objeto real.
Ao carregar uma seta, você usa a matriz e o ID para obter uma referência ao nó para o qual aponta. Se você escrevesse o objeto duas vezes, obteria dois objetos separados que parecem idênticos, o que provavelmente não é o que você queria.
O processamento de uma árvore de diálogo se torna muito simples. Você apenas coloca o nó raiz em uma currentNode
variável, exibe a coisa toda de alguma forma e, quando uma escolha é feita, defina rootNode
o destino da seta. No pseudocódigo:
Node& currentNode = dialogTree.node[0];
while( currentNode != END_CONVERSATION_PSEUDO_NODE )
{
stage.displayNode( currentNode );
currentNode = stage.waitForUserToChoose();
}
Recentemente, tive que desenvolver algo assim usando o Node e optei por uma estrutura de arquivo de texto muito básica para representar um gráfico direcionado de nós de conversação.
Você pode ver o código resultante e o formato do texto em:
https://github.com/scottbw/dialoguejs
Ainda não suporta condições ou gatilhos de eventos, mas provavelmente é simples o suficiente para muitos desenvolvedores de jogos.
(O próprio código na GPL, btw)
dialog-tree
tag.