Làm cách nào tôi có thể gán ID thực thể một cách mạnh mẽ trong trò chơi mạng?


17

Tôi đang làm việc trên một hệ thống thực thể cho một trò chơi được nối mạng và tôi đang gán cho mỗi thực thể một id số nguyên 32 bit duy nhất mà tôi có thể sử dụng để tuần tự hóa các tham chiếu đến các thực thể và chính các thực thể.

Hiện tại tôi chỉ tăng một bộ đếm mỗi khi một thực thể được tạo. Tôi đoán các id cuối cùng sẽ hết nhưng tôi thực sự không mong đợi có 4 tỷ thực thể. Ngoài ra, điều này cũng tránh được vấn đề nếu thực thể số 5 bị phá hủy và chúng tôi nhận được id là 5. Có nghĩa là đề cập đến số 5 mới hoặc số 5 cũ đã bị xóa?

Vấn đề là tôi không chắc chắn cách xử lý / tránh va chạm. Hiện tại nếu một khách hàng nhận được bản cập nhật cho một thực thể có id cao hơn "id miễn phí" hiện tại thì nó chỉ vượt qua id miễn phí để vượt qua nó. Nhưng điều đó dường như không mạnh mẽ.

Tôi đã nghĩ về việc có thể gán phạm vi cho từng khách hàng để họ có thể phân bổ các thực thể mà không xung đột (giả sử các bit n hàng đầu là số người chơi) nhưng tôi lo lắng về những gì sẽ xảy ra nếu phạm vi bắt đầu chồng chéo theo thời gian.

Có cách nào tốt hơn để xử lý này? Tôi thậm chí có nên quan tâm đến việc id tràn hay đi qua cuối phạm vi được phép không? Tôi có thể thêm mã để phát hiện những trường hợp này nhưng nó sẽ làm gì nếu chúng xảy ra ngoài sự cố.

Một lựa chọn khác là sử dụng thứ gì đó có cơ hội duy nhất cao hơn như GUID 128 bit nhưng điều đó dường như thực sự nặng nề đối với một trò chơi đang cố gắng giảm thiểu lưu lượng mạng. Ngoài ra, thực tế tôi sẽ không bao giờ cần nhiều thực thể cùng một lúc sau đó sẽ phù hợp với số nguyên 32 bit hoặc thậm chí 24 bit.

Cảm ơn!


1
Tại sao tất cả khách hàng không có cùng thực thể? Là các khách hàng không được đồng bộ hóa? Hoặc đó là một thế giới rộng lớn của một số loại mà tất cả các khách hàng không chạy cùng một trò chơi.
Philip

2
Kiến trúc của tôi cho đến nay vẫn lỏng lẻo theo UE3 (thông tin thêm ở đây ). Về cơ bản khách hàng chỉ biết về các thực thể gần họ trên thế giới. Ngoài ra, các máy khách không chạy theo bước khóa nhưng máy chủ kiểm soát hầu hết logic và có thể ghi đè lên dữ liệu của máy khách bất cứ lúc nào. Tôi đoán bây giờ tôi nghĩ về nó, tôi chỉ có thể cho phép máy chủ tạo các thực thể và khiến khách hàng sử dụng RPC để làm điều này. Tôi không chắc chắn về cách tiếp cận tốt nhất. Tôi là một lập trình viên đồ họa vào ban ngày :)
Lucas

1
Tôi nghĩ, như bạn nói, nó chỉ nên được xử lý bởi máy chủ nếu điều đó hoàn toàn khả thi trong kiến ​​trúc đã cho của bạn. Sau đó giữ một chồng ID thực thể miễn phí tồn tại tách biệt với danh sách / bản đồ thực thể, để bạn biết ID nào có sẵn. Không có một mô hình máy chủ có thẩm quyền, thì cách tiếp cận trong phạm vi của bạn sẽ hoạt động tốt, xét về phạm vi. Bốn tỷ là rất nhiều, thậm chí để chia cho 4000 người chơi trong một MMO. Sau đó sử dụng cùng một cách tiếp cận để theo dõi các ID có sẵn như với một xác thực. người phục vụ.
Kỹ sư

@Lucas, liên kết của bạn cho biết "Máy chủ xác định nhóm" Diễn viên "phù hợp cho từng khách hàng". Điều này ngụ ý rằng máy chủ biết về tất cả các thực thể và đang ở trong một vị trí để liệt kê chúng.
Kylotan

1
Chắc chắn, nhưng nếu khách hàng tạo thực thể A mới nhưng trước khi có thể nhận được thông báo tạo thì máy chủ tạo thực thể B mới, cả hai đều được gán cùng một id "miễn phí".
Lucas

Câu trả lời:


13

Những gì tôi đã làm là làm cho máy chủ làm mọi thứ . (Các) khách hàng chỉ có thể yêu cầu máy chủ làm điều gì đó nhưng không thể tự làm bất cứ điều gì. Trong trường hợp này, máy chủ sẽ luôn là một ID gán ID và vấn đề được giải quyết.

Tôi đã không xử lý dự đoán phía khách hàng trong khi chờ máy chủ phê duyệt các hành động như: "Bắn tên lửa" hoặc "Tạo trạm năng lượng mặt trời ở đây". Những hành động này sẽ muốn tạo các thực thể và các thực thể có ID. Cho đến nay, tôi chỉ ngồi trên ngón tay cái chờ máy chủ, nhưng tôi tin rằng những gì cần làm là tạo ra một thực thể tạm thời trong khi bạn chờ phê duyệt máy chủ. Khi bạn nhận được sự chấp thuận của máy chủ, máy chủ sẽ gán ID và bạn có thể cập nhật hoặc ghi đè lên đối tượng tạm thời.

Tôi cũng chưa xử lý lỗi tràn ID, nhưng nếu máy chủ kiểm soát hoàn toàn và phát hiện tràn, nó có thể làm bất cứ điều gì bạn thấy cần thiết (khởi động lại ở 0, chọn từ ngăn xếp miễn phí, sự cố, v.v.) và tất cả khách hàng thậm chí sẽ không biết hoặc quan tâm. Các khách hàng sẽ chỉ chấp nhận ID do máy chủ đưa ra.


Cảm ơn tất cả các bạn thông tin tốt! Cuối cùng tôi đã đi với máy chủ tạo ra tất cả các cách tiếp cận thực thể, nhưng nếu tôi thấy điều đó giới thiệu quá nhiều độ trễ, tôi sẽ thử phương pháp của Trevor.
Lucas

Đối với id cụ thể của máy khách (cần để dự đoán trong khi chờ máy chủ), bạn có thể chỉ cần sử dụng tiền tố trên id.
danijar

6

Khi tôi làm điều này cho một trò chơi nhiều người chơi thương mại, tôi đã làm chính xác những gì bạn đề xuất: sử dụng số nguyên GUID 32 bit, trong đó tám bit trên cùng là số người chơi và hai mươi bốn bit dưới cùng chứa một số duy nhất cục bộ.

Nếu / khi số cục bộ tràn ra (trong trường hợp của tôi, điều đó gần như không bao giờ xảy ra; trong sử dụng bình thường, phải mất bốn đến năm ngày chơi liên tục trong một phiên mạng để xảy ra), chủ sở hữu sẽ gửi Thông báo "Đặt lại tất cả các đối tượng của tôi" và đánh số lại tất cả các đối tượng vẫn còn tồn tại bắt đầu từ số 0 trước đây. Thông báo nói với tất cả các đồng nghiệp để loại bỏ các đối tượng họ đã nhận được và truy vấn lại chúng.

Một cách tiếp cận lạ mắt hơn sẽ là "Đối tượng với GUID 'n' hiện là Đối tượng có thông báo GUID 'm'" cho mọi đối tượng hiện có. Nhưng trong trường hợp của tôi, điều đó dường như không bao giờ thực sự xảy ra và tôi không nghĩ mọi người sẽ thực sự bận tâm đến những vật thể từ xa biến mất khỏi thế giới trong nửa giây, sau năm ngày chơi không ngừng nghỉ trong một phiên mạng duy nhất. ;)


Đó là một ý tưởng tốt để xử lý tràn. Đơn giản, nhưng tôi không nghĩ về nó :). "Quên" tất cả các thực thể của bạn là tốt vì về cơ bản nó có thể sử dụng lại cùng một loại mật mã mà khách hàng sử dụng khi tham gia trò chơi
Lucas

4

Nếu khách hàng của bạn có thể sinh ra các thực thể của riêng họ, tôi đoán bạn có một trò chơi nhiều người chơi ngang hàng.

Nếu đó là trường hợp, bạn có thể không có quá nhiều khách hàng. Chắc chắn không quá 256. Và id thực thể của bạn được đảm bảo phù hợp với 24 bit (16000000+ thực thể là đủ cho tất cả mọi người!). Vì vậy, chỉ cần tạo byte cao nhất trong id của bạn bằng id của khách hàng:

entityId = clientId<<24 + (maxEntityIn++)

hoặc một cái gì đó.

Và nếu tôi sai và bạn có một máy chủ có thẩm quyền, thì đừng bao giờ tạo các thực thể mới trên máy khách.


1

Tôi đang sử dụng phương pháp 'ngây thơ nhất' (chỉ cần tăng số nguyên cho mỗi ID mới) trong trò chơi nhiều người chơi liên tục của tôi và nó hoạt động tốt vì tôi không cho phép khách hàng tạo ID mới: s.

Nếu bạn để khách hàng quyết định (bằng cách sử dụng một loại kỹ thuật GUID được giải thích), khách hàng cũng có thể đưa ra nhiều lỗi khác nhau bằng cách gán ID cũ cho một mục mới (đó chỉ là những gì tôi nghĩ ra trên đầu suy nghĩ trong 5 giây , có thể có vô số sơ hở khác).

Như thường lệ, để tránh gian lận , máy chủ nên thực hiện TẤT CẢ việc tạo và xác thực .

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.