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ư:
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ộtMoveLeft
hà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.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).
Á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.
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ư:
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
MoveLeft
hà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.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 đó.
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):
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:
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:
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.
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).
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.