Bagaimana saya bisa menghentikan pemain dari melayang karena prediksi input lokal ketika mereka berhenti?

14

Saya sedang mengerjakan mesin game multiplayer server-klien 2D (yang bisa Anda coba di sini ). Ini menggunakan DataChannels WebRTC . (Koneksi peer-to-peer, tetapi host host masih bertindak sebagai server.)

Masalah terbesar (terlepas dari konektivitas) adalah prediksi input lokal. Kami melakukan hal yang biasa: Pada penekanan tombol, pemain bergerak secara instan, memberi tahu tuan rumah tombol apa yang ditekan, menerima data kembali dari tuan rumah dan membandingkannya dengan posisi historis. Posisi diperbaiki dari waktu ke waktu jika ada perbedaan. Ini berfungsi baik dengan packet loss atau PDV yang rendah , bahkan jika pingnya tinggi.

Jika ada kerugian atau PDV, penyimpangan bisa lebih besar. Saya pikir ini karena jika paket pertama yang menunjukkan perubahan input ditunda atau dihapus, tuan rumah mengetahuinya nanti, dan mulai mengubah pemain itu lebih lambat dari yang ditunjukkan oleh prediksi input lokal mereka.

Jika pemain bergerak, kami menaikkan jumlah koreksi yang diterapkan, karena itu kurang terlihat. Ini tampaknya menutupi celah saat mulai bergerak dan saat bergerak. Namun, koreksi apa pun lebih terlihat jika mereka berhenti mendadak. Kemudian jika PDV atau kerugian berarti tuan rumah berpikir mereka berhenti kemudian, tuan rumah melakukan overshoot, mengirim kembali data yang mengatakan mereka sedikit lebih jauh ke depan, dan koreksi membuat pemain melayang sedikit. Pada koneksi yang tidak stabil, pemain sering terlihat melayang setelah berhenti.

Saya tidak melihat ini di game lain. Bagaimana ini bisa dikurangi?

AshleysBrain
sumber
3
Gim P2P yang memiliki server? Ada yang salah di sini.
API-Beast
Ups, dengan 'server' yang saya maksud adalah 'host peer'.
AshleysBrain
2
Yah, itu juga tidak terlihat seperti model peer-to-peer, hanya karena salah satu pemain berpose karena server tidak membuatnya peer to peer. Teknik yang Anda gunakan jelas merupakan teknik Client-Server. Di P2P Anda percaya sepenuhnya semua klien (misalnya setiap rekan bertanya satu sama lain di mana pemain mereka berada) atau Anda tidak percaya (misalnya Anda menunda input sampai semua rekan telah menerimanya).
API-Beast
Ah ... sebenarnya itu poin yang bagus ... Saya bingung: koneksi peer-to-peer (yang dilakukan WebRTC), tetapi mesinnya sendiri adalah server-client (salah satu rekan hanya server ). Poin yang bagus.
AshleysBrain
2
Apa ini membuat saya pikirkan adalah sendiri Andrew Russell kami 's Tongkat Ninja dev log di YouTube , khususnya yang satu ini pada memperbaiki kesalahan prediksi . Hanyut yang Anda gambarkan terdengar sangat mirip dengan apa yang terjadi dalam video itu dan Andrew menceritakan detailnya. Apakah ini terkait, atau mungkin bahkan masalah yang sama?
Anko

Jawaban:

8

Lapisan jaringan harus memiliki jam yang disepakati. Mereka dapat menyetujui nilai jam di awal permainan (dan menyinkronkannya kembali secara berkala jika ada penyimpangan) sehingga tuan rumah tahu berapa lama paket tertentu sampai benar-benar tiba dan kapan klien melakukan tindakan, dan sebaliknya.

Lihat artikel ini untuk satu cara yang mungkin untuk menyinkronkan jam di game. Ada yang lain. Berarti spesifik tidak masalah.

Bagian kedua dari masalahnya adalah bahwa server menerapkan input melewati waktu klien berhenti menerapkan input. Ini membutuhkan buffer dari gerakan sebelumnya di server dan beberapa logika pada klien untuk mengabaikan input gerakan dari server melewati gerakan terakhir yang diketahui.

Pertama, buffer server. Server perlu melacak cap jam dari input terakhir yang diterima dari pemain. Ini juga membutuhkan semua gerakan yang berlaku untuk pemain, cap jam gerakan. Jika input diterima, semua gerakan terbaru yang diterapkan dengan cap jam yang lebih baru dari paket input dijatuhkan dan semua gerakan diterapkan kembali dari paket input. Oleh karena itu jika server over-move pemain berdasarkan beberapa input, input yang diperbarui akan membatalkan gerakan-gerakan tersebut dan posisi baru pemain akan didasarkan pada pengetahuan input terbaru yang dimiliki server.

Di sisi klien, klien tahu kapan input terakhir dikirim ke server. Karena setiap pembaruan pemain dari server seharusnya ditandai dengan jam input terakhir yang diketahui server, klien dapat mengabaikan pembaruan server yang memiliki tag input kadaluwarsa dan hanya bertahan dengan prediksi klien. Akhirnya, pembaruan server baru akan tiba dengan input terbaru dan klien dapat memperbaikinya.

Server perlu memvalidasi jam input dan memastikan mereka tidak hanyut dari harapan terlalu banyak untuk mencegah kecurangan. Jam input tidak boleh secara drastis lebih besar dari waktu setengah perjalanan yang harus Anda hitung. Jepit semua yang berada pada kisaran yang wajar ( [Now-2*RTT,Now]misalnya).

Klien akan melihat banyak kegugupan dari avatar pemain lain jika latensi tinggi karena mereka akan mendapatkan pembaruan dari server berdasarkan input basi tetapi tidak memiliki cara untuk mengetahui bahwa itu basi dan kemudian server dapat mulai mengirim lokasi yang cukup berbeda berdasarkan pada input yang dimutakhirkan yang diterimanya (dan menjatuhkan sebagian dari sejarahnya dan memutarnya kembali dengan input baru). Masalah terakhir ini dengan pemain lain yang melihat avatar jitter Anda tidak benar-benar dapat diperbaiki. Latency menyebalkan dan gamer terjebak pada koneksi latensi tinggi akan melihat banyak jittering pemain lain, bahkan jika pemain mereka sendiri bergerak dengan lancar. Satu-satunya koreksi adalah bermain di koneksi yang lebih baik atau dengan rekan / server dengan latensi lebih sedikit.

Sean Middleditch
sumber
1

Saya telah menggunakan pesan UDP yang dapat diandalkan untuk mengindikasikan perubahan status tombol dan pesan UDP yang tidak dapat diandalkan untuk koreksi posisi. Pada dasarnya, artikel-artikel berikut sangat membantu saya: https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking

Dikatakan tentang prediksi pergerakan dengan menyimpan status pemain dalam interval waktu yang konstan sesuai dengan pesan koreksi posisi kedatangan selama sekitar 20 atau 30 penyimpanan negara. Jadi sepertinya pemain jarak jauh Anda akan hidup dalam waktu yang tidak terlalu lama "lewat" sebenarnya dengan terus-menerus menerapkan teknik prediksi :) Berdasarkan latensi pesan net Anda dapat memperoleh kira-kira posisi objek dalam waktu ketika pesan baru saja dikirim dari tuan rumah.

Posisi "di layar" saat ini dapat dengan lancar diterjemahkan ke posisi yang diprediksi menggunakan matematika Lerp (linear interpolasi). Idenya adalah untuk menginterpolasi nilai dalam kesenjangan waktu antara paket koreksi. Jadi sepertinya objek yang ditampilkan selalu bergerak ke arah posisi yang diprediksi. Untuk nilai interpolasi saya mengambil 1 dibagi dengan "latensi pesan menengah" dibagi dengan "waktu rendering bingkai menengah" sehingga gerakan terlihat halus.

Dalam skenario ini permainan menghitung pada semua klien dan server mengoreksi nilai-nilai seperti kecepatan dan posisi dari waktu ke waktu.

Satu hal lagi yang sangat membantu dalam hal ini: optimalkan logika permainan Anda sehingga Anda dapat dengan mudah meniadakan efek latensi dengan memastikan bahwa server dan klien dapat meniru perilaku yang mirip berdasarkan input pemain.

Saya telah menjelaskan seluruh skema yang saya gunakan dalam proyek saya jadi saya harap Anda akan menemukan jawaban untuk pertanyaan Anda.

Alexander Smirnov
sumber