Bir ağ oyununda varlık kimliklerini nasıl sağlam bir şekilde atayabilirim?


17

Ağa bağlı bir oyun için bir varlık sistemi üzerinde çalışıyorum ve ben her varlık varlık ve varlıkların kendilerine referans serileştirmek için kullanabileceğiniz benzersiz bir 32 bit tamsayı kimliği atarım.

Şu anda bir varlık her oluşturulduğunda bir sayacı artırıyorum. Tahminimce kimlikler bitecek ama gerçekten 4 milyar varlık olmasını beklemiyorum. Ayrıca, # 5 varlığı yok edilirse ve 5 kimliği alırsak bu da sorunu önler. Yeni # 5'e veya eski 5 numaralı silindiğine mi işaret etmek gerekiyor?

Sorun şu ki, çarpışmaların nasıl ele alınacağından / kaçınacağından emin değilim. Şu anda bir müşteri mevcut "serbest kimlik" değerinden daha yüksek bir kimliği olan bir varlık için bir güncelleme alırsa, ücretsiz kimliği o zamana kadar çarpar. Ancak bu pek sağlam görünmüyor.

Her müşteriye aralık atamalarını düşündüm, böylece çakışmadan varlıkları tahsis edebilirler (en iyi n bitin oyuncu numarası olduğunu söyleyebilirim), ancak aralıklar zamanla çakışmaya başlarsa ne olacağı konusunda endişeliyim.

Bunu ele almanın daha iyi bir yolu var mı? Taşan veya izin verilen aralığın sonunu aşan kimlikleri bile önemsemeli miyim? Bu durumları tespit etmek için kod ekleyebilirim ama kilitlenme dışında olsaydı ne yapardı.

Başka bir seçenek, 128 bitlik bir GUID gibi benzersiz olma şansı daha yüksek olan bir şey kullanmaktır, ancak ağ trafiğini en aza indirmeye çalışan bir oyun için gerçekten ağır görünüyor. Ayrıca, gerçekçi olarak, bir seferde asla daha fazla objeye ihtiyacım olmazdı, o zaman 32 bit veya 24 bit tam sayıya sığardı.

Teşekkürler!


1
Neden tüm müşteriler aynı varlıklara sahip değil? İstemciler senkronize edilmiyor mu? Yoksa istemcilerin aynı oyunu çalıştırmadığı büyük bir dünya mı?
Philip

2
Benim mimarim şu ana kadar UE3'ü biraz daha rahat takip ediyor (daha fazla bilgi burada ). Temel olarak müşteriler sadece dünyadaki yakınları bilirler. Ayrıca, istemciler kilit adımında çalışmaz, ancak sunucu mantığın çoğunu kontrol eder ve istediği zaman istemci verilerinin üzerine yazabilir. Sanırım şimdi düşünüyorum sadece sunucu varlıkları oluşturmak ve istemciler bunu yapmak için RPC kullanmak yapmak izin verebilir. En iyi yaklaşımdan emin değilim. Gündüz grafik programcısıyım :)
Lucas

1
Söylediğin gibi, verilen mimarinin içinde mümkün olduğunda sadece sunucu tarafından ele alınması gerektiğini düşünüyorum. Ardından, varlık listesinden / haritadan ayrı olarak mevcut olan ücretsiz varlık kimlikleri yığınını saklayın; böylece hangi kimliklerin kullanılabilir olduğunu bilirsiniz. Yetkili bir sunucu modelinin başarısız olması durumunda, menzilli yaklaşımınızın menziller açısından iyi çalışması gerekir. Bir MMO'daki 4000 oyuncu arasında bölünmek için bile dört milyar çok fazla. Ardından, bir kimlik doğrulamasında olduğu gibi kullanılabilir kimliklerin kaydını tutmak için aynı yaklaşımı kullanın. sunucusu.
Mühendis

@Lucas, bağlantınız "Sunucu her istemci için" ilgili "Aktörler kümesini tanımlar. Bu, sunucunun tüm varlıkları bildiğini ve bunları numaralandıracağı anlamına gelir.
Kylotan

1
Elbette, ancak bir istemci yeni varlık A oluşturur, ancak oluşturma iletisini almadan önce sunucu yeni varlık B'yi oluşturursa, her ikisine de aynı "ücretsiz" kimliği atanır.
Lucas

Yanıtlar:


13

Yaptığım şey sunucuyu her şeyi yapmak . İstemciler yalnızca sunucudan bir şey yapmasını isteyebilir, ancak hiçbir şey yapamaz. Bu durumda, sunucu her zaman kimlik atayan ve sorun çözülen sunucu olacaktır.

Sunucunun "" Bir roket vur "veya" Burada bir güneş istasyonu yap "gibi eylemleri onaylamasını beklerken istemci tarafı tahmini ile ilgilenmedim. Bu eylemler varlık oluşturmak isteyecek ve varlıkların kimlikleri var. Şimdiye kadar, sadece sunucumu bekleyen baş parmağımın üzerinde oturuyorum, ancak sunucu onayı beklerken yapılması gereken geçici bir varlık oluşturmak olduğuna inanıyorum. Sunucu onayı aldığınızda, sunucu bir kimlik atayacaktır ve geçici nesneyi güncelleyebilir veya üzerine yazabilirsiniz.

Ayrıca bir kimlik taşması ile uğraşmadım, ancak sunucu tam kontrol altındaysa ve bir taşma algılarsa, gerekli gördüğünüz her türlü işlemi yapabilir (0'da yeniden başlat, ücretsiz bir yığın, çökme vb. müşteriler bile bilmeyecek ya da umursamayacak. İstemciler sadece sunucu tarafından verilen kimlikleri kabul eder.


Tüm iyi bilgi için teşekkürler çocuklar! Ben sunucu ile tüm varlıklar yaklaşım oluşturur gidiş sona erdi, ama bu çok fazla gecikme getiriyor bulursanız Trevor'ın yöntemini çalışacağız.
Lucas

İstemciye özgü kimlikler için (sunucuyu beklerken tahmin için gereklidir) kimlikte bir önek kullanabilirsiniz.
danijar

6

Bunu ticari bir çok oyunculu oyun için yaptığımda, tam olarak önerdiğiniz şeyi yaptım: ilk sekiz bitin oyuncu numarası olduğu ve alt yirmi dört bitin yerel olarak benzersiz bir sayı içerdiği 32 bitlik bir GUID tamsayısı kullanın.

Yerel sayı taşarsa (benim durumumda, neredeyse hiç olmazdı; normal kullanımda, tek bir ağ oturumunda bunun gerçekleşmesi için dört ila beş gün sürekli oynatma süresi olurdu), sahibi bir "Tüm nesnelerimi sıfırlama" mesajını girin ve sıfırdan önce mevcut olan tüm nesneleri yeniden numaralandırın. Mesaj, tüm arkadaşlara aldıkları nesneleri atmalarını ve onları tekrar sorgulamalarını söyledi.

Daha süslü bir yaklaşım "GUID ile Nesne 'n' artık GUID 'm' ile Nesne" mesajıdır. Ama benim durumumda, gerçekte gerçekleşmesi pek olası değildi ve insanların tek bir ağ oturumunda beş gün kesintisiz oyun oynadıktan sonra, yarım saniye boyunca dünyadan kaybolan uzak nesneleri gerçekten önemsemediklerini düşünmüyordum. ;)


Taşmayı idare etmek için iyi bir fikir. Basit, ama düşünmedim :). "Varlıkları" unutmak güzel çünkü temelde müşterinin oyuna katıldığında kullandığı aynı kod yolunu yeniden kullanabilirsiniz
Lucas

4

Müşterileriniz kendi varlıklarını üretebilirlerse, sanırım eşler arası çok oyunculu oyununuz var.

Bu durumda, muhtemelen çok fazla müşteriniz yok. Kesinlikle 256'dan fazla değil. Ve varlık kimliğinizin 24 bite sığacağı garanti edilir (16000000+ varlık herkes için yeterlidir!). Bu nedenle, kimliğinizin en yüksek baytını müşterinin kimliğine eşit hale getirin:

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

ya da başka birşey.

Eğer yanılıyorsam ve yetkili bir sunucunuz varsa, istemcilerde asla yeni varlıklar oluşturmayın.


1

Kalıcı çok oyunculu oyunumda 'en saf' yöntemi kullanıyorum (sadece her yeni kimlik için bir tamsayıyı artırın) ve istemcinin yeni kimlik oluşturmasına izin vermediğim için iyi çalışıyor.

İstemcinin karar vermesine izin verirseniz (açıklanan bir çeşit GUID tekniği kullanarak), istemci yeni bir öğeye Eski Kimlik atayarak çeşitli hatalar da getirebilir (bu sadece 5 saniye gibi kafamın üstünde düşündüğüm şeydi , başka boşluklar da olabilir).

Her zamanki gibi, hile yapılmasını önlemek için, sunucu TÜM oluşturma ve doğrulama işlemini yapmalıdır .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.