Saya tertarik untuk mengevaluasi berbagai cara yang berbeda bahwa netcode dapat "menghubungkan ke" mesin gim. Saya sedang mendesain permainan multipemain sekarang, dan sejauh ini saya telah menentukan bahwa saya perlu (paling tidak) memiliki utas terpisah untuk menangani soket jaringan, berbeda dari sisa mesin yang menangani loop grafis dan skrip.
Saya memang memiliki satu cara potensial untuk membuat game jaringan sepenuhnya single-threaded, yaitu memeriksanya setelah merender setiap frame, menggunakan soket non-blocking. Namun ini jelas tidak optimal karena waktu yang diperlukan untuk membuat bingkai ditambahkan ke jeda jaringan: Pesan yang tiba melalui jaringan harus menunggu sampai bingkai saat ini membuat (dan logika game) selesai. Tapi, setidaknya dengan cara ini gameplaynya akan tetap lancar, kurang lebih.
Memiliki utas terpisah untuk jaringan memungkinkan game menjadi sepenuhnya responsif terhadap jaringan, misalnya ia dapat mengirim kembali paket ACK secara instan setelah menerima pembaruan status dari server. Tapi saya agak bingung tentang cara terbaik untuk berkomunikasi antara kode permainan dan kode jaringan. Utas jaringan akan mendorong paket yang diterima ke antrian, dan utas permainan akan membaca dari antrian pada waktu yang tepat selama perulangannya, jadi kami belum menyingkirkan keterlambatan bingkai hingga satu ini.
Juga, sepertinya saya ingin utas yang menangani pengiriman paket terpisah dari yang memeriksa paket yang turun, karena tidak akan dapat mengirim satu saat berada di tengah-tengah memeriksa apakah ada pesan masuk. Saya berpikir tentang fungsi select
atau sejenisnya.
Saya kira pertanyaan saya adalah, apa cara terbaik untuk mendesain game untuk respon jaringan yang terbaik? Jelas klien harus mengirim input pengguna sesegera mungkin ke server, jadi saya bisa meminta kode net-send segera setelah loop pemrosesan acara, keduanya di dalam loop game. Apakah ini masuk akal?
sumber
Tidak, kamu tidak.
Tidak penting. Kapan logika Anda diperbarui? Ada gunanya mengambil data dari jaringan jika Anda belum bisa melakukan apa-apa dengannya. Demikian pula ada gunanya merespons jika Anda tidak memiliki sesuatu untuk dikatakan.
Jika game Anda berjalan sangat cepat sehingga menunggu frame berikutnya yang akan diberikan adalah penundaan yang signifikan, maka itu akan mengirimkan cukup data sehingga Anda tidak perlu mengirim paket ACK terpisah - cukup sertakan nilai ACK di dalam data normal Anda payload, jika Anda membutuhkannya sama sekali.
Untuk sebagian besar game berjejaring, sangat mungkin untuk memiliki loop game seperti ini:
Anda dapat memisahkan pembaruan dari rendering, yang sangat disarankan, tetapi segala sesuatu yang lain dapat tetap sederhana seperti itu kecuali Anda memiliki kebutuhan khusus. Apa jenis gim yang Anda buat?
sumber
Itu tidak benar sama sekali. Pesan melewati jaringan sementara penerima membuat bingkai saat ini. Kelambatan jaringan dijepit ke sejumlah bingkai di sisi klien; ya- tetapi jika klien memiliki FPS yang sangat sedikit sehingga ini adalah masalah besar, maka mereka memiliki masalah yang lebih besar.
sumber
Komunikasi jaringan harus dikelompokkan. Anda harus berjuang untuk satu paket yang dikirim setiap tick game (yang seringkali ketika frame diberikan tetapi benar-benar harus independen).
Entitas game Anda berbicara dengan subsistem jaringan (NSS). NSS mengumpulkan pesan, ACK, dll dan mengirimkan beberapa (semoga satu) paket UDP berukuran optimal (biasanya ~ 1500 byte). NSS mengemulasi paket, saluran, prioritas, mengirim ulang, dll, sementara hanya mengirim paket UDP tunggal.
Baca melalui gaffer pada tutorial gim atau gunakan ENet yang mengimplementasikan banyak ide Glenn Fiedler.
Atau Anda bisa menggunakan TCP jika gim Anda tidak membutuhkan reaksi kedutan. Lalu semua masalah batching, kirim ulang, dan ACK hilang. Anda masih menginginkan NSS untuk mengelola bandwidth dan saluran.
sumber
Jangan sepenuhnya "mengabaikan respons". Ada sedikit keuntungan dari menambahkan latensi 40ms ke paket yang sudah tertunda. Jika Anda menambahkan beberapa bingkai (pada 60fps) maka Anda menunda pemrosesan pembaruan posisi beberapa bingkai. Lebih baik menerima paket dengan cepat dan memprosesnya dengan cepat sehingga Anda meningkatkan akurasi simulasi.
Saya sangat sukses mengoptimalkan bandwidth dengan memikirkan informasi keadaan minimum yang diperlukan untuk merepresentasikan apa yang terlihat di layar. Kemudian melihat setiap bit data dan memilih model untuk itu. Informasi posisi dapat dinyatakan sebagai nilai delta seiring waktu. Anda dapat menggunakan model statistik Anda sendiri untuk ini dan menghabiskan waktu men-debug mereka, atau Anda dapat menggunakan perpustakaan untuk membantu Anda. Saya lebih suka menggunakan model floating point perpustakaan ini DataBlock_Predict_Float Itu membuatnya sangat mudah untuk mengoptimalkan bandwidth yang digunakan untuk grafik adegan permainan.
sumber