Menyinkronkan klien dengan server dan satu sama lain

9

Apa cara terbaik untuk menjaga semua klien disinkronkan dengan server dan satu sama lain?

Saat ini, kami memiliki dua pendekatan dalam pikiran:

  1. Ketika klien mengirim sesuatu ke server, server segera mengirimkan pesan ke semua klien, yang langsung bereaksi.
  2. Memperkenalkan beberapa waktu tunda, di mana server mengirimkan pesan ke semua klien, dengan arahan, "bertindak berdasarkan hal ini pada waktunya t.

Pendekatan kedua sepertinya akan lebih memungkinkan klien dalam sinkronisasi yang lebih baik (karena melayani beberapa tingkat kelambatan); tapi saya bertanya-tanya apakah daya tanggap akan hilang ke tingkat yang terlalu tinggi (yaitu pengguna mengklik 'lompatan' dan ada kesenjangan yang nyata antara menekan tombol dan benar-benar melompat).

Ada juga kemungkinan memiliki klien menghitung posisi mereka sendiri (dan tidak menunggu server mengatakan "Anda telah melompat"); tetapi karena jeda yang tak terhindarkan, klien akan menjadi sangat tidak sinkron.

Lalu ada seluruh pertanyaan TCP vs UDP; karena kami ingin cepat, tetapi saya juga benci server mengatakan Anda berada di lokasi yang sama sekali berbeda dari yang Anda kira.

Dengan semua tuntutan yang saling bersaing ini, semuanya menjadi sangat tidak pasti bagaimana kita harus mendekati masalah ini. Manakah dari pendekatan ini (atau yang lainnya) yang terbaik untuk menjaga agar klien dan server tetap sinkron? Yang mana yang benar-benar digunakan dalam industri?

Menghancurkan
sumber

Jawaban:

7

Jawaban cepatnya adalah: tidak ada pendekatan terbaik.

Game semua berisi arsitektur yang berbeda; setiap game akan memilih set data yang berbeda untuk dikirim untuk menyinkronkan dirinya dengan mesin lain, yang akan memengaruhi pilihan yang dapat Anda buat saat memilih cara menangani lag.

Apa yang Anda tentukan dalam opsi # 2 - bahwa klien mengirim pesan untuk ditindaklanjuti di masa depan - jelas merupakan satu pendekatan. Bahkan, mesin Sumber menggunakan varian dari pendekatan ini , di mana rendering selalu 100 ms di belakang tindakan klien lokal; semua mesin berusaha untuk beroperasi pada tindakan yang sama pada saat yang bersamaan. Ini menambahkan lag buatan yang tidak terlihat ke dalam permainan untuk menyembunyikan latensi jaringan yang sebenarnya.

Jika Anda tidak dapat mengambil pendekatan ini, Anda juga dapat memilih opsi # 1, cukup mengirim data terbaru dan setelah diterima, gunakan interpolasi dan ekstrapolasi (prediksi sisi klien) untuk mencoba menyembunyikan latensi. Saya telah menggunakan pendekatan ini dalam setidaknya satu permainan pengiriman - tetapi sekali lagi, semuanya tergantung pada permainan Anda ; mungkin ada pendekatan lain yang bisa Anda ambil.

Akhirnya, ketika memilih antara TCP dan UDP - Anda mungkin menginginkan UDP. Ada beberapa skenario di mana TCP adalah opsi yang memungkinkan untuk membuat jaringan game Anda, tetapi ketika Anda membuat game aksi, Anda menginginkan data terbaru sesegera mungkin. Jika Anda dapat menangani sendiri paket yang dijatuhkan, UDP adalah pilihan yang lebih baik. (Ada perpustakaan, seperti ENet , yang menyediakan pembungkus di sekitar UDP untuk menggantikan fungsi dari TCP, seperti paket yang dapat diandalkan.)

Blair Holloway
sumber
Anda benar-benar tidak ingin menggunakan UDP. Overhead koneksi TCP yang dikonfigurasi dengan benar adalah minimal dan pengiriman yang tidak sesuai pesanan adalah sesuatu yang tidak seorang pun harus menjalani.
coderanger
2
Ini bukan masalah overhead, meskipun TCP menambahkan beberapa - cara TCP menangani paket yang dijatuhkan pada dasarnya tidak baik dalam permainan di mana latensi yang besar antara aksi dan reaksi dapat membuat perbedaan besar dalam kemampuan bermain. Untuk gim seperti WoW, di mana tindakan relatif jarang terjadi, TCP berfungsi, tetapi akan jatuh datar di gim seperti CounterStrike, karena satu paket yang dijatuhkan akan mencekik koneksi Anda dan berpotensi membuat Anda "ketinggalan" selama sedetik atau lebih.
Blair Holloway
Jika Anda akan menggunakan UDP, yang terbaik adalah tidak menulisnya sendiri; gunakan pembungkus seperti ENet yang melakukan kerja keras untuk Anda. Tetapi jawaban asli saya tetap berlaku - UDP adalah cara terbaik untuk pergi jika Anda membuat game dengan segala jenis tindakan cepat.
Blair Holloway
Bagi saya, RakNet membuat menjalankan koneksi UDP untuk mesin gim saya sangat mudah. Ini memiliki banyak pilihan untuk bagaimana Anda ingin mengirim paket Anda yaitu. cara memesannya, apakah paket harus dikirim ulang jika dijatuhkan dll.
BarakatX2
3

Berikut adalah beberapa tautan bagus yang mencakup banyak sekali jaringan game.

Dan ini adalah bagian pertama dari lebih banyak seri jejaring. http://gafferongames.com/networking-for-game-programmers/udp-vs-tcp/

Untuk sejarah. 'Kami minta maaf, tetapi sebagai mekanisme pencegahan spam, pengguna baru hanya dapat memposting maksimum satu hyperlink. Hasilkan 10 reputasi untuk mengirim lebih banyak hyperlink. ' Lihat saja situs webnya.

jsimmons
sumber
1

Karena Anda menyebutkan Klien dan Server, saya akan berasumsi bahwa Anda berbicara tentang arsitektur Client / Server di mana Server adalah otoritas pada keadaan semua objek.

Catatan: Alternatifnya adalah arsitektur Peer-To-Peer di mana pemilik objek adalah otoritas untuk objek itu.

Sudah ada metode yang telah terbukti dengan baik untuk menyinkronkan objek bergerak menggunakan arsitektur Client-Server. Itu disebut Dead Reckoning. .

Cara yang baik untuk mengimplementasikan ini dalam game adalah seperti ini:

  1. Klien mengirim input ke server.
  2. Server memperbarui objek game (akselerasi & arah) dan mengirimkannya kembali ke Klien.
  3. Klien menggunakan nilai-nilai yang diperbarui untuk mensimulasikan pergerakan objek secara lokal.
  4. Kadang-kadang, server mengirim koreksi posisi untuk menghindari penyimpangan.
  5. Bilasan; ulang.
JanSolo
sumber