Come funzionano gli alberi di dialogo?


20

Cioè, cosa è collegato a cosa e come spostarsi tra le linee di discorso al termine di una conversazione secondaria?

Se hai esempi di un albero di dialogo di base in C #, pubblicali.


Penso che sarebbe bello avere un dialog-treetag.
user1306322

La richiesta di esempi di codice non viene generalmente considerata favorevolmente.
MichaelHouse

Se ci sono alcuni esempi di codice dell'albero di dialogo 101 che vale la pena condividere, non potrebbe far male.
user1306322

Il problema è che questo sito riguarda la risposta corretta alle domande. Non è per la raccolta di esempi di codice.
MichaelHouse

Ecco perché la frase inizia con "if". Ma quello che sto chiedendo è la spiegazione su come le linee di dialogo si collegano tra loro in un modo che può essere efficacemente tradotto in codice. Dopo tutto lo scriverò in C #.
user1306322

Risposte:


24

Il nome "albero di dialogo" è un po 'fuorviante: di solito sono semplici grafici diretti , non solo alberi . La struttura dei dati di base di tali grafici di solito consiste in una sorta di "dati" per i nodi, che rappresentano i punti in cui ci troviamo nella conversazione, e collegamenti da essi ad altri nodi, che rappresentano ciò che viene detto e fatto dai partecipanti e facoltativamente hanno condizioni su di loro per limitare la loro visibilità o script per eseguire varie azioni aggiuntive. Di solito uno dei nodi è il nodo iniziale predefinito (le etichette tipiche sono "ROOT", "START" e "SALUTO") e i nodi che non hanno collegamenti validi che conducono da loro terminano la conversazione.

Nella maggior parte dei casi, il grafico è rappresentato in memoria come un elenco di Nodestrutture dati, ognuna con almeno un ID e un elenco di 0..n Linkstrutture dati. L'elenco può essere locale all'NPC o globale; il secondo caso è preferito se si hanno molti NPC generici che possono essere consultati per informazioni, ma non offrono conversazioni specifiche per conto proprio. Il sistema stesso trova il nodo di conversazione iniziale per l'NPC, ricorda il suo ID come ID di conversazione corrente, presenta i collegamenti attualmente validi per il giocatore tra cui scegliere (o "[termina conversazione]" se non ci sono collegamenti validi) e attende ingresso. Quando il giocatore sceglie un collegamento, vengono visualizzate le linee di dialogo associate e tutti gli script associati vengono eseguiti.

Invece di avere regole e condizioni complesse sui collegamenti, puoi invece cavartela con una semplice variabile booleana "valida", che può quindi essere modificata dagli script di altri collegamenti di conversazione (incluso quello predefinito dal nodo iniziale) o dall'esterno meccanismi. In generale, questo approccio è più semplice ma adatto solo a giochi con pochissime conversazioni di questo tipo, poiché sposta la logica di "Quando è possibile questa risposta?" lontano dai dati di risposta stessi.


Si noti che la struttura che descrivo qui è leggermente diversa da quella di Byte56 in quanto i nodi non hanno bisogno di avere linee di dialogo; i collegamenti possono averli tutti. Nella variante più semplice, questo si traduce nella seguente struttura.

enter image description here


+1 Per menzionare le regole e le condizioni sui collegamenti, un semplice grafico diretto spesso non è sufficiente e le cose possono diventare complicate quando inizi a necessitarne.
Laurent Couvidou,

+1 Mi piace di più quella struttura. Tuttavia, non lo consiglierei come primo passaggio. Comincerei con qualcosa di più semplice. È certamente un bersaglio migliore per cui sparare.
MichaelHouse

+1 Per una risposta molto dettagliata. Questo potrebbe tornare utile per me in seguito.
Marton,

Questa immagine mi è stata molto utile, ma devo chiedermi perché DialogueLine è separato dal Link? Ogni link non avrebbe il suo testo di risposta? E dove andrebbe il testo dell'NPC? Non avrebbe senso averlo nel nodo?
Kyle Baran,

@Danjen In questa struttura, un collegamento può avere più DialogueLine, possibilmente di caratteri diversi, fino a quando appare la successiva finestra di dialogo. Questo è anche dove va il testo dell'NPC. Quando le linee si ripetono, diversi Link possono condividere DialogueLines, riordinandoli eventualmente nel loro elenco (Vector), sostituendo parti di essi con linee diverse, aggiungendo interiezioni e così via.
Martin Sojka,

16

Gli alberi delle finestre di dialogo vengono creati con una struttura grafica diretta .

inserisci qui la descrizione dell'immagine

Il grafico viene attraversato in base alle decisioni di dialogo prese dal giocatore. Le opzioni della finestra di dialogo fornite all'utente provengono dai bordi che definiscono i percorsi verso altri nodi della finestra di dialogo.

I grafici diretti sono una struttura di dati di base. Possono essere facilmente implementati e probabilmente vorrai implementarlo da solo. Dal momento che vorrai personalizzare il grafico in base alle tue esigenze di dialogo.

Alcuni dei nodi potrebbero aver bisogno di condizioni speciali soddisfatte per mostrarsi. Ad esempio, il giocatore richiederebbe un'abilità nel discorso sopra X. Oppure il giocatore deve aver completato la missione Z prima di poter avanzare in un ramo della finestra di dialogo. Oppure devono chiedere qualcosa 4 volte prima che l'NPC ne discuterà con loro. Queste funzionalità saranno personalizzate per il tuo gioco. Ma vale la pena menzionare quando si implementano il nodo e l'attraversamento dei bordi. Ovviamente è sempre meglio iniziare con la forma più semplice e costruire da lì.


Non riesco proprio a capire cosa fare in casi come "Newton-trouble" in questa immagine. Ad esempio come impostare l'ordine di quelle righe nel codice senza ripeterle.
user1306322

Troverai spesso che la finestra di dialogo può essere ripetuta. Di solito è solo segnato in qualche modo, quindi l'utente sa che ha già scelto quel percorso di dialogo. Puoi mettere una bandiera sui bordi che indica se sono stati selezionati in precedenza. Quindi spetta a te consentire agli utenti di selezionarlo di nuovo (per aggiornarsi) o non mostrarlo.
MichaelHouse

1
Normalmente non si farebbe con l'ordinamento di righe di codice, ma tramite i riferimenti nella struttura dei dati.
Kylotan,

7

Ho creato un semplice sistema dialogtree: http://iki.fi/sol/d3/ il "motore" stesso è attualmente semplice, ma i dati prodotti dall'editore sono piuttosto semplici da usare in qualsiasi lingua. Lo strumento genera XML, JSON e un formato binario personalizzato.

Il concetto principale è piuttosto semplice:

Sei in un labirinto di piccoli passaggi tortuosi, tutti uguali

Ogni nodo (che io chiamo "carta", come con l'analogo sopra) della finestra di dialogo è costituito da un testo di domanda e zero o più risposte. Ciascuna delle risposte porta ad un'altra carta.

C'è anche un sistema di tag in cui determinate risposte vengono mostrate all'utente solo se è impostato un tag (o un tag non è impostato). L'immissione di una scheda imposta (o disinserisce) i tag specificati.

Questo è praticamente tutto ciò che serve per qualsiasi tipo di dialogo in un gioco. Il "testo della domanda" può essere un testo semplice oppure può essere uno script per guidare l'animazione o quant'altro.


4

È possibile utilizzare TreeSharp e alberi comportamentali per modellare un sistema di dialogo. TreeSharp è una libreria che fornisce una semplice implementazione dell'albero del comportamento. IA robot per wow sono fatti con questo, quindi è maturo ... :)

La mia implementazione ha nodi che consentono di scegliere tra le risposte e ogni risposta può essere unita a un altro dialogo o un'azione, o una sequenza di azioni, o un nodo che consente di passare a un'altra finestra di dialogo ... o ciò che si desidera ...

Ho usato l'editor per il cervello per renderlo visivamente ... ma alla fine produce un codice c # basato sull'albero ...

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


2

Vuoi un grafico diretto (possibilmente ciclico).

Modelleresti i nodi come oggetti e anche tutte le frecce in uscita nel nodo di un grafico sono modellate come oggetti separati. Il nodo ha un elenco di frecce in uscita e ogni oggetto "freccia" ha un testo da visualizzare e un riferimento alla destinazione. Non sono sicuro, ma penso che in C # gli oggetti facciano sempre riferimento, quindi devi solo creare prima gli oggetti, quindi quando crei gli oggetti freccia, collega lo stesso oggetto nel campo di destinazione di due frecce. (In C ++ useresti un tipo di riferimento o puntatore, Nodo e o Nodo *)

Per caricare cose come queste dal disco, di solito si dà a ciascun nodo un numero ID univoco, quindi si caricano tutti i nodi in un array in cui l'indice è quel numero univoco. Quindi le frecce vengono serializzate scrivendo il numero, non l'oggetto reale.

Quando si carica una freccia, si utilizzano l'array e l'ID per ottenere un riferimento al nodo a cui punta. Se scrivessi l'oggetto due volte, otterrai due oggetti separati che sembrano identici, il che probabilmente non è quello che volevi.

L'elaborazione di un albero di dialogo diventa molto semplice. Basta inserire il nodo radice in una currentNodevariabile, visualizzare l'intera cosa in qualche modo, quindi quando viene effettuata una scelta, impostare rootNodela destinazione della freccia. In pseudocodice:

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

1

Di recente ho dovuto sviluppare qualcosa di simile usando Node e ho optato per una struttura di file di testo molto semplice per rappresentare un grafico diretto dei nodi di conversazione.

Puoi vedere il codice e il formato di testo risultanti su:

https://github.com/scottbw/dialoguejs

Non supporta le condizioni o i trigger di eventi (ancora), ma è probabilmente abbastanza semplice da iniziare per molti sviluppatori di giochi.

(Il codice stesso in GPL, btw)


La domanda richiede C #.
Seth Battin,

D'oh - scusa per quello.
Scott Wilson,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.