Tutorial By Me, I Hope You Enjoy : )
What Is math.noise()?
To put it simply, math.noise()
is a function that basically allows the user to create random terrain, by using a method known as Perlin Noise. Perlin Noise can be used for many things but mostly random terrain generation. An example of a popular game using Perlin Noise is Minecraft, which uses multiple Perlin Noise’s to determine Biomes, Mountains, Villages, etc. Perlin Noise uses randomness to determine everything, like i did in my Perlin Noise Generator which only uses Math.Random
. Many people don’t really understand what randomness is, so here’s a definition and how it works.
“The quality or state of lacking a pattern or principle of organization; unpredictability.” (Taken From Google)
Lets say you went to the lottery, and you were asked to pick 6 numbers. Most people already, would think that it would be impossible for 123456 to be the winning code. Theoretically, it is still a Approximately 1/1000000 (0.0001 %*) chance that 123456 is the winning code, which is the same as the code 749286. So if you used math.random(1,1000)
, there is a 1/1000 chance that 1, 2 and 3 and so on is picked. This is a very basic example. Before the 1990s, i believe people used the Time * Pi / (random number / seed or whatever ).
How To Use math.noise()
I’m not going to provide you the script, so you’ll have to follow along and learn : D
First, we need to make a place to store the parts for our Perlin Noise. In Workspace, create a folder named: “PerlinNoise_Storage”. This is where we are storing our Parts that will be generated when using math.noise()
.
Now, open the Output (Toolbar > View > Output), And make a script named “PerlinNoiseHandler”. This Script will handle the generation with math.noise()
Next, create a variable that is the folder we made at the start, like this:
local PartStorage = workspace:WaitForChild("PerlinNoise_Storage")
Now we need to create a few variables that will control how our Perlin Noise will look:
local RenderSize = 100 -- Controls The Size
local Resolution = 100 -- Controls The Resolution
local Frequency = 3
local Amplitude = 10
local BlockSize = 1 -- Controls The Block Size
local Blocky: boolean = false -- Controls If We're Making A Blocky Render Like Minecraft
Here, the RenderSize
is 100 meaning it will be 100 blocks wide, and 100 blocks long. The resolution controls how smooth it will be.
Next we need to make a Local Function. This will take in 2 variables, which will turn into Noise.
local function GetHeight(x :number, z :number): number -- Creates Our Function
local noiseHeight = math.noise( -- Math.Noise
x / Resoloution * Frequency, -- The First Value Is X Divided And Multiplied
z / Resoloution * Frequency -- The Second is Z but the same as X
)
noiseHeight = math.clamp(noiseHeight, -.5, .5) + .5
return noiseHeight -- Returns The 'Noise' Height / Value
end
Now we need to make 2 For Loops. 1 For The X, And The Y.
for x = 0, RenderSize do
for z = 0, RenderSize do
This will obviously render a square. You can change this to your liking.
For this next part, you can use the Inbuilt Instance.New() or use the BetterInstances Module (Note the BetterInstances Module May Be Very Inefficient
BetterInstances Module
local BetterInstances = {}
local ClipBoard = {}
--local Settings = require(script.Settings.Settings)
--if script.Config:GetAttribute("DevMode") == true then
-- BetterInstances.Changelog = function()
-- return [[
-- -- BetterInstances Changelog --
-- - Created Module
-- - Added Commands
-- ]]
-- end
-- BetterInstances.Credits = function()
-- return [[
-- -- BETTER INSTANCES CHANGELOG --
--
-- ]]
-- end
-- BetterInstances.Version = function()
-- return tostring(script.Config:GetAttribute("Ver"))
-- end
--end
BetterInstances.new = function(INName:string, NewParent:Instance?, NewName:string?):Instance
local inst = Instance.new(INName, NewParent)
inst.Name = NewName
return inst
end
BetterInstances.Copy = function(Obj:Instance, NewParent:Instance, Name:string?):Instance
table.clear(ClipBoard)
table.insert(ClipBoard, Obj.Name)
Obj:Clone().Parent = NewParent
if Name ~= "" or nil then
Obj.Name = Name
end
end
function BetterInstances:GetClipboard()
return table.unpack(ClipBoard)
end
function BetterInstances:ClearClipboard()
table.clear(ClipBoard)
end
function BetterInstances:SetClipboard(Obj:Instance)
table.clear(ClipBoard)
table.insert(ClipBoard, Obj.Name)
end
return BetterInstances
Anyways, Here’s The Next Part Of The Script.
local Part = Instance.new("Part") -- Creates The Part
Part.Parent = PartStorage
Part.Anchored = true
Part.Size = Vector3.new(BlockSize,BlockSize,BlockSize) -- Sets The Part Size
local height = GetHeight(x,z) -- Gets The Perlin Noise Height
if Blocky then -- Checks If We Want The Blocky Terrain
Part.Position = Vector3.new(math.floor(x), math.floor(height * Amplitude), math.floor(z))
else
Part.Position = Vector3.new(x, height * Amplitude, z)
end
Part.Color = Color3.new(height + BlockSize, height + BlockSize, height + BlockSize) -- Sets The Parts Colour
end
end
If you save the script, and run it, You should get something like this:
Obviously, this is super basic and can be built apon. Try adding + Number in random places and experiment.
(Also Here’s A Module )
PerlinNoise.lua (994 Bytes)
Or, The Text Version
Module
local PN = {}
function PN.Render(PartStorage: Instance, RenderSize:number, Resoloution:number, Frequency:number, Amplitude:number, BlockSize: number, Blocky: boolean)
local function GetHeight(x :number, z :number): number
local noiseHeight = math.noise(
x / Resoloution * Frequency,
z / Resoloution * Frequency
)
noiseHeight = math.clamp(noiseHeight, -.5, .5) + .5
return noiseHeight
end
for x = 0, RenderSize do
for z = 0, RenderSize do
local Part = Instance.new("Part")
Part.Parent = PartStorage
Part.Anchored = true
Part.Size = Vector3.new(BlockSize,BlockSize,BlockSize)
local height = GetHeight(x,z)
if Blocky then
Part.Position = Vector3.new(math.floor(x), math.floor(height * Amplitude), math.floor(z))
else
Part.Position = Vector3.new(x, height * Amplitude, z)
end
Part.Color = Color3.new(height + BlockSize, height + BlockSize, height + BlockSize)
end
end
return true
end
return PN.Render
If you’ve found any mistakes or somethings not working, please let me know. This iks my first tutorial!
Thank you for reading and making it this far.
From what you’ve made and learnt, how do you rate the Final Product You’ve Made.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
0 voters
As always, have a good day.