Help me with Infinite Map Generator

I’m trying to make an infinite map generator and it’s working perfectly except for one thing that’s been bugging me and I can’t think of a way to fix it. when the map is being generated, it creates paths like a worm path, and when a path crosses another I made the path just end, that is, a black wall so as not to cross the other building. I wanted it to join the path instead of simply ending it, making the player go back along the path where it would end up.

sorry if this seems a bit confusing. I don’t know how to explain much.

I’ll leave here my code and some prints so that it can help you understand.


This is where the truck collides with another and then puts up a wall.

CODE:

local Rarity = require(script.Parent.Rarity)

local Seed = Random.new(1234)

local Examples = workspace.Examples
Examples.Parent = game.ServerStorage


function ChooseObj(ModelObj)
	local ObjName = ModelObj and ModelObj.Name or "Front"
	
	local Dist = (workspace.Spawn.Baseplate.Position - ModelObj:GetPivot().Position).Magnitude
	table.sort(Rarity,function(a,b)
		return (a.Dist) > (b.Dist)
	end)
	
	local TableOfDist
	for i,v in pairs(Rarity) do
		if Dist > v.Dist then
			TableOfDist=v
			break
		end
	end
	local Data = TableOfDist[1][ObjName]
	local TablePriority = Data and Data[2] or {}
	
	local TotalWeight = 0
	for i,v in pairs(TableOfDist[1]) do
		TotalWeight = TotalWeight + (v[1]*(TablePriority[i] or 1))
	end
	local Chance = Seed:NextInteger(0,TotalWeight*(10^7))
	local Counter = 0
	for i,v in pairs(TableOfDist[1]) do
		Counter = Counter+(v[1]*(TablePriority[i] or 1))
		if Counter >= Chance/(10^7) then
			return i
		end
	end
end

local Range = 500

local Fronts = {}

for i,v in pairs(workspace.RenderMap:GetChildren()) do
	for i,v in pairs(v:FindFirstChild("Continue"):GetChildren()) do
		v.Transparency = 1
		v.Decal.Transparency = 1
		table.insert(Fronts,v)
	end
end

local OverLap = OverlapParams.new()
OverLap.FilterType =  Enum.RaycastFilterType.Include
OverLap.MaxParts = 1

local Statstics = {}

local OldText = ""

game["Run Service"].Heartbeat:Connect(function()
	local Players = game.Players:GetPlayers()
	for i,Player in pairs(Players) do
		local Char = Player.Character
		if not Char then continue end
		local FrontsOrder = table.clone(Fronts)
		table.sort(FrontsOrder,function(a,b)
			return (a.Position-Char.HumanoidRootPart.Position).Magnitude < ((b.Position-Char.HumanoidRootPart.Position)).Magnitude
		end)
		
		local CloseFront = FrontsOrder[1]
		table.clear(FrontsOrder)
		
		local Choose,Model
		
		local CanPut = false
		
		local Attempts = 0
		if not CloseFront or (CloseFront.Position-Char.HumanoidRootPart.Position).Magnitude > Range then continue end
		
		repeat
			if Attempts >= 50 then Model = Examples:FindFirstChild("End"):Clone() break end
			
			Choose = ChooseObj(CloseFront:FindFirstAncestorOfClass("Model"))
			Model = Examples:FindFirstChild(Choose)
			if not Model then print("Error To Find Model: "..Choose) end
			Model = Model:Clone()
			Model:PivotTo(CloseFront.CFrame)
			
			local Filter = workspace.RenderMap:GetChildren()
			table.remove(Filter,table.find(Filter,CloseFront:FindFirstAncestorOfClass("Model")))
			OverLap.FilterDescendantsInstances = {Filter}
			
			local HavePart = false
			for i,v in pairs(Model:GetDescendants()) do
				if v:IsA("BasePart") then
					local PartsInPart = workspace:GetPartsInPart(v,OverLap)
					if #PartsInPart > 0 then HavePart = true break end
				end
			end
			if HavePart then
				Model:Destroy()
				Attempts+=1
			else
				CanPut = true
			end
		until CanPut
		
		Model:PivotTo(CloseFront.CFrame)
		Model.PrimaryPart:Destroy()
		
		table.remove(Fronts,table.find(Fronts,CloseFront))
		
		for i,v in pairs(Model:FindFirstChild("Continue"):GetChildren()) do
			v.Transparency = 1
			v.Decal.Transparency = 1
			table.insert(Fronts,v)
		end
		
		Model.Parent = workspace.RenderMap
		
		if Statstics[Model.Name] then
			Statstics[Model.Name] += 1
		else
			Statstics[Model.Name] = 1
		end
	end
	local Text = "Fronts: "..#Fronts
	for i,v in pairs(Statstics) do
		Text = Text.." "..i..": "..v
	end
	if Text ~= OldText then
		OldText = Text
		print(Text)
	end
end)
1 Like

Do you have a map part you can place there? Or would you have to make a special part for each case?

special part for each case, i guess.

Best bet then would be to change one of the hallway sections to be a “close fit” and then have some function that generates special gap-filling parts between the two openings.

it would not always be just a section that the path would take

So far I’ve been testing this.

local ToUse = script.Parent.ToUse

local RayParms = RaycastParams.new()
RayParms.FilterType = Enum.RaycastFilterType.Exclude
RayParms.FilterDescendantsInstances = {ToUse}

local Left = ToUse.Left

local Origin = Left.CFrame*CFrame.new(0,0,Left.Size.Z/2)
local Rayc =  workspace:Raycast(Origin.Position,Origin.LookVector*500,RayParms)

Left.Size = Vector3.new(Left.Size.X,Left.Size.Y,Rayc.Distance)
Left.CFrame = Origin*CFrame.new(0,0,-Left.Size.Z/2)




local Right = ToUse.Right

local Origin = Right.CFrame*CFrame.new(0,0,Right.Size.Z/2)
local Rayc =  workspace:Raycast(Origin.Position,Origin.LookVector*500,RayParms)

Right.Size = Vector3.new(Right.Size.X,Right.Size.Y,Rayc.Distance)
Right.CFrame = Origin*CFrame.new(0,0,-Right.Size.Z/2)





local Floor = ToUse.Floor

local Origin = Floor.CFrame*CFrame.new(0,0,Floor.Size.Z/2)
local Rayc =  workspace:Raycast(Origin.Position,Origin.LookVector*500,RayParms)

Floor.Size = Vector3.new(Floor.Size.X,Floor.Size.Y,Rayc.Distance+5)
Floor.CFrame = Origin*CFrame.new(0,0,-Floor.Size.Z/2)



but it still doesn’t seem like something smart? I don’t know

What I have done with procedural generation has always been if there’s an issue with continuing a pathway, I just have it delete segments until it can readjust or create a stopping point

Alternatively, you could create a door wall segment for this purpose, and replace a segment on the hallway you want to connect the new hallway to, then raycast new walls and floors and generate them to predetermined points on the door segment. Might not be the cleanest fix.

1 Like