Bagaimana cara menangani banyak utas cerita dalam game RPG?

26

Saya merancang sebuah game RPG yang memiliki banyak alur cerita, artinya, tergantung pada pilihan pengguna beberapa hal mungkin atau mungkin tidak terjadi, Anda dapat mencapai hal yang sama dalam beberapa cara, akhir ceritanya bisa berbeda dan seterusnya.

Saya menerapkan mesin pengambilan keputusan sederhana, yang berfungsi dengan baik tetapi memiliki satu cacat besar, pada saat Anda mengambil keputusan, kisah tersebut segera dipengaruhi oleh keputusan Anda, yang berarti bahwa Anda tidak dapat mengambil keputusan yang akan mempengaruhi Anda di masa depan yang jauh . Ini karena ceritanya terbuka seperti cabang dalam struktur pohon, dan selalu perlu tahu simpul mana yang berikutnya. Di bawah tenda, keputusan diimplementasikan menggunakan antrian: setiap simpul tahu tentang simpul sebelumnya dan simpul berikutnya (atau jika itu adalah simpul keputusan yang menunggu input pengguna untuk mengatur simpul berikutnya)

Saya melihat banyak permainan yang memiliki mesin keputusan yang kompleks, dan saya bertanya-tanya, bagaimana mereka dibuat? Apakah ada desain khusus yang membuat semuanya sangat mudah? Adakah yang melakukan sesuatu yang serupa dan dapat memberi saya petunjuk tentang cara mengatasi ini?

PEMBARUAN 1:

Aspek penting adalah mengatur agar kode cerita tetap independen, sehingga dapat dimanipulasi dari file eksternal. Saya berencana untuk menggunakan ini sebagai mesin sehingga bahkan pilihan yang mungkin harus datang dari file eksternal. Kode harus sepenuhnya abstrak.

Juga, saya tertarik pada solusi desain, cara yang bagus untuk melakukannya, bagaimana orang lain melakukannya atau melakukannya.

Valentin Radu
sumber
1
Ketika keputusan-keputusan penting dibuat, catatlah mereka dalam variabel yang dapat diakses secara global (sejumlah variabel ini akan lebih mudah dikelola). Variabel-variabel ini kemudian dapat direferensikan oleh bagian selanjutnya dari program game Anda untuk bertindak atau menampilkan hal-hal yang sesuai. Sebagai contoh, pemain memutuskan untuk menanam pohon kecil, dan kemudian pohon itu muncul sangat besar - jika mereka tidak menanam pohon itu, maka pohon itu tidak akan ada di sana pada titik yang sama di permainan.
Randolf Richardson
Ya, itulah yang awalnya saya lakukan, namun, saya perlu ini menjadi kode independen. Itu artinya, cerita dapat sepenuhnya dimanipulasi dari file eksternal. Jadi, saya harus menemukan cara untuk menggeneralisasi apa yang baru saja Anda katakan dan melakukannya sedemikian rupa sehingga saya tidak kehilangan kendali atas proyek (ada beberapa keputusan). Akan memperbarui pertanyaan. Terima kasih!
Valentin Radu
Jadi, untuk lebih spesifik, saya tidak dapat memeriksa if (isTree)atau menyimpan isTreeglobal var karena ceritanya mungkin atau mungkin tidak memiliki pilihan di dalamnya. Tau apa yang saya maksud? Ini lebih seperti mesin pilihan yang akan menyajikan banyak cerita.
Valentin Radu
Ini juga memiliki masalah lain, katakanlah jika pengguna memutuskan untuk menanam pohon yang kita atur isTree=true, tetapi kemudian, dia melakukan sesuatu yang lain, seperti, melawan teman sekolah, yang sebaliknya pergi dan memotong pohonnya ketika pohon itu masih muda karena dia mendapatkan pantatnya ditendang. Sekarang, kami memiliki 2 variabel yang mempengaruhi keberadaan pohon isTree==true' and didFightBrat == false`. Tau apa yang saya maksud? Dan rantai itu bisa berlangsung selamanya, keberadaan pohon itu dapat dipengaruhi oleh sejumlah faktor yang tidak diketahui. Tau apa yang saya maksud?
Valentin Radu
Kemudian simpan data itu dalam file di disk. Anda harus membuat dua subrutin untuk memuat dan menyimpan informasi, dan kemudian menggunakan rutinitas tersebut dari setiap bagian dari kode berdasarkan kebutuhan.
Randolf Richardson

Jawaban:

18

Anda juga bisa menggeneralisasi antrian menjadi grafik asiklik terarah (DAG). Anda dapat membaca tentang ini di Wikipedia. Pada dasarnya, setiap node dapat memiliki satu atau lebih node induk yang "tergantung". Siklus tidak diizinkan, yaitu jika A bergantung pada B, B tidak dapat bergantung pada A (secara langsung atau melalui rantai tidak langsung dari node lain).

Setiap node dalam keadaan "aktif" atau "tidak aktif", dan hanya diperbolehkan untuk menjadi aktif jika semua orang tuanya sudah aktif. Struktur grafik (simpul apa yang ada di sana dan bagaimana mereka terhubung) adalah bagian dari data permainan, tetapi keadaan aktif / tidak aktif adalah bagian dari data simpanan pemain.

Dengan begitu, Anda dapat memodelkan hal-hal seperti: ketika Anda menanam pohon, Anda menandai tugas "ditanamTree" sebagai aktif; kemudian, di kemudian hari dalam permainan, tugas lain "treeGrown" menamai "ditanam Pohon" dan beberapa simpul lainnya (bagian dari cerita) sebagai orang tuanya. Kemudian, "treeGrown" hanya aktif ketika pemain mencapai titik itu dalam cerita, dan juga "ditanamTree" aktif.

Anda dapat menyertakan fitur lain seperti simpul yang aktif jika salah satu dari orang tuanya mengaktifkan, atau simpul yang diaktifkan oleh satu orangtua dan dinonaktifkan oleh yang lain, dan seterusnya. Ini adalah kerangka kerja yang cukup umum untuk membuat cerita dengan banyak utas yang saling tergantung.

Nathan Reed
sumber
Jawaban yang sangat bagus, terima kasih. Ini sebenarnya memecahkan masalah lain yang saya miliki juga, seperti menyimpan kemajuan pengguna. Ini yang saya butuhkan.
Valentin Radu
@NathanReed Mengapa ini tidak bisa berulang? Menjadi asiklik biasanya bukan fitur, tetapi produk sampingan dari desain grafik. Saya tidak akan membuatnya dengan niat itu. Misalnya, bayangkan jika Anda ingin pohon Anda mengenali musim. Mereka pada dasarnya siklus, dan busur cerita Anda bisa identik tergantung pada pilihan yang tersedia selama satu musim.
Itu harus asiklik karena jika ada siklus, Anda masuk ke loop tak terbatas ketika mencoba mencari tahu apakah sebuah simpul pada siklus dapat aktif, karena Anda secara rekursif memeriksa semua leluhurnya, yang termasuk simpul itu sendiri. Jika Anda ingin memodelkan sesuatu seperti musim, saya tidak akan melakukannya dalam konteks grafik ini.
Nathan Reed
@NathanReed Ah, maaf, saya melewatkan bagian rekursif.
3

Dari apa yang saya mengerti, apa yang Anda inginkan bukan hanya mesin pengambilan keputusan, tetapi juga mesin aturan. Untuk setiap keputusan, Anda menjalankan sebagian aturan yang ditentukan oleh keputusan itu. Eksekusi aturan-aturan itu seringkali tergantung pada keadaan entitas tertentu seperti contoh pohon Anda.

Pada dasarnya, ketika pemain Anda membuat keputusan, Anda mencari keputusan itu, melaksanakan aturan, dan kemudian memberikan set keputusan berikutnya yang tersedia seperti biasa. Namun, aturan Anda bersifat dinamis karena beberapa di antaranya hanya akan dijalankan berdasarkan aturan lain yang sudah dijalankan.

Beberapa lagi di Wikipedia .

Dari judulnya When To Use Rule Engine (penekanan adalah milikku):

  • Masalahnya terlalu kompleks untuk kode tradisional.
  • Masalahnya mungkin tidak rumit, tetapi Anda tidak dapat melihat cara yang kuat untuk membangunnya.
  • Masalahnya adalah di luar solusi berbasis algoritma yang jelas.
  • Ini adalah masalah yang rumit untuk dipecahkan. Tidak ada solusi tradisional yang jelas atau masalahnya tidak sepenuhnya dipahami.
  • Logikanya sering berubah
  • Logikanya mungkin sederhana tetapi aturannya sering berubah. Dalam banyak organisasi, rilis perangkat lunak jarang terjadi dan aturan dapat membantu memberikan "kelincahan" yang dibutuhkan dan diharapkan dengan cara yang cukup aman.
  • Pakar domain dan analis bisnis sudah tersedia, tetapi tidak teknis.
  • Pakar domain sering memiliki banyak pengetahuan tentang aturan dan proses bisnis. Mereka biasanya nonteknis, tetapi bisa sangat logis. Aturan dapat memungkinkan mereka untuk mengekspresikan logika dengan istilah mereka sendiri. Tentu saja, mereka masih harus berpikir kritis dan mampu berpikir logis. Banyak orang di posisi nonteknis tidak memiliki pelatihan logika formal, jadi berhati-hatilah dan bekerja bersama mereka. Dengan mengkodifikasi pengetahuan bisnis dalam aturan, Anda akan sering mengekspos lubang-lubang dalam cara aturan dan proses bisnis saat ini dipahami.

Satu hal yang perlu diperhatikan adalah bahwa kadang-kadang mesin aturan paling baik diimplementasikan menggunakan domain khusus "bahasa" yang disederhanakan, atau sesuatu seperti YAML. Saya tidak akan menyarankan XML.


sumber
1

Anda harus mempertimbangkan bahwa suatu peristiwa tidak murni berdasarkan keputusan pengguna. Seperti yang Anda catat, beberapa peristiwa harus ditambahkan jika ketika serangkaian keputusan diambil dan kemudian sesuatu yang lain ditambahkan (seperti dua hari setelahnya).

Apa yang saya pikir Anda butuhkan adalah cara untuk memodelkan acara dan cara memicunya. Sementara yang pertama lebih terikat pada kasus spesifik Anda, yang terakhir dapat dimodelkan oleh mesin negara hierarkis (HSM) yang secara langsung atau tidak langsung memicu acara Anda.

Perlu diingat bahwa mesin negara menderita Kutukan dimensi yang hanya dikurangi oleh struktur hierarkis. Segera Anda akan memahami bahwa Anda perlu memodelkan makna status yang kompleks menggunakan HMS tetapi juga menyediakan cara untuk menanyakannya.

Dalam skenario ini Anda memiliki acara dasar (keputusan pengguna, waktu, perubahan cuaca dan sebagainya) yang diproses oleh HSM dan oleh panggilan balik acara dasar. HSM menyediakan model untuk "memori" dan panggilan balik menyediakan cara untuk menggambarkan bagaimana memori itu harus digunakan untuk menghitung konsekuensi dari urutan keputusan / peristiwa eksternal.

Anda juga dapat menggunakan kamus (atau beberapa struktur koleksi lain) HMS, satu untuk setiap "aspek" status yang harus Anda hitung. Contohnya adalah menggunakan acara HMS terkait dan satu untuk keputusan yang diambil panggilan balik untuk memicu peristiwa.

Semua infrastruktur ini melayani tujuan untuk meniru perilaku Master Penjara Bawah Tanah manusia: ia umumnya mengambil catatan mental tentang situasi saat ini (HMS ["eksternal"]) karena keputusan pemain dan kondisi lingkungan; ketika sesuatu menambahkan, ia dapat mengambil keputusan menggunakan catatan mentalnya dan merekam beberapa status strategi internal juga (HSM ["internal"]) untuk menghindari bereaksi dengan cara yang sama jika beberapa situasi menambahkan misalnya.

FxIII
sumber