Any way to circumvent rooms generating in a circle?

Bit of an odd question, but when I generate my rooms there’s a slight chance they can go full circle

this, in turn, makes my script not generate the rest of the rooms. Are there any tips on fixing this?

function module.GenerateRooms(iRooms)
	local function getAllEndpoints()
		local pointsToInclude = {}
		for _, room in ipairs(workspaceRooms:GetDescendants()) do
			for _, child in ipairs(room:GetDescendants()) do
				if child:IsA("BasePart") and (child.Name == "EndPoint" or child.Name == "StartPoint") then
					table.insert(pointsToInclude, child)
				end
			end
		end
		return pointsToInclude
	end

	local function getNextRoomName()
		local roomCount = #workspaceRooms:GetChildren()
		return tostring(roomCount + 1)
	end

-- vvv THIS is supposed to be the actual "generating part" of the script
	while #workspaceRooms:GetChildren() < iRooms do
		local currentRooms = workspaceRooms:GetChildren()
		--print("Current room count: " .. #currentRooms)

		if #currentRooms == 0 then
			print("No rooms found. Creating the first room.")
			local firstRoom = SelectRoom():Clone()
			firstRoom.Name = "1"
			firstRoom.Parent = workspaceRooms
			local endPoint = firstRoom:FindFirstChild("EndPoint")
			if endPoint then
				firstRoom:PivotTo(endPoint.CFrame)
				print("First room placed at: " .. firstRoom.Name)
			end
			continue
		end

		-- Get all available endpoints across all rooms
		local allEndpoints = getAllEndpoints()
		--print("Total available endpoints: " .. #allEndpoints)

		-- Track if any room has been successfully placed
		local roomPlaced = false

		for _, endPoint in ipairs(allEndpoints) do
			-- Create a new room and try to place it
			local newRoom = SelectRoom():Clone()
			newRoom.Name = getNextRoomName()
			newRoom.Parent = workspaceRooms
			if newRoom:FindFirstChild("Humanoid") then print("B") end
			newRoom:PivotTo(endPoint.CFrame)

			local boundary = newRoom:FindFirstChild("Boundary") :: Part
			if boundary then
				local pointsToExclude = getAllEndpoints()  -- Exclude all endpoints when checking overlaps
				table.insert(pointsToExclude, newRoom)

				local overlapParams = OverlapParams.new()
				overlapParams.FilterType = Enum.RaycastFilterType.Exclude
				overlapParams.FilterDescendantsInstances = pointsToExclude

				local overlappingParts = workspace:GetPartsInPart(boundary, overlapParams)

				if #overlappingParts == 0 then
					--print("Room placed successfully without overlap at " .. newRoom.Name)
					roomPlaced = true
					break  -- Exit the loop after successful placement
				else
					--warn("Overlap detected, room not placed: " .. newRoom.Name)
					newRoom:Destroy()  -- Destroy the room if it overlaps
				end
			else
				warn("Boundary not found in new room: " .. newRoom.Name)
			end
		end

		-- If no room was placed, output a warning
		if not roomPlaced then
			warn("No room could be placed. All endpoints tried.")
			break
		end
	end
-- ^^^ THIS is supposed to be the actual "generating part" of the script

	-- Final check for the total number of rooms generated
	if #workspaceRooms:GetChildren() < iRooms then
		warn("Not all rooms generated. Total generated: " .. #workspaceRooms:GetChildren() .. " out of " .. iRooms)
	end
end

You can set the last room or two generated as local variables during generation, and check whether they’re turning in the same direction as the previous room(s).

As you generate new rooms, update the variable for the last room(s) generated. If the new room chosen from the list turns in the same direction again, re-roll for a new room until it results in a different room type.

1 Like

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