Saya sedang mengerjakan penembak top-down 2D dan melakukan yang terbaik untuk menyalin konsep yang digunakan dalam game berjejaring seperti Quake 3.
- Saya memiliki server otoritatif.
- Server mengirimkan snapshot ke klien.
- Snapshots berisi cap waktu dan posisi entitas.
- Entitas diinterpolasi di antara posisi snapshot sehingga gerakan terlihat mulus.
- Karena kebutuhan, interpolasi entitas terjadi sedikit "di masa lalu" sehingga kami memiliki beberapa snapshot untuk interpolasi.
Masalah yang saya hadapi adalah "sinkronisasi jam".
- Demi kesederhanaan, mari kita berpura-pura sejenak bahwa tidak ada latensi saat mentransfer paket ke dan dari server.
- Jika jam server lebih cepat 60 detik dari jam klien, maka cap waktu snapshot akan lebih dari 60000 ms dari cap waktu lokal klien.
- Oleh karena itu, snapshot entitas akan mengumpulkan dan duduk selama sekitar 60 detik sebelum klien melihat entitas tertentu melakukan gerakannya, karena dibutuhkan waktu yang lama untuk clock klien untuk mengejar ketinggalan.
Saya telah berhasil mengatasinya dengan menghitung perbedaan antara server dan jam klien setiap kali snapshot diterima.
// For simplicity, don't worry about latency for now...
client_server_clock_delta = snapshot.server_timestamp - client_timestamp;
Ketika menentukan seberapa jauh ke dalam interpolasi entitas, saya hanya menambahkan perbedaan pada waktu klien saat ini. Masalah dengan ini, bagaimanapun, adalah bahwa hal itu akan menyebabkan jerkiness karena perbedaan antara dua jam akan tiba-tiba berfluktuasi karena snapshot tiba lebih cepat / lebih lambat daripada yang lain.
Bagaimana saya bisa menyinkronkan jam cukup dekat sehingga satu-satunya keterlambatan yang dapat dipahami adalah bahwa yang hard-coded untuk interpolasi, dan apa yang disebabkan oleh latensi jaringan biasa?
Dengan kata lain, bagaimana saya bisa mencegah interpolasi dari mulai terlambat atau terlalu cepat ketika jam secara signifikan tidak tersinkronisasi, tanpa memperkenalkan jerkiness?
Sunting: Menurut Wikipedia , NTP dapat digunakan untuk menyinkronkan jam melalui internet dalam hitungan beberapa milidetik. Namun, protokolnya tampak rumit, dan mungkin berlebihan untuk digunakan dalam game?
Jawaban:
Setelah mencari-cari, sepertinya menyinkronkan jam 2 atau lebih komputer bukanlah tugas yang sepele. Protokol seperti NTP melakukan pekerjaan dengan baik tetapi seharusnya lambat dan terlalu rumit untuk praktis dalam gim. Selain itu, ia menggunakan UDP yang tidak akan berfungsi untuk saya karena saya bekerja dengan soket web, yang tidak mendukung UDP.
Saya menemukan metode di sini , yang tampaknya relatif sederhana:
Ia mengklaim untuk menyinkronkan jam ke dalam 150 ms (atau lebih baik) satu sama lain.
Saya tidak tahu apakah itu akan cukup baik untuk tujuan saya, tetapi saya belum dapat menemukan alternatif yang lebih tepat.
Berikut algoritma yang disediakannya:
Solusi ini muncul untuk menjawab pertanyaan saya dengan memuaskan, karena menyinkronkan jam dan kemudian berhenti, memberikan waktu untuk mengalir secara linear. Sedangkan metode awal saya memperbarui jam terus-menerus, menyebabkan waktu untuk melompat-lompat sedikit saat foto diterima.
sumber
Pada dasarnya, Anda tidak dapat memperbaiki dunia [seluruh] dan, pada akhirnya, Anda harus menarik garis.
Jika server dan semua klien berbagi frame-rate yang sama, mereka hanya perlu melakukan sinkronisasi saat menghubungkan, dan kadang-kadang, setelahnya, terutama setelah acara latensi. Latensi tidak memengaruhi aliran waktu atau kemampuan PC untuk mengukurnya sehingga, dalam banyak kasus, alih-alih interpolasi, Anda harus mengekstrapolasi. Ini menciptakan efek yang sama sekali tidak diinginkan tetapi, sekali lagi, ini adalah apa itu dan Anda harus memilih yang paling buruk dari semua kejahatan yang tersedia.
Pertimbangkan bahwa dalam banyak MMO populer, pemain yang tertinggal jelas secara visual. Jika Anda melihat mereka berjalan di tempat, langsung ke dinding, klien Anda memperkirakan. Ketika klien Anda menerima data baru, pemain (pada klien mereka) mungkin telah bergerak cukup jauh dan akan "karet gelang" atau teleport ke lokasi baru ("jerkiness" yang Anda sebutkan?). Ini terjadi bahkan di game-game besar bermerek.
Secara teknis, ini adalah masalah dengan infrastruktur jaringan pemain, bukan gim Anda. Titik di mana ia bergerak dari satu ke yang lain adalah garis yang harus Anda gambar. Kode Anda, pada 3 komputer yang terpisah, harus lebih atau kurang merekam jumlah waktu yang sama berlalu. Jika Anda tidak menerima pembaruan, itu tidak akan mempengaruhi tingkat bingkai Pembaruan () Anda; jika ada, itu harus lebih cepat karena mungkin ada kurang untuk memperbarui.
"Jika Anda memiliki internet payah, Anda tidak dapat memainkan game ini secara kompetitif."
Itu bukan masalah atau bug.
sumber