You can write your topic however you want, but you need to answer these questions:
-
What do you want to achieve? Keep it simple and clear!
I want to achieve 3D perlin noise with overhangs as well as the transitioning of different biomes with different perlin noise. Also if it’s possible, I would like to make my structures/flowers also be generated with math…noise so they are the same for everybody’s client side… -
What is the issue? Include screenshots / videos if possible!
I can’t seem to get the 3d perlin noise with the chunk rendering sytem I have. I also cannot find a way to transition from one biome to the other. I also cannot find a way to get a position for the structures/flowers with math.noise. -
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I have looked on the DevForum for help and I have tried many other people’s solutions however none of them seem to work.
After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!
If possibile I would like to keep using the same rendering system that I am using and hopefully I can find a way to optimize it myself.
local ChunkRenderDistance = 8
local ChunkSize = 16
local ChunkSizeY = 1
local ChunkGrid = {}
local CurrentBiome = 4
local SeedValue = workspace:WaitForChild("Seed")
repeat task.wait() until SeedValue.Value ~= -2
local Seed = SeedValue.Value
local blockSize = 3
local worldHeight = 10
local worldSize = 16
local divisor = 32
local blockSize = 3
local blocks = game.Workspace.Blocks
local uis = game:GetService("UserInputService")
local Biomes = {
--{'Mountains' ,80, 70},
{'Plains' ,160, 80},
{'Forest' ,160, 80},
{'Desert' ,160, 80},
{'Rivers' ,160, 80},
}
game.Players.PlayerAdded:Connect(function(player)
local Character = player.Character or player.CharacterAdded:Wait()
Character:FindFirstChildWhichIsA("Humanoid").WalkSpeed = 12.951
end)
local function fractalNoise(x, y, octaves, lacunarity, persistence, scale, seed)
-- The sum of our octaves
local value = 0
-- These coordinates will be scaled the lacunarity
local x1 = x
local y1 = y
-- Determines the effect of each octave on the previous sum
local amplitude = 1
for i = 1, octaves, 1 do
-- Multiply the noise output by the amplitude and add it to our sum
value += math.noise(x1 / scale, y1 / scale, seed) * amplitude
-- Scale up our perlin noise by multiplying the coordinates by lacunarity
y1 *= lacunarity
x1 *= lacunarity
-- Reduce our amplitude by multiplying it by persistence
amplitude *= persistence
end
-- It is possible to have an output value outside of the range [-1,1]
-- For consistency let's clamp it to that range
return math.clamp(value, -1, 1)
end
function GenerateNewChunk(Position)
--if math.random(1,100) == 1 then CurrentBiome = math.random(1, #Biomes) print('Changed') end
local Frequency = Biomes[CurrentBiome][2] --
local Amplitude = Biomes[CurrentBiome][3] --Height of wave
local ChunkData = {}
for x = 1, ChunkSize do
ChunkData[x] = {}
local LastYPos = 0
for y = 1, ChunkSizeY do
for z = 1, ChunkSize do
local X = ((x * 3) + Position.X + 1.5)
local noiseValue = math.noise((((x * 3) + Position.X + 1.5) / Frequency) + Seed, (((y * 3) + Position.Y + 1.5) / Frequency) + Seed, (((z * 3) + Position.Z + 1.5) / Frequency) + Seed)
local Y = ((math.floor((noiseValue * Amplitude) / 3) * 3) + 1.5)
local Z = ((z * 3) + Position.Z + 1.5)
ChunkData[x][z] = Vector3.new(X, Y, Z)
LastYPos = Y
end
end
end
table.insert(ChunkGrid, {Position ,ChunkData})
return {Position ,ChunkData}
end
function GetBlockTypes(BlockPos, Chunk)
local YPos = BlockPos.Y
if CurrentBiome == 1 then
if YPos < -4 then return game.ReplicatedStorage.Blocks.GrassBlock:Clone() end
if YPos >= -4 then return game.ReplicatedStorage.Blocks.GrassBlock:Clone() end
elseif CurrentBiome == 2 then
if YPos < -4 then return game.ReplicatedStorage.Blocks.GrassBlock:Clone() end
if YPos >= -4 then return game.ReplicatedStorage.Blocks.GrassBlock:Clone() end
elseif CurrentBiome == 3 then
if YPos < -4 then return game.ReplicatedStorage.Blocks.SandBlock:Clone() end
if YPos >= -4 then return game.ReplicatedStorage.Blocks.SandBlock:Clone() end
elseif CurrentBiome == 4 then
if YPos < 1 then
local WaterBlock = BlockPos
repeat
WaterBlock += Vector3.new(0,3,0)
until WaterBlock.Y + 3 > 2
local NewWaterBlock = game.ReplicatedStorage.WaterBlock:Clone()
NewWaterBlock.Parent = Chunk
NewWaterBlock.Position = WaterBlock + Vector3.new(1,1,1)
end
if YPos < 2 then return game.ReplicatedStorage.Blocks.SandBlock:Clone() end
if YPos >= 2 then return game.ReplicatedStorage.Blocks.GrassBlock:Clone() end
end
end
local ChunksRendered = 0
local WorldLoaded = false
function RenderChunk(ChunkData, ChunkIndex, player)
local ChunkCenter = ChunkData[1]
local BlockData = ChunkData[2]
local ChunkModel = Instance.new('Model')
ChunkModel.Name = 'Chunk '..ChunkIndex
ChunkModel.Parent = workspace.Chunks
local RunService = game:GetService("RunService")
for _, Row in ipairs(BlockData) do
for _, Block in ipairs(Row) do
local NewBlock = GetBlockTypes(Block ,ChunkModel)
NewBlock.Position = Block + Vector3.new(1,0,1)
NewBlock.Parent = ChunkModel
if NewBlock.Name == "GrassBlock" then
--[[local OddsMob = math.random(1,1000)
if OddsMob <= 4 then
local NewMob = game.ReplicatedStorage.Mobs["Pig"]:Clone()
NewMob.PrimaryPart.Position = NewBlock.Position + Vector3.new(0,3.345,0)
NewMob.Parent = game.Workspace.Mobs
NewMob.Name = NewMob.Name.."#"..#game.Workspace.Mobs:GetChildren()
end]]
local OddsPlant = math.random(1, 100)
if OddsPlant <= 5 then
local NewPlant = game.ReplicatedStorage.Blocks.FlowerBlock:Clone()
NewPlant.Position = NewBlock.Position + Vector3.new(0,3,0)
NewPlant.Parent = ChunkModel
end
local OddsStructure = math.random(0, 100)
if CurrentBiome == 2 then
if OddsStructure <= 2 then
local NewStructure = game.ReplicatedStorage.Structures.Tree:Clone()
NewStructure.PrimaryPart.Position = NewBlock.Position + Vector3.new(0,3,0)
NewStructure.Parent = ChunkModel
for _, block in ipairs(NewStructure:GetChildren()) do
block.Parent = ChunkModel
end
NewStructure:Destroy()
end
elseif CurrentBiome == 4 then
if OddsStructure <= 2 then
local NewStructure = game.ReplicatedStorage.Structures.Tree:Clone()
NewStructure.PrimaryPart.Position = NewBlock.Position + Vector3.new(0,3,0)
NewStructure.Parent = ChunkModel
for _, block in ipairs(NewStructure:GetChildren()) do
block.Parent = ChunkModel
end
NewStructure:Destroy()
end
end
elseif NewBlock.Name == "SandBlock" then
local OddsStructure = math.random(0, 100)
if CurrentBiome == 3 then
if OddsStructure <= 2 then
local NewStructure = game.ReplicatedStorage.Structures.Cactus:Clone()
NewStructure.PrimaryPart.Position = NewBlock.Position + Vector3.new(0,3,0)
NewStructure.Parent = ChunkModel
for _, block in ipairs(NewStructure:GetChildren()) do
block.Parent = ChunkModel
end
NewStructure:Destroy()
end
end
end
end
end
print(ChunksRendered)
if ChunksRendered >= 14 then
if WorldLoaded == false then
WorldLoaded = true
game.Workspace.SpawnLocation.CanCollide = false
game.ReplicatedStorage.Events.WorldLoaded:FireServer()
ChunksRendered = 1
else
ChunksRendered = 1
end
else
ChunksRendered = ChunksRendered + 1
end
end
function RenderChunksNearPlayer(Player)
for x = 1, (ChunkRenderDistance) do
for z = 1, (ChunkRenderDistance) do
local PlayerPos = workspace:WaitForChild(Player.Name):WaitForChild('HumanoidRootPart').Position
local FoundChunk = false
local ChunkX = ((math.floor(PlayerPos.x / (ChunkSize * 3)) * (ChunkSize * 3)) + ((ChunkSize * 3) * x)) - ((ChunkSize * 3) * (ChunkRenderDistance / 1.5))
local ChunkZ = ((math.floor(PlayerPos.z / (ChunkSize * 3)) * (ChunkSize * 3)) + ((ChunkSize * 3) * z)) - ((ChunkSize * 3) * (ChunkRenderDistance / 1.5))
for _, Chunk in ipairs(ChunkGrid) do
if Chunk[1] == Vector3.new(ChunkX, 0, ChunkZ) then
FoundChunk = true
end
end
if not FoundChunk then
GenerateNewChunk(Vector3.new(ChunkX, 0, ChunkZ))
end
end
end
for ChunkIndex, Chunk in ipairs(ChunkGrid) do
if (workspace:WaitForChild(Player.Name):WaitForChild('HumanoidRootPart').Position - Chunk[1]).Magnitude <= (ChunkSize * ChunkRenderDistance) then
if not workspace.Chunks:FindFirstChild('Chunk '..ChunkIndex) then
print('Render')
RenderChunk(Chunk, ChunkIndex, Player)
end
else
if workspace.Chunks:FindFirstChild('Chunk '..ChunkIndex) then
workspace.Chunks:FindFirstChild('Chunk '..ChunkIndex):Destroy()
end
end
end
end
local Player = game.Players.LocalPlayer
while task.wait() do
RenderChunksNearPlayer(Player)
end
Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.