Cách xử lý số lượng lớn xe bán tải trong trò chơi MMO


26

Làm thế nào để các trò chơi như Minecraft, hoặc thực sự bất kỳ trò chơi MMO nào có bán tải, xử lý chúng?

Nói địa hình sinh ra 3 giọt "bụi bẩn" mỗi khi bạn đào địa hình nói. Nói mỗi mục có một hình ảnh động xoay được tính toán mọi khung hình. Nếu số lượng xe bán tải trên thế giới tăng rất cao, đó sẽ là một chi phí khổng lồ vô dụng trong tính toán khung cho một khách hàng trong một máy chủ nhất định, vì rất có thể những món đồ bán tải đó cách bạn rất nhiều năm.

Vì vậy, điều tôi nghĩ là bạn phải "làm công cụ" chỉ với những chiếc xe bán tải gần với người chơi cục bộ, nhưng điều này sẽ ám chỉ rằng mọi khung hình tôi phải kiểm tra xem có bất kỳ vật phẩm đón nào khác đủ gần để nó bắt đầu hoạt hình không.

Câu hỏi thực tế của tôi là: các MMO khác đã giải quyết vấn đề này như thế nào?


9
Ngoài ra, trong ngữ cảnh của Minecraft, sau khi một số lượng vật phẩm nhất định gần đủ với nhau (3+ vật phẩm trong cùng một khối), máy chủ sẽ thay thế 3 trường hợp bằng một thể hiện được nhóm có chứa loại khối ( minecraft:dirt) và số đếm (30), để khi người chơi đủ gần để nhặt nó, nó chỉ cần thêm càng nhiều số lượng có thể vào kho của người chơi. Nếu người chơi chỉ có đủ chỗ cho 6 vật phẩm và một chồng 30 trên mặt đất, người chơi sẽ nhặt được 6 vật phẩm và số lượng trên mặt đất được giảm xuống còn 24.
Zymus

6
@Zymus Điều đáng chú ý là thực sự giảm hiệu suất đánh dấu cho số lượng vừa phải của các mặt hàng bị bỏ vì tất cả chúng đều liên tục tìm kiếm những thứ gần đó.
dùng253751

Câu trả lời:


48

Bằng cách đơn giản chỉ tải những phần của thế giới vào bộ nhớ gần với người chơi. Bất cứ điều gì khác bị đình chỉ vào ổ cứng. Khi có một vật thể nhỏ nằm cách đó khoảng hai km, thì người chơi không thể nhìn thấy nó và không thể tương tác với nó. Vì vậy, không có lý do gì để cập nhật hoặc gửi nó đến GPU để kết xuất. Đối tượng càng nhỏ và phạm vi tương tác của nó, phạm vi xung quanh trình phát mà bạn cần tải nó càng thấp.

Về việc tìm hiểu những gì gần gũi với người chơi: Điều đó chủ yếu tập trung vào việc lưu trữ thế giới trong một cơ sở hạ tầng được tối ưu hóa để tra cứu không gian. Ứng cử viên tốt cho những người là băm không giancây đa chiều .


Cảm ơn vì sớm phản hồi. Tôi đã suy nghĩ về việc sử dụng Unity vì tôi đoán nó sử dụng một loại phân vùng không gian để kiểm tra trình kích hoạt trình kích hoạt, vì vậy tôi sẽ tạo một trình tạo vòng tròn lớn xung quanh nhân vật của mình và mọi vật phẩm bên trong nó sẽ là "hoạt hình". Đây có phải là một cách để thực hiện câu trả lời của bạn? Sửa lỗi cho tôi nếu tôi sai, chúc mừng!
Alakanu

2
@Alakanu Nó có thể được sử dụng nếu bạn muốn các vật thể nhìn thấy được ở khoảng cách xa nhưng chỉ thực hiện một số hành vi cường độ tính toán nhất định khi ở gần người chơi (và chỉ xoay một cái gì đó quanh trục y của nó không nên rất tốn kém). Nhưng thách thức thực tế khi thực hiện một trò chơi thế giới mở trong Unity là khởi tạo và tiêu diệt các đối tượng trò chơi một cách thông minh trong khi người chơi di chuyển khắp thế giới (hoặc thậm chí tốt hơn: sử dụng nhóm đối tượng thay vì kích hoạt và phá hủy).
Philipp

Vâng, nhóm đối tượng là bắt buộc trong tình huống này :) Ok cảm ơn bạn rất nhiều!
Alakanu

3
@Alakanu Bạn có thể kiểm tra khái niệm "Loaded Chunks" của Minecraft để biết thêm thông tin về cách câu trả lời này áp dụng cho trò chơi đó.
T. Sar - Tái lập Monica

1
Điều này không chỉ đúng với xe bán tải. BẤT K object đối tượng quá xa người chơi có thể được đối xử theo cách đó. Đôi khi, ngay cả những đồ vật gần gũi với người chơi. Hãy tưởng tượng một ngôi nhà với nội thất đầy đủ nhưng không cần phải kết xuất cho đến khi bạn thực sự bước vào nhà.
Zibelas

22

Bạn có hai thứ rất khác nhau để quản lý:

  1. Máy chủ phải quản lý toàn bộ thế giới, theo cách có thẩm quyền. Vì thế, việc liên lạc với N khách hàng (trong đó N là "lớn") là cần thiết.

  2. Về nguyên tắc, khách hàng có thể biết về toàn bộ thế giới, nhưng không cần . Đối với khách hàng, việc biết người chơi gần đó là đủ. Ví dụ, giả sử phân vùng giống như lưới khá thô, chỉ cần biết ô của người chơi và 26 ô xung quanh trình phát (hoặc 8 ô trong trường hợp bạn có lưới 2D). Một lưới tốt hơn một chút là tốt hơn, nhưng bạn có ý tưởng.

Bây giờ, rất nhiều xe bán tải, "rất nhiều" là gì? Bạn có thể đào 5 thứ mỗi giây, đó có thể là hai chục số cần được cập nhật trên máy chủ và máy chủ có thể phải truyền chúng cho một số người chơi khác có khu vực quan tâm chồng lên ô của bạn. Đối với một máy tính, đây là lượng dữ liệu khá vô lý và một lượng tính toán không đáng có. Nó có thể trở thành một thách thức khi có hàng trăm / nghìn người chơi trong cùng một ô (khi đó việc phân nhóm của bạn quá thô thiển).

Máy chủ không cần biết, cũng không quan tâm đến vòng quay của xe bán tải hoặc các chi tiết như vậy. Tại sao nó?

Khách hàng thực sự cũng không quan tâm, vì đây chỉ là trò vui mắt mà khách hàng có thể trang điểm nhanh chóng.

Điều cần thiết từ quan điểm của máy chủ là biết rằng bạn đang đào (30, 40, 50) trong nút bạn đang ở và nó quyết định rằng điều này sinh ra, ví dụ như ba đối tượng loại 5 hoặc một đối tượng loại 7 với tổng số 3. Đó là tất cả những gì nó quan tâm, và đó là tất cả những gì nó nói với bạn. Nó cũng sẽ bao gồm thông tin trong dữ liệu được gửi cho ai đó di chuyển khu vực quan tâm của anh ta qua ô lưới sau đó (giả sử sau đó nó vẫn còn ở đó).

Khách hàng được nói với ba đối tượng sinh ra ở đó, blah blah. Bây giờ, cho dù khách hàng có hiển thị bản đồ nghệ thuật ASCII trong đó giờ là 'D' hay liệu nó có hiển thị một đống bụi bẩn đang quay hay không, tất cả đều giống nhau. Cho dù các cọc có các góc quay khác nhau hay chỉ các cọc gần với trình phát của bạn cũng giống nhau. Nó chỉ là thứ được hiển thị trên màn hình của bạn, nó không ảnh hưởng đến bất kỳ ai khác.

Vì vậy, trong trường hợp cụ thể mà bạn muốn chỉ xoay các đống bụi bẩn gần đó, bạn có thể thực hiện kiểm tra phạm vi trên tất cả các đối tượng bạn biết. Vì tập dữ liệu không lớn, thậm chí vũ phu đối với mọi thứ sẽ hoạt động.

Bạn có thể (và nên) tùy thuộc vào kích thước phân vùng của mình, cắt tỉa các ô lưới quá xa.

Tất nhiên, bạn có thể phân vùng phụ của tế bào của bạn và sử dụng một cái gì đó siêu thông minh. Sử dụng cây kd-Tree nếu bạn muốn, nhưng đừng mong đợi lợi nhuận khổng lồ. Bạn có thể cắt tỉa đồ đạc với Manhattan distace, hoặc bạn có thể sắp xếp đồ đạc của bạn trong một lưới nhỏ của riêng bạn ... nhưng tại sao?

Kiểm tra khoảng cách (khoảng cách thực sự bình phương, nhưng nó giống với bạn) chỉ là hai phép nhân và phép cộng (được tối ưu hóa cho MUL, MADD, do đó thực sự chỉ là hai thao tác), tiếp theo là một nhánh hoặc di chuyển có điều kiện. Đó là khá nhanh như bất kỳ hoạt động khác mà không cắt tỉa toàn bộ các ô lưới tại một thời điểm. Trên thực tế, đây là điều mà bạn thậm chí có thể làm trên GPU ...

Xem cách bạn sẽ có vài trăm hoặc nhiều nhất là vài nghìn kiểm tra khoảng cách so với cùng một vị trí (khoảng cách bình phương hoạt động tốt), bạn thực sự không gặp nhiều khó khăn khi thực hiện phép tính đó, thậm chí nhiều hơn vì nó khá là bộ nhớ cache- lặp đi lặp lại thân thiện trên bộ nhớ tiếp giáp, và với các động thái có điều kiện, nó rất rẻ. Một cái gì đó như (mã giả) rot = r[i] + 1; r[i] = ((dx*dx+dy*dy) < DIST_SQ) ? rot : r[i];. Đó là một lần lặp trên một mảng vài trăm giá trị trên mỗi khung. Máy tính không quan tâm đến việc thực hiện điều đó, đó là tải và lưu trữ liền kề, ALU đơn giản, không có chi nhánh và chỉ vài nghìn lần lặp.

Điều này (nhiều-một) không phải là cùng một loại vấn đề (nhiều-nhiều) như trên máy chủ. Thực sự, khách hàng không phải là vấn đề.


Tôi xin lỗi, tôi nghĩ rõ ràng rằng tôi đã nói về một khách hàng khi tôi bắt đầu nói về tốc độ khung hình.
Alakanu

1
Nhưng khách hàng không bao giờ là vấn đề. Máy khách rất nhiều không lớn và rất nhiều cục bộ, nó cần biết ít hơn nhiều so với máy chủ. Lý tưởng nhất, khách hàng biết nút phân vùng không gian (dù đó là gì, nói là lưới) mà người chơi đang ở và những người xung quanh ngay lập tức, và đó là nó. Các cập nhật vì thế rất khiêm tốn trừ khi một ngàn người chơi đứng cạnh nhau. Thông thường, bạn chỉ cần deltas cho một hoặc hai đối tượng và nội dung của nút lưới mới sau khi di chuyển về một hướng trong hơn một nửa chiều rộng của nút. Mọi thứ khác: Không phải vấn đề của bạn.
Damon

1
Vấn đề là quá thông minh có thể là một ý tưởng ngu ngốc ồ ạt. Thế giới của bạn nhất thiết phải được phân chia theo không gian, với số lượng đối tượng có thể quản lý được trong mỗi nút. Các CPU hiện đại (và GPU thậm chí còn hơn thế) rất giỏi trong việc xử lý tuần tự các khối dữ liệu SoA. Họ không thích phân nhánh không liên tục và họ thích truy cập bộ nhớ không liên tục thậm chí ít hơn - đó chính xác là những gì "chỉ xử lý gần đó" làm. Đối với các số có thể quản lý (vài trăm, vài nghìn), "xử lý tất cả" trong một ô là hoàn toàn đầy đủ và có thể là điều tốt nhất bạn có thể làm.
Damon

1
@Alakanu Đây giống như một câu trả lời chi tiết và đầy đủ cho câu hỏi của bạn, với tôi. Nếu bạn nghĩ rằng đó không phải là một câu trả lời, thì bạn đã hiểu nhầm nó hoặc câu hỏi của bạn không rõ ràng đến mức nó bị Damon hiểu lầm, tôi và tất cả những người đã đưa ra câu trả lời này.
David Richerby

2
@Alakanu Bạn thực sự dành một lượng lớn thời gian để phàn nàn với những người đang cố gắng giúp đỡ bạn. Chúc may mắn với điều đó.
David Richerby

2

@ T.Sar viết trong một bình luận rằng bạn nên xem xét khái niệm "chunk nạp" của Mineccraft để biết thêm thông tin. Nếu bạn làm như vậy, hãy lưu ý rằng điều này khá phức tạp trong Minecraft do mọi người chế tạo máy trong trò chơi.

Một phiên bản rất đơn giản sau:

Thế giới được chia thành các khu vực vuông (chunk). Trong Minecraft cũng có sự phân chia chiều cao nhưng hầu hết các mmos không cần điều đó.

Khách hàng trò chơi chỉ quan tâm đến các khu vực gần với người chơi. Điều này đơn giản hơn nhiều so với vẽ một vòng tròn xung quanh người chơi, nhưng hoàn toàn đủ tốt.

Trong Minecraft, các vùng là các khối 16x16 và khách hàng biết về các vùng 9x9, 4 vùng ở mỗi hướng. (4 khu vực phía đông + khu vực người chơi ở + 4 khu vực phía tây = tổng cộng 9 khu vực. Cùng phía bắc / nam)

Không có gì kỳ diệu về những con số này, sử dụng bất cứ điều gì có ý nghĩa trong trò chơi của bạn.

Khách hàng chỉ hoạt hình những thứ bên trong khu vực này. Máy chủ chỉ tính toán những thứ như quái vật lang thang ở những khu vực gần với một số người chơi.

Khi một người chơi đi bộ xung quanh bên trong một khu vực, không có gì đặc biệt xảy ra, khi họ đi qua một khu vực biên giới, "cạnh của hoạt hình" được đẩy lên một khu vực. Sau đó, khách hàng cần hỏi máy chủ về các khu vực mà nó hiện nhìn thấy.

Không có gì sai khi có một số giới hạn hoạt hình lồng nhau. Ví dụ, vật phẩm animate rơi trong khu vực 3x3, quái vật lang thang trong khu vực 5x5 và chỉ hiển thị cảnh quan trong khu vực 9x9.

Máy chủ giữ một "phiên bản đóng băng" của các khu vực mà không người chơi nào nhìn thấy. Nếu việc này chiếm nhiều bộ nhớ, bạn có thể muốn dỡ chúng sau một thời gian. Khi một người chơi tiếp theo đến, khu vực được tải lại mà không có vật phẩm nào bị rơi. Lần sau bạn cần nhanh hơn, Người chơi 1.


Khoảng cách vẽ có thể điều chỉnh nhưng trong trường hợp này, 8 khối là 9x9 và là quyết định phía máy khách, nó có thể thông báo cho máy chủ để tăng tốc mọi thứ (vì vậy máy chủ không gửi dữ liệu mà máy khách sẽ không hiển thị). Ngoài ra ... không phải Doom và Quake giải quyết vấn đề đó về việc chỉ hiển thị những gì có ý nghĩa?
SparK

Về việc xem thường các vật phẩm bị rơi ... trong minecraft, vật phẩm chỉ "có tuổi" khi có người chơi ở gần đó. Vì vậy, bạn có thể "lưu" một vật phẩm bị rơi vào một khối không tải và lấy nó sau.
SparK
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.