How to add Trees to Perlin Noise?

It creates a tree some time later it creates another tree next to it.

I believe there is a problem with your calculation of x and z. When you use perlin noise, you would usually multiply the x and z values by the width and depth of the blocks respectively. Otherwise the blocks would all overlap, and so would the trees. For example, you would do this:

Part.CFrame = CFrame.new(x * Part.Size.X, y, z * Part.Size.Z)
-- ...
Tree.CFrame = CFrame.new(x * Part.Size.X, TreeY, z * Part.Size.Z)

Ideally you would have a constant outside of the for loop with the scale of the blocks,

-- Before for loop
local Scale = Part.Size

-- For loop
for x = 1, resolution do
    for z = 1, resoluation do
        -- ...
        Part.CFrame = CFrame.new(x * Scale.X, y, z * Scale.Z)
        -- ...
        Tree.CFrame = CFrame.new(x * Scale.X, TreeY, z * Scale.Z)
    end
end
1 Like

treebug2

It is making the same thing but with more space

I ran your script on my machine and did not have any problem. Here is some of the output:



(Trees are the brown cylinders and the Parts are the green blocks)


Here is my script (I changed a few things, but I commented on what I chenged):

local Part = Instance.new("Part") --For cloning
Part.Anchored = true
Part.FormFactor = "Custom"
Part.Size = Vector3.new(4,4,4)
Part.TopSurface = "Smooth"
-- Added this to make the part more visible
Part.BrickColor = BrickColor.new("Forest green")

local seed = math.random(1, 10e6)
local frequency = 3
local power = 20
-- Changed to 64 from 256 because my computer cannot handle so many parts
local resolution = 64 

local Scale = Part.Size

-- Changed from "for x = 1, resolution" to "for x = -resolution / 2, resolution / 2" in order to make map centered.
for x = -resolution / 2, resolution / 2 do  
	-- Did the same here for z
	for z = -resolution / 2, resolution / 2 do
        local y1 = math.noise(
            (x * frequency) / resolution,
            (z * frequency) / resolution,
            seed
        )

		local y2 = math.noise(
            (x * frequency * .125) / resolution,
            (z * frequency * .125) / resolution,
            seed
		)
		
		local y3 = math.noise(
            (x * frequency * 4) / resolution,
            (z * frequency * 4) / resolution,
            seed
        )
        
		local y = (y1 * y2 * power * power) + y3
		
        local Part = Part:Clone()
        Part.Parent = game.Workspace.Map
        Part.CFrame = CFrame.new(x * Scale.X, y, z * Scale.Z)

		local c = 0.4 -- c is some constant you use to customise how the noise feels
		local threshold = 0.1 -- the TreeChance needs to be greater than this to spawn a tree
		
		local TreeChance = math.noise(x * frequency * c / resolution, z * frequency * c / resolution, seed)
		
		if TreeChance > threshold then
		    local Tree = game.Workspace.Tree:Clone()
		    Tree.Parent = workspace.Map
			local TreeHeight = Tree.Size.Y
			local PartHeight = Part.Size.Y
			
			local TreeY = y + PartHeight / 2 + TreeHeight  / 2
			
			-- I changed it to Tree.Position instead of Tree.CFrame because the tree is a cylinder, so would spawn flat if I updated the CFrame instead of the position.
			Tree.Position = Vector3.new(x * Scale.X, TreeY, z * Scale.Z)
		end
	end
end

btw there’s no need to do math.random(1, 10e6). Firstly, the lower limit for math.random() is 1 by default, so it’s fine if you just do math.random(10e6). Secondly, you don’t even need an upper limit if you want something completely random. Just doing math.random() and not passing any arguments will generate something random. After you’re done generating, though, you should do math.randomseed(tick() or math.randomseed(os.time()) to reset it.

If it looks a bit unnatural, you can always make it so that no trees can spawn below a certain level (using the y result from the original math.noise) and then set limits to a certain level using the new math.noise.

Edit: oops replied to the wrong person

I found the problem. It was because of the water code. It works without the water code thank you. The water code and the tree code don’t work together.

:sweat_smile:

I think it worked

Please could you mark the post which helped you as the solution so others can find the answer easily. :slight_smile:

1 Like


I got trees to work on my generator but I created a probability function and slapped that onto the generator and added the y offset for the trees (so they would not be in the ground)

2 Likes

:+1: :+1: :+1:
Ok I will do it I might make this a kit maybe.

This is what I ended up with I will try to make the water code fit with the trees then It will be finished.

What are you using for the water? The easiest (and probably best) way to do it is to place water instead of a part whenever the height is below a certain level.

local Part = Instance.new("Part") --For cloning
Part.Anchored = true
Part.FormFactor = "Custom"
Part.Size = Vector3.new(4,4,4)
Part.TopSurface = "Smooth"    

local seed = math.random(1, 10e6)
local frequency = 3
local power = 20
local resolution = 256 
local WaterLevel = 0 --We store the level the water spawns below

for x = 1, resolution do  
	for z = 1, resolution do
        local y1 = math.noise(
            (x*frequency)/resolution,
            (z*frequency)/resolution,
            seed
        )

		local y2 = math.noise(
            (x*frequency*.125)/resolution,
            (z*frequency*.125)/resolution,
            seed
		)
		
		local y3 = math.noise(
            (x*frequency*4)/resolution,
            (z*frequency*4)/resolution,
            seed
        )
        
		local y = (y1*y2*power*power)+y3
		
        local Part = Part:Clone()
        Part.Parent = game.Workspace.Map
        Part.CFrame = CFrame.new(x,y,z)
		
		if z%resolution/2==resolution/4 then
			wait(0)
		end
		
		--[[if math.abs(y2) < .1 then
		    Part.BrickColor = BrickColor.Green()
		elseif math.abs(y2) > .25 then
		    Part.BrickColor = BrickColor.Red()
		else
			Part.BrickColor = BrickColor.Blue()
		end]]
		if y+(Part.Size.Y/2)<WaterLevel then -- We check if water is able to spawn.
			print(WaterLevel-y+(Part.Size.Y/2))
			local WaterPart=Part:Clone()
			WaterPart.CanCollide=false -- We set some values to the water.
			WaterPart.Transparency=1
			WaterPart.Reflectance=0.1
			WaterPart.Size=Vector3.new(4,WaterLevel-y+(Part.Size.Y/2),1)
			WaterPart.BrickColor=BrickColor.new("Cyan")
			WaterPart.CFrame=CFrame.new(x,y+(WaterLevel-y+(Part.Size.Y/2))/2,z)
			WaterPart.Parent=workspace.Map
                        game.Workspace.Terrain:FillBlock(WaterPart.CFrame, WaterPart.Size, Enum.Material.Water)
		end
	end
end

this is the code I am using for water

Instead of creating a part for the water and then filling the terrain, you can just fill the terrain. The players can’t interact with the water parts anyway.

1 Like

Yes but I want players to be able to swim in the water. So I did this:

I made water using the terrain editor.

That works too lol and whenever the map is under the certain height it will show water.

1 Like

Yes and this is easier to make

Using Perlin Noise To Make A Map here I made it a tutorial I will edit the tutorial and add ways to make water.