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