Mengenai model rangkaian dalam permainan untuk pemula

Mengenai model rangkaian dalam permainan untuk pemula
Selama dua minggu lepas saya telah mengusahakan enjin dalam talian untuk permainan saya. Sebelum ini, saya tidak tahu langsung tentang rangkaian dalam permainan, jadi saya membaca banyak artikel dan melakukan banyak eksperimen untuk memahami semua konsep dan boleh menulis enjin rangkaian saya sendiri.

Dalam panduan ini, saya ingin berkongsi dengan anda pelbagai konsep yang perlu anda pelajari sebelum menulis enjin permainan anda sendiri, serta sumber dan artikel terbaik untuk mempelajarinya.

Secara umum, terdapat dua jenis utama seni bina rangkaian: peer-to-peer dan klien-server. Dalam seni bina peer-to-peer (p2p), data dipindahkan antara mana-mana pasangan pemain yang disambungkan, manakala dalam seni bina pelayan-pelanggan, data dipindahkan hanya antara pemain dan pelayan.

Walaupun seni bina peer-to-peer masih digunakan dalam sesetengah permainan, pelayan-klien adalah standard: ia lebih mudah untuk dilaksanakan, memerlukan lebar saluran yang lebih kecil dan menjadikannya lebih mudah untuk melindungi daripada penipuan. Oleh itu, dalam tutorial ini kita akan memberi tumpuan kepada seni bina pelayan-pelanggan.

Khususnya, kami paling berminat dengan pelayan autoritarian: dalam sistem sedemikian, pelayan sentiasa betul. Sebagai contoh, jika pemain fikir dia berada di koordinat (10, 5), dan pelayan memberitahunya bahawa dia berada di (5, 3), maka pelanggan harus menggantikan kedudukannya dengan yang dilaporkan oleh pelayan, dan bukannya sebaliknya. sebaliknya. Menggunakan pelayan berwibawa memudahkan untuk mengenal pasti penipu.

Sistem permainan rangkaian mempunyai tiga komponen utama:

  • Protokol pengangkutan: bagaimana data dipindahkan antara pelanggan dan pelayan.
  • Protokol aplikasi: apa yang dihantar dari klien ke pelayan dan dari pelayan ke klien dan dalam format apa.
  • Logik aplikasi: bagaimana data yang dipindahkan digunakan untuk mengemas kini keadaan pelanggan dan pelayan.

Adalah sangat penting untuk memahami peranan setiap bahagian dan cabaran yang berkaitan dengannya.

Protokol pengangkutan

Langkah pertama ialah memilih protokol untuk mengangkut data antara pelayan dan pelanggan. Terdapat dua protokol Internet untuk ini: TCP ΠΈ UDP. Tetapi anda boleh membuat protokol pengangkutan anda sendiri berdasarkan salah satu daripadanya atau menggunakan perpustakaan yang menggunakannya.

Perbandingan TCP dan UDP

Kedua-dua TCP dan UDP adalah berdasarkan IP. IP membenarkan paket dihantar dari sumber kepada penerima, tetapi tidak menjamin bahawa paket yang dihantar lambat laun akan sampai kepada penerima, bahawa ia akan sampai sekurang-kurangnya sekali, dan urutan paket akan tiba dengan betul. pesanan. Selain itu, satu paket hanya boleh mengandungi jumlah data yang terhad, diberikan oleh nilai MTU.

UDP hanyalah lapisan nipis di atas IP. Oleh itu, ia mempunyai batasan yang sama. Sebaliknya, TCP mempunyai banyak ciri. Ia menyediakan sambungan yang boleh dipercayai dan teratur antara dua nod dengan pemeriksaan ralat. Oleh itu, TCP sangat mudah dan digunakan dalam banyak protokol lain, mis. HTTP, ftp ΠΈ SMTP. Tetapi semua ciri ini datang pada harga: kelewatan.

Untuk memahami sebab fungsi ini boleh menyebabkan kependaman, kita perlu memahami cara TCP berfungsi. Apabila nod penghantar menghantar paket ke nod penerima, ia menjangka untuk menerima pengakuan (ACK). Jika selepas masa tertentu ia tidak menerimanya (kerana paket atau pengakuan hilang, atau atas sebab lain), maka ia menghantar semula paket itu. Selain itu, TCP menjamin bahawa paket diterima dalam susunan yang betul, jadi sehingga paket yang hilang diterima, semua paket lain tidak dapat diproses, walaupun ia telah diterima oleh hos penerima.

Tetapi seperti yang anda boleh bayangkan, kependaman dalam permainan berbilang pemain adalah sangat penting, terutamanya dalam genre penuh aksi seperti FPS. Inilah sebabnya mengapa banyak permainan menggunakan UDP dengan protokol mereka sendiri.

Protokol berasaskan UDP asli boleh menjadi lebih cekap daripada TCP atas pelbagai sebab. Sebagai contoh, ia boleh menandakan beberapa paket sebagai dipercayai dan yang lain sebagai tidak dipercayai. Oleh itu, ia tidak peduli sama ada paket yang tidak dipercayai sampai kepada penerima. Atau ia boleh memproses berbilang aliran data supaya paket yang hilang dalam satu aliran tidak memperlahankan aliran yang tinggal. Sebagai contoh, mungkin terdapat urutan untuk input pemain dan urutan lain untuk mesej sembang. Jika mesej sembang yang tidak mendesak hilang, ia tidak akan melambatkan input yang mendesak. Atau protokol proprietari mungkin melaksanakan kebolehpercayaan secara berbeza daripada TCP untuk menjadi lebih cekap dalam persekitaran permainan video.

Jadi, jika TCP menyusahkan, maka kami akan mencipta protokol pengangkutan kami sendiri berdasarkan UDP?

Ia lebih rumit sedikit. Walaupun TCP hampir tidak optimum untuk sistem rangkaian permainan, ia boleh berfungsi dengan baik untuk permainan khusus anda dan menjimatkan masa anda yang berharga. Sebagai contoh, kependaman mungkin bukan isu untuk permainan berasaskan giliran atau permainan yang hanya boleh dimainkan pada rangkaian LAN, di mana kependaman dan kehilangan paket jauh lebih rendah daripada di Internet.

Banyak permainan yang berjaya, termasuk World of Warcraft, Minecraft dan Terraria, menggunakan TCP. Walau bagaimanapun, kebanyakan FPS menggunakan protokol berasaskan UDP mereka sendiri, jadi kami akan bercakap lebih lanjut mengenainya di bawah.

Jika anda memutuskan untuk menggunakan TCP, pastikan ia dilumpuhkan Algoritma Nagle, kerana ia menimbal paket sebelum dihantar, yang bermaksud ia meningkatkan kependaman.

Untuk mengetahui lebih lanjut tentang perbezaan antara UDP dan TCP dalam konteks permainan berbilang pemain, anda boleh membaca artikel Glenn Fiedler UDP lwn. TCP.

Protokol sendiri

Jadi anda ingin mencipta protokol pengangkutan anda sendiri, tetapi tidak tahu di mana untuk bermula? Anda bertuah kerana Glenn Fiedler telah menulis dua artikel yang menakjubkan tentang perkara ini. Anda akan dapati banyak pemikiran pintar di dalamnya.

Artikel pertama Rangkaian untuk Pengaturcara Permainan 2008, lebih mudah daripada yang kedua, Membina Protokol Rangkaian Permainan 2016. Saya syorkan anda mulakan dengan yang lebih tua.

Ambil perhatian bahawa Glenn Fiedler adalah penyokong besar menggunakan protokol tersuai berdasarkan UDP. Dan selepas membaca artikelnya, anda mungkin akan menerima pakai pendapatnya bahawa TCP mempunyai kelemahan yang serius dalam permainan video, dan anda akan mahu melaksanakan protokol anda sendiri.

Tetapi jika anda baru dalam rangkaian, bantu diri anda sendiri dan gunakan TCP atau perpustakaan. Untuk berjaya melaksanakan protokol pengangkutan anda sendiri, anda perlu banyak belajar terlebih dahulu.

Perpustakaan rangkaian

Jika anda memerlukan sesuatu yang lebih cekap daripada TCP, tetapi tidak mahu melalui kerumitan melaksanakan protokol anda sendiri dan pergi ke banyak perincian, anda boleh menggunakan perpustakaan rangkaian. Terdapat banyak daripada mereka:

Saya belum mencuba kesemuanya, tetapi saya lebih suka ENet kerana ia mudah digunakan dan boleh dipercayai. Di samping itu, ia mempunyai dokumentasi yang jelas dan tutorial untuk pemula.

Protokol Pengangkutan: Kesimpulan

Untuk meringkaskan: terdapat dua protokol pengangkutan utama: TCP dan UDP. TCP mempunyai banyak ciri berguna: kebolehpercayaan, pemeliharaan pesanan paket, pengesanan ralat. UDP tidak mempunyai semua ini, tetapi TCP mengikut sifatnya telah meningkatkan kependaman, yang tidak boleh diterima untuk sesetengah permainan. Iaitu, untuk memastikan kependaman rendah, anda boleh membuat protokol anda sendiri berdasarkan UDP atau menggunakan perpustakaan yang melaksanakan protokol pengangkutan pada UDP dan disesuaikan untuk permainan video berbilang pemain.

Pilihan antara TCP, UDP dan perpustakaan bergantung pada beberapa faktor. Pertama, dari keperluan permainan: adakah ia memerlukan kependaman rendah? Kedua, dari keperluan protokol aplikasi: adakah ia memerlukan protokol yang boleh dipercayai? Seperti yang akan kita lihat dalam bahagian seterusnya, adalah mungkin untuk mencipta protokol aplikasi yang mana protokol yang tidak dipercayai agak sesuai. Akhir sekali, anda juga perlu mengambil kira pengalaman pembangun enjin rangkaian.

Saya ada dua nasihat:

  • Abstrak protokol pengangkutan dari seluruh aplikasi sebanyak mungkin supaya ia boleh diganti dengan mudah tanpa menulis semula semua kod.
  • Jangan terlalu mengoptimumkan. Jika anda bukan pakar rangkaian dan tidak pasti sama ada anda memerlukan protokol pengangkutan berasaskan UDP tersuai, anda boleh mulakan dengan TCP atau perpustakaan yang menyediakan kebolehpercayaan, dan kemudian menguji dan mengukur prestasi. Jika masalah timbul dan anda yakin bahawa puncanya adalah protokol pengangkutan, maka mungkin sudah tiba masanya untuk mencipta protokol pengangkutan anda sendiri.

Di penghujung bahagian ini, saya syorkan anda membaca Pengenalan kepada Pengaturcaraan Permainan Berbilang Pemain oleh Brian Hook, yang merangkumi banyak topik yang dibincangkan di sini.

Protokol aplikasi

Sekarang kita boleh bertukar-tukar data antara pelanggan dan pelayan, kita perlu memutuskan data yang hendak dipindahkan dan dalam format apa.

Skim klasik ialah pelanggan menghantar input atau tindakan kepada pelayan, dan pelayan menghantar keadaan permainan semasa kepada pelanggan.

Pelayan tidak menghantar keadaan penuh, tetapi keadaan ditapis dengan entiti yang terletak berhampiran pemain. Dia melakukan ini kerana tiga sebab. Pertama, keadaan lengkap mungkin terlalu besar untuk dihantar pada frekuensi tinggi. Kedua, pelanggan terutamanya berminat dalam data visual dan audio, kerana kebanyakan logik permainan disimulasikan pada pelayan permainan. Ketiga, dalam beberapa permainan pemain tidak perlu mengetahui data tertentu, sebagai contoh, kedudukan musuh di sisi lain peta, jika tidak, dia boleh menghidu paket dan tahu dengan tepat ke mana hendak bergerak untuk membunuhnya.

Serialisasi

Langkah pertama ialah menukar data yang ingin kami hantar (keadaan input atau permainan) ke dalam format yang sesuai untuk penghantaran. Proses ini dipanggil bersiri.

Pemikiran yang segera terlintas di fikiran ialah menggunakan format yang boleh dibaca manusia, seperti JSON atau XML. Tetapi ini akan menjadi tidak berkesan sama sekali dan akan membazirkan kebanyakan saluran.

Adalah disyorkan untuk menggunakan format binari sebaliknya, yang lebih padat. Iaitu, paket hanya akan mengandungi beberapa bait. Terdapat masalah untuk dipertimbangkan di sini pesanan bait, yang mungkin berbeza pada komputer yang berbeza.

Untuk mensiri data, anda boleh menggunakan perpustakaan, contohnya:

Hanya pastikan perpustakaan mencipta arkib mudah alih dan mengambil berat tentang endian.

Penyelesaian alternatif ialah melaksanakannya sendiri; ia tidak begitu sukar, terutamanya jika anda menggunakan pendekatan berpusatkan data kepada kod anda. Di samping itu, ia akan membolehkan anda melakukan pengoptimuman yang tidak selalu dapat dilakukan apabila menggunakan perpustakaan.

Glenn Fiedler menulis dua artikel mengenai serialisasi: Paket Membaca dan Menulis ΠΈ Strategi Serialisasi.

Pemampatan

Jumlah data yang dipindahkan antara pelanggan dan pelayan dihadkan oleh lebar jalur saluran. Pemampatan data akan membolehkan anda memindahkan lebih banyak data dalam setiap syot kilat, meningkatkan kekerapan kemas kini atau hanya mengurangkan keperluan saluran.

Pembungkusan bit

Teknik pertama adalah sedikit pembungkusan. Ia terdiri daripada menggunakan tepat bilangan bit yang diperlukan untuk menerangkan nilai yang dikehendaki. Sebagai contoh, jika anda mempunyai enum yang boleh mempunyai 16 nilai berbeza, maka bukannya bait keseluruhan (8 bit), anda boleh menggunakan hanya 4 bit.

Glenn Fiedler menerangkan cara melaksanakan perkara ini dalam bahagian kedua artikel Paket Membaca dan Menulis.

Pembungkusan bit berfungsi dengan baik terutamanya dengan pensampelan, yang akan menjadi topik bahagian seterusnya.

Pensampelan

Pensampelan ialah teknik mampatan lossy yang hanya menggunakan subset nilai yang mungkin untuk mengekod nilai. Cara paling mudah untuk melaksanakan pendiskretan ialah dengan membundarkan nombor titik terapung.

Glenn Fiedler (sekali lagi!) menunjukkan cara mempraktikkan pensampelan dalam artikelnya Mampatan Syot Kilat.

Algoritma pemampatan

Teknik seterusnya ialah algoritma pemampatan tanpa kerugian.

Di sini, pada pendapat saya, adalah tiga algoritma paling menarik yang perlu anda ketahui:

  • Pengekodan Huffman dengan kod pra-pengiraan, yang sangat pantas dan boleh menghasilkan keputusan yang baik. Ia digunakan untuk memampatkan paket dalam enjin rangkaian Quake3.
  • zlib ialah algoritma pemampatan tujuan umum yang tidak pernah meningkatkan jumlah data. Bagaimana anda boleh melihat di sini, ia telah digunakan dalam pelbagai aplikasi. Ia mungkin berlebihan untuk mengemas kini keadaan. Tetapi ia boleh berguna jika anda perlu menghantar aset, teks panjang atau rupa bumi kepada pelanggan daripada pelayan.
  • Menyalin panjang larian - Ini mungkin algoritma pemampatan yang paling mudah, tetapi ia sangat berkesan untuk jenis data tertentu, dan boleh digunakan sebagai langkah pra-pemprosesan sebelum zlib. Ia amat sesuai untuk memampatkan rupa bumi yang terdiri daripada jubin atau voxel di mana banyak elemen bersebelahan diulang.

Mampatan delta

Teknik pemampatan terakhir ialah pemampatan delta. Ia terdiri daripada fakta bahawa hanya perbezaan antara keadaan permainan semasa dan keadaan terakhir yang diterima oleh pelanggan dihantar.

Ia pertama kali digunakan dalam enjin rangkaian Quake3. Berikut ialah dua artikel yang menerangkan cara menggunakannya:

Glenn Fiedler juga menggunakannya dalam bahagian kedua artikelnya Mampatan Syot Kilat.

Penyulitan

Di samping itu, anda mungkin perlu menyulitkan pemindahan maklumat antara pelanggan dan pelayan. Terdapat beberapa sebab untuk ini:

  • privasi/kerahsiaan: mesej hanya boleh dibaca oleh penerima dan tiada orang lain yang menghidu rangkaian akan dapat membacanya.
  • pengesahan: seseorang yang ingin memainkan peranan sebagai pemain mesti mengetahui kuncinya.
  • Pencegahan penipuan: Ia akan menjadi lebih sukar bagi pemain berniat jahat untuk mencipta pakej penipuan mereka sendiri, mereka perlu menghasilkan semula skim penyulitan dan mencari kunci (yang berubah dengan setiap sambungan).

Saya amat mengesyorkan menggunakan perpustakaan untuk ini. Saya cadangkan menggunakan lisodium, kerana ia sangat mudah dan mempunyai tutorial yang sangat baik. Terutama menarik ialah tutorial mengenai pertukaran kunci, yang membolehkan anda menjana kunci baharu dengan setiap sambungan baharu.

Protokol Aplikasi: Kesimpulan

Ini menyimpulkan protokol aplikasi kami. Saya percaya bahawa pemampatan adalah pilihan sepenuhnya dan keputusan untuk menggunakannya hanya bergantung pada permainan dan lebar jalur yang diperlukan. Penyulitan, pada pendapat saya, adalah wajib, tetapi dalam prototaip pertama anda boleh lakukan tanpanya.

Logik aplikasi

Kami kini boleh mengemas kini keadaan dalam klien, tetapi mungkin menghadapi masalah kependaman. Pemain, selepas melengkapkan input, perlu menunggu keadaan permainan dikemas kini daripada pelayan untuk melihat kesannya terhadap dunia.

Lebih-lebih lagi, antara dua kemas kini negeri, dunia benar-benar statik. Jika kadar kemas kini negeri adalah rendah, maka pergerakan akan menjadi sangat tersentak.

Terdapat beberapa teknik untuk mengurangkan kesan masalah ini, dan saya akan membincangkannya dalam bahagian seterusnya.

Teknik Melicin Latensi

Semua teknik yang diterangkan dalam bahagian ini dibincangkan secara terperinci dalam siri ini Berbilang Pemain Pantas Gabriel Gambetta. Saya sangat mengesyorkan membaca siri artikel yang sangat baik ini. Ia juga termasuk demo interaktif yang membolehkan anda melihat cara teknik ini berfungsi dalam amalan.

Teknik pertama adalah menggunakan hasil input secara langsung tanpa menunggu respons daripada pelayan. Ia dikenali sebagai ramalan sisi pelanggan. Walau bagaimanapun, apabila pelanggan menerima kemas kini daripada pelayan, ia mesti mengesahkan bahawa ramalannya adalah betul. Jika ini tidak berlaku, maka dia hanya perlu menukar keadaannya mengikut apa yang dia terima daripada pelayan, kerana pelayan itu autoritarian. Teknik ini pertama kali digunakan dalam Quake. Anda boleh membaca lebih lanjut mengenainya dalam artikel Semakan kod Enjin Gempa Fabien Sanglars [terjemahan pada HabrΓ©].

Set teknik kedua digunakan untuk melicinkan pergerakan entiti lain antara dua kemas kini keadaan. Terdapat dua cara untuk menyelesaikan masalah ini: interpolasi dan ekstrapolasi. Dalam kes interpolasi, dua keadaan terakhir diambil dan peralihan dari satu ke yang lain ditunjukkan. Kelemahannya ialah ia menyebabkan sedikit kelewatan kerana klien sentiasa melihat apa yang berlaku pada masa lalu. Ekstrapolasi adalah mengenai meramalkan tempat entiti seharusnya kini berdasarkan keadaan terakhir yang diterima oleh pelanggan. Kelemahannya ialah jika entiti menukar arah pergerakan sepenuhnya, maka akan berlaku ralat besar antara ramalan dan kedudukan sebenar.

Teknik terkini dan paling canggih yang hanya berguna dalam FPS ialah pampasan ketinggalan. Apabila menggunakan pampasan lag, pelayan mengambil kira kelewatan pelanggan apabila ia menembak pada sasaran. Contohnya, jika pemain melakukan tangkapan kepala pada skrin mereka, tetapi sebenarnya sasaran mereka berada di lokasi yang berbeza kerana kelewatan, maka adalah tidak adil untuk menafikan hak pemain untuk membunuh kerana kelewatan. Oleh itu, pelayan memundurkan masa kembali ke saat pemain melepaskan tembakan untuk mensimulasikan apa yang pemain lihat pada skrin mereka dan memeriksa perlanggaran antara pukulan mereka dan sasaran.

Glenn Fiedler (seperti biasa!) menulis artikel pada tahun 2004 Fizik Rangkaian (2004), di mana beliau meletakkan asas untuk menyegerakkan simulasi fizik antara pelayan dan pelanggan. Pada tahun 2014 dia menulis satu siri artikel baru Fizik Rangkaian, yang menerangkan teknik lain untuk menyegerakkan simulasi fizik.

Terdapat juga dua artikel di wiki Valve, Rangkaian Berbilang Pemain Sumber ΠΈ Kaedah Pampasan Kependaman dalam Reka Bentuk dan Pengoptimuman Protokol Dalam Permainan Pelanggan/Pelayan yang mempertimbangkan pampasan untuk kelewatan.

Mencegah penipuan

Terdapat dua teknik utama untuk mencegah penipuan.

Pertama: menjadikannya lebih sukar bagi penipu untuk menghantar paket berniat jahat. Seperti yang dinyatakan di atas, cara yang baik untuk melaksanakan ini ialah penyulitan.

Kedua: pelayan autoritarian hanya boleh menerima arahan/input/tindakan. Pelanggan seharusnya tidak boleh menukar keadaan pada pelayan selain dengan menghantar input. Kemudian, setiap kali pelayan menerima input, ia mesti menyemak sama ada ia sah sebelum menggunakannya.

Logik aplikasi: kesimpulan

Saya syorkan anda melaksanakan cara untuk mensimulasikan latensi tinggi dan kadar muat semula yang rendah supaya anda boleh menguji kelakuan permainan anda dalam keadaan yang teruk, walaupun ketika klien dan pelayan berjalan pada komputer yang sama. Ini akan sangat memudahkan pelaksanaan teknik pelicinan kelewatan.

Sumber Berguna Lain

Jika anda ingin meneroka sumber lain pada model rangkaian, anda boleh menemuinya di sini:

Sumber: www.habr.com

Tambah komen