Làm cách nào để quản lý tất cả các đối tượng NPC / AI trên máy chủ?


8

Tôi đang viết một MMO đơn giản và hiện đang có kiến ​​trúc máy chủ-máy khách để nhiều người dùng nhìn thấy nhau và có thể di chuyển cùng nhau ... giờ là lúc để thêm kẻ thù.

Đã tự hỏi nếu có ai có liên kết đến các bài viết thảo luận về cách xử lý tốt nhất hàng trăm đối tượng NPC cần được quản lý trên thế giới. Tôi đã thực hiện một số tìm kiếm và không thể tìm thấy nhiều thông tin về cách thức này thường được thực hiện.

Hai phương pháp cấu trúc việc thực hiện tôi có thể nghĩ ra:

  1. Giữ tất cả các đối tượng NPC được khởi tạo trong một danh sách và có một vòng lặp NPC Thread thông qua chúng một cách tuần tự và xem liệu mỗi đối tượng có bất kỳ logic nào cần được xử lý và thực hiện các hành động cần thiết hay không. Tôi không chắc hiệu suất của thiết kế này có đủ không?
  2. Hệ thống dựa trên sự kiện. Tạo một phương thức trong lớp NPC xử lý AI / Logic trên nó, có phương thức này được gọi khi một sự kiện liên quan được báo hiệu, trên bộ hẹn giờ cho chức năng AI không tương tác (như đi lang thang) hoặc báo hiệu sự kiện bên ngoài từ gói handler (người chơi di chuyển gần đó, hoặc người chơi tấn công trong phạm vi).

Là một trong những cách tiếp cận đúng cách? Những phương pháp khác để làm điều này tồn tại?

Câu trả lời:


5

Như mọi khi, kiến ​​trúc phụ thuộc vào yêu cầu của bạn. Bạn sẽ có bao nhiêu mob? AI của họ phức tạp đến mức nào? Nó phản ứng với cái gì? Làm thế nào thường xuyên nó thay đổi trạng thái của nó? Trả lời những câu hỏi này và bạn sẽ hiểu rõ hơn về những gì bạn muốn và làm thế nào để có được điều đó.

Nói chung, bạn muốn có ít nhất một số loại hệ thống sự kiện. AI thường được định nghĩa theo các sự kiện: "Khi A xảy ra, làm B"; và nếu bạn không có các sự kiện trong mã thực tế, bạn phải bằng cách nào đó dịch các định nghĩa này.

Theo kinh nghiệm của tôi, bạn có thể thoát khỏi việc thực hiện vòng lặp đơn giản khi bạn có một vài mob thực sự đơn giản (trái với những gì câu trả lời khác dường như gợi ý). Ví dụ, trong trò chơi hiện tại của chúng tôi, chúng tôi có hàng trăm trường hợp nhỏ với mỗi lần có tối đa 10 mob. Và những mob này là ngu ngốc; AI của 99% trong số họ có thể được mô tả trong một câu: "Tôi có tấn công ai không? Nếu không, hãy tấn công người chơi gần nhất". Trong trường hợp này, một vòng lặp đơn giản là quá đủ - hai lần một giây chúng tôi kiểm tra mục tiêu mới (và một vài thứ khác cho mob "thông minh" hiếm gặp), và điều đó thực hiện được.

Tuy nhiên, khi bạn có nhiều mob và / hoặc mob thông minh hơn, cách tiếp cận ngây thơ sẽ ngừng hoạt động. Để AI phản ứng với một số kích thích, bạn phải viết mã phát hiện nó bên trong vòng lặp AI của bạn. Ví dụ: giả sử mob của bạn nên làm gì đó "khi bị người chơi đánh". Với cách tiếp cận vòng lặp, không có cách nào dễ dàng để xác định mob bị tấn công. Khi AI đang chạy, bạn có thể kiểm tra xem sức khỏe của mob có bị giảm kể từ lần đánh dấu cuối cùng không, hoặc mob hiện đang được ai đó nhắm đến. Nhưng bạn không thể phát hiện các lượt truy cập thực tế mà không cần dùng đến hack, như lưu từng thông tin lần truy cập ở đâu đó để AI truy cập sau.

Thứ hai, một vòng lặp ngây thơ luôn luôn chạy, bất kể điều gì xảy ra. Khi bạn có nhiều mob, bạn muốn AI chạy nhanh nhất có thể .. và mã nhanh nhất là mã không bao giờ chạy cả. Nếu bạn có mob không hoạt động, bạn muốn chúng không chạy AI hoặc chỉ chạy nó một cách rời rạc (như trong, mob di động AI chỉ nên chạy khi nó quyết định đi đâu tiếp theo).

Với cách tiếp cận dựa trên sự kiện, bạn có thể yêu cầu các hệ thống con khác gửi các sự kiện AI bất cứ khi nào thuận tiện, loại bỏ vấn đề "phát hiện lượt truy cập". Tất nhiên, một số sự kiện vẫn sẽ yêu cầu phát hiện mã: ví dụ nổi tiếng nhất là sự kiện "tiếp cận". Và khi bạn không chạy thói quen AI của mình trong một vòng lặp khi không có gì xảy ra, bạn sẽ đạt được hiệu suất.

Bạn cũng có thể sử dụng một phương pháp lai. Thay vì xử lý các sự kiện AI ngay lập tức, bạn có thể nhét chúng vào một số loại hàng đợi. Sau đó, khi thói quen AI chạy (trong một vòng lặp), nó sẽ loại bỏ các sự kiện khỏi hàng đợi này và xử lý từng cái một. Với kiến ​​trúc này, hiệu suất AI có thể chậm hơn một chút, nhưng nó dễ dự đoán hơn; đồng thời, bạn có thể đảm bảo rằng tất cả AI chạy trên một luồng duy nhất (điều này có thể khó khăn nếu không). Loại vòng lặp này cũng có thể dễ dàng được điều chỉnh bằng cách bỏ qua một số sự kiện (ví dụ: mỗi lần lặp AI chỉ xử lý ba sự kiện gần đây nhất, loại bỏ phần còn lại). Hoặc các sự kiện có thể được ưu tiên và những sự kiện ít quan trọng hơn sẽ bị loại bỏ nếu phát hiện ra AI bị tụt lại.

Nhìn chung, phương pháp "vòng lặp với hàng đợi sự kiện" có lẽ là linh hoạt nhất. Nhưng tôi muốn nhắc lại: đừng chỉ chọn nó một cách mù quáng là "tốt nhất". Trước tiên hãy nghĩ về yêu cầu của bạn và một số cách tiếp cận đơn giản hơn có thể trở nên tốt hơn.


và chỉ cần hoàn thành câu trả lời này, bạn luôn có thể thêm mob hoặc xóa chúng khỏi vòng kiểm tra của bạn. ví dụ. khi không có ai quan sát mob đang làm gì thì thật không hợp lý để làm tất cả những việc mà NPC sẽ làm vào lúc đó. vì vậy bạn có thể dễ dàng lọc nhiều mob và chỉ cần kiểm tra xem những mob quan trọng (thông thường là những mob đủ gần với người chơi) có cần bất kỳ cập nhật nào không
Ali1S232

Là một "mob" một nhóm kẻ thù hay một kẻ thù duy nhất?
Richard Marskell - Drackir

"mob" là một kẻ thù duy nhất. Thuật ngữ này được đặt ra bởi Richard Bartle trong MUD1, và viết tắt của "mobile" - bởi vì mob di chuyển xung quanh, trái ngược với các đối tượng khác.
Nevermind

2

Nó sẽ phụ thuộc vào số lượng kẻ thù bạn có và mức độ hoạt động của chúng.

Nếu bạn có nhiều kẻ thù, nhưng họ không làm phần lớn thời gian, một hệ thống sự kiện có thể tốt hơn. Nếu bạn có kẻ thù thường làm gì đó, vòng lặp có thể hoạt động tốt nhất vì nó ảnh hưởng đến sự phức tạp của hệ thống sự kiện và bởi vì nếu sự kiện diễn ra, chúng sẽ liên tục nổ súng.

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.