Saya menerapkan klon asteroid multipemain untuk belajar tentang arsitektur jaringan klien / server dalam permainan. Saya telah menghabiskan waktu membaca publikasi GafferOnGames dan Valve tentang teknologi klien / server mereka. Saya mengalami masalah dengan dua konsep.
Saat ini saya memiliki server permainan otoritatif yang mensimulasikan fisika dengan box2d dan mengirimkan keadaan dunia kepada klien sekitar 20 kali per detik. Setiap klien melacak beberapa snapshot terakhir yang diterima dan lerps antara dua negara untuk memperlancar pergerakan sprite. Namun tidak semulus itu. Bisa mulus untuk sementara waktu, lalu sedikit tersentak-sentak, lalu kembali ke halus, dll. Saya telah mencoba TCP dan UDP, keduanya hampir sama. Adakah yang tahu apa masalah saya? (Catatan: Saya menerapkan ini untuk pemain tunggal terlebih dahulu, dan gerakan sprite sangat halus pada 60fps saat memperbarui dunia fisika hanya 20 kali per detik).
Untuk menyelesaikan masalah pertama saya pikir mungkin klien harus menjalankan simulasi box2d juga dan hanya memperbarui posisi sprite-nya untuk mencocokkan snapshot server ketika mereka tidak cocok. Saya pikir ini mungkin lebih lancar karena implementasi pemain tunggal saya lancar. Apakah ini ide yang bagus?
Bahkan jika itu tidak akan memperbaiki masalah di atas, apakah perlu untuk prediksi sisi klien? Misalnya, jika seorang pemain mencoba untuk memindahkan kapalnya, bagaimana mereka akan tahu jika mereka menabrak asteroid, dinding, atau kapal musuh tanpa simulasi fisika? Sepertinya kapal mereka akan terlihat melewati objek yang harus bertabrakan dengan mereka sebelum mereka menerima snapshot dari server yang mengatakan bahwa mereka mengenai objek tersebut.
Terima kasih!
sumber
+-*/
" benar-benar salah. Semua operasi di IEEE-754 dapat bervariasi berdasarkan pada implementasinya. Lihat di sini dan di sini untuk info lebih lanjut.Ini mungkin tidak terlihat begitu baik karena interpolasi di antara mereka bergantung pada selalu memiliki set data berikutnya untuk diinterpolasi. Ini berarti bahwa, jika ada lonjakan jeda pendek, semuanya harus menunggu untuk mengejar ketinggalan.
Ada artikel lama di GameDev tentang menggunakan splines kubik untuk memprediksi posisi objek melewati titik di mana Anda terakhir memiliki data untuk itu. Yang kemudian Anda lakukan adalah menggunakan posisi itu dan kemudian menyesuaikan spline ketika Anda mendapatkan data baru untuk memperhitungkan posisi baru itu. Ini juga mungkin jauh lebih murah daripada menjalankan simulasi fisika kedua, dan itu berarti Anda tidak harus memutuskan siapa yang Anda percayai, karena Anda telah secara eksplisit mengimplementasikan klien yang mengada-ada. :)
sumber
Saya sendiri sudah melakukan beberapa hal yang serupa, dan saya menjalankan Box2D hanya pada klien. Cara saya melakukannya adalah membiarkan klien menjalankan simulasi sendiri dengan cukup banyak, mengirimkan kecepatan saat ini (dan rotasi) pada setiap paket sinkronisasi ke server. Server kemudian mengirimkan informasi ini ke pemain lain, yang mengatur kecepatan yang baru diterima ke entitas yang direplikasi. Itu sangat lancar, tanpa ada perbedaan mencolok antara klien.
Tentu saja, masalahnya di sini adalah bahwa tidak ada kontrol terpusat atas entitas, tapi saya pikir itu bisa dilakukan di sisi server juga dengan melakukan simulasi fisika sisi-server juga.
sumber
Saya pribadi lebih suka menjalankan simulasi hanya di server dan menyiarkannya perubahan pada kecepatan linear / sudut / percepatan objek yang terlibat setiap kali mereka terjadi. Itu adalah, ketika suatu objek tertentu, untuk alasan apa pun, mengubah sifat fisiknya (seperti kecepatan dan percepatan yang disebutkan di atas), perubahan spesifik ini akan dikirim dari server ke klien, dan klien akan mengubah sisi itu dari objek tersebut. data objek sesuai.
Keuntungannya daripada implementasi Anda saat ini adalah bahwa itu akan membatalkan perlunya interpolasi sisi klien dan akan menghasilkan perilaku yang sangat setia pada objek. Masalahnya adalah bahwa metode ini sangat sangat rentan terhadap latensi, yang menjadi masalah yang sangat besar ketika para pemain secara geografis terlalu jauh satu sama lain.
Sedangkan untuk pertanyaan 1, saya katakan masalahnya adalah fluktuasi pada latensi, karena tidak ada jaminan mutlak bahwa akan ada interval 20 detik yang tepat antara setiap penerima snapshot. Biarkan saya menggambarkan (menjadi "t" waktu yang diukur dalam milidetik):
1) Pada t = 20 sejak awal permainan, klien menerima snapshot dan melakukan interpolasi berhasil dan lancar.
2) Pada t = 40, ada latensi antara server dan klien, dan potret yang terjadi hanya benar-benar sampai pada t = 41.
3) Pada t = 60, server mengirim snapshot lain, tetapi satu detik simulasi sia-sia di sisi klien karena latensi. Jika snapshot tiba pada t = 60, klien tidak akan melakukan interpolasi dari 40 dan 60 instance, tetapi sebenarnya dari instance 41 hingga 60, menghasilkan perilaku yang berbeda. Ketidakaktifan ini mungkin menjadi penyebab "jerkiness" akhirnya.
Sedangkan untuk pertanyaan 2, ide Anda mungkin berfungsi jika Anda mengimplementasikan sesuatu yang secara efisien akan melacak apakah setiap objek benar-benar disinkronkan dengan server-klien tanpa harus mengirim paket setiap frame yang menginformasikan posisi objek. Bahkan jika Anda melakukannya pada interval diskrit, Anda tidak hanya akan berjalan pada masalah yang sama dari pertanyaan 1, tetapi juga memiliki jumlah data yang terlalu besar untuk ditransfer (yang merupakan hal yang buruk).
sumber