Generasi prosedural adalah tulang punggung game roguelike dan RPG perayap di Roblox. Tanpa desain algoritma yang efisien, peta akan memicu lag parah dan tabrakan geometri.
Dengan memanfaatkan pembagian ruang BSP, Triangulasi Delaunay untuk rute lorong, serta fitur bawaan `StreamingEnabled`, pengembang dapat membangun dungeon berskala masif yang sangat ringan.
1. Pembagian Ruangan dengan Binary Space Partitioning (BSP)
Subdivisi ruang terstruktur untuk distribusi kamar yang rapi:
- Pembagian Rekursif: Ruang induk dipotong secara vertikal atau horizontal berulang kali hingga ukuran partisi daun mencapai batas yang diinginkan.
- Pembatasan Aspek Rasio: Membatasi proporsi ruangan agar tidak ada kamar yang berbentuk lorong sempit tak wajar.
- Inskripsi Tanpa Tabrakan: Ruangan digambar tepat di dalam batas partisi sehingga dijamin tidak akan saling bertumpuk.
2. Lorong Alami: Triangulasi Delaunay & Minimum Spanning Tree (MST)
Menghubungkan kamar secara mulus tanpa jalan buntu:
- Awan Titik Pusat: Titik tengah setiap kamar dihubungkan membentuk jaringan segitiga Delaunay 2D.
- Algoritma MST: Memangkas jalur berlebih untuk memastikan seluruh ruangan terhubung melalui rute terpendek.
- Sirkulasi Berputar (15% Jalur Ekstra): Mengembalikan sebagian jalur yang dipangkas agar pemain tidak merasa jenuh berjalan bolak-balik.
3. Pembuatan Lorong Kotak & Penempatan Tile Mesh
Mengubah garis grafik menjadi struktur fisik di Roblox:
- Rute Belok Siku: Lorong dibentuk dengan sudut tegak lurus menghubungkan pintu-pintu ruangan.
- Autotiling 4-Bit: Memilih jenis dinding lurus, sudut, atau persimpangan secara otomatis berdasarkan tile tetangga.
- Penggabungan Aset: Menyatukan lantai dan dinding menjadi model padat untuk menghemat jumlah part hingga 90%.
-- Modul Partisi Ruang Biner (BSP)
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. Optimasi Memori & Arsitektur StreamingEnabled
Memastikan dungeon besar berjalan mulus di perangkat RAM 2GB:
- ModelStreamingMode.Atomic: Memuat ruangan secara utuh sekaligus agar pemain tidak jatuh ke ruang hampa.
- Partisi Sektor 64x64 studs: Menonaktifkan kalkulasi fisika pada sektor yang jauh dari posisi pemain.
- Occlusion Culling: Pintu tertutup mencegah mesin merender ruangan yang terhalang dari pandangan.
5. Sinkronisasi Seed & Spawn Otoritatif Server
Mencegah cheat dan memastikan konsistensi peta tanpa beban jaringan:
- Replikasi Seed Acak: Server hanya membagikan satu angka seed 32-bit; klien membangun peta identik secara mandiri.
- Spawn Musuh di Server: Monster, jebakan, dan peti harta karun selalu dibuat dan dikontrol dari sisi server.
- NavMesh Otomatis: Memasang PathfindingModifier pada lantai agar kecerdasan buatan musuh dapat mengejar pemain dengan lancar.
Frequently Asked Questions
Mengapa memilih BSP daripada menaruh ruangan secara acak?
Penempatan acak membutuhkan pengecekan tabrakan yang berat dan menyisakan banyak ruang kosong. BSP membagi wilayah secara merata dan rapi.
Apa fungsi gabungan Triangulasi Delaunay dan MST?
Delaunay menemukan rute tetangga alami, sedangkan MST menjamin seluruh kamar saling terhubung tanpa jalan buntu.
Mengapa StreamingEnabled penting untuk dungeon besar?
Fitur ini menghemat penggunaan RAM dengan hanya merender ruangan di sekitar pemain secara dinamis.
Bagaimana cara mencegah peta berbeda antara klien dan server?
Cukup gunakan nilai seed acak yang sama persis di kedua sisi, sehingga perhitungan bentuk peta akan menghasilkan wujud yang identik.