Prosedürel harita üretimi, Roblox'taki roguelike ve zindan RPG oyunlarının omurgasıdır. Zayıf mimariler bellek taşmalarına ve harita çakışmalarına neden olur.
Oda yerleşimi için BSP, doğal koridorlar için Delaunay üçgenlemesi ve performans için `StreamingEnabled` kullanarak devasa ve hafif zindanlar inşa edebilirsiniz.
1. Binary Space Partitioning (BSP) ile Çakışmasız Odalar
Haritanın orantılı bölünmesi için matematiksel algoritma:
- Özyinelemeli Bölünme: Harita alanı, yaprak düğümler istenen boyuta inene kadar dikey veya yatay olarak rastgele parçalanır.
- En-Boy Oranı Sınırı: Odaların aşırı dar koridorlara dönüşmesini önlemek için 1:1 ile 1:2.5 arası oranlar korunur.
- Çakışmasız Yerleşim: Her oda kendi bölümünün içine çizildiği için pahalı çarpışma testleri olmadan %100 çakışma engellenir.
2. Doğal Koridorlar: Delaunay Üçgenlemesi & Minimum Spanning Tree (MST)
Kör nokta bırakmadan organik geçiş hatları oluşturma:
- Merkez Noktaları Ağı: Oda merkezleri birleştirilerek düzlemsel 2D Delaunay üçgenleme ağı elde edilir.
- MST Algoritması: Gereksiz hatlar elenerek tüm odaların en kısa toplam mesafeyle bağlanması sağlanır.
- Döngü Ekleme (%15 Ekstra): Elenen hatların bir kısmı geri eklenerek tekdüze doğrusal yürüyüşler engellenir.
3. Izgara Tabanlı Koridor Açma ve Modüler Parça Montajı
Grafiksel verilerin Roblox fiziksel parçalarına dönüştürülmesi:
- Dik Açılı L ve S Bağlantıları: Odalar kapı eşiklerinden dik açılı koridor hatlarıyla birbirine bağlanır.
- 4-Bit Otomatik Döşeme: Komşu karolara göre düz duvar, köşe ve kavşak modelleri otomatik seçilir.
- Parça Birleştirme: Zemin ve duvar modelleri kaynaklanarak parça sayısı %90 oranında düşürülür.
-- BSP Düğüm Bölme Modülü
local BSPNode = {}
BSPNode.__index = BSPNode
function BSPNode.new(x, z, width, depth)
local self = setmetatable({}, BSPNode)
self.X, self.Z = x, z
self.Width, self.Depth = width, depth
self.LeftChild = nil
self.RightChild = nil
self.Room = nil
return self
end
function BSPNode:Split(minSize)
if self.LeftChild or self.RightChild then return false end
local splitHorizontal = math.random() > 0.5
if self.Width > self.Depth and (self.Width / self.Depth) >= 1.25 then
splitHorizontal = false
elseif self.Depth > self.Width and (self.Depth / self.Width) >= 1.25 then
splitHorizontal = true
end
local maxDimension = (splitHorizontal and self.Depth or self.Width) - minSize
if maxDimension <= minSize then return false end
local splitPos = math.random(minSize, maxDimension)
if splitHorizontal then
self.LeftChild = BSPNode.new(self.X, self.Z, self.Width, splitPos)
self.RightChild = BSPNode.new(self.X, self.Z + splitPos, self.Width, self.Depth - splitPos)
else
self.LeftChild = BSPNode.new(self.X, self.Z, splitPos, self.Depth)
self.RightChild = BSPNode.new(self.X + splitPos, self.Z, self.Width - splitPos, self.Depth)
end
return true
end
return BSPNode
4. Bellek Yönetimi ve StreamingEnabled Mimarisi
100'den fazla odası olan zindanları 2GB RAM'li cihazlarda akıcı çalıştırma:
- ModelStreamingMode.Atomic: Odaların tek parça halinde yüklenmesiyle zeminsizliğe düşme hataları önlenir.
- 64x64 studs Bölümleme: Oyuncudan uzak zindan kısımlarının fizik hesaplamaları durdurulur.
- Görüş Alanı Kısıtlama (Occlusion): Kapalı kapılar arkadaki odaların çizilmesini engelleyerek GPU yükünü hafifletir.
5. Tohum (Seed) Eşitleme ve Sunucu Otoritesi
Ağ gecikmesi olmadan hilesiz ve senkronize haritalar:
- Ortak Rastgele Tohum: Sunucudan paylaşılan tek bir 32-bit tamsayı tohumuyla istemci ve sunucu aynı haritayı bağımsız üretir.
- Sunucu Yetkili Varlıklar: Canavarlar, tuzaklar ve sandıklar sadece sunucu tarafında oluşturulup kontrol edilir.
- Otomatik NavMesh: Düşman yapay zekasının zemin boşluklarını fark edip oyuncuyu doğru takip etmesi için PathfindingModifier atanır.
Frequently Asked Questions
Rastgele yerleşim yerine neden BSP kullanılmalıdır?
Rastgele yerleşim oda çakışmalarına ve boşluklara yol açar. BSP alanı dengeli böler ve çakışmayı matematiksel olarak önler.
Delaunay ve MST ikilisinin görevi nedir?
Delaunay komşu yolları bulur, MST ise hiçbir odayı izole bırakmadan en kısa koridor ağını inşa eder.
StreamingEnabled zindanlarda nasıl performans sağlar?
Yalnızca oyuncunun yakınındaki odaları belleğe alıp uzaktakileri kaldırarak mobil cihazlarda RAM tasarrufu sağlar.
Haritanın herkes için aynı olması nasıl sağlanır?
Sunucu ve istemci aynı rastgele tohum değerini paylaşır, böylece harita veri aktarımı olmadan yerel olarak üretilir.