I’m trying to make an island system using 3d Perlin noise, but my current code is extremely slow. At the time, I made it able to detect parts that are occluded, but only after generating every coordinate, and the code that checks it is also pretty slow. I tried using RunService.Heartbeat:Wait()
rather than task.wait()
to make it faster but it’s still obnoxiously slow and laggy.
Here’s a quick recording of how laggy it is
What it generates (the front islands are carved because i didnt want to wait a decade for the whole thing to generate, since with each row it gets slower)
The code (please forgive me for how poorly coded it is, I did pretty quickly and I'm pretty tired)
local blockSize = 4
local worldSize = 256
local divisor = 200 -- This makes the terrain more wild / crazy, and the higher it is the more overhangs there will be, and the less this is the less overhangs there will be.
local seed = math.random(1,1000)
local positions = {}
function get_update(position)
local coord_to_place = Vector3.new(0,0,0)
end
function place_block(position:Vector3)
local block = Instance.new("Part")
block.Parent = workspace
block.Size = Vector3.new(blockSize, blockSize, blockSize)
block.Anchored = true
block.CFrame = CFrame.new(position.X, position.Y, position.Z)
end
function check_for_air_exposure()
for i,v:Vector3 in pairs(positions) do
local is_valid = false
local positions_to_check = {}
local obstructed = {}
-- sorry for this bad code lol i was too braindead while making this
table.insert(positions_to_check, Vector3.new(v.X - blockSize, v.Y, v.Z))
table.insert(positions_to_check, Vector3.new(v.X + blockSize, v.Y, v.Z))
table.insert(positions_to_check, Vector3.new(v.X, v.Y - blockSize, v.Z))
table.insert(positions_to_check, Vector3.new(v.X, v.Y + blockSize, v.Z))
table.insert(positions_to_check, Vector3.new(v.X, v.Y, v.Z - blockSize))
table.insert(positions_to_check, Vector3.new(v.X, v.Y, v.Z + blockSize))
for _, pos in positions_to_check do
--print(table.find(positions, pos))
if table.find(positions, pos) then
--print("Side obstructed")
table.insert(obstructed, pos)
else
is_valid = true
end
end
if is_valid then
place_block(v)
end
if i % 100 == 0 then
game["Run Service"].Heartbeat:Wait()
end
end
end
for x = 1, worldSize do
for y = 1, worldSize do
for z = 1, worldSize do
local noiseValue = math.noise(
(x + seed) * (blockSize/10) / 16,
(y + seed) * (blockSize/10) / 16,
(z + seed) * (blockSize/10) / 16) - ((y - (worldSize / 2)) / divisor
) -- Subtract the world size divided by two because without it, the terrain will have alot of holes in the ground.
if noiseValue >= .9 then
table.insert(positions,Vector3.new(x*blockSize,y*blockSize,z*blockSize))
end
end
end
game["Run Service"].Heartbeat:Wait()
end
check_for_air_exposure()
I wanna be able to make it render much faster and if possible maybe in chunks, but I am very new to noise generation
Any help is appreciated!