Bagaimana agen AI mengakses informasi tentang lingkungan mereka?


9

Ini mungkin semacam pertanyaan sepele, tapi saya kesulitan memahami ini. Akan sangat menghargai bantuan Anda.

Dalam pengembangan game menggunakan desain berorientasi objek, saya ingin memahami bagaimana agen AI mengakses informasi yang mereka butuhkan dari dunia game untuk melakukan tindakan mereka.

Seperti yang kita semua tahu, dalam game sangat sering agen AI perlu 'memahami lingkungan mereka' dan bertindak sesuai dengan apa yang terjadi di sekitar mereka. Misalnya, agen mungkin diprogram untuk mengejar pemain jika dia cukup dekat, menghindari rintangan saat bergerak (menggunakan perilaku kemudi Menghindari Rintangan), dll.

Masalah saya adalah saya tidak yakin bagaimana melakukannya. Bagaimana agen AI dapat mengakses informasi yang dibutuhkannya tentang dunia game?

Salah satu pendekatan yang mungkin adalah bahwa agen hanya meminta informasi yang mereka butuhkan langsung dari dunia game.

Ada kelas yang disebut GameWorld. Ini menangani logika game penting (loop game, deteksi tabrakan, dll), dan juga memegang referensi ke semua entitas dalam game.

Saya bisa membuat kelas ini menjadi Singleton. Ketika seorang agen membutuhkan informasi dari dunia game, ia hanya mendapatkannya langsung dari instance GameWorld.

Misalnya, agen mungkin diprogram ke Seekpemain ketika dia dekat. Untuk melakukan ini, agen harus mendapatkan posisi pemain. Jadi itu hanya dapat meminta langsung: GameWorld.instance().getPlayerPosition().

Agen juga bisa mendapatkan daftar semua entitas dalam game, dan menganalisisnya untuk kebutuhannya (untuk mencari tahu entitas apa yang dekat, atau apa pun): GameWorld.instance().getEntityList()

Ini adalah pendekatan yang paling sederhana: agen menghubungi kelas GameWorld secara langsung dan mendapatkan informasi yang mereka butuhkan. Namun, ini adalah satu-satunya pendekatan yang saya tahu. apakah ada yang lebih baik?

Bagaimana pengembang game yang berpengalaman mendesain ini? Apakah pendekatan "dapatkan daftar semua entitas dan cari apa pun yang Anda butuhkan" naif? Pendekatan dan mekanisme apa yang ada untuk memungkinkan agen AI mengakses informasi yang mereka butuhkan untuk melakukan tindakan mereka?


Jika Anda memiliki akses ke langganan GDCVault, ada pembicaraan yang sangat baik pada tahun 2013 yang disebut "Menciptakan AI untuk Hidup, Bernafas Dunia Hitman Absolution" yang masuk ke model pengetahuan AI mereka secara rinci.
DMGregory

Jawaban:


5

Apa yang Anda gambarkan adalah model "tarikan" klasik yang menanyakan dunia. Sebagian besar waktu, ini bekerja dengan cukup baik, terutama untuk game dengan AI dasar (yang paling banyak). Namun, ada beberapa poin yang harus Anda pertimbangkan yang mungkin merugikan:

  • Anda mungkin ingin menggandakan buffer. Lihat pola pemrograman game pada subjek . Dengan selalu meminta data langsung dari dunia, Anda bisa mendapatkan kondisi ras yang aneh di mana hasilnya tergantung pada urutan AI dipanggil. Apakah ini penting untuk gim Anda, Anda harus menentukannya. Salah satu hasil yang mungkin adalah bahwa itu bias permainan untuk siapa pun yang pergi "pertama" atau "terakhir," membuat multiplayer tidak adil.

  • Seringkali bisa jauh lebih efisien untuk permintaan batch, terutama untuk struktur data tertentu. Di sini Anda dapat membuat setiap agen AI yang ingin mencari kendala membuat "objek permintaan" dan mendaftarkannya dengan kendala tunggal pusat. Kemudian, sebelum loop AI utama, semua kueri dijalankan terhadap struktur data, yang membuat struktur data hambatan lebih banyak di cache. Kemudian selama bagian AI, setiap agen memproses hasil kueri itu, tetapi tidak diizinkan untuk membuat lebih langsung. Di akhir bingkai, objek AI memperbarui kueri dengan lokasi baru mereka, atau menambah atau menghapusnya. Ini mirip dengan desain berorientasi data .

    Perhatikan bahwa ini pada dasarnya melakukan buffering ganda dengan menyimpan hasil query dalam buffer. Ini juga mengharuskan Anda untuk mengantisipasi apakah Anda perlu melakukan query frame sebelumnya. Ini adalah model "push", karena agen menyatakan jenis pembaruan apa yang mereka minati (dengan membuat objek kueri yang sesuai), dan pembaruan ini didorong kepada mereka. Catatan Anda juga dapat meminta objek kueri berisi panggilan balik, daripada menyimpan semua hasil untuk sebuah bingkai.

  • Akhirnya, Anda mungkin ingin menggunakan antarmuka atau komponen untuk objek yang dapat dicari daripada warisan, yang didokumentasikan dengan baik di tempat lain. Mengulang daftar Entitiespemeriksaan instanceOfmungkin resep untuk kode yang cukup rapuh, saat Anda menginginkan keduanya StaticObjectdan MovingObjectmenjadi Healable. (kecuali instanceOfberfungsi untuk antarmuka dalam bahasa pilihan Anda.)


5

Karena harganya mahal, kinerja seringkali menjadi faktor pendorong dalam arsitektur.

Untuk meredakan kekhawatiran Anda tentang model akses data, mari kita pertimbangkan beberapa contoh AI yang berbeda baik di dalam maupun di luar industri game, bekerja dari apa yang paling jauh dari navigasi manusia ke apa yang paling akrab bagi kita.

(Setiap contoh mengasumsikan satu, pembaruan logika global.)

  • A * jalur terpendekSetiap AI menghitung status peta untuk tujuan merintis jalan. A * mensyaratkan bahwa setiap AI sudah mengetahui seluruh lingkungan (lokal) di mana ia harus mencari, jadi kita harus memberikan informasi tentang hambatan peta dan ruang (seringkali array boolean 2D). A * adalah bentuk khusus dari Algoritma Dijkstra, algoritma pencarian grafik jalur terbuka terpendek; pendekatan tersebut mengembalikan daftar yang mewakili jalur, dan pada setiap langkah, AI cukup memilih simpul berikutnya dalam daftar ini untuk melangkah, sampai mencapai tujuannya atau perhitungan ulang diperlukan (misalnya karena perubahan peta hambatan). Tanpa pengetahuan ini, tidak ada jalan terpendek yang realistis dapat ditemukan. A * adalah alasan mengapa AI dalam game RTS selalu tahu cara untuk mendapatkan dari titik A ke titik B - jika ada jalur. Ini akan menghitung ulang jalur terpendek untuk setiap AI individu, karena validitas jalur didasarkan pada posisi AI yang telah pindah (dan berpotensi memblokir jalur tertentu) sebelumnya. Proses berulang dimana A * menghitung nilai sel selama pathfinding adalah salah satu konvergensi matematis. Bisa dikatakan hasil akhirnya menyerupai indera penciuman yang dicampur dengan indra penglihatan, tetapi dalam semua itu agak asing bagi pola pikir kita.

  • Difusi kolaboratif Juga ditemukan dalam permainan, ini paling mirip dengan indra penciuman, berdasarkan difusi gas dan partikulat. CD memecahkan masalah pemrosesan ulang yang mahal yang ditemukan di A *: Alih-alih, keadaan peta tunggal disimpan, diproses sekali per pembaruan untuk semua AI, dan hasilnya kemudian diakses oleh masing-masing AI secara bergantian, agar ia dapat bergerak masing-masing . Tidak ada lagi jalur tunggal (daftar sel) yang dikembalikan oleh algoritma pencarian; alih-alih, setiap AI akan memeriksa peta setelah diproses, dan pindah ke sel yang bersebelahan mana yang memiliki nilai tertinggi. Ini disebut mendaki bukit . Namun demikian, tahap pemrosesan peta harus sudah dilakukanmemiliki akses sebelumnya ke informasi peta, yang di sini juga berisi lokasi semua badan AI. Oleh karena itu, petakan rujukan AI, dan kemudian rujukan AI peta.

  • Visi komputer dan siaran sinar + lintasan terpendek Dalam robot rover & drone, ini menjadi norma untuk menentukan luas ruang yang dinavigasi oleh robot. Ini memungkinkan robot untuk membangun model volumetrik penuh dari lingkungan mereka, sama seperti yang akan kita lihat atau bahkan suara atau sentuhan (untuk orang buta atau tuli), yang kemudian dapat direduksi oleh robot menjadi grafik topografi minimal (agak seperti grafik titik arah) digunakan dalam game dengan A *), yang dengannya algoritma jalur terpendek kemudian dapat diterapkan. Dalam hal ini, sementara "visi" dapat memberikan petunjuk untuk lingkungan terdekat, itu masih menghasilkanpencarian grafik yang pada akhirnya menyediakan path-to-goal. Ini dekat dengan pemikiran manusia: Untuk mencapai dapur dari kamar tidur, saya harus melewati ruang tamu. Fakta bahwa saya telah melihat mereka dan mengetahui ruang mereka dan portal mereka, adalah apa yang memungkinkan langkah yang diperhitungkan ini. Ini adalah topologi grafik, yang diterapkan algoritma jalur terpendek, meskipun tertanam dalam protein lunak daripada silikon keras.

Jadi Anda dapat melihat bahwa dua yang pertama bergantung pada sudah mengetahui lingkungan secara keseluruhan. Ini, untuk alasan biaya mengevaluasi lingkungan dari awal, adalah hal biasa dalam permainan. Jelas, yang terakhir paling kuat. Robot yang dilengkapi cara ini (atau misalnya, game AI yang membaca buffer kedalaman setiap frame) dapat bernavigasi secara memadai di lingkungan apa pun tanpa sepengetahuan sebelumnya. Seperti yang Anda duga, ini juga yang paling mahal dari ketiga pendekatan di atas, dan dalam permainan kami biasanya tidak mampu melakukan ini berdasarkan per-AI. Tentu saja, ini jauh lebih murah dalam 2D ​​daripada 3D.

Poin arsitektur

Menjadi jelas di atas bahwa kita tidak dapat mengasumsikan hanya satu pola akses data yang benar untuk AI; pilihan tergantung pada apa yang ingin Anda capai. Mengakses GameWorldkelas secara langsung benar-benar standar: itu hanya memberi Anda informasi dunia. Pada dasarnya itu adalah model data Anda, dan itulah gunanya model data. Singleton baik-baik saja untuk ini.

"dapatkan daftar semua entitas dan cari apa pun yang kamu butuhkan"

Tidak ada yang naif tentang itu, sama sekali. Satu-satunya hal yang mungkin naif adalah melakukan iterasi daftar lebih banyak dari yang Anda butuhkan. Dalam deteksi tabrakan, kami menghindari ini dengan menggunakan mis quadtrees untuk mengurangi ruang pencarian. Mekanisme serupa dapat berlaku untuk AI. Dan jika Anda dapat berbagi loop yang sama untuk melakukan banyak hal, lakukan itu, karena cabang mahal.


Terimakasih telah menjawab. Karena saya seorang pemula untuk game dev, saya pikir saya akan tetap berpegang pada pendekatan sederhana "dapatkan daftar dari dunia game" untuk saat ini :) Satu pertanyaan: dalam pertanyaan saya, saya menggambarkan GameWorldkelas sebagai kelas yang berisi referensi ke semua entitas game, dan juga mengandung sebagian besar logika 'mesin' penting: loop game utama, deteksi tabrakan, dll. Ini pada dasarnya adalah 'kelas utama' dari game. Pertanyaan saya adalah: Apakah pendekatan ini biasa dalam permainan? Punya 'kelas utama'? Atau haruskah saya memisahkannya menjadi kelas yang lebih kecil dan memiliki satu kelas sebagai objek 'database entitas' yang dapat disurvei?
Aviv Cohn

@Prog Sama-sama. Sekali lagi, tidak ada dalam pendekatan AI di atas (atau yang lain, dalam hal ini) yang menunjukkan bahwa Anda "mendapatkan daftar dari dunia game" adalah cara, bentuk atau bentuk arsitektur yang salah. The AI arsitektur harus sesuai dengan kebutuhan AI; tetapi logika itu, seperti yang Anda sarankan, harus dimodulasi, dienkapsulasi (di kelasnya sendiri) dari arsitektur aplikasi Anda yang lebih luas . Ya, subsistem harus selalu diperhitungkan dalam modul terpisah begitu pertanyaan seperti itu muncul. Prinsip panduan Anda haruslah SRP .
Insinyur

2

Pada dasarnya saya punya 2 cara untuk menanyakan informasi.

  1. ketika AIState berubah karena Anda mendeteksi tabrakan atau cache apa pun referensi ke objek apa pun yang penting. Dengan begitu Anda tahu referensi apa yang Anda butuhkan. Ketika ada sistem lain yang harus menjalankan pencarian besar setiap frame saya sarankan piggy mundur mereka sehingga Anda tidak harus melakukan beberapa pencarian. Jadi 'tabrakan' terdeteksi dengan zona yang membuat musuh 'waspada' mengirimnya pesan / peristiwa yang mendaftarkannya dengan objek itu jika ia belum melakukannya dan mengubah status permainan menjadi yang membuatnya menjalankan bisnisnya berdasarkan keberadaannya di gamestate itu. Anda memerlukan acara dengan tipe tertentu yang memberi tahu Anda untuk melakukan perubahan, saya hanya akan meneruskan referensi ke panggilan balik apa pun yang Anda gunakan untuk memberikan informasi itu. Ini lebih dapat diperluas daripada hanya harus berurusan dengan pemain. Mungkin Anda ingin musuh mengejar musuh lain atau benda lain. Dengan cara ini Anda hanya perlu mengubah tag apa pun yang Anda identifikasi.

  2. Dengan informasi itu Anda kemudian akan melakukan kueri ke sistem pencarian jalur yang menggunakan A * atau algoritma lain untuk memberi Anda jalan atau Anda dapat menggunakannya dengan beberapa perilaku kemudi. Mungkin kombinasi keduanya atau apa pun. Pada dasarnya dengan transformasi kedua Anda harus dapat query sistem simpul Anda atau navmesh dan memberikannya jalan. Gameworld Anda kemungkinan memiliki banyak hal selain penelusuran jalan. Saya akan mengirimkan permintaan Anda hanya untuk merintis jalan. Juga mengumpulkan hal-hal ini mungkin yang terbaik jika Anda memiliki banyak pertanyaan karena ini bisa menjadi sangat intensif dan batching akan membantu kinerja.

    Transform* targetTransform = nullptr;
    EnemyAIState  AIState = EnemyAIState::Idle;
    void OnTriggerEnter(GameObject* go)
    {
       if(go->hasTag(TAG_PLAYER))
       {
       //Cache important information that will be needed during pursuit
       targetTransform = go->getComponent<Transform>();
       AIState = EnemyAIState::Pursue;
       }
    }
    
    void Update()
    {
       switch(AIState)
       {
          case EnemyAIState::Pursue:
           //Find position to move to
           Vector3 nextNode = PathSystem::Seek(
                              transform->position,targetTransform->position);
           /*Update the position towards the target by whatever speed the unit moves
             Depending on how robust your path system is you might want to raycast
             against obstacles it can't take into account or might clip the path.*/
            transform->Move((nextNode - transform->position).unitVector()*speed*Time::deltaTime());
            break;
        }
     }
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.