Megapack: Cara Factorio Menyelesaikan Masalah Berbilang Pemain 200 Pemain

Megapack: Cara Factorio Menyelesaikan Masalah Berbilang Pemain 200 Pemain
Pada bulan Mei tahun ini, saya mengambil bahagian sebagai pemain Acara MMO KatherineOfSky. Saya perhatikan apabila bilangan pemain mencapai jumlah tertentu, setiap beberapa minit sebahagian daripada mereka "jatuh". Nasib baik untuk anda (tetapi bukan untuk saya), saya adalah salah seorang pemain itu setiap kaliwalaupun dengan sambungan yang baik. Saya menganggapnya sebagai cabaran peribadi dan mula mencari punca masalah itu. Selepas tiga minggu penyahpepijatan, ujian dan pembetulan, pepijat akhirnya dibetulkan, tetapi perjalanannya tidak begitu mudah.

Masalah dalam permainan berbilang pemain sangat sukar untuk dikesan. Ia biasanya berlaku di bawah parameter rangkaian yang sangat spesifik dan di bawah keadaan permainan yang sangat spesifik (dalam kes ini, lebih 200 pemain). Dan walaupun masalah boleh diterbitkan semula, ia tidak boleh dinyahpepijat dengan betul kerana memasukkan titik putus menghentikan permainan, mengacaukan pemasa dan biasanya menyebabkan sambungan tamat masa kerana tamat masa. Tetapi terima kasih kepada ketekunan dan alat yang hebat dipanggil kekok Saya dapat mengetahui apa yang berlaku.

Ringkasnya, disebabkan pepijat dan pelaksanaan simulasi keadaan kelewatan yang tidak lengkap, pelanggan kadangkala mendapati dirinya dalam situasi di mana ia terpaksa menghantar paket rangkaian dalam satu kitaran jam, yang terdiri daripada tindakan input pemain untuk memilih kira-kira 400 entiti permainan ( kami memanggilnya "megapaket"). Selepas itu, pelayan bukan sahaja perlu menerima dengan betul semua tindakan input ini, tetapi juga menghantarnya kepada semua pelanggan lain. Jika anda mempunyai 200 pelanggan, ini dengan cepat menjadi masalah. Saluran ke pelayan dengan cepat menjadi tersumbat, mengakibatkan kehilangan paket dan rangkaian paket yang diminta semula. Menangguhkan tindakan input kemudian menyebabkan lebih ramai pelanggan mula menghantar megapaket, dan runtuhan salji mereka menjadi lebih kuat. Pelanggan yang berjaya berjaya pulih, semua yang lain jatuh.

Megapack: Cara Factorio Menyelesaikan Masalah Berbilang Pemain 200 Pemain
Masalahnya agak asas, dan saya mengambil masa 2 minggu untuk menyelesaikannya. Ia agak teknikal, jadi saya akan menerangkan butiran teknikal yang menarik di bawah. Tetapi pertama sekali, anda perlu tahu bahawa sejak versi 0.17.54, dikeluarkan pada 4 Jun, dalam menghadapi masalah sambungan sementara, berbilang pemain telah menjadi lebih stabil, dan kelewatan bersembunyi adalah lebih kurang buggy (kurang brek dan teleport). Selain itu, saya telah mengubah cara kelewatan pertempuran disembunyikan, dan semoga ini akan menjadikannya lebih lancar.

Pek Mega Berbilang Pemain - Butiran Teknikal

Ringkasnya, berbilang pemain dalam permainan berfungsi seperti ini: semua pelanggan mensimulasikan keadaan permainan dengan menerima dan menghantar input pemain sahaja (dipanggil "tindakan input" Tindakan Input). Tugas utama pelayan adalah untuk memindahkan Tindakan Input dan memastikan semua pelanggan melakukan tindakan yang sama dalam kitaran yang sama. Anda boleh membaca lebih lanjut mengenai ini dalam siaran. FFF-149.

Memandangkan pelayan perlu membuat keputusan tentang tindakan yang perlu diambil, tindakan pemain bergerak mengikut laluan berikut: tindakan pemain -> klien permainan -> rangkaian -> pelayan -> rangkaian -> klien permainan. Ini bermakna setiap tindakan pemain dilakukan hanya selepas ia membuat laluan pergi balik melalui rangkaian. Oleh sebab itu, permainan akan kelihatan sangat perlahan, jadi hampir sejurus selepas kemunculan berbilang pemain dalam permainan, mekanisme untuk menyembunyikan kelewatan diperkenalkan. Penyembunyian kependaman mensimulasikan input pemain tanpa mengambil kira tindakan pemain lain dan membuat keputusan pelayan.

Megapack: Cara Factorio Menyelesaikan Masalah Berbilang Pemain 200 Pemain
Factorio mempunyai keadaan permainan keadaan permainan ialah keadaan lengkap peta, pemain, entiti dan segala-galanya. Ia disimulasikan secara deterministik dalam semua pelanggan berdasarkan tindakan yang diterima daripada pelayan. Keadaan permainan adalah suci, dan jika ia mula berbeza daripada pelayan atau mana-mana klien lain, maka penyahsegerakan berlaku.

Tetapi keadaan permainan kita mempunyai keadaan kelewatan Keadaan Latensi. Ia mengandungi subset kecil keadaan utama. Keadaan Latensi tidak suci dan hanya mewakili gambaran tentang keadaan permainan pada masa hadapan berdasarkan input daripada pemain Tindakan Input.

Untuk melakukan ini, kami menyimpan salinan yang dihasilkan Tindakan Input dalam barisan kelewatan.

Megapack: Cara Factorio Menyelesaikan Masalah Berbilang Pemain 200 Pemain
Iaitu, pada akhir proses di sisi pelanggan, gambar kelihatan seperti ini:

  1. Mohon Tindakan Input semua pemain ke keadaan permainan cara tindakan input ini diterima daripada pelayan.
  2. Alih keluar segala-galanya daripada baris gilir kelewatan Tindakan Input, yang, menurut pelayan, telah digunakan untuk keadaan permainan.
  3. Padam Keadaan Latensi dan tetapkan semula supaya ia kelihatan sama seperti keadaan permainan.
  4. Gunakan semua tindakan dari baris gilir kelewatan hingga Keadaan Latensi.
  5. Berdasarkan data keadaan permainan ΠΈ Keadaan Latensi memberikan permainan kepada pemain.

Semua ini diulang dalam setiap ukuran.

Sangat susah? Jangan berehat, bukan itu sahaja. Untuk mengimbangi sambungan Internet yang tidak boleh dipercayai, kami telah mencipta dua mekanisme:

  • Tanda dilangkau: apabila pelayan memutuskan itu Tindakan Input akan dilaksanakan dalam kebijaksanaan permainan, maka jika dia belum menerima Tindakan Input sesetengah pemain (contohnya, disebabkan kelewatan yang meningkat), dia tidak akan menunggu, tetapi akan memberitahu pelanggan ini "Saya tidak mengambil kira anda Tindakan Input, saya akan cuba menambahkannya dalam bar seterusnya. Ini dilakukan supaya disebabkan masalah dengan sambungan (atau dengan komputer) satu pemain, kemas kini peta tidak menjadi perlahan untuk orang lain. Perlu diingat bahawa Tindakan Input tidak diabaikan, tetapi hanya ditangguhkan.
  • Kependaman pergi balik penuh: Pelayan cuba meneka apakah kependaman pergi balik antara pelanggan dan pelayan untuk setiap pelanggan. Setiap 5 saat, ia merundingkan kelewatan baharu dengan pelanggan mengikut keperluan (bergantung pada cara sambungan telah berkelakuan pada masa lalu) dan menambah atau mengurangkan kelewatan perjalanan pergi dan balik dengan sewajarnya.

Dengan sendirinya, mekanisme ini agak mudah, tetapi apabila ia digunakan bersama (yang sering berlaku dengan masalah sambungan), logik kod menjadi sukar untuk diurus dan dengan banyak kes kelebihan. Di samping itu, apabila mekanisme ini mula bermain, pelayan dan baris gilir kelewatan mesti melaksanakan khas dengan betul Tindakan Input dipanggil StopMovementInTheNextTick. Terima kasih kepada ini, sekiranya berlaku masalah sambungan, watak itu tidak akan berjalan sendiri (contohnya, di bawah kereta api).

Sekarang saya perlu menerangkan kepada anda cara pemilihan entiti berfungsi. Salah satu jenis yang lulus Tindakan Input ialah perubahan dalam keadaan pemilihan sesuatu entiti. Ia memberitahu semua orang entiti mana yang pemain tuding dengan tetikus. Seperti yang anda boleh lihat, ini adalah salah satu tindakan input yang paling kerap dihantar oleh pelanggan, jadi untuk menjimatkan lebar jalur, kami telah mengoptimumkannya supaya ia mengambil sedikit ruang yang mungkin. Ini dilaksanakan seperti ini: apabila setiap entiti dipilih, bukannya menyimpan koordinat peta berketepatan tinggi mutlak, permainan menyimpan offset relatif ketepatan rendah daripada pemilihan sebelumnya. Ini berfungsi dengan baik kerana pemilihan tetikus biasanya berlaku sangat hampir dengan pemilihan sebelumnya. Ini menimbulkan dua keperluan penting: Tindakan Input tidak boleh dilangkau dan mesti dilakukan mengikut urutan yang betul. Keperluan ini dipenuhi untuk keadaan permainan. Tetapi sejak tugas itu keadaan latensi dalam "kelihatan cukup baik" untuk pemain, mereka tidak berpuas hati dalam keadaan kelewatan. Keadaan Latensi tidak mengambil kira banyak kes sempadandikaitkan dengan melangkau jam dan menukar kelewatan penghantaran pergi balik.

Anda sudah boleh meneka ke mana arahnya. Akhirnya kita mula melihat punca masalah megapackage. Punca masalah ialah logik pemilihan entiti bergantung pada Keadaan Latensi, dan keadaan ini tidak selalu mengandungi maklumat yang betul. Jadi megapacket dijana seperti ini:

  1. Pemain mengalami masalah sambungan.
  2. Mekanisme untuk melangkau kitaran dan mengawal kelewatan penghantaran pergi dan balik turut dimainkan.
  3. Barisan gilir keadaan kelewatan tidak mengambil kira mekanisme ini. Ini menyebabkan beberapa tindakan dialih keluar lebih awal atau dijalankan dalam susunan yang salah, mengakibatkan tindakan tidak betul Keadaan Latensi.
  4. Pemain tidak mempunyai masalah sambungan dan mensimulasikan sehingga 400 kitaran untuk mengejar pelayan.
  5. Dalam setiap kitaran, tindakan baharu dijana dan disediakan untuk dihantar ke pelayan, mengubah pemilihan entiti.
  6. Pelanggan menghantar megapaket sebanyak 400+ perubahan pemilihan entiti kepada pelayan (dan dengan tindakan lain: keadaan menembak, keadaan berjalan, dsb. turut mengalami masalah ini).
  7. Pelayan menerima 400 tindakan input. Memandangkan ia tidak dibenarkan melangkau satu tindakan input, ia mengarahkan semua pelanggan untuk melaksanakan tindakan ini dan menghantarnya melalui rangkaian.

Ironinya ialah mekanisme yang direka untuk menjimatkan lebar jalur menghasilkan paket rangkaian yang besar.

Kami telah menyelesaikan isu ini dengan membetulkan semua kes tepi kemas kini dan menangguhkan sokongan baris gilir. Walaupun ia mengambil masa yang agak lama, ia berbaloi untuk membetulkannya pada akhirnya daripada bergantung pada penggodaman pantas.

Sumber: www.habr.com

Tambah komen