The terrain generator won't generate trees because it detects... nil?

I am working on a script that generates a voxel world, but the trees won’t generate at all because it detects… nothing?

(This illustration shows how I know that the generator is detecting nil using the print() function)
butwhy

And now I will place my code for you to analyze and help me fix.

local BLOCK_SIZE = 3.054
local MAP_SIZE = Vector3.new(100, 64, 100)
local MOUNTAIN_INTENSITY = 6

seed = workspace.SEED.Value
noisescale = 1/64
amplitude = 10

function get_density(v3)
	local noise_value = math.noise(v3.X * noisescale, v3.Y * noisescale, v3.Z * noisescale + seed)*amplitude
	local height_bonus = -v3.Y / MOUNTAIN_INTENSITY + 7

	return noise_value + height_bonus
end

function is_on_boundary(v3)
	if get_density(v3) <= 0 - 10 then
		return false
	end

	for _, dirEnum in pairs(Enum.NormalId:GetEnumItems()) do
		local dir = Vector3.FromNormalId(dirEnum)
		local neighbor_pos = v3 + dir * BLOCK_SIZE
		local neighbor_density = get_density(neighbor_pos)

		if neighbor_density <= 0 then
			return true
		end
	end

	return false
end

```for x = 0, MAP_SIZE.X do
	for y = 0, MAP_SIZE.Y do
		for z = 0, MAP_SIZE.Z do
			local block_pos = Vector3.new(x, y, z) * BLOCK_SIZE
			local density = get_density(block_pos)

			if density > 0 and is_on_boundary(block_pos) then
				local block = script.Block:Clone()
				block.Parent = game.Workspace
				block.CFrame = CFrame.new(block_pos)
				if y > 25 then
					local c = game.ReplicatedStorage.Blocks.Nature.Snow:Clone()
					c:SetPrimaryPartCFrame(block.CFrame)
					c.Parent = workspace.TerrainFolder
					block:Destroy()
				elseif y < 23 and y > 10 then
					local c = game.ReplicatedStorage.Blocks.Nature.Grass:Clone()
					c:SetPrimaryPartCFrame(block.CFrame)
					c.Parent = workspace.TerrainFolder
					block:Destroy()
					local trees = game.ReplicatedStorage.Structures.Trees:GetChildren()


					if math.random(1, 1) then
						local tree = trees[math.random(1, #trees)]:Clone()

						local Region = Region3.new(Vector3.new(c.PrimaryPart.Position.X - tree.Hitbox.Size.X,c.PrimaryPart.Position.Y + 10,c.PrimaryPart.Position.Z - tree.Hitbox.Size.Z),Vector3.new(c.PrimaryPart.Position.X + tree.Hitbox.Size.X,c.PrimaryPart.Position.Y + tree.Hitbox.Size.Y,c.PrimaryPart.Position.Z + tree.Hitbox.Size.Z))
						local touching = game.Workspace:FindPartsInRegion3(Region,c,math.huge) -- table with parts in region3, ignoring hitbox

						if touching == nil or touching.Name == "nil" then
							print("Nothing obstructed the tree!")
							tree.Parent = workspace
							tree:SetPrimaryPartCFrame(c.Dirt.CFrame)
						elseif touching ~= nil then
							print(touching.Name)
							tree:Destroy()
						end


					end

				elseif y <= 10 then
					local p = Instance.new("Part")
					p.Parent = workspace.TerrainFolder
					p.Size = Vector3.new(3.054, 0.005, 3.054)
					p.Anchored = true
					p.CanCollide = false
					p.Transparency = 0.01
					p.Reflectance = 0.1
					p.CFrame = CFrame.new(block.CFrame.X, 30, block.CFrame.Z)
					p.Material = Enum.Material.SmoothPlastic
					p.Name = "Water"
					p.BrickColor = BrickColor.new("Electric blue")

					local c = game.ReplicatedStorage.Blocks.Nature.Sand:Clone()
					c:SetPrimaryPartCFrame(block.CFrame)
					c.Parent = workspace.TerrainFolder
					block:Destroy()
				else
					local c = game.ReplicatedStorage.Blocks.Nature.Stone:Clone()
					c:SetPrimaryPartCFrame(block.CFrame)
					c.Parent = workspace.TerrainFolder
					block:Destroy()
				end
			end
		end
	end
	wait(0.2)
end
1 Like

FindPartsInRegion3 is returning an array. I think it’s printing nil because the array itself has no name.

1 Like

Adding on to this, you can loop through the array and then filter it through your conditional statement to create a new tree.

I have no Idea how I can filter an array

EDIT: Now that I think about it, I have not a single Idea what an array is

An array is a type of table. Basically it’s just a list of items. Can be objects, colors, words, numbers, etc
local array = {Color3.fromRGB(255,255,255), workspace.Baseplate, "strings strings"}

So the function FindPartsinRegion3 is returning the list of items in the given area. You can use a simple loop to loop through the items in the list.

local array = {"list_item","list_item2"}
for index = 1, #array do
    print(array[index])
end
1 Like

I know what I must do, but I don’t know if I have the strength ability how to do it

I genuinely dont know what to do, I tried everything and it still detects nil

What exactly do I add to the code? I tried everything and it still detects nil