function RoomPackager.CategoriseModel(T,F)if F:FindFirstChild("\069\110\100\080\097\114\116\115")then return game.ReplicatedStorage.PathModules.Branch elseif F.Start.Position.Y<F.End.Position.Y-5 then return game.ReplicatedStorage.PathModules.GoingUp elseif F.Start.Position.Y>F.End.Position.Y+5 then return game.ReplicatedStorage.PathModules.GoingDown else return game.ReplicatedStorage.PathModules.SameHeight end end local function F(T,r)local u=T:GetChildren()for T=1,#u,1 do if u[T]:isA("\066\097\115\101\080\097\114\116")then(r:Clone()).Parent=u[T]else F(u[T],r)end end end RoomPackager.setUpBehaviours=function(T)if T:FindFirstChild("\066\101\104\097\118\105\111\117\114\115")then F(T,T.Behaviours)return end local r=T:GetChildren()for F=1,#r,1 do RoomPackager.setUpBehaviours(r[F])end end local function T(F,T,r)if T.Parent==F then return end if T.Name=="\069\110\100"and F:FindFirstChild("\069\110\100")then local r=Instance.new("\077\111\100\101\108")r.Name="\069\110\100\080\097\114\116\115"r.Parent=F T.Parent=r;(F:FindFirstChild("\069\110\100")).Parent=r elseif T.Name=="\069\110\100"and F:FindFirstChild("\069\110\100\080\097\114\116\115")then T.Parent=F:FindFirstChild("\069\110\100\080\097\114\116\115")elseif T.Name=="\069\110\100"then T.Parent=F else local u=closestParentToWorkspace(T,F)if u~=nil then if u:isA("\066\097\115\101\080\097\114\116")then local T=u:GetConnectedParts(true)for T,V in pairs(T)do if V.Name=="\069\110\100"then table.insert(r,V)else local T=closestParentToWorkspace(V,F)if T and T~=u then T.Parent=F end end end end u.Parent=F end end end function RoomPackager.PackageRoom(r,F)local u=Instance.new("\077\111\100\101\108")u.Name="\080\097\116\104"u.Parent=game.ReplicatedStorage.PathModules local V=r:RegionsFromBasePlate(F)for F=1,#V,1 do while true do local r=game.Workspace:FindPartsInRegion3(V[F],nil,200)if#r==0 then break end for F,V in pairs(r)do T(u,V,r)end end end F.Transparency=1 F.Parent=u;(u:FindFirstChild("\083\116\097\114\116",true)).Parent=u;(u:FindFirstChild("\083\116\097\114\116",true)).Transparency=1 if u:FindFirstChild("\069\110\100\080\097\114\116\115")then local F=(u:FindFirstChild("\069\110\100\080\097\114\116\115")):GetChildren()for T=1,#F,1 do F[T].Transparency=1 end else u.End.Transparency=1 end u.PrimaryPart=F u.Parent=r:CategoriseModel(u)RoomPackager.setUpBehaviours(u)return u end return RoomPackager
--Categorises a model based on the location of the start and end points of the path in the model
function RoomPackager:CategoriseModel(pathModel)
	if pathModel:FindFirstChild("EndParts") then
		return game.ReplicatedStorage.PathModules.Branch
	elseif pathModel.Start.Position.Y < pathModel.End.Position.Y - 5 then
		return game.ReplicatedStorage.PathModules.GoingUp
	elseif pathModel.Start.Position.Y > pathModel.End.Position.Y + 5 then
		return game.ReplicatedStorage.PathModules.GoingDown
	else
		return game.ReplicatedStorage.PathModules.SameHeight
	end
end

local function addBehavioursRecur(model, behaviourFolder)
	local children = model:GetChildren()
	for i = 1, #children do
		if children[i]:isA("BasePart") then
			behaviourFolder:Clone().Parent = children[i]
		else
			addBehavioursRecur(children[i], behaviourFolder)
		end
	end
end

RoomPackager.setUpBehaviours = function(roomModel)
	if roomModel:FindFirstChild("Behaviours") then
		addBehavioursRecur(roomModel, roomModel.Behaviours)
		return
	end
	local children = roomModel:GetChildren()
	for i = 1, #children do
		RoomPackager.setUpBehaviours(children[i])
	end
end

local function processPart(roomModel, part, parts)
	if part.Parent == roomModel then
		return
	end
	if part.Name == "End" and roomModel:FindFirstChild("End") then
		local endsModel = Instance.new("Model") --Used for branching the path
		endsModel.Name = "EndParts"
		endsModel.Parent = roomModel
		part.Parent = endsModel
		roomModel:FindFirstChild("End").Parent = endsModel
	elseif part.Name == "End" and roomModel:FindFirstChild("EndParts") then
		part.Parent = roomModel:FindFirstChild("EndParts")
	elseif part.Name == "End" then
		part.Parent = roomModel
	else
		local topLevelParent = closestParentToWorkspace(part, roomModel)
		if topLevelParent ~= nil then
			if topLevelParent:isA("BasePart") then
				local connectedParts = topLevelParent:GetConnectedParts(true)
				for _, connectedPart in pairs(connectedParts) do
					if connectedPart.Name == "End" then
						table.insert(parts, connectedPart)
					else
						local conTopLevelParent = closestParentToWorkspace(connectedPart, roomModel)
						if conTopLevelParent and conTopLevelParent ~= topLevelParent then
							conTopLevelParent.Parent = roomModel
						end
					end
				end
			end
			topLevelParent.Parent = roomModel
		end
	end
end

function RoomPackager:PackageRoom(roomBasePlate)
	local roomModel = Instance.new("Model")
	roomModel.Name = "Path"
	roomModel.Parent = game.ReplicatedStorage.PathModules

	local regions = self:RegionsFromBasePlate(roomBasePlate)

	for i = 1, #regions do
		--Repeatedly finds 200 parts in the region until none are left
		while true do
			local parts = game.Workspace:FindPartsInRegion3(regions[i], nil, 200)
			if #parts == 0 then
				break
			end
			for _, part in pairs(parts) do
				processPart(roomModel, part, parts)
			end
		end
	end

	--Set-up model for use in the path (parts for locating the path are made transparent)
	roomBasePlate.Transparency = 1
	roomBasePlate.Parent = roomModel
	roomModel:FindFirstChild("Start", true).Parent = roomModel
	roomModel:FindFirstChild("Start", true).Transparency = 1
	if roomModel:FindFirstChild("EndParts") then
		local ends = roomModel:FindFirstChild("EndParts"):GetChildren()
		for i = 1, #ends do
			ends[i].Transparency = 1
		end
	else
		roomModel.End.Transparency = 1
	end
	roomModel.PrimaryPart = roomBasePlate
	roomModel.Parent = self:CategoriseModel(roomModel)
	RoomPackager.setUpBehaviours(roomModel)
	return roomModel
end

return RoomPackager
