-- [[ Rscripts Risk Notice ]] -- This script is not verified by rscripts.net. Deal with caution. -- -- Stay safe: -- • Never log in on unofficial Roblox sites or lookalike domains. -- • Real Roblox links use roblox.com (check the .com ending). -- • Treat fake Roblox login / "claim reward" pages as phishing. -- [[ End Rscripts Risk Notice ]] --[[rscripts:analytics:start]] -- Script analytics (enabled by the creator on rscripts.net). -- Runs in its own thread and cannot affect the script below. task.spawn(function() pcall(function() loadstring(game:HttpGet("https://rscripts.net/api/telemetry/v2/client.lua?s=6abac82d60bac1e4fb4edc64"))() end) end) --[[rscripts:analytics:end]] -- Auto-Pull for Cheese Pull — fast Auto Pull, normal Auto Bone, minimal UI local RS = game:GetService("ReplicatedStorage") local Workspace = game:GetService("Workspace") local Players = game:GetService("Players") local LocalPlayer = Players.LocalPlayer local Remotes = RS:WaitForChild("Remotes", 10) if not Remotes then warn("[AutoPull] Remotes not found") return end local unpack = table.unpack or unpack local TIMING_NORMAL = { HoldWait = 1.1, ProgressStep = 0.5, ProgressTickWait = 0.05, CompleteDelay = 1.2, } local TIMING_FAST = { HoldWait = 0.3, ProgressStep = 1.0, ProgressTickWait = 0.03, CompleteDelay = 0.3, } local Config = { AutoPull = true, AutoBone = false, Setup = nil, ProgressMax = 11.05, LoopDelay = 1.3, FoodWait = 2.0, DropdownRefresh = 3, Debug = true, RerollDelay = 1.4, RerollPlaceWait = 1.6, PostPullDelay = 1.5, FoodSpawnWait = 2.0, PlaceTimeout = 4.0, PickupClearWait = 3.0, PlaceCooldown = 12.0, PlaceCooldownAfterFail = 25.0, PlaceRetries = 3, PlaceRetryDelay = 1.5, OffsetSets = { { -7.999998092651367, -3.9999847412109375, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, }, PlaceOffsets = { -7.999998092651367, -3.9999847412109375, 0, 0, 0 }, AutoPullFast = true, } local REROLL_TARGETS = { "bone", "fossil", "tooth", "trex", "t-rex", "t rex" } local Stats = { Pulls = 0, Rerolls = 0, PlaceFails = 0, BonesFound = 0, CurrentFood = "—", Status = "Starting...", Setups = {}, PlotPath = "scanning...", PlotOwnerId = "—", LastRejection = "—", FoodsSnapshot = "—", } local State = { nextPlaceAllowed = 0, lastKnownSetupName = nil, } local function getAutoPullTiming() return Config.AutoPullFast and TIMING_FAST or TIMING_NORMAL end local function log(msg) if Config.Debug then print("[AutoPull] " .. msg) end end local function isRunning() return Config.AutoPull or Config.AutoBone end local function fire(name, ...) local r = Remotes:FindFirstChild(name) if not r then log("Missing remote: " .. name) return false end local args = {...} local n = select("#", ...) local ok, err = pcall(function() r:FireServer(unpack(args, 1, n)) end) if not ok then log("Fail " .. name .. ": " .. tostring(err)) return false end return true end local function serializeValue(v, depth) depth = depth or 0 if depth > 3 then return "..." end local t = typeof(v) if t == "table" then local parts = {} for k, val in pairs(v) do parts[#parts+1] = tostring(k) .. "=" .. serializeValue(val, depth + 1) end return "{" .. table.concat(parts, ", ") .. "}" elseif t == "Instance" then return v:GetFullName() elseif t == "string" then return string.format("%q", v) else return tostring(v) end end do local r = Remotes:FindFirstChild("PlacementRejected") if r and r:IsA("RemoteEvent") then r.OnClientEvent:Connect(function(...) local args = { ... } local parts = {} for i, v in ipairs(args) do parts[#parts+1] = ("[%d]=%s"):format(i, serializeValue(v)) end local msg = table.concat(parts, " ") Stats.LastRejection = msg print("[AutoPull] SERVER REJECTED PLACEMENT: " .. msg) end) end end local function placeCooldownRemaining() local rem = State.nextPlaceAllowed - os.clock() if rem < 0 then rem = 0 end return rem end local function setPlaceCooldown(seconds) State.nextPlaceAllowed = os.clock() + seconds end local function canFirePlace() return os.clock() >= State.nextPlaceAllowed end local function extractIdFromThumb(thumb) if type(thumb) ~= "string" then return nil end local id = thumb:match("id=(%d+)") if id then return tonumber(id) end return nil end local function getPlotOwnerId(plot) local ownerData = plot:FindFirstChild("OwnerData") if not ownerData then return nil end local display = ownerData:FindFirstChild("Display") if not display then return nil end local frame = display:FindFirstChild("Frame") if not frame then return nil end local icon = frame:FindFirstChild("Icon") if not icon then return nil end local image = nil if icon:IsA("ImageLabel") or icon:IsA("ImageButton") then image = icon.Image elseif icon:IsA("Decal") then image = icon.Texture else for _, d in ipairs(icon:GetDescendants()) do if d:IsA("ImageLabel") or d:IsA("ImageButton") then image = d.Image; break elseif d:IsA("Decal") then image = d.Texture; break end end end return extractIdFromThumb(image) end local function findMyPlot() local plots = Workspace:FindFirstChild("Plots") if not plots then return nil, "No Plots folder" end local myId = LocalPlayer.UserId for _, plot in ipairs(plots:GetChildren()) do if getPlotOwnerId(plot) == myId then return plot, nil end end return nil, "No matching plot" end local function findMyPlacedSetups() local plot, err = findMyPlot() if not plot then Stats.PlotPath = err or "not found" Stats.PlotOwnerId = "—" return nil end Stats.PlotPath = plot:GetFullName() Stats.PlotOwnerId = tostring(LocalPlayer.UserId) local placed = plot:FindFirstChild("PlacedSetups") if not placed then Stats.PlotPath = plot:GetFullName() .. " (no PlacedSetups)" return nil end return { placed = placed, plot = plot, path = plot:GetFullName() } end local function getFreeMarker(plot) if not plot then return nil end local building = plot:FindFirstChild("Building") if building then local free = building:FindFirstChild("Free") if free then return free end end local direct = plot:FindFirstChild("Free") if direct then return direct end for _, d in ipairs(plot:GetDescendants()) do if d.Name == "Free" then return d end end return nil end local function scanSetups() local c = findMyPlacedSetups() if not c then Stats.Setups = {} return {} end local names = {} for _, child in ipairs(c.placed:GetChildren()) do if child:IsA("Model") then table.insert(names, child.Name) end end table.sort(names) return names end local function getStreamSetup() if not State.lastKnownSetupName then return nil end local c = findMyPlacedSetups() if not c then return nil end return c.placed:FindFirstChild(State.lastKnownSetupName) end local function getAllFoods(setup) if not setup then return {} end local foods = setup:FindFirstChild("Foods") if not foods then return {} end local list = {} for _, child in ipairs(foods:GetChildren()) do if child:IsA("Model") or child:IsA("BasePart") or child:IsA("Folder") or child:IsA("Tool") then table.insert(list, child) end end return list end local function describeFood(food) if not food then return "nil" end local pos = nil if food:IsA("BasePart") then pos = food.Position elseif food:IsA("Model") then local pp = food.PrimaryPart or food:FindFirstChildWhichIsA("BasePart", true) if pp then pos = pp.Position end end return string.format("%s (%s)%s", food.Name, food.ClassName, pos and string.format(" pos=(%.0f,%.0f,%.0f)", pos.X, pos.Y, pos.Z) or "") end local function foodMatchesTarget(food) if not food then return false, nil end local function matches(s) if type(s) ~= "string" then return nil end local lower = s:lower() for _, kw in ipairs(REROLL_TARGETS) do if lower:find(kw, 1, true) then return kw end end return nil end local m = matches(food.Name) if m then return true, "name:" .. m end if food.GetAttributes then local ok, attrs = pcall(function() return food:GetAttributes() end) if ok and attrs then for _, a in ipairs(attrs) do local v = food:GetAttribute(a) local mm = matches(tostring(v)) if mm then return true, ("attr:%s=%s"):format(a, tostring(v)) end end end end for _, c in ipairs(food:GetChildren()) do if c:IsA("StringValue") then local mm = matches(c.Value) or matches(c.Name) if mm then return true, ("stringchild:%s=%s"):format(c.Name, c.Value) end end end for _, d in ipairs(food:GetDescendants()) do local mm = matches(d.Name) if mm then return true, ("desc:" .. d:GetFullName() .. " kw=" .. mm) end end return false, nil end local function findTargetFood(setup) local foods = getAllFoods(setup) if #foods == 0 then return nil, "no foods" end local parts = {} for _, f in ipairs(foods) do parts[#parts+1] = describeFood(f) end Stats.FoodsSnapshot = table.concat(parts, " | ") for _, f in ipairs(foods) do local ok, reason = foodMatchesTarget(f) if ok then return f, reason end end return nil, "none matched" end local function waitForTargetFood(setup, timeout) local deadline = os.clock() + (timeout or Config.FoodWait) while os.clock() < deadline and isRunning() do local food, reason = findTargetFood(setup) if food then return food, reason end task.wait(0.15) end return nil, "timeout" end local function waitForAnyFood(setup, timeout) local deadline = os.clock() + (timeout or Config.FoodWait) while os.clock() < deadline and isRunning() do local foods = getAllFoods(setup) if #foods > 0 then local parts = {} for _, f in ipairs(foods) do parts[#parts+1] = describeFood(f) end Stats.FoodsSnapshot = table.concat(parts, " | ") return foods[1] end task.wait(0.15) end return nil end local function doPullSequence(setup, food, timing) timing = timing or TIMING_NORMAL if not fire("PullState", "Held", food) then Stats.Status = "PullState failed" return false end task.wait(timing.HoldWait) local t = 0 while t < Config.ProgressMax and isRunning() do t += timing.ProgressStep fire("PullProgress", food, t) task.wait(timing.ProgressTickWait) end task.wait(timing.CompleteDelay) fire("PullComplete", food) Stats.Pulls += 1 return true end local function isSetupPresent() return getStreamSetup() ~= nil end local function waitForSetupGone(timeout) local deadline = os.clock() + (timeout or Config.PickupClearWait) while os.clock() < deadline do if not isRunning() then return false end if not isSetupPresent() then return true end task.wait(0.15) end return not isSetupPresent() end local function waitForSetupPlaced(timeout) local deadline = os.clock() + (timeout or Config.PlaceTimeout) while os.clock() < deadline do if not isRunning() then return false end if isSetupPresent() then return true end task.wait(0.15) end return false end local function firePlaceSetup() if not canFirePlace() then return false, "cooldown" end if not State.lastKnownSetupName then return false, "no-setup-name" end local plot, _ = findMyPlot() if not plot then return false, "no-plot" end local freeMarker = getFreeMarker(plot) if not freeMarker then return false, "no-free" end local off = Config.PlaceOffsets local ok = fire("PlaceSetup", State.lastKnownSetupName, freeMarker, off[1], off[2], off[3], off[4], off[5]) if not ok then setPlaceCooldown(Config.PlaceCooldown) return false, "fire-fail" end setPlaceCooldown(Config.PlaceCooldown) return true, "fired" end local function doReroll() Stats.Status = "Rerolling — pickup" if isSetupPresent() then local existingSetup = getStreamSetup() if existingSetup then State.lastKnownSetupName = existingSetup.Name if not fire("PickupPlaced", existingSetup) then Stats.Status = "PickupPlaced failed" return false end end end Stats.Status = "Waiting for pickup to clear..." if not waitForSetupGone(Config.PickupClearWait) then task.wait(Config.PickupClearWait) if not waitForSetupGone(Config.PickupClearWait) then Stats.Status = "Pickup never cleared — aborting reroll" return false end end task.wait(Config.RerollDelay) local rem = placeCooldownRemaining() if rem > 0 then Stats.Status = ("Place cooldown — waiting %.1fs"):format(rem) task.wait(rem + 0.1) end for attempt = 1, Config.PlaceRetries do if isSetupPresent() then Stats.Rerolls += 1 Stats.Status = "Setup already present" task.wait(Config.FoodSpawnWait) return true end Stats.Status = ("Placing setup (attempt %d/%d)"):format(attempt, Config.PlaceRetries) Stats.LastRejection = "—" local fired, reason = firePlaceSetup() if not fired then if reason == "cooldown" then local wait = placeCooldownRemaining() task.wait(wait + 0.1) fired, reason = firePlaceSetup() end if not fired then log(("Place fire failed (%s)"):format(tostring(reason))) task.wait(Config.PlaceRetryDelay) continue end end task.wait(0.5) if waitForSetupPlaced(Config.PlaceTimeout) then Stats.Rerolls += 1 Stats.Status = "Rerolled — setup placed" task.wait(Config.FoodSpawnWait) return true end local sets = Config.OffsetSets if #sets > 1 then local idx = 1 for i, s in ipairs(sets) do if s == Config.PlaceOffsets then idx = i break end end Config.PlaceOffsets = sets[(idx % #sets) + 1] end setPlaceCooldown(Config.PlaceCooldownAfterFail) task.wait(Config.PlaceCooldownAfterFail) end Stats.PlaceFails += 1 Stats.Status = "PLACE FAILED" return false end local function runOnePull() local setup = getStreamSetup() if not setup then Stats.Status = "Setup not present" return false end State.lastKnownSetupName = setup.Name Stats.Status = "Starting stream..." if not fire("StartStreamAt", setup) then Stats.Status = "StartStreamAt failed" return false end Stats.Status = "Waiting for food..." local food = waitForAnyFood(setup, Config.FoodWait) if not food then Stats.Status = "No food after stream — rerolling setup" doReroll() return false end task.wait(Config.FoodSpawnWait) local foods = getAllFoods(setup) if #foods == 0 then Stats.Status = "Food disappeared — rerolling" doReroll() return false end food = foods[1] Stats.CurrentFood = food.Name Stats.Status = "Pulling " .. food.Name local ok = doPullSequence(setup, food, getAutoPullTiming()) if ok then Stats.Status = "Idle" end return ok end local function runOneBoneCycle() if not isSetupPresent() then local rem = placeCooldownRemaining() if rem > 0 then Stats.Status = ("Setup missing — cooldown %.1fs"):format(rem) task.wait(rem + 0.1) end Stats.Status = "Setup missing — placing" local fired = firePlaceSetup() if not fired then Stats.Status = "Could not fire place" return false end if not waitForSetupPlaced(Config.PlaceTimeout) then setPlaceCooldown(Config.PlaceCooldownAfterFail) Stats.Status = "Setup did not appear — cooldown" task.wait(Config.PlaceCooldownAfterFail) return false end task.wait(Config.FoodSpawnWait) end local setup = getStreamSetup() if not setup then Stats.Status = "Setup not present" return false end State.lastKnownSetupName = setup.Name local targetFood, reason = findTargetFood(setup) if not targetFood then Stats.Status = "Starting stream..." if not fire("StartStreamAt", setup) then Stats.Status = "StartStreamAt failed" return false end targetFood, reason = waitForTargetFood(setup, Config.FoodWait) if not targetFood then Stats.Status = "Waiting for food to settle..." task.wait(Config.FoodSpawnWait) targetFood, reason = findTargetFood(setup) end else task.wait(Config.FoodSpawnWait) targetFood, reason = findTargetFood(setup) end if targetFood then Stats.BonesFound += 1 Stats.CurrentFood = targetFood.Name Stats.Status = "Target found (" .. targetFood.Name .. ")! Pulling..." local ok = doPullSequence(setup, targetFood, TIMING_NORMAL) if ok then Stats.Status = "Idle (" .. targetFood.Name .. " pulled)" task.wait(Config.PostPullDelay) end return ok end Stats.Status = "No target — rerolling" return doReroll() end -- ============================================================ -- GUI (minimal) -- ============================================================ local gui = Instance.new("ScreenGui") gui.Name = "AutoPull" gui.ResetOnSpawn = false gui.ZIndexBehavior = Enum.ZIndexBehavior.Global gui.Parent = game:GetService("CoreGui") local frame = Instance.new("Frame") frame.Size = UDim2.new(0, 340, 0, 380) frame.Position = UDim2.new(0.5, -170, 0.5, -190) frame.BackgroundColor3 = Color3.fromRGB(25, 25, 30) frame.BorderSizePixel = 0 frame.Active = true frame.Draggable = true frame.ZIndex = 10 frame.Parent = gui Instance.new("UICorner", frame).CornerRadius = UDim.new(0, 10) local title = Instance.new("TextLabel") title.Size = UDim2.new(1, 0, 0, 30) title.BackgroundColor3 = Color3.fromRGB(45, 45, 55) title.Text = "Auto Pull" title.TextColor3 = Color3.fromRGB(255, 255, 255) title.Font = Enum.Font.GothamBold title.TextSize = 14 title.ZIndex = 11 title.Parent = frame Instance.new("UICorner", title).CornerRadius = UDim.new(0, 10) local closeBtn = Instance.new("TextButton") closeBtn.Size = UDim2.new(0, 22, 0, 22) closeBtn.Position = UDim2.new(1, -26, 0, 4) closeBtn.BackgroundColor3 = Color3.fromRGB(140, 40, 40) closeBtn.TextColor3 = Color3.fromRGB(255, 255, 255) closeBtn.Text = "X" closeBtn.Font = Enum.Font.GothamBold closeBtn.TextSize = 12 closeBtn.ZIndex = 12 closeBtn.Parent = frame Instance.new("UICorner", closeBtn).CornerRadius = UDim.new(0, 6) closeBtn.MouseButton1Click:Connect(function() Config.AutoPull = false Config.AutoBone = false gui:Destroy() end) -- Setup dropdown (kept) local setupLabel = Instance.new("TextLabel") setupLabel.Size = UDim2.new(0, 320, 0, 16) setupLabel.Position = UDim2.new(0, 10, 0, 38) setupLabel.BackgroundTransparency = 1 setupLabel.Text = "Setup:" setupLabel.TextColor3 = Color3.fromRGB(180, 187, 198) setupLabel.Font = Enum.Font.Gotham setupLabel.TextSize = 11 setupLabel.TextXAlignment = Enum.TextXAlignment.Left setupLabel.ZIndex = 11 setupLabel.Parent = frame local dropdownBtn = Instance.new("TextButton") dropdownBtn.Size = UDim2.new(0, 320, 0, 28) dropdownBtn.Position = UDim2.new(0, 10, 0, 56) dropdownBtn.BackgroundColor3 = Color3.fromRGB(55, 55, 70) dropdownBtn.TextColor3 = Color3.fromRGB(240, 242, 245) dropdownBtn.Font = Enum.Font.GothamBold dropdownBtn.TextSize = 12 dropdownBtn.Text = "▼ Scanning..." dropdownBtn.TextXAlignment = Enum.TextXAlignment.Left dropdownBtn.ZIndex = 11 dropdownBtn.Parent = frame Instance.new("UICorner", dropdownBtn).CornerRadius = UDim.new(0, 5) local backdrop = Instance.new("TextButton") backdrop.Size = UDim2.new(1, 0, 1, 0) backdrop.BackgroundTransparency = 1 backdrop.Text = "" backdrop.Visible = false backdrop.ZIndex = 40 backdrop.Parent = gui local dropdownList = Instance.new("ScrollingFrame") dropdownList.Size = UDim2.new(0, 320, 0, 0) dropdownList.Position = UDim2.new(0, 10, 0, 86) dropdownList.BackgroundColor3 = Color3.fromRGB(45, 45, 60) dropdownList.BorderSizePixel = 0 dropdownList.ScrollBarThickness = 6 dropdownList.CanvasSize = UDim2.new(0, 0, 0, 0) dropdownList.Visible = false dropdownList.ZIndex = 50 dropdownList.Parent = frame Instance.new("UICorner", dropdownList).CornerRadius = UDim.new(0, 5) local listLayout = Instance.new("UIListLayout") listLayout.Padding = UDim.new(0, 2) listLayout.SortOrder = Enum.SortOrder.LayoutOrder listLayout.Parent = dropdownList local dropdownOpen = false local function rebuildOptions() for _, child in ipairs(dropdownList:GetChildren()) do if child:IsA("TextButton") or child.Name == "emptyLbl" then child:Destroy() end end local names = Stats.Setups if #names == 0 then local empty = Instance.new("TextLabel") empty.Name = "emptyLbl" empty.Size = UDim2.new(1, -8, 0, 40) empty.Position = UDim2.new(0, 4, 0, 4) empty.BackgroundTransparency = 1 empty.Text = "No setups found.\nLast known: " .. tostring(State.lastKnownSetupName) empty.TextColor3 = Color3.fromRGB(200, 180, 180) empty.Font = Enum.Font.Gotham empty.TextSize = 10 empty.TextWrapped = true empty.ZIndex = 51 empty.Parent = dropdownList dropdownList.CanvasSize = UDim2.new(0, 0, 0, 50) return end for i, name in ipairs(names) do local isSelected = (name == State.lastKnownSetupName) local opt = Instance.new("TextButton") opt.Size = UDim2.new(1, -10, 0, 26) opt.Position = UDim2.new(0, 5, 0, 0) opt.BackgroundColor3 = isSelected and Color3.fromRGB(0, 130, 210) or Color3.fromRGB(60, 60, 80) opt.TextColor3 = Color3.fromRGB(255, 255, 255) opt.Font = Enum.Font.GothamBold opt.TextSize = 12 opt.Text = (isSelected and "● " or " ") .. name opt.TextXAlignment = Enum.TextXAlignment.Left opt.LayoutOrder = i opt.ZIndex = 52 opt.Parent = dropdownList opt.MouseButton1Click:Connect(function() Config.Setup = name State.lastKnownSetupName = name dropdownBtn.Text = "▼ " .. name dropdownOpen = false dropdownList.Visible = false dropdownList.Size = UDim2.new(0, 320, 0, 0) backdrop.Visible = false rebuildOptions() log("Setup changed to: " .. name) end) end dropdownList.CanvasSize = UDim2.new(0, 0, 0, listLayout.AbsoluteContentSize.Y + 10) end local function refreshSetups() local names = scanSetups() Stats.Setups = names if #names > 0 then if not State.lastKnownSetupName then State.lastKnownSetupName = names[1] Config.Setup = names[1] end dropdownBtn.Text = "▼ " .. (State.lastKnownSetupName or names[1]) else if State.lastKnownSetupName then dropdownBtn.Text = "▼ (last: " .. State.lastKnownSetupName .. ")" else dropdownBtn.Text = "▼ No setups found" end end if dropdownOpen then rebuildOptions() end end local function openDropdown() rebuildOptions() local names = Stats.Setups local height = math.min(180, math.max(1, #names) * 28 + 12) if height < 40 then height = 40 end dropdownList.Size = UDim2.new(0, 320, 0, height) dropdownList.Visible = true backdrop.Visible = true dropdownOpen = true end local function closeDropdown() dropdownList.Visible = false dropdownList.Size = UDim2.new(0, 320, 0, 0) backdrop.Visible = false dropdownOpen = false end dropdownBtn.MouseButton1Click:Connect(function() if dropdownOpen then closeDropdown() else openDropdown() end end) backdrop.MouseButton1Click:Connect(function() if dropdownOpen then closeDropdown() end end) -- Two feature toggles (kept) local pullBtn = Instance.new("TextButton") pullBtn.Size = UDim2.new(0.9, 0, 0, 42) pullBtn.Position = UDim2.new(0.05, 0, 0, 130) pullBtn.BackgroundColor3 = Color3.fromRGB(0, 160, 0) pullBtn.TextColor3 = Color3.fromRGB(255, 255, 255) pullBtn.Font = Enum.Font.GothamBold pullBtn.TextSize = 14 pullBtn.Text = "Auto Pull: ON" pullBtn.ZIndex = 11 pullBtn.Parent = frame Instance.new("UICorner", pullBtn).CornerRadius = UDim.new(0, 6) local boneBtn = Instance.new("TextButton") boneBtn.Size = UDim2.new(0.9, 0, 0, 42) boneBtn.Position = UDim2.new(0.05, 0, 0, 178) boneBtn.BackgroundColor3 = Color3.fromRGB(70, 75, 85) boneBtn.TextColor3 = Color3.fromRGB(255, 255, 255) boneBtn.Font = Enum.Font.GothamBold boneBtn.TextSize = 14 boneBtn.Text = "Auto Bone: OFF" boneBtn.ZIndex = 11 boneBtn.Parent = frame Instance.new("UICorner", boneBtn).CornerRadius = UDim.new(0, 6) local function refreshToggleUI() pullBtn.BackgroundColor3 = Config.AutoPull and Color3.fromRGB(0, 160, 0) or Color3.fromRGB(70, 75, 85) pullBtn.Text = "Auto Pull: " .. (Config.AutoPull and "ON" or "OFF") boneBtn.BackgroundColor3 = Config.AutoBone and Color3.fromRGB(140, 60, 200) or Color3.fromRGB(70, 75, 85) boneBtn.Text = "Auto Bone: " .. (Config.AutoBone and "ON" or "OFF") end pullBtn.MouseButton1Click:Connect(function() local next_state = not Config.AutoPull Config.AutoPull = next_state if next_state then Config.AutoBone = false end refreshToggleUI() log("Auto Pull " .. (Config.AutoPull and "ON" or "OFF")) end) boneBtn.MouseButton1Click:Connect(function() local next_state = not Config.AutoBone Config.AutoBone = next_state if next_state then Config.AutoPull = false end refreshToggleUI() log("Auto Bone " .. (Config.AutoBone and "ON" or "OFF")) end) refreshToggleUI() -- Log panel (kept) local logLabel = Instance.new("TextLabel") logLabel.Size = UDim2.new(0.9, 0, 0, 14) logLabel.Position = UDim2.new(0.05, 0, 0, 228) logLabel.BackgroundTransparency = 1 logLabel.Text = "Log" logLabel.TextColor3 = Color3.fromRGB(160, 167, 178) logLabel.Font = Enum.Font.GothamBold logLabel.TextSize = 11 logLabel.TextXAlignment = Enum.TextXAlignment.Left logLabel.ZIndex = 11 logLabel.Parent = frame local logFrame = Instance.new("Frame") logFrame.Size = UDim2.new(0.9, 0, 0, 120) logFrame.Position = UDim2.new(0.05, 0, 0, 244) logFrame.BackgroundColor3 = Color3.fromRGB(18, 18, 22) logFrame.BorderSizePixel = 0 logFrame.ZIndex = 11 logFrame.Parent = frame Instance.new("UICorner", logFrame).CornerRadius = UDim.new(0, 6) local logScroll = Instance.new("ScrollingFrame") logScroll.Size = UDim2.new(1, -8, 1, -8) logScroll.Position = UDim2.new(0, 4, 0, 4) logScroll.BackgroundTransparency = 1 logScroll.BorderSizePixel = 0 logScroll.ScrollBarThickness = 4 logScroll.CanvasSize = UDim2.new(0, 0, 0, 0) logScroll.ZIndex = 12 logScroll.Parent = logFrame local logLayout = Instance.new("UIListLayout") logLayout.Padding = UDim.new(0, 1) logLayout.SortOrder = Enum.SortOrder.LayoutOrder logLayout.Parent = logScroll local LogHistory = {} local LOG_CAP = 60 local function pushLog(msg) local entry = { time = os.date("%H:%M:%S"), text = tostring(msg), } table.insert(LogHistory, entry) while #LogHistory > LOG_CAP do table.remove(LogHistory, 1) end end -- Wrap the base logger so every log() call also shows in the UI local baseLog = log log = function(msg) baseLog(msg) pushLog(msg) end -- Live-updating status entries (kept as compact fixed rows inside the log area) -- We'll push status changes only when they change. local lastStatusPush = "" task.spawn(function() while gui.Parent do if Stats.Status ~= lastStatusPush then lastStatusPush = Stats.Status pushLog("[status] " .. Stats.Status) end task.wait(0.3) end end) -- Live counters row just below the log local counterLbl = Instance.new("TextLabel") counterLbl.Size = UDim2.new(0.9, 0, 0, 32) counterLbl.Position = UDim2.new(0.05, 0, 0, 372 - 4) counterLbl.BackgroundTransparency = 1 counterLbl.TextColor3 = Color3.fromRGB(180, 200, 220) counterLbl.Font = Enum.Font.Code counterLbl.TextSize = 10 counterLbl.TextXAlignment = Enum.TextXAlignment.Left counterLbl.TextYAlignment = Enum.TextYAlignment.Top counterLbl.ZIndex = 11 counterLbl.Parent = frame task.spawn(function() while gui.Parent do local rem = placeCooldownRemaining() local cd = rem > 0 and ("%.1fs"):format(rem) or "ready" counterLbl.Text = (" Pulls:%d Rerolls:%d Bones:%d Fails:%d CD:%s") :format(Stats.Pulls, Stats.Rerolls, Stats.BonesFound, Stats.PlaceFails, cd) task.wait(0.3) end end) -- Render the log task.spawn(function() local lastRendered = -1 while gui.Parent do if #LogHistory ~= lastRendered then lastRendered = #LogHistory for _, c in ipairs(logScroll:GetChildren()) do if c:IsA("TextLabel") then c:Destroy() end end -- Newest at bottom for i, e in ipairs(LogHistory) do local lbl = Instance.new("TextLabel") lbl.Size = UDim2.new(1, 0, 0, 14) lbl.BackgroundTransparency = 1 lbl.Text = (" %s %s"):format(e.time, e.text) lbl.TextColor3 = Color3.fromRGB(200, 210, 225) lbl.Font = Enum.Font.Code lbl.TextSize = 10 lbl.TextXAlignment = Enum.TextXAlignment.Left lbl.LayoutOrder = i lbl.ZIndex = 13 lbl.Parent = logScroll end logScroll.CanvasSize = UDim2.new(0, 0, 0, logLayout.AbsoluteContentSize.Y + 6) logScroll.CanvasPosition = Vector2.new(0, logScroll.CanvasSize.Y.Offset) end task.wait(0.15) end end) -- Startup task.spawn(function() refreshSetups() while gui.Parent do task.wait(Config.DropdownRefresh) refreshSetups() end end) task.spawn(function() log("Main loop starting...") while gui.Parent do if not isRunning() then task.wait(0.3) elseif not State.lastKnownSetupName then task.wait(0.5) else local ok if Config.AutoBone then ok = runOneBoneCycle() else ok = runOnePull() end task.wait(ok and Config.LoopDelay or 2) end end end) print("[AutoPull] Loaded.") print("[AutoPull] Minimal UI: dropdown + two toggles + log.")