Saya tahu bahwa pengaturan multi-pemain super sederhana saya mungkin bukan ide yang baik, tetapi mengapa?

11

Saya membuat MOBA kecil sederhana hanya untuk bersenang-senang. Saya membuat semuanya single-player kemudian saya menyadari "oh sial, saya mungkin harus menambahkan multiplayer, ya."

Saya belum pernah melakukan apa pun dengan jaringan sebelumnya, jadi belajar bagaimana mengintegrasikan Lidgren ke dalam permainan saya menyenangkan dan mengagumkan. Masalahnya, saya cukup tahu cara saya melakukan sesuatu itu salah, karena itu tidak cukup kuat untuk digunakan oleh permainan umum, sejauh yang saya tahu, tetapi apa yang salah dengan itu?

Apa yang saya lakukan adalah, pada dasarnya, setiap kali seorang pemain melakukan suatu tindakan, ia mengirim pesan ke server mengatakan "hei, saya baru saja melakukan hal ini." Server dan klien menjalankan simulasi yang sama. Server kemudian mengirim pesan ke semua klien lain mengatakan kepada mereka bahwa orang itu melakukan hal itu.

Sebagian besar, kecuali dalam beberapa kasus, ketika seorang pemain melakukan sesuatu, klien menganggap itu keren dan melanjutkannya sendiri. Jadi ketika Anda mengklik kanan di suatu tempat untuk pindah ke sana, klien pemain itu baru saja mulai memindahkan orangnya di sana, dan kemudian mengirim pesan ke server untuk memberitahukannya.

Jadi pada dasarnya:

  • Pemain 1 mengucapkan mantra untuk membuatnya bergerak 100% lebih cepat selama enam detik
  • Klien lokal Player 1 menambahkan buff itu ke objek Unitnya
  • Klien Player 1 mengirim pesan ke server yang mengatakan "hei saya baru saja membaca mantra ini"
  • Server memastikan dia benar-benar memiliki cukup mana untuk menggunakan mantra itu, dan jika demikian, menambahkan buff itu ke salinan server objek Unit itu
  • Server mengirim pesan ke semua klien lain mengatakan "hei orang ini baru saja membaca mantra ini"
  • Setiap klien lain menerima pesan dan pergi "ah oke, keren," dan menambahkan buff itu ke objek Unit lokal mereka untuk pemain itu

Saya telah membaca sekilas tentang hal-hal untuk melihat bagaimana permainan besar melakukan multipemain, dan ini agak membingungkan bagi seseorang yang baru mulai mencoba-coba hal ini, tetapi sepertinya mesin Sumber mengirimkan paket berisi semua perubahan ke semua yang ada di dunia setiap kutu? Sekali lagi, benar-benar baru dalam hal ini, tetapi bisakah Anda benar-benar mendorong sebanyak itu data sebanyak itu?

Maaf jika ini agak kasar, tetapi pada dasarnya, saya bertanya-tanya mengapa sistem saya yang lebih sederhana bukan cara yang tepat untuk pergi, karena jika itu, game lain akan menggunakannya, kan?

takua108
sumber
6
Satu langkah yang Anda lewatkan adalah server juga mengirim pesan ini ke klien asli (bukan hanya orang lain) untuk mengkonfirmasi atau menolak hasil simulasi, klien yang berasal kemudian terus berjalan atau menyesuaikan diri dengan kenyataan baru. Selain itu, metode ini baik-baik saja dan jawaban lain di bawah ini akan membantu Anda memahami lebih dalam aspek-aspek lainnya.
Patrick Hughes
1
Yang luar biasa adalah bahwa kita semua memiliki harapan yang masuk akal bahwa jaringannya tidak terlalu sulit. Itu bisa dilakukan.
ashes999

Jawaban:

12

Selain jawaban Byte56, ada beberapa hal yang perlu dipertimbangkan:

Bagaimana Anda akan berkomunikasi antara klien tentang pergerakan pemain? Tidak seperti kebanyakan aksi pemain lain, yang cenderung merupakan peristiwa yang terisolasi dan agaknya jarang terjadi, gerakannya terus menerus. Ada batas pada tingkat di mana Anda dapat (dan ingin, dalam hal ini) mengirim dan menerima pembaruan. Prediksi sisi klien yang disebutkan oleh Byte56 biasanya melibatkan pembaruan berkala tentang posisi dan kecepatan klien. Klien kemudian menginterpolasi secara lokal di antara mereka, menggunakan sesuatu seperti Cubic Spline .

Masalah kedua, yang menghubungkan kembali ke yang sebelumnya, adalah bahwa UDP tidak memiliki jaminan pengiriman. Anda tidak dapat memastikan bahwa setiap pesan yang Anda kirim tiba, atau bahkan tiba dalam urutan yang benar. Anda dapat mengirim paket 1, 2, dan 3, dan server menerima 3 kemudian 1 dan bukan 2. Sering kali mereka berada di urutan yang benar, dan sering kali mereka akan tiba, tetapi tidak selalu. Jadi, Anda membutuhkan sistem yang kuat untuk kehilangan paket. Sistem konfirmasi sederhana sudah cukup. Biasanya yang digunakan adalah bitfield yang memberitahu node lain apakah telah menerima 32 pesan terakhir (untuk int 32bit), dan apa pesan terakhir yang diterima. Dengan cara ini, Anda dapat memberi label pada pesan sebagai kritis atau tidak, dan mengirim ulang jika tidak menerima pesan kritis. Ada diskusi yang cukup baik di sini .

Anda juga harus ingat, ketika melakukan ini, bahwa klien Anda akan tidak sinkron dengan satu sama lain. Masing-masing akan menunjukkan pemain lain interpolasi antara dua frame jaringan sebelumnya saat Anda bekerja pada yang berikutnya, dalam skenario kasus terbaik. Jadi, Anda memerlukan sistem yang memperhitungkan (secara adil) bahwa apa yang dilihat oleh seorang pemain ketika ia melakukan suatu tindakan bukanlah keadaan sebenarnya dari permainan saat ia melakukan tindakan itu. Dia bereaksi terhadap kondisi game lama yang tidak sinkron.

Akhirnya, jika game ini dimaksudkan untuk menjadi kompetitif, Anda juga perlu khawatir tentang kecurangan. Dengan demikian, sejauh mungkin (dan masuk akal), Anda harus tidak mempercayai klien dan memverifikasi tindakan mereka itu mungkin. "Tidak, kamu tidak bisa berjalan melewati tembok itu. Tidak, kamu tidak bisa berjalan lebih cepat dari kecepatan larimu. Tidak, kamu tidak bisa mengklaim telah mengenai target itu." dll.

Untuk lebih banyak ide, saya sarankan untuk menelusuri artikel lain di tautan kedua itu.

Semoga berhasil!

Agen TAS
sumber
6

Apa yang Anda gambarkan pada dasarnya adalah prediksi sisi klien , tetapi Anda tidak mengatakan apa yang terjadi ketika server dan klien tidak setuju.

Itu berevolusi dari hari-hari ketika klien hanya terminal bodoh, mengirimkan inputnya ke server, dan server memberi tahu klien hasilnya. Namun, begitu gim bergerak melampaui LAN (dan sering sebelumnya) latensi terlihat dalam situasi ini. Apa yang Anda gambarkan, prediksi sisi klien diperkenalkan untuk memperbaikinya. Sekarang klien juga mensimulasikan gerakan sambil menunggu server merespons. Kemudian mereka mencapai kesepakatan tentang hasilnya. Dengan server menjadi otoritas.

Langkah selanjutnya adalah bagaimana Anda menanggapi ketidaksepakatan. Jika Anda tidak memiliki apa pun untuk itu, Anda akan mendapatkan karet-banding atau teleportasi klien ketika klien dan server tidak setuju.

MichaelHouse
sumber
5

Pengaturan waktu. Jawaban lain tidak menyebutkan waktu kejadian di server dan klien yang berbeda. Tergantung pada gimnya, ini bisa menjadi sesuatu yang harus diwaspadai. Latency (alias Lag) memperkenalkan penundaan variabel antara saat paket dikirim dan saat diterima. Waktu bisa rumit, tetapi saya akan mencoba menjelaskan potensi masalah sebaik mungkin. Ada beberapa game yang bisa bertahan tanpa khawatir tentang hal ini, tetapi inilah contoh sederhana dari mana hal itu dapat menyebabkan masalah.

Anggap semua orang bertindak atas paket begitu mereka tiba.

@ Time 0 (wall time), Player 1 puts up a shield   (Message has been sent, but not received by anyone)
@ Time 1, Player 2 shoots player 1   (Message has been sent, but not received by anyone)

Asumsikan Waktu 0 (T0) dan T1 berdekatan.

Apa yang terjadi selanjutnya tergantung pada siapa yang melihat ini, dan pada urutan paket-paket itu tiba di server. Server harus selalu memiliki keputusan akhir. JIKA server menerima paket dalam urutan yang diberikan di atas, maka server akan menerapkan perisai sebelum tembakan dan pemain 1 (P1) akan bertahan. Dari perspektif P1, setelah memasang perisai sendiri, ia akan melihat perisai sebelum tembakan dan bertahan. Tapi bagaimana dengan P2? Mereka akan melihat tembakan itu segera karena mereka menembaknya, tetapi apakah mereka akan melihat perisai terlebih dahulu? Jika (T0 + latency between P1 and the server + the latency between the server and P2) > T1, perisai akan muncul setelah tembakan, dan P2 akan berpikir tembakan mereka telah membunuh P1. Server harus memperbaiki situasi ini entah bagaimana.

Namun, jika server menerima paket dalam urutan terbalik (yang sangat mungkin, bahkan jika T0 <T1), maka terjadi sebaliknya. P1 salah (dan mati), sedangkan P2 benar (dan menang).

Ada beberapa cara untuk menghadapi situasi seperti ini, tetapi cara termudah adalah membiarkan server melakukan semuanya. Anda dapat mencoba mensimulasikan ini pada klien, tetapi jangan izinkan tindakan permanen apa pun, seperti kematian. Para pemain harus menunggu konfirmasi perubahan permainan penting dari server.

Mengirim stempel waktu dengan tindakan dapat bermanfaat. JIKA sebagian besar Anda mempercayai klien, maka Anda dapat menggunakan cap waktu ini yang dapat digunakan untuk menentukan tindakan mana yang terjadi terlebih dahulu, alih-alih mengikuti asumsi pertama kami. Ini bisa rumit, karena menerima pesan dari masa lalu biasanya berarti Anda harus dapat membalikkan waktu.

Waktu itu menyenangkan ya? Tidak peduli apa yang akhirnya Anda lakukan, akan sangat membantu untuk mengetahui masalah waktu ini.

John McDonald
sumber