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)

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