I don’t know if this will help, as its a LOT of code, but when I was working with generating terrain, I had lots of issues like that, but eventually I worked it out, but its an abandoned project I havent touched in a few years, so not sure what I did, but here is the function that generates a chunk of terrain. If you can follow it, maybe you can spot something that helps you out.
function RenderChunk(chunk)
if chunk then
if math.abs(chunk.ChunkX-MyX) <= ViewRadius and math.abs(chunk.ChunkZ - MyZ) <= ViewRadius then
local mat = Enum.Material.Grass
-- if chunk.ChunkX%2 == 0 then
-- if chunk.ChunkZ%2 == 0 then mat = Enum.Material.Snow end
-- elseif chunk.ChunkZ%2 ~= 0 then
-- mat = Enum.Material.Snow
-- end
--if show then print("Chunk Draw ",chunk.Key) end
local opaGrid = {}
local matGrid = {}
for x = 1,ChunkSize.X+2 do
matGrid[x] = {}
opaGrid[x] = {}
for y = 1,ChunkSize.Y do
matGrid[x][y] = {}
opaGrid[x][y] = {}
for z = 1,ChunkSize.Z+2 do
matGrid[x][y][z] = Enum.Material.Air
opaGrid[x][y][z] = 1
end
end
end
local cx = chunk.ChunkX
local cz = chunk.ChunkZ
for z = 1,ChunkSize.Z+2 do
cz = (chunk.ChunkZ * ChunkSize.Z) + (z-1)
for x = 1,ChunkSize.X+2 do
cx = (chunk.ChunkX * ChunkSize.X) + (x-1)
local surface,value,noise = PerlinModule.FindSurface(cx,cz)
--if value > 0 then value = 1 end
--if chunk.ChunkX == -1 and chunk.ChunkZ == 0 then
--print(cx,cz,surface,value)
--end
if noise+1 > noiseHigh then
--print(noise+1)
noiseHigh = noise+1
end
local random = Random.new(math.abs(cx*cz*noise))
if (random:NextInteger(0,300)==1) and surface < 70 then
local rock = Rock:Clone()
local scale = random:NextNumber()*2+.5
rock:ScaleTo(scale) -- .Size = rock.Size * scale
rock:PivotTo(CFrame.new(cx*4,surface*4,cz*4)*CFrame.Angles(0,math.rad(math.random(0,359)),0)) --.CFrame = CFrame.new(cx*4,surface*4,cz*4)*CFrame.Angles(0,math.rad(math.random(0,359)),0)
rock.Parent = GetSceneryFolder(chunk.Key,true)
end
if (random:NextInteger(0,200)==21) and surface > waterMaxY and surface < 70 then
local bush = Bush:Clone()
local scale = random:NextNumber()*2+.5
bush:ScaleTo(scale) --.Size = bush.Size * scale
bush:PivotTo(CFrame.new(cx*4,(surface)*4,cz*4)*CFrame.Angles(0,math.rad(math.random(0,359)),0))
bush.Parent = GetSceneryFolder(chunk.Key,true)
end
if (random:NextInteger(0,200)==1) and surface < (waterMaxY-20) then
local seaweed = Seaweed:Clone()
local scale = random:NextNumber()*1+.5
seaweed:ScaleTo(scale) -- .Size = rock.Size * scale
seaweed:PivotTo(CFrame.new(cx*4,surface*4,cz*4)*CFrame.Angles(0,math.rad(math.random(0,359)),0)) --.CFrame = CFrame.new(cx*4,surface*4,cz*4)*CFrame.Angles(0,math.rad(math.random(0,359)),0)
seaweed.Parent = GetSceneryFolder(chunk.Key,true)
end
--if surface < 2 then
-- print(cx,",",cz," : ",surface,",",value,",",noise)
--end
--print(surface)
--surface = 5
local soil = Enum.Material.Ground
local top = Enum.Material.Grass
local altTop = Enum.Material.LeafyGrass
local water = Enum.Material.Water
local terrain = PerlinModule.Perlin(cx,0,cz,1,.03,1)
local alt = false
if math.abs(terrain)<.3 and math.abs(terrain)>.2 then
alt = true
end
if surface < waterMaxY then
soil = Enum.Material.Limestone
top = Enum.Material.Sand
altTop = Enum.Material.Limestone
end
if alt then top = altTop end
for y = 1,ChunkSize.Y do
if y < surface-2 then
matGrid[x][y][z] = soil
elseif y<= surface then
matGrid[x][y][z] = top
elseif y==surface+1 then
matGrid[x][y][z] = top
local i = math.floor(value*100)/100
if i==0 then i = .01 end
--print(i)
opaGrid[x][y][z] = i
--if value < 1 and y > 1 then
-- matGrid[x][y-1][z] = mat
--end
--break
elseif y<=waterMaxY then
matGrid[x][y][z] = water
else
break
end
end
end
end
local region = chunk.Region
--print(region)
--print("region(",chunk.Key,") Region size(",region.Size,") pos(",region.CFrame.Position,")")
--print(matGrid)
--print(opaGrid)
--wait()
workspace.Terrain:WriteVoxels(region,4,matGrid,opaGrid)
return true
end
end
end