How could i improve my random map / maze generator?

so i made a very primitive random maze generator for my game and it works fine, but it has one major problem, its really slow and i dont really have any idea what i could do.

here is my current script i just made and a video:

local mapSizeX = 10
local mapSizeY = 10
local segmentStart = workspace.Map.Segments.SegmentStart

for length = 1,mapSizeX do
	
	for height = 1,mapSizeY do
		
		if length == 1 and height == 1 then
			
			print("segment start")
			
		else
			
			local segmentClone = workspace.Map.Segments.SegmentStart:Clone()
			segmentClone.Name = "Segment"
			segmentClone.Parent = workspace.Map.Segments
			segmentClone:SetPrimaryPartCFrame(CFrame.new(segmentClone.PrimaryPart.Position+Vector3.new((length-1)*51,(height-1)*51,0)))
			segmentClone.Height.Value = height
			segmentClone.Length.Value = length
			wait()
			
		end
		
	end
	
end

function getSegment(length,height)
	
	local segment
	
	for i,v in pairs(workspace.Map.Segments:GetChildren()) do
		
		if v.Length.Value == length and v.Height.Value == height then
			
			segment = v
			
		end
		
	end
	
	if segment ~= nil then
		
		return segment
		
	else
		
		return "N/A"
		
	end
	
end

local segmentsVisited = {}

function getNeighbours(segment)
	
	local neighbours = {}
	
	table.insert(neighbours,getSegment(segment.Length.Value + 1, segment.Height.Value))
	table.insert(neighbours,getSegment(segment.Length.Value - 1, segment.Height.Value))
	table.insert(neighbours,getSegment(segment.Length.Value, segment.Height.Value - 1))
	table.insert(neighbours,getSegment(segment.Length.Value, segment.Height.Value + 1))
	
	local neighboursFiltered = {}
	
	for i,v in pairs(neighbours) do
		
		if v ~= "N/A" then
			
			table.insert(neighboursFiltered,v)
			
		end
		
	end
	
	return neighboursFiltered
	
end

function checkSegment(segment)
	
	print("workin")
	local neighbours = getNeighbours(segment)
	local chosenNeighbour = neighbours[math.random(1,#neighbours)]

	if not table.find(segmentsVisited,chosenNeighbour) then

		if chosenNeighbour.Height.Value == segment.Height.Value then

			if chosenNeighbour.Length.Value < segment.Length.Value then

				if segment:FindFirstChild("WallLeft") then

					segment.WallLeft:Destroy()

				end

				if chosenNeighbour:FindFirstChild("WallRight") then

					chosenNeighbour.WallRight:Destroy()

				end

			else

				if segment:FindFirstChild("WallRight") then

					segment.WallRight:Destroy()

				end

				if chosenNeighbour:FindFirstChild("WallLeft") then

					chosenNeighbour.WallLeft:Destroy()

				end

			end

		else

			if chosenNeighbour.Height.Value < segment.Height.Value then

				if segment:FindFirstChild("WallDown") then

					segment.WallDown:Destroy()

				end

				if chosenNeighbour:FindFirstChild("WallUp") then

					chosenNeighbour.WallUp:Destroy()

				end

			else
				
				if segment:FindFirstChild("WallUp") then
					
					segment.WallUp:Destroy()
					
				end
				
				if chosenNeighbour:FindFirstChild("WallDown") then

					chosenNeighbour.WallDown:Destroy()

				end

			end

		end

		table.insert(segmentsVisited,chosenNeighbour)
		chosenNeighbour.Back.Color = Color3.fromRGB(255, 0, 0)

	end
	
	wait()
	
	if #segmentsVisited ~= mapSizeX*mapSizeY then
		
		checkSegment(chosenNeighbour)
		
	else
		
		for i,v in pairs(segmentsVisited) do

			v.Back.Color = Color3.fromRGB(0,255,0)
			wait()

		end
		
		for i,v in pairs(segmentsVisited) do

			v.Back.Color = Color3.fromRGB(99, 95, 98)
			wait()

		end
		
		workspace.Map.TemporaryWalls:Destroy()

	end
	
end

checkSegment(segmentStart)

This looks to be using a random walker. Since you rely on it having to touch every tile, it’s going to be slow. But I do have an idea to speed it up.

Right now you have a wait for every step. Just before this line of code

if #segmentsVisited ~= mapSizeX*mapSizeY then

That’s going to be the major slowdown of your code.

I would do this. Create a local variable outside the function called lastYield and set it to tick()

Then in place of the wait above that if statement do

if tick() - lastYield > 0.15 then
    wait()
lastYield = tick()
end

Basically what this does this makes it so you don’t have to wait every single time your algorithm takes a misstep. It will only do a wait when it needs to.

I should also note that I don’t think recursion is the best thing to use for this algorithm. The reason is because you’re going to have it error out with large map sizes.

1 Like

It looks good but in the video, not “hard”. It looks very simple to finish.

1 Like

thanks! that is quite an improvement

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.