Nền tảng nhiều người chơi - Có phải các chỉnh sửa máy chủ thường được yêu cầu với một máy khách trên máy chủ không?


10

Tôi hiện đang làm việc trên một nền tảng nhiều người chơi khá đơn giản. Tôi đã đọc khá nhiều bài viết về các kỹ thuật được sử dụng để che giấu độ trễ, nhưng tôi vẫn không thể hiểu được một số khái niệm. Tôi thấy chủ đề này rất thú vị và thích tự mình thử ý tưởng, nhưng tôi nghĩ việc hỏi gamedev stackexchange sẽ hiệu quả hơn cho câu hỏi của tôi. Tôi sẽ cố gắng hết sức để mô tả tình hình hiện tại của tôi và câu hỏi nào phát sinh trên đường đi.

Ngay bây giờ, tôi chỉ muốn có một người chơi được đồng bộ hóa với máy chủ. Về mặt lý thuyết, tôi giả định một người chơi tự dự đoán phía khách hàng sẽ không yêu cầu chỉnh sửa máy chủ, vì không có yếu tố bên ngoài nào ảnh hưởng đến chuyển động của anh ta. Do đó, nguyên mẫu của tôi hiện chỉ có một người chơi được đồng bộ hóa với máy chủ mà không gửi chỉnh sửa máy chủ.

Nếu bạn quen thuộc với mạng trò chơi, tôi nghĩ bạn có thể bỏ qua các phần bối cảnh, mặc dù tôi cũng có thể đã làm điều gì đó sai trên đường đi.

Vòng lặp máy khách (một lần trên mỗi khung hình, cứ sau ~ 16,67ms)

Vòng lặp máy khách được đơn giản hóa trông giống như:

  1. Kiểm tra đầu vào cục bộ (WASD) và đóng gói chúng dưới dạng hành động (ví dụ Type=MoveLeft, Time=132.0902, ID=15). Chúng tôi giữ các hành động đóng gói để cuối cùng gửi chúng sau này. Ngoài ra, chúng tôi trực tiếp áp dụng hành động mong muốn vào mô phỏng vật lý địa phương của trò chơi. Ví dụ: nếu chúng ta có một MoveLefthành động, chúng ta sẽ tác dụng một lực về phía bên trái theo vận tốc của người chơi.

  2. Kiểm tra để gửi hành động. Để tránh lạm dụng băng thông của máy khách, chỉ gửi các hành động được đóng gói theo các khoảng nhất định (ví dụ: 30ms).

  3. Áp dụng sửa đổi máy chủ. Tại một thời điểm nhất định, điều này sẽ xử lý các deltas và chỉnh sửa mà máy chủ nhận được và áp dụng chúng cho mô phỏng cục bộ của trò chơi. Đối với câu hỏi cụ thể này, điều này không được sử dụng.

  4. Cập nhật vật lý địa phương. Chạy vòng lặp vật lý trên máy nghe nhạc chính. Về cơ bản, điều này thực hiện dự đoán phía khách hàng về chuyển động của người chơi. Điều này tăng thêm lực hấp dẫn cho vận tốc của người chơi, áp dụng vận tốc của người chơi vào vị trí của anh ta, khắc phục va chạm trên đường đi, v.v. Tôi nên xác định rằng mô phỏng vật lý luôn được thực hiện với một giây delta cố định (được gọi nhiều lần tùy thuộc vào giây delta thực) .

Tôi bỏ qua một vài chi tiết cụ thể về vật lý và các phần khác bởi vì tôi cảm thấy chúng không bắt buộc cho câu hỏi, nhưng hãy cho tôi biết nếu chúng có liên quan đến câu hỏi.

Vòng lặp máy chủ (cứ sau 15ms)

Vòng lặp máy chủ được đơn giản hóa trông giống như:

  1. Xử lý các hành động. Kiểm tra các gói hành động nhận được từ khách hàng và áp dụng chúng cho mô phỏng vật lý của máy chủ. Ví dụ: chúng ta có thể nhận được 5 MoveLefthành động và chúng ta sẽ tác dụng lực lên vận tốc 5 lần . Điều quan trọng cần lưu ý, toàn bộ gói hành động được thực thi trên một "khung" , trái với máy khách nơi nó được áp dụng ngay khi hành động xảy ra.

  2. Cập nhật logic trò chơi. Chúng tôi cập nhật vật lý trò chơi, di chuyển người chơi và sửa chữa va chạm, v.v. Chúng tôi cũng gói bất kỳ sự kiện quan trọng nào xảy ra để gửi cho người chơi (ví dụ như sức khỏe của người chơi bị giảm, người chơi đã chết, v.v.) sau đó.

  3. Gửi sửa chữa. Chúng tôi thường xuyên (ví dụ cứ sau 35ms) gửi deltas cho người chơi khác (ví dụ: vị trí người chơi, sức khỏe, v.v.) nếu họ thay đổi gần đây. Phần này hiện chưa được triển khai, vì tôi muốn mô phỏng của một người chơi sẽ cho kết quả tương tự trên máy khách và máy chủ mà không cần sửa, để đảm bảo rằng dự đoán phía máy khách hoạt động tốt.

Vấn đề

Hệ thống hiện tại hoạt động tốt trong các trường hợp đơn giản và tôi rất vui khi thấy rằng nó cho kết quả rất giống với các chuyển động ngang đơn giản (sự không chính xác là do lỗi chính xác của dấu phẩy động, tôi tin):

Đồng bộ hoạt động tốt với các va chạm / chuyển động đơn giản

Hãy bỏ qua các đồ họa nguyên mẫu. Hình chữ nhật màu trắng = người chơi, Hình chữ nhật màu đỏ = chướng ngại vật, Màu xanh = nền

Tuy nhiên, tôi đang gặp lỗi đồng bộ hóa sau khi thực hiện các chuyển động nhạy cảm với thời gian, chẳng hạn như nhảy và di chuyển đến gần chướng ngại vật bị cô lập:

Đồng bộ hóa không hoạt động vì tôi đã nhảy xung quanh chướng ngại vật được chỉ định vào những thời điểm nhạy cảm với thời gian

Về lý thuyết, tôi mong muốn cả hai luôn kết thúc với cùng một kết quả, vì không có yếu tố bên ngoài nào để khách hàng ảnh hưởng đến vị trí của anh ta. Trong thực tế, mặc dù, tôi nghĩ rằng tôi hiểu vấn đề.

Do nhảy xung quanh một chướng ngại vật phụ thuộc rất nhiều vào thời gian của người chơi, nên các biến thể nhỏ khi vận tốc được áp dụng cho vị trí sẽ có tác động lên kết quả (ví dụ: khách hàng có thể di chuyển kịp thời để tránh va chạm với trở ngại, trong khi máy chủ sẽ làm điều đó vì nó nhận được toàn bộ gói hành động sau đó và bị mắc kẹt trên chướng ngại vật trong một khoảng thời gian nhỏ, thay đổi kết quả cuối cùng). Sự khác biệt giữa cách máy khách và máy chủ xử lý nó chủ yếu là máy khách thực hiện tất cả các hành động của nó khi chúng xảy ra, trong khi máy chủ thực hiện tất cả các thao tác khi nó nhận được chúng.

Câu hỏi

Bối cảnh dài này cuối cùng cũng dẫn đến câu hỏi của tôi (cảm ơn bạn đã đọc đến nay): Có yêu cầu chỉnh sửa máy chủ ngay cả khi chỉ có một người chơi được đồng bộ hóa với máy chủ hay tôi nên sử dụng một số kỹ thuật nhất định để tránh đồng bộ hóa trong các tình huống nhạy cảm với thời gian ?

Tôi đã nghĩ đến một số giải pháp khả thi, một số trong đó tôi không thoải mái với:

  1. Thực hiện chỉnh sửa máy chủ. Đơn giản chỉ cần giả định rằng đây là hành vi bình thường và sửa lỗi khi chúng xảy ra. Dù sao tôi cũng muốn thực hiện nó, nhưng tôi chỉ muốn chắc chắn rằng những gì tôi đã làm cho đến nay là chấp nhận được.

  2. Sử dụng thời gian khách hàng được cung cấp để áp dụng các hành động mong muốn. Tôi đoán điều này sẽ tương tự như bù độ trễ, yêu cầu "quay ngược thời gian" và kiểm tra chuyển động. Kiểu như áp dụng chỉnh sửa máy chủ, quay ngược thời gian và áp dụng lại các hành động tiếp theo sau đó. Tôi thực sự không thích ý tưởng. Nó có vẻ phức tạp, tốn kém về tài nguyên và đòi hỏi phải tin tưởng vào thời gian nhất định của khách hàng (mặc dù tôi có kế hoạch thực sự kiểm tra xem thời gian có vẻ tương đối hợp pháp không).

  3. Hỏi GameDevelopment StackExchange cho một ý tưởng mới tuyệt vời sẽ khắc phục tất cả các vấn đề của tôi.

Tôi mới bắt đầu tham gia vào thế giới mạng trò chơi, vì vậy xin vui lòng sửa / phê bình / xúc phạm bất kỳ khái niệm nào ở trên hoặc đưa ra ý tưởng / tài nguyên có thể giúp tôi trong hành trình của mình trong Thế giới mạng tuyệt vời. Xin lỗi nếu tôi có thể tìm thấy câu trả lời của mình ở nơi khác, tôi đã thất bại ở đó.

Cảm ơn bạn rất nhiều vì thời gian quý báu của bạn.


Máy chủ và máy khách của bạn chạy các khung ở các mức giá khác nhau. Điều gì xảy ra nếu máy khách thực hiện hai hành động trên các khung liên tiếp, nhưng máy chủ thấy khoảng cách một khung giữa chúng?
dùng253751

@immibis dựa vào gafferongames.com/game-physics/fix-your-timestep để giảm thiểu hiệu ứng này.
Jesse Emond

Câu trả lời:


11

Trong những trường hợp như vậy, bạn có thể tốt hơn để cho khách hàng có thẩm quyền một chút. Đối với các điều khiển chính xác như vậy, bạn rất khó có thể có được hành vi tốt ngay cả với sự điều chỉnh và dự đoán thực sự tiên tiến.

Khách hàng cần mở rộng từ việc chỉ gửi tin nhắn "Tôi đã nhảy" sang gửi tin nhắn "Tôi đã nhảy từ X, Y tại thời điểm T". Sau đó, máy chủ sẽ kiểm tra xem vị trí đó có gần với vị trí mà người chơi nghĩ tại thời điểm T (mà bạn có thể giới hạn trong một khoảng thời gian khá nhỏ trong quá khứ) để bảo vệ chống gian lận, sau đó mô phỏng bước nhảy từ vị trí của máy khách gởi. Máy chủ chỉ sửa lỗi máy khách khi nó không hoạt động (thường là do độ trễ hoặc tương tự).

Loại kỹ thuật này được sử dụng kết hợp với hiệu chỉnh và nội suy để làm cho trò chơi cảm thấy phản hồi trên máy khách cục bộ và trông mượt mà cho các máy khách từ xa.


Rất thú vị. Tôi sẽ cố gắng thực hiện điều này và xem nó diễn ra như thế nào. Cảm ơn bạn rất nhiều vì đã dành thời gian để trả lời. Nhân tiện, bạn đã đề cập "trong khoảng cách gần" và "thời gian khá nhỏ trong quá khứ", bạn có thể chỉ cần kiểm tra với một khoảng cách và thời gian không đổi, tương ứng? Hoặc bạn sẽ sử dụng các kỹ thuật phức tạp hơn như giữ lịch sử vị trí và sử dụng Thời gian khứ hồi trung bình của khách hàng (hoặc bất cứ điều gì khác, thực sự)?
Jesse Emond

Bất cứ điều gì làm việc cho trò chơi của bạn. Bắt đầu đơn giản, làm phức tạp nó chỉ đến mức độ bạn thấy cần thiết. Một số máy chủ giữ lịch sử chụp nhanh các loại xung quanh ~max(RTT)máy chủ trong quá khứ, nhưng liệu bạn có cần cho trò chơi của mình không, tôi không biết. Nó thậm chí còn tiện dụng hơn cho các trò chơi kiểu bắn súng, nơi bạn cũng muốn thực hiện một số mức phát hiện trúng / bắn trên máy khách và không chỉ cần biết người chơi ở đâu 46ms trước mà cả mục tiêu của anh ta ở đâu 46ms trước và ở đâu di chuyển các nền tảng nơi.
Sean Middleditch

Hoàn hảo. Tôi sẽ thử nghiệm và xem những gì hoạt động tốt nhất. Đánh dấu nó là câu trả lời được chấp nhận, cảm ơn một lần nữa!
Jesse Emond
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.