Cara menangani komputer yang lebih cepat dalam videogame real-time klien / server

15

Saya membuat game online pertama saya menggunakan socket.io, dan saya ingin ini menjadi game multipemain waktu nyata seperti agar.io atau diep.io.

Tapi saya sudah mengalami masalah mencoba mencari cara untuk mendapatkan semua komputer untuk bekerja pada kecepatan yang sama.

Saya punya tiga ide untuk model, tetapi tidak ada yang tampak benar, dan saya bertanya-tanya bagaimana cara videogame yang normal melakukannya. (Anda dapat melewatkan membaca ide-ide saya; mereka hanya memberi Anda cara untuk melihat masalah yang saya alami.)

  1. Server memungkinkan klien berjalan sendiri dan memberikan pembaruan ke server, yang kemudian menyiarkannya ke seluruh klien. Ini memiliki masalah bahwa beberapa komputer berjalan lebih cepat dari yang lain, membiarkannya memperbarui lebih cepat dan bergerak melintasi layar lebih cepat.

  2. Minta server memberi tahu klien kapan harus memperbarui. Saya kemudian dapat menunggu sampai klien terakhir merespons (ide yang buruk jika satu orang memiliki komputer lambat), menunggu sampai klien pertama merespons (sekali lagi, menunggu komunikasi sebelum setiap frame), atau hanya mengirimnya secepat mungkin (yang tampaknya mengalami masalah yang sama dengan nomor 1).

  3. Di awal permainan, minta server memberi tahu klien seberapa cepat untuk memperbarui. Ini berarti klien akan bertanggung jawab untuk membatasi pergerakan di antara periode waktu itu. Misalnya, jika seseorang entah bagaimana berhasil menekan tombol dua kali dalam periode waktu itu, itu hanya akan mengirim satu acara tekan tombol. Ini memiliki masalah bahwa beberapa tindakan akan diabaikan (seperti menekan tombol ganda), dan bahwa interaksi akan bergantung pada jam klien, yang mungkin tidak cocok dengan jam server. Server kemudian harus melacak setiap klien dan memastikan pembaruan mereka dikirimkan pada waktu yang tepat.

Saya telah melakukan riset , tetapi artikel yang saya baca tampaknya tidak secara khusus membahas apa yang harus dilakukan jika klien mengirim pembaruan lebih cepat daripada klien lain.

Dalam kasus khusus saya, saya berurusan dengan orang-orang yang memiliki kecepatan keyboard lebih cepat (komputer mereka akan mengirim lebih banyak pembaruan keyboard daripada komputer lain).

Bagaimana biasanya programmer menangani hal ini?

Pro Q
sumber
1
Dalam pengalaman saya, mereka tidak. Inilah sebabnya mengapa mesin gamer ada; orang-orang yang membayar 5 ribu untuk pelempar nyala api canggih secara otomatis memiliki keuntungan dari yang masih menggunakan Commodore 64.
Robert Harvey
1
Jadi permainan saya akan terlihat lambat karena kita harus bermain dengan penyebut yang paling umum? Sepertinya server game harus mengatur tempo dan terserah kepada klien untuk mengikutinya atau Anda hanya perlu ketinggalan.
JeffO
3
Saya mungkin salah memahami pertanyaan, tetapi menggunakan klien berbasis centang dan model server mungkin adalah apa yang Anda cari. gamedev.stackexchange.com/questions/81608/... Pada dasarnya Anda hanya memproses input dan logika setiap jumlah waktu X (biasanya 1 / N detik, seperti 1/60 untuk 60Hz logika)
Christopher Wirt
4
Setelah membaca pertanyaan itu sedikit lebih dekat, sepertinya Anda terlalu fokus pada aspek-aspek klien dari permainan. Jika Anda menginginkan gim multipemain yang "adil", server Anda harus berwibawa. Berarti bahwa segala sesuatu yang terjadi pada klien diverifikasi atau dilakukan oleh server. Kemudian Anda membatasi hal-hal dari sini, mungkin melalui sistem berbasis centang seperti di atas.
Christopher Wirt
1
Ah, netcode waktu-nyata. Tempat pengembangan game terdalam dan tergelap. Selamat datang di kapal, sobat!
T. Sar - Reinstate Monica

Jawaban:

8

Ide ketiga Anda tampaknya paling dekat dengan apa yang saya pikirkan sebagai solusi industri untuk masalah seperti ini.

Apa yang Anda gambarkan biasanya disebut sebagai Kutu . Dalam setiap centang, sejumlah tindakan tetap akan diproses untuk setiap klien secara serial. Seringkali, server game akan memiliki beberapa aksi paralel saat mampu, tetapi ini adalah masalah yang jauh lebih rumit.

Kutu kemungkinan akan berbentuk 1 / N detik, N menjadi jumlah kutu per detik, atau Tickrate. Kursor ini bisa sangat sering atau sangat jarang, tergantung pada kasus penggunaan Anda. Saran pribadi saya adalah untuk menghindari tickrate di atas 60 ticks / detik kecuali Anda yakin Anda membutuhkan lebih banyak. Anda mungkin tidak :)

Tindakan harus berupa atom. Misalnya, di slither.io, tindakan seperti bergerak tidak harus segera memproses sesuatu seperti mematahkan rantai Anda, kecuali jika pemain yang Anda tekan telah melakukan gerakannya. Ini mungkin terlihat sepele untuk sesuatu pada tingkat piksel, tetapi jika Anda berurusan dengan gerakan berbasis ubin, itu menjadi jauh lebih jelas, dan memastikan keadilan. Jika Pemain A pindah ke ubin X, Y dan Pemain B saat ini di ubin itu, Anda harus memastikan bahwa pada akhir centang, pemain B masih akan berada di ubin itu untuk tindakan apa pun yang terjadi di antara mereka.

Lebih lanjut, saya akan mengatakan hindari melakukan perhitungan Anda di sisi klien kecuali jika dilakukan secara independen di sisi server. Ini menjadi rumit dan mahal dengan fisika (banyak game memilih tingkat centang yang lebih rendah untuk fisika daripada banyak tindakan dan peristiwa lainnya karena ini)

Untuk referensi, berikut adalah tautan yang bagus untuk melengkapi pemahaman Anda sendiri tentang server game dan jaringan multipemain.

Terakhir, saya katakan jangan biarkan keadilan merusak server Anda. Jika ada eksploit yang menyebabkan game Anda menjadi tidak adil, perbaiki itu. Jika itu masalah komputer yang lebih baik memiliki sedikit keuntungan, saya akan mengatakan itu mungkin bukan masalah besar.

Christopher Wirt
sumber
3
@ ProQ perlu dicatat bahwa menulis netcode yang baik bukanlah hal sepele! Jika aplikasi Anda tidak berfungsi dengan baik sejak awal dan netcode Anda tampaknya payah, jangan menyerah. Bahkan orang-orang yang melakukan itu untuk kehidupan sehari-hari memiliki masalah dengannya. itu hanya bahwa sulit!
T. Sar - Kembalikan Monica
0

Sistem berikut memastikan semua klien dan server berbagi kondisi permainan yang hampir sama setiap saat.

Memiliki status permainan pada klien dan server.

Saat klien mencoba menggunakan perintah (mouse, keyboard, dll. Input lainnya), lihat status permainannya jika valid.

Jika ya, kirim perintah ke server, tanpa menjalankannya pada klien pengirim.

Saat server menerima perintah, lihat status permainannya jika valid.

Jika ya, kirim kembali perintah ke SEMUA klien dengan tanggal yang akan datang setelah apa yang seharusnya selesai dieksekusi di server, kemudian jalankan tindakan yang diminta oleh perintah setelah penundaan sama dengan waktu minimum untuk mengirim perintah ke klien . lalu catat tanggalnya, ini membantu membuat prediksi di masa depan. Jika waktunya terlalu banyak bervariasi, jadikan sistem game Anda lebih deterministik waktu.

Ketika klien menerima perintah dari server, lihat status permainannya jika valid segera jalankan tindakan yang diminta oleh perintah, kemudian lihat tanggal saat ini dan bandingkan dengan tanggal prediksi yang diterima. Jika tidak valid, klien tidak sinkron. (Semua klien dengan koneksi yang sama menerima pada saat yang sama)

Jika tanggalnya sebelumnya, Anda punya masalah di langkah sebelumnya, perbaiki itu. Jika tanggal sedikit setelah tidak melakukan apa-apa, Jika tanggal lama setelah itu, klien tidak sinkron, yaitu klien tertinggal terlalu banyak.

Saat klien tidak sinkron, minta salinan seluruh kondisi permainan server, dan gunakan yang itu. Jika itu terjadi terlalu sering, perbaiki itu karena lebih mahal daripada mengirim perintah.

Di klien, render barang di layar SAJA ketika tidak ada lagi yang bisa dilakukan. Dalam skenario sederhana fungsi render hanya mengambil status gim saat ini sebagai input.

Selain itu Anda dapat mengoptimalkan banyak, dengan menggunakan sistem prediksi, pengelompokan perintah, render hanya berbeda dll ...

Validasi harus berbeda, misalnya, tergantung pada server untuk membatasi permintaan perintah / unit waktu.

Walle Cyril
sumber
0

Saya tidak tahu apakah ini masalah perpustakaan atau lingkungan yang Anda gunakan, tapi saya pikir Anda salah mendekati.

Di sebagian besar gim multipemain, hanya server yang melakukan perhitungan nyata. Klien hanya mesin IO yang bodoh di mana satu-satunya masalah kinerja nyata adalah menggambar grafik 3D. Dan jika hal itu tidak masalah jika klien dapat berjalan pada 20 atau 200 FPS, karena itu hanya mempengaruhi visual. Itu berarti "pembaruan klien" sama sekali tidak ada artinya. Klien mungkin mencoba untuk "memprediksi" apa yang mungkin dihitung oleh server, tetapi itu hanya untuk memperlancar perasaan gameplay dan tidak memiliki dampak aktual pada gameplay itu sendiri.

kecepatan keyboard lebih cepat

Saya bahkan tidak tahu apa artinya itu. Kebanyakan orang bahkan tidak bisa mengikuti kecepatan keyboard low-end, jadi bagaimana itu akan mempengaruhi kinerja pemain?

Kalau tidak, pertanyaannya tampaknya terlalu luas dan Anda harus fokus pada satu masalah aktual, alih-alih mencoba membuat masalah "umum" yang bahkan mungkin tidak Anda miliki.

Euforia
sumber
kecepatan keyboard yang lebih cepat bukan tentang mengetik, ini tentang berapa banyak perintah yang dapat dikirim jika Anda menahan tombol "maju" atau tombol "tembak".
gbjbaanb
@ gbjbaanb Dan bagaimana itu menjadi masalah? Anda seharusnya hanya peduli dengan perintah yang ditekan dan dirilis. Anda seharusnya tidak peduli seberapa cepat pembaruan itu.
Euforia
Anda peduli jika Anda menangani semua acara seperti yang diharapkan OP - pada klien Jadi jika menekan w membuat Anda maju sedikit, dan keyboard Anda lebih cepat daripada orang lain, Anda akan lebih cepat daripada mereka. Hal terakhir yang Anda inginkan adalah membuat game balapan Anda harus terus menekan tombol untuk bergerak maju!
gbjbaanb
@ gbjbaanb Tidak. Itu salah. Server tahu "pemain akan maju" dan kemudian setiap 1/60 dari yang kedua memperbarui posisi SEMUA pemain berdasarkan jika mereka maju. Beginilah cara SEMUA permainan bekerja. Loop pembaruan sama untuk semua entitas dalam game dan pembaruan TIDAK didasarkan pada acara dari UI.
Euforia
1
Tidak, bukan itu pengertian OP itu, itulah sebabnya dia menanyakannya, dan itulah mengapa Anda berkata "Aku bahkan tidak tahu apa artinya itu". Jika Anda memahami posisi OP, maka pertanyaannya masuk akal. Jika OP telah mengkodekan game-nya untuk bekerja dengan loop game berdasarkan sepenuhnya pada seberapa cepat peristiwa dikirim dari klien maka itulah yang ia tanyakan - Anda salah menerapkan beberapa desain game hipotetis untuk apa yang sebenarnya ditanyakan OP, terlepas dari apakah desainnya salah oleh sebagian besar standar.
gbjbaanb