wanted to create a random dungeon generation type system, but the rooms are like actually random layouts and stuff, couldn’t find much on it besides this one post
Video for lazy people
He actually made some cool looking generation thing,
i “somewhat” made the grid system
(most of it is taked / made off of his stuff, but with some extras added in to help)
and now im wondering how i would generate based on the area next to an area?
an idea i had was figuring out what each face to each cell has (wall, floor, door, escape door, ect) and generating based on that but not sure how to achieve said thing
Code
Module Script for grid
-- Variables
local NumberOfGeneratedGrids = 0
local NumberOfCellsGenerated = 0
local CellGen = require(script.CellGeneration)
local PartDebug = {}
local Debris = game:GetService("Debris")
-- Functions
local function TempDebugPart(P1, P2, P3, P4, P5)
if #PartDebug > 0 then
for i, v in ipairs(PartDebug) do
v:Destroy()
end
end
local T_ = {P1, P2, P3, P4, P5}
for i = 1, #T_ do
local Part = Instance.new("Part")
Part.Anchored = true
Part.Size = Vector3.new(1,1,1)
Part.Position = T_[i]
local Highlight = Instance.new("Highlight", Part)
Part.Parent = workspace
table.insert(PartDebug, Part)
end
end
local function TempDebugPart2(P1, P2, P3, P4, P5)
local T_ = {P1, P2, P3, P4, P5}
for i = 1, #T_ do
local Part = Instance.new("Part")
Part.Anchored = true
Part.Size = Vector3.new(1,1,1)
Part.Position = T_[i]
local Highlight = Instance.new("Highlight", Part)
Part.Parent = workspace
Debris:AddItem(Part, 10)
end
end
local function RangeCheck(Position, Corner1, Corner2)
--TempDebugPart(Position, Corner1, Corner2)
local Check1
local Check2
local PosX, PosY, PosZ = Position.X, Position.Y, Position.Z
local Corner1X, Corner1Y, Corner1Z = Corner1.X, Corner1.Y, Corner1.Z
local Corner2X, Corner2Y, Corner2Z = Corner2.X, Corner2.Y, Corner2.Z
if PosX < Corner2X and PosY < Corner2Y and PosZ < Corner2Z then
Check1 = true
end
if PosX > Corner1X and PosY > Corner1Y and PosZ > Corner1Z then
Check2 = true
end
if Check1 and Check2 then
return true
end
end
-- Cells are ordered as XZY
local Grid = {}
function Grid.New(X, Y, Z, cframe, CellSize, SendDelay)
local self = setmetatable({}, Grid)
NumberOfGeneratedGrids += 1
self.CFrame = cframe
self.TotalCells = X * Z * Y
self.NumX = X
self.NumZ = Z
self.NumY = Y
self.CellSize = CellSize
self.Cells = {}
for x = 1, X do
self.Cells[x] = {}
for z = 1, Z do
self.Cells[x][z] = {}
for y = 1, Y do
local WorldCFrame = cframe + (Vector3.new(x,y,z) * CellSize)
local Cell = CellGen.New(x, y, z, WorldCFrame, CellSize)
Cell:Display()
NumberOfCellsGenerated += 1
self.Cells[x][z][y] = Cell
if SendDelay then task.wait(SendDelay) end
end
end
end
return self, true
end
function Grid:CellFromPosition(Position)
for x = 1, self.NumX do
for z = 1, self.NumZ do
for y = 1, self.NumY do
local cell = self.Cells[x][z][y]
local CC1 = (cell["Size"]/2 + cell.Position)
local CC2 = (-cell["Size"]/2 + cell.Position)
local InRange = RangeCheck(Position, CC2, CC1)
if InRange then
return cell
end
end
end
end
return false
end
function Grid:GetCellsInBetween(CellA, CellB)
local cells = {}
local cellsTable = self.Cells
local X1 = math.abs(CellA.X - CellB.X)
local Y1 = math.abs(CellA.Y - CellB.Y)
local Z1 = math.abs(CellA.Z - CellB.Z)
local X2 = math.min(CellA.X, CellB.X)
local Y2 = math.min(CellA.Y, CellB.Y)
local Z2 = math.min(CellA.Z, CellB.Z)
Y1 += 1
for x = 1, X1 do
for z = 1, Z1 do
for y = 1, Y1 do
local Cell = cellsTable[X2+x-1][Z2+z-1][Y2+y-1]
table.insert(cells, Cell)
end
end
end
return cells
end
function Grid:GetCellRegionCFrame(cf, Size)
local halfCellSize = (self.CellSize/2)
local CornerCFA = cf * CFrame.new(-halfCellSize.X, -halfCellSize.Y, -halfCellSize.Z)
local CornerCFB = cf * CFrame.new(halfCellSize.X, halfCellSize.Y, halfCellSize.Z)
PartDebug(cf.Position, CornerCFA.Position, CornerCFB.Position)
local CellA, CellB = self:CellFromPosition(CornerCFA.Position), self:CellFromPosition(CornerCFB.Position)
return self:GetCellsInBetween(CellA, CellB)
end
function Grid:GetCellRegionCells(CellA, CellB)
return self:GetCellsInBetween(CellA, CellB)
end
function Grid.Info()
print("Number of grids: " .. NumberOfGeneratedGrids)
print("Number of cells: " .. NumberOfCellsGenerated)
end
function Grid.CellTablePartDebug(Table)
for i, v in ipairs(Table) do
TempDebugPart2(v["Position"])
end
end
Grid.__index = Grid
return Grid
Module script for cells
local AllCells = {}
local CellPartDisplay = script.CellPartDisplay
local Cell = {}
function Cell.New(X, Y, Z, WorldCFrame, Size)
local self = setmetatable({}, Cell)
self.X = X
self.Y = Y
self.Z = Z
self.Occuiped = false
self.Size = Size
self.WCF = WorldCFrame
self.Position = WorldCFrame.Position
table.insert(AllCells, self)
return self
end
function Cell:Display()
if not workspace.Terrain:FindFirstChild("DisplayParts") then
local DisplayParts = Instance.new("Folder")
DisplayParts.Name = "DisplayParts"
DisplayParts.Parent = workspace.Terrain
end
local Folder = workspace.Terrain:FindFirstChild("DisplayParts")
local DisplayPart = CellPartDisplay:Clone()
DisplayPart.Size = self.Size
DisplayPart.Parent = Folder
DisplayPart.CFrame = self.WCF
DisplayPart.T.TextLabel.Text = self.X .. ", " .. self.Y .. ", " .. self.Z
DisplayPart.Name = "DisplayPart: " .. self.X .. ", " .. self.Y .. ", " .. self.Z
end
local color = Color3.new(1,0,0)
Cell.__index = Cell
return Cell
Server Script
not really needed but this is what ive been testing
local GridGeneration = require(game.ReplicatedStorage.GridGeneration)
local CellSize = Vector3.new(20,10,20)
local CellCFrame = CFrame.new(1,1,1)
local XAmount = 20
local YAmount = 2
local ZAmount = 20
local Grid = GridGeneration.New(XAmount, YAmount, ZAmount, CellCFrame, CellSize)
local Cell1 = Grid:CellFromPosition(Vector3.new(26, 21.5, 80))
local Cell2 = Grid:CellFromPosition(Vector3.new(256, 17, 241))
local CellsInBetween = Grid:GetCellsInBetween(Cell1, Cell2)
print(CellsInBetween)
GridGeneration.CellTablePartDebug(CellsInBetween)
heres a little video of it working
(Edit)
Added something else in that i forgot to add before, also forgot to dash out some of the code