Bagaimana saya bisa menerapkan pohon dialog ke dalam game saya?

51

Apa cara terbaik untuk menerapkan sistem pohon dialog di game saya? Saya ingin NPC untuk memberikan pemain tanggapan yang berbeda, beberapa yang hanya dapat muncul ketika Player memiliki item atau peristiwa sebelumnya telah terjadi.

Bryan Denny
sumber
2
BOUNTY terutama untuk ide-ide bagus tentang bagaimana menangani terjemahan frasa pemicu dan teks NPC. Sehingga NPC dapat memahami dan berbicara berbagai bahasa tergantung pada pemain yang memulai percakapan. Bahkan dengan pendekatan building block di gamedev.stackexchange.com/questions/31/… sepertinya bukan ide yang baik untuk memiliki logika di dalam repositori teks. Tetapi membaginya membuat lebih sulit untuk memahami kode.
Hendrik Brummermann

Jawaban:

17

Pohon Dialog harus dilakukan menggunakan XML. Anda menyimpan kondisi untuk respons dan respons di pohon bersarang dengan referensi ke file skrip jika Anda perlu melakukan sesuatu yang lebih kompleks.

Anda harus memisahkan skrip dan dialog, terutama jika Anda sedang membuat RPG yang memiliki percakapan metrik ton. Anda kemudian dapat menggunakan perpustakaan seperti simpleXML untuk membaca file XML.

Ada pertanyaan serupa di SO dengan contoh: https://stackoverflow.com/questions/372915/game-logic-in-xml-files

Rubah
sumber
+1 untuk XML. Jauh lebih baik daripada menanamkan dalam kode itu sendiri, memungkinkan untuk perubahan tanpa mengkompilasi ulang kode, dan merupakan format standar yang dapat dibaca oleh beberapa editor yang kuat.
AttackingHobo
34
XML hanyalah format (dan, IMO, yang buruk). Sungguh apa yang dikatakan oleh jawaban ini adalah, "Buat bahasa domain kecil yang berisi logika dan aliran dasar, tetapi terutama terdiri dari dialog Anda, dan uraikan." Secara umum, saya setuju dengan jawaban ini.
Ipsquiggle
5
Tepatnya, XML hanyalah wadahnya, Anda juga bisa (dan pasti lebih bisa dibaca oleh manusia dan bisa diedit oleh manusia) mengimplementasikan ini menggunakan Lua atau bahasa skrip lain.
LearnCocos2D
4
XML mahal untuk diurai dan membutuhkan banyak memori. Tidak apa-apa untuk menggunakannya sebagai format penyimpanan, tapi saya akan menulis utilitas yang mengubah pohon dialog menjadi format biner yang digunakan saat runtime. Jika Anda menggunakan PC dan tidak peduli dengan penggunaan memori Anda, itu mungkin baik-baik saja, tetapi pada platform lain, biaya memori akan membebani Anda.
BigSandwich
1
-1 untuk XML. Saya setuju dengan @Ipsquiggle dan @BigSandwich
o0 '.
20

Saya akan melihat ke dalam bahasa scripting embedding seperti lua atau ruby ​​dan coding interaksi dialog di dalamnya.

Dengan demikian skrip dialog dapat terlihat seperti:

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

Ini juga berfungsi dengan baik untuk mengkode AI dan hal-hal sederhana lainnya yang berguna untuk mengubah selama waktu berjalan. Anda bahkan dapat menambahkan editor yang ada di dalam aplikasi Anda yang dapat dipanggil saat berjalan dalam debug (atau sebagai Telur Paskah).

BarrettJ
sumber
1
Saya lebih suka ini ke XML lurus karena Anda dapat menambahkan logika. Tetapi saya akan mengatakan teks itu sendiri mungkin harus dalam XML daripada dalam kode. (lebih mudah untuk mengedit, melokalisasi ke bahasa lain, dll).
Iain
jika Anda memerlukan lokalisasi / edit lebih mudah Anda dapat membungkus teks dalam suatu fungsi yang menulis teks terlampir ke file terpisah seperti fungsi tr (QString) / makro di Qt. pepper.troll.no/s60prereleases/doc/linguist-hellotr.html
Nailer
apa yang membuat Anda berhenti menggunakan atribut atau tag tambahan di xml untuk mensimulasikan logika di sini?
lathomas64
16

Dalam game Stendhal kami menggunakan mesin negara terbatas untuk mengimplementasikan NPC.

Diagram berikut menunjukkan sedikit contoh dari cara menulis tutorial pencarian .

FSM dengan IDLE negara, MENGHADIRI dan QUEST_OFFERED

Pada awalnya, NPC dalam keadaan IDLE dan mungkin berjalan-jalan. Seorang pemain dapat memulai percakapan dengan mengatakan "hai" dan NPC akan pergi ke negara HADIR. Dalam kondisi ini ia menjawab pertanyaan tentang "pekerjaannya" dan menawarkan beberapa permainan "bantuan". Pemain mungkin meminta pencarian dan NPC akan menyatakan QUEST_OFFERED menunggu pemain untuk menerima ("ya") atau menolak ("tidak") itu.

Kami telah menetapkan serangkaian kondisi yang dapat dilampirkan ke transisi. Misalnya menyelesaikan sebuah pencarian hanya dimungkinkan jika PlayerHasItemWithHimCondition terpenuhi.

Setelah transisi dieksekusi, NPC dapat mengatakan beberapa teks dan / atau menjalankan suatu tindakan. Mirip dengan kondisi, kami telah menetapkan serangkaian tindakan yang dapat digunakan kembali seperti EquipItemAction yang digunakan untuk memberikan hadiah pencarian kepada pemain.

Beberapa kondisi dapat digabungkan menggunakan AndCondition , OrCondition dan NotCondition . Biasanya ada sejumlah tindakan yang harus dilakukan pada penyelesaian pencarian, sehingga ada kelas MultipleActions juga.

Sementara implementasi aktual di Stendhal tidak mudah diterjemahkan dalam bahasa (manusia) lainnya, saya pikir konsep umum itu baik.

Hendrik Brummermann
sumber
5

Anda dapat melihat alat Dlgedit dari mesin RPG Open Source Adonthell . Ini sangat canggih dan harus berisi semua yang Anda butuhkan (termasuk sumber;))

Koonsolo
sumber
5

Saya pikir untuk menambahkan terjemahan, Anda masih bisa menggunakan XML untuk logika seperti yang dinyatakan di atas . Ketika Anda masuk ke dalam jenis kompleksitas itu, Anda harus menulis alat dialog Anda sendiri. Teks dialog Anda akan disimpan sebagai kunci ke basis data yang dapat Anda tukarkan tergantung pada bahasa yang ingin Anda tampilkan.

Misalnya, Anda dapat memiliki:

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

Anda kemudian akan memiliki renderer teks pencarian menggantikan "Localize.FixMyCar" dengan teks yang diterjemahkan dengan tepat.

Alat Anda akan menampilkan apa yang akan dilihat pemain dalam bahasa yang dapat dipilih di samping XML mentah yang dapat diedit.

Demikian pula Anda dapat menggunakan sesuatu seperti ini dari contoh yang Anda referensikan :

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

Jika kunci Anda cukup deskriptif, tidak memiliki teks lengkap seharusnya tidak menjadi masalah.

Sesuatu seperti ini bisa bermanfaat juga:

Localization[ "<Location>.<NPC_name>.<Dialogue_text_key>" ];
toddw
sumber
4

Data mengarahkan karakter Anda dengan skrip LUA atau bahkan file XML. Saat Anda berinteraksi dengan NPC, ambil file yang terlampir padanya, baca, sesuaikan untuk variabel game apa pun yang mungkin telah dipicu, dan produkkan respons yang valid.

Keuntungan terbesar dari melakukannya dengan cara ini adalah Anda dapat dengan mudah masuk dan memanipulasi dialog, menambahkan karakter baru, dll. Anda juga menghindari memasukkan basis kode Anda dengan logika khusus dalam menangani setiap kasus.

David McGraw
sumber
1
Itu Lua, bukan LUA. :)
RCIX
2
Aku melakukannya hanya untukmu, kawan. ;)
David McGraw
4

Jika Anda menggunakan XML, pastikan Anda membuat alat kecil untuk mengedit file XML. Anda akan menjadi gila jika tidak.

zooropa
sumber
Jika sudah tidak ada alat untuk mengeditnya, maka tidak ada gunanya untuk menggunakannya di tempat pertama: buat format Anda sendiri juga!
o0 '.
3

Jika Anda memiliki kumpulan pohon dialog yang cukup dalam, gunakan ChatMapper . Mereka memiliki versi gratis fitur lengkap dan alat ini memungkinkan Anda untuk mengekspor pohon dialog Anda ke XML. Saya telah menggunakannya dan ini adalah cara terbaik untuk memvisualisasikan dan mengatur pohon dialog yang kompleks.


sumber
1

Jika dialog Anda memiliki kompleksitas, hal terpenting yang Anda perlukan untuk implementasi dialog adalah cara untuk memahami kompleksitas interaksi Anda. Saya merekomendasikan editor Node semacam untuk memvisualisasikan ini, meskipun saya tidak memiliki sistem terbuka yang baik untuk merekomendasikan.

Aaron Brady
sumber
1

Saya pikir, bahwa Anda menggunakan bahasa skrip Anda sendiri untuk mengarahkan jenis permainan ini (jika tidak, Anda harus). Lalu perluas skrip Anda untuk penanganan dialog juga.
Anda dapat bekerja dengan variabel game lainnya selama pembuatan logika dialog. Mesin permainan seperti Lego. Anda hanya memprogram batu bata dan skrip menggunakannya. Tidak masalah jika Anda membuat penerjemah atau kompiler skrip. Tapi skrip selalu berguna.

samboush
sumber
0

Otomat sederhana mungkin dilakukan:

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

Mungkin terlihat seperti ini:

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

Dalam permainan, Anda menemukan id dan mencoba mencocokkan id dan kondisinya.

Anda perlu memodelkan kondisi dan tindakan. Berdasarkan objek, pointer fungsi, XML ...

Editor dialog yang baik juga akan berguna.

pengguna712092
sumber