Come posso implementare alberi di dialogo nel mio gioco?


51

Qual è il modo migliore per implementare un sistema ad albero di dialogo nel mio gioco? Voglio che un NPC dia al giocatore diverse serie di risposte, alcune che possono apparire solo quando il giocatore ha un oggetto o si è verificato un evento precedente.


2
BOUNTY è particolarmente utile per le buone idee su come gestire le traduzioni di frasi trigger e testo NPC. In modo che l'NPC possa capire e parlare lingue diverse a seconda del giocatore che ha iniziato la conversazione. Anche con l'approccio building block in gamedev.stackexchange.com/questions/31/… non sembra essere una buona idea avere una logica all'interno dei repository di testo. La loro suddivisione rende molto più difficile la comprensione del codice.
Hendrik Brummermann,

Risposte:


17

Gli alberi delle finestre di dialogo devono essere eseguiti utilizzando XML. Memorizzare le condizioni per le risposte e la risposta in alberi nidificati con riferimento a un file di script se è necessario eseguire operazioni più complesse.

Dovresti tenere separati gli script e la finestra di dialogo soprattutto se stai mettendo insieme un gioco di ruolo che ha una metrica di conversazioni. È quindi possibile utilizzare una libreria come simpleXML per leggere il file XML.

C'è una domanda simile su SO con un esempio: https://stackoverflow.com/questions/372915/game-logic-in-xml-files


+1 per XML. Molto meglio dell'incorporamento nel codice stesso, consente modifiche senza ricompilare il codice ed è un formato standard che può essere letto da alcuni potenti editor.
Attaccando

34
XML è solo un formato (e, IMO, un cattivo). In realtà ciò che dice questa risposta è "Crea un linguaggio di dominio di piccole dimensioni che contenga logiche e flussi di base, ma che consiste principalmente nel tuo dialogo e analizzalo". In questo modo, sono d'accordo con questa risposta.
Ipsquiggle,

5
Esattamente, XML è solo il contenitore, puoi anche (e sicuramente più leggibile e modificabile dall'uomo) implementarlo usando Lua o altri linguaggi di scripting.
LearnCocos2D,

4
XML è costoso da analizzare e occupa MOLTA memoria. Va bene usarlo come formato di archiviazione, ma scrivo un programma di utilità che converte gli alberi di dialogo in un formato binario che viene utilizzato in fase di esecuzione. Se sei su un PC e non ti interessa l'utilizzo della memoria, potrebbe andare bene, ma su qualsiasi altra piattaforma il costo della memoria ti affliggerà.
BigSandwich,

1
-1 per XML. Sono d'accordo con @Ipsquiggle e @BigSandwich
o0 '.

20

Vorrei esaminare un incorporamento di un linguaggio di scripting come lua o ruby ​​e interazioni di dialogo di codifica in questo.

Quindi uno script di dialogo potrebbe apparire come:

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

Questo funziona bene anche per la codifica dell'intelligenza artificiale e altre cose semplici che sono utili per modificare durante il runtime. Puoi anche aggiungere un editor integrato nella tua applicazione che può essere invocato durante l'esecuzione nel debug (o come Easter Egg).


1
Preferisco questo al semplice XML in quanto puoi aggiungere la logica. Ma direi che il testo stesso dovrebbe probabilmente essere in XML piuttosto che nel codice. (più facile da modificare, localizzare in altre lingue ecc.).
Iain,

se hai bisogno di localizzazione / modifica più semplice puoi avvolgere il testo in una funzione che scrive il testo allegato in un file separato come la funzione / macro tr (QString) in Qt. pepper.troll.no/s60prereleases/doc/linguist-hellotr.html
Nailer

cosa ti impedisce di usare attributi o tag extra nell'xml per simulare la logica qui?
lathomas64,

16

Nel gioco Stendhal utilizziamo una macchina a stati finiti per implementare gli NPC.

Il seguente diagramma mostra un piccolo esempio del tutorial su come scrivere le missioni .

FSM con stati IDLE, ATTENDING e QUEST_OFFERED

All'inizio, l'NPC è in uno stato IDLE e potrebbe essere in giro. Un giocatore può iniziare una conversazione dicendo "ciao" e l'NPC andrà allo stato PARTECIPAZIONE. In questo stato risponde alle domande sul suo "lavoro" e offre un po 'di "aiuto" di gioco. Il giocatore potrebbe chiedere una missione e l'NPC andrà a dichiarare QUEST_OFFERED in attesa che il giocatore lo accetti ("sì") o lo rifiuti ("no").

Abbiamo definito un insieme di condizioni che possono essere associate alle transizioni. Ad esempio, il completamento di una missione può essere possibile solo se viene soddisfatta una PlayerHasItemWithHimCondition .

Dopo l'esecuzione di una transizione, l'NPC può pronunciare del testo e / o eseguire un'azione. Simile alle condizioni abbiamo definito un insieme riutilizzabile di azioni come EquipItemAction che viene utilizzato per assegnare una ricompensa missione a un giocatore.

È possibile combinare più condizioni utilizzando AndCondition , OrCondition e NotCondition . Di solito c'è una serie di azioni da compiere al completamento della missione, quindi c'è anche una classe MultipleActions .

Mentre l'implementazione effettiva in Stendhal soffre di non essere facilmente traducibile in altre lingue (umane), penso che il concetto generale sia buono.



5

Penso che per l'aggiunta di traduzioni, potresti ancora usare XML per la logica come indicato sopra . Quando stai entrando in quel tipo di complessità, dovresti scrivere il tuo strumento di dialogo. Il testo del tuo dialogo verrebbe archiviato come chiave di un database che potresti scambiare a seconda della lingua che desideri visualizzare.

Ad esempio potresti avere:

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

Avresti quindi il renderizzatore di testo di ricerca sostituire "Localize.FixMyCar" con il testo tradotto in modo appropriato.

Il tuo strumento mostrerebbe ciò che il giocatore vedrebbe in una lingua selezionabile insieme all'XML grezzo modificabile.

Allo stesso modo potresti usare qualcosa del genere dall'esempio a cui hai fatto riferimento :

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

Se le tue chiavi sono abbastanza descrittive, non avere il testo completo non dovrebbe essere un problema.

Qualcosa del genere potrebbe anche essere utile:

Localization[ "<Location>.<NPC_name>.<Dialogue_text_key>" ];

4

I dati guidano i tuoi personaggi con script LUA o persino file XML. Quando interagisci con un NPC, prendi il file ad esso allegato, leggilo, aggiusta le variabili di gioco che potrebbero essere state attivate e produci la risposta valida.

Il più grande vantaggio nel farlo in questo modo è che puoi facilmente entrare e manipolare la finestra di dialogo, aggiungere nuovi caratteri, ecc. Inoltre eviti di confondere la tua base di codice con una logica speciale nella gestione di ogni singolo caso.


1
È Lua, non LUA. :)
RCIX,

2
L'ho fatto solo per te, amico. ;)
David McGraw,

4

Se usi XML, assicurati di creare un piccolo strumento per modificare il file XML. Altrimenti impazzirai.


Se non esiste già uno strumento per modificarlo, è inutile usarlo in primo luogo: crea anche il tuo formato!
o0 '.

3

Se hai un set abbastanza profondo di alberi di dialogo, usa ChatMapper . Hanno una versione gratuita con funzionalità complete e lo strumento ti consente di esportare i tuoi alberi di dialogo in XML. L'ho usato ed è un modo eccellente per visualizzare e organizzare complessi alberi di dialogo.


1

Se i tuoi dialoghi sono di qualche complessità, la cosa più importante di cui hai bisogno per l'implementazione dei dialoghi è un modo per capire la complessità della tua interazione. Raccomando un editor Node di qualche tipo per visualizzarlo, anche se non ho buoni sistemi aperti da raccomandare.


1

Penso che tu usi il tuo linguaggio di script per dirigere questo tipo di gioco (in caso contrario, dovresti). Quindi espandi anche il tuo script per gestire le finestre di dialogo.
Puoi lavorare con altre variabili di gioco durante la creazione della logica delle finestre di dialogo. I motori di gioco sono come Lego. Hai programmato solo mattoni e lo script li usa. Non importa se crei un interprete o un compilatore di script. Ma lo script è sempre utile.


0

L'automa semplice potrebbe fare:

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

Potrebbe assomigliare a questo:

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

Nel gioco trovi id e prova ad abbinare id e la condizione.

Devi modellare le condizioni e le azioni. Per oggetti, puntatori a funzioni, XML ...

Sarà utile anche un buon editor di dialoghi.

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.