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!
sumber
Jawaban:
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.
sumber
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. ;)
sumber
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:
atau sesuatu.
Dan jika saya salah dan Anda memiliki server yang berwenang, adil tidak pernah membuat entitas baru pada klien.
sumber
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 .
sumber