Có cách nào để tạo ra một thế giới năng động như MMORPG có thể mở rộng theo chiều ngang không?


11

Hãy tưởng tượng một thế giới mở gồm hơn 500 người chơi với dữ liệu thay đổi nhanh như 20 cập nhật / người chơi / giây. Lần trước tôi đã làm việc trong một MMORPG tương tự, nó đã sử dụng SQL, vì vậy, nó không thể truy vấn DB mọi lúc. Thay vào đó, nó tải tất cả người chơi từ DB vào bộ nhớ dưới dạng đối tượng C ++ và sử dụng chúng. Đó là, nó được thu nhỏ theo chiều dọc. Thay vào đó, có thể làm cho máy chủ đó có thể mở rộng theo chiều ngang không? Có một cơ sở dữ liệu được thiết kế để hỗ trợ số lượng cập nhật đồng thời không?


Tại sao bạn muốn cập nhật trình phát trong cơ sở dữ liệu 20 lần / giây?
Balon

@Balon đó là nơi tôi bối rối. Nếu tôi không cập nhật nó trong cơ sở dữ liệu, chỉ trong bộ nhớ, thì tôi sẽ có các trạng thái khác nhau giữa các máy khác nhau. Nhưng tôi đoán các bản cập nhật DB có một số chi phí khổng lồ để nó không thực sự hoạt động với số lượng cập nhật đó?
MaiaVictor 23/03/13

2
Nếu bạn thực sự, thực sự nghĩ rằng các máy khác nhau (hoặc thậm chí các quy trình) cần cập nhật 20Hz trên hàng trăm đối tượng thì hoàn toàn bỏ qua cơ sở dữ liệu và sử dụng trực tiếp hệ thống nhắn tin. Nhưng những gì bạn thực sự, thực sự nghĩ rằng bạn muốn không phải là những gì bạn thực sự muốn. Những gì bạn muốn là có một phạm vi lành mạnh của những người cần biết những gì và sau đó có một cách để vận chuyển gọn gàng các đối tượng giữa các phạm vi trên đó. Bạn nên trả lời câu hỏi tại sao bạn cần cập nhật 20Hz giữa các máy khác nhau để có câu trả lời tuyệt vời, ai đó có thể nghĩ ra một cách mới để xem xét vấn đề.
Patrick Hughes

@PatrickHughes Tôi không biết mình cần gì, tôi chỉ giải thích cách trò chơi hoạt động. Nhân vật di chuyển 2 ~ 3 gạch / giây. Một người chơi săn bắn có thể được bao quanh bởi một vài quái vật, vì vậy ít nhất 10 gạch / người chơi / giây. Sau đó, có những vật phẩm mục nát trên sàn nhà, trên ba lô của người chơi. Có những cuộc tấn công di chuyển theo hướng của người chơi, có những cuộc tấn công di chuyển theo hướng của quái vật. Có sự suy giảm sức khỏe, mana đang được sử dụng, tính giờ gây sát thương độc cho người chơi. Vì vậy, mọi thứ thay đổi thực sự nhanh chóng. Đây là thiết kế trò chơi. Làm thế nào thiết kế như vậy có thể được thu nhỏ theo chiều dọc?
MaiaVictor 24/03/13

1
Tôi thấy điều này trên HackerNews một thời gian ngắn trước: paralleluniverse.co Họ đang làm việc trên một cơ sở dữ liệu mà làm tất cả các công cụ phân / phân bố không gian cho bạn. Tôi đoán rằng dưới mui xe, họ đang làm tất cả những điều trong câu trả lời dưới đây.
kéo

Câu trả lời:


17

Trường hợp thử nghiệm gồm 500 người chơi đang liên lạc, đó là luồng thông tin 250K bay xung quanh ở tần số 20Hz. Băng thông nội bộ cho điều đó sẽ là, giả sử 100 byte mỗi tin nhắn, khoảng 500MB / giây. Âm thanh đầy tham vọng. Đặc biệt là giữa các quá trình.

Nếu bạn tách người chơi thành các nhóm 100 người, điều đó sẽ giảm xuống còn 20MB / giây, v.v. Đó là lý do tại sao các MMO có các vùng và trong các vùng đó ít bong bóng ảnh hưởng, và cứ thế giảm dần cho đến khi băng thông trở nên hợp lý.

Vấn đề ban đầu có thể được nói rằng nếu bạn có 10 người chia sẻ thông tin theo thời gian thực, nhưng bạn muốn có tất cả 500 chia sẻ , đó là sự tăng trưởng theo cấp số nhân của các liên kết truyền thông và làm thế nào chúng ta có thể khắc phục điều đó . Tôi sợ rằng không có viên đạn ma thuật nào mà tôi từng nghe nói có thể làm cho tiến trình hình học biến mất một cách kỳ diệu.

Không sử dụng cơ sở dữ liệu để liên lạc, đó là những gì nhắn tin dành cho. Sử dụng cơ sở dữ liệu để thực thi các giao dịch và lưu trữ thông tin mà bạn không muốn người chơi bị mất. Hầu hết các MMO mà tôi quen thuộc chỉ cập nhật cơ sở dữ liệu với thông tin người chơi động cứ sau 1-10 phút hoặc tại các điểm tiện dụng như chuyển vùng hoặc vào vùng "an toàn" trong thiết kế.

Bạn có thể phải thiết kế lại nhu cầu của trò chơi cho mọi người chơi, bất kể ở xa, để có các cập nhật theo thời gian thực của mọi nội dung ba lô của người chơi khác.

Đồng thời thay đổi mẫu cập nhật từ 20Hz thành tốc độ dựa trên khoảng cách, một người nào đó cách xa 1 dặm không cần biết rằng bạn đã di chuyển 1 feet trong đúng 230,6 giây, sau đó một chân khác ở mức 231,4 giây, họ có thể đối phó với bạn di chuyển 15 feet cứ sau 10 phút giây


Câu trả lời tuyệt vời và nhiều thông tin, cảm ơn. Nhưng tôi có thể nói thêm rằng trong khi thế giới thay đổi với tốc độ rất nhanh, một người chơi chỉ có thể thấy những người chơi khác ngay bên cạnh mình. Tôi không thấy nó là hình học - 500 người chơi gửi thông tin đến máy chủ; máy chủ định kỳ gửi thông tin cho 500 người chơi đó. Đó là tuyến tính, như tôi thấy. Nhưng điểm chính nằm ở đoạn thứ 4: nếu tôi chỉ sử dụng cơ sở dữ liệu để lưu trữ thì tôi đang tải dữ liệu vào bộ nhớ. Nếu tôi đang tải dữ liệu vào bộ nhớ trong một máy, tôi đang tạo một phiên bản không đồng bộ của thế giới. Đó là những gì tôi không nhận được.
MaiaVictor 24/03/13

Đối với 1 khách hàng: 1 tin nhắn ra + 1 tin nhắn trong = 2. Đối với 2 khách hàng: 2 tin nhắn ra, 2 tin nhắn trong = 4. Đối với 3 khách hàng: 3 tin nhắn ra, 3 tin nhắn trong = 9. Và cứ thế. Nó giống như thế này: gửi một thông điệp trạng thái, máy chủ gửi kết quả cho tôi và 2 khách hàng khác (1 trong, 3 ra) và 3 khách hàng đều làm điều đó (1 trong 9 trên 9). Mặc dù có vẻ tuyến tính đối với chỉ một khách hàng trong số 3 khách hàng, nhưng bạn có thể nhân số đó với tất cả các khách hàng cho tổng thông lượng của hệ thống. Đối với desync, ngay cả các quy trình trên cùng một hộp vật lý cũng không đồng bộ cho đến khi thông báo trạng thái được tạo và gửi, đó chỉ là vấn đề đường ống trống, RAM cục bộ hoặc mạng.
Patrick Hughes

5

Sử dụng diện tích lọc quan tâm. Nếu một thế giới được chia thành 3 máy chủ và khu vực trên máy chủ 1 không ở gần khu vực của máy chủ 3, không có lý do gì để họ chia sẻ thông tin về các thực thể cả.

Tương tự, trên một máy chủ, chỉ gửi thông tin liên quan đến khách hàng. Nếu người chơi A ở phía đối diện hoàn toàn trên bản đồ từ người chơi B, không có lý do gì để gửi thông tin cập nhật về B đến A hoặc ngược lại.

Khi bạn có nhiều máy chủ trong một thế giới liên tục, bạn sẽ có các thực thể gần một cạnh trên máy chủ 2 gần với các thực thể trên máy chủ 1. Bạn có thể gửi các bản cập nhật từ máy chủ "có thẩm quyền" cho một thực thể đến máy chủ khác (khi thích hợp) và tương tự chuyển tiếp bất kỳ tin nhắn nào đến máy chủ có thẩm quyền nếu thích hợp.

Có, trong trường hợp này, một máy chủ sẽ hơi lỗi thời đối với các thực thể cụ thể. Đừng cố gắng giải quyết điều đó. Chỉ cần đối phó với nó. Giả sử rằng các thực thể có thể là một chút lỗi thời. Thực hiện bất kỳ logic nào cần thông tin cập nhật chỉ trên máy chủ sở hữu chính thức các thực thể. Khi một thực thể ảnh hưởng đến một thực thể khác, hãy gửi một tin nhắn và cho rằng nó có thể mất nhiều dấu logic logic trò chơi trước khi nó được xử lý và chế độ xem của bạn cập nhật.

Thiết kế này cũng làm cho nó dễ dàng hơn nhiều để xâu chuỗi một máy chủ. Không có thực thể nào nên trực tiếp sửa đổi một cái khác, chỉ gửi tin nhắn và bộ đệm proxy cho mỗi máy chủ / mỗi luồng cục bộ nên được coi là hơi lỗi thời.

Ví dụ: nếu thực thể A tấn công thực thể B, đừng kiểm tra tuổi thọ của B và sau đó gửi tin nhắn tử vong nếu nó chạm 0. Chỉ cần gửi tin nhắn "bị hỏng", hãy để máy chủ có thẩm quyền cho B xử lý, sau đó xử lý bất kỳ Thông báo "thực thể đã chết" được gửi bởi máy chủ B sau đó nếu thực thể A quan tâm đến điều đó.

Điều tương tự cũng áp dụng cho bất kỳ ứng dụng phi trò chơi lớn, có thể mở rộng. Một cơ sở dữ liệu trung tâm không phải là một công nghệ chia sẻ tức thì kỳ diệu. Hai máy chủ phải liên lạc với các tin nhắn, không đồng bộ, theo đợt, để duy trì thông lượng cao. Do đó, sự phổ biến của các công nghệ như AMPQ và tương tự. Cơ sở dữ liệu là để lưu trữ và hỗ trợ đồng bộ hóa ngoài sự cần thiết cho phép chúng được sử dụng để liên lạc, không phải vì bản thân chúng có nghĩa là để đồng bộ hóa hoặc liên lạc.


Cảm ơn, điều này đã chấm dứt hầu hết những nghi ngờ còn lại của tôi. Ngoài ra, bạn đã cho tôi ý tưởng ngăn cách các máy chủ của người chơi, không phải các khu vực - điều này sẽ trông mượt mà hơn. Mỗi máy chủ chăm sóc x người chơi. Tôi thực sự thích điều này! Cái này có dùng không? Ngoài ra, chỉ còn một điều nữa. Như tôi đã hỏi ở trên, tôi vừa tìm hiểu về cơ sở dữ liệu NoQuery mới, Couchbase. Nó được cho là giống như CouchDB, ngoại trừ với tốc độ ghi / đọc rất nhanh: lên tới 200k cập nhật mỗi giây! Có lẽ điều này thực sự có thể hoạt động như một "mô hình thế giới chia sẻ thời gian thực" như vậy, hoặc chưa?
MaiaVictor

Tôi không biết liệu kỹ thuật đó có được sử dụng ngoài tự nhiên bên cạnh việc "lột xác" thông thường của các máy chủ hay không. Chỉ cần làm điều đó bởi người chơi và khu vực địa lý có nghĩa là mỗi máy chủ có thể cần phải biết về một số lượng rất lớn các thực thể trên một tập hợp các khu vực khác nhau, tăng tải máy chủ và tăng đáng kể liên lạc giữa các máy chủ. Thực hiện theo khu vực có nghĩa là máy chủ của bạn có thể bị quá tải trên các khu vực đông người (mặc dù bạn có thể tự động phân chia và tham gia các khu vực trong trường hợp đó), nhưng có nghĩa là mỗi máy chủ có một tập hợp nhỏ hơn các thực thể và hình học không liên quan để theo dõi .
Sean Middleditch

@Dokkat: Có thể có một số loại "khu vực mềm" nơi bạn có mỗi máy chủ chủ yếu xử lý người chơi trong một phần cụ thể của thế giới trò chơi, nhưng họ sẽ bàn giao người chơi một cách minh bạch cho máy chủ khác nếu họ đi quá xa khu vực máy chủ ban đầu của họ. Bạn chỉ cần đảm bảo rằng việc bàn giao đủ trơn tru để người chơi không thực sự chú ý đến nó. Bạn thậm chí có thể thử sử dụng một số kỹ thuật thích ứng lạ mắt để giữ các cụm người chơi tương tác trên cùng một máy chủ, ngay cả khi chúng chỉ nằm trên ranh giới khu vực.
Ilmari Karonen

3

Bạn có thể sẽ quan tâm đến bài viết này trên Gamasutra , nơi các nhà phát triển của Eve Online thảo luận về cách có thể thành công khi chạy một trò chơi với 400 000 người chơi đang hoạt động ... trong một cơ sở dữ liệu SQL.


2

Đừng nghĩ về cơ sở dữ liệu như một mô hình thế giới chia sẻ thời gian thực nào đó lưu trữ mọi thứ về mọi thứ mọi lúc - như bạn đã nhận thấy, điều đó không thể thực hiện được.

Thay vào đó, hãy coi cơ sở dữ liệu giống như một tệp lưu được cập nhật tự động: thỉnh thoảng bạn chỉ cập nhật cơ sở dữ liệu, chẳng hạn như khi người chơi đăng nhập hoặc đăng xuất hoặc di chuyển từ vùng này sang vùng khác hoặc bất cứ khi nào điều gì quan trọng xảy ra mà bạn không muốn mất trong trường hợp máy chủ gặp sự cố.

Trạng thái thế giới thời gian thực thực tế phải được giữ bởi các máy chủ trò chơi, trong bộ nhớ, giống như trong ví dụ ban đầu của bạn. Bây giờ, mẹo cho quy mô ngang là không phải mọi máy chủ đều cần biết mọi thứ ở mọi thời điểm . Ví dụ, nếu người chơi A đang chơi ở khu A trên máy chủ A, B máy chủ chạy Khu B thường không cần phải biết những gì người chơi A có trong ba lô của họ - và, nếu nó không cần phải biết rằng đối với một số lý do (nói, bởi vì người chơi B trong khu vực B đưa ra một loại phép thuật gián điệp từ xa trên A), nó chỉ có thể yêu cầu máy chủ khác cung cấp thông tin đó .

Điều này đòi hỏi bạn phải phân công trách nhiệm rõ ràng cho các máy chủ, để khi máy chủ B muốn biết về ba lô của người chơi A, nó sẽ biết máy chủ nào có thông tin chính thức về điều đó. Bạn cũng có thể muốn bao gồm một số loại cơ chế đăng ký cập nhật, do đó, ví dụ: máy chủ B chỉ có thể nói với máy chủ A " Tôi có ai đó theo dõi người chơi A, hãy cập nhật cho tôi mọi thứ họ làm cho đến khi tôi nói với bạn. " cũng muốn bao gồm một số loại hệ thống phát sóng toàn cầu cho các sự kiện toàn cầu quan trọng mà người chơi có thể cần biết về bất kể họ ở đâu; tất nhiên, những sự kiện như vậy cũng nên được ghi lại trong cơ sở dữ liệu, nhưng việc chúng chủ động phát đến tất cả các máy chủ có nghĩa là các máy chủ sẽ không phải tiếp tục thăm dò cơ sở dữ liệu để cập nhật.


Câu trả lời tuyệt vời! Đây chính xác là những gì tôi đã hỏi, cảm ơn bạn. Vì vậy, có lẽ chìa khóa là phân chia máy chủ theo các khu vực, giữ logic trong bộ nhớ. Mặc dù vậy, tôi có thể thêm: Tôi vừa tìm hiểu về cơ sở dữ liệu NoQuery mới, Couchbase. Nó được cho là giống như CouchDB, ngoại trừ với tốc độ ghi / đọc rất nhanh: lên tới 200k cập nhật mỗi giây! Có lẽ điều này thực sự có thể hoạt động như một "mô hình thế giới chia sẻ thời gian thực" như vậy, hoặc chưa?
MaiaVictor 24/03/13

@Dokkat không, nó sẽ không. Couchbase không phải là phép thuật.
Philipp

2

Các phản hồi khác đã thực hiện tốt việc chỉ ra cách sử dụng cơ sở dữ liệu và không sử dụng cơ sở dữ liệu để liên lạc. Một khía cạnh khác mà bạn có thể xem xét là phân loại các cập nhật của bạn dựa trên cách thông tin cần được truyền đạt tới các thực thể khác. Thay vì giao tiếp phạm vi đến các máy chủ, bạn có thể phân phối tin nhắn của mình và sử dụng các cơ chế pubsub để liên lạc cập nhật giữa các thực thể. Chẳng hạn, bạn có thể đối xử với vị trí khác nhau dựa trên những người gần gũi với bạn:

  • Vị trí chính xác, thời gian thực có thể hữu ích trong bán kính R
  • Cập nhật vị trí ít chính xác hơn, ít thường xuyên hơn có thể hữu ích trong bán kính 2 * R
  • Không có thông tin vị trí có thể cần thiết ngoài bán kính 2 * R

Bạn có thể truyền đạt thông tin vị trí cho một thực thể bằng cách quét định kỳ các thực thể trong bán kính 2 * R (hoặc một số bội số dựa trên tốc độ cập nhật và vận tốc tối đa của thực thể) và đăng ký thực thể vào nguồn cấp dữ liệu vị trí chính xác hoặc không chính xác của thực thể khác.

Bạn có thể có các chiến lược khác nhau cho các loại thông tin khác nhau, nhóm các thứ chung vào cùng một hàng đợi tin nhắn hoặc có các hàng đợi khác nhau cho các thư cần đến các thực thể khác nhau (hoặc chỉ gửi chúng đến nhóm thực thể rộng nhất và loại bỏ các tin nhắn nếu chúng 'không hữu ích).

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.