Bagaimana cara mengatur semua objek NPC / AI di server?

8

Saya sedang menulis MMO sederhana, dan saat ini memiliki arsitektur server-klien di tempat untuk beberapa pengguna untuk melihat satu sama lain dan dapat bergerak bersama-sama ... sekarang saatnya untuk menambahkan musuh.

Sungguh bertanya-tanya apakah ada yang punya tautan ke artikel yang membahas cara terbaik menangani ratusan objek NPC yang perlu dikelola di dunia. Saya telah melakukan pencarian dan tidak dapat menemukan banyak info tentang bagaimana hal ini biasanya dilakukan.

Dua metode penataan implementasi yang dapat saya pikirkan:

  1. Pegang semua objek NPC instantiated dalam daftar, dan buat NPC Thread melalui mereka secara berurutan dan lihat apakah masing-masing memiliki logika yang perlu diproses dan melakukan tindakan yang diperlukan. Saya tidak yakin apakah kinerja desain ini akan cukup?
  2. Sistem berbasis acara. Buat metode di kelas NPC yang memproses AI / Logika di atasnya, minta metode ini dipanggil ketika acara terkait diberi sinyal, baik pada timer untuk fungsi AI yang tidak berinteraksi (seperti mengembara), atau memberi sinyal acara secara eksternal dari paket handler (pemain bergerak di dekatnya, atau pemain menyerang dalam jangkauan).

Apakah salah satu dari pendekatan ini adalah cara yang benar? Apa metode lain untuk melakukan ini?

dgo
sumber

Jawaban:

5

Seperti biasa, arsitektur tergantung pada kebutuhan Anda. Berapa banyak gerombolan yang akan Anda miliki? Seberapa kompleks AI mereka? Apa reaksinya? Seberapa sering ia mengubah kondisinya? Jawab pertanyaan-pertanyaan ini, dan Anda akan memiliki pemahaman yang jauh lebih baik tentang apa yang Anda inginkan dan bagaimana mendapatkannya.

Secara umum, Anda ingin memiliki setidaknya semacam sistem acara. AI biasanya didefinisikan dalam hal peristiwa: "Ketika A terjadi, lakukan B"; dan jika Anda tidak memiliki acara dalam kode aktual, Anda harus entah bagaimana menerjemahkan definisi ini.

Dalam pengalaman saya, Anda bisa lolos dengan implementasi loop sederhana ketika Anda memiliki sedikit dan benar-benar gerombolan sederhana (bertentangan dengan apa yang tampaknya disarankan oleh jawaban lain). Misalnya, dalam permainan kami saat ini, kami memiliki ratusan contoh kecil dengan masing-masing memiliki 10 massa paling banyak. Dan gerombolan ini sangat bodoh; AI dari 99% dari mereka dapat dijelaskan dalam satu kalimat: "Apakah saya menyerang siapa pun? Jika tidak, serang pemain terdekat." Dalam hal ini, loop sederhana lebih dari cukup - dua kali per detik kami memeriksa target baru (dan beberapa hal lain untuk monster "pintar" yang langka), dan itu berhasil.

Namun, ketika Anda memiliki lebih banyak dan / atau massa yang lebih pintar, pendekatan naif berhenti bekerja. Agar AI bereaksi terhadap beberapa rangsangan, Anda harus menulis kode yang mendeteksi itu di dalam loop AI Anda. Sebagai contoh: misalkan massa Anda harus melakukan sesuatu "ketika ditabrak oleh pemain". Dengan pendekatan loop, tidak ada cara mudah untuk menentukan massa terkena. Ketika AI berjalan, Anda dapat memeriksa bahwa kesehatan massa berkurang sejak centang terakhir, atau bahwa massa saat ini ditargetkan oleh seseorang. Tetapi Anda tidak dapat mendeteksi hit aktual tanpa menggunakan peretasan, seperti menyimpan setiap info klik di suatu tempat bagi AI untuk mengaksesnya nanti.

Kedua, loop naif selalu berjalan, apa pun yang terjadi. Ketika Anda memiliki banyak gerombolan, Anda ingin AI berjalan secepat mungkin .. dan kode tercepat adalah kode yang tidak pernah berjalan sama sekali. Jika Anda memiliki gerombolan yang tidak aktif, Anda ingin mereka tidak menjalankan AI, atau hanya menjalankannya secara sporadis (seperti di, gerombolan gerombolan AI hanya boleh berjalan ketika ia memutuskan ke mana harus pergi berikutnya).

Dengan pendekatan berbasis peristiwa, Anda dapat meminta Anda subsistem lain mengirimkan peristiwa AI kapan pun nyaman, menghilangkan masalah "mendeteksi hit". Tentu saja, beberapa peristiwa masih memerlukan deteksi kode: contoh paling terkenal adalah peristiwa "pendekatan". Dan ketika Anda tidak menjalankan rutinitas AI Anda dalam satu lingkaran ketika tidak ada yang terjadi, Anda mendapatkan kinerja.

Anda juga dapat menggunakan pendekatan hybrid. Alih-alih menangani peristiwa AI dengan segera, Anda dapat memasukkannya ke dalam semacam antrian. Kemudian, ketika rutin AI berjalan (dalam satu lingkaran), ia menghapus peristiwa dari antrian ini dan menanganinya satu per satu. Dengan arsitektur ini, kinerja AI mungkin sedikit lebih lambat, tetapi lebih dapat diprediksi; juga, Anda dapat menjamin bahwa semua AI berjalan pada satu utas (yang mungkin agak rumit). Jenis loop ini juga dapat dengan mudah dicekik dengan melewatkan beberapa peristiwa (misalnya, setiap iterasi AI hanya menangani tiga peristiwa terbaru, membuang sisanya). Atau peristiwa mungkin diprioritaskan, dan yang kurang penting dibuang jika AI ditemukan tertinggal.

Secara keseluruhan, pendekatan "loop with events queue" mungkin yang paling fleksibel. Tetapi saya ingin menegaskan kembali: jangan hanya memilihnya secara membabi buta sebagai "yang terbaik". Pikirkan persyaratan Anda terlebih dahulu, dan beberapa pendekatan yang lebih sederhana mungkin menjadi lebih baik.

Sudahlah
sumber
dan hanya untuk menyelesaikan jawaban ini, Anda selalu dapat menambahkan massa atau menghapusnya dari lingkaran pemeriksaan Anda. misalnya. ketika tidak ada orang yang mengamati apa yang sedang dilakukan massa, tidak logis untuk melakukan semua hal yang akan dilakukan NPC pada saat itu. sehingga Anda dapat dengan mudah menyaring banyak massa dan hanya memeriksa apakah yang penting (biasanya yang cukup dekat dengan pemain) memerlukan pembaruan
Ali1S232
Apakah "gerombolan" sekelompok musuh atau musuh tunggal?
Richard Marskell - Drackir
"massa" adalah musuh tunggal. Istilah ini diciptakan oleh Richard Bartle dalam MUD1, dan merupakan kependekan dari "ponsel" - karena gerombolan bergerak di sekitar, sebagai lawan dari objek lain.
Nevermind
2

Itu akan tergantung pada jumlah musuh yang Anda miliki dan seberapa aktif mereka.

Jika Anda memiliki banyak musuh, tetapi mereka tidak melakukan sebagian besar waktu, sistem acara mungkin lebih baik. Jika Anda memiliki musuh yang biasanya melakukan sesuatu, perulangan mungkin berfungsi paling baik karena faktor kompleksitas sistem acara dan karena jika ada acara, mereka akan terus menembak.

Nate
sumber