Fixing models overlapping when creating ores in workspace

Hello! I have written a procedurally generated ore spawning system and i have stumbled upon a small problem. There is a chance that sometimes models might overlap with eachother and im trying to figure out how to fix it.

I already tried some solutions but none of them seem to work so now im asking for help here.

Here’s the function from a module that handles ore’s creation and spawning:

function oreModule.spawnOre(Info:SharedTable, Parent:Folder, Location:BasePart) : Model
	local m = Instance.new("Model")
	m.Name = Info.Name

	local pp = Instance.new("Part", m)
	pp.Color = Info.Colors[math.random(1,#Info.Colors)]
	pp.Material = Info.Materials[math.random(1,#Info.Materials)]
	pp.Anchored = true

	local sizex = math.random(Info.SizeX[1]*100, Info.SizeX[2]*100)/100
	local sizey = math.random(Info.SizeY[1]*100, Info.SizeY[2]*100)/100
	local sizez = math.random(Info.SizeZ[1]*100, Info.SizeZ[2]*100)/100

	local size = Vector3.new(sizex*Info.SizeMultiplier, sizey*Info.SizeMultiplier, sizez*Info.SizeMultiplier)
	pp.Size = size
	pp.Orientation = Vector3.new(math.random(-10,10)/2, math.random(0,360), math.random(-10,10)/2)

	pp.Position = Location.Position + Vector3.new(math.random(-Location.Size.X/2, Location.Size.X/2), math.random(5,10)/12, math.random(-Location.Size.Z/2, Location.Size.Z/2))
	
	local am = math.random(Info.AdditionalPieces[1], Info.AdditionalPieces[2])
	
	for i=1, am do
		local p = Instance.new("Part", m)
		p.Color = Info.Colors[math.random(1,#Info.Colors)]
		p.Material = Info.Materials[math.random(1,#Info.Materials)]
		p.Anchored = true

		sizex = math.random(Info.SizeX[1]*100, Info.SizeX[2]*100)/100
		sizey = math.random(Info.SizeY[1]*100, Info.SizeY[2]*100)/60
		sizez = math.random(Info.SizeZ[1]*100, Info.SizeZ[2]*100)/100

		p.Size = Vector3.new(sizex*1.5, sizey, sizez*1.5)
		p.Orientation = Vector3.new(math.random(-10,10)/2, math.random(-10,10)/2, math.random(-10,10)/2)

		-- offset stuff ( i have no idea how this works )
		local yoffset = math.random(-6,-3)/6
		local sideX = math.random(0,3)
		local sideZ = math.random(0,1)

		if sideX == 0 then
			p.Position = pp.Position + Vector3.new(pp.Size.X/2,yoffset,math.random(-10,10)/12)
		elseif sideX == 1 then
			p.Position = pp.Position + Vector3.new(-pp.Size.X/2,yoffset,math.random(-10,10)/12)
		elseif sideZ == 0 then
			p.Position = pp.Position + Vector3.new(math.random(10,10)/12, yoffset, -pp.Size.Z/2)
		else
			p.Position = pp.Position + Vector3.new(math.random(-10,10)/12, yoffset, -pp.Size.Z/2)
		end
	end

	m.PrimaryPart = pp
	m.Parent = Parent or workspace
	m:ScaleTo(math.random(Info.RandomSize[1]*100, Info.RandomSize[2]*100)/100)

	return m
end
1 Like

Your offset code is incorrect. You should be referencing the part’s size when calculating the offset.

Tell me if this works:

function oreModule.spawnOre(Info:SharedTable, Parent:Folder, Location:BasePart) : Model
	local m = Instance.new("Model")
	m.Name = Info.Name

	local pp = Instance.new("Part", m)
	pp.Color = Info.Colors[math.random(1,#Info.Colors)]
	pp.Material = Info.Materials[math.random(1,#Info.Materials)]
	pp.Anchored = true

	local sizex = math.random(Info.SizeX[1]*100, Info.SizeX[2]*100)/100
	local sizey = math.random(Info.SizeY[1]*100, Info.SizeY[2]*100)/100
	local sizez = math.random(Info.SizeZ[1]*100, Info.SizeZ[2]*100)/100

	local size = Vector3.new(sizex*Info.SizeMultiplier, sizey*Info.SizeMultiplier, sizez*Info.SizeMultiplier)
	pp.Size = size
	pp.Orientation = Vector3.new(math.random(-10,10)/2, math.random(0,360), math.random(-10,10)/2)

	pp.Position = Location.Position + Vector3.new(math.random(-Location.Size.X/2, Location.Size.X/2), math.random(5,10)/12, math.random(-Location.Size.Z/2, Location.Size.Z/2))

	local am = math.random(Info.AdditionalPieces[1], Info.AdditionalPieces[2])

	for i=1, am do
		local p = Instance.new("Part", m)
		p.Color = Info.Colors[math.random(1,#Info.Colors)]
		p.Material = Info.Materials[math.random(1,#Info.Materials)]
		p.Anchored = true

		sizex = math.random(Info.SizeX[1]*100, Info.SizeX[2]*100)/100
		sizey = math.random(Info.SizeY[1]*100, Info.SizeY[2]*100)/60
		sizez = math.random(Info.SizeZ[1]*100, Info.SizeZ[2]*100)/100

		p.Size = Vector3.new(sizex*1.5, sizey, sizez*1.5)
		p.Orientation = Vector3.new(math.random(-10,10)/2, math.random(-10,10)/2, math.random(-10,10)/2)

		-- offset stuff
		local xOffset = math.random(-pp.Size.X/2, pp.Size.X/2)
		local zOffset = math.random(-pp.Size.Z/2, pp.Size.Z/2)
		local yoffset = math.random(-6,-3)/6

		p.Position = pp.Position + Vector3.new(xOffset, yoffset, zOffset)
	end

	m.PrimaryPart = pp
	m.Parent = Parent or workspace
	m:ScaleTo(math.random(Info.RandomSize[1]*100, Info.RandomSize[2]*100)/100)

	return m
end

Also, you don’t need to include 1 in math.random, because it automatically picks a number between 1 and whatever number you specify.

For example:

Instead of:

math.random(1, 100)

You can do:

math.random(100)
1 Like

i mean, thank you for pointing those things out but thats not quite what i asked for :sweat_smile:

i was wondering about models overlapping when i set their position to a random one.