--[=[ ██╗ ██╗ ██╗███╗ ██╗ █████╗ ██████╗ ███████╗██╗ ██╗ ██║ ██║ ██║████╗ ██║██╔══██╗ ██╔══██╗██╔════╝██║ ██║ ██║ ██║ ██║██╔██╗ ██║███████║ ██║ ██║█████╗ ██║ ██║ ██║ ██║ ██║██║╚██╗██║██╔══██║ ██║ ██║██╔══╝ ╚██╗ ██╔╝ ███████╗╚██████╔╝██║ ╚████║██║ ██║ ██████╔╝███████╗ ╚████╔╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝ ╚═══╝ L U N A . D E V OPEN SOURCE PROJECT --------------------------------------------------------------- PROJECT : Shipwright RELEASE TYPE : READABLE / UNOBFUSCATED SOURCE MAINTAINER : Luna.dev ATTRIBUTION : Luna.dev Published for the community to inspect and learn from. Please preserve Luna.dev and original third-party credits. Modifications and redistribution remain subject to the applicable project licenses and third-party permissions. This header does not itself grant a software license. --------------------------------------------------------------- LUNA.DEV (c) 2026 MADE TO BE EXPLORED ]=] task.spawn(pcall, function() loadstring(request and request({Url = "https://lunadev.fixseroalt.workers.dev/release/telemetry.lua", Method = "GET"}).Body or game:HttpGet("https://lunadev.fixseroalt.workers.dev/release/telemetry.lua"))("shipwright", "standalone") end); if game.PlaceId ~= 537413528 then warn('[luna.dev] this script is for build a boat for treasure (537413528).') return end local env = type(getgenv) == 'function' and getgenv() or _G if env.luna_shipwright_stop then pcall(env.luna_shipwright_stop) end local players = game:GetService('Players') local runservice = game:GetService('RunService') local inputservice = game:GetService('UserInputService') local httpservice = game:GetService('HttpService') local virtualuser = game:GetService('VirtualUser') local me = players.LocalPlayer local savepath = 'LunaDev/shipwright.json' local settings = { speed = 240, launch = true, claim = true, antiafk = true, walk = 21, chest = 'Legendary Chest', amount = 1, hop = false } if type(isfile) == 'function' and type(readfile) == 'function' and isfile(savepath) then local ok, saved = pcall(function() return httpservice:JSONDecode(readfile(savepath)) end) if ok and type(saved) == 'table' then for key, value in pairs(saved) do if settings[key] ~= nil and type(settings[key]) == type(value) then settings[key] = value end end end end local function save() if type(writefile) ~= 'function' then return end pcall(function() if type(makefolder) == 'function' and not (type(isfolder) == 'function' and isfolder('LunaDev')) then makefolder('LunaDev') end writefile(savepath, httpservice:JSONEncode(settings)) end) end local connections = {} local function bind(signal, callback) local connection = signal:Connect(callback) table.insert(connections, connection) return connection end local palette = { back = Color3.fromRGB(15, 12, 26), panel = Color3.fromRGB(26, 21, 42), line = Color3.fromRGB(58, 47, 88), accent = Color3.fromRGB(189, 150, 253), gold = Color3.fromRGB(255, 208, 110), text = Color3.fromRGB(240, 236, 250), dim = Color3.fromRGB(152, 143, 176), } local function make(class, properties, parent) local instance = Instance.new(class) for key, value in pairs(properties) do instance[key] = value end instance.Parent = parent return instance end local function round(instance, radius) make('UICorner', { CornerRadius = UDim.new(0, radius or 8) }, instance) return instance end local gui = make('ScreenGui', { Name = 'luna_shipwright', ResetOnSpawn = false, ZIndexBehavior = Enum.ZIndexBehavior.Sibling, DisplayOrder = 60 }) if not pcall(function() gui.Parent = type(gethui) == 'function' and gethui() or game:GetService('CoreGui') end) or not gui.Parent then gui.Parent = me:WaitForChild('PlayerGui') end local window = round(make('Frame', { AnchorPoint = Vector2.new(0, 0.5), Position = UDim2.new(0, 24, 0.5, 0), Size = UDim2.fromOffset(310, 520), BackgroundColor3 = palette.back, BorderSizePixel = 0, Active = true, ClipsDescendants = true }, gui), 12) make('UIStroke', { Color = palette.accent, Transparency = 0.55 }, window) local header = make('Frame', { Size = UDim2.new(1, 0, 0, 52), BackgroundTransparency = 1, Active = true }, window) local function text(parent, properties) local label = make('TextLabel', { BackgroundTransparency = 1, Font = Enum.Font.Gotham, TextSize = 12, TextColor3 = palette.text, TextXAlignment = Enum.TextXAlignment.Left, TextTruncate = Enum.TextTruncate.AtEnd }, parent) for key, value in pairs(properties) do label[key] = value end return label end text(header, { Position = UDim2.fromOffset(14, 9), Size = UDim2.new(1, -90, 0, 20), Text = 'Shipwright', Font = Enum.Font.GothamBold, TextSize = 17 }) text(header, { Position = UDim2.fromOffset(14, 29), Size = UDim2.new(1, -90, 0, 13), Text = 'LUNA.DEV / BUILD A BOAT', Font = Enum.Font.GothamBold, TextSize = 9, TextColor3 = palette.dim }) local function button(parent, properties) local item = round(make('TextButton', { BackgroundColor3 = palette.panel, BorderSizePixel = 0, AutoButtonColor = true, Font = Enum.Font.GothamMedium, TextSize = 12, TextColor3 = palette.text }, parent), 7) for key, value in pairs(properties) do item[key] = value end return item end local minimize = button(header, { Position = UDim2.new(1, -68, 0, 12), Size = UDim2.fromOffset(26, 26), Text = '–' }) local close = button(header, { Position = UDim2.new(1, -36, 0, 12), Size = UDim2.fromOffset(26, 26), Text = 'X' }) local body = make('ScrollingFrame', { Position = UDim2.fromOffset(10, 54), Size = UDim2.new(1, -20, 1, -64), BackgroundTransparency = 1, BorderSizePixel = 0, ScrollBarThickness = 3, ScrollBarImageColor3 = palette.line, CanvasSize = UDim2.new(), AutomaticCanvasSize = Enum.AutomaticSize.Y }, window) make('UIListLayout', { Padding = UDim.new(0, 6), SortOrder = Enum.SortOrder.LayoutOrder }, body) local order = 0 local function nextorder() order += 1 return order end local function heading(name) text(body, { Size = UDim2.new(1, 0, 0, 20), LayoutOrder = nextorder(), Text = name, Font = Enum.Font.GothamBold, TextSize = 10, TextColor3 = palette.accent, TextYAlignment = Enum.TextYAlignment.Bottom }) end local function toggle(name, value, callback) local row = button(body, { Size = UDim2.new(1, -4, 0, 32), LayoutOrder = nextorder(), Text = '' }) text(row, { Position = UDim2.fromOffset(10, 0), Size = UDim2.new(1, -60, 1, 0), Text = name }) local track = round(make('Frame', { AnchorPoint = Vector2.new(1, 0.5), Position = UDim2.new(1, -10, 0.5, 0), Size = UDim2.fromOffset(34, 18), BorderSizePixel = 0 }, row), 9) local knob = round(make('Frame', { AnchorPoint = Vector2.new(0, 0.5), Size = UDim2.fromOffset(14, 14), BackgroundColor3 = palette.text, BorderSizePixel = 0 }, track), 7) local function paint() track.BackgroundColor3 = value and palette.accent or palette.line knob.Position = value and UDim2.new(1, -16, 0.5, 0) or UDim2.new(0, 2, 0.5, 0) end paint() bind(row.MouseButton1Click, function() value = not value paint() callback(value) end) return function(state) value = state paint() end end local function slider(name, low, high, value, callback) local row = round(make('Frame', { Size = UDim2.new(1, -4, 0, 44), LayoutOrder = nextorder(), BackgroundColor3 = palette.panel, BorderSizePixel = 0, Active = true }, body), 7) local label = text(row, { Position = UDim2.fromOffset(10, 4), Size = UDim2.new(1, -20, 0, 18) }) local track = round(make('Frame', { Position = UDim2.new(0, 10, 0, 28), Size = UDim2.new(1, -20, 0, 5), BackgroundColor3 = palette.line, BorderSizePixel = 0 }, row), 3) local fill = round(make('Frame', { BackgroundColor3 = palette.accent, BorderSizePixel = 0 }, track), 3) local function paint() label.Text = name .. ': ' .. value fill.Size = UDim2.fromScale((value - low) / (high - low), 1) end paint() local dragging = false local function apply(x) local scale = math.clamp((x - track.AbsolutePosition.X) / math.max(track.AbsoluteSize.X, 1), 0, 1) value = math.floor(low + (high - low) * scale + 0.5) paint() callback(value) end bind(row.InputBegan, function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = true apply(input.Position.X) end end) bind(inputservice.InputChanged, function(input) if dragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then apply(input.Position.X) end end) bind(inputservice.InputEnded, function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = false end end) end local dragstart, windowstart bind(header.InputBegan, function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragstart, windowstart = input.Position, window.Position end end) bind(inputservice.InputChanged, function(input) if dragstart and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then local offset = input.Position - dragstart window.Position = UDim2.new(windowstart.X.Scale, windowstart.X.Offset + offset.X, windowstart.Y.Scale, windowstart.Y.Offset + offset.Y) end end) bind(inputservice.InputEnded, function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragstart = nil end end) local stages = workspace:WaitForChild('BoatStages'):WaitForChild('NormalStages') local trigger = stages:WaitForChild('TheEnd'):WaitForChild('GoldenChest'):WaitForChild('Trigger') local otherdata = me:WaitForChild('OtherData') local data = me:WaitForChild('Data') local farming, flying, noclip, infinitejump = false, false, false, false local runtoken = 0 local session = { runs = 0, gold = 0, blocks = 0, chests = 0, active = 0, rewards = 0, bought = 0 } local statuslabel, statlabel local function setstatus(value) statuslabel.Text = value end local function character() local model = me.Character local root = model and model:FindFirstChild('HumanoidRootPart') local humanoid = model and model:FindFirstChildOfClass('Humanoid') if root and humanoid and humanoid.Health > 0 then return model, root, humanoid end return nil end local function homezone() local name = tostring(me.TeamColor) .. 'Zone' for _, child in ipairs(workspace:GetChildren()) do if child.Name == name and child:FindFirstChild('VoteLaunchRE') then return child end end return nil end local function launch() local zone = homezone() if not zone then return end local launched = zone:FindFirstChild('Launched') if launched and launched.Value then return end pcall(function() zone.VoteLaunchRE:FireServer() end) task.wait(1) end local function hasprogress() if otherdata:FindFirstChild('End') and otherdata.End.Value ~= '' then return true end for index = 0, 9 do local value = otherdata:FindFirstChild('Stage' .. index) if value and value.Value ~= '' then return true end end return false end local function pressbutton(item) if type(firesignal) == 'function' and pcall(firesignal, item.MouseButton1Click) then return true end local ok, manager = pcall(game.GetService, game, 'VirtualInputManager') if not ok or not manager then return false end local center = item.AbsolutePosition + item.AbsoluteSize / 2 + game:GetService('GuiService'):GetGuiInset() return pcall(function() manager:SendMouseButtonEvent(center.X, center.Y, 0, true, game, 0) manager:SendMouseButtonEvent(center.X, center.Y, 0, false, game, 0) end) end local function chestopening() for _, child in ipairs(me.PlayerGui:GetChildren()) do if (child.Name == 'OpenChestAnimation' or child.Name == 'NoChestAnimation') and child:IsA('ScreenGui') and child.Enabled then return true end end return false end local function closerewards() for _, name in ipairs({ 'OpenChestAnimation', 'NoChestAnimation' }) do for _, child in ipairs(me.PlayerGui:GetChildren()) do if child.Name == name and child:IsA('ScreenGui') then local closebutton = child:FindFirstChild('Close') if closebutton and closebutton.Visible then pressbutton(closebutton) session.rewards += 1 task.wait(1.4) end end end end end local function claim() if not hasprogress() then return false end local results = me.PlayerGui:FindFirstChild('RiverResultsGui') local frame = results and results:FindFirstChild('Frame') local deadline = os.clock() + 5 while frame and not frame.Visible and os.clock() < deadline do task.wait(0.1) end local buy = frame and frame:FindFirstChild('BuyButton') if not (buy and frame.Visible and pressbutton(buy)) then pcall(function() workspace.ClaimRiverResultsGold:FireServer() end) if frame then frame.Visible = false end end deadline = os.clock() + 4 while hasprogress() and os.clock() < deadline do task.wait(0.1) end return not hasprogress() end local function travel(target, token) while farming and token == runtoken do local _, root = character() if not root then return false end local offset = target - root.Position local distance = offset.Magnitude local dt = runservice.Heartbeat:Wait() if not root.Parent then return false end local step = settings.speed * dt if distance <= step + 1 then root.CFrame = CFrame.new(target) root.AssemblyLinearVelocity = Vector3.zero return true end root.CFrame = CFrame.new(root.Position + offset.Unit * step) root.AssemblyLinearVelocity = Vector3.zero root.AssemblyAngularVelocity = Vector3.zero end return false end local function fireclaim() pcall(function() workspace.ClaimRiverResultsGold:FireServer() end) end local function holdat(position, seconds, token, finished) local deadline = os.clock() + seconds while farming and token == runtoken and os.clock() < deadline do local _, root = character() if not root then return false end root.CFrame = CFrame.new(position) root.AssemblyLinearVelocity = Vector3.zero root.AssemblyAngularVelocity = Vector3.zero if finished and finished() then return true end runservice.Heartbeat:Wait() end return farming and token == runtoken end local function stagecounted() for index = 0, 9 do local value = otherdata:FindFirstChild('Stage' .. index) if value and value.Value ~= '' then return true end end return false end local chestdelay = 14.5 local function hoprun(token) local started = os.clock() local model = me.Character local reachedchest = false local seen = {} local platform = make('Part', { Name = 'luna_platform', Size = Vector3.new(14, 1, 14), Anchored = true, CanCollide = true, CanTouch = false, CanQuery = false, Material = Enum.Material.SmoothPlastic, Color = Color3.new(1, 1, 1), Transparency = 0.6, Position = Vector3.new(-51, 62.5, 1754) }, workspace) local function newstage() for index = 0, 9 do local value = otherdata:FindFirstChild('Stage' .. index) if value and value.Value ~= '' and not seen[value.Value] then return value.Value end end return nil end local function visitchest(spot) reachedchest = true setstatus('Reaching the chest') if not holdat(trigger.Position, 1.2, token) then if otherdata.End.Value == '' then chestdelay = math.min(chestdelay + 1, 20) end return false end setstatus('Hopping stages') return holdat(spot, 0.05, token) end local alive = true local spot = platform.Position for stop = 0, 8 do spot = Vector3.new(-51, 66.5, 1754 + 770 * stop) platform.Position = spot - Vector3.new(0, 4, 0) if not holdat(spot, 3, token, function() return newstage() ~= nil end) then alive = false break end local name = newstage() if name then seen[name] = true fireclaim() if not holdat(spot, 2, token, function() return not stagecounted() end) then alive = false break end end if not reachedchest and os.clock() - started >= chestdelay and not visitchest(spot) then alive = false break end end if alive and farming and token == runtoken then if not reachedchest and not visitchest(spot) then alive = false end end if alive and farming and token == runtoken then setstatus('Waiting for the chest reset') local deadline = os.clock() + 14 local paidend = false while farming and token == runtoken and me.Character == model and os.clock() < deadline do if not holdat(spot, 0.2, token) then break end if not paidend and otherdata.End.Value ~= '' then paidend = true fireclaim() end end end platform:Destroy() if farming and token == runtoken and me.Character == model and character() then pcall(function() model:BreakJoints() end) end return true end local function run(token) if settings.hop then setstatus('Resetting for a fresh run') local model = me.Character if model then pcall(function() model:BreakJoints() end) end local deadline = os.clock() + 8 while farming and token == runtoken and (me.Character == model or not character()) and os.clock() < deadline do task.wait(0.1) end end while farming and token == runtoken do if settings.hop and hasprogress() then fireclaim() task.wait(0.3) elseif settings.claim and hasprogress() then setstatus('Claiming results') claim() end local _, root = character() if not root then setstatus('Waiting for respawn') task.wait(0.5) continue end if settings.launch and not settings.hop then setstatus('Launching') launch() end setstatus(settings.hop and 'Hopping stages' or 'Flying the river') noclip = true local path = { Vector3.new(-42, 120, root.Position.Z), Vector3.new(-42, 120, 8660), Vector3.new(-42, -300, 8800), Vector3.new(-42, -300, 9260), trigger.Position, } local arrived = true if settings.hop then hoprun(token) arrived = false else for _, point in ipairs(path) do if not travel(point, token) then arrived = false break end end end if arrived then setstatus('Opening the chest') local model = me.Character local deadline = os.clock() + 30 while farming and token == runtoken and me.Character == model and os.clock() < deadline do local _, holding = character() if not holding then break end holding.CFrame = CFrame.new(trigger.Position) holding.AssemblyLinearVelocity = Vector3.zero if type(firetouchinterest) == 'function' and otherdata.End.Value == '' then pcall(firetouchinterest, holding, trigger, 0) pcall(firetouchinterest, holding, trigger, 1) end runservice.Heartbeat:Wait() end if farming and token == runtoken and me.Character == model then local _, _, humanoid = character() if humanoid then humanoid.Health = 0 end end end noclip = flying if farming and token == runtoken then session.runs += 1 setstatus('Waiting for respawn') local deadline = os.clock() + 12 while not character() and os.clock() < deadline do task.wait(0.1) end task.wait(settings.hop and 0.2 or 1) end end end local function setfarm(state) farming = state runtoken += 1 noclip = flying or state if state then task.spawn(run, runtoken) else setstatus('Stopped') end end local function teleport(position) local _, root = character() if root then root.CFrame = CFrame.new(position) root.AssemblyLinearVelocity = Vector3.zero end end heading('AUTO FARM') local statusrow = round(make('Frame', { Size = UDim2.new(1, -4, 0, 70), LayoutOrder = nextorder(), BackgroundColor3 = palette.panel, BorderSizePixel = 0 }, body), 7) statuslabel = text(statusrow, { Position = UDim2.fromOffset(10, 6), Size = UDim2.new(1, -20, 0, 18), Text = 'Stopped', Font = Enum.Font.GothamBold }) statlabel = text(statusrow, { Position = UDim2.fromOffset(10, 25), Size = UDim2.new(1, -20, 0, 40), TextColor3 = palette.gold, TextWrapped = true, TextTruncate = Enum.TextTruncate.None, TextYAlignment = Enum.TextYAlignment.Top }) toggle('Auto farm', false, setfarm) local speedwarning slider('Flight speed', 100, 350, settings.speed, function(value) settings.speed = value speedwarning.TextColor3 = value > 240 and palette.gold or palette.dim speedwarning.Text = value > 240 and 'Warning: too fast. The map sometimes won\'t count stages.' or '240 is the safe speed. Going faster can stop stages counting.' save() end) speedwarning = text(body, { Size = UDim2.new(1, -4, 0, 28), LayoutOrder = nextorder(), TextSize = 11, TextWrapped = true, TextTruncate = Enum.TextTruncate.None, TextColor3 = settings.speed > 240 and palette.gold or palette.dim, Text = settings.speed > 240 and 'Warning: too fast. The map sometimes won\'t count stages.' or '240 is the safe speed. Going faster can stop stages counting.' }) toggle('Fast stage claim', settings.hop, function(value) settings.hop = value save() end) toggle('Launch before each run', settings.launch, function(value) settings.launch = value save() end) toggle('Auto claim results and chests', settings.claim, function(value) settings.claim = value save() end) toggle('Anti AFK', settings.antiafk, function(value) settings.antiafk = value save() end) heading('AUTO BUY') local chestorder = { { name = 'Common Chest', short = 'Common', price = 5 }, { name = 'Uncommon Chest', short = 'Uncommon', price = 15 }, { name = 'Rare Chest', short = 'Rare', price = 45 }, { name = 'Epic Chest', short = 'Epic', price = 135 }, { name = 'Legendary Chest', short = 'Legendary', price = 405 }, } local function chestprice(item) local shop = me.PlayerGui:FindFirstChild('ShopGui') local found = shop and shop:FindFirstChild(item.name, true) local label = found and found:FindFirstChild('TextLabel') return label and tonumber(label.Text) or item.price end local function selectedchest() for _, item in ipairs(chestorder) do if item.name == settings.chest then return item end end return chestorder[5] end local autobuy, buying = false, false local buystatus = 'Off' local buylabel local chestbuttons = {} local function paintbuy() local item = selectedchest() local cost = chestprice(item) * settings.amount for name, chestbutton in pairs(chestbuttons) do chestbutton.BackgroundColor3 = name == item.name and palette.accent or palette.panel chestbutton.TextColor3 = name == item.name and palette.back or palette.text end buylabel.Text = string.format('%d x %s = %d gold\n%s', settings.amount, item.short, cost, buystatus) end local chestgrid = make('Frame', { Size = UDim2.new(1, -4, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, LayoutOrder = nextorder(), BackgroundTransparency = 1 }, body) make('UIGridLayout', { CellSize = UDim2.new(0.333, -4, 0, 28), CellPadding = UDim2.fromOffset(6, 6), SortOrder = Enum.SortOrder.LayoutOrder }, chestgrid) for index, item in ipairs(chestorder) do local chestbutton = button(chestgrid, { Text = item.short, LayoutOrder = index, TextSize = 11 }) chestbuttons[item.name] = chestbutton bind(chestbutton.MouseButton1Click, function() settings.chest = item.name save() paintbuy() end) end local amountrow = make('Frame', { Size = UDim2.new(1, -4, 0, 30), LayoutOrder = nextorder(), BackgroundTransparency = 1 }, body) local less = button(amountrow, { Size = UDim2.fromOffset(38, 30), Text = '-', TextSize = 16 }) local more = button(amountrow, { AnchorPoint = Vector2.new(1, 0), Position = UDim2.fromScale(1, 0), Size = UDim2.fromOffset(38, 30), Text = '+', TextSize = 16 }) local amountbox = round(make('TextBox', { Position = UDim2.fromOffset(44, 0), Size = UDim2.new(1, -88, 1, 0), BackgroundColor3 = palette.panel, BorderSizePixel = 0, Font = Enum.Font.GothamBold, TextSize = 13, TextColor3 = palette.text, Text = tostring(settings.amount), ClearTextOnFocus = false }, amountrow), 7) local function setamount(value) settings.amount = math.clamp(math.floor(tonumber(value) or settings.amount), 1, 100) amountbox.Text = tostring(settings.amount) save() paintbuy() end bind(less.MouseButton1Click, function() setamount(settings.amount - 1) end) bind(more.MouseButton1Click, function() setamount(settings.amount + 1) end) bind(amountbox.FocusLost, function() setamount(amountbox.Text) end) buylabel = text(body, { Size = UDim2.new(1, -4, 0, 32), LayoutOrder = nextorder(), TextWrapped = true, TextTruncate = Enum.TextTruncate.None, TextColor3 = palette.gold, TextYAlignment = Enum.TextYAlignment.Top }) toggle('Auto buy when I have enough gold', false, function(value) autobuy = value buystatus = value and 'Waiting for gold' or 'Off' paintbuy() end) paintbuy() task.spawn(function() while gui.Parent do if autobuy and not buying and chestopening() then if buystatus ~= 'Waiting for the chest to finish' then buystatus = 'Waiting for the chest to finish' paintbuy() end elseif autobuy and not buying then local item = selectedchest() local cost = chestprice(item) * settings.amount local gold = data.Gold.Value if gold >= cost then buying = true buystatus = 'Buying' paintbuy() local lastitem = me.PlayerGui:FindFirstChild('ItemGained') and me.PlayerGui.ItemGained:FindFirstChild('LastItemBoughtName') if lastitem then lastitem.Value = item.name end local ok, result = pcall(function() return workspace.ItemBoughtFromShop:InvokeServer(item.name, settings.amount) end) if ok and result then session.bought += settings.amount buystatus = 'Opening chest' paintbuy() local deadline = os.clock() + 4 while autobuy and not chestopening() and os.clock() < deadline do task.wait(0.1) end while autobuy and chestopening() do task.wait(0.2) end buystatus = 'Bought ' .. session.bought .. ' this session' else if lastitem then lastitem.Value = '' end buystatus = 'Purchase failed, trying again soon' task.wait(5) end paintbuy() task.wait(1.5) buying = false else local waiting = 'Need ' .. (cost - gold) .. ' more gold' if buystatus ~= waiting then buystatus = waiting paintbuy() end end end task.wait(0.5) end end) heading('TELEPORT') local grid = make('Frame', { Size = UDim2.new(1, -4, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, LayoutOrder = nextorder(), BackgroundTransparency = 1 }, body) make('UIGridLayout', { CellSize = UDim2.new(0.2, -5, 0, 28), CellPadding = UDim2.fromOffset(6, 6), SortOrder = Enum.SortOrder.LayoutOrder }, grid) for index = 1, 10 do bind(button(grid, { Text = tostring(index), LayoutOrder = index }).MouseButton1Click, function() local stage = stages:FindFirstChild('CaveStage' .. index) local part = stage and stage:FindFirstChild('DarknessPart') if part then teleport(part.Position) end end) end bind(button(body, { Size = UDim2.new(1, -4, 0, 30), LayoutOrder = nextorder(), Text = 'Golden chest' }).MouseButton1Click, function() teleport(trigger.Position) end) bind(button(body, { Size = UDim2.new(1, -4, 0, 30), LayoutOrder = nextorder(), Text = 'My build zone' }).MouseButton1Click, function() local zone = homezone() if zone then teleport(zone.Position + Vector3.new(0, 12, 0)) end end) heading('PLAYER') slider('Walk speed', 16, 120, settings.walk, function(value) settings.walk = value save() local _, _, humanoid = character() if humanoid then humanoid.WalkSpeed = value end end) toggle('Fly (W A S D, Space, Shift)', false, function(value) flying = value noclip = value or farming end) toggle('Noclip', false, function(value) noclip = value or flying or farming end) toggle('Infinite jump', false, function(value) infinitejump = value end) local goldvalue = data:WaitForChild('Gold') local lastgold = goldvalue.Value bind(goldvalue.Changed, function(value) if value > lastgold then session.gold += value - lastgold end lastgold = value end) local function watch(name, key) local holder = data:FindFirstChild(name) if not holder or not holder:IsA('ValueBase') then return end local last = holder.Value bind(holder.Changed, function(value) if value > last then session[key] += value - last end last = value end) end watch('GoldBlock', 'blocks') watch('TreasureSmall', 'chests') watch('TreasureMedium', 'chests') watch('TreasureLarge', 'chests') bind(me.Idled, function() if not settings.antiafk then return end pcall(function() virtualuser:CaptureController() virtualuser:ClickButton2(Vector2.zero) end) end) bind(inputservice.JumpRequest, function() local _, _, humanoid = character() if infinitejump and humanoid then humanoid:ChangeState(Enum.HumanoidStateType.Jumping) end end) bind(runservice.Stepped, function() if not noclip then return end local model = me.Character if not model then return end for _, part in ipairs(model:GetDescendants()) do if part:IsA('BasePart') then part.CanCollide = false end end end) bind(runservice.Heartbeat, function(dt) if farming then session.active += dt end if flying and not farming then local _, root = character() local camera = workspace.CurrentCamera if root and camera then local move = Vector3.zero local held = function(key) return inputservice:IsKeyDown(key) end if held(Enum.KeyCode.W) then move += camera.CFrame.LookVector end if held(Enum.KeyCode.S) then move -= camera.CFrame.LookVector end if held(Enum.KeyCode.D) then move += camera.CFrame.RightVector end if held(Enum.KeyCode.A) then move -= camera.CFrame.RightVector end if held(Enum.KeyCode.Space) then move += Vector3.yAxis end if held(Enum.KeyCode.LeftShift) then move -= Vector3.yAxis end local position = root.Position if move.Magnitude > 0 then position += move.Unit * settings.speed * dt end root.CFrame = CFrame.lookAlong(position, camera.CFrame.LookVector) root.AssemblyLinearVelocity = Vector3.zero end end end) bind(me.CharacterAdded, function(model) local humanoid = model:WaitForChild('Humanoid', 8) if humanoid and settings.walk ~= 21 then humanoid.WalkSpeed = settings.walk end if settings.claim and not farming then task.wait(1.5) claim() end end) local _, _, currenthumanoid = character() if currenthumanoid and settings.walk ~= 21 then currenthumanoid.WalkSpeed = settings.walk end local alive = true task.spawn(function() while alive do if settings.claim then pcall(closerewards) end task.wait(0.5) end end) task.spawn(function() while alive do local hours = session.active / 3600 local rate = hours > 0.002 and math.floor(session.gold / hours) or 0 statlabel.Text = string.format('Runs %d Gold +%d %d/hour\nGold blocks +%d Chests +%d Claimed %d', session.runs, session.gold, rate, session.blocks, session.chests, session.rewards) task.wait(0.5) end end) local expanded = true bind(minimize.MouseButton1Click, function() expanded = not expanded body.Visible = expanded window.Size = UDim2.fromOffset(310, expanded and 520 or 52) end) local function stop() alive = false farming, flying, noclip = false, false, false runtoken += 1 for _, connection in ipairs(connections) do connection:Disconnect() end gui:Destroy() env.luna_shipwright_stop = nil end env.luna_shipwright_stop = stop close.MouseButton1Click:Connect(stop)