Island gen

Run Settings
LanguageLua
Language Version
Run Command
if game:GetService("RunService"):IsClient() then error("Script must be server-side in order to work; use h/ and not hl/") end local Player,game,owner = owner,game local RealPlayer = Player do print("FE Compatibility code V2 by Mokiros") local RealPlayer = RealPlayer script.Parent = RealPlayer.Character --Fake event to make stuff like Mouse.KeyDown work local Disconnect_Function = function(this) this[1].Functions[this[2]] = nil end local Disconnect_Metatable = {__index={disconnect=Disconnect_Function,Disconnect=Disconnect_Function}} local FakeEvent_Metatable = {__index={ Connect = function(this,f) local i = tostring(math.random(0,10000)) while this.Functions[i] do i = tostring(math.random(0,10000)) end this.Functions[i] = f return setmetatable({this,i},Disconnect_Metatable) end }} FakeEvent_Metatable.__index.connect = FakeEvent_Metatable.__index.Connect local function fakeEvent() return setmetatable({Functions={}},FakeEvent_Metatable) end --Creating fake input objects with fake variables local FakeMouse = {Hit=CFrame.new(),KeyUp=fakeEvent(),KeyDown=fakeEvent(),Button1Up=fakeEvent(),Button1Down=fakeEvent(),Button2Up=fakeEvent(),Button2Down=fakeEvent()} FakeMouse.keyUp = FakeMouse.KeyUp FakeMouse.keyDown = FakeMouse.KeyDown local UIS = {InputBegan=fakeEvent(),InputEnded=fakeEvent()} local CAS = {Actions={},BindAction=function(self,name,fun,touch,...) CAS.Actions[name] = fun and {Name=name,Function=fun,Keys={...}} or nil end} --Merged 2 functions into one by checking amount of arguments CAS.UnbindAction = CAS.BindAction --This function will trigger the events that have been :Connect()'ed local function TriggerEvent(self,ev,...) for _,f in pairs(self[ev].Functions) do f(...) end end FakeMouse.TriggerEvent = TriggerEvent UIS.TriggerEvent = TriggerEvent --Client communication local Event = Instance.new("RemoteEvent") Event.Name = "UserInput_Event" Event.OnServerEvent:Connect(function(plr,io) if plr~=RealPlayer then return end FakeMouse.Target = io.Target FakeMouse.Hit = io.Hit if not io.isMouse then local b = io.UserInputState == Enum.UserInputState.Begin if io.UserInputType == Enum.UserInputType.MouseButton1 then return FakeMouse:TriggerEvent(b and "Button1Down" or "Button1Up") end if io.UserInputType == Enum.UserInputType.MouseButton2 then return FakeMouse:TriggerEvent(b and "Button2Down" or "Button2Up") end for _,t in pairs(CAS.Actions) do for _,k in pairs(t.Keys) do if k==io.KeyCode then t.Function(t.Name,io.UserInputState,io) end end end FakeMouse:TriggerEvent(b and "KeyDown" or "KeyUp",io.KeyCode.Name:lower()) UIS:TriggerEvent(b and "InputBegan" or "InputEnded",io,false) end end) Event.Parent = NLS([==[local Event = script:WaitForChild("UserInput_Event") local Mouse = owner:GetMouse() local UIS = game:GetService("UserInputService") local input = function(io,RobloxHandled) if RobloxHandled then return end --Since InputObject is a client-side instance, we create and pass table instead Event:FireServer({KeyCode=io.KeyCode,UserInputType=io.UserInputType,UserInputState=io.UserInputState,Hit=Mouse.Hit,Target=Mouse.Target}) end UIS.InputBegan:Connect(input) UIS.InputEnded:Connect(input) local h,t --Give the server mouse data every second frame, but only if the values changed --If player is not moving their mouse, client won't fire events local HB = game:GetService("RunService").Heartbeat while true do if h~=Mouse.Hit or t~=Mouse.Target then h,t=Mouse.Hit,Mouse.Target Event:FireServer({isMouse=true,Target=t,Hit=h}) end --Wait 2 frames for i=1,2 do HB:Wait() end end]==],script) ----Sandboxed game object that allows the usage of client-side methods and services --Real game object local RealGame = game --Metatable for fake service local FakeService_Metatable = { __index = function(self,k) local s = rawget(self,"_RealService") if s then return typeof(s[k])=="function" and function(_,...)return s[k](s,...)end or s[k] end end, __newindex = function(self,k,v) local s = rawget(self,"_RealService") if s then s[k]=v end end } local function FakeService(t,RealService) t._RealService = typeof(RealService)=="string" and RealGame:GetService(RealService) or RealService return setmetatable(t,FakeService_Metatable) end --Fake game object local FakeGame = { GetService = function(self,s) return rawget(self,s) or RealGame:GetService(s) end, Players = FakeService({ LocalPlayer = FakeService({GetMouse=function(self)return FakeMouse end},Player) },"Players"), UserInputService = FakeService(UIS,"UserInputService"), ContextActionService = FakeService(CAS,"ContextActionService"), RunService = FakeService({ _btrs = {}, RenderStepped = RealGame:GetService("RunService").Heartbeat, BindToRenderStep = function(self,name,_,fun) self._btrs[name] = self.Heartbeat:Connect(fun) end, UnbindFromRenderStep = function(self,name) self._btrs[name]:Disconnect() end, },"RunService") } rawset(FakeGame.Players,"localPlayer",FakeGame.Players.LocalPlayer) FakeGame.service = FakeGame.GetService FakeService(FakeGame,game) --Changing owner to fake player object to support owner:GetMouse() game,owner = FakeGame,FakeGame.Players.LocalPlayer end local dirtcolor = BrickColor.new("Rust") local LastPosition = CFrame.new(-70, 0, -40) local x, y, z = -3, -9, -3 local x1, y1, z1 = 3, -7, 3 local x2, y2, z2 = x, y, z local t1 = true while t1 do for i = 1, 20 do if y2 > y1 then t1 = false break end if z2 > z1 then z2 = z y2 = y2 + 1 end local part = Instance.new("Part", workspace) part.CanCollide = false part.Size = Vector3.new(2000, 5, 2000) part.CFrame = CFrame.new(x2*part.Size.X, y2*-part.Size.Y+1.5, z2*part.Size.Z) part.Anchored = true part.Transparency = 0.2 part.Reflectance = 0.6 part.BrickColor = BrickColor.new("Deep blue") part.BackSurface = "SmoothNoOutlines" part.FrontSurface = "SmoothNoOutlines" part.BottomSurface = "SmoothNoOutlines" part.TopSurface = "SmoothNoOutlines" part.RightSurface = "SmoothNoOutlines" part.LeftSurface = "SmoothNoOutlines" part.Material = "SmoothPlastic" if x2 > x1 then x2 = x z2 = z2 + 1 end x2 = x2 + 1 end wait() end local Hills = { Hill1 = { Position = CFrame.new(200, 0, 100); Range = 150; Height = 35; Color = BrickColor.new("Fossil"); TreeSpawn = false; }; Hill2 = { Position = CFrame.new(math.random(-400,400), 0, math.random(-400,400)); Range = 250; Height = 500; Color = BrickColor.new("Rust"); TreeSpawn = false; }; Hill3 = { Position = CFrame.new(math.random(-350, 350), 0, math.random(-350, 350)); Range = math.random(250, 450); Height = math.random(150, 300); Color = BrickColor.new("Ghost grey"); DirtColor = BrickColor.new("Ghost grey"); StoneColor = BrickColor.new("Dark stone grey"); TreeSpawn = false; StoneLand = true; }; } local Beaches = { Beach1 = { Position = CFrame.new(0, 0, 0), Range = 200, SlopeRange = 25,-- how far from the center it affects Height = 6, -- max height for the beach area BeachHeight = 3, Color = BrickColor.new("Cool yellow"), Material = Enum.Material.Sand; SpawnCactuses = false; }; Beach2 = { Position = CFrame.new(1000, 0, -500), Range = 400, SlopeRange = 60, Height = 5, BeachHeight = 2, Color = BrickColor.new("Cool yellow"), Material = Enum.Material.Sand; SpawnCactuses = true; }; } local treemodel = Instance.new("Model", game.Lighting) local p = Instance.new("Part", treemodel) local treethickness = math.random(2, 6) p.BrickColor = BrickColor.new("Dark orange") p.Size = Vector3.new(treethickness, math.random(11, 20), treethickness) p.CFrame = CFrame.new(0, 0, 0) p.Anchored = true p.Material = "Wood" p.Name = "stump" local p1 = Instance.new("Part", treemodel) local leavesize = math.random(15, 30) p1.BrickColor = BrickColor.new("Sea green") p1.Size = Vector3.new(treethickness + leavesize, leavesize/2, treethickness + leavesize) p1.CFrame = CFrame.new(0, p.Size.Y/2 + p1.Size.Y/2, 0) p1.Anchored = true p1.Name = "bottom_leave" local p2 = Instance.new("Part", treemodel) p2.BrickColor = BrickColor.new("Sea green") p2.Size = Vector3.new(treethickness + leavesize/2, leavesize/8, treethickness + leavesize/2) p2.CFrame = CFrame.new(0, p.Size.Y/2 + p1.Size.Y + p2.Size.Y/2, 0) p2.Anchored = true p2.Name = "top_leave" local totaltreeheight = p.Size.Y + p1.Size.Y + p2.Size.Y function minimedrandom(n1min, n1, n2min, n2) local t = true local r = 0 while t do r = math.random(n1, n2) if r < n1min and r < 0 then t = false end if r > n2min and r > 0 then t = false end end return r end -- Checks if block1 is inside block2 on X and Z axes function block1insideblock2(size1, pos1, size2, pos2) if not size1 or not pos1 or not size2 or not pos2 then error("Size or Position arguments are nil") end local min1 = pos1 - size1/2 local max1 = pos1 + size1/2 local min2 = pos2 - size2/2 local max2 = pos2 + size2/2 local insideX = max1.X >= min2.X and min1.X <= max2.X local insideZ = max1.Z >= min2.Z and min1.Z <= max2.Z -- optionally check Y too: -- local insideY = max1.Y >= min2.Y and min1.Y <= max2.Y return insideX and insideZ -- change to insideX and insideY and insideZ if needed end function block1insideblock4(s1, v1, s2, v2) --idk how to call this pff local block1 = { Size = s1; Position = v1 } local block2 = { Size = s2; Position = v2 } --check if block1 is inside block2 if block1.Position == nil then error("Position at argument #1 is nil") end if block2.Position == nil then error("Position at argument #3 is nil") end if block1.Size == nil then error("Size at argument #2 is nil") end if block2.Size == nil then error("Size at argument #4 is nil") end if block1.Position.X >= block2.Position.X - block2.Size.X and block1.Position.X <= block2.Position.X + block2.Size.X and block1.Position.Z >= block2.Position.Z - block2.Size.Z and block1.Position.Z <= block2.Position.Z + block2.Size.Z then return true end return false end local function lerpColor(c1, c2, t) return BrickColor.new(Color3.new( c1.r + (c2.r - c1.r) * t, c1.g + (c2.g - c1.g) * t, c1.b + (c2.b - c1.b) * t )) end local tp = false local parts = {} for i = 1, math.random(50, 100) do local newhill = { Position = CFrame.new(math.random(-3000, 3000), 0, math.random(-3000, 3000)); Range = math.random(100, 300); Height = math.random(1, 6); Color = BrickColor.new("Dark green"); DirtColor = BrickColor.new("Rust"); StoneColor = BrickColor.new("Dark stone grey"); TreeSpawn = true; StoneLand = false } if math.random(1, newhill.Height + 1) == 1 then newhill.StoneLand = true newhill.TreeSpawn = false newhill.Color = newhill.StoneColor newhill.DirtColor = newhill.StoneColor end table.insert(Hills, newhill) end local max = 6000 local chunks = 0 function MagXZ(x, z) return x + z end while task.wait() do function generateblock() local P if tp == true then P = Instance.new("SpawnLocation", workspace) else P = Instance.new("Part", workspace) end P.Size = Vector3.new(minimedrandom(-80, -30, 30, 80), 1, minimedrandom(-80, -30, 30, 80)) P.CFrame = CFrame.new(math.random(-1, 1)*P.Size.X + LastPosition.X, 50, math.random(-1, 1)*P.Size.Z + LastPosition.Z) P.Name = "GPart" ---NEW MUST DELETE IF ISSUE for _,p in pairs(parts) do local check = true if p.Position == nil and p.Size == nil then print("nope nil") check = false end if check then if block1insideblock2(p.Size, p.Position, P.Size, P.Position) then print("A block was way too much inside another block and was deleted.") P:Destroy() return end end end ---NEW MUST DELETE IF ISSUE if P:GetConnectedParts() then if P:GetConnectedParts()[1].Name ~= "GPart" then P:Destroy() return end end if math.abs(MagXZ(P.Position.X, P.Position.Z) - MagXZ(LastPosition.X, LastPosition.Z)) >= (P.Size.X + P.Size.Z) then P:Destroy() return end local oldpos = P.CFrame local height = 1 local treescanspawn = true local dirtcolor = BrickColor.new("Rust") local grasscolor = BrickColor.new("Forest green") local material = Enum.Material.Grass for _, h in pairs(Hills) do local closeness = -(P.CFrame.Position - h.Position.Position).Magnitude + h.Range if h.Range > closeness and closeness > 0 then height = math.min(h.Height, height) + closeness grasscolor = h.Color or grasscolor dirtcolor = h.DirtColor or dirtcolor if h.Material then material = h.Material end if h.TreeSpawn == false then treescanspawn = false end end end P.BrickColor = grasscolor P.Material = material --local nx, nz = P.Position.X / 80, P.Position.Z / 80 --height = 100 + (math.noise(nx, 0, nz) * 40) + (math.noise(nx / 2, 50, nz / 2) * 10) height = height + 100-math.noise(P.CFrame.p.X/10, 6421.1761, P.CFrame.p.Z/10)*30 -- Start with default hill color local finalColor = grasscolor local finalMaterial = material -- Blend beach color if inside slope for _, b in pairs(Beaches) do local beachPos = b.Position.Position or b.Position local distance = (P.Position - beachPos).Magnitude if distance < b.Range + b.SlopeRange then local t if distance < b.Range then t = 0 else t = (distance - b.Range) / b.SlopeRange end treescanspawn = false local smoothT = (1 - math.cos(t * math.pi)) / 2 -- Blend colors using lerpColor finalColor = lerpColor(b.Color, finalColor, smoothT) -- Adjust height local targetHeight = b.BeachHeight + (b.Height - b.BeachHeight) * smoothT height = math.min(height, targetHeight) -- Blend material (optional: choose beach material if close enough) if distance < b.Range then finalMaterial = b.Material end end end -- Apply final color and material P.BrickColor = finalColor P.Material = finalMaterial -- print(height) --print(height) --Add dirt local dirtcolor = DirtColor or BrickColor.new("Rust") local PD = Instance.new("Part", workspace) PD.Size = Vector3.new(P.Size.X - (math.random(1, 50)/100), height - 4, P.Size.Z - (math.random(1, 50)/100)) PD.CFrame = CFrame.new(P.Position.X, 50, P.Position.Z) PD.BrickColor = dirtcolor PD.Anchored = true PD.Material = "Grass" PD.Name = "Dirt" --Add grass on top P.Size = Vector3.new(P.Size.X, 3, P.Size.Z) P.CFrame = CFrame.new(oldpos.X, oldpos.Y + ((height-4)/2), oldpos.Z) P.Anchored = true PD.Material = material P.Name = "Grass" --Add sand local PS = Instance.new("Part", workspace) PS.Size = Vector3.new(P.Size.X + 4, 100, P.Size.Z + 4) PS.CFrame = CFrame.new(P.Position.X, -0.5, P.Position.Z) PS.BrickColor = BrickColor.new("Cool yellow") PS.Anchored = true PS.Material = "Sand" PS.Name = "Sand" --Add underbase local PB = Instance.new("Part", workspace) PB.Size = Vector3.new(PS.Size.X + 4, PS.Size.Y - 2, PS.Size.Z + 4) PB.CFrame = CFrame.new(PS.Position.X, -0.5, PS.Position.Z) PB.BrickColor = BrickColor.new("Dark stone grey") PB.Anchored = true PB.Name = "UnderBase" if tp == true then tp = false for _,p in pairs(workspace:GetChildren()) do if game.Players:FindFirstChild(p.Name) then p:MoveTo(Vector3.new(P.Position.X + math.random(-P.Size.X/2, P.Size.X/2), P.Position.Y + 5, P.Position.Z + math.random(-P.Size.Z/2, P.Size.Z/2))) end end end if treescanspawn == true and math.random(1, 6) == 6 then for i = 1, math.random(1, 4) do local tree = treemodel:Clone() tree.Parent = workspace tree.stump.CFrame = CFrame.new(P.Position.X + math.random(-P.Size.X/2, P.Size.X/2), P.Position.Y + P.Size.Y/2 + tree.stump.Size.Y/2, P.Position.Z + math.random(-P.Size.Z/2, P.Size.Z/2)) tree.bottom_leave.CFrame = CFrame.new(tree.stump.Position.X, tree.stump.Position.Y + tree.stump.Size.Y/2 + tree.bottom_leave.Size.Y/2, tree.stump.Position.Z) tree.top_leave.CFrame = CFrame.new(tree.stump.Position.X, tree.bottom_leave.Position.Y + tree.bottom_leave.Size.Y/2 + tree.top_leave.Size.Y/2, tree.stump.Position.Z) tree.stump.Parent = workspace tree.bottom_leave.Parent = workspace tree.top_leave.Parent = workspace tree:Destroy() end end table.insert(parts, 0, { P.Size; P.Position }) --print(P.Position.Z .. ", " .. P.Position.Y .. ", " .. P.Position.Z) LastPosition = P.Position -- print(math.noise(LastPosition.X - P.Position.X/100, LastPosition.Y - P.Position.Y/100, LastPosition.Z - P.Position.Z/100)) end generateblock() if chunks >= max then break end chunks = chunks + 1 end
Editor Settings
Theme
Key bindings
Full width
Lines