Büyük bir karo haritasında ve zindanlarda 'bölgeleme'


10

Oyunum, Minecraft'a benzer bir haritaya sahip, sözde sahte ve rastgele üretildi. Ve büyük. Kullanıcının 1000x1000 alan (burada 2D) keşfettiğini varsayalım, bu 1.000.000 kutucuk.

Açıkçası hepsini hafızada saklayamayacağım. Ben de sadece 10 döşemeden veya yarıçaptan her şeyi göz ardı etmek istemiyorum - her ikisi de hiçbir şey güncellenmeyecek (tüm NPC'ler, belki de reaktif fayanslar) ve 1382.12918 gibi garip pozisyonlarla çalışmak zorunda kalacağım.

Öyleyse parçalara veya bölgelere ya da 64x64 fayans diyelim.

Parça a, b. Konum x, y.

Peki ya haritamda zindan ve benzeri isteseydim? Yani, her biri 40x40 alana sahip 40 katlı bir zindana götüren tek bir karo. Bunları tam olarak aynı haritada saklayamıyorum.

Ve bir de bellek tarafı var; bellekte aynı anda ne kadar saklayabilirim? Fayansları kimliğe göre kolayca yapabilirim ve normal 2B diziye sahip olabilirim. Ya da, karo türlerinin bir veri dosyasına sahip olmaktan daha etkili bir çözüm var mı? Yani 64x64 için .. bu sadece 20K ya da her neyse olacak. En gerçekçi güncelleme için mümkün olduğunca çevreye yüklenmesini istiyorum. Ama bellek sarkması olmadan ne tür sınırlara vurabileceğimi bilmiyorum.

Yanıtlar:


9

Ben şu görüşe katılıyorum: "kanıtlanmış bir mesele olmadıkça endişelenmeyin", erken düşünmeye değer olduğunu düşünüyorum: bir çözümün geriye dönük takılması çok daha acı vericidir. Ve evet, sadece 'yakındaki' fayans güncelleme onlar gitmek yoludur. Ancak, oyun dünyanızdaki öğelerin verimli bir şekilde depolanması ve adreslenebilirliği performans nedeniyle çok önemlidir.

Burada gerçekten düşündüğünüz seyrek bir veri kümesidir: potansiyel dizinlerin büyük (veya sınırsız) olduğu, ancak sadece küçük bir oranın gerçekte kullanıldığı bir şey. Kilit nokta, hangi oranın kullanılacağını tam olarak bilmemenizdir.

Seyrek veri seti problemine standart çözüm, indeksi / adreslenebilirliği gerçek veri deposundan ayırmaktır. Döşeme nesnesi pahalıysa, kompakt bir biçimde (örneğin düz bir dizi) saklayın. Ancak daha ucuz bir nesne ile dizine eklenmesine izin verin. En basit haliyle, bu, koordinatla kolayca indeksleyebileceğiniz bir 2D (veya 3D) matris olabilir, ancak matristeki her öğe basitçe bir endekstir. Daha sonra bu dizini, gerçek kutucuk içeriklerini ayrı, kompakt bir dizide aramak için kullanırsınız. Döşeme içeriği henüz yoksa, bunları dizinin sonuna ekleyin ve dizini 3D matrisinde saklayın.

İçeriklerin silinmesini desteklemek istiyorsanız (içerik dizisinin parçalanmasına yol açtığı için) çözüm daha karmaşık hale gelir ve karo içeriğiniz ucuzsa, dizinin ekstra ağırlığı (32 bit veya 64 bit indeksler) muhtemelen her bir potansiyel döşemeyi saklamaz. Ayrıca, önbellek performansınıza zarar verecek ekstra bir arama.

Ekstra dolaylı katmanlar ekleyerek daha fazla depolama verimliliği elde edebilirsiniz. Döşemelerinizi parçalar halinde düzenlediğinizi ve parçaların 64x64x64 boyutunda olduğunu varsayalım. 125, 1, 132'de bir karo verildiğinde, parçanın (1,0,2) olduğunu biliyorsunuz. Böylece, kompakt bir yığın dizisinden ve bir yığın indeks matrisinden oluşan bir dünyanız var (yığın yoksa -1). Her parçanın içeriği (varsa) 64x64x64 karo dizini matrisidir (karo henüz yoksa -1) ve kullanılan döşemelerin küçük bir dizisidir. Bu şekilde, asla kullanılmayan parçalar için büyük miktarda kiremit indeksi yakmazsınız. Bu tür bir yaklaşımı izleyerek ve yığın ayrıntı düzeyi için mantıklı sayılar seçerek, evreninizi büyük ölçüde ölçeklendirebilir ve bellek kullanımınızı kontrol altında tutabilirsiniz. Aslında, parçalarınızı 32x32x32 yaparsanız,

Ayrıca, özel bir şey ifade etmek için yığın veya karo dizinlerinizin yüksek dereceli bitini kullanmak gibi gizli hileler de yapabilirsiniz. Döşeme matrisindeki bir girişin üst biti ayarlanmışsa, daha düşük 31 bit bir döşeme dizini anlamına gelmez, bunun yerine bir 'çözgü endeksi' veya benzeri bir şey anlamına gelir ve bunu ayrı ayrı tutulan bir listede arayabilirsiniz. yol açtığı koordinatları bulmak için.


Gelecekte bu soruya rastlayan herkesi uyarıyorum: Bu yazıdaki hiçbir şey yanlış olmasa da, seyrek olmayan bir dünyaya sahip Minecraft gibi bir oyun için dürüstçe korkunç. (Ve MrCranky kadar diyor.) Bundan Dünyanız sadece faydaları birkaç birşeyler ve bir sürü varsa yaramazlar , değil birkaç somethings ve bir sürü boşaltır .

1
Yürekten veri seti depolama çözümünü korumakla yüklenen yükün oldukça yüksek olduğuna yürekten katılıyorum, bu yüzden sadece denge açıkça seyrekliğe doğru eğilirse devam edersiniz. Buradaki temel faktörler şunlardır: veri öğesinin maliyeti ve veri öğesinin olasılığı kullanılmaz. Minecraft'ın devasa, devasa bir potansiyel veri seti vardır (her yönde çok sayıda karo). Kullanılan potansiyel oyun dünyasının gerçek oranı küçüktür. Dünyada hareket ederken büyük çaplı alanlar talep etseniz de, potansiyel veri öğelerinin hala küçük bir kısmı.
MrCranky

1
Minecraft'ı farklı kılan şey, birim başına maliyetin küçük olması - belki de tek bir baytlık depolama alanıdır? Bir değer 'orada hiçbir şey' olmadığını gösterir, geri kalanı blok tipleridir ve bunu bir bayta kolayca sığdırabilirsiniz. Yani tek bir bloğa endeksiniz olmazdı, bu sadece deli, dizin sadece gerçek blok değerini saklamaktan çok daha büyük. Ancak seyrek veri seti kuralları hala daha yüksek seviyelerde çalışır. Her yığının (örn. 64x64x64) saklanması pahalıdır (256K blok), bu nedenle yokluğunu belirtmek için tek bir küçük değer veya varsa adresini kullanırsanız, büyük depolama alanı tasarruf etmiş olursunuz.
MrCranky

6

Neden bir milyon kutuyu hafızada saklayamıyorsunuz? Telefonumda bile 256MB RAM var; bir milyon boş fayans ne olacak, 4-32MB?


Depolanmak için çok büyük bir sayı gibi görünüyordu. Bunun yanı sıra, bunları güncellemek uzun zaman alacaktır.
Komünist Ördek

2
Güncellemeler için bir dizi kutucuğu görmezden gelmek, bir tür disk sayfalama çözümüyle uğraşmaktan çok daha kolaydır. Sadece .. onları görmezden gel. Fayansları bilinen bir oyuncuya X mesafeden daha fazla güncellemeyin.

2
@TheCommunistDuck Önemli olan tek şey, döşemelerin sayısını değil, döşemeleri saklamak için kullanılan toplam bellek miktarıdır.
Justin

1
Kragen ve Joe ile anlaştılar. Kulağa çok benzeyen şeylerden endişe etmeyin - matematiği yapın ve çalışın. Bir sorun olması pek olası değil.
Kylotan
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.