Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Game Development
  2. Unity 3D
Gamedevelopment

Perencanaan Aksi Berorientasi Tujuan untuk AI yang Lebih Cerdas

by
Difficulty:IntermediateLength:LongLanguages:

Indonesian (Bahasa Indonesia) translation by Nasruddin (you can also view the original English article)

Goal Oriented Action Planning (GOAP) adalah sistem AI yang akan dengan mudah memberikan pilihan agen Anda dan alat untuk membuat keputusan cerdas tanpa harus mempertahankan finite state machine yang besar dan kompleks.

Lihat Demo

Dalam demo ini, ada empat kelas karakter, masing-masing menggunakan alat yang rusak setelah digunakan untuk sementara:

  • Penambang: Tambang bijih di bebatuan. Membutuhkan alat untuk bekerja.
  • Tukang Tebang Kayu: Memotong pohon untuk menghasilkan kayu gelondongan. Membutuhkan alat untuk bekerja.
  • Pemotong Kayu: Memotong pohon menjadi kayu yang bisa digunakan. Membutuhkan alat untuk bekerja.
  • Pandai besi: Menempa alat di bengkel. Semua orang menggunakan alat ini.

Setiap kelas akan mencari tahu secara otomatis, menggunakan perencanaan aksi berorientasi tujuan, tindakan apa yang perlu mereka lakukan untuk mencapai tujuan mereka. Jika alat mereka rusak, mereka akan pergi ke tumpukan pasokan yang dibuat oleh pandai besi.

Apa itu GOAP?

Perencanaan aksi yang berorientasi pada tujuan adalah sistem kecerdasan buatan untuk agen yang memungkinkan mereka merencanakan serangkaian tindakan untuk memenuhi tujuan tertentu. Urutan tindakan tertentu tidak hanya tergantung pada tujuan tetapi juga pada keadaan dunia saat ini dan agennya. Ini berarti bahwa jika tujuan yang sama diberikan untuk agen atau negara dunia yang berbeda, Anda bisa mendapatkan urutan tindakan yang benar-benar berbeda., Yang membuat AI lebih dinamis dan realistis. Mari kita lihat contoh, seperti yang terlihat pada demo di atas.

Kami memiliki agen, pemotong kayu, yang mengambil kayu dan memotongnya menjadi kayu bakar. Pemotong kayu dapat diberikan tujuan MakeFirewood, dan memiliki tindakan ChopLog, GetAxe, dan CollectBranches.

Tindakan ChopLog akan mengubah kayu gelondongan menjadi kayu bakar, tetapi hanya jika pemotong kayu memiliki kapak. Tindakan GetAxe akan memberikan kapak pada pemotong kayu. Akhirnya, tindakan CollectBranches akan menghasilkan kayu bakar tanpa membutuhkan kapak, tetapi kayu bakar tidak akan memiliki kualitas yang tinggi.

Saat kita memberi agen tujuan MakeFirewood, kita mendapatkan dua urutan tindakan yang berbeda ini:

  • Membutuhkan kayu bakar -> GetAxe -> ChopLog = membuat kayu bakar
  • Membutuhkan kayu bakar -> CollectBranches = membuat kayu bakar

Jika agen bisa mendapatkan kapak, maka mereka dapat memotong kayu untuk membuat kayu bakar. Tetapi mungkin mereka tidak bisa mendapatkan kapak; kemudian, mereka bisa pergi dan mengumpulkan ranting. Masing-masing urutan ini akan memenuhi tujuan MakeFirewood.

GOAP dapat memilih urutan terbaik berdasarkan prakondisi apa saja yang tersedia. Jika tidak ada kapak yang berguna, maka pemotong kayu harus mengambil ranting. Mengambil ranting bisa memakan waktu sangat lama dan menghasilkan kayu bakar berkualitas buruk, jadi kami tidak ingin itu berjalan sepanjang waktu, hanya ketika diperlukan saja.

Untuk GOAP Anda

sekarang, mungkin Anda telah akrab dengan Finite State Machines (FSM), tetapi jika tidak, maka lihatlah tutorial hebat ini.

Anda mungkin telah mengalami keadaan yang sangat berat dan kompleks untuk beberapa agen FSM Anda, di mana Anda akhirnya sampai pada titik di mana Anda tidak ingin menambahkan perilaku baru karena mereka menyebabkan terlalu banyak efek samping dan kesenjangan dalam AI.

GOAP mengubah ini:

Status Mesin Hingga Menyatakan: terhubung ke segala arah.

Menjadi ini:

GOAP: bagus dan mudah diatur.


Dengan memisahkan aksi dari satu sama lain, kita sekarang dapat fokus pada setiap tindakan secara individual. Yaitu membuat kode modular, yang mudah untuk diuji dan dipertahankan. Jika Anda ingin menambahkan tindakan lain, Anda cukup memasukkannya, dan tidak ada tindakan lain yang harus diubah. Coba lakukan itu dengan FSM!

Selain itu, Anda dapat menambahkan atau menghapus tindakan dengan cepat untuk mengubah perilaku agen agar membuatnya lebih dinamis. Menghadapi raksasa yang tiba-tiba mulai mengamuk? Beri mereka tindakan "serangan kemarahan" yang baru dihapus saat mereka sudah tenang. Cukup tambahkan tindakan ke daftar tindakan yang harus Anda lakukan; perencana GOAP akan mengurus sisanya.

Jika Anda merasa Anda memiliki FSM yang sangat kompleks untuk agen Anda, maka Anda harus mencoba GOAP. Salah satu tanda bahwa FSM Anda menjadi terlalu rumit adalah ketika setiap negara memiliki segudang pernyataan if-else yang menguji keadaan apa yang harus mereka lakukan selanjutnya, dan menambahkan dalam keadaan baru membuat Anda mengeluh atas implikasi yang mungkin terjadi.

Jika Anda memiliki agen yang sangat sederhana yang hanya melakukan satu atau dua tugas, maka GOAP mungkin agak berat dan FSM akan mencukupi. Namun, ada baiknya melihat konsep di sini dan melihat apakah mereka akan cukup mudah bagi Anda untuk menyambungkan ke agen Anda.

Tindakan

Suatu tindakan adalah sesuatu yang dilakukan agen. Biasanya hanya memainkan animasi dan suara, dan mengubah sedikit keadaan (misalnya, menambahkan kayu bakar). Membuka pintu adalah tindakan yang berbeda (dan animasi) daripada mengambil pensil. Suatu tindakan dirangkum, dan tidak perlu khawatir tentang tindakan yang lain.

Untuk membantu GOAP menentukan tindakan apa yang ingin kita gunakan, setiap tindakan diberi harga. Tindakan dengan harga tinggi tidak akan dipilih dibandingkan dengan tindakan dengan biaya yang lebih rendah. Ketika kita mengurutkan aksi bersama, kita menambahkan biaya dan kemudian memilih urutan dengan biaya terendah.

Mari tetapkan beberapa harga untuk tiap tindakan:

  • Harga GetAxe: 2
  • Harga ChopLog: 4
  • Harga CollectBranches: 8

Jika kita melihat urutan tindakan lagi dan menjumlahkan total harga, kita akan melihat urutan termurahnya:

  • Kebutuhan kayu bakar -> GetAxe (2) -> ChopLog (4) = membuat kayu bakar (total: 6)
  • Kebutuhan kayu bakar -> CollectBranches (8) = membuat kayu bakar (total: 8)

Mendapatkan kapak dan memotong kayu menghasilkan kayu bakar dengan biaya lebih rendah 6, sementara mengumpulkan cabang menghasilkan kayu dengan biaya lebih tinggi dari 8. Jadi, agen kami memilih untuk mendapatkan kapak dan memotong kayu.

Tetapi apakah urutan yang sama ini tidak akan berjalan sepanjang waktu? Tidak jika kami memperkenalkan prasyarat...

Prakondisi dan Efek

Tindakan- tindakan memiliki prakondisi dan efek. Prasyarat adalah keadaan yang diperlukan untuk tindakan agar bisa dijalankan, dan efeknya adalah perubahan ke keadaan setelah tindakan dijalankan.

Sebagai contoh, aksi ChopLog membutuhkan agen untuk memiliki kapak berguna. Jika agen tidak memiliki kapak, ia perlu mencari tindakan lain yang dapat memenuhi prakondisi itu untuk membiarkan tindakan ChopLog berjalan. Untungnya, tindakan GetAxe bisa melakukannya — ini adalah efek dari tindakan.

Perencana GOAP

Perencana GOAP adalah bagian dari kode yang melihat prakondisi dan efek tindakan, dan menciptakan antrian tindakan yang akan memenuhi tujuan. Tujuan itu diberikan oleh agen, bersama dengan keadaan dunia, dan daftar tindakan yang dapat dilakukan agen. Dengan informasi ini perencana GOAP dapat memesan tindakan, melihat mana yang dapat berjalan dan mana yang tidak, dan kemudian memutuskan tindakan mana yang terbaik untuk dilakukan. Untungnya, saya telah menulis kode ini, jadi Anda tidak perlu melakukannya.

Untuk menyiapkan ini, tambahkan prakondisi dan efek pada tindakan penebangan kayu kita:

  • Biaya GetAxe: 2. Prekondisi: "kapak tersedia", "tidak memiliki kapak". Efek: "memiliki kapak".
  • Biaya ChopLog: 4. Prekondisi: "memiliki kapak". Efek: "membuat kayu bakar"
  • Biaya CollectBranches: 8. Prekondisi: (tidak ada). Efek: "membuat kayu bakar".

Perencana GOAP sekarang memiliki informasi yang diperlukan untuk memesan urutan tindakan untuk membuat kayu bakar (tujuan kami).

Kami mulai dengan menyediakan GOAP Planner dengan keadaan dunia saat ini dan keadaan agen. Keadaan dunia gabungan ini adalah:

  • "tidak memiliki kapak"
  • "kapak tersedia"
  • "matahari bersinar"

Melihat tindakan kita yang tersedia saat ini, satu-satunya bagian dari keadaan bagian yang relevan bagi mereka adalah "tidak memiliki kapak" dan keadaan "kapak tersedia"; yang lain mungkin digunakan untuk agen lain dengan tindakan lain.

Oke, kita memiliki keadaan dunia kita saat ini, tindakan kita (dengan prakondisi dan efek mereka), dan tujuan. Ayo rencanakan!

Perencana akan menjalankan tindakan lainnya juga, dan itu tidak akan berhenti hingga menemukan solusi untuk tujuan tersebut. Bagaimana jika urutan lain memiliki biaya lebih rendah? Ini akan berjalan melalui semua kemungkinan untuk menemukan solusi terbaik.

Ketika itu direncanakan, ia akan membangun sebuah pohon. Setiap kali tindakan diterapkan, tindakan ini muncul dari daftar tindakan yang tersedia, jadi kami tidak memiliki serangkaian 50 tindakan GetAxe secara berurutan. Keadaan diubah dengan efek tindakan itu.

Pohon yang dibangun perencana terlihat seperti ini:

Kita dapat melihat bahwa itu benar-benar akan menghasilkan tiga jalur ke tujuan dengan total biaya mereka:

  • GetAxe -> ChopLog (total: 6)
  • GetAxe -> CollectBranches (total: 10)
  • CollectBranches (total: 8)

Meskipun GetAxe -> CollectBranches berfungsi, jalur termurahnya adalah GetAxe -> ChopLog, jadi yang ini dikembalikan.

Seperti apa prakondisi dan efek yang sebenarnya terlihat dalam kode? Yah, itu terserah Anda, tetapi saya merasa paling mudah untuk menyimpannya sebagai pasangan kunci-nilai, di mana kuncinya selalu berupa String dan nilainya adalah objek atau tipe primitif (float, int, Boolean, atau sejenisnya). Dalam C#, itu bisa terlihat seperti ini:

Saat aksi sedang berlangsung, seperti apa sebenarnya efek ini dan apa yang mereka lakukan? Yah, mereka tidak perlu melakukan apa-apa — mereka benar-benar hanya digunakan untuk perencanaan, dan tidak memengaruhi keadaan agen sebenarnya sampai mereka benar-benar nyata.

Ini perlu ditekankan: tindakan perencanaan tidak sama dengan menjalankannya. Ketika agen melakukan tindakan GetAxe, itu mungkin akan berada di dekat tumpukan alat, memainkan animasi bend-down-and-pick-up, dan kemudian menyimpan objek kapak di ranselnya. Ini mengubah status agen. Namun, selama perencanaan GOAP, perubahan keadaan hanya sementara, sehingga perencana dapat mencari solusi optimal.  

Prakondisi Prosedural

Terkadang, tindakan perlu melakukan sedikit lebih banyak untuk menentukan apakah mereka dapat berjalan. Misalnya, tindakan GetAxe memiliki prakondisi "kapak tersedia" yang perlu mencari dunia, atau di sekitarnya, untuk melihat apakah ada kapak yang bisa diambil oleh agen. Mungkin menentukan bahwa kapak terdekat terlalu jauh atau di belakang garis musuh, dan akan mengatakan bahwa kapak itu tidak dapat berjalan. Prasyarat ini bersifat prosedural dan perlu menjalankan beberapa kode; ini bukan operator Boolean sederhana yang bisa kita atur.

Tentunya, beberapa prakondisi prosedural ini dapat membutuhkan waktu untuk dijalankan, dan harus dilakukan pada sesuatu selain render thread, idealnya sebagai utas latar belakang atau sebagai Coroutines (dalam Kesatuan).

Anda bisa memiliki efek prosedural juga, jika Anda menginginkannya. Dan jika Anda ingin memperkenalkan hasil yang lebih dinamis, Anda dapat mengubah biaya tindakan dengan cepat!

GOAP dan Keadaan

Sistem GOAP kita harus tinggal di Finite State Machine (FSM) kecil, karena satu-satunya alasan bahwa, dalam banyak permainan, tindakan harus dekat dengan target agar dapat berfungsi. Kita berakhir dengan tiga keadaan:

  • Idle
  • MoveTo
  • PerformAction

Saat sedang tidak aktif, agen akan mencari tahu tujuan yang ingin mereka penuhi. Bagian ini ditangani di luar GOAP; GOAP hanya akan memberi tahu Anda tindakan mana yang dapat Anda jalankan untuk melakukan tujuan itu. Ketika suatu tujuan dipilih, itu diteruskan ke Perencana GOAP, bersama dengan dunia dan keadaan awal agen, dan perencana akan mengembalikan daftar tindakan (jika dapat memenuhi tujuan itu).

Ketika perencana selesai dan agen memiliki daftar tindakan, ia akan mencoba melakukan tindakan pertama. Semua tindakan perlu diketahui jika mereka harus berada dalam jangkauan target. Jika mereka melakukannya, maka FSM akan mendorong pada keadaan berikutnya: MoveTo.

Keadaan MoveTo akan memberi tahu agen bahwa ia perlu pindah ke target tertentu. Agen akan melakukan pemindahan (dan memutar animasi berjalan), dan kemudian membiarkan FSM tahu kapan itu berada dalam jangkauan target. Keadaan ini kemudian terpotong, dan aksi bisa dilakukan.

Keadaan PerformAction akan menjalankan tindakan selanjutnya dalam antrean tindakan yang dikembalikan oleh GOAP Planner. Tindakan bisa terjadi seketika atau berakhir melalui banyak bingkai, tetapi ketika itu selesai, itu akan terpotong dan kemudian tindakan selanjutnya dilakukan (sekali lagi, setelah memeriksa apakah tindakan selanjutnya harus dilakukan dalam jangkauan objek).

Ini semua terulang hingga tidak ada tindakan yang tersisa untuk dilakukan, pada titik mana kita kembali ke keadaan diam (Idle), mendapatkan tujuan baru, dan merencanakan lagi

Contoh Kode Nyata

Saatnya untuk melihat contoh nyata! Jangan khawatir; itu tidak terlalu rumit, dan saya telah menyediakan copy pekerjaan dalam Kesatuan dan C# untuk Anda coba. Saya hanya akan membicarakannya sebentar di sini sehingga Anda bisa merasakan arsitekturnya. Kode ini menggunakan beberapa contoh WoodChopper yang sama seperti di atas.

Jika Anda ingin menggali dengan benar, ke sini untuk kode: http://github.com/sploreg/goap

Kami memiliki empat pekerja:

  • Pandai besi: mengubah bijih besi menjadi alat.
  • Tukang tebang kayu: menggunakan alat untuk menebang pohon untuk menghasilkan kayu gelondongan.
  • Penambang: menambang batu dengan alat untuk menghasilkan bijih besi.
  • Pemotong kayu: menggunakan alat untuk memotong kayu untuk menghasilkan kayu bakar.

Peralatan akan menjadi aus dari waktu ke waktu dan perlu diganti. Untungnya, pandai besi bertugas  membuat alat. Tetapi bijih besi diperlukan untuk membuat alat; di situlah Penambang masuk (yang juga membutuhkan alat). Pemotong Kayu membutuhkan kayu gelondongan, yang berasal dari tukang potong kayu; keduanya membutuhkan alat juga.

Alat dan sumber daya disimpan di tumpukan pasokan. Para agen akan mengumpulkan bahan atau alat yang mereka butuhkan dari tumpukan, dan juga menurunkan produk mereka.

Kode ini memiliki enam kelas GOAP utama:

  • GoapAgent: memahami keadaan dan menggunakan FSM dan GoapPlanner untuk beroperasi.
  • GoapAction: tindakan yang dapat dilakukan oleh agen.
  • GoapPlanner: merencanakan tindakan untuk GoapAgent.
  • FSM: mesin keadaan yang terbatas.
  • FSMState: sebuah keadaan dalam FSM.
  • IGoap: antarmuka yang digunakan oleh aktor Buruh kita yang sebenarnya. Mengikat acara untuk GOAP dan FSM.

Mari kita lihat kelas GoapAction, karena itu yang akan Anda jadikan subkelas:

Tidak ada yang terlalu mewah di sini: ia akan menyimpan prakondisi dan efek. Ia juga tahu apakah itu harus dalam jangkauan target, dan, jika demikian, maka FSM tahu untuk mendorong keadan pada MoveTo saat diperlukan. Ia juga tahu kapan itu dapat diselesaikan; yang ditentukan oleh kelas tindakan pelaksana.

Berikut ini salah satu tindakannya:

Bagian terbesar dari tindakan ini adalah metode checkProceduralPreconditions. Metode ini mencari objek permainan terdekat dengan IronRockComponent, dan menyimpan batu target ini. Kemudian, ketika melakukan, ia mendapat batu target yang disimpan dan akan melakukan tindakan di atasnya. Ketika tindakan itu digunakan kembali dalam perencanaan lagi, semua bidangnya disetel ulang sehingga dapat dihitung kembali.

Ini adalah semua komponen yang ditambahkan ke objek entitas Penambang di Unity:


Agar agen Anda berfungsi, Anda harus menambahkan komponen berikut ke dalamnya:

  • GoapAgent.
  • Kelas yang mengimplementasikan IGoap (dalam contoh di atas, yaitu Miner.cs).
  • Beberapa tindakan.
  • Tas punggung (hanya karena tindakan menggunakannya; itu tidak terkait dengan GOAP).
Anda dapat menambahkan tindakan apa pun yang Anda inginkan, dan ini akan mengubah perilaku agen. Anda bahkan bisa memberikan semua tindakan sehingga dapat menambang bijih, menempa alat, dan memotong kayu.

Berikut ini demo dalam aksi:

Setiap buruh pergi ke target yang mereka butuhkan untuk memenuhi tindakan mereka (pohon, batu, memotong blok, atau apa pun), melakukan tindakan, dan sering kembali ke tumpukan pasokan untuk menurunkan barang-barang mereka. Pandai besi akan menunggu sebentar sampai ada bijih besi di salah satu tumpukan pasokan (ditambahkan oleh Penambang). Pandai besi kemudian pergi dan membuat alat, dan akan menurunkan alat di tumpukan pasokan terdekatnya. Saat alat kerja buruh rusak, mereka akan menuju ke tumpukan pasokan di dekat Pandai besi tempat di mana alat-alat baru berada.

Anda dapat mengambil kode dan aplikasi lengkap di sini: http://github.com/sploreg/goap.

Kesimpulan

Dengan GOAP, Anda dapat membuat serangkaian tindakan besar tanpa pusing keadaa- keadaan yang saling terhubung yang sering kali mencul dengan Finite State Machine.  Tindakan dapat ditambahkan dan dihapus dari agen untuk menghasilkan hasil yang dinamis, serta membuat Anda tetap normal ketika mempertahankan kode. Anda akan berakhir dengan AI yang fleksibel, cerdas, dan dinamis.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.