Bagaimana saya bisa menetapkan ID entitas dengan cara yang kuat dalam permainan jaringan?


17

Saya sedang bekerja pada sistem entitas untuk game jaringan dan saya menugaskan setiap entitas id integer 32-bit unik yang bisa saya gunakan untuk membuat cerita bersambung referensi ke entitas dan entitas itu sendiri.

Saat ini saya hanya menambah penghitung setiap kali entitas dibuat. Saya kira id pada akhirnya akan habis tetapi saya tidak benar-benar berharap untuk memiliki 4 miliar entitas. Ini juga menghindari masalah jika entitas # 5 dihancurkan dan kita mendapatkan id 5. Apakah ini dimaksudkan untuk merujuk ke yang baru # 5 atau yang lama dihapus # 5?

Masalahnya adalah saya tidak yakin bagaimana menangani / menghindari tabrakan. Saat ini jika klien menerima pembaruan untuk entitas dengan id lebih tinggi daripada "id bebas" saat ini, ia hanya menabraknya id gratis hingga melewati itu. Tapi itu tampaknya tidak terlalu kuat.

Saya berpikir tentang mungkin menetapkan rentang untuk setiap klien sehingga mereka dapat mengalokasikan entitas tanpa konflik (katakanlah n bit atas adalah nomor pemain) tetapi saya khawatir tentang apa yang terjadi jika rentang mulai tumpang tindih dari waktu ke waktu.

Apakah ada cara yang lebih baik untuk menangani ini? Haruskah saya peduli dengan id yang meluap atau melewati batas kisaran yang diizinkan? Saya bisa menambahkan kode untuk mendeteksi kasus-kasus ini tetapi apa yang akan dilakukan jika terjadi selain crash.

Pilihan lain adalah menggunakan sesuatu dengan peluang lebih tinggi untuk menjadi unik seperti GUID 128-bit tetapi tampaknya sangat berat untuk gim yang mencoba meminimalkan lalu lintas jaringan. Juga, secara realistis saya tidak akan pernah membutuhkan lebih banyak entitas pada satu waktu kemudian akan masuk ke dalam integer 32-bit atau bahkan 24 bit.

Terima kasih!


1
Mengapa tidak semua klien memiliki entitas yang sama? Apakah klien tidak disinkronkan? Atau apakah ini semacam dunia besar di mana klien tidak semua menjalankan permainan yang sama.
Philip

2
Arsitektur saya sejauh ini agak longgar mengikuti UE3 (info lebih lanjut di sini ). Pada dasarnya klien hanya tahu tentang entitas yang dekat dengan mereka di dunia. Selain itu, klien tidak berjalan dalam langkah-kunci tetapi server mengontrol sebagian besar logika dan dapat menimpa data klien kapan saja. Saya kira sekarang saya berpikir tentang hal itu saya hanya bisa mengizinkan server untuk membuat entitas dan membuat klien menggunakan RPC untuk melakukan ini. Saya tidak yakin dengan pendekatan terbaik. Saya seorang programmer grafis di siang hari :)
Lucas

1
Saya pikir, seperti yang Anda katakan, itu harus ditangani hanya oleh server jika itu layak dalam arsitektur yang Anda berikan. Kemudian simpan setumpuk ID entitas bebas yang ada terpisah dari daftar entitas / peta, sehingga Anda tahu ID apa yang tersedia. Gagal model server otoritatif, maka pendekatan rentang Anda akan bekerja dengan baik, dalam hal rentang. Empat miliar sangat banyak, bahkan untuk membagi di antara 4000 pemain dalam MMO. Kemudian gunakan pendekatan yang sama untuk melacak ID yang tersedia seperti dengan auth. server.
Insinyur

@Lucas, tautan Anda mengatakan "Server mengidentifikasi sekumpulan Aktor" relevan "untuk setiap klien". Ini berarti server mengetahui tentang semua entitas, dan berada dalam posisi untuk menyebutkannya.
Kylotan

1
Tentu, tetapi bagaimana jika klien membuat entitas baru A tetapi sebelum bisa mendapatkan pesan pembuatan, server membuat entitas baru B, keduanya mendapatkan id "bebas" yang sama.
Lucas

Jawaban:


13

Apa yang saya lakukan adalah membuat server melakukan semuanya . Klien hanya dapat meminta server untuk melakukan sesuatu tetapi tidak dapat melakukan apa pun sendiri. Dalam hal ini, server akan selalu menjadi yang menetapkan ID dan masalah terpecahkan.

Saya belum berurusan dengan prediksi sisi klien sambil menunggu server menyetujui tindakan seperti: "Tembak roket" atau "Buat stasiun tenaga surya di sini". Tindakan ini akan ingin membuat entitas, dan entitas memiliki ID. Sejauh ini, saya hanya duduk di ibu jari saya menunggu server, tapi saya percaya apa yang perlu dilakukan adalah membuat entitas sementara saat Anda menunggu persetujuan server. Ketika Anda menerima persetujuan server, server akan menetapkan ID dan Anda dapat memperbarui atau menimpa objek sementara.

Saya juga belum berurusan dengan ID overflow, tetapi jika server berada dalam kendali penuh dan mendeteksi overflow, ia dapat melakukan penanganan apa pun yang Anda anggap perlu (restart pada 0, pilih dari stack gratis, crash, dll) dan semua klien bahkan tidak akan tahu atau peduli. Klien hanya akan menerima ID yang diberikan oleh server.


Terima kasih untuk semua info bagus kalian! Saya akhirnya pergi dengan server membuat semua pendekatan entitas, tetapi jika saya menemukan bahwa memperkenalkan terlalu banyak latensi saya akan mencoba metode Trevor.
Lucas

Untuk id khusus klien (diperlukan untuk prediksi sambil menunggu server), Anda bisa menggunakan awalan pada id.
danijar

6

Ketika saya melakukan ini untuk permainan multipemain komersial, saya melakukan persis apa yang Anda usulkan: gunakan bilangan bulat GUID 32-bit, di mana delapan bit teratas adalah nomor pemain, dan bagian bawah dua puluh empat bit berisi angka unik lokal.

Jika / ketika nomor lokal meluap (dalam kasus saya, itu hampir tidak akan pernah terjadi; dalam penggunaan normal, itu akan memakan waktu empat hingga lima hari bermain terus menerus dalam satu sesi jaringan untuk menyebabkan hal itu terjadi), pemilik akan mengirim Pesan "Reset semua objek saya", dan beri nomor baru semua objek yang masih ada mulai dari nol yang lalu. Pesan itu memberi tahu semua teman untuk membuang objek yang telah mereka terima dan meminta mereka lagi.

Pendekatan yang lebih mewah adalah pesan "Object with GUID 'n' sekarang Object with GUID 'm'" untuk setiap objek yang ada. Tetapi dalam kasus saya, itu tidak mungkin benar-benar terjadi, dan saya tidak berpikir orang akan benar-benar keberatan benda jauh menghilang dari dunia selama setengah detik, setelah lima hari bermain tanpa henti dalam satu sesi jaringan tunggal. ;)


Itu ide yang bagus untuk menangani overflow. Sederhana, tetapi saya tidak memikirkannya :). "Lupa" semua entitas Anda baik karena pada dasarnya dapat menggunakan kembali codepath yang sama dengan yang digunakan klien saat bergabung dengan permainan
Lucas

4

Jika klien Anda dapat menelurkan entitas mereka sendiri, saya kira Anda memiliki game multipemain peer-to-peer.

Jika itu masalahnya, Anda mungkin tidak memiliki terlalu banyak klien. Tentu saja tidak lebih dari 256. Dan id entitas Anda dijamin masuk ke dalam 24 bit (16000000+ entitas cukup untuk semua orang!). Jadi, buat saja byte tertinggi id Anda sama dengan id klien:

entityId = clientId<<24 + (maxEntityIn++)

atau sesuatu.

Dan jika saya salah dan Anda memiliki server yang berwenang, adil tidak pernah membuat entitas baru pada klien.


1

Saya menggunakan metode 'paling naif' (hanya menambah bilangan bulat untuk setiap ID baru) dalam permainan multipemain persisten saya dan itu berfungsi dengan baik karena saya tidak membiarkan klien membuat ID baru: s.

Jika Anda membiarkan klien memutuskan (dengan menggunakan semacam teknik GUID yang dijelaskan), klien juga dapat memperkenalkan berbagai bug dengan menetapkan ID Lama ke item baru (itulah yang saya pikirkan di atas kepala saya sambil berpikir 5 detik) , mungkin ada banyak celah lain).

Seperti biasa, untuk mencegah kecurangan , server harus melakukan SEMUA pembuatan dan validasi .

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.