Bagaimana cara kerja pohon dialog?

20

Yaitu, apa yang terhubung dengan apa dan bagaimana bergerak di antara garis-garis pembicaraan ketika sub-percakapan berakhir?

Jika Anda memiliki contoh pohon dialog dasar di C #, silakan kirim.

pengguna1306322
sumber
Saya pikir akan lebih baik memiliki dialog-treetag.
user1306322
Meminta sampel kode biasanya tidak disukai.
MichaelHouse
Jika ada beberapa contoh kode pohon dialog 101 yang layak dibagikan, tidak ada salahnya.
user1306322
Masalahnya adalah bahwa situs ini adalah tentang mendapatkan jawaban yang benar atas pertanyaan. Ini bukan untuk mengumpulkan sampel kode.
MichaelHouse
Itu sebabnya kalimat dimulai dengan "jika". Tapi yang saya minta adalah penjelasan tentang bagaimana garis dialog terhubung satu sama lain dengan cara yang dapat diterjemahkan secara efisien ke kode. Lagipula saya akan menuliskannya dalam C #.
user1306322

Jawaban:

24

Nama "pohon dialog" agak menyesatkan - biasanya grafik berarah sederhana , bukan hanya pohon . Struktur data dasar dari grafik tersebut biasanya terdiri dari semacam "data" untuk node, yang mewakili titik-titik yang kita bahas dalam percakapan, dan tautan dari mereka ke node lain, yang mewakili apa yang dikatakan dan dilakukan oleh para peserta dan secara opsional memiliki persyaratan untuk membatasi visibilitas atau skrip mereka untuk melakukan berbagai tindakan tambahan. Biasanya salah satu node adalah simpul awal default (label khas untuk itu adalah "ROOT", "MULAI" dan "SALAM"), dan node yang tidak memiliki tautan valid yang mengarah dari mereka mengakhiri pembicaraan.

Dalam kebanyakan kasus, grafik direpresentasikan dalam memori sebagai daftar Nodestruktur data, masing-masing memiliki setidaknya ID dan daftar Linkstruktur data 0..n . Daftar ini dapat bersifat lokal untuk NPC atau yang global; kasus kedua lebih disukai jika Anda memiliki banyak NPC generik yang dapat diajak bicara untuk mendapatkan informasi, tetapi tidak menawarkan percakapan khusus sendiri. Sistem itu sendiri menemukan simpul percakapan awal untuk NPC, mengingat ID-nya sebagai ID percakapan saat ini, menyajikan tautan yang saat ini valid untuk pemain pilih (atau "[akhiri percakapan]" jika tidak ada tautan yang valid) dan tunggu memasukkan. Ketika pemain memilih tautan, garis dialog terkait ditampilkan dan semua skrip terkait dijalankan.

Alih-alih memiliki aturan dan ketentuan yang rumit pada tautan, Anda dapat menggunakan variabel boolean "valid" sederhana, yang kemudian dapat diubah dari skrip tautan percakapan lain (termasuk yang default dari simpul awal) atau dari luar mekanisme. Secara umum, pendekatan ini lebih sederhana tetapi hanya cocok untuk game dengan percakapan yang sangat sedikit, karena ini menggerakkan logika "Kapan respons ini mungkin?" jauh dari data respons itu sendiri.


Perhatikan bahwa struktur yang saya jelaskan di sini sedikit berbeda dari Byte56 di mana node tidak perlu memiliki garis dialog; tautannya dapat memiliki semuanya. Dalam varian paling dasar, ini diterjemahkan ke struktur berikut.

masukkan deskripsi gambar di sini

Martin Sojka
sumber
+1 Untuk menyebutkan aturan dan ketentuan pada tautan, grafik berarah sederhana seringkali tidak cukup, dan banyak hal menjadi rumit ketika Anda mulai membutuhkannya.
Laurent Couvidou
+1 Saya suka struktur itu dengan lebih baik. Padahal, saya tidak akan merekomendasikan ini sebagai pass pertama. Saya akan mulai dengan sesuatu yang lebih sederhana. Tentunya target yang lebih baik untuk menembak.
MichaelHouse
+1 Untuk jawaban yang sangat terperinci. Ini mungkin berguna bagi saya nanti.
Marton
Gambar ini sangat membantu saya, tetapi saya harus bertanya-tanya mengapa DialogueLine terpisah dari Tautan? Tidakkah setiap tautan memiliki teks responsnya sendiri? Dan kemana teks NPC akan pergi? Apakah tidak masuk akal untuk memilikinya di node?
Kyle Baran
@Danjen Dalam struktur ini, sebuah Tautan dapat memiliki beberapa DialogueLines, mungkin dari karakter yang berbeda, hingga pilihan dialog berikutnya muncul. Di sinilah letak teks NPC. Ketika garis berulang, Tautan yang berbeda dapat membagikan DialogueLines, mungkin menyusun ulang mereka dalam daftar (Vektor), mengganti bagian-bagiannya dengan garis yang berbeda, menambahkan kata seru dan sebagainya.
Martin Sojka
16

Pohon dialog dibuat dengan struktur grafik terarah .

masukkan deskripsi gambar di sini

Grafik dilintasi berdasarkan keputusan dialog yang dibuat pemain. Opsi dialog yang disediakan untuk pengguna berasal dari tepi yang menentukan jalur ke node dialog lain.

Grafik yang diarahkan adalah struktur data dasar. Mereka dapat dengan mudah diimplementasikan dan Anda mungkin ingin menerapkannya sendiri. Karena Anda ingin menyesuaikan grafik dengan kebutuhan dialog Anda.

Beberapa node mungkin perlu memiliki kondisi khusus yang terpenuhi untuk muncul. Sebagai contoh, pemain akan membutuhkan keterampilan berbicara di atas X. Atau pemain harus menyelesaikan misi Z sebelum mereka dapat melanjutkan satu cabang dialog. Atau mereka perlu menanyakan sesuatu 4 kali sebelum NPC mendiskusikannya dengan mereka. Fitur-fitur ini akan disesuaikan untuk gim Anda. Tetapi perlu disebutkan ketika Anda mengimplementasikan node dan edge traversal. Tentu saja selalu yang terbaik untuk memulai dengan bentuk yang paling sederhana dan membangun dari sana.

MichaelHouse
sumber
Saya tidak tahu apa yang harus dilakukan dalam kasus-kasus seperti "Newton-trouble" dalam gambar ini. Seperti cara mengatur urutan baris-baris tersebut dalam kode tanpa mengulanginya.
user1306322
Anda akan sering menemukan bahwa dialog dapat diulang. Biasanya hanya ditandai dengan beberapa cara sehingga pengguna tahu mereka sudah memilih jalur dialog itu. Anda dapat menempatkan bendera di tepi Anda yang menunjukkan apakah mereka telah dipilih sebelumnya. Jadi terserah kepada Anda untuk mengizinkan pengguna untuk memilihnya lagi (untuk menyegarkan diri) atau tidak menunjukkannya.
MichaelHouse
1
Biasanya tidak akan dilakukan dengan urutan baris kode, tetapi melalui referensi dalam struktur data.
Kylotan
7

Saya telah membangun sistem dialogtree sederhana: http://iki.fi/sol/d3/ "engine" itu sendiri saat ini jelas c, tetapi data yang dihasilkan oleh editor cukup sederhana untuk digunakan dalam bahasa apa pun. Alat ini menghasilkan XML, JSON dan format biner khusus.

Konsep utamanya cukup sederhana:

Anda berada dalam labirin lorong-lorong kecil yang berkelok-kelok, semuanya sama

Setiap node (yang saya sebut "kartu", seperti analog di atas) dari dialog terdiri dari teks pertanyaan dan nol atau lebih jawaban. Setiap jawaban mengarah ke kartu lain.

Ada juga sistem tag di mana jawaban tertentu ditampilkan kepada pengguna hanya jika tag diatur (atau tag tidak disetel). Memasukkan set kartu (atau unsets) tag yang ditentukan.

Ini adalah hampir semua yang perlu dilakukan seseorang dalam segala jenis dialog dalam sebuah game. "Teks pertanyaan" dapat berupa teks biasa, atau dapat berupa skrip untuk mendorong animasi atau yang lainnya.

Jari Komppa
sumber
4

Anda dapat menggunakan TreeSharp dan pohon perilaku untuk memodelkan sistem dialog. TreeSharp adalah perpustakaan yang menyediakan implementasi pohon perilaku sederhana. IA bot untuk wow selesai dengan ini, jadi sudah matang ... :)

Implementasi saya memiliki simpul yang memungkinkan memilih antara jawaban, dan setiap jawaban dapat digabungkan ke dialog lain atau tindakan, atau urutan tindakan, atau simpul yang memungkinkan pergi ke dialog lain ... atau apa yang Anda inginkan ...

Saya telah menggunakan editor Jenius untuk membuatnya secara visual ... tetapi pada akhirnya menghasilkan kode c # berdasarkan treesharp ...

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

Blau
sumber
2

Anda ingin grafik terarah (mungkin bersiklus).

Anda akan memodelkan simpul sebagai objek, dan semua panah keluar dalam simpul grafik dimodelkan sebagai objek yang terpisah juga. Node memiliki daftar panah keluar, dan setiap objek "panah" memiliki teks untuk ditampilkan dan referensi ke tujuan. Tidak yakin, tapi saya pikir dalam objek C # selalu direferensikan, jadi Anda hanya membuat objek pertama, dan kemudian ketika Anda membuat objek panah, tancapkan objek yang sama ke bidang tujuan dua panah. (Dalam C ++ Anda akan menggunakan referensi atau tipe pointer, Node & atau Node *)

Untuk memuat hal-hal seperti ini dari disk, biasanya memberikan setiap node nomor ID unik, lalu memuat semua node ke dalam array di mana indeks adalah nomor unik itu. Kemudian panah diserialisasi dengan menuliskan nomornya, bukan objek yang sebenarnya keluar.

Saat Anda memuat panah, Anda menggunakan array dan ID untuk mendapatkan referensi ke simpul yang ditunjuknya. Jika Anda menulis objek dua kali, Anda akan mendapatkan dua objek terpisah yang hanya terlihat identik, yang mungkin bukan yang Anda inginkan.

Memproses pohon dialog menjadi sangat sederhana. Anda cukup meletakkan simpul root dalam sebuah currentNodevariabel, menampilkan semuanya entah bagaimana, lalu ketika suatu pilihan dibuat, setel rootNodeke tujuan panah. Dalam pseudocode:

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

Saya baru-baru ini harus mengembangkan sesuatu seperti ini menggunakan Node, dan memilih struktur file teks yang sangat dasar untuk mewakili grafik diarahkan dari node percakapan.

Anda dapat melihat kode dan format teks yang dihasilkan di:

https://github.com/scottbw/dialoguejs

Ini tidak mendukung kondisi atau pemicu peristiwa (belum), tetapi mungkin cukup sederhana untuk memulai dengan banyak pengembang game.

(Kode itu sendiri di GPL, btw)

Scott Wilson
sumber
Pertanyaannya menanyakan C #.
Seth Battin
Doh - maaf soal itu.
Scott Wilson