Saat ini saya sedang mengerjakan platformer multiplayer yang agak sederhana. Saya membaca cukup banyak artikel tentang teknik yang digunakan untuk menyembunyikan latensi, tetapi saya masih gagal memahami beberapa konsep. Saya menemukan topik yang sangat menarik dan suka mencoba ide sendiri, tetapi saya pikir meminta gamedev stackexchange akan lebih efisien untuk pertanyaan saya. Saya akan mencoba yang terbaik untuk menggambarkan situasi saya saat ini dan pertanyaan apa yang muncul di sepanjang jalan.
Saat ini, saya hanya ingin satu pemain disinkronkan dengan server. Secara teoritis, saya mengasumsikan seorang pemain sendiri dengan prediksi sisi klien tidak akan memerlukan koreksi server, karena tidak ada faktor eksternal yang mempengaruhi pergerakannya. Oleh karena itu, prototipe saya saat ini hanya memiliki satu pemain yang disinkronkan dengan server tanpa koreksi server yang dikirim.
Jika Anda terbiasa dengan jaringan game, saya pikir Anda dapat melewati bagian konteks, meskipun saya mungkin telah melakukan sesuatu yang salah di sepanjang jalan.
Lingkaran klien (sekali per bingkai, sekali setiap ~ 16,67 ms)
Simpul klien yang disederhanakan terlihat seperti:
Periksa input lokal (WASD) dan kemaslah sebagai tindakan (mis
Type=MoveLeft, Time=132.0902, ID=15
.). Kami menjaga tindakan paket untuk akhirnya mengirimnya nanti. Selain itu, kami langsung menerapkan tindakan yang diinginkan ke simulasi fisika lokal gim. Sebagai contoh, jika kita memilikiMoveLeft
aksi, kita menerapkan gaya ke kiri pada kecepatan pemain.Periksa untuk mengirim tindakan. Untuk mencegah penyalahgunaan bandwidth klien, hanya mengirim tindakan paket pada interval tertentu (misalnya 30 ms).
Terapkan modifikasi server. Pada titik tertentu ini akan menangani delta dan koreksi yang diterima oleh server dan menerapkannya pada simulasi permainan lokal. Untuk pertanyaan khusus ini, ini tidak digunakan.
Perbarui fisika setempat. Jalankan loop fisika pada pemain utama. Pada dasarnya, ini melakukan prediksi sisi klien dari pergerakan pemain. Ini menambah gravitasi pada kecepatan pemain, menerapkan kecepatan pemain ke posisinya, memperbaiki tabrakan di sepanjang jalan, dll. Saya harus menentukan bahwa simulasi fisika selalu dijalankan dengan delta tetap (disebut beberapa kali tergantung pada detik delta nyata) .
Saya melewatkan beberapa detail spesifik tentang fisika dan bagian lain karena saya merasa mereka tidak diharuskan untuk pertanyaan, tetapi merasa bebas untuk memberi tahu saya jika mereka akan relevan dengan pertanyaan itu.
Server loop (setiap 15 ms)
Loop server yang disederhanakan terlihat seperti:
Tangani tindakan. Periksa paket tindakan yang diterima dari klien dan terapkan pada simulasi fisika server. Sebagai contoh, kita dapat menerima 5
MoveLeft
aksi, dan kita akan menerapkan gaya pada kecepatan 5 kali . Penting untuk dicatat, paket seluruh tindakan dijalankan pada satu "bingkai" , berlawanan dengan klien di mana ia diterapkan segera setelah tindakan terjadi.Perbarui logika game. Kami memperbarui fisika permainan, menggerakkan pemain, dan memperbaiki tabrakan, dll. Kami juga mengemas setiap peristiwa penting yang kebetulan dikirim ke pemain (mis. Kesehatan pemain turun, pemain meninggal, dll.) Nanti.
Kirim koreksi. Kami secara teratur (mis. Setiap 35 ms) mengirim delta ke pemain lain (mis. Posisi pemain, kesehatan, dll.) Jika baru saja diubah. Bagian ini saat ini tidak diimplementasikan, karena saya ingin simulasi pemain tunggal untuk memberikan hasil yang sama pada klien dan server tanpa koreksi, untuk memastikan bahwa prediksi sisi klien berfungsi dengan baik.
Masalah
Sistem saat ini berfungsi dengan baik dalam keadaan sederhana, dan saya senang terkejut melihat bahwa ia memberikan hasil yang sangat mirip dengan gerakan horisontal sederhana (ketidakakuratan disebabkan oleh kesalahan presisi titik mengambang, saya percaya):
Abaikan grafik prototipe. Kotak putih = pemain, Kotak merah = rintangan, Biru = latar belakang
Namun, saya mendapatkan kesalahan sinkronisasi setelah melakukan gerakan sensitif waktu, seperti melompat dan bergerak mendekati rintangan yang terisolasi:
Secara teori, saya berharap keduanya selalu berakhir dengan hasil yang sama, karena tidak ada faktor eksternal pada klien yang mempengaruhi posisinya. Namun dalam praktiknya, saya pikir saya mengerti masalahnya.
Karena melompati rintangan seperti itu sangat tergantung pada waktu pemain, variasi kecil ketika kecepatan diterapkan pada posisi akan berakibat pada hasil (misalnya klien bisa bergerak tepat pada waktunya untuk menghindari tabrakan dengan pemain). Kendala, sementara server akan melakukannya karena menerima paket tindakan keseluruhan di kemudian hari dan tetap terjebak pada kendala untuk sejumlah kecil waktu, mengubah hasil akhir). Perbedaan antara bagaimana klien dan server menanganinya adalah bahwa klien melakukan semua tindakannya saat terjadi, sementara server melakukan semuanya dalam bulks saat menerimanya.
Pertanyaan
Konteks panjang ini akhirnya mengarah ke pertanyaan saya (terima kasih telah membaca sejauh ini): Apakah normal untuk meminta koreksi server walaupun hanya ada satu pemain yang disinkronkan dengan server, atau haruskah saya menggunakan teknik tertentu untuk menghindari desinkronisasi pada situasi yang peka waktu ?
Saya telah memikirkan solusi tertentu yang mungkin, beberapa di antaranya saya kurang nyaman dengan:
Terapkan koreksi server. Anggap saja ini perilaku normal dan perbaiki kesalahan yang terjadi. Saya ingin mengimplementasikannya, tetapi saya hanya ingin memastikan bahwa apa yang telah saya lakukan sejauh ini dapat diterima.
Gunakan waktu klien yang disediakan untuk menerapkan tindakan yang diinginkan. Saya kira ini akan mirip dengan kompensasi lag, yang membutuhkan "kembali ke masa lalu" dan memeriksa pergerakan. Seperti menerapkan koreksi server, kembali ke masa lalu dan mengajukan kembali tindakan selanjutnya setelah itu. Saya sangat tidak menyukai ide itu. Itu terlihat rumit, mahal dalam sumber daya dan membutuhkan kepercayaan waktu yang diberikan klien (walaupun saya berencana untuk benar-benar memeriksa bahwa waktu terlihat relatif sah).
Tanyakan GameDevelopment StackExchange untuk ide baru yang hebat yang akan memperbaiki semua masalah saya.
Saya baru memulai di dunia jaringan game, jadi silakan koreksi / kritik / penghinaan salah satu konsep di atas atau berikan ide / sumber daya yang dapat membantu saya sepanjang perjalanan saya di Dunia Jaringan yang Luar Biasa. Maafkan saya jika saya dapat menemukan jawaban saya di tempat lain, saya gagal dalam hal itu.
Terima kasih banyak atas waktu berharga Anda.