Làm thế nào để đồng bộ hóa đồng hồ qua mạng để phát triển trò chơi?


10

Tôi đang viết một trò chơi có nhiều khía cạnh dựa trên thời gian. Tôi sử dụng thời gian để giúp ước tính vị trí của người chơi khi mạng bị đình trệ và các gói không đi qua (và thời gian giữa lúc nhận và không nhận được gói). Đây là một trò chơi kiểu pacman theo nghĩa người chơi chọn một hướng và không thể ngừng di chuyển, vì vậy hệ thống đó có ý nghĩa (hoặc ít nhất là tôi nghĩ là như vậy).

Vì vậy, tôi có hai câu hỏi: 1) Làm cách nào để đồng bộ hóa đồng hồ của các trò chơi khi bắt đầu vì có sự chậm trễ trong mạng. 2) Có ổn không khi đồng bộ hóa chúng và chỉ cho rằng chúng giống nhau (mã của tôi độc lập với múi giờ). Đây không phải là một trò chơi siêu cạnh tranh, nơi mọi người sẽ thay đổi đồng hồ của họ để gian lận, nhưng vẫn vậy.

Trò chơi đang được lập trình bằng Java và Python (phát triển song song như một dự án)


7
tra cứu ntp
ratchet freak

5
Tôi chắc chắn rằng câu hỏi này đã được đề cập trên gamedev.stackexchange.com, hoặc ít nhất nó thuộc về nó.
congusbongus

1
@CongXu: Tôi không chắc lắm. Mặc dù đây là nhiệm vụ thường được thực hiện cho các trò chơi, nhưng nó không phải là đặc thù cho phát triển trò chơi. Nhiều hệ thống phân tán khác cần đồng hồ đồng bộ.
Jan Hudec

2
Bạn đã thử sử dụng tùy chọn IPv4 TIMESTAMP chưa? Thông tin thêm có tại linux.die.net/man/7/socket từ đó đến linux.die.net/man/3/cmsg và sau đó là một chương trình ví dụ nhỏ tại pdbuchan.com/rawsock/rawsock.html cái cuối cùng trước Phần IPv6.
ott--

2
Trò chơi (ứng dụng) không nên chạm vào đồng hồ hệ thống.
Phục hồi Monica - M. Schröder

Câu trả lời:


9

Tôi nghĩ rằng nó chắc chắn là không OK để synchornize đồng hồ trong hệ thống . Người dùng không mong đợi bạn chạm vào cài đặt hệ thống và nhiều hệ thống thậm chí sẽ không cho phép bạn.

Tất cả những gì bạn cần là có một mối tương quan để chuyển đổi dấu thời gian từ đồng hồ này sang đồng hồ khác. Mặt khác, bạn cần mối tương quan này khá chính xác, hãy nói ít nhất là một phần trăm giây, nếu bạn muốn sử dụng nó để dự đoán vị trí người chơi. Đồng hồ hệ thống sẽ không bao giờ tương quan tốt giữa các máy ngẫu nhiên này. Vì vậy, bạn nên tự thiết lập mối tương quan, sử dụng một số biến thể trên chủ đề NTP , có thể được nhúng trong các thông báo khác của bạn để tiết kiệm băng thông mạng.

Ý tưởng cơ bản có thể là với mỗi gói bạn gửi dấu thời gian bạn đã gửi nó và số thứ tự và dấu thời gian khi bạn nhận được gói cuối cùng từ phía bên kia. Từ đây, bạn tính toán khứ hồi: Ví dụ: nếu gói Q nói rằng nó được gửi ở 1000 và gói P được nhận ở mức 500, so với khi bạn gửi gói P ở 0 và đang nhận Q ở 800, thì khứ hồi là (800 - 0 ) - (1000 - 500) = 300. Không có cách nào để biết được sự đồng điệu, vì vậy bạn chỉ cần giả sử gói mất một nửa (150) tick theo một trong hai hướng. Và dấu thời gian từ xa đó đi trước địa phương 1000 - (800 - 150) = 350 tick. Chuyến đi khứ hồi sẽ khác nhau. Nếu bạn cho rằng đồng hồ là chính xác hợp lý, bạn nên sử dụng mức trung bình dài hạn của mối tương quan.

Lưu ý rằng bạn cũng không muốn sử dụng đồng hồ hệ thống cho đồng hồ. Họ có thể được đồng bộ hóa giữa chừng, ném bạn đi sai hướng. Bạn nên sử dụng clock(CLOCK_MONOTONIC)trên Unix hoặc GetTickCounttrên Windows (không chắc chắn cách các API đó được gói trong Java hoặc Python ngay bây giờ).


Lưu ý: SO_TIMESTAMPTùy chọn ổ cắm (xem ổ cắm (7) được đề cập bởi ott-- trong nhận xét về câu hỏi) sẽ hữu ích để phân tách ảnh hưởng của độ trễ của vòng lặp sự kiện nhận các gói. Liệu nó có xứng đáng với nỗ lực hay không phụ thuộc vào mức độ chính xác mà bạn cần.


1

Làm thế nào để bạn biết đồng hồ của người chơi là chính xác? Bạn không nên sử dụng đồng hồ tham khảo .

NTP là quá mức cần thiết ở đây - bạn chỉ cần ~ 1 chính xác thứ hai - vì vậy sử dụng rdate hoặc chọn một cái gì đó từ một trong nhiều thuật toán đồng bộ hóa đồng hồ.

Bạn đã chọn một phương thức, yêu cầu mỗi máy của người chơi chọn thời gian cho mỗi phương thức đó (mà không thay đổi đồng hồ hệ thống của họ). Bất kể sự khác biệt nào giữa thời gian UTC tham chiếu và thời gian UTC đồng hồ hệ thống của người chơi là phần bù hiệu quả của chúng. Bất cứ khi nào bạn thực hiện các phép tính liên quan đến thời gian, ví dụ như ngoại suy các chuyển động bot hoặc đạn theo dõi tia, bạn sẽ tính đến phần bù này sau khi có được thời gian hệ thống. Sử dụng UTC sẽ loại bỏ các yếu tố múi giờ.


1

Tôi tuyên bố thứ hai rằng bạn không nên sử dụng NTP hoặc đến gần đồng hồ hệ thống cho việc này. Nếu bạn thực sự kiểm tra yêu cầu này, bạn sẽ thấy rằng bạn có các nhu cầu sau:

  • Bao nhiêu thời gian đã trôi qua kể từ khung trước đó để bạn có thể tiến lên bất kỳ công cụ dựa trên thời gian nào. Điều này có thể khác nhau trên máy khách và máy chủ nếu cả hai đánh dấu ở các tốc độ khác nhau (ví dụ: đôi khi bạn có thể thấy các máy chủ chạy ở tần số cố định 20Hz (hoặc bất cứ thứ gì) nhưng các máy khách được phép chạy nhanh như chúng muốn).
  • Bao nhiêu thời gian đã trôi qua kể từ khi bản đồ hiện tại bắt đầu. Đây là bộ đếm thời gian dựa trên số 0 (chỉ khởi tạo nó thành 0 trên cả máy khách và máy chủ khi chúng khởi động) và thời gian máy chủ được coi là "chính", do đó máy chủ sẽ gửi chế độ xem hiện tại của nó cho máy khách cho mỗi khung hình chạy trên máy chủ. Điều này có thể nhận được bằng cách lấy thời gian của máy chủ hiện tại và trừ đi thời gian máy chủ khởi động hoặc bằng cách tích lũy thời gian trên mỗi khung hình ở trên. Thời gian trên mỗi khung hình phía máy khách ở trên cũng có thể được sử dụng để tạo các điểm nội suy giữa bất kỳ hai khung máy chủ liên tiếp nào.
  • Một tham chiếu "thời gian cơ sở" mà từ đó tất cả các thời gian khác tiến lên; điều này có thể (nhưng không nhất thiết phải dành cho tất cả các loại trò chơi) giống nhau trên cả máy khách và máy chủ và được khởi tạo khi bắt đầu trò chơi (hoặc bản đồ hiện tại) nhưng không bao giờ thay đổi sau (trừ khi trò chơi mới - hoặc bản đồ mới - được bắt đầu).

Đây là một phác thảo đơn giản - tôi không cố gắng xử lý các vấn đề như độ trễ / gói bị rớt / v.v. - nhưng đó là khung cơ bản mà toàn bộ sự việc nên dựa vào.

Không ai trong số này cần phải đến gần đồng hồ hệ thống hoặc quan tâm đến các vấn đề như các múi giờ khác nhau, mặc dù mục cuối cùng có thể sử dụng múi giờ nếu muốn. Điều quan trọng là thời gian trôi qua thực tế được đo bằng cách sử dụng bộ hẹn giờ dựa trên độ phân giải cao, do đó chúng hoàn toàn không tin vào sự khác biệt của múi giờ. Bạn muốn tìm thời gian hiện tại thực tế trên máy chủ? Chỉ cần thêm thời gian đã trôi qua vào thời gian cơ sở tham chiếu và bạn đã có nó. Tương tự như vậy cho khách hàng.

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.