Quản lý một số lượng lớn các tác nhân độc lập trong thời gian thực


8

Tôi đang làm việc trên một trò chơi chiến lược thời gian thực quy mô lớn - lý tưởng với hàng ngàn đơn vị hoạt động cùng một lúc - nhưng tôi gặp khó khăn trong việc quản lý tất cả các đơn vị cùng một lúc mà không trở nên chậm một cách đáng kinh ngạc. Vấn đề là phải mất một thời gian để cập nhật vị trí và trạng thái của mọi thứ mỗi bước. Bạn có biết bất kỳ mẫu thiết kế / phương pháp / mẹo để giảm thiểu điều này?


1
mặc dù câu hỏi của bạn có vẻ rất khác nhau, bạn có thể sử dụng cùng một thuật toán như được giải thích ở đây . không cần sử dụng xử lý song song trong thuật toán đó, chỉ với một lần duy nhất bạn sẽ có được hiệu suất cao.
Ali1S232

Song song với việc cập nhật sẽ không giúp ích gì nếu bạn có hai lõi và việc cập nhật một nửa trong số đó đã mất quá nhiều thời gian, nhưng nếu bạn có sẵn nhiều lõi và không sử dụng chúng, điều đó sẽ giúp ích. Lý tưởng nhất là bạn sẽ muốn một giải pháp không yêu cầu bạn cập nhật từng đơn vị từng bước một hoặc cách đơn giản hóa bản cập nhật để bạn có thể. Bước này lớn như thế nào? Nó độc lập với khung vẽ, phải không?
Blecki

4
Điều đầu tiên bạn có thể làm là nhận ra rằng tốc độ của bạn không liên quan gì đến số lượng diễn viên độc lập. Nó phải làm với những gì các diễn viên đang làm . Tôi có thể có hàng trăm nghìn diễn viên độc lập cập nhật> 60fps nếu tất cả những gì họ đang làm là if not dead position += 1hoặc một diễn viên cập nhật <1fps nếu nó đi vào một vòng lặp vô hạn. Một số thuật toán của bạn - một số phần trong những gì các đơn vị này đang làm - quá đắt so với cách bạn đang thực hiện chúng và đó là tất cả. Có lẽ có rất nhiều nguyên nhân có thể khác nhau, và rất nhiều chiến lược có thể khác nhau cho mỗi nguyên nhân.
doppelgreener

Câu trả lời:


4

Có hai điều khác biệt cần xem xét khi đo lường và tối ưu hóa hiệu suất của một hệ thống các thực thể quy mô lớn như vậy.

Ở mức độ thấp, bạn có đại diện vật lý cho các thực thể của mình có xu hướng sử dụng các bố cục lưu trữ hiệu quả như SoA (cấu trúc của mảng) để giảm chi phí lặp và cập nhật tất cả các thực thể hoạt động.

Ở cấp độ cao hơn, bạn có logic đưa ra quyết định, logic trò chơi chung, AI và tìm đường. Đây là tất cả các tác vụ có điểm chung là chúng không phải chạy ở cùng tốc độ cập nhật như kết xuất của bạn.

Vì bạn sẽ có thời gian khung hình không đồng đều nếu bạn thực hiện phương pháp ngây thơ khi chỉ thực hiện các tác vụ đó trên mỗi khung hình N, có xu hướng có lợi khi khấu hao chi phí qua nhiều khung hình.

Nếu bản chất nhiệm vụ là tăng dần, bạn có thể chạy một phần của thuật toán mỗi khung và sử dụng một phần kết quả trong các bản cập nhật của bạn.

Nếu tác vụ phần lớn là nguyên khối nhưng có thể tách rời cho mỗi thực thể, bạn có thể thực hiện tác vụ đó cho một tập hợp con của các thực thể trò chơi của mình trên mỗi khung, xoay vòng giữa chúng theo kiểu vòng tròn. Điều này có lợi ích là giảm sự phức tạp của những thứ như tìm đường và AI, vì bạn không có ai cố gắng hành động cùng một lúc.

Trong RTS chiến thuật quy mô lớn mà tôi đã làm việc, chúng tôi tập trung vào việc có các cấu trúc dữ liệu mạnh mẽ để truy vấn biểu diễn cấp thấp trong các thuật toán cấp cao, để tìm hàng xóm của các thực thể trò chơi. Quá trình cập nhật cấp thấp đã hành động theo ý định được cung cấp bởi mô phỏng cấp cao cập nhật chậm, và cuối cùng đã biến thành một mô phỏng hạt giá rẻ, mở rộng ra hàng ngàn.


+1. Suy nghĩ của tôi chính xác, đặc biệt là giảm logic xuống các nhóm được quản lý chỉ được xử lý sau mỗi vài chu kỳ, với tất cả các nhóm như vậy có khả năng được đặt so le để xử lý.
Kỹ sư

1

theo như tôi có thể nhớ, bạn sẽ luôn có ít hơn 10.000 đơn vị một trò chơi. Không có trò chơi nào tôi có thể nhớ nhiều hơn con số đó, mặc dù trái đất đế chế có thể lên tới 14000 máng nhưng không ai có thể đạt đến điểm đó. vì vậy chỉ cần có một mảng tĩnh gồm 10.000 đối tượng dường như là nhiều hơn mức cần thiết.

như bạn biết, việc lặp lại hơn 10000 đối tượng không phải là vấn đề lớn nhưng nó có thể tiêu tốn rất nhiều thời gian nếu thuật toán của bạn chạy chậm hơn O (n). ví dụ: nếu bạn thử kiểm tra hai đối tượng để phát hiện va chạm thì sẽ mất thời gian O (n ^ 2), điều đó có nghĩa là rất nhiều thời gian. vì vậy bạn phải phá vỡ các thuật toán của bạn bằng cách nào đó. hãy xem lại một thuật toán mẫu cho mọi thứ mà tôi có thể nghĩ ra ngay bây giờ:

  1. phát hiện va chạm: đối với mọi thuật toán phát hiện va chạm, bạn phải kiểm tra hai đối tượng nhưng bạn có thể loại bỏ một số kiểm tra bắt đầu các vòng lặp. như tôi đã đề xuất trong các bình luận, bạn có thể sử dụng cùng một thuật toán cho câu hỏi này . không cần sử dụng nhiều luồng hoặc bất cứ thứ gì, ngay cả với một luồng và 4 vùng, bạn sẽ giảm kiểm tra từ n * (n-1) xuống 4 * (n / 4) ((n-1) / 4), và bằng cách tối ưu hóa số vùng, bạn có thể nhận được kết quả tốt hơn nữa. Tôi nghĩ bằng cách sử dụng các vùng số tốt nhất, bạn thậm chí có thể truy cập O (n log (n)).

  2. bạn phải tạo đường dẫn cho từng đối tượng chuyển động. hệ thống thông thường mà tôi đã thấy cho đến nay là một điều rất đơn giản: bất cứ khi nào người chơi ra lệnh cho các đơn vị di chuyển đến một nơi nào đó, máy tính sẽ tính toán đường đi của nó, sau đó trong mỗi chu kỳ nếu đối tượng có thể di chuyển thì nó không thể bỏ qua chu kỳ đó. không có gì đặc biệt. mặc dù bạn cũng có thể thay đổi các thuật toán được cung cấp ở đây để giảm đường dẫn tìm cuộc gọi và tìm đường dẫn thời gian thực cho từng nhóm đơn vị nhưng điều đó thực sự không cần thiết.

  3. bạn phải kiểm tra xem một số viên đạn hoặc bom hoặc vật tương tự có trúng một trong các đơn vị không: bạn có thể sử dụng cùng một khu vực bạn đã tạo để phát hiện va chạm tại đây.

  4. để chọn đơn vị, bạn cũng có thể sử dụng các vùng tương tự.

nói chung tôi sẽ đề nghị sử dụng một mảng tĩnh (hoặc một mảng động với kích thước dành riêng) tối đa 10.000 hoặc 20.000. sau đó sử dụng một cái gì đó khoảng 10 hoặc 15 vòng lặp mỗi vòng lặp trên tất cả các đơn vị. đó là một mảng lớn thực sự chứa tất cả các đơn vị từ tất cả người chơi. vì vậy mỗi chỉ mục có cả dữ liệu về chủ sở hữu đơn vị và loại đơn vị. bạn cũng tạo một số mảng khác cho mỗi người chơi. trong mỗi chỉ mục của mảng thứ cấp này, bạn sẽ chỉ phải lưu trữ các con trỏ tới các đối tượng trong mảng chính.

nếu bạn có bất kỳ câu hỏi nào khác, hãy đặt ý kiến ​​để thêm chúng vào câu trả lời của tôi.


Tôi nhớ có hơn 40.000 trong Empires Dawn of the Modern World :). Xấu hổ là trình kết xuất chỉ có thể giữ khoảng 1000 trên màn hình mặc dù trước khi chúng bắt đầu biến mất, nhưng phần còn lại của trò chơi hoạt động tốt :).
deceleratedcaviar

@daniel: đó không phải là vấn đề lớn, các tướng không có bất kỳ giới hạn nào về số lượng đơn vị. Tôi chỉ đưa ra một số phép đo số lượng đơn vị tốt để làm cơ sở cho các phép tính toán của tôi. 40000 và 10000 không khác nhau lắm.
Ali1S232
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.