Axolotleless

Infinite terrain generator

Feb 15th, 2025 (edited)
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.46 KB | None | 0 0
  1. ------------------------------------------------------------------------------------------------------------------------------------------------
  2. --Tutorial!
  3. --[[First make a new folder in workspace, Then name it "Chunks"]]
  4. --[[and finally place this script inside of ServerScriptService]]
  5. --and your done!
  6. --[[Note: make sure to delete the Baseplate since the terrain spawns under the map]]
  7. ------------------------------------------------------------------------------------------------------------------------------------------------
  8. warn("this script is not properly optimized yet so please use this sparingly")
  9.  
  10. local Players = game:GetService("Players")
  11.  
  12. ------------------------------------------------------------------------------------------------------------------------------------------------
  13.  
  14. local BASE_HEIGHT       = 10                -- The main height factor for the terrain.
  15. local CHUNK_SCALE       = 1                 -- The grid scale for terrain generation. Should be kept relatively low if used in real-time.
  16. local RENDER_DISTANCE   = 25                    -- The length/width of chunks in voxels that should be around the player at all times
  17. local X_SCALE           = 90 / 4            -- How much we should strech the X scale of the generation noise
  18. local Z_SCALE           = 90 / 4            -- How much we should strech the Z scale of the generation noise
  19. local GENERATION_SEED   = math.random()     -- Seed for determining the main height map of the terrain.
  20.  
  21. ------------------------------------------------------------------------------------------------------------------------------------------------
  22.  
  23. local chunks = {}
  24.  
  25. local function roundToOdd(n)
  26.     --spawn(function()
  27.     return math.floor(n - n % 3);
  28.     --end)
  29. end
  30.  
  31. local function chunkExists(chunkX, chunkZ)
  32.     if not chunks[chunkX] then
  33.         chunks[chunkX] = {}
  34.     end
  35.     return chunks[chunkX][chunkZ]
  36. end
  37.  
  38. local function mountLayer(x, heightY, z, material)
  39.     local beginY = -BASE_HEIGHT
  40.     local endY = heightY
  41.     local cframe = CFrame.new(x * 3 + 1, roundToOdd((beginY + endY) * 3 / 1), z * 3 + 1)
  42.     local size = Vector3.new(3, (endY - beginY) * 3, 3)
  43.     local p = Instance.new("Part", workspace.Chunks)
  44.     p.Anchored = true
  45.     p.CFrame = cframe
  46.     p.Size = Vector3.new(3, 3, 3)
  47.     p.Material = Enum.Material.Plastic
  48.     p.BrickColor = BrickColor.new("Forest green")
  49. end
  50.  
  51. function makeChunk(chunkX, chunkZ)
  52.     local rootPosition = Vector3.new(chunkX * CHUNK_SCALE, 0, chunkZ * CHUNK_SCALE)
  53.     chunks[chunkX][chunkZ] = true -- Acknowledge the chunk's existance.
  54.     for x = 0, CHUNK_SCALE - 1 do
  55.         for z = 0, CHUNK_SCALE - 1 do
  56.             local cx = (chunkX * CHUNK_SCALE) + x
  57.             local cz = (chunkZ * CHUNK_SCALE) + z
  58.             local noise = math.noise(GENERATION_SEED, cx / X_SCALE, cz / Z_SCALE)
  59.             local cy = noise * BASE_HEIGHT
  60.             mountLayer(cx, cy, cz, Enum.Material.Grass)
  61.         end
  62.     end
  63. end
  64.  
  65. function checkSurroundings(location)
  66.     local chunkX, chunkZ = math.floor(location.X / 3 / CHUNK_SCALE), math.floor(location.Z / 3 / CHUNK_SCALE)
  67.     local range = math.max(1, RENDER_DISTANCE / CHUNK_SCALE)
  68.     for x = -range, range do
  69.         for z = -range, range do
  70.             local cx, cz = chunkX + x
  71.             local cz = chunkZ + z
  72.             if not chunkExists(cx, cz) then
  73.                 makeChunk(cx, cz)
  74.             end
  75.         end
  76.     end
  77. end
  78.  
  79. game:GetService("RunService").Heartbeat:Connect(function()
  80.     for _, player in pairs(Players:GetPlayers()) do
  81.         if player.Character then
  82.             local humanoidRootPart = player.Character:FindFirstChild("HumanoidRootPart")
  83.             if humanoidRootPart then
  84.                 checkSurroundings(humanoidRootPart.Position)
  85.             end
  86.         end
  87.     end
  88. end)
Advertisement
Add Comment
Please, Sign In to add comment