terraingen

Run Settings
LanguageLua
Language Version
Run Command
function getChunkID(v1) return `{v1.X},{v1.Y}` end function fromChunkID(id) local x, y = unpack(id:split(",")) return Vector2.new(tonumber(x), tonumber(y)) end function parseVal(v) return v == "true" and true or v == "false" and false or tonumber(v) and tonumber(v) or v end function parseOptions(opt) local set = opt:split(";") local t = {} for i, v in set do local idx, val = unpack(v:split("=")) t[idx] = parseVal(val) end return t end function hashCode(value) local h = 0 local MAX_INT = 65535 for i = 1, #value do h = (31 * h + string.byte(value, i, i)) % MAX_INT end return h end if (...) == "?" then return getfenv().warnf("\n<b>TerrainGen options:</b>\nOptions formatted as: 'index=value;index2=value2'\nseed = int|str\nfeatures = bool\nchunkSize = int\nrenderDist = int") end local setting = parseOptions(... or "") print(setting) local chunks = {} local provisionedSeed = setting.seed or os.time() local seed = type(provisionedSeed) == "number" and provisionedSeed or hashCode(provisionedSeed) local srng = Random.new(seed) local terrainSeed = srng:NextInteger(-65535, 65535) local tempSeed = srng:NextInteger(-65535, 65535) local preSeed = srng:NextInteger(-65535, 65535) local featureSeed = srng:NextInteger(-65535, 65535) local globalTempMul = srng:NextNumber(0.8, 3) local globalPreMul = srng:NextNumber(0.8, 3) print(globalTempMul, globalPreMul) local populateFeatures = setting.features or true local chunkSize = setting.chunkSize or 256 local halfChunk = chunkSize // 2 local res = 4 local Step = Instance.new("BindableEvent") Step.Parent = script local Tick = 0 local FrameTime = 1 / 4000 game:GetService("RunService").Heartbeat:Connect(function(DT) Tick += DT if Tick >= FrameTime then for _ = 1, math.floor(Tick / FrameTime) do Step:Fire() end Tick = 0 end end) function fractalNoise(x, y, seed, octaves, persistence, scale) local total = 0 local frequency = scale local amplitude = 1 for i = 1, octaves do total = total + math.noise(x * frequency, y * frequency, seed) * amplitude frequency = frequency * 2 amplitude = amplitude * persistence end return total end local featureRng = Random.new(featureSeed) local featureParams = RaycastParams.new() featureParams.FilterType = Enum.RaycastFilterType.Include featureParams:AddToFilter(workspace.Terrain) local TreeLib = loadstring(game:GetService("HttpService"):GetAsync("https://glot.io/snippets/gv7v07pjx9/raw/main.lua"))() local stuff = LoadAssets(17131558926) local flower = stuff:Get("flower") for i, v in flower:GetDescendants() do if v:IsA("BasePart") then v.CanCollide = false end end local features = { Spikes = function(pos) if featureRng:NextNumber() < 1/20 then local initialWidth = featureRng:NextInteger(14, 30) local height = featureRng:NextInteger(8, 55) local width = initialWidth for i = 1, height do workspace.Terrain:FillBall(pos + Vector3.new(0, i, 0), width, Enum.Material.Glacier) width -= featureRng:NextNumber(0, 0.5) end end end, PineTrees = function(pos) local tree = TreeLib.new({ MaxIterations = 3, StartingWidth = 2.3, StartingHeight = 30, StartingWidthVariation = 1, StartingHeightVariation = 1, WidthDiminish = 0.9, HeightDiminish = 1, BranchColor = Color3.fromRGB(91, 62, 52), BranchColorVariation = 0.1, LeavesMaterial = Enum.Material.Grass, BranchMaterial = Enum.Material.Wood, LeavesColor = Color3.fromRGB(15, 72, 41), LeavesColorVariation = 0.1, LeavesSize = 20, LeavesSizeVariation = 0.3, GrowAnimation = false, RoundedBranches = false, Locked = false }) if featureRng:NextNumber() < 1/90 then local r = workspace:GetPartBoundsInRadius(pos, 38) for i, v in next, r do if v.Name == "__BRANCH" then return end end tree:Generate(pos, script, workspace.Terrain) end end, NormalTrees = function(pos) local tree = TreeLib.new({ MaxIterations = 3, StartingWidth = 2.3, StartingHeight = 16.5, StartingWidthVariation = 1, StartingHeightVariation = 1, WidthDiminish = 0.9, HeightDiminish = 1, BranchColor = Color3.fromRGB(91, 62, 52), BranchColorVariation = 0.1, LeavesMaterial = Enum.Material.Grass, BranchMaterial = Enum.Material.Wood, LeavesColor = Color3.fromRGB(31, 124, 25), LeavesColorVariation = 0.1, LeavesSize = 16.4, LeavesSizeVariation = 0.3, GrowAnimation = false, RoundedBranches = false, Locked = false }) if featureRng:NextNumber() < 1/90 then local r = workspace:GetPartBoundsInRadius(pos, 38) for i, v in next, r do if v.Name == "__BRANCH" then return end end tree:Generate(pos, script, workspace.Terrain) end end, Flowers = function(pos) if featureRng:NextNumber() < 1/150 then for i = 1, featureRng:NextInteger(8, 24) do local p = pos + Vector3.new(featureRng:NextNumber(-8, 8), 0, featureRng:NextNumber(-8, 8)) local ypos = workspace:Raycast(Vector3.new(p.X, 256, p.Z), Vector3.new(0, -1024, 0), featureParams) if ypos == nil then return end local col = Color3.new(featureRng:NextNumber(), featureRng:NextNumber(), featureRng:NextNumber()) local f = flower:Clone() for _, v in f.petals:GetChildren() do v.Color = col end f.Parent = script f:PivotTo(CFrame.new(ypos.Position + Vector3.new(0, 0.53, 0))) end end end, Cacti = function(pos) if featureRng:NextNumber() < 1/75 then local r = workspace:GetPartBoundsInRadius(pos, 16) for i, v in next, r do if v.Name == "cactus" then return end end local cac = stuff:Get("cactus"):Clone() cac.Anchored = true cac.CanCollide = true cac.CFrame = CFrame.new(pos) * CFrame.new(0, 11, 0) cac.Parent = script end end, GiantTrees = function(pos) local tree = TreeLib.new({ MaxIterations = 6, StartingWidth = 7, StartingHeight = 30, StartingWidthVariation = 1, StartingHeightVariation = 1, WidthDiminish = 1, HeightDiminish = 1, BranchColor = Color3.fromRGB(91, 62, 52), BranchColorVariation = 0.1, LeavesMaterial = Enum.Material.Grass, BranchMaterial = Enum.Material.Wood, LeavesColor = Color3.fromRGB(82, 124, 34), LeavesColorVariation = 0.1, LeavesSize = 16.4, LeavesSizeVariation = 0.3, GrowAnimation = false, RoundedBranches = false, Locked = false }) if featureRng:NextNumber() < 1/90 then local r = workspace:GetPartBoundsInRadius(pos, 38) for i, v in next, r do if v.Name == "__BRANCH" then return end end tree:Generate(pos, script, workspace.Terrain) end end, } local biomeMap = { ["Tundra"] = { temperature = 0.1, precipitation = 0.2, material = Enum.Material.Snow, terrainFeatures = {"Spikes"}, amplitude = 20 }, ["Taiga"] = { temperature = 0.3, precipitation = 0.4, terrainType = "Coniferous Forest", material = Enum.Material.LeafyGrass, terrainFeatures = {"PineTrees"}, amplitude = 15 }, ["Temperate Forest"] = { temperature = 0.6, precipitation = 0.5, material = Enum.Material.Ground, terrainType = "Deciduous Forest", terrainFeatures = {"NormalTrees"}, amplitude = 18 }, ["Grassland"] = { temperature = 0.7, precipitation = 0.3, terrainType = "Wide Plains", material = Enum.Material.Grass, terrainFeatures = {"Flowers"}, amplitude = 25 }, ["Desert"] = { temperature = 0.8, precipitation = 0.1, material = Enum.Material.Sand, terrainType = "Sandy Dunes", terrainFeatures = {"Cacti"}, amplitude = 35 }, ["Tropical Rainforest"] = { temperature = 1.0, precipitation = 0.9, material = Enum.Material.Mud, terrainType = "Lush Jungle", terrainFeatures = {"GiantTrees"}, amplitude = 22 } } function findBiome(temperature, precipitation) local minDistance = math.huge local closestBiome = nil for biome, data in pairs(biomeMap) do local tempDiff = math.abs(data.temperature - temperature) local precDiff = math.abs(data.precipitation - precipitation) local distance = math.sqrt(tempDiff^2 + precDiff^2) if distance < minDistance then minDistance = distance closestBiome = biome end end return closestBiome end function round(number, increment) return math.floor(number / increment + 0.5) * increment end function map(value, inputMin, inputMax, outputMin, outputMax) return outputMin + (value - inputMin) * (outputMax - outputMin) / (inputMax - inputMin) end function generateChunk(pos) for x = pos.X - halfChunk, pos.X + halfChunk, res do for z = pos.Y - halfChunk, pos.Y + halfChunk, res do local temp = map(fractalNoise(x, z, tempSeed, 7, 0.5, 0.001), -1, 1, 0, 1) * globalTempMul local wota = map(fractalNoise(x, z, preSeed, 7, 0.5, 0.001), -1, 1, 0, 1) * globalPreMul local biome = findBiome(temp, wota) biome = biome or "Desert" local data = biomeMap[biome] local noise = fractalNoise(x, z, terrainSeed, 5, 0.2, 0.01) * data.amplitude workspace.Terrain:FillBall(Vector3.new(x, noise, z), res, data.material) if populateFeatures == true then task.spawn(function() for i, v in data.terrainFeatures do features[v](Vector3.new(x, noise, z)) end end) end end Step.Event:Wait() end chunks[getChunkID(pos)] = true end local renderDistance = setting.renderDist or 1 function getChunksInRange(pos) local chunksInRange = {} for x = pos.X - (renderDistance * chunkSize), pos.X + (renderDistance * chunkSize), chunkSize do for z = pos.Y - (renderDistance * chunkSize), pos.Y + (renderDistance * chunkSize), chunkSize do table.insert(chunksInRange, Vector2.new(x, z)) end end return chunksInRange end local td = Instance.new("ScreenGui") td.Name = "td" td.DisplayOrder = 6969 td.IgnoreGuiInset = true td.ResetOnSpawn = false td.ScreenInsets = Enum.ScreenInsets.DeviceSafeInsets td.ZIndexBehavior = Enum.ZIndexBehavior.Sibling local db = Instance.new("TextLabel") db.Name = "db" db.FontFace = Font.fromEnum(Enum.Font.SourceSans) db.Text = "" db.TextColor3 = Color3.fromRGB(255, 255, 255) db.TextSize = 40 db.TextStrokeTransparency = 0 db.TextXAlignment = Enum.TextXAlignment.Right db.TextYAlignment = Enum.TextYAlignment.Bottom db.AnchorPoint = Vector2.new(1, 1) db.AutomaticSize = Enum.AutomaticSize.X db.BackgroundColor3 = Color3.fromRGB(255, 255, 255) db.BackgroundTransparency = 1 db.BorderColor3 = Color3.fromRGB(0, 0, 0) db.BorderSizePixel = 0 db.Position = UDim2.fromScale(1, 1) db.Size = UDim2.new(0, 256, 1, 0) db.Parent = td td.Parent = owner.PlayerGui task.defer(function() while true do task.wait() local pos = owner.Character:GetPivot().Position local cpos = Vector2.new(round(pos.X, chunkSize), round(pos.Z, chunkSize)) local temp = map(fractalNoise(pos.X, pos.Z, tempSeed, 7, 0.5, 0.001), -1, 1, 0, 1) * globalTempMul local wota = map(fractalNoise(pos.X, pos.Z, preSeed, 7, 0.5, 0.001), -1, 1, 0, 1) * globalPreMul local biome = findBiome(temp, wota) biome = biome or "Desert" local text = "x: %d, z: %d\ncx: %d, cz: %d\nbiome: %s\ntemp: %f\nhumid: %f\npopulateFeatures: %s\nchunkSize: %d\norigSeed: %s\nseed: %s\nrenderDist: %d" db.Text = text:format(math.round(pos.X), math.round(pos.Z), cpos.X // chunkSize, cpos.Y // chunkSize, biome, temp, wota, populateFeatures and "true" or "false", chunkSize, provisionedSeed, seed, renderDistance) end end) while true do for i, v in game:GetService("Players"):GetPlayers() do if v.Character then local position1 = v.Character:GetPivot().Position local position = Vector2.new(round(position1.X, chunkSize), round(position1.Z, chunkSize)) local possibleChunks = getChunksInRange(position) for _, pos in possibleChunks do local id = getChunkID(pos) if chunks[id] == nil then task.spawn(generateChunk, pos) end task.wait() end end task.wait() end task.wait() end
Editor Settings
Theme
Key bindings
Full width
Lines