Procedurally generated maze not working as intended with a round system

I have this round system and I combined it with this procedurally generating maze system, however after every round it prints the error “10,10 is not a valid member of Folder “Workspace.Grid””

The maze generates normally on the first round, then it prints the error, then the maze generates but stops

I have tried to reset the current cell at the end of the maze generation script but it didn’t work.

CurrentPosX = 0
CurrentPosY = 0

I can’t find any solutions to this issue, please help!





Video

Round System:

local Players = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")

local INTERMISSION_TIME = 5
local ROUND_END_TIME = 5
local ROUND_TIME = 15
local MIN_PLAYERS = 1

local roundActive = false
local intermission = false
local AlivePlayers = {}

local function TeleportPlayers(cframe)
	local players = Players:GetPlayers()
	for i, player in players do
		if not player.Character then continue end
		player.Character:PivotTo(cframe)
	end
end

local function Countdown(duration)
	for i = duration, 1, -1 do
		if roundActive == false and not intermission then return end -- end countdown early
		workspace:SetAttribute("Clock", i)
		task.wait(1)
	end
end

-- checks if any survivors are still alive
local function CheckRoundEnd()
	local aliveSurvivors = 0

	for player, alive in pairs(AlivePlayers) do
		if alive and player:GetAttribute("Role") == "Survivor" then
			aliveSurvivors += 1
		end
	end

	-- survivors all dead
	if aliveSurvivors <= 0 and roundActive == true then
		print("All survivors eliminated!")
		roundActive = false
		workspace:SetAttribute("GenerateMap", false)
	end
end

local function RegisterHumanoid(player)
	if not player.Character then return end
	local hum = player.Character:FindFirstChildOfClass("Humanoid")
	if not hum then return end

	AlivePlayers[player] = true

	hum.Died:Connect(function()
		AlivePlayers[player] = false
		CheckRoundEnd()
	end)
end

local function Intermission()
	local players = Players:GetPlayers()
	
	intermission = true
	print("INTERMISSION")
	workspace:SetAttribute("GenerateMap", false)
	workspace:SetAttribute("Status", "Intermission")
	
	for i, plr in pairs(players) do
		plr:LoadCharacter()
		plr:SetAttribute("Role", "Lobby")
		print("haha")
	end	
	
	--TeleportPlayers(workspace.SpawnLocation.CFrame * CFrame.new(math.random(-5, 5), 5, math.random(-5, 5)))
	Countdown(INTERMISSION_TIME)
end

local function RunGame(map)
	local spawnLocation = workspace.Grid:WaitForChild("Spawn").CFrame

	local players = Players:GetPlayers()
	local chosen = players[math.random(1, #players)]
	local weapon = game.ServerStorage["Fire Axe"]:Clone()

	weapon.Parent = chosen.Backpack

	chosen:SetAttribute("Role", "Exterminator")
	chosen.PlayerGui.GameUI.RoleUI.RoleGiven.Text = "Exterminator"
	chosen.PlayerGui.GameUI.RoleUI.RoleGiven.TextColor3 = Color3.fromRGB(255, 0, 0)
	chosen.PlayerGui.GameUI.RoleUI.Visible = true

	for i, plr in pairs(players) do
		if plr ~= chosen then
			plr:SetAttribute("Role", "Survivor")
			plr.PlayerGui.GameUI.RoleUI.RoleGiven.Text = "Survivor"
			plr.PlayerGui.GameUI.RoleUI.RoleGiven.TextColor3 = Color3.fromRGB(0, 255, 0)
			plr.PlayerGui.GameUI.RoleUI.Visible = true
		end
	end	

	print("GAME BEGIN")
	workspace:SetAttribute("Status", "Round")

	for _, p in pairs(players) do
		RegisterHumanoid(p)
	end
	
	intermission = false
	roundActive = true
	task.spawn(function()
		task.wait(0.5)
		TeleportPlayers(spawnLocation)
	end)

	Countdown(ROUND_TIME)
	task.wait(ROUND_END_TIME)
	roundActive = false
	intermission = true

	print("ROUND OVER")
	weapon:Destroy()
	
	local partToKeep = workspace.Grid:FindFirstChild("Spawn") -- The specific part to keep
	local partToKeep2 = workspace.Grid:FindFirstChild("Roof")

	for _, child in ipairs(workspace.Grid:GetChildren()) do
		if child ~= partToKeep and child ~= partToKeep2 then
			child:Destroy()
		end
	end

	--map:Destroy()
end

Players.PlayerAdded:Connect(function(player)
	player:SetAttribute("Role", "Lobby")

	player.CharacterAdded:Connect(function()
		task.wait(0.1)
		RegisterHumanoid(player)
	end)
end)

while true do
	if #Players:GetPlayers() >= MIN_PLAYERS then
		Intermission()

		workspace:SetAttribute("Status", "Loading map...")
		workspace:SetAttribute("GenerateMap", true)
 --[[	local maps = RS.Maps:GetChildren()
		local randomMaps = maps[math.random(#maps)]
		local newMap = randomMaps:Clone()
]]
		task.wait(10)
		--newMap.Parent = workspace
		task.wait(1)

		RunGame()
	else
		workspace:SetAttribute("Status", "Waiting for players...")
		task.wait(1)
	end
end

Maze Generator:

--Made by gibblesham2/GibbleDev

--This generator can use a lot of optimization, but here it is.

local Seed = math.random(1, 5000) --The "key" used to generate the maze.
local SizeX = math.random(10, 15) --How many cells on the x axis.
local SizeY = SizeX --How many cells on the y axis.

local Control = math.pi --This is just a random decimal that makes sure that the noise doesn't return 0.

local MazeModel = game.Workspace.Grid --This is the place where the segments of the maze go after it's generated.
local SpawnPart = MazeModel.Spawn

local Scale = script.Segment.WallL.Size.Y --How much the maze scales up.

print("Seed:".. Seed)
print("Size:".. SizeX, SizeY)

--Grid Setup

--game.Workspace.Baseplate:Destroy()

local function Cloning()
	for x = 1,SizeX do
		for y = 1,SizeY do
			local clone = script.Segment:Clone()
			clone:SetPrimaryPartCFrame(CFrame.new(x*Scale-(SizeX*Scale/2)-Scale/2,Scale/2,y*Scale-(SizeY*Scale/2)-Scale/2) - Vector3.new(0, 0, 500)) --This makes the grid fully centered at (0,0,0)

			clone.Name = y..","..x --I flipped them so that the grid would be numbered nicely.

			clone.Parent = MazeModel

		end
	end
end

NumberCompleted = 0 --The number of cells gone into.

Moves = {} --The moves that have happened so far.

CurrentPosX = 1 --Current X position of generator.
CurrentPosY = 1 --Current Y position of generator.


local function DeleteWall(CurrentCell,ChosenCell,CellLeft,CellRight,CellUp,CellDown)
	
	--This function deletes the wall between the chosen part, and the current cell.
	
	if ChosenCell == CellLeft then
		CellLeft.WallL:Destroy()
		CurrentCell.WallR:Destroy() 

		CurrentPosX = CurrentPosX-1	

		Moves[#Moves+1] = "B"
	elseif ChosenCell == CellRight then
		CellRight.WallR:Destroy()
		CurrentCell.WallL:Destroy() 

		CurrentPosX = CurrentPosX+1

		Moves[#Moves+1] = "T"
	elseif ChosenCell == CellUp then
		CellUp.WallB:Destroy()
		CurrentCell.WallT:Destroy() 

		CurrentPosY = CurrentPosY+1

		Moves[#Moves+1] = "R"
	elseif ChosenCell == CellDown then
		CellDown.WallT:Destroy()
		CurrentCell.WallB:Destroy() 

		CurrentPosY = CurrentPosY-1

		Moves[#Moves+1] = "L"
	end
end

local function BackTrack()
	
	--This function repeats the turns made, but backwards until we find a cell that has a neighbor that hasn't been checked yet.
	
	local Found = false
	
	repeat 
		local Move = Moves[#Moves]
		if Move == "T" then
			CurrentPosX = CurrentPosX-1	

			Moves[#Moves] = nil
		elseif Move == "B" then
			CurrentPosX = CurrentPosX+1	

			Moves[#Moves] = nil
		elseif Move == "L" then
			CurrentPosY = CurrentPosY+1

			Moves[#Moves] = nil
		elseif Move == "R" then
			CurrentPosY = CurrentPosY-1

			Moves[#Moves] = nil
		end

		local CellLeft = MazeModel:FindFirstChild(CurrentPosY .. "," .. (CurrentPosX-1))
		local CellRight = MazeModel:FindFirstChild(CurrentPosY .. "," .. (CurrentPosX+1))
		local CellUp = MazeModel:FindFirstChild((CurrentPosY+1) .. "," .. CurrentPosX)
		local CellDown = MazeModel:FindFirstChild((CurrentPosY-1) .. "," .. CurrentPosX)

		Cells = {}

		if CellLeft then
			if CellLeft.GoneInto.Value == false then
				Cells[#Cells+1]=CellLeft
			end
		end

		if CellRight then
			if CellRight.GoneInto.Value == false then
				Cells[#Cells+1]=CellRight
			end
		end

		if CellUp then
			if CellUp.GoneInto.Value == false then
				Cells[#Cells+1]=CellUp
			end
		end

		if CellDown then
			if CellDown.GoneInto.Value == false then
				Cells[#Cells+1]=CellDown
			end
		end
		
		if #Cells>0 then
			Found = true
		end
	until
	Found == true
end

local function Generation()
	local Roof = script.Roof:Clone()
	print(CurrentPosX)
	print(CurrentPosY)
	while task.wait() do --Loops until the Maze is completely generated.
		local CurrentCell = MazeModel[CurrentPosY..","..CurrentPosX]

		local CellLeft = MazeModel:FindFirstChild(CurrentPosY..","..CurrentPosX-1)
		local CellRight = MazeModel:FindFirstChild(CurrentPosY..","..CurrentPosX+1)
		local CellUp = MazeModel:FindFirstChild(CurrentPosY+1 ..","..CurrentPosX)
		local CellDown = MazeModel:FindFirstChild(CurrentPosY-1 ..","..CurrentPosX)

		local Noise = math.noise(CurrentPosX,Seed/Control,CurrentPosY)

		if Noise == 0 then
			Noise = math.noise(CurrentPosX/Control,Seed/Control,CurrentPosY)
		end

		if Noise == 0 then
			Noise = math.noise(CurrentPosX,Seed/Control,CurrentPosY/Control)
		end

		if Noise == 0 then
			Noise = math.noise(CurrentPosX/Control,Seed/Control,CurrentPosY/Control)
		end

		local Split = string.split(Noise,"")



		local Percentage = tonumber(Split[7]..Split[8]..Split[9])


		Cells = {}

		if CellLeft then
			if CellLeft.GoneInto.Value == false then
				Cells[#Cells+1]=CellLeft
			end
		end

		if CellRight then
			if CellRight.GoneInto.Value == false then
				Cells[#Cells+1]=CellRight
			end
		end

		if CellUp then
			if CellUp.GoneInto.Value == false then
				Cells[#Cells+1]=CellUp
			end
		end

		if CellDown then
			if CellDown.GoneInto.Value == false then
				Cells[#Cells+1]=CellDown
			end
		end

		if CurrentCell.GoneInto.Value == false then
			NumberCompleted = NumberCompleted+1
			print(NumberCompleted)
			CurrentCell.GoneInto.Value = true
		end

		if #Cells==1 then
			local ChosenCell = Cells[#Cells]
			DeleteWall(CurrentCell,ChosenCell,CellLeft,CellRight,CellUp,CellDown)
		elseif #Cells == 2 then
			ChosenCell = nil

			if Percentage<500 then
				ChosenCell =Cells[1]
			else
				ChosenCell =Cells[2]
			end
			DeleteWall(CurrentCell,ChosenCell,CellLeft,CellRight,CellUp,CellDown)
		elseif #Cells == 3 then
			ChosenCell = nil

			if Percentage<333 then
				ChosenCell =Cells[1]
			elseif Percentage<667 then
				ChosenCell =Cells[2]
			else
				ChosenCell =Cells[3]
			end
			DeleteWall(CurrentCell,ChosenCell,CellLeft,CellRight,CellUp,CellDown)
		elseif #Cells == 4 then
			ChosenCell = nil

			if Percentage<250 then
				ChosenCell =Cells[1]
			elseif Percentage<500 then
				ChosenCell =Cells[2]
			elseif Percentage<750 then
				ChosenCell =Cells[3]
			else
				ChosenCell =Cells[4]
			end
			DeleteWall(CurrentCell,ChosenCell,CellLeft,CellRight,CellUp,CellDown)
		elseif #Cells == 0 then

			if NumberCompleted<SizeX*SizeY then
				BackTrack()
			else
				--MazeModel["1,1"].WallB.Transparency = 1
				--MazeModel["1,1"].WallB.CanCollide = false
				--SpawnPart.Parent = MazeModel
				SpawnPart.CFrame = MazeModel["1,1"].Floor.CFrame + Vector3.new(0, 5, 0)
				
				Roof.Parent = MazeModel
				Roof.CFrame = MazeModel["8,8"].Floor.CFrame + Vector3.new(0, 23, 0)
				
				--MazeModel[SizeY..","..SizeX].WallT.Transparency = 1
				MazeModel[SizeY..","..SizeX].WallT.CanCollide = false
				--break
			end
		end
	end
	CurrentPosX = 0
	CurrentPosY = 0
end

workspace:GetAttributeChangedSignal("GenerateMap"):Connect(Cloning)
task.wait(5)
workspace:GetAttributeChangedSignal("GenerateMap"):Connect(Generation)

Can you show the 149th Line? Since the error is there

1 Like
local CurrentCell = MazeModel[CurrentPosY..","..CurrentPosX]

In the maze generation script