How to make a path generating system which has a specific spacing between roads

Hello there! I want to make a path system which generates path like in the image below. I want it so the path has a size of x, and the spacing between all pathes is dividable by for example 2x. So if each path part has a size of 25, you should be able to put blocks 50x50 without any free space. I tried to do this, but my script always makes distance of 75 or 25 between 2 roads so it leaves free space.

Can you post your script? charlimitcharlimit

It might be easier to instead have a grid of 50x50 squares and selectively turn their edges into roads, that could guarantee what you’re looking for.

Sorry for a late response, I was sleeping. Here’s the code, but I don’t think it was made good.


local minPlotSize=50
local roadSize=25
local roadLength=minPlotSize/roadSize


function GenerateRoads(xsize,zsize)
	local center={math.round(xsize/2),math.round(zsize/2)}
	local startRoads={
		--{{center[1],center[2]-1},'W'},
		--{{center[1]+1,center[2]},'N'},
		--{{center[1],center[2]+1},'E'},
		--{{center[1]-1,center[2]},'S'},
		{center,'N'},
	}
	
	for i,v in pairs(startRoads) do
		local startPos=v[1]
		local startDirection=v[2]
		local roadData={startPos,startDirection,true,1}
		table.insert(Roads,roadData)
		table.insert(headRoads,roadData)
		table.insert(Cells,{startPos,'Road',roadData})
		local road=CreateRoad(startPos)
		road.Color=Color3.new(0,0,1)
	end
	wait(2)
	while #headRoads >0 do
		--wait(1)
		AddNewRoads(xsize,zsize,headRoads[#headRoads])
	end
	
end
function AddNewRoads(xsize,zsize,road)	
	
	
	local lastRoad
	local dir = road[2]
	local pos = road[1]
	local length=road[4]
	
	if not road[3] then
		table.remove(headRoads,table.find(headRoads,road))
		return
	elseif road[4]%roadLength~=0 then
		--local newRoad=EnlargeRoad(road)
		--newRoad[5].BrickColor=BrickColor.new("Brown")
		--return
		road[3]=false
		table.remove(headRoads,table.find(headRoads,road))
	else
		road[3]=false
		table.remove(headRoads,table.find(headRoads,road))
	end
	
	local dirPosition=roadDirections[dir]
	local newPos={(pos[1]+dirPosition[1]),(pos[2]+dirPosition[2])}
	
	if CheckForCollision(newPos) then
		local collisionRoad=CheckForCollision(newPos)[3]
		print(collisionRoad)
		task.wait()
		local lastRoad=FindLastRoad(collisionRoad)
		if lastRoad ~= collisionRoad then
			--local newRoad=EnlargeRoad(lastRoad)
			--newRoad[5].BrickColor=BrickColor.new('White')
		end
	end
	
	if newPos[1]+1 >=xsize or newPos[2]+1 >=zsize or 
		newPos[1] < 0 or newPos[2] < 0 or 
		CheckForCollision(newPos) or 
		CheckForRoadAround(newPos,dir) then
	else
		lastRoad=EnlargeRoad(road)
		for i =1,roadLength-1,1 do
			lastRoad=EnlargeRoad(lastRoad)
			lastRoad[5].BrickColor=BrickColor.new('Fog')
		end

	end
	if not lastRoad then
		return
	end
	
	
	
	--lastRoad[4]+=1
	
	local maxChance=math.max(10-math.round(length),1)
	local splitChance=math.random(1,maxChance)
	
	if splitChance~=maxChance then	
	else
		lastRoad=EnlargeRoad(lastRoad)
		local dir = road[2]
		local pos = lastRoad[1]
		local length=lastRoad[4]
		
		local splitAmountChance=math.random(1,6)
		local splitAmount
		if splitAmountChance==6 then
			splitAmount=3
		elseif splitAmountChance >= 2 then
			splitAmount=2
		else
			splitAmount=1
		end
		local possibleDirections={}
		
		--Makin' list of possible direcitons
		for i,v in pairs(oppositeDirections) do
			if i~=dir then
				table.insert(possibleDirections,v)
			end
		end
		for i = 1,splitAmount,1 do
			local newDirIndex=math.random(1,#possibleDirections)
			local newDir=possibleDirections[newDirIndex]
			local dirPosition=roadDirections[newDir]
			local newPos={(pos[1]+dirPosition[1]),(pos[2]+dirPosition[2])}
			if newPos[1]+1 >=xsize or newPos[2]+1 >=zsize or 
				newPos[1] < 0 or newPos[2] < 0 or 
				CheckForCollision(newPos) or 
				CheckForRoadAround(newPos,newDir) then
				--local road
				
				--return AddNewRoads(xsize,zsize)

			else
				local newRoad=CreateRoad(newPos)
				local roadTable={newPos,newDir,true,1,newRoad,lastRoad}
				table.insert(Roads,roadTable)
				table.insert(headRoads,roadTable)
				table.insert(Cells,{newPos,'Road',roadTable})
				table.remove(possibleDirections,newDirIndex)
				newRoad.BrickColor=BrickColor.new("Gold")
				local lastRoad1=roadTable

				for i=1,roadLength-1,1 do
					lastRoad1 = EnlargeRoad(lastRoad1)
					lastRoad1[5].BrickColor=BrickColor.new("Cyan")
				end
			end
		end
	end
	return true
end

Basically this script creates a list of roads which can be enlarged and it creats new roads until the list is empty. Each iteration it creats new road and with a chance it can branch out in 1 - 3.

This is pretty complicated and you have lots of “magic”, like road[4] that make it harder to understand, as opposed to if it was something like “road.northLength”. I also think you’ve complicated it by writing the structure of an algorithm that can do a lot of things but then giving it a very specific requirement (always at least 50 space between roads). Neither of this things will directly stop it from working of course but will make it harder to work on especially if you have to come back to it after a long time not working on it.

What do you think of my previous idea about “coloring in” a grid?:

Honestly I don’t really understand that. Could you explain this idea? As I understand, if you turn part of the grid into road, the grid will have <50 size

Assume all roads are edges of a 50x50 (or any size) grid. Then, any road will have to be at least 50 units away from another parallel road. If you need there to be 50x50 between roads then you will have to add one road width to the grid size, for example 62x62.
Pick a random edge to start with. Then, choose a connected edge to add. If you want lots of straight roads you should bias towards picking an edge that is inline to the current edge, as opposed to perpendicular. Do this recursively until you fill a desired area or reach some number of desired total road length.