ECS: Các thành phần và hệ thống AI


9

Tôi đang cố gắng tìm mẫu thiết kế tốt nhất cho mã AI của mình bằng ECS.

Ngay bây giờ các thực thể hoạt động như CPU ​​điều khiển có các thành phần như:

  • Vũ khí
  • ChargeComponent
  • Phong trào
  • AIControlledComponent

...

Tôi có AIControlSystem vượt qua các thực thể có AIControlledComponent và trong mỗi khung chuyển trạng thái tinh thần của thực thể dựa trên một số quy tắc như "tôi có thể thấy người chơi không?", "Tôi có thể di chuyển đến nơi an toàn không?", V.v. .

Dựa trên trạng thái tinh thần, hệ thống này thêm một tập hợp các hành động vào hàng đợi.

Sau đó, hàng đợi đang được tiêu thụ và đánh giá. Một hành động như "Tấn công" thực sự đang gọi một phương thức của hệ thống để kiểm tra xem thực thể đó có WeaponComponent được gắn và bắn hay không, nếu có ChargeComponent, nó sẽ sạc cho người chơi. Theo cách này, các phương thức đó có xu hướng phát triển khi loại kẻ thù và hành động phát triển và mã bắt đầu trở thành một mớ hỗn độn vì có quá nhiều kiểm tra và đường dẫn để theo dõi.

Tôi nghĩ rằng tôi có thể cấu trúc lại mã phân tách dựa trên loại kẻ thù (còn gọi là kẻ thù có Vũ khí sẽ không thể sạc và ngược lại) nhưng sau đó tôi phải có AIControlSystem cơ bản và kế thừa từ đó và chuyên môn hóa nó dựa trên các thành phần gắn liền với các thực thể. Điều này sẽ dẫn đến khá nhiều hệ thống mới cho mỗi loại kẻ thù và nó không thực sự giống như một giải pháp tốt.

Tôi đã nghĩ đến việc chuyển hướng từ mẫu ECS thuần túy chỉ giữ các thành phần dưới dạng bộ chứa dữ liệu và thực sự thực hiện các phương thức đó trong chính các thành phần đó để tôi có thể có AIControlledComponent cơ bản với các phương thức ảo diễn giải hàng đợi hành động và kế thừa một thành phần mới từ đó một cho mỗi loại kẻ thù. Nó có vẻ tốt hơn một chút cho tổ chức mã nhưng tôi không chắc chắn rằng tạo ra loại ngoại lệ này là một ý tưởng tốt.

Có cách nào khác để giữ mã dưới sự kiểm soát và đồng thời có sự linh hoạt cần thiết không?


6
AI chính xác là một trong những điều khiến tôi không thích sự vô lý nghiêm ngặt của ECS mà những người có sở thích Reddit đạp xe ngày nay. Sử dụng linh kiện là tốt. Sử dụng một cách tiếp cận giống như ECS cho một số thứ là tốt. Sử dụng một ECS nghiêm ngặt cho mọi thứ là yêu cầu khó khăn không cần thiết.
Sean Middleditch

@SeanMiddleditch Tôi đồng ý với tình cảm của bạn. Tôi đã đánh giá việc biến AIControlledComponent của mình thành một loại bảng đen và chuyển mọi thứ khác liên quan đến AI sang một hệ thống hoàn toàn khác không thực sự sử dụng ECS ​​trực tiếp. Nếu bạn có bất kỳ gợi ý nào để chia sẻ để thiết kế một cái gì đó như thế thì nó sẽ thực sự được đánh giá cao.
Valerio Santinelli 9/2/2016

Không có mô-đun chính nào của bạn thậm chí sẽ được phép bao gồm các tiêu đề ECS ở vị trí đầu tiên. Chỉ sử dụng các thành phần để dán các mô-đun với nhau vào các đối tượng trò chơi. Tất cả các mã công cụ cốt lõi của bạn nên có thể sử dụng được với bất kỳ mô hình đối tượng nào. Đồ họa biểu diễn các nút cảnh, vật lý di chuyển cơ thể, AI cốt lõi diễn giải các biểu đồ quyết định, v.v. Không ai trong số đó dựa vào các đối tượng trò chơi thực tế. Tất nhiên các nút AI cụ thể phụ thuộc vào trạng thái trò chơi, vì vậy Hệ thống AI cấp cao có thể sử dụng Thành phần để cung cấp dữ liệu hoặc cây cho mô-đun AI cấp thấp, nhưng mô-đun hoàn toàn không phụ thuộc vào các thành phần.
Sean Middleditch

@SeanMiddleditch vấn đề tôi thấy với cách tiếp cận này là mô-đun AI có thể dễ dàng tách rời khỏi các thành phần được gắn vào các thực thể. Để đánh giá cây hoặc chạy máy trạng thái, nó cần biết thông tin từ thực thể đang được sử dụng để thực sự cần phải lấy thông tin như kho, vũ khí có sẵn, vị trí, v.v. từ các thành phần thực tế. Làm thế nào bạn sẽ tách rời điều đó?
Valerio Santinelli

Tôi có thể không rõ ràng. Bản thân mô-đun AI không cần biết, vì nó không phải biết logic quyết định cụ thể trong các nút đánh giá. Đó là những "plugin" (triển khai giao diện) mà mã trò chơi cấp cao hơn có thể cung cấp.
Sean Middleditch

Câu trả lời:


3

The problem I see with this approach is that the AI module cannot be easily decoupled from the components attached to the entities. To evaluate a tree or run a state machine, it needs to know information from the entity being used so it actually needs to pull information like the inventory, the weapons available, the position, etc from the actual components.

Quan sát bất kỳ động vật nào: hệ thống thần kinh của nó được điều chỉnh theo nhiệm vụ của nó. Chim có thị lực sắc bén để tìm kiếm thức ăn và các mối đe dọa, và khả năng điều chỉnh tư thế của chúng và đạt được lực nâng khi rơi, theo bản năng. Và tâm trí con người có dây để nhận thức rất rõ về khả năng của chính cơ thể mình, mức độ khỏe mạnh, đói, lạnh, chưa kể đến sự hiện diện hay vắng mặt của chân tay ... bạn sẽ bị trôi dạt. Nếu chúng ta sử dụng RL làm cơ sở cho mô hình hóa đối tượng, sẽ không có lỗi trong việc trí tuệ / AI nhận thức được các khía cạnh như vị trí, tư thế, sức khỏe, vật phẩm, khả năng, v.v. Những gì bạn có thể làm là vũ khí tên lửa trừu tượng được xử lý như một loại chung chung. Điều này dẫn đến logic AI trừu tượng đẹp nhưif holding missile weapon in hand, attempt to fire. Một bộ não trong một cái bình, OTOH, chính xác là như vậy - miễn là nó biết nó bị thất sủng, nó cũng biết rằng cố gắng trèo ra khỏi cái lọ là vô ích. Đó là: kiểm tra AI cho nullcác thành phần và tiến hành tương ứng.

I thought about diverging from the pure ECS pattern of keeping components as data containers only and actually implement those methods in the components themselves so that I can have a base AIControlledComponent

I thought I could refactor the code splitting it up based on the kind of enemy (aka an enemy that has a Weapon won't be able to Charge and vice versa) but then I'd have to have a base AIControlSystem and inherit from that and specialize it based on the components attached to the entities. This would result in pretty much one new system per enemy kind and it doesn't really look like a good solution.

  1. Giữ chúng như các mục dữ liệu thuần túy hay không không phải là vấn đề quan trọng; nhưng hệ thống kiểm soát của bạn là, và trong vấn đề đó, phương pháp "thuần túy" thường được đẩy là "thực hành âm thanh". Trong thực tế, nó làm cho rất ít sự khác biệt cho dù logic là trên thishoặc trên một cái gì đó khác (như bộ điều khiển cấp cao hơn). Chỉ cần đừng để phương thức không thuần túy biến mã của bạn thành spaghetti. (Theo kinh nghiệm của tôi, cách tiếp cận thuần túy có nhiều mã nguyên khối hơn và khiến cho việc mắc lỗi ở đối tượng địa phương không đồng ý với các cơ chế kiểm soát toàn cầu trở nên khó khăn hơn - Tôi luôn tìm cách tiếp cận từ trên xuống rõ ràng nhất.)

  2. Một số người sẽ không đồng ý, nhưng nói chung, toàn bộ ý tưởng đằng sau ECS là thành phần đối tượng so với kế thừa. Tôi không nói rằng bạn không thể sử dụng tính kế thừa trên một số loại thành phần của mình, nhưng tôi sẽ tránh điều đó càng tốt.

Based on the mental state, this systems adds a set of actions to a queue. Then the queue is being consumed and evaluated. An action like "Attack" is actually calling a method of the system that checks whether the entity has a WeaponComponent attached and fires, or if there's a ChargeComponent it charges at the player.

Tôi nghĩ rằng đây là trung tâm của cuộc khủng hoảng của bạn. Thành phần trí tuệ AI của bạn, nên biết toàn bộ trạng thái của cơ thể mình và các bộ phận liên quan của môi trường bên ngoài, không bao giờ xếp hàng "Tấn công" trừ khi hoàn cảnh lý tưởng ở nơi đầu tiên. Ví dụ, hãy tưởng tượng bạn đột nhiên nhận ra rằng bạn không có một khẩu súng trường trong tay, mà là một cây bút. Bạn vẫn sẽ tấn công và tấn công, đặc biệt là nếu kẻ thù đều được trang bị súng? Tôi nghi ngờ điều đó. Về mặt chiến thuật rất khác biệt và trong mã hiện tại của bạn, sự khác biệt đó không được tạo ra bởi thành phần AI của bạn trước khi xếp hàng hành động được đề cập.

whether the entity has a WeaponComponent attached and fires, or if there's a ChargeComponent it charges at the player

Điều này cũng hoàn toàn sai với tâm trí của tôi. Tại sao là Chargemột Component? Chắc chắn đó chỉ là một động từ, một loại hành động mà bất kỳ AI nào cũng có thể chọn thực hiện, ngay cả khi nó có vũ khí tên lửa trong tay? Chắc chắn điều duy nhất ngăn chặn một khoản phí là tốc độ / sự đóng gói và đó là những yếu tố được xử lý trong quyết định của AI về những hành động cần thực hiện, dựa trên trạng thái vật lý của chính thực thể? Nhưng ... OK.

Hai đoạn cuối cung cấp cho bạn ý chính của các vấn đề của bạn: bạn đang để lại những gì quan trọng, quyết định AI (!) Hạng nhất được đưa ra trước khi xếp hàng xảy ra, để trở thành phút cuối, quyết định của lớp thứ hai được đưa ra vào lúc mà thực thể của bạn nên được kích hoạt hoặc chạy cho cuộc sống của nó. Nghe có vẻ không quyết định lắm đối với tôi và tôi có thể tưởng tượng điều gì xảy ra với những người lính thực sự chiến đấu theo cách này. Ngoài ra, tôi thậm chí không chắc chắn liệu AI có tham gia vào giai đoạn "đoán thứ hai" của bạn hay không, hay đó chỉ là những thành phần khác đưa ra những quyết định cuối cùng về việc có nên hành động hay không ... nếu sau này , bạn cần thay đổi điều đó thành xử lý quyết định AI một pha và các hành động xếp hàng dựa trên các xác nhận.

Đề nghị bạn hợp nhất xử lý AI của bạn để xảy ra hoàn toàn trước khi bắt đầu xếp hàng. Các vấn đề ở đây là tất cả trong chiến lược AI của bạn chứ không phải trong cách sử dụng ECS ​​của bạn, trong chừng mực mà tôi có thể thấy.


1

Sử dụng một cây hành vi thay vì chắc chắn. Mỗi cây hành vi, bạn làm cho nó cụ thể cho "diễn viên". Mỗi tác nhân có các thành phần mà nó có và vì BT được gắn vào nó, các nút của BT sẽ biết các thành phần và có thể truy vấn chúng. Bây giờ BT của bạn biết chính xác những gì diễn viên có khi xử lý và có thể làm việc với nó.

Vì vậy, ví dụ bạn có một BT chim mà bạn gắn vào các thực thể chim có thành phần bay. Bạn có nút lá / hành động bay cụ thể mà bạn sử dụng trong BT này khi bạn muốn có AI chim này xung quanh. Vì nút hành động là bay, nên nó mong muốn thực thể được gắn vào, có thành phần bay. Nó sẽ truy vấn để có được nó, và sẽ làm việc với nó.

Bây giờ các thực thể của bạn có các thành phần được đính kèm và BT được đính kèm có thể có các nút trong BT đó hoạt động trên các thành phần của nó.


Câu trả lời này dường như cho rằng người đọc đã biết cây hành vi là gì và cách chúng hoạt động. Bạn có thể cải thiện nó bằng cách đưa ra một bản tóm tắt nhanh chóng hoặc ít nhất là đăng một liên kết đến một.
Philipp


Tôi tranh luận, bạn không nhất thiết phải thay đổi các thành phần trong BT, nhưng thêm / xóa các thành phần "thẻ" hoặc "điểm đánh dấu", rằng Hệ thống (bên ngoài cây) sẽ hoạt động trên thực thể có chứa các dấu / thẻ đã nói.
Seivan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.