I have created a script that randomly generates a maze from a center point in a perfectly cube-shaped formation.
Here’s the full script for anybody who wants to look. (It’s a server script)
(You can point out problems in my script if you also want to, but only after if the Z-Fighting gets solved.)
local storage = game:GetService("ReplicatedStorage")
local gameWorkspace = game:GetService("Workspace")
local replicatedFirst = game:GetService("ReplicatedFirst")
local walls = {
storage.Maze.HorizentalLeft,
storage.Maze.HorizentalRight,
storage.Maze.VerticalLeft,
storage.Maze.VerticalRight
}
local firstRandom = walls[math.random(#walls)]
local firstMazeSection = firstRandom:Clone()
firstMazeSection.Parent = gameWorkspace.Maze
local northX = 0
local northY = 0
local northZ = 0
local southX = 0
local southY = 0
local southZ = 0
local westX = 0
local westY = 0
local westZ = 0
local eastX = 0
local eastY = 0
local eastZ = 0
local northXD = 0
local northYD = 0
local northZD = 0
local southXD = 0
local southYD = 0
local southZD = 0
local westXD = 0
local westYD = 0
local westZD = 0
local eastXD = 0
local eastYD = 0
local eastZD = 0
--North and South
local cloneCounterNW = 0
local northWestPositions = {}
local flexibleCounterNW = 0
local cloneCounterNE = 0
local northEastPositions = {}
local flexibleCounterNE = 0
local cloneCounterSW = 0
local southWestPositions = {}
local flexibleCounterSW = 0
local cloneCounterSE = 0
local southEastPositions = {}
local flexibleCounterSE = 0
--East and West
local cloneCounterWN = 0
local westNorthPositions = {}
local flexibleCounterWN = 0
local cloneCounterWS = 0
local westSouthPositions = {}
local flexibleCounterWS = 0
local cloneCounterEN = 0
local eastNorthPositions = {}
local flexibleCounterEN = 0
local cloneCounterES = 0
local eastSouthPositions = {}
local flexibleCounterES = 0
local moveDistance = 24.5
local sections = {}
while cloneCounterNW <= 25 do
task.wait()
--Straight generations
northX = northX +moveDistance
local randomWallN = walls[math.random(#walls)]
local cloneWallN = randomWallN:Clone()
cloneWallN.Parent = game.Workspace.Maze
cloneWallN:PivotTo(cloneWallN:GetPivot() +Vector3.new(northX, 0, 0))
southX = southX +moveDistance
local randomWallS = walls[math.random(#walls)]
local cloneWallS = randomWallS:Clone()
cloneWallS.Parent = game.Workspace.Maze
cloneWallS:PivotTo(cloneWallS:GetPivot() -Vector3.new(southX, 0, 0))
westZ = westZ +moveDistance
local randomWallW = walls[math.random(#walls)]
local cloneWallW = randomWallW:Clone()
cloneWallW.Parent = game.Workspace.Maze
cloneWallW:PivotTo(cloneWallW:GetPivot() -Vector3.new(0, 0, westZ))
eastZ = eastZ +moveDistance
local randomWallE = walls[math.random(#walls)]
local cloneWallE = randomWallE:Clone()
cloneWallE.Parent = game.Workspace.Maze
cloneWallE:PivotTo(cloneWallE:GetPivot() +Vector3.new(0, 0, eastZ))
--Diagonal generations
northXD = northXD +moveDistance
northZD = northZD +moveDistance
local randomWallND = walls[math.random(#walls)]
local cloneWallND = randomWallND:Clone()
cloneWallND.Parent = game.Workspace.Maze
cloneWallND:PivotTo(cloneWallND:GetPivot() +Vector3.new(northXD, 0, northZD))
southXD = southXD +moveDistance
southZD = southZD +moveDistance
local randomWallSD = walls[math.random(#walls)]
local cloneWallSD = randomWallSD:Clone()
cloneWallSD.Parent = game.Workspace.Maze
cloneWallSD:PivotTo(cloneWallSD:GetPivot() -Vector3.new(southXD, 0, southZD))
westXD = westXD +moveDistance
westZD = westZD -moveDistance
local randomWallWD = walls[math.random(#walls)]
local cloneWallWD = randomWallWD:Clone()
cloneWallWD.Parent = game.Workspace.Maze
cloneWallWD:PivotTo(cloneWallWD:GetPivot() +Vector3.new(westXD, 0, westZD))
eastXD = eastXD -moveDistance
eastZD = eastZD +moveDistance
local randomWallED = walls[math.random(#walls)]
local cloneWallED = randomWallED:Clone()
cloneWallED.Parent = game.Workspace.Maze
cloneWallED:PivotTo(cloneWallED:GetPivot() +Vector3.new(eastXD, 0, eastZD))
--Filling in the gaps
--Northwest
if cloneCounterNW == 0 then
cloneCounterNW = cloneCounterNW +1
else
repeat
flexibleCounterNW = flexibleCounterNW +moveDistance
table.insert(northWestPositions, cloneCounterNW, cloneWallN.PrimaryPart.Position.Z
-flexibleCounterNW)
local randomWallNW = walls[math.random(#walls)]
local cloneWallNW = randomWallNW:Clone()
cloneWallNW.Parent = game.Workspace.Maze
cloneWallNW:PivotTo(cloneWallNW:GetPivot() +Vector3.new(math.abs(
cloneWallN.PrimaryPart.Position.X -cloneWallNW.PrimaryPart.Position.X)), 0, 0)
cloneWallNW:PivotTo(cloneWallNW:GetPivot() -Vector3.new(0, 0,
math.abs(flexibleCounterNW)))
until flexibleCounterNW == cloneCounterNW *moveDistance
for serial, value in pairs(northWestPositions) do
table.remove(northWestPositions, serial)
end
flexibleCounterNW = 0
cloneCounterNW = cloneCounterNW +1
end
--Northeast
if cloneCounterNE == 0 then
cloneCounterNE = cloneCounterNE +1
else
repeat
flexibleCounterNE = flexibleCounterNE +moveDistance
table.insert(northEastPositions, cloneCounterNE, cloneWallN.PrimaryPart.Position.Z
-flexibleCounterNE)
local randomWallNE = walls[math.random(#walls)]
local cloneWallNE = randomWallNE:Clone()
cloneWallNE.Parent = game.Workspace.Maze
cloneWallNE:PivotTo(cloneWallNE:GetPivot() +Vector3.new(math.abs(
cloneWallN.PrimaryPart.Position.X -cloneWallNE.PrimaryPart.Position.X)), 0, 0)
cloneWallNE:PivotTo(cloneWallNE:GetPivot() +Vector3.new(0, 0,
math.abs(flexibleCounterNE)))
until flexibleCounterNE == cloneCounterNE *moveDistance
for serial, value in pairs(northEastPositions) do
table.remove(northEastPositions, serial)
end
flexibleCounterNE = 0
cloneCounterNE = cloneCounterNE +1
end
--Southwest
if cloneCounterSW == 0 then
cloneCounterSW = cloneCounterSW +1
else
repeat
flexibleCounterSW = flexibleCounterSW +moveDistance
table.insert(southWestPositions, cloneCounterSW, cloneWallS.PrimaryPart.Position.Z
-flexibleCounterSW)
local randomWallSW = walls[math.random(#walls)]
local cloneWallSW = randomWallSW:Clone()
cloneWallSW.Parent = game.Workspace.Maze
cloneWallSW:PivotTo(cloneWallSW:GetPivot() -Vector3.new(math.abs(
cloneWallS.PrimaryPart.Position.X -cloneWallSW.PrimaryPart.Position.X)), 0, 0)
cloneWallSW:PivotTo(cloneWallSW:GetPivot() -Vector3.new(0, 0,
math.abs(flexibleCounterSW)))
until flexibleCounterSW == cloneCounterSW *moveDistance
for serial, value in pairs(southWestPositions) do
table.remove(southWestPositions, serial)
end
flexibleCounterSW = 0
cloneCounterSW = cloneCounterSW +1
end
--Southeast
if cloneCounterSE == 0 then
cloneCounterSE = cloneCounterSE +1
else
repeat
flexibleCounterSE = flexibleCounterSE +moveDistance
table.insert(southEastPositions, cloneCounterSE, cloneWallS.PrimaryPart.Position.Z
-flexibleCounterSE)
local randomWallSE = walls[math.random(#walls)]
local cloneWallSE = randomWallSE:Clone()
cloneWallSE.Parent = game.Workspace.Maze
cloneWallSE:PivotTo(cloneWallSE:GetPivot() -Vector3.new(math.abs(
cloneWallS.PrimaryPart.Position.X -cloneWallSE.PrimaryPart.Position.X)), 0, 0)
cloneWallSE:PivotTo(cloneWallSE:GetPivot() +Vector3.new(0, 0,
math.abs(flexibleCounterSE)))
until flexibleCounterSE == cloneCounterSE *moveDistance
for serial, value in pairs(southEastPositions) do
table.remove(southEastPositions, serial)
end
flexibleCounterSE = 0
cloneCounterSE = cloneCounterSE +1
end
--Westnorth
if cloneCounterWN == 0 then
cloneCounterWN = cloneCounterWN +1
else
repeat
flexibleCounterWN = flexibleCounterWN +moveDistance
table.insert(westNorthPositions, cloneCounterWN, cloneWallW.PrimaryPart.Position.X
-flexibleCounterWN)
local randomWallWN = walls[math.random(#walls)]
local cloneWallWN = randomWallWN:Clone()
cloneWallWN.Parent = game.Workspace.Maze
cloneWallWN:PivotTo(cloneWallWN:GetPivot() -Vector3.new(0, 0,
math.abs(cloneWallW.PrimaryPart.Position.Z -cloneWallWN.PrimaryPart.Position.Z)))
cloneWallWN:PivotTo(cloneWallWN:GetPivot() +Vector3.new(math.abs(
flexibleCounterWN)), 0, 0)
until flexibleCounterWN == cloneCounterWN *moveDistance
for serial, value in pairs(westNorthPositions) do
table.remove(westNorthPositions, serial)
end
flexibleCounterWN = 0
cloneCounterWN = cloneCounterWN +1
end
--Westsouth
if cloneCounterWS == 0 then
cloneCounterWS = cloneCounterWS +1
else
repeat
flexibleCounterWS = flexibleCounterWS +moveDistance
table.insert(westSouthPositions, cloneCounterWS, cloneWallW.PrimaryPart.Position.X
-flexibleCounterWS)
local randomWallWS = walls[math.random(#walls)]
local cloneWallWS = randomWallWS:Clone()
cloneWallWS.Parent = game.Workspace.Maze
cloneWallWS:PivotTo(cloneWallWS:GetPivot() -Vector3.new(0, 0,
math.abs(cloneWallW.PrimaryPart.Position.Z -cloneWallWS.PrimaryPart.Position.Z)))
cloneWallWS:PivotTo(cloneWallWS:GetPivot() -Vector3.new(math.abs(
flexibleCounterWS)), 0, 0)
until flexibleCounterWS == cloneCounterWS *moveDistance
for serial, value in pairs(westSouthPositions) do
table.remove(westSouthPositions, serial)
end
flexibleCounterWS = 0
cloneCounterWS = cloneCounterWS +1
end
--Eastnorth
if cloneCounterEN == 0 then
cloneCounterEN = cloneCounterEN +1
else
repeat
flexibleCounterEN = flexibleCounterEN +moveDistance
table.insert(eastNorthPositions, cloneCounterEN, cloneWallE.PrimaryPart.Position.X
-flexibleCounterEN)
local randomWallEN = walls[math.random(#walls)]
local cloneWallEN = randomWallEN:Clone()
cloneWallEN.Parent = game.Workspace.Maze
cloneWallEN:PivotTo(cloneWallEN:GetPivot() +Vector3.new(0, 0,
math.abs(cloneWallE.PrimaryPart.Position.Z -cloneWallEN.PrimaryPart.Position.Z)))
cloneWallEN:PivotTo(cloneWallEN:GetPivot() +Vector3.new(math.abs(
flexibleCounterEN)), 0, 0)
until flexibleCounterEN == cloneCounterEN *moveDistance
for serial, value in pairs(eastNorthPositions) do
table.remove(eastNorthPositions, serial)
end
flexibleCounterEN = 0
cloneCounterEN = cloneCounterEN +1
end
--Eastsouth
if cloneCounterES == 0 then
cloneCounterES = cloneCounterES +1
else
repeat
flexibleCounterES = flexibleCounterES +moveDistance
table.insert(eastSouthPositions, cloneCounterES, cloneWallE.PrimaryPart.Position.X
-flexibleCounterES)
local randomWallES = walls[math.random(#walls)]
local cloneWallES = randomWallES:Clone()
cloneWallES.Parent = game.Workspace.Maze
cloneWallES:PivotTo(cloneWallES:GetPivot() +Vector3.new(0, 0,
math.abs(cloneWallE.PrimaryPart.Position.Z -cloneWallES.PrimaryPart.Position.Z)))
cloneWallES:PivotTo(cloneWallES:GetPivot() -Vector3.new(math.abs(
flexibleCounterES)), 0, 0)
until flexibleCounterES == cloneCounterES *moveDistance
for serial, value in pairs(eastSouthPositions) do
table.remove(eastSouthPositions, serial)
end
flexibleCounterES = 0
cloneCounterES = cloneCounterES +1
end
end
storage.Maze.GeneratedMaze:FireClient()
Now, when these walls get generated I have to make the walls merge with each other so that they form a seamless array of walls.
But of course, this would obviously cause Z-Fighting, which is recognized as an event that happens when two textures are “fighting” because they perfectly overlap. I want to create a randomly generated maze that does not cause intense lag or show Z-Fighting.
Examples of the Z-Fighting that occurs:
Now, as I don’t want the maze to cause intense lag, unions or negative parts are out of the question, as I have already tried them and almost received the crashing of my Roblox Studio, and as they are known to be very laggy in the first place. I have tried offsetting, but changing the generated walls’ position by even a small margin like 0.001 studs or giving the types of walls different offsets only solves some of the Z-Fighting and not all of it. I have went through many Roblox Wiki pages and Dev forum posts and haven’t found a viable solution yet.
Note that I want to avoid using 3-D software but if the problem can’t be solved by scripting, I will if I have to.
(Also would this be more of a Scripting Support topic or the people over there would be able to help me more? Tell me if it is.)
Thanks for reading.