Bir MMO oyunda çok sayıda alıcı nasıl ele alınır?


26

Minecraft gibi oyunlar ya da alıcıları olan herhangi bir MMO oyunu nasıl oynanır?

Arazinin her kaztığında her seferinde 3 damla "pislik" damlacağının ortaya çıktığını söyleyin. Her öğenin her karede hesaplanan bir döndürme animasyonu olduğunu söyleyin. Eğer dünyadaki alıcıların sayısı çok yüksekse, bu alıcıların birçoğunun çerçeve hesaplamasında, bu alıcıların birçoğunun sizden hafif yıllar uzakta olması muhtemel olduğu için işe yaramaz bir yükü olacaktır.

Bu yüzden düşündüğüm şey, yalnızca yerel oyuncuya yakın pikaplarla "şeyler" yapmanız gerektiği, ancak yine de bu, herhangi bir pikap öğesinin animasyona başlamak için yeterince yakın olup olmadığını kontrol etmek zorunda olduğum anlamına geliyor.

Asıl sorum şu: diğer MMO'lar bu sorunu nasıl çözdü?


9
Ek olarak, Minecraft bağlamında, belirli sayıda öğe birbirine yeterince yakın olduktan sonra (aynı blok alanındaki aynı maddenin 3+'si), sunucu 3 örneği, blok türünü içeren gruplanmış bir örneğiyle değiştirir ( minecraft:dirt) ve bir sayı (30), böylece oyuncu onu almaya yetecek kadar yakın olduğunda, oyuncunun envanterine olabildiğince çok sayı ekler. Eğer oyuncu sadece 6 eşya için yer açarsa ve 30'luk bir yığın yerde kalırsa, oyuncu
6'yı toplar

6
@Zymus Ortaya çıkan sayısız öğede kene performansını düşürdüğüne dikkat çeker çünkü hepsi sürekli olarak yakındakileri arar.
user253751

Yanıtlar:


48

Sadece dünyanın bu kısımlarını müzikçalara yakın olan belleğe yükleyerek. Başka bir şey sabit sürücüye askıya alındı. İki kilometre uzağa koyan küçük bir nesne olduğunda, oyuncu onu göremez ve onunla etkileşime giremez. Bu nedenle, güncellemek veya görüntülenmesi için GPU'ya göndermek için hiçbir neden yoktur. Nesne ve etkileşim menzili ne kadar küçükse, oynatmak istediğiniz oynatıcının etrafındaki mesafe o kadar düşük olur.

Müzikçalara neyin yakın olduğunu bulmakla ilgili: Bu daha çok, dünyayı mekansal arama için optimize edilmiş bir veri yapısında depolamaktan kaynaklanıyor. Onlar için iyi adaylar mekansal karma ve çok boyutlu ağaçlar .


Hızlı cevap için teşekkürler. Birlik'i tetikleyici çarpıştırıcıları kontrol etmek için bir çeşit uzamsal bölümlendirme kullandığını tahmin ettiğim gibi kullanmayı düşünüyordum, bu yüzden karakterimin etrafında büyük bir daire çarpıştırıcısı oluşturacağım ve içindeki her öğe "canlandırılacak". Bu, cevabınızı uygulamanın bir yolu mu? Yanılıyorsam düzelt beni, şerefe!
Alakanu

2
@ Alakanu Nesnelerin uzun mesafelerde görünür olmasını istiyorsanız, ancak oyuncuya yakınken yalnızca hesaplama yoğunluğu gerektiren bazı davranışlarda bulunmayı istiyorsanız (ve y ekseni etrafında bir şeyi döndürmek çok pahalı olmamalıdır) kullanılabilir. Ancak Unity'de açık bir dünya oyunu uygularken ortaya çıkan asıl zorluk, oyuncu dünya içinde hareket ederken oyun nesnelerini akıllıca canlandırmak ve yok etmektir (ya da daha iyisi: dikmek ve yok etmek yerine nesne havuzlamayı kullanmak).
Philipp

Evet, bu durumda nesne havuzu yapmak zorunludur :) Tamam, çok teşekkür ederim!
Alakanu

3
@Alakanu Bu cevabın o oyuna nasıl uygulandığı hakkında daha fazla bilgi için Minecraft'ın "Yüklü Topakları" konseptini kontrol edebilirsiniz.
T. Sar - Monica,

1
Bu sadece alıcılar için doğru değildir. Müzikçalardan çok uzakta olan herhangi bir nesneye bu şekilde davranılabilir. Bazen müzikçalara yakın olan nesneler bile. Dolu bir iç mekana sahip bir ev hayal edin, ancak siz gerçekten eve girene kadar iş yapmaya gerek yoktur.
Zibelas

22

Yönetmeniz gereken iki farklı şey var:

  1. Sunucu gerekir bir authorative şekilde, tüm dünyayı yönetmek. Bunun için, N müşterileri ile iletişim (N'nin "büyük" olduğu) gerekir.

  2. Müşteri prensip olarak tüm dünyayı biliyor olabilirdi , ama buna ihtiyacı yok . Müşteri için, oyuncunun yakınında ne olduğunu bilmek yeterlidir. Örneğin oldukça kaba bir ızgara benzeri bölümleme olduğu varsayıldığında, sadece oyuncunun hücresini ve oynatıcının etrafındaki 26 hücreleri (veya 2B bir ızgaraya sahipseniz 8 hücreyi) bilmesi gerekir. Biraz daha ince bir ızgara daha iyidir, ancak fikri anladınız.

Şimdi, birçok alıcı, "çok" nedir? Saniyede belki 5 şey kazarsınız, bu belki de sunucuda güncellenmesi gereken iki düzine sayıdır ve sunucunun, ilgilendiğiniz alanı hücrenizle örtüşen başka bir oyuncuya iletmesi gerekebilir . Bir bilgisayar için bu oldukça saçma bir veri ve ihmal edilebilir bir hesaplama. Aynı hücrede yüzlerce / bin oyuncu varsa (o zaman ayrıştırma çok kaba) zor olabilir.

Sunucunun, alıcıların dönüşünü veya bu gibi ayrıntıları bilmesi veya umursaması gerekmez. Neden olsun ki?

Müşteri aslında umursamıyor, çünkü bu sadece müşterinin anında yapabileceği göz şekeri.

Sunucunun bakış açısından gerekli olan, içinde bulunduğunuz düğümde (30, 40, 50) kazı yaptığınızı bilmek ve bunun, örneğin 5 tipinde üç nesneyi ya da 7 tipinde bir nesneyi ortaya çıkardığına karar vermesidir. 3 sayısı. Tek umursadığı şey ve sana anlattığı her şey. Ayrıca, ilgilenilen alanını daha sonra şebeke hücresi üzerinde hareket ettiren birine gönderilen verilerde de bulunacaktır (o zamana kadar hala orada olduğunu varsayarak).

Müvekkilinin orada ortaya çıktığı üç nesneye söylendiğini söyledi. Şimdi, müşteri şimdi bir 'D' olan bir ASCII-sanat haritası görüntüler mi, yoksa dönen bir kir yığını mı gösterir, hepsi aynıdır. Kazıkların farklı dönmelere sahip olup olmadığı ya da sadece oynatıcınıza yakın olanların da dönüp dönmediği de aynıdır. Monitörünüzde görüntülenen şeyler yalnızca başkasını etkilemez.

Böylece, sadece yakındaki kir yığınlarını döndürmek istediğiniz somut durumda, bildiğiniz tüm cisimler üzerinde bir aralık kontrolü yapabilirsiniz. Veri seti büyük olmadığı için her şey için kaba kuvvet bile işe yarayacak.

Bölünme boyutunuza bağlı olarak (ve gerekir), çok uzaktaki ızgara hücrelerini önemsiz şekilde eritebilirsiniz.

Elbette, hücrenizi daha alt bölümlere ayırabilir ve süper zeki bir şey kullanabilirsiniz. İsterseniz kd-Tree kullanın, ancak büyük kazançlar beklemeyin. Manhattan distasından bir şeyler eritebilir veya bir şeylerinizi küçük bir ızgarada sıralayabilirsiniz… ama neden?

Bir mesafe kontrolü (gerçekten karesel mesafe, ancak sizin için aynıdır) sadece iki çarpma ve bir dallanma veya koşullu hareket izleyen bir toplama (MUL, MADD, yani gerçekten sadece iki işlem için optimize edilmiştir). Bu, bir seferde tüm ızgara hücrelerini budamayan herhangi bir işlem kadar hızlı. Aslında bu o şey olabilir hatta GPU yapmak ...

Aynı yüzeye karşı nasıl birkaç yüz veya en fazla birkaç bin mesafe kontrol edeceğinizi görünce (kare mesafe iyi çalışır), bu hesaplamayı yapmakta zorlanmayacaksınız. bitişik bellek üzerine dostça yineleme ve koşullu hareketlerle, bu ucuzdur. Gibi bir şey (sözde kodu) rot = r[i] + 1; r[i] = ((dx*dx+dy*dy) < DIST_SQ) ? rot : r[i];. Bu, kare başına birkaç yüz değerden oluşan bir dizi üzerinde bir yineleme. Bilgisayar bunu yapmayı daha az umursamıyordu, bitişik yükler ve depolar, basit ALU, dallar yok ve sadece birkaç bin yineleme.

Bu (çoğa bire), sunucudakiyle aynı sorun sınıfına (çoğa çoğa) değil. Gerçekten, müşteri sorun değil.


Üzgünüm, framerate hakkında konuşmaya başladığımda bir müşteriden bahsettiğimin açık olduğunu düşündüm.
Alakanu

1
Ancak müşteri hiçbir zaman sorun olmaz. Istemci çok büyük ve kitlesel ve çok yerel, sunucudan çok daha az bilmek gerekiyor . İdeal olarak, müşteri, uzamsal bölümlendirme düğümünü (her ne demek olursa olsun, ızgara), oyuncuların içinde ve hemen çevreleyenleri bilir ve işte budur. Dolayısıyla, bin oyuncu yan yana durmadığı sürece güncellemeler çok mütevazı. Normalde, yalnızca bir ya da iki nesne için deltalara ve bir düğümün genişliğinin yarısından fazlası için bir yöne doğru hareket ettikten sonra yeni bir ızgara düğümünün içeriğine ihtiyacınız olacaktır. Her şey: Senin sorunun değil.
Damon

1
Mesele şu ki, akıllı olmak çok aptalca bir fikir olabilir. Dünyanız ille de uzamsal olarak bölünmüştür, her düğümde yönetilebilir sayıda nesne vardır. Modern CPU'lar (ve daha da fazlası olan GPU'lar) SoA verilerinin sıralı olarak işlenmesinde iyidir. Onlar tutarsız dallanma sevmiyorum ve onlar da az tutarsız bellek erişimi gibi - ancak olduğu tam olarak "sadece yakın işlemek" yapar. Yönetilebilir sayılar için (yüz, bin), bir hücrede "tümünü işle" tamamen yeterli ve muhtemelen yapabileceğiniz en iyi şey.
Damon

1
@ Alakanu Bu, sorunuza ayrıntılı ve eksiksiz bir cevap gibi görünüyor. Bunun bir cevap olmadığını düşünüyorsanız, ya yanlış anladınız ya da sorunuz o kadar net değil ki, Damon, ben ve bu cevabı kaldıran tüm insanlar tarafından yanlış anlaşıldığını.
David Richerby

2
@Alakanu Size yardım etmeye çalışan insanlardan şikayet ederek gerçekten çok fazla zaman harcıyorsunuz. Bununla iyi şanslar.
David Richerby

2

@ T.Sar, daha fazla bilgi için Minecrafts "yüklü yığın" kavramına bakmanız gerektiğini yorumunda yazıyor. Bunu yaparsanız, oyunda makine üreten insanlar nedeniyle Minecraft'ta bunun oldukça karmaşık olduğunu unutmayın.

Çok basitleştirilmiş bir versiyon şöyle:

Dünya kare bölgelere ayrılmıştır (parçalar). Minecraft'da ayrıca bir yükseklik bölümü de var ama çoğu kişi buna ihtiyaç duymuyor.

Oyun istemcisi, yalnızca oyuncuya yakın bölgelere önem verir. Bu, oynatıcının etrafına bir daire çizmekten çok daha kolaydır, ancak yeterince iyi.

Minecraft'ta bölgeler 16x16 bloktur ve müşteri her bir yönde 4 bölge olan yaklaşık 9x9 bölgeyi bilir. (4 bölge doğu + bölge oyuncusu + 4 bölge batı = toplam 9 bölgedir. Aynı kuzey / güney)

Bu sayılarla ilgili büyülü bir şey yok, oyununuzda anlamlı olanları kullanın.

Müşteri sadece bu alandaki şeyleri canlandırır. Sunucu yalnızca bazı oyunculara yakın bölgelerde dolaşan canavarlar gibi şeyleri hesaplar .

Bir oyuncu bir bölgenin içinde dolaştığında, özel bir şey olmaz, bir bölgeyi geçtiklerinde "canlandırma kenarı" bir bölgeye itilir. Ardından müşterinin sunucuya şu anda gördüğü bölgeleri sorması gerekir.

İç içe geçmiş birkaç animasyon sınırına sahip olmanın yanlış bir tarafı yoktur. Örneğin canlandırma maddesi 3x3'lük bir alana düşer, 5x5'lik bir alanda canavarları dolaşır ve manzarayı 9x9'luk bir alanda gösterir.

Sunucu, oyuncunun görmediği bölgelerin "dondurulmuş halini" tutar. Bu çok fazla hafıza gerektiriyorsa, bir süre sonra bunları çıkarmak isteyebilirsiniz. Bir oyuncu daha sonra geldiğinde, bölge ürün düşmeden yeniden yüklenir. Bir dahaki sefere daha hızlı olman gerekiyor, Oyuncu 1.


Beraberlik mesafesi ayarlanabilir ancak bu durumda 8 topak 9x9'dur ve istemci tarafında bir karardır, ancak sunucuya işleri hızlandırması için bilgi verebilir (böylece sunucu, istemcinin oluşturmadığı verileri göndermez). Ayrıca ... Doom ve Quake bu sorunu yalnızca mantıklı kılan şeyleri oluşturma konusunda çözmedi mi?
SparK

Bırakılan eşyaların ümitsizleştirilmesi hakkında ... yakındaki bir oyuncu olduğunda eşyayı sadece "yaşlanır" minecraftında. Böylece, bırakılan bir öğeyi boş bir parçaya kaydedebilir ve daha sonra alabilirsiniz.
SparK
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.