Terrain is pretty cool, and procedural terrain is even cooler, but it can cause performance issues especially when using parts so I’m trying to make it perform well so I can use it without worrying too much about how it will effect gameplay
Here is a gif using the generator I created
this is rather small for what I need and it already has 3600 parts
I could make the parts bigger and the amount of parts lower like so
but then it starts to look less appealing
I have an idea that could drastically reduce part count by making all rows of the same part a single longer part shown below (red lines would be connected parts)
but I’m still not sure if it will be viable then
is there another method of making terrain like this perform better? I don’t know but it might be necessary to swap to actual roblox terrain, but then loss of quality would be pretty high and isn’t really the style I’m going for
Streaming Enabled is an option roblox is also adding level of detail features and improved Streaming
Code
Module
local RunService = game:GetService("RunService")
local Part = Instance.new("Part")
Part.Anchored = true
Part.Color = Color3.fromRGB(255, 255, 255)
Part.Name = "TerrainCell"
local TerrainHeights = {
["Water"] = {Height = -1020, Material = Enum.Material.Plastic, Color = Color3.fromRGB(4, 175, 236), Transparency = 0, IncreasedHeight = 0},
--["Sand"] = {Height = -50, Material = Enum.Material.Plastic, Color = Color3.fromRGB(248, 217, 109), Transparency = 0, IncreasedHeight = 1},
["Grass"] = {Height = -60, Material = Enum.Material.Plastic, Color = Color3.fromRGB(91, 154, 76), Transparency = 0, IncreasedHeight = 1},
["DarkGrass"] = {Height = 30, Material = Enum.Material.Plastic, Color = Color3.fromRGB(39, 70, 45), Transparency = 0, IncreasedHeight = 2},
["Stone"] = {Height = 45, Material = Enum.Material.Plastic, Color = Color3.fromRGB(163, 162, 165), Transparency = 0, IncreasedHeight = 200},
["DarkStone"] = {Height = 55, Material = Enum.Material.Plastic, Color = Color3.fromRGB(99, 95, 98), Transparency = 0, IncreasedHeight = 300},
}
local TerrainHeightsList = {
TerrainHeights["Water"],
--TerrainHeights["Sand"],
TerrainHeights["Grass"],
TerrainHeights["DarkGrass"],
TerrainHeights["Stone"],
TerrainHeights["DarkStone"]
}
local TerrainModule = {}
function TerrainModule.TerrainPolisher(TerrainTable)
local MaxY = -100
for i, v in pairs(TerrainTable) do
if v[1] > MaxY then MaxY = v[1] end
end
for i, v in pairs(TerrainTable) do
local Y = math.floor((v[1] / MaxY) * 100)
local Type
for i, v in pairs(TerrainHeightsList) do
if Y > v.Height then
Type = v
end
end
local function SetProperties()
v[2].Material = Type.Material
v[2].Color = Type.Color
v[2].Transparency = Type.Transparency
v[2].Size = v[2].Size + Vector3.new(0, Type.IncreasedHeight, 0)
v[2].Position = v[2].Position + Vector3.new(0, Type.IncreasedHeight / 2, 0)
end
SetProperties()
end
end
function TerrainModule.GenTerrain(Size, CellSize, Power, Frequency)
local Seed = math.random(1, 10e6)
local TerrainList = {}
--[[
Size is the amount of Cells
CellSize is the Size of a Cell
Power is the magnitude of how high or low the noise map can go
Frequency is how compact the noise map is
--]]
for X = 1, Size do
for Z = 1, Size do
local Y = math.noise((X * Frequency) / Size, (Z * Frequency) / Size, Seed) * Power
local TerrinCell = Part:Clone()
TerrinCell.Size = Vector3.new(CellSize, CellSize, CellSize)
TerrinCell.Position = Vector3.new((X * CellSize), 5, (Z * CellSize))
TerrinCell.Parent = workspace
table.insert(TerrainList, {Y, TerrinCell})
end
RunService.Heartbeat:Wait()
end
TerrainModule.TerrainPolisher(TerrainList)
end
return TerrainModule
Script
local TerrainModule = require(game.ServerScriptService.TerrainModule)
local Size, CellSize, Power, Frequency = 40, 50, 45, 4
TerrainModule.GenTerrain(Size, CellSize, Power, Frequency)
I wasn’t sure if this should go in Scripting Support or Code Review because it is a bit of both