Saya sedang menulis game yang memiliki banyak aspek berbasis waktu. Saya menggunakan waktu untuk membantu memperkirakan posisi pemain ketika jaringan berhenti dan paket tidak melalui (dan waktu antara paket diterima dan tidak). Ini adalah jenis permainan pacman dalam arti bahwa seorang pemain memilih arah dan tidak bisa berhenti bergerak, sehingga sistem masuk akal (atau setidaknya saya pikir itu bisa).
Jadi saya punya dua pertanyaan: 1) Bagaimana cara menyinkronkan jam dari permainan di awal karena ada keterlambatan dalam jaringan. 2) Apakah boleh BUKAN untuk menyinkronkannya dan hanya berasumsi bahwa semuanya sama (kode saya tidak tergantung pada zona waktu). Ini bukan game yang sangat kompetitif di mana orang akan mengubah jam mereka menjadi curang, tapi tetap saja.
Gim ini diprogram dalam Java dan Python (pengembangan paralel sebagai proyek)
Jawaban:
Saya pikir sudah pasti tidak baik untuk menyinkronkan jam dalam sistem . Pengguna tidak berharap Anda menyentuh pengaturan sistem dan banyak sistem bahkan tidak akan membiarkan Anda melakukannya.
Yang Anda butuhkan hanyalah memiliki korelasi untuk mengubah timestamp dari jam satu sisi ke jam pihak lain. Di sisi lain Anda perlu korelasi ini agak tepat, katakan setidaknya seperseratus detik, jika Anda ingin menggunakannya untuk memprediksi posisi pemain. Jam sistem tidak akan pernah berkorelasi dengan baik antara mesin acak ini. Jadi, Anda harus membuat korelasinya sendiri, menggunakan beberapa variasi pada tema NTP , mungkin tertanam dalam pesan Anda yang lain untuk menghemat bandwidth jaringan.
Ide dasarnya mungkin bahwa dengan setiap paket yang Anda kirim timestamp yang Anda kirim dan nomor urut dan timestamp ketika Anda menerima paket terakhir dari sisi lain. Dari ini Anda menghitung pulang pergi: Misalnya jika paket Q mengatakan itu dikirim pada 1000 dan paket P diterima pada 500, daripada memberi Anda mengirim paket P pada 0 dan menerima Q pada 800, round-trip adalah (800 - 0 ) - (1000 - 500) = 300. Tidak ada cara untuk mengetahui asimetri, sehingga Anda hanya berasumsi bahwa paket tersebut mengambil setengah (150) kutu di kedua arah. Dan stempel waktu jauh lebih cepat dari lokal dengan 1000 - (800 - 150) = 350 ticks. Perjalanan pulang pergi akan bervariasi. Jika Anda menganggap jam itu cukup tepat, Anda harus menggunakan rata-rata korelasi jangka panjang.
Perhatikan, Anda juga tidak ingin menggunakan jam sistem untuk jam tersebut. Mereka mungkin disinkronkan di tengah jalan, membuat Anda keluar jalur. Anda harus menggunakan
clock(CLOCK_MONOTONIC)
Unix atauGetTickCount
Windows (tidak yakin bagaimana API tersebut dibungkus dengan Java atau Python sekarang).Catatan:
SO_TIMESTAMP
Opsi soket (lihat soket (7) yang disebutkan oleh ott-- dalam mengomentari pertanyaan) akan berguna untuk memisahkan efek latensi dari loop peristiwa yang menerima paket. Apakah itu sepadan dengan usaha tergantung pada seberapa baik presisi yang Anda butuhkan.sumber
Bagaimana Anda tahu jam pemain mana yang benar? Anda tidak, jadi gunakan jam referensi .
NTP berlebihan di sini - Anda hanya perlu ~ 1 detik akurasi - jadi gunakan rdate atau pilih sesuatu dari salah satu dari banyak algoritma sinkronisasi jam.
Jika Anda telah memilih metode, minta mesin setiap pemain untuk mengambil waktu per metode itu (tanpa mengubah jam sistem mereka). Apa pun perbedaan ada di antara waktu UTC referensi dan jam sistem pemain waktu UTC adalah offset efektif mereka. Setiap kali Anda melakukan perhitungan yang berkaitan dengan waktu untuk mis memperkirakan pergerakan bot atau peluru ray-trace, Anda memperhitungkan offset ini setelah mendapatkan waktu sistem. Menggunakan UTC akan menghilangkan faktor zona waktu.
sumber
Saya menyatakan kedua bahwa Anda tidak boleh menggunakan NTP atau mendekati jam sistem untuk ini. Jika Anda benar-benar memeriksa persyaratan ini, Anda akan menemukan bahwa Anda memiliki kebutuhan berikut:
Ini adalah garis besar yang disederhanakan - Saya tidak berusaha untuk menangani masalah-masalah seperti latensi / paket yang dijatuhkan / dll - tetapi ini adalah kerangka dasar di mana semuanya harus didasarkan.
Tidak satu pun dari ini perlu mendekati jam sistem atau peduli dengan hal-hal seperti zona waktu yang berbeda, meskipun item terakhir dapat menggunakan zona waktu jika diinginkan. Yang penting adalah waktu aktual yang berlalu diukur menggunakan timer berbasis nol resolusi tinggi, sehingga mereka benar-benar agnostik terhadap perbedaan zona waktu. Ingin menemukan waktu aktual saat ini di server? Tambahkan saja sudah waktunya untuk referensi waktu dasar dan Anda sudah mendapatkannya. Demikian juga untuk klien.
sumber