AI tempur realistis untuk game 2D

gambar

Meskipun Close Quarters sebagian besar merupakan permainan multi-pemain, bot AI yang kompleks masih harus ada di dalamnya untuk membuat pemain tetap bermain saat koneksi internet buruk atau jika tidak ada pemain online lain. Selain itu, bot memainkan peran pendukung penting dalam beberapa mode permainan. Oleh karena itu, mereka harus berperilaku dapat dipercaya dan menunjukkan serangkaian perilaku kompleks, termasuk penggunaan tempat penampungan, penggunaan benda-benda pada waktu yang tepat, melewati sayap, melempar granat dan melarikan diri darinya.

Lingkungan dan batasan


Lingkungan permainan terdiri dari poligon. Sebagian besar poligon menghalangi pergerakan, jarak pandang, dan penembakan, tetapi ada juga poligon "rendah" yang hanya memblokir gerakan. Lingkungan tertutup rapat dengan rintangan dan tempat berlindung.

AI juga dibatasi oleh beberapa faktor teknis. Yang paling penting dari mereka: server tempat bot dijalankan, ketika ada beberapa pemain online, harus cepat bekerja pada VPS murah dengan setidaknya sepuluh bot. Selain itu, beban CPU harus tetap cukup rendah untuk memungkinkan beberapa contoh server pada VPS yang sama tanpa melebihi batas CPU, dan tanpa menyebabkan sanksi dari penyedia layanan VPS.


Gambar 1: lingkungan


Gambar 2: tampilan dari wajah pemain yang menghalangi pandangan (area abu-abu tidak terlihat olehnya)

Jala navigasi dan visibilitas, pencarian taktis jalan


Bot menggunakan jaring navigasi padat yang terdiri dari titik-titik diskrit. Mesh dihasilkan sebagai berikut: pertama, poligon yang membentuk lingkungan diperluas dan digabungkan . Node tambahan ditambahkan di dekat sudut-sudut, karena tempat-tempat ini kemungkinan besar merupakan posisi perlindungan yang sesuai. Ruang gerak yang dihasilkan kemudian triangulasi untuk menghasilkan mesh.


Gambar 3: jala navigasi

Karena bot harus melakukan pencarian taktis untuk jalur , jala navigasi harus berisi data visibilitas yang memungkinkan kita untuk dengan cepat memeriksa apakah node berisi tempat berlindung dari musuh yang dipilih. Oleh karena itu, setiap node berisi array 24 byte, yang masing-masing mewakili jarak perkiraan pra-dihitung antara node dan halangan terdekat yang menghalangi bidang pandang dalam arah tertentu.


Gambar 4: Data visibilitas disimpan dalam node (garis biru). Setiap baris mewakili nilai byte tunggal yang mendefinisikan visibilitas dalam arah yang diberikan.

Berkat data ini, Anda dapat mencari grafik menggunakan algoritma A *di jala navigasi, di mana node yang dapat dibuka untuk musuh yang dikenal menerima prioritas yang lebih rendah tanpa pemeriksaan garis pandang yang mahal. Untuk memeriksa apakah simpul tertentu terbuka untuk musuh, kami menentukan arah dan jarak dari simpul ke musuh, dan kemudian memeriksa apakah jarak ini kurang dari jarak yang disimpan dalam elemen array yang paling dekat dengan arah ini. Selain itu, kita dapat memeriksa apakah musuh melihat node. Kemudian kita dapat menerapkan faktor penalti pada biaya bergerak melalui node yang terbuka untuk musuh, dan jalur yang dihasilkan akan cenderung menghindari node tersebut.

Data visibilitas yang sama, selain menemukan jalur antara dua titik yang diberikan, dapat digunakan untuk tindakan "taktis" lainnya. Misalnya, bot mencari perlindungan dengan melakukan pencarian pertama kali dan berhenti segera setelah menemukan situs yang dilindungi. Tes garis pandang digunakan untuk memverifikasi bahwa situs tersebut benar-benar menyediakan perlindungan. Demikian pula, kita dapat membuat jalur serangan dari sisi-sisi dengan mencari A * untuk target; pada saat yang sama, denda tinggi dikenakan pada node terbuka dalam kerucut menembak target. Pencarian berhenti segera setelah kami mencapai simpul terbuka di luar kerucut ini. (Salah satu masalah dengan pendekatan ini adalah bahwa bot yang keluar dari ruang lingkup terus-menerus berusaha untuk lebih dekat ke target, dan karena itu tampaknya terlalu agresif; ini mungkin dapat diperbaiki dengan menetapkan heuristik A * jadisehingga bot tidak bergerak langsung ke target, tetapi ke setiap node yang terletak pada jarak yang dipilih dari target).

Perasaan dan memori bot


Agar bot berperilaku meyakinkan, mereka seharusnya tidak tampak seperti curang. Dengan kata lain, informasi yang bekerja dengan bot harus serupa dengan informasi yang dimiliki pemain. Sebagai contoh, musuh di belakang rintangan harus tidak terlihat oleh bot seperti itu tidak terlihat oleh pemain.


Ada dua cara di mana pemain dapat mendeteksi posisi musuh: dia dapat melihat musuh atau mendengar bagaimana dia bergerak, menembak, atau melakukan beberapa tindakan lain.

Setiap bot menyimpan daftar "fakta" yang diketahui tentang posisi dan arah pandangan musuh. Tanpa pembaruan, fakta-fakta ini dihapus setelah sepuluh detik. Fakta yang terkait dengan musuh tertentu diperbarui ketika bot dapat mendengar atau melihat musuh itu. Ketika bot mendengar musuh, untuk mensimulasikan ketidakpastian, posisi fakta yang sesuai bergeser dari posisi sebenarnya musuh dalam arah dan jarak acak, tergantung pada seberapa dekat bot itu terdengar (lihat video, 1:28).


Gambar 5: fakta (lingkaran merah muda) dalam memori bot

Pohon perilaku


Dalam versi Close Quarters sebelumnya, AI menggunakan STRIPS, solusi yang dipopulerkan oleh FEAR pada 2005. Dalam STRIPS, hubungan antara perilaku AI yang berbeda tidak ditentukan oleh programmer. Sebaliknya, setiap perilaku berisi daftar prasyarat dan hasil biner. Setiap bot memiliki keadaan masalah di dunia dan menggunakan pencarian di grafik A * untuk menemukan urutan perilaku pencapaiannya. Solusi ini bekerja dengan baik, tetapi saya merasa itu terlalu kompleks untuk aplikasi saya dan lebih cocok untuk AI, yang perlu mengembangkan rencana kompleks yang melibatkan banyak perilaku berbeda. Dalam kebanyakan kasus, saya sudah tahu keadaan di mana bot harus melakukan perilaku ini atau itu, jadi menggunakan A * untuk algoritma ini adalah pemborosan sumber daya CPU yang tidak perlu.

Oleh karena itu, bot sekarang menggunakan pohon keputusan dan perilaku sederhana. Dalam setiap ukuran, bot berputar di sekitar pohon, mulai dari akar, hingga mencapai perilaku. Jika perilaku ini sama seperti yang sudah dilakukan, maka bot melanjutkan perilaku ini. Jika tidak, bot memulai perilaku dan mulai menjalankannya.

Beberapa perilaku dapat "memblokir", yaitu mencegah bot dari berulang kali melintasi pohon sampai kondisi tertentu terpenuhi. Ini berguna, misalnya, untuk memastikan bahwa bot dapat menutup sebelum memutuskan untuk menyerang. Juga, perilaku dapat "membatalkan" satu sama lain, memaksa bot untuk memotong kembali pohon dan memulai kembali perilaku. Ini berguna, misalnya, ketika bot keluar dari granat, dan granat lain muncul yang membahayakan posisi pelarian yang dipilih.


Gambar 6: Pohon keputusan dan perilaku yang sedang digunakan

Beberapa perilaku sekunder dikodekan dalam perilaku lain yang lebih umum. Misalnya, jika bot mencoba menyerang musuh dan menemukan bahwa musuh tidak dalam posisi yang diharapkan, maka ia mengasumsikan di mana musuh bisa berada sekarang dan menghitung jalur serangan baru tanpa meninggalkan perilaku serangan.

Distribusi muatan


Setiap bot tidak harus diperbarui dalam setiap kerangka fisika, yaitu 40 kali per detik. Untuk mengurangi biaya CPU, setiap bot "berpikir" hanya 20 kali per detik (angka ini dapat dikurangi jika perlu). Oleh karena itu, hanya setengah dari bot diperbarui dalam setiap siklus fisika.

Bekerja dengan granat


Masalah serius adalah penggunaan granat oleh bot. Bekerja dengan granat jauh lebih sulit daripada menembak, karena granat dapat terbang dari dinding, memiliki radius kehancuran dan waktu untuk melempar. Untungnya, bot tidak diharuskan untuk menggunakan granat dengan sempurna, cukup persuasif.

Solusi tradisional untuk masalah ini adalah dengan pra-menghitung jalur granat di node navigasi , tetapi ketika diterapkan, beberapa detik ditambahkan ke waktu pemuatan masing-masing peta, yang bertentangan dengan tujuan saya: Perempat Tutup harus melempar pemain ke pertempuran dalam hitungan detik setelah memulai permainan.

Karena itu, bot mencari peluang untuk menggunakan granat, menghitung jalur granat dengan cepat. Dalam setiap siklus, bot penyerang memeriksa beberapa lintasan yang mungkin dalam arah tertentu dalam jarak 60 derajat dari arah target yang dipilih. Jika sebuah granat yang dilemparkan di sepanjang jalan yang terbukti dapat membunuh target dan target berada di luar jangkauan, bot melempar granat. Arah yang dicentang diulang di setiap jam AI.


Gambar 7: arah diperiksa oleh bot selama satu detik (garis merah muda pucat) dan lintasan yang diuji (lingkaran biru) di sepanjang arah yang dipilih dalam ukuran saat ini (garis merah muda cerah).

Yaitu, bot menggunakan granat kapan pun memungkinkan dan tidak pindah ke posisi tertentu untuk melempar granat. Namun, jalur yang dipilih oleh bot untuk menyerang musuh sering kali merupakan jalan yang masuk akal untuk melempar granat.

Kelemahan signifikan dari sistem semacam itu adalah, karena terbatasnya arah yang diperiksa, bot kehilangan kesempatan untuk melempar granat sehingga mereka memantul dari hambatan kecil. Yang paling mencolok, ini berada di sebelah ambang pintu, di mana bot biasanya tidak mengenali kemungkinan menggunakan granat. Masalah ini dapat diselesaikan dengan menguji beberapa arah dalam satu frame dan dengan demikian mengurangi sudut antara arah yang diperiksa dan yang berikutnya.

Gerakan ke perilaku yang lebih manusiawi


Masalah seperti itu dengan cepat menjadi jelas: bot terlalu cepat untuk menarik pelatuk, karena sangat sulit untuk mengalahkan mereka dalam pertempuran satu lawan satu. Waktu reaksi manusia rata-rata terhadap rangsangan visual adalah 250 milidetik, tetapi pada 20 kali per detik, waktu reaksi bot maksimum hanya 50 milidetik!

Untuk mengatasi masalah ini, saya sengaja menambahkan penundaan antara saat ketika bot mendapat kesempatan untuk menembak dan tembakan itu sendiri, sehingga waktu reaksinya sebanding dengan waktu reaksi seseorang.

Perbaikan lebih lanjut


Sistem yang disajikan di atas memberikan AI fundamental yang kuat, tetapi tidak memberikan peluang untuk perbaikan besar. Sebagai contoh, sekarang pemikiran spasial bot dibatasi oleh lingkungan terdekatnya, oleh karena itu, meskipun bot biasanya mencoba untuk mem-bypass musuh dari sayap, ia sering melewatkan rute yang mengitari rintangan besar. Selain itu, bot hanya secara kasar mengetahui tentang keberadaan rekan satu tim, jadi kadang-kadang mereka terakumulasi di satu tempat, alih-alih dibagi dan dilewati dari sisi-sisi.

All Articles