Lewati ke konten
Berfungsi

ORBITAL — Mine a Planet

CLclarkdevlinorg0 tayanganUniversal26 Jul 2026
Bagikan
ORBITAL — Mine a Planet

Kode Script

Lua
-- ORBITAL - Mine a Planet [BETA 8]
if game.PlaceId ~= 121125129560252 then return end

local BOOTOK, BOOTERR = pcall(function()

local Players           = game:GetService("Players")
local TweenService      = game:GetService("TweenService")
local UserInputService  = game:GetService("UserInputService")
local RS                = game:GetService("ReplicatedStorage")
local LP                = Players.LocalPlayer
local Net               = RS:WaitForChild("Net")

local HOST = (gethui and gethui()) or game:GetService("CoreGui")
for _, root in ipairs({ HOST, LP:FindFirstChild("PlayerGui") }) do
	if root then for _, n in ipairs({ "Orbital", "OrbitalBoot" }) do
		local o = root:FindFirstChild(n); if o then pcall(function() o:Destroy() end) end
	end end
end

local DEF = { autoCollect=false, autoSell=false, autoUpgrade=false, autoEvent=false, autoRoll=false,
	rarities = { Divine=true, Exotic=true, Prismatic=true, Transcendent=true, Void=true },
	returnHome=true, notify=true, collectMs=140 }
local S = getgenv().OrbitalX
if not S then S = {}; getgenv().OrbitalX = S; for k,v in pairs(DEF) do S[k]=v end end
for k,v in pairs(DEF) do if S[k]==nil then S[k]=v end end
if S._cleanup then pcall(S._cleanup); task.wait(0.1) end
S.run = true
local GEN = (S._gen or 0)+1; S._gen = GEN
local function live() return S.run==true and S._gen==GEN end
-- stats can survive a hot reload from an older build, so backfill every field
local stats = S._stats or {}
stats.collected = stats.collected or 0
stats.upgrades  = stats.upgrades  or 0
stats.rolls     = stats.rolls     or 0
stats.errors    = stats.errors    or 0
S._stats = stats

local conns = {}
if getgenv()._OrbitalConns then for _,c in ipairs(getgenv()._OrbitalConns) do pcall(function() c:Disconnect() end) end end
getgenv()._OrbitalConns = {}
local function track(c) if c then conns[#conns+1]=c; table.insert(getgenv()._OrbitalConns,c) end return c end

-- theme
local C = { bg=Color3.fromRGB(12,14,20), surf=Color3.fromRGB(19,22,31), surf2=Color3.fromRGB(27,31,43),
	line=Color3.fromRGB(60,70,96), txt=Color3.fromRGB(236,240,250), sub=Color3.fromRGB(132,144,172),
	acc=Color3.fromRGB(96,170,255), good=Color3.fromRGB(80,214,140), bad=Color3.fromRGB(240,96,110) }
local FB,FM,FR = Enum.Font.GothamBold, Enum.Font.GothamMedium, Enum.Font.Gotham
local function mk(cls,p,k) local i=Instance.new(cls) for a,b in pairs(p) do i[a]=b end if k then for _,c in ipairs(k) do c.Parent=i end end return i end
local function corner(r) return mk("UICorner",{CornerRadius=UDim.new(0,r or 8)}) end
local function stroke(t,c) return mk("UIStroke",{Transparency=t or 0.8,Color=c or C.line,Thickness=1}) end
local function pad(n) return mk("UIPadding",{PaddingTop=UDim.new(0,n),PaddingBottom=UDim.new(0,n),PaddingLeft=UDim.new(0,n),PaddingRight=UDim.new(0,n)}) end
local function tw(o,p,t,st) TweenService:Create(o,TweenInfo.new(t or 0.18,st or Enum.EasingStyle.Quad,Enum.EasingDirection.Out),p):Play() end

-- ======================================================= root gui (hidden) =
local gui = mk("ScreenGui",{Name="Orbital",ResetOnSpawn=false,ZIndexBehavior=Enum.ZIndexBehavior.Sibling,DisplayOrder=999,Enabled=false,Parent=HOST})

local toasts = mk("Frame",{AnchorPoint=Vector2.new(1,0),Position=UDim2.new(1,-18,0,18),Size=UDim2.new(0,300,1,-36),
	BackgroundTransparency=1,Parent=gui},{mk("UIListLayout",{Padding=UDim.new(0,8),HorizontalAlignment=Enum.HorizontalAlignment.Right,SortOrder=Enum.SortOrder.LayoutOrder})})
local function notify(title,msg,kind)
	if not S.notify then return end
	local col=(kind=="bad" and C.bad) or (kind=="good" and C.good) or C.acc
	local card=mk("Frame",{Size=UDim2.new(1,0,0,0),AutomaticSize=Enum.AutomaticSize.Y,BackgroundColor3=C.surf,
		Position=UDim2.new(1,40,0,0),Parent=toasts},{corner(10),stroke(0.72)})
	mk("Frame",{Size=UDim2.new(0,3,1,0),BackgroundColor3=col,BorderSizePixel=0,Parent=card})
	local body=mk("Frame",{Position=UDim2.new(0,14,0,0),Size=UDim2.new(1,-24,0,0),AutomaticSize=Enum.AutomaticSize.Y,
		BackgroundTransparency=1,Parent=card},{mk("UIPadding",{PaddingTop=UDim.new(0,10),PaddingBottom=UDim.new(0,11)}),
		mk("UIListLayout",{Padding=UDim.new(0,2),SortOrder=Enum.SortOrder.LayoutOrder})})
	mk("TextLabel",{BackgroundTransparency=1,Size=UDim2.new(1,0,0,15),Text=title,TextColor3=C.txt,
		TextXAlignment=Enum.TextXAlignment.Left,Font=FM,TextSize=13,LayoutOrder=1,Parent=body})
	mk("TextLabel",{BackgroundTransparency=1,Size=UDim2.new(1,0,0,0),AutomaticSize=Enum.AutomaticSize.Y,Text=msg,
		TextColor3=C.sub,TextWrapped=true,TextXAlignment=Enum.TextXAlignment.Left,Font=FR,TextSize=11,LayoutOrder=2,Parent=body})
	tw(card,{Position=UDim2.new(0,0,0,0)},0.28)
	task.delay(5,function() if card.Parent then tw(card,{Position=UDim2.new(1,40,0,0)},0.25) task.wait(0.3) pcall(function() card:Destroy() end) end end)
end
S._notify=notify

local errLast, errLog = {}, {}
S._errLog=errLog
local function report(f,e)
	stats.errors=stats.errors+1
	local m=tostring(e):gsub("^.-:%d+: ",""):sub(1,110)
	table.insert(errLog,1,{f=f,e=m,t=os.date("%H:%M:%S")}); if #errLog>30 then table.remove(errLog) end
	local now=os.clock()
	if not errLast[f] or now-errLast[f]>20 then errLast[f]=now; notify("Error: "..f,m,"bad") end
end
local function loopify(fn,delay,name)
	task.spawn(function() while live() do
		local ok,err=xpcall(fn,function(e) return tostring(e).." | "..debug.traceback("",2):gsub("%s+"," "):sub(1,160) end)
		if not ok then report(name,err) end
		task.wait((type(delay)=="function" and delay()) or delay)
	end end)
end

-- ======================================================= game bindings ====
local function R(n) return Net:FindFirstChild(n) end
local MYID = LP.UserId
local function ownerOf(i) local a=i.Parent for _=1,6 do if not a then return end local v=a:GetAttribute("FS_UserId") if v then return v end a=a.Parent end end
local myDocks = {}
local function reindexDocks()
	table.clear(myDocks)
	for _,d in ipairs(workspace:GetDescendants()) do
		if d:IsA("BasePart") and d:GetAttribute("FS_OreCount")~=nil and ownerOf(d)==MYID then
			local pr=d:FindFirstChildWhichIsA("ProximityPrompt"); if pr then myDocks[d]=pr end
		end
	end
end
pcall(reindexDocks)
local function myOre() local t,n=0,0 for p in pairs(myDocks) do local ok,v=pcall(function() return p.Parent and p:GetAttribute("FS_OreCount") or nil end) if ok and v then t=t+v n=n+1 end end return t,n end

-- native perk toggles (player already owns these; this is the game's own path)
local function setPerk(key,val)
	local r=R("SetAutoPerk"); if not r then return false end
	local ok=pcall(function() r:FireServer({key=key,value=val}) end)
	return ok
end

-- upgrade state cache
local UP = {
	{k="luck",        req="RequestUpgradeLuck",        sync="LuckSync",        label="Luck"},
	{k="dockStorage", req="RequestUpgradeDockStorage", sync="DockStorageSync", label="Dock Storage"},
	{k="laser",       req="RequestUpgradeLaserPower",  sync="LaserSync",       label="Laser"},
	{k="droneRolls",  req="RequestUpgradeDroneRolls",  sync="DroneRollSync",   label="Drone Rolls"},
	{k="planet",      req="RequestUpgradePlanet",      sync="PlanetSync",      label="Planet"},
	{k="cargo",       req="RequestUpgradeCargo",       sync="CargoSync",       label="Cargo"},
}
local upState = {}
S._upState = upState
for _,u in ipairs(UP) do
	local r=R(u.sync)
	if r then track(r.OnClientEvent:Connect(function(payload)
		local st=payload
		if type(st)=="table" and st.nextCost==nil and st.level==nil then
			for _,v in pairs(st) do if type(v)=="table" and (v.nextCost~=nil or v.level~=nil) then st=v break end end
		end
		upState[u.k]=st
	end)) end
end
local cash=0
do local r=R("CurrencySync")
	if r then track(r.OnClientEvent:Connect(function(p)
		local s=p; if type(s)=="table" and s.m==nil then for _,v in pairs(s) do if type(v)=="table" and v.m then s=v break end end end
		if type(s)=="table" and s.m then cash=(s.m or 0)*10^(s.e or 0) end
	end)) end
end
local function pullState() pcall(function() local r=R("RequestStateSync") if r then r:FireServer() end end) end
pullState()

-- forward declared: the automation loops below are defined before the movement helpers
local hrpOf, flyTo, myEventDrops, mySellPad

-- ======================================================= event drops =====
-- Mirrors GlobalDropController's protocol exactly:
--   sync  {campaignId, scope="server"|"global", drops={{dropId,position,expiresAt}}}
--         {clear=true, scope}            -> wipe that scope
--         {claimResult={dropId,status,retryAfter}}
--   claim RequestGlobalDropClaim:FireServer{dropId, campaignId, scope}
-- The game gates claims client-side on distance (<=8 studs); we skip that and claim by id,
-- but we DO honour its 2s per-drop throttle, the retry backoff, and the server's
-- EventDropConfig.maxClaimsPerMinute = 90 cap so we never trip rate limiting.
local drops, claimTimes = {}, {}
local ev = S._ev or { claimed=0, rejected=0, attempts=0 }
S._ev = ev; S._drops = drops
local MAX_CLAIMS_PER_MIN = 85          -- config says 90; stay just under

do
	local r = R("GlobalDropSync")
	if r then track(r.OnClientEvent:Connect(function(p)
		if type(p) ~= "table" then return end
		if p.clear == true and (p.scope == "server" or p.scope == "global") then
			for id, d in pairs(drops) do if d.scope == p.scope then drops[id] = nil end end
			return
		end
		local cr = p.claimResult
		if type(cr) == "table" and type(cr.dropId) == "string" then
			if cr.status == "claimed" then drops[cr.dropId] = nil; ev.claimed = ev.claimed + 1
			elseif cr.status == "terminal" then drops[cr.dropId] = nil; ev.rejected = ev.rejected + 1
			elseif cr.status == "retry" then
				local d = drops[cr.dropId]
				if d then d.nextClaimAt = os.clock() + math.clamp(tonumber(cr.retryAfter) or 1, 0.5, 2) end
			end
			return
		end
		if type(p.campaignId) == "string" and (p.scope == "server" or p.scope == "global") and type(p.drops) == "table" then
			for _, v in ipairs(p.drops) do
				if type(v) == "table" and type(v.dropId) == "string" and typeof(v.position) == "Vector3" and drops[v.dropId] == nil then
					drops[v.dropId] = { position = v.position, expiresAt = v.expiresAt,
						campaignId = p.campaignId, scope = p.scope, nextClaimAt = 0 }
				end
			end
		end
	end)) end
end

local function dropCount() local n = 0 for _ in pairs(drops) do n = n + 1 end return n end
local function shards(kind) return LP:GetAttribute("FS_EventShards_" .. kind) or 0 end

-- Auto roll. The game's native SetAutoRollActive is gamepass gated (FS_GP_autoRoll), and the
-- server rejects it if unowned, so we drive the roll action itself instead. Targets are still
-- pushed so the native panel stays in sync if the pass is ever owned.
loopify(function()
	if not S.autoRoll then return end
	local r = R("RequestRollDrones"); if not r then return end
	pcall(function() r:FireServer({}) end)
	stats.rolls = (stats.rolls or 0) + 1
end, 1.1, "Auto roll")

-- Incident shard pickup is validated SERVER-SIDE (EventDropConfig.pickupRadiusStuds = 8) and
-- there is no client claim remote for it, so it cannot be done from range. What we can do is
-- park at the sky beam where drops spawn (radius 110 around FS_SkyBeamAnchor) - which is exactly
-- what any player farming the event does, so it reads as completely normal.
local function eventActive() return #myEventDrops() > 0 end
S._eventActive = eventActive

-- Fly over each of OUR drops. The server grants the shard on proximity (8 studs), which is
-- exactly the manual "fly over it" action, just driven automatically. Returns home after.
loopify(function()
	if not S.autoEvent then return end
	if not (S._myDrops and S._flyTo and S._hrpOf) then return end
	local list = S._myDrops()
	ev.pending = #list
	if #list == 0 then return end
	local hrp = S._hrpOf(); if not hrp then return end
	local home = hrp.Position
	for _, drop in ipairs(list) do
		if not live() or not S.autoEvent then break end
		if drop.Parent then
			-- must close to ~3 studs: the server only grants the pickup on true contact range
			local ok = S._flyTo(drop.Position, 3)
			ev.moves = (ev.moves or 0) + 1
			if ok then
				task.wait(0.8)                      -- let the server register the pickup
				if not drop.Parent then ev.claimed = ev.claimed + 1 end
			end
		end
	end
	if S.returnHome ~= false then S._flyTo(home, 6) end
end, 2.5, "Event shards")

-- Auto sell. The native autoSell perk is gamepass gated (FS_GP_autoSell) and the server refuses
-- to enable it when unowned, so we do it the manual way: fly to OUR sell pad (prompt range is 16)
-- fire "Sell All", then fly back. Only runs when the backpack actually holds ore.
loopify(function()
	if not S.autoSell then return end
	if not (S._mySellPad and S._flyTo and S._hrpOf) then return end
	local ore = LP:GetAttribute("FS_BackpackOre") or 0
	if ore <= 0 then return end
	local anchor, prompt = S._mySellPad()
	if not anchor then return end
	local hrp = S._hrpOf(); if not hrp then return end
	local home = hrp.Position
	local dist = (anchor.Position - hrp.Position).Magnitude
	if dist > 12 then
		if not S._flyTo(anchor.Position + Vector3.new(0, 3, 0), 8) then return end
	end
	if prompt and fireproximityprompt then
		for _ = 1, 3 do
			pcall(fireproximityprompt, prompt)
			task.wait(0.35)
			if (LP:GetAttribute("FS_BackpackOre") or 0) <= 0 then break end
		end
	end
	stats.sells = (stats.sells or 0) + 1
	if S.returnHome ~= false and dist > 12 then S._flyTo(home, 6) end
end, 6, "Auto sell")

-- ======================================================= movement ========
-- Both shard pickup and selling are validated SERVER-SIDE by proximity, so they genuinely
-- require being there. We glide in steps (~160 studs/s, close to the game's own jetpack) so it
-- reads as normal flying rather than a snap teleport, and we return to where we started.
hrpOf = function() local ch=LP.Character; return ch and ch:FindFirstChild("HumanoidRootPart") end
S._hrpOf = hrpOf
-- Travel at the character's REAL jetpack speed. Moving faster than FS_JetpackFlightSpeed trips
-- the server's movement correction (FS_MovementCorrectionToken climbs and you get yanked back),
-- which is exactly why the first version never arrived. At legit speed it is just normal flight.
flyTo = function(pos, arrive, timeout)
	local hrp=hrpOf(); if not hrp then return false end
	arrive = arrive or 6
	local speed = (LP:GetAttribute("FS_JetpackFlightSpeed") or 80) * 0.9
	local dt = 0.06
	local perStep = math.max(2, speed * dt)
	local t0 = os.clock()
	timeout = timeout or math.clamp((pos - hrp.Position).Magnitude / math.max(speed, 1) + 6, 8, 30)
	while live() and os.clock()-t0 < timeout do
		local h = hrpOf(); if not h then return false end
		local cur = h.Position
		local d = pos - cur
		if d.Magnitude <= arrive then return true end
		local ok = pcall(function() h.CFrame = CFrame.new(cur + d.Unit * math.min(d.Magnitude, perStep)) end)
		if not ok then return false end
		task.wait(dt)
	end
	local h = hrpOf()
	return (h ~= nil) and (h.Position - pos).Magnitude <= arrive + 4
end
S._flyTo = flyTo

-- our own event drops only. Other players' drops live in sibling folders and are not ours to take.
-- Two kinds of drops live under FarmStar.EventDrops:
--   Shared/      -> the actual EVENT SHARDS, FS_DropOwner == 0, free for anyone to fly over
--   <userId>/    -> private drops (consumables/batteries) owned by that player
-- We take the shared shards plus our OWN private drops, never another player's.
myEventDrops = function()
	local out={}
	local fs=workspace:FindFirstChild("FarmStar"); if not fs then return out end
	local eds=fs:FindFirstChild("EventDrops"); if not eds then return out end
	local now=os.time()
	local hrp=hrpOf()
	local here=hrp and hrp.Position or Vector3.new()
	local function scan(folder)
		if not folder then return end
		for _,d in ipairs(folder:GetDescendants()) do
			if d:IsA("BasePart") and d.Name=="FS_EventDrop" then
				local exp=d:GetAttribute("FS_DropExpireAt")
				local owner=d:GetAttribute("FS_DropOwner")
				if (owner==0 or owner==LP.UserId) and (type(exp)~="number" or exp>now) then
					out[#out+1]=d
				end
			end
		end
	end
	scan(eds:FindFirstChild("Shared"))
	scan(eds:FindFirstChild(tostring(LP.UserId)))
	-- shards first, then nearest first, so the valuable pickups are never missed on a short event
	table.sort(out, function(a,b)
		local sa = (a:GetAttribute("FS_DropKind")=="shard") and 1 or 0
		local sb = (b:GetAttribute("FS_DropKind")=="shard") and 1 or 0
		if sa ~= sb then return sa > sb end
		return (a.Position-here).Magnitude < (b.Position-here).Magnitude
	end)
	return out
end
S._myDrops=myEventDrops

-- our own sell pad (each plot has one under Platforms.<userId>.Shops)
mySellPad = function()
	local fs=workspace:FindFirstChild("FarmStar"); if not fs then return nil end
	local plats=fs:FindFirstChild("Platforms"); if not plats then return nil end
	local mine=plats:FindFirstChild(tostring(LP.UserId)); if not mine then return nil end
	local anchor=mine:FindFirstChild("FS_SellPromptAnchor", true)
	if not anchor then return nil end
	local prompt=anchor:FindFirstChildWhichIsA("ProximityPrompt")
	return anchor, prompt
end
S._mySellPad=mySellPad

-- ======================================================= drones ==========
-- Rarity ladder + catalog come straight from the game's own config, so the target
-- list we hand to SetAutoRollTargets is exactly what its own panel would send.
local DroneCatalog, RarityConfig
pcall(function()
	local Cfg = RS:WaitForChild("Config")
	DroneCatalog = require(Cfg:WaitForChild("DroneCatalog"))
	RarityConfig = require(Cfg:WaitForChild("RarityConfig"))
end)
local RARITY_ORDER = (RarityConfig and RarityConfig.order) or
	{ "Common","Uncommon","Rare","Epic","Legendary","Mythic","Secret","Divine","Exotic","Prismatic","Transcendent","Void" }
local function rankOf(rarity)
	if RarityConfig and RarityConfig.rank then local ok,v = pcall(RarityConfig.rank, rarity); if ok and type(v)=="number" then return v end end
	for i,r in ipairs(RARITY_ORDER) do if r == rarity then return i end end
	return 0
end
local function rarityOfDrone(key)
	if DroneCatalog and DroneCatalog.rarity then local ok,v = pcall(DroneCatalog.rarity, key); if ok then return v end end
	return nil
end
local function targetsForSelection()
	local out, seen = {}, {}
	if not (DroneCatalog and DroneCatalog.obtainableDronesOfRarity) then return out end
	for _, r in ipairs(RARITY_ORDER) do
		if S.rarities and S.rarities[r] then
			local ok, list = pcall(DroneCatalog.obtainableDronesOfRarity, r)
			if ok and type(list) == "table" then
				for _, k in ipairs(list) do if type(k)=="string" and not seen[k] then seen[k]=true; out[#out+1]=k end end
			end
		end
	end
	return out
end
local function pushRollTargets()
	local t = targetsForSelection()
	pcall(function() local r=R("SetAutoRollTargets"); if r then r:FireServer({ targets = t }) end end)
	return #t
end
local function setRollActive(v)
	pcall(function() local r=R("SetAutoRollActive"); if r then r:FireServer({ active = v and true or false }) end end)
end

-- drone inventory mirror (InventorySync items: {uid, kind, droneType, location, level, favorite})
local invItems = {}
S._inv = invItems
do
	local r = R("InventorySync")
	if r then track(r.OnClientEvent:Connect(function(p)
		local src = p
		if type(src) == "table" and src.items == nil then
			for _, v in pairs(src) do if type(v)=="table" and v.items then src = v break end end
		end
		local items = type(src)=="table" and src.items or nil
		if type(items) ~= "table" then return end
		table.clear(invItems)
		for _, it in pairs(items) do if type(it)=="table" and it.kind=="drone" then invItems[#invItems+1]=it end end
	end)) end
end
-- returns: placedCount, storedCount, list of upgrade suggestions {dock, from, to, gain}
local function droneAnalysis()
	local placed, stored = {}, {}
	for _, it in ipairs(invItems) do
		local loc = tostring(it.location or "")
		local d = { uid=it.uid, key=it.droneType, fav=it.favorite,
			rank=rankOf(rarityOfDrone(it.droneType)), rarity=rarityOfDrone(it.droneType) }
		local dock = loc:match("^dock:(%d+)")
		if dock then d.dock = tonumber(dock); placed[#placed+1]=d else stored[#stored+1]=d end
	end
	table.sort(placed, function(a,b) return a.rank < b.rank end)          -- weakest first
	table.sort(stored, function(a,b) return a.rank > b.rank end)          -- strongest first
	local sugg, si = {}, 1
	for _, weak in ipairs(placed) do
		local best = stored[si]
		if best and best.rank > weak.rank and not weak.fav then
			sugg[#sugg+1] = { dock=weak.dock, from=weak.key, fromR=weak.rarity, to=best.key, toR=best.rarity }
			si = si + 1
		end
	end
	return placed, stored, sugg
end
S._droneAnalysis = droneAnalysis

-- ======================================================= loading screen ===
local bootDone = false
do
	local bg = mk("ScreenGui",{Name="OrbitalBoot",ResetOnSpawn=false,IgnoreGuiInset=true,DisplayOrder=1000,Parent=HOST})
	local card = mk("Frame",{AnchorPoint=Vector2.new(0.5,0.5),Position=UDim2.new(0.5,0,0.5,0),Size=UDim2.new(0,380,0,140),
		BackgroundColor3=C.surf,BackgroundTransparency=1,Parent=bg},{corner(16),stroke(0.55)})
	mk("UIGradient",{Rotation=90,Color=ColorSequence.new(Color3.fromRGB(255,255,255),Color3.fromRGB(170,170,170)),Parent=card})
	local dot = mk("Frame",{Position=UDim2.new(0,26,0,28),Size=UDim2.new(0,20,0,20),BackgroundColor3=C.acc,
		BackgroundTransparency=1,Parent=card},{corner(6)})
	local t1 = mk("TextLabel",{BackgroundTransparency=1,Position=UDim2.new(0,58,0,26),Size=UDim2.new(1,-80,0,22),Text="ORBITAL",
		TextColor3=C.txt,TextTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Font=FB,TextSize=22,Parent=card})
	local t2 = mk("TextLabel",{BackgroundTransparency=1,Position=UDim2.new(0,58,0,50),Size=UDim2.new(1,-80,0,16),Text="mine a planet",
		TextColor3=C.sub,TextTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Font=FR,TextSize=12,Parent=card})
	local step = mk("TextLabel",{BackgroundTransparency=1,Position=UDim2.new(0,26,1,-46),Size=UDim2.new(1,-52,0,14),Text="",
		TextColor3=C.sub,TextTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Font=FR,TextSize=11,Parent=card})
	local barBg = mk("Frame",{Position=UDim2.new(0,26,1,-28),Size=UDim2.new(1,-52,0,5),BackgroundColor3=C.surf2,
		BackgroundTransparency=1,BorderSizePixel=0,Parent=card},{corner(3)})
	local bar = mk("Frame",{Size=UDim2.new(0,0,1,0),BackgroundColor3=C.acc,BorderSizePixel=0,Parent=barBg},{corner(3)})
	tw(card,{BackgroundTransparency=0.02},0.3) tw(dot,{BackgroundTransparency=0},0.3)
	tw(t1,{TextTransparency=0},0.35) tw(t2,{TextTransparency=0},0.4)
	tw(step,{TextTransparency=0},0.4) tw(barBg,{BackgroundTransparency=0},0.4)
	task.spawn(function()
		local steps={"reading plot","indexing docks","binding remotes","syncing state","ready"}
		for i,s in ipairs(steps) do
			if step.Parent then step.Text=s end
			tw(bar,{Size=UDim2.new(i/#steps,0,1,0)},0.26)
			task.wait(0.26)
		end
		task.wait(0.2)
		tw(card,{BackgroundTransparency=1},0.3) tw(t1,{TextTransparency=1},0.28) tw(t2,{TextTransparency=1},0.28)
		tw(step,{TextTransparency=1},0.28) tw(dot,{BackgroundTransparency=1},0.28) tw(barBg,{BackgroundTransparency=1},0.28)
		task.wait(0.34)
		pcall(function() bg:Destroy() end)
		bootDone = true
		gui.Enabled = true                                  -- window only appears AFTER the loader
	end)
end

-- ======================================================= window ===========
local W,H = 560, 400
local win = mk("Frame",{Name="Win",AnchorPoint=Vector2.new(0.5,0.5),Position=UDim2.new(0.5,0,0.5,0),
	Size=UDim2.new(0,W,0,H),BackgroundColor3=C.bg,Active=true,Draggable=true,Parent=gui},{corner(16),stroke(0.5)})
mk("UIGradient",{Rotation=90,Color=ColorSequence.new(Color3.fromRGB(255,255,255),Color3.fromRGB(184,184,184)),Parent=win})

local bar = mk("Frame",{Size=UDim2.new(1,0,0,56),BackgroundTransparency=1,Parent=win})
mk("Frame",{Position=UDim2.new(0,20,0.5,-10),Size=UDim2.new(0,20,0,20),BackgroundColor3=C.acc,Parent=bar},{corner(6)})
mk("TextLabel",{BackgroundTransparency=1,Position=UDim2.new(0,52,0,12),Size=UDim2.new(1,-150,0,19),Text="ORBITAL",
	TextColor3=C.txt,TextXAlignment=Enum.TextXAlignment.Left,Font=FB,TextSize=18,Parent=bar})
mk("TextLabel",{BackgroundTransparency=1,Position=UDim2.new(0,52,0,33),Size=UDim2.new(1,-150,0,14),Text="mine a planet",
	TextColor3=C.sub,TextXAlignment=Enum.TextXAlignment.Left,Font=FR,TextSize=11,Parent=bar})
local cashLbl = mk("TextLabel",{AnchorPoint=Vector2.new(1,0.5),Position=UDim2.new(1,-58,0.5,0),Size=UDim2.new(0,150,0,18),
	Text="",TextColor3=C.good,TextXAlignment=Enum.TextXAlignment.Right,Font=FM,TextSize=13,BackgroundTransparency=1,Parent=bar})
local hideB = mk("TextButton",{AnchorPoint=Vector2.new(1,0.5),Position=UDim2.new(1,-18,0.5,0),Size=UDim2.new(0,28,0,28),
	BackgroundColor3=C.surf2,Text="-",TextColor3=C.txt,Font=FB,TextSize=16,AutoButtonColor=false,Parent=bar},{corner(8)})
mk("Frame",{Position=UDim2.new(0,20,0,56),Size=UDim2.new(1,-40,0,1),BackgroundColor3=C.line,
	BackgroundTransparency=0.6,BorderSizePixel=0,Parent=win})

local side = mk("Frame",{Position=UDim2.new(0,16,0,68),Size=UDim2.new(0,136,1,-84),BackgroundColor3=C.surf,Parent=win},
	{corner(12),mk("UIListLayout",{Padding=UDim.new(0,5),SortOrder=Enum.SortOrder.LayoutOrder}),pad(8)})
local content = mk("Frame",{Position=UDim2.new(0,166,0,68),Size=UDim2.new(1,-182,1,-84),BackgroundTransparency=1,ClipsDescendants=true,Parent=win})

local pages,tabs = {},{}
local function selectTab(id)
	for k,pg in pairs(pages) do pg.Visible=(k==id) end
	for k,b in pairs(tabs) do
		tw(b,{BackgroundTransparency=(k==id) and 0 or 1},0.15)
		local l=b:FindFirstChildOfClass("TextLabel"); if l then l.TextColor3=(k==id) and C.txt or C.sub end
	end
end
local tOrd=0
local function addTab(id,label)
	tOrd=tOrd+1
	local b=mk("TextButton",{Size=UDim2.new(1,0,0,34),BackgroundColor3=C.surf2,BackgroundTransparency=1,Text="",
		AutoButtonColor=false,LayoutOrder=tOrd,Parent=side},{corner(9)})
	mk("TextLabel",{BackgroundTransparency=1,Position=UDim2.new(0,12,0,0),Size=UDim2.new(1,-16,1,0),Text=label,
		TextColor3=C.sub,TextXAlignment=Enum.TextXAlignment.Left,Font=FM,TextSize=13,Parent=b})
	local pg=mk("ScrollingFrame",{Size=UDim2.new(1,0,1,0),BackgroundTransparency=1,BorderSizePixel=0,Visible=false,
		CanvasSize=UDim2.new(),AutomaticCanvasSize=Enum.AutomaticSize.Y,ScrollBarThickness=3,ScrollBarImageColor3=C.acc,Parent=content},
		{mk("UIListLayout",{Padding=UDim.new(0,9),SortOrder=Enum.SortOrder.LayoutOrder})})
	pages[id]=pg tabs[id]=b
	track(b.MouseButton1Click:Connect(function() selectTab(id) end))
	return pg
end
local ord=0
local function O() ord=ord+1 return ord end
local function sect(p,t) mk("TextLabel",{BackgroundTransparency=1,Size=UDim2.new(1,0,0,14),Text=string.upper(t),
	TextColor3=C.sub,TextXAlignment=Enum.TextXAlignment.Left,Font=FB,TextSize=10,LayoutOrder=O(),Parent=p}) end
local function Toggle(p,label,key,cb)
	local row=mk("Frame",{Size=UDim2.new(1,0,0,42),BackgroundColor3=C.surf,LayoutOrder=O(),Parent=p},{corner(10),stroke(0.85)})
	mk("TextLabel",{BackgroundTransparency=1,Position=UDim2.new(0,14,0,0),Size=UDim2.new(1,-70,1,0),Text=label,
		TextColor3=C.txt,TextXAlignment=Enum.TextXAlignment.Left,Font=FM,TextSize=13,Parent=row})
	local knob=mk("Frame",{AnchorPoint=Vector2.new(1,0.5),Position=UDim2.new(1,-12,0.5,0),Size=UDim2.new(0,42,0,22),
		BackgroundColor3=S[key] and C.acc or C.surf2,Parent=row},{corner(11)})
	local dot=mk("Frame",{AnchorPoint=Vector2.new(0,0.5),Position=UDim2.new(0,S[key] and 22 or 2,0.5,0),Size=UDim2.new(0,18,0,18),
		BackgroundColor3=C.txt,Parent=knob},{corner(9)})
	local btn=mk("TextButton",{BackgroundTransparency=1,Size=UDim2.new(1,0,1,0),Text="",Parent=row})
	track(btn.MouseButton1Click:Connect(function()
		S[key]=not S[key]
		tw(knob,{BackgroundColor3=S[key] and C.acc or C.surf2},0.15)
		tw(dot,{Position=UDim2.new(0,S[key] and 22 or 2,0.5,0)},0.15)
		if cb then pcall(cb,S[key]) end
	end))
end
local function card(p,h) return mk("Frame",{Size=UDim2.new(1,0,0,h),BackgroundColor3=C.surf,LayoutOrder=O(),Parent=p},{corner(10),stroke(0.85),pad(13)}) end

local U={}
do local p=addTab("auto","Automation")
	sect(p,"Ore")
	Toggle(p,"Auto collect","autoCollect",function(v) setPerk("autoCollect",v) end)
	Toggle(p,"Auto sell","autoSell",function(v) setPerk("autoSell",v) end)
	sect(p,"Status")
	local c=card(p,58)
	U.s1=mk("TextLabel",{BackgroundTransparency=1,Size=UDim2.new(1,0,0,17),Text="",TextColor3=C.txt,
		TextXAlignment=Enum.TextXAlignment.Left,Font=FM,TextSize=13,Parent=c})
	U.s2=mk("TextLabel",{BackgroundTransparency=1,Position=UDim2.new(0,0,0,20),Size=UDim2.new(1,0,0,16),Text="",
		TextColor3=C.sub,TextXAlignment=Enum.TextXAlignment.Left,Font=FR,TextSize=11,Parent=c})
end
do local p=addTab("upg","Upgrades")
	sect(p,"Auto")
	Toggle(p,"Auto upgrade all","autoUpgrade")
	sect(p,"Tracks")
	U.upRows={}
	for _,u in ipairs(UP) do
		local c=card(p,38)
		mk("TextLabel",{BackgroundTransparency=1,Size=UDim2.new(0.5,0,1,0),Text=u.label,TextColor3=C.txt,
			TextXAlignment=Enum.TextXAlignment.Left,Font=FM,TextSize=12,Parent=c})
		U.upRows[u.k]=mk("TextLabel",{BackgroundTransparency=1,Position=UDim2.new(0.5,0,0,0),Size=UDim2.new(0.5,0,1,0),Text="-",
			TextColor3=C.sub,TextXAlignment=Enum.TextXAlignment.Right,Font=FR,TextSize=11,Parent=c})
	end
end
do local p=addTab("drn","Drones")
	sect(p,"Auto roll")
	Toggle(p,"Auto roll drones","autoRoll",function(v)
		local n=pushRollTargets(); setRollActive(v)
		if v then notify("Auto roll on", n.." drone types targeted","good") end
	end)
	sect(p,"Target rarities")
	local grid=mk("Frame",{Size=UDim2.new(1,0,0,0),AutomaticSize=Enum.AutomaticSize.Y,BackgroundTransparency=1,LayoutOrder=O(),Parent=p},
		{mk("UIGridLayout",{CellSize=UDim2.new(0.5,-4,0,30),CellPadding=UDim2.new(0,8,0,8),SortOrder=Enum.SortOrder.LayoutOrder})})
	U.rarChips={}
	for _,r in ipairs(RARITY_ORDER) do
		local on=(S.rarities and S.rarities[r]) and true or false
		local chip=mk("TextButton",{BackgroundColor3=on and C.acc or C.surf,Text="",AutoButtonColor=false,Parent=grid},{corner(8),stroke(0.85)})
		local lb=mk("TextLabel",{BackgroundTransparency=1,Size=UDim2.new(1,0,1,0),Text=r,
			TextColor3=on and Color3.fromRGB(12,16,26) or C.sub,Font=FM,TextSize=11,Parent=chip})
		U.rarChips[r]={chip=chip,lb=lb}
		track(chip.MouseButton1Click:Connect(function()
			S.rarities=S.rarities or {}
			S.rarities[r]=not S.rarities[r]
			local o=S.rarities[r] and true or false
			tw(chip,{BackgroundColor3=o and C.acc or C.surf},0.14)
			lb.TextColor3 = o and Color3.fromRGB(12,16,26) or C.sub
			local n=pushRollTargets()
			if U.rollInfo then U.rollInfo.Text=n.." drone types targeted" end
		end))
	end
	U.rollInfo=mk("TextLabel",{BackgroundTransparency=1,Size=UDim2.new(1,0,0,16),Text="",TextColor3=C.sub,
		TextXAlignment=Enum.TextXAlignment.Left,Font=FR,TextSize=11,LayoutOrder=O(),Parent=p})
	sect(p,"Loadout")
	local dc=card(p,58)
	U.d1=mk("TextLabel",{BackgroundTransparency=1,Size=UDim2.new(1,0,0,17),Text="",TextColor3=C.txt,
		TextXAlignment=Enum.TextXAlignment.Left,Font=FM,TextSize=13,Parent=dc})
	U.d2=mk("TextLabel",{BackgroundTransparency=1,Position=UDim2.new(0,0,0,20),Size=UDim2.new(1,0,0,16),Text="",
		TextColor3=C.sub,TextXAlignment=Enum.TextXAlignment.Left,Font=FR,TextSize=11,Parent=dc})
	sect(p,"Suggested swaps")
	U.swapBox=mk("Frame",{Size=UDim2.new(1,0,0,116),BackgroundColor3=C.surf,LayoutOrder=O(),Parent=p},
		{corner(10),stroke(0.85),pad(11),mk("UIListLayout",{Padding=UDim.new(0,4),SortOrder=Enum.SortOrder.LayoutOrder})})
	U.swapEmpty=mk("TextLabel",{BackgroundTransparency=1,Size=UDim2.new(1,0,0,15),Text="Loadout is optimal",
		TextColor3=C.sub,TextXAlignment=Enum.TextXAlignment.Left,Font=FR,TextSize=11,Parent=U.swapBox})
end

do local p=addTab("evt","Events")
	sect(p,"Shard farming")
	Toggle(p,"Auto collect shards","autoEvent")
	Toggle(p,"Return to start after","returnHome")
	sect(p,"Progress")
	local c1=card(p,44)
	mk("TextLabel",{BackgroundTransparency=1,Size=UDim2.new(0.45,0,1,0),Text="UFO",TextColor3=C.txt,
		TextXAlignment=Enum.TextXAlignment.Left,Font=FM,TextSize=13,Parent=c1})
	U.ufo=mk("TextLabel",{BackgroundTransparency=1,Position=UDim2.new(0.45,0,0,0),Size=UDim2.new(0.55,0,1,0),Text="-",
		TextColor3=C.sub,TextXAlignment=Enum.TextXAlignment.Right,Font=FR,TextSize=12,Parent=c1})
	local c2=card(p,44)
	mk("TextLabel",{BackgroundTransparency=1,Size=UDim2.new(0.45,0,1,0),Text="JellyFish",TextColor3=C.txt,
		TextXAlignment=Enum.TextXAlignment.Left,Font=FM,TextSize=13,Parent=c2})
	U.jelly=mk("TextLabel",{BackgroundTransparency=1,Position=UDim2.new(0.45,0,0,0),Size=UDim2.new(0.55,0,1,0),Text="-",
		TextColor3=C.sub,TextXAlignment=Enum.TextXAlignment.Right,Font=FR,TextSize=12,Parent=c2})
	sect(p,"Live")
	local c3=card(p,58)
	U.e1=mk("TextLabel",{BackgroundTransparency=1,Size=UDim2.new(1,0,0,17),Text="",TextColor3=C.txt,
		TextXAlignment=Enum.TextXAlignment.Left,Font=FM,TextSize=13,Parent=c3})
	U.e2=mk("TextLabel",{BackgroundTransparency=1,Position=UDim2.new(0,0,0,20),Size=UDim2.new(1,0,0,16),Text="",
		TextColor3=C.sub,TextXAlignment=Enum.TextXAlignment.Left,Font=FR,TextSize=11,Parent=c3})
end

do local p=addTab("diag","Diagnostics")
	sect(p,"Health")
	local c=card(p,40)
	U.health=mk("TextLabel",{BackgroundTransparency=1,Size=UDim2.new(1,0,1,0),Text="Nominal",TextColor3=C.good,
		TextXAlignment=Enum.TextXAlignment.Left,Font=FM,TextSize=13,Parent=c})
	sect(p,"Errors")
	U.errBox=mk("Frame",{Size=UDim2.new(1,0,0,120),BackgroundColor3=C.surf,LayoutOrder=O(),Parent=p},
		{corner(10),stroke(0.85),pad(11),mk("UIListLayout",{Padding=UDim.new(0,4),SortOrder=Enum.SortOrder.LayoutOrder})})
	U.errEmpty=mk("TextLabel",{BackgroundTransparency=1,Size=UDim2.new(1,0,0,15),Text="None",TextColor3=C.sub,
		TextXAlignment=Enum.TextXAlignment.Left,Font=FR,TextSize=11,Parent=U.errBox})
	Toggle(p,"Notifications","notify")
end
selectTab("auto")

-- ======================================================= loops ============
loopify(function()
	if not S.autoCollect then return end
	local n=0
	for part,pr in pairs(myDocks) do
		if not live() then break end
		local ok,ore=pcall(function() return part.Parent and (part:GetAttribute("FS_OreCount") or 0) or nil end)
		if not ok or ore==nil then myDocks[part]=nil
		elseif ore>0 and pr.Parent then pcall(fireproximityprompt,pr) n=n+1 task.wait(0.03) end
	end
	if n>0 then stats.collected=stats.collected+n end
end, function() return (S.collectMs or 140)/1000 end, "Auto collect")

loopify(function() reindexDocks() end, 12, "Dock reindex")
loopify(function() pullState() end, 6, "State sync")

-- auto upgrade: buy any track that is not maxed and is affordable
loopify(function()
	if not S.autoUpgrade then return end
	for _,u in ipairs(UP) do
		if not live() then break end
		local st=upState[u.k]
		if type(st)=="table" and type(st.nextCost)=="number" and cash>=st.nextCost then
			local r=R(u.req)
			if r then
				pcall(function() r:FireServer({}) end)
				stats.upgrades=stats.upgrades+1
				task.wait(0.4)
			end
		end
	end
end, 3, "Auto upgrade")

loopify(function()
	local ore,docks=myOre()
	if U.s1 then U.s1.Text=string.format("Docks %d    Ore %d", docks, ore) end
	if U.s2 then U.s2.Text=string.format("Collected %d    Upgrades %d", stats.collected, stats.upgrades) end
	if cashLbl then
		local v=cash
		local s = v>=1e12 and string.format("%.2fT",v/1e12) or v>=1e9 and string.format("%.2fB",v/1e9)
			or v>=1e6 and string.format("%.2fM",v/1e6) or v>=1e3 and string.format("%.1fk",v/1e3) or string.format("%d",v)
		cashLbl.Text=s
	end
	for _,u in ipairs(UP) do
		local lb=U.upRows and U.upRows[u.k]
		if lb then
			local st=upState[u.k]
			if type(st)~="table" then lb.Text="-" lb.TextColor3=C.sub
			elseif st.nextCost==nil then lb.Text="MAX" lb.TextColor3=C.good
			else
				local c=st.nextCost
				local s = c>=1e12 and string.format("%.2fT",c/1e12) or c>=1e9 and string.format("%.2fB",c/1e9)
					or c>=1e6 and string.format("%.2fM",c/1e6) or c>=1e3 and string.format("%.1fk",c/1e3) or tostring(c)
				lb.Text=(st.level and ("L"..tostring(st.level).."   ") or "")..s
				lb.TextColor3=(cash>=c) and C.acc or C.sub
			end
		end
	end
	do
		local u,j = shards("UFO"), shards("JellyFish")
		if U.ufo then U.ufo.Text=string.format("%d/10 shards    %d token%s", u%10, math.floor(u/10), (math.floor(u/10)==1) and "" or "s")
			U.ufo.TextColor3=(u>0) and C.acc or C.sub end
		if U.jelly then U.jelly.Text=string.format("%d/10 shards    %d token%s", j%10, math.floor(j/10), (math.floor(j/10)==1) and "" or "s")
			U.jelly.TextColor3=(j>0) and C.acc or C.sub end
		local pend = ev.pending or 0
		if U.e1 then U.e1.Text = (pend > 0) and (pend .. " drop" .. ((pend == 1) and "" or "s") .. " waiting") or "No drops right now" end
		if U.e2 then U.e2.Text = string.format("Picked up %d    Trips %d    Backpack %s",
			ev.claimed or 0, ev.moves or 0, tostring(LP:GetAttribute("FS_BackpackOre") or 0)) end
	end
	do
		local placed, stored, sugg = droneAnalysis()
		if U.d1 then U.d1.Text=string.format("Placed %d    Stored %d", #placed, #stored) end
		if U.d2 then
			local bestP = placed[#placed]; local bestS = stored[1]
			U.d2.Text = string.format("Best placed %s    Best stored %s",
				(bestP and (bestP.rarity or "?")) or "-", (bestS and (bestS.rarity or "?")) or "-")
		end
		if U.swapBox then
			for _,ch in ipairs(U.swapBox:GetChildren()) do if ch:IsA("TextLabel") and ch~=U.swapEmpty then ch:Destroy() end end
			U.swapEmpty.Visible=(#sugg==0)
			for i=1,math.min(#sugg,5) do local s=sugg[i]
				mk("TextLabel",{BackgroundTransparency=1,Size=UDim2.new(1,0,0,15),
					Text=string.format("Dock %s   %s -> %s", tostring(s.dock), tostring(s.fromR or s.from), tostring(s.toR or s.to)),
					TextColor3=C.acc,TextTruncate=Enum.TextTruncate.AtEnd,TextXAlignment=Enum.TextXAlignment.Left,
					Font=FR,TextSize=10,LayoutOrder=i,Parent=U.swapBox})
			end
		end
	end
	if U.health then
		U.health.Text=(stats.errors==0) and "Nominal" or (stats.errors.." error(s)")
		U.health.TextColor3=(stats.errors==0) and C.good or C.bad
	end
	if U.errBox then
		for _,ch in ipairs(U.errBox:GetChildren()) do if ch:IsA("TextLabel") and ch~=U.errEmpty then ch:Destroy() end end
		U.errEmpty.Visible=(#errLog==0)
		for i=1,math.min(#errLog,5) do local e=errLog[i]
			mk("TextLabel",{BackgroundTransparency=1,Size=UDim2.new(1,0,0,15),Text=e.t.."  "..e.f..": "..e.e,TextColor3=C.bad,
				TextTruncate=Enum.TextTruncate.AtEnd,TextXAlignment=Enum.TextXAlignment.Left,Font=FR,TextSize=10,LayoutOrder=i,Parent=U.errBox})
		end
	end
end, 1, "UI")

-- chrome
local shown=true
track(hideB.MouseButton1Click:Connect(function()
	shown=not shown
	tw(win,{Size=shown and UDim2.new(0,W,0,H) or UDim2.new(0,W,0,56)},0.22)
	side.Visible=shown content.Visible=shown
end))
track(UserInputService.InputBegan:Connect(function(i,gp)
	if gp then return end
	if i.KeyCode==Enum.KeyCode.RightControl and bootDone then gui.Enabled=not gui.Enabled end
end))

S._cleanup=function() S.run=false for _,c in ipairs(conns) do pcall(function() c:Disconnect() end) end pcall(function() gui:Destroy() end) end

task.delay(2.2,function() if live() then notify("Ready","Wave 2 online.","good") end end)

end)

if not BOOTOK then warn("[ORBITAL] "..tostring(BOOTERR)) end

Deskripsi

Ore Auto collect — pulls ore from your docks across all floors. Only fires on docks that actually hold ore, and only ever touches your own plot. Auto sell — flies to your sell pad, sells, then returns to where you were. Separate toggle, so you can collect without selling. Upgrades Auto upgrade buys any track that isn't maxed once you can afford it. Luck and Planet work now; the per-floor tracks (laser, cargo, dock storage) are still being mapped. All six show live cost and MAX status. Events Collects UFO and Jellyfish shards during incidents by flying over the drops, prioritising shards over item drops and taking the nearest first. Returns to your starting spot afterwards, and skips other players' drops. Shows shard progress and token count for both events. Drones Auto roll with a rarity picker across all twelve tiers, so you can target only what you care about. Loadout analyser compares your placed drones against storage and lists which docks could be upgraded. It reports suggestions only — it won't move drones for you yet, since the swap call isn't verified and I'd rather not risk your inventory. Diagnostics Every feature runs guarded. If one fails it's listed with the reason and line number, and you get a single notification rather than repeated spam.

Komentar (0)

Masuk untuk ikut berdiskusi

  • Jadilah yang pertama berkomentar.

Pertanyaan yang sering diajukan

Bagaimana cara menggunakan script ORBITAL — Mine a Planet?
Salin kode script di atas, buka executor Roblox Anda, tempel kodenya, lalu tekan execute saat Anda berada di dalam game. Fitur akan aktif seketika setelah script berjalan.
Apakah script ORBITAL — Mine a Planet gratis?
Ya. Script ini gratis untuk disalin dan digunakan. Jika menggunakan sistem kunci, ikuti tautan "Dapatkan kunci" untuk membukanya tanpa biaya.
Apakah script ORBITAL — Mine a Planet aman digunakan?
Kode sumber lengkap ditampilkan di halaman ini sehingga Anda bisa membaca persis apa yang dilakukannya sebelum menjalankannya. Selalu gunakan executor tepercaya, dan ingat bahwa menggunakan script melanggar ketentuan layanan Roblox, jadi gunakan dengan risiko Anda sendiri.
Executor mana yang kompatibel dengan ORBITAL — Mine a Planet?
Script ini bekerja dengan sebagian besar executor Roblox populer. Lihat halaman executor kami untuk menemukan executor gratis atau berbayar yang tepercaya untuk perangkat Anda.
ORBITAL — Mine a Planet | BloxScripter