Bagaimana cara mengkompensasi objek bergerak dengan prediksi sisi klien?

11

Saya menerapkan server game yang mendukung huru-hara seperti Star Control . Jadi, Anda memiliki kapal yang terbang dan menembak, dengan kecepatan / akselerasi / peredam fisika super sederhana untuk mendorong gerakan.

masukkan deskripsi gambar di sini

Saya telah membaca Valve, Gafferon dan Gambetta dan menerapkan algoritma Gambetta untuk prediksi klien:

masukkan deskripsi gambar di sini

Prediksi klien berfungsi pada kapal pemain dengan memperbarui posisinya dari server saat datang dan kemudian menerapkan kembali input yang belum diproses oleh server ke kapal pemain.

Sayangnya, itu tidak berfungsi dengan baik untuk permainan saya. Saya percaya itu ada hubungannya dengan fakta bahwa contoh Gambetta tidak memperhitungkan objek akun yang sudah bergerak, atau perintah yang diperbarui pada langkah demi langkah. (Dengan "langkah" Maksudku bingkai). Jadi dalam permainan saya, pemain menekan untuk mempercepat kapal (yang sudah bergerak), yang terus bergerak pada klien, mengirimkan perintah ke server dan biasanya menerima snapshot dunia dari server pada langkah berikutnya. Saya mendapatkan sesuatu yang lebih seperti:

masukkan deskripsi gambar di sini

Perintah pemain berjalan di klien langkah 3 , tetapi di server hanya berjalan di server langkah 5 . Pada saat snapshot dunia diterima oleh klien pada langkah klien 6 , prediksi tersebut hilang, terutama dalam kecepatan yang lebih cepat.

Inti masalahnya adalah bahwa klien menjalankan perintah pada langkah 5 , tetapi server menjalankannya pada langkah 6 . Saya berpikir tentang mungkin mengirim langkah klien dengan perintah, dan meminta server memutar kembali dan menjalankan kembali perintah dengan langkah waktu klien. Itu mungkin mengarah pada banyak masalah lain - seperti apa yang terjadi pada perintah yang diterima sejak rollback, atau bagaimana menipu klien dapat mengeksploitasi dengan mengubah langkah yang dikirim.

Membaca dan menonton video seperti ini dari Google menyebutkan pendekatan yang berbeda, di mana Anda secara bertahap mengubah posisi pemain agar sesuai dengan snapshot dalam beberapa langkah.

Pertanyaan saya:

  • Bisakah Anda membuat algoritma Gambetta bekerja dengan gerakan langkah konstan? Atau apakah secara konseptual tidak kompatibel dengan game saya?

  • Apakah interpolasi bertahap atas langkah-langkah cara yang benar untuk pergi kemudian? Jika demikian, bagaimana Anda menginterpolasi objek yang sudah bergerak dari posisi klien agar sesuai dengan yang baru saja diterima dari server?

  • Dapatkah metode ini, interpolasi bertahap dan algoritma Gambetta bekerja bersama-sama, atau mereka saling eksklusif?

OpherV
sumber
Saya sudah melakukan hal yang sama dan mengalami masalah yang sama persis. Segera setelah saya menambahkan kecepatan menerapkan status server dan menerapkan kembali input menyingkirkan perubahan kecepatan yang sudah ditangani. Saya sudah mencoba menerapkan kembali semua pembaruan sejak pesan terakhir diterima tetapi belum terlalu lancar. Pernahkah Anda menemukan solusi untuk ini?
MakuraYami
@ MasuraYami Ya - Saya sudah mulai menulis artikel yang menjelaskan solusinya. Akan segera diperbarui!
OpherV
Saya telah bekerja lebih banyak pada proyek saya dan menemukan solusi yang dapat digunakan dan beberapa sumber daya yang lebih baik membicarakan masalah ini. Saya tertarik untuk membahas lebih lanjut, membandingkan solusi, dll. Biarkan saya tahu di mana saya dapat menghubungi Anda :)
MakuraYami
@makurayami nama pengguna saya di Gmail
OpherV

Jawaban:

5

Selama 6 bulan sejak saya mengajukan pertanyaan ini, saya akhirnya mengembangkan server game sumber terbuka lengkap untuk menangani masalah yang sebenarnya ini (dan banyak lainnya!): Http://lance.gg

masukkan deskripsi gambar di sini

R&D yang terlibat sekarang memungkinkan saya untuk menjawab pertanyaan saya sendiri:

  • Bisakah Anda membuat algoritma Gambetta bekerja dengan gerakan langkah konstan? Atau apakah secara konseptual tidak kompatibel dengan game saya?

    Algoritma Gambetta tidak akan bekerja ketika pergerakan entitas tidak deterministik (dari POV klien). Jika suatu entitas dapat dipengaruhi tanpa input oleh fisika atau pemain lain, misalnya pendekatan yang lebih sulit perlu diambil.

  • Apakah interpolasi bertahap atas langkah-langkah cara yang benar untuk pergi kemudian? Jika demikian, bagaimana Anda menginterpolasi objek yang sudah bergerak dari posisi klien agar sesuai dengan yang baru saja diterima dari server?

    Ini menyentuh pada topik yang berbeda, yaitu rekonsiliasi klien dari pembaruan server. Interpolasi bertahap berfungsi, tetapi untuk game yang sangat cepat seperti yang ada di pertanyaan, lebih baik menerapkan ekstrapolasi

  • Dapatkah metode ini, interpolasi bertahap dan algoritma Gambetta bekerja bersama-sama, atau mereka saling eksklusif?

    Mereka dapat bekerja bersama, tetapi hanya jika pergerakan entitas bersifat deterministik dari POV klien. Jadi itu tidak akan berfungsi jika entitas dipengaruhi oleh fisika atau psuedo-physics seperti penyisipan, seret dll.

OpherV
sumber
1

Game Anda sepertinya terlalu "real-time" untuk berpikir dalam hal langkah waktu. Saya hanya akan berpikir dalam hal "belokan" jika permainan dapat dianggap "berbasis giliran". Kalau tidak, tinggalkan saja ide belokan atau langkah. Semuanya jadi lebih mudah :)

Perhatikan bahwa Anda memprediksi secara lokal untuk pemain Anda, dan hanya menyisipkan untuk entitas lain (seperti yang dijelaskan dalam artikel ke-3 dalam seri). Cara untuk menangani pembaruan server untuk objek yang sudah bergerak adalah rekonsiliasi sisi-server, dijelaskan di bagian bawah artikel ke-2 (yang Anda tautkan ke arah).

Semoga ini membantu :)

ggambett
sumber
Hanya untuk memperjelas - dengan "langkah" Maksudku "bingkai", yang berjalan 60 kali per detik. Saya menyebutnya langkah (dan bukan bingkai) untuk membedakan progres game aktual dari rendering, dan idealnya keduanya disinkronkan pada 60 per detik. Saya sudah menerapkan versi rekonsiliasi sisi server Anda yang bekerja dengan sangat baik. Pertanyaan ini hanya mengacu pada kapal pemain - yang terus bergerak terlepas dari perintah pemain (karena inersi). Di situlah letak kesulitan saya. Adakah pemikiran tentang itu? :)
OpherV
Frame berbeda dari langkah. Langkah-langkah bergerak dalam urutan yang konstan dan dapat diprediksi. Frame memindahkan jumlah waktu variabel, sehingga setiap perkembangan harus dikalikan dengan waktu delta untuk frame itu.
Tealr
@Tealr memang, itulah sebabnya saya menggunakan istilah "langkah" untuk memulainya - Saya hanya ingin membuatnya lebih jelas bahwa penggunaan "langkah" tidak terbatas pada permainan berbasis giliran, dan dalam permainan saya langkah mengambil tepat 1 / 60 detik tanpa memandang rendering.
OpherV
Hanya sesuatu yang saya perhatikan untuk percobaan saya sendiri: 1/60-an. sangat cepat dan saya akan bertaruh bahwa sebagian besar game online dengan partisipasi lebih dari 1x1 bekerja pada 1/10. pembaruan atau tentang itu.
Patrick Hughes