Good day everyone! Recently I started make a terrain generation system using perlin noise, but I ran into a problem that took a long time to generate the terrain itself. My terrain is 250 x 250 in size.
Is there any option to optimize my code and make it faster?
I’m writing here out of despair because I’ve been sitting on this for 4 days now.
Code
local Players = game:GetService("Players")
local perlinFolder = workspace:WaitForChild("PerlinTest")
local terrain = workspace:WaitForChild("Terrain")
local periodicity = 60
local size = 250
local chunck = {}
local seed = math.random()*30
print(seed)
local amp = 80
local materials = {
[1] = Enum.Material.Ground,
[2] = Enum.Material.Grass,
[3] = Enum.Material.Granite,
[4] = Enum.Material.Sand,
[5] = Enum.Material.Snow,
[6] = Enum.Material.Mud,
}
function SelectMaterial(x,z)
local xNoise = x/50
local zNoise = z/50
local noise = math.noise(xNoise,zNoise,seed)+1
local delta = #materials/2
local num = math.floor(noise*delta)
if num < 1 then
num = 1
elseif num > #materials then
num = #materials
end
return materials[num]
end
function NoizeCount(x,z)
local xNoise = x/50
local zNoise = z/50
local noise = math.noise(xNoise,zNoise,seed)*periodicity+amp
return noise
end
function CheckChunk(x,z)
local ret = nil
if chunck[x] == nil then
chunck[x] = {}
end
ret = chunck[x][z]
return ret
end
function WorldGenerate(posX,posZ)
print("Start generation")
warn(posX,posZ)
for x=posX-size,posX+size do
for z=posZ-size, posZ+size do
if CheckChunk(x,z) == nil then
chunck[x][z] = true
local part = Instance.new("Part",perlinFolder)
part.Shape = Enum.PartType.Block
part.Anchored = true
local y = NoizeCount(x,z)
local y1 = y - 3*4
part.Size = Vector3.new(4,(y-y1)/2,4)
part.Position = Vector3.new(x,(y+y1)/2,z)
terrain:FillBlock(part.CFrame,part.Size,SelectMaterial(x,z))
part:Destroy()
end
end
wait()
end
print("End generation")
task.wait()
end
function CharacterMoved(character)
local oldX = nil
local oldZ = nil
repeat
if character and character.Parent then
local coordinates = character:WaitForChild("HumanoidRootPart"):GetPivot()
local posX = math.floor(coordinates.Position.X)
local posZ = math.floor(coordinates.Position.Z)
if oldX ~= posX or oldZ ~= posZ then
warn("Генерация началась в ", posX,posZ)
task.spawn(WorldGenerate,posX,posZ)
oldX = posX
oldZ = posZ
else
task.wait()
end
else
return
end
until not (character and character.Parent)
end
function CharacterAdded(character)
task.spawn(CharacterMoved,character)
end
function PlayerAdded(player:Player)
player.CharacterAdded:Connect(CharacterAdded)
end
Players.PlayerAdded:Connect(PlayerAdded)