-- ===================================================================== -- MADE BY deepseek-v4-flash INSIDE PROJECT UAI -- Legends of Speed Ultimate Autofarm v5 -- ===================================================================== -- v5 was written against the LIVE place 3101667897 on 2026-09-21, using the -- decompiled client scripts (Potassium 2.4.9) instead of guesswork. -- -- WHAT v4 GOT WRONG, AND WHAT v5 DOES INSTEAD (all measured in-game) -- --------------------------------------------------------------------- -- * EGG HATCHING WAS 50x TOO SLOW AND SILENTLY DEAD. v4 held E for 0.8s beside -- the crystal and hopped 34 studs out and back, giving ~1 hatch per 7s. The -- real call the game makes is one line inside crystalOpenScript: -- openCrystalRemote:InvokeServer("openCrystal", " Crystal") -- v5 calls it directly. No menu, no E, no movement, no proximity: the client's -- 30-stud check lives in crystalOpenScript.openOneCrystal and the server does -- not repeat it (verified hatching from 400+ studs away). -- MEASURED v5: 4.4-9.4 hatches/s, zero failures. -- * HATCHING DIES AT FULL CAPACITY. openOneCrystal refuses when -- calculatePetCapacity(petsFolder) or calculateTrailCapacity(trailsFolder) -- reaches maxPetCapacity, and the server refuses too (0 gems spent, nil back). -- v4 reported "crystal busy" forever. v5 adds a SELL ENGINE that keeps N free -- slots, so hatching never stalls. -- * NOTHING WAS EVER SOLD OR EQUIPPED. Real shapes, read from the GUI scripts: -- sellPetEvent:FireServer("sellPet", petInstance) -- sellTrailEvent:FireServer("sellTrail", trailInstance) -- equipPetEvent:FireServer("equipPet" / "unequipPet", petInstance) -- petEvolveEvent:FireServer("evolvePet", pet.Name) -- evolveTrailEvent:FireServer("evolveTrail", trailInstance) -- rebirthEvent:FireServer("rebirthRequest") -- rEvents.ultimatesRemote:InvokeServer("upgradeUltimate", "") -- rEvents.checkChestRemote:InvokeServer("") -- Sell value is globalFunctions.calculatePetValue(tier, level, evolved). -- * THE DROP TABLES ARE PUBLIC. ReplicatedStorage.crystalChances lists every -- crystal's pool with chanceValue/nameValue/rarityValue, and cPetShopFolder -- prices every pet and trail. v5 reads both, so it can snipe a named pet -- ("Swift Samurai", Jungle Crystal, 1%) instead of hatching blind. -- Jungle Crystal: Swift Samurai Omega 1%, Golden Viking Unique 20%, -- Speedy Sensei Unique 14%, Maestro Dog Unique 35%, Divine Pegasus Epic 30%. -- Electro Legends Crystal: six Omegas, 2-30% each (no rare ones). -- * ORB FARM, HOOP LOOP, QUESTS were already right in v4 and are unchanged. -- orbEvent:FireServer("collectOrb", orbName, currentMap.Value) is exactly what -- oScript fires; hoopEvent is server->client only, so relocating Workspace.Hoops -- onto the character is still the only lever. -- -- NEW IN v5: sell engine (ranked by real pet/trail prices, never sells equipped), -- auto-equip that frees a slot first, pet sniper with live chance math, auto -- rebirth, auto ultimate upgrades, chest collector, session income stats. -- ===================================================================== local Players = game:GetService("Players") local player = Players.LocalPlayer local RS = game:GetService("ReplicatedStorage") local RunService = game:GetService("RunService") local TweenService = game:GetService("TweenService") local UserInputService = game:GetService("UserInputService") local HttpService = game:GetService("HttpService") local rEvents = RS:WaitForChild("rEvents", 30) local function remote(name) local r = rEvents and rEvents:FindFirstChild(name) return r end local orbEvent = remote("orbEvent") local questsEvent = remote("questsEvent") local openCrystalRemote = remote("openCrystalRemote") local sellPetEvent = remote("sellPetEvent") local sellTrailEvent = remote("sellTrailEvent") local equipPetEvent = remote("equipPetEvent") local petEvolveEvent = remote("petEvolveEvent") local evolveTrailEvent = remote("evolveTrailEvent") local rebirthEvent = remote("rebirthEvent") local speedRampEvent = remote("speedRampEvent") local ultimatesRemote = remote("ultimatesRemote") local checkChestRemote = remote("checkChestRemote") local GF = nil pcall(function() GF = require(RS:WaitForChild("globalFunctions")) end) local MONO = { bg = Color3.fromRGB(18, 18, 20), panel = Color3.fromRGB(26, 26, 30), panel2 = Color3.fromRGB(34, 34, 40), border = Color3.fromRGB(48, 48, 56), text = Color3.fromRGB(235, 235, 240), sub = Color3.fromRGB(150, 150, 160), accent = Color3.fromRGB(200, 200, 210), success = Color3.fromRGB(120, 255, 160), warn = Color3.fromRGB(255, 200, 90), danger = Color3.fromRGB(255, 90, 90), rare = Color3.fromRGB(180, 140, 255), } local state = { -- hatch hatcher = false, hatchThread = nil, hatchChoice = "Jungle", hatchRate = 8, hatchMax = 0, gemReserve = 0, autoSell = true, keepTop = 6, keepFree = 3, snipePet = "", hatches = 0, rarity = {}, hits = {}, -- sell / equip autoEquip = false, equipThread = nil, -- other loops orbFarming = false, orbChoice = nil, orbRate = 1200, orbAmount = 250000, orbInfinite = true, orbThread = nil, hoopLoop = false, hoopThread = nil, quest = false, questThread = nil, evolvePets = false, petThread = nil, evolveTrails = false, trailThread = nil, ramps = false, rampThread = nil, autoRebirth = false, rebirthThread = nil, rebirthsDone = 0, rebirthReserve = 3, autoUltimates = false, ultimateThread = nil, ultimatesBought = 0, chests = false, chestThread = nil, chestsOpened = 0, keepNames = {}, minimised = false, session = {}, } -- ============ INSTANCE GUARD ============ local GENV = _G pcall(function() if type(getgenv) == "function" then GENV = getgenv() end end) local INSTANCE_ID = (GENV.__LOS_AUTOFARM_ID or 0) + 1 GENV.__LOS_AUTOFARM_ID = INSTANCE_ID local function isCurrent() return GENV.__LOS_AUTOFARM_ID == INSTANCE_ID end -- replaced with the real thing once the GUI exists (declared here so every loop -- below can report through it) local setStatus = function() end -- toast, replaced once the GUI exists local notify = function() end -- names that must never be sold (filled from the GUI / API) state.keepNames = {} local function spawnLoop(fn) local co = coroutine.create(function() local ok, err = pcall(fn) if not ok then warn("[LOS Autofarm v5] loop error: " .. tostring(err)) end end) local ok, err = coroutine.resume(co) if not ok then warn("[LOS Autofarm v5] loop error: " .. tostring(err)) end return co end -- ============ LIVE GAME DATA ============ local function shorten(n) n = tonumber(n) or 0 local s = { "", "K", "M", "B", "T", "Qa", "Qi" } local i = 1 while n >= 1000 and i < #s do n = n / 1000; i = i + 1 end return i == 1 and tostring(math.floor(n)) or string.format("%.2f%s", n, s[i]) end local function statValue(name) local v = player:FindFirstChild(name) if v and v:IsA("ValueBase") then return v.Value end local ls = player:FindFirstChild("leaderstats") v = ls and ls:FindFirstChild(name) return v and v.Value or 0 end local function shadowNum(v) return tonumber(v) or 0 end local function gems() return shadowNum(player:FindFirstChild("Gems") and player.Gems.Value) end local function level() return shadowNum(player:FindFirstChild("level") and player.level.Value) end local function rebirths() return shadowNum(statValue("Rebirths")) end local function cap() local c = player:FindFirstChild("maxPetCapacity") return c and c.Value or 20 end -- every crystal, cheapest first, with its real drop pool local crystals = {} do local prices = RS:FindFirstChild("crystalPrices") local chances = RS:FindFirstChild("crystalChances") if prices then for _, c in ipairs(prices:GetChildren()) do local base = c.Name:gsub(" Crystal$", "") local p, t = c:FindFirstChild("price"), c:FindFirstChild("priceType") local entry = { base = base, price = (p and p.Value) or math.huge, ptype = (t and t.Value) or "Gems", pool = {} } local ch = chances and chances:FindFirstChild(c.Name) if ch then for _, item in ipairs(ch:GetChildren()) do local n = item:FindFirstChild("nameValue") local r = item:FindFirstChild("rarityValue") local cv = item:FindFirstChild("chanceValue") if n then table.insert(entry.pool, { name = n.Value, rarity = r and r.Value or "?", chance = (cv and cv.Value) or 0 }) end end table.sort(entry.pool, function(a, b) return a.chance < b.chance end) end table.insert(crystals, entry) end table.sort(crystals, function(a, b) return a.price < b.price end) end end local function crystalByName(base) if base == nil then return nil end base = tostring(base):gsub("%s*Crystal%s*$", "") for _, c in ipairs(crystals) do if c.base == base or (c.base .. " Crystal") == base then return c end end return nil end local function crystalLabel(c) local parts = {} for _, p in ipairs(c.pool) do table.insert(parts, string.format("%s %s %d%%", p.name, p.rarity, p.chance)) end return table.concat(parts, ", ") end -- real pet/trail prices: cPetShopFolder prices every pet and trail local priceOf = {} do local shop = RS:FindFirstChild("cPetShopFolder") if shop then for _, item in ipairs(shop:GetChildren()) do local p = item:FindFirstChild("priceValue") local r = item:FindFirstChild("rarityValue") if p and not priceOf[item.Name] then priceOf[item.Name] = { price = p.Value, rarity = r and r.Value or "?" } end end end end local orbs = {} -- orb name -> { stat = "Steps"/"Gems", base = n } do local folder = RS:FindFirstChild("Orbs") if folder then for _, m in ipairs(folder:GetChildren()) do local v = m:FindFirstChildOfClass("IntValue") or m:FindFirstChildOfClass("NumberValue") if v then orbs[m.Name] = { stat = v.Name, base = v.Value } end end end end -- ============ ITEM HELPERS ============ local function folders() return { pets = player:FindFirstChild("petsFolder"), trails = player:FindFirstChild("trailsFolder"), } end local function itemRows(kind) local f = folders()[kind] local rows = {} if not f then return rows end for _, tier in ipairs(f:GetChildren()) do for _, it in ipairs(tier:GetChildren()) do rows[#rows + 1] = { it = it, tier = tier.Name, name = it.Name, kind = kind } end end return rows end local function itemCount(kind) local f = folders()[kind] local n = 0 if not f then return 0 end for _, tier in ipairs(f:GetChildren()) do n = n + #tier:GetChildren() end return n end -- what selling an item actually pays, level and evolution included local function sellValueOf(row) if not GF then return 0 end local lvl = row.it:FindFirstChild("level") return GF.calculatePetValue(row.tier, lvl and lvl.Value or 1, row.it:FindFirstChild("evolved") ~= nil) end local function equippedSet() local set = {} local eq = player:FindFirstChild("equippedPets") if eq then for _, c in ipairs(eq:GetChildren()) do local ref = c:FindFirstChild("petReference") if ref and ref.Value then set[ref.Value] = true end end end return set end local function equippedTrail() local t = player:FindFirstChild("equippedTrail") return t and t.Value or nil end -- ============ SELL / KEEP POLICY ============ -- Every sell decision goes through buildKeepSet, so "what gets sold" is one -- readable rule instead of scattered conditions: -- 1. NEVER sell the equipped pets, the equipped trail, or anything named in -- state.keepNames. -- 2. NEVER sell evolved pets/trails (state.keepEvolved) - each one cost five -- non-evolved copies, verified below. -- 3. ALWAYS sell anything below the rarity floor (state.sellBelow) unless it is -- hard-protected (equipped, named in keepNames, or evolved with keepEvolved -- on) - a floor is for dumping fodder, not for destroying a kept pet. -- 4. KEEP UP TO state.keepDupes copies of a name in state.keepNames - that is -- evolve fodder, and selling it is what silently kills auto-evolve. -- 5. KEEP the best state.keepTop items by the selected ranking. -- 6. Sell the lowest-ranked survivors, worst first, when a slot is needed. local RARITY_ORDER = { Basic = 1, Advanced = 2, Rare = 3, Epic = 4, Unique = 5, Omega = 6 } local sellStats = { pets = 0, trails = 0, gems = 0 } state.rankMode = state.rankMode or "MARKET" state.sellBelow = state.sellBelow or "Basic" if state.keepEvolved == nil then state.keepEvolved = true end state.keepDupes = state.keepDupes or 5 if state.evolveAll == nil then state.evolveAll = true end if state.autoEvolve == nil then state.autoEvolve = false end -- ranking is selectable, because "best" means different things here: -- MARKET = ReplicatedStorage.cPetShopFolder priceValue (rarity/desirability) -- VALUE = what selling it actually pays, globalFunctions.calculatePetValue -- RARITY = tier first (Omega > Unique > Epic > Rare > Advanced > Basic) local function marketOf(row) local p = priceOf[row.name] return p and p.price or 0 end local function rarityOf(row) local p = priceOf[row.name] return p and p.rarity or "Basic" end local function rankOf(row) if state.rankMode == "VALUE" then return sellValueOf(row) end if state.rankMode == "RARITY" then return (RARITY_ORDER[rarityOf(row)] or 0) * 1000000 + sellValueOf(row) end return marketOf(row) end local function isEvolved(row) local e = row.it:FindFirstChild("evolved") return e ~= nil and e.Value == true end local function isProtected(row) if row.kind == "pets" and equippedSet()[row.it] then return true end if row.kind == "trails" and equippedTrail() == row.it then return true end if state.keepNames[row.name] then return true end return false end -- worst first, so index 1 is the next candidate to sell local function rankedWorstFirst(kind) local rows = itemRows(kind) table.sort(rows, function(a, b) local ra, rb = rankOf(a), rankOf(b) if ra == rb then return sellValueOf(a) < sellValueOf(b) end return ra < rb end) return rows end local function buildKeepSet(kind) local rows = rankedWorstFirst(kind) local keep, dupes = {}, {} local topKept = 0 local floor = RARITY_ORDER[state.sellBelow] or 0 for i = #rows, 1, -1 do -- best first local row = rows[i] local protected = isProtected(row) local evo = isEvolved(row) local belowFloor = (RARITY_ORDER[rarityOf(row)] or 0) < floor if protected or (state.keepEvolved and evo) then keep[row.it] = true elseif belowFloor then -- forced out, never kept (step 3) elseif state.keepNames[row.name] then dupes[row.name] = dupes[row.name] or 0 if dupes[row.name] < state.keepDupes then dupes[row.name] = dupes[row.name] + 1 keep[row.it] = true end elseif topKept < state.keepTop then topKept = topKept + 1 keep[row.it] = true end end return keep end local function nextToSell(kind) local keep = buildKeepSet(kind) for _, row in ipairs(rankedWorstFirst(kind)) do if not keep[row.it] then return row end end return nil end -- what the policy would sell next, for the GUI (answers "what gets auto sold") local function sellPreview(kind, n) local keep = buildKeepSet(kind) local out = {} for _, row in ipairs(rankedWorstFirst(kind)) do if not keep[row.it] then table.insert(out, string.format("%s (%s, %d)", row.name, rarityOf(row), sellValueOf(row))) if #out >= (n or 3) then break end end end return out end local function sellRow(row) if row.kind == "pets" then if sellPetEvent then sellPetEvent:FireServer("sellPet", row.it) end sellStats.pets = sellStats.pets + 1 else if sellTrailEvent then sellTrailEvent:FireServer("sellTrail", row.it) end sellStats.trails = sellStats.trails + 1 end return true end local function sellLowest(kind) local row = nextToSell(kind) if not row then return nil end sellRow(row) return row end -- sell a freshly hatched item unless the policy says it is a keeper local function sellIfJunk(row) if not state.autoSell or not row then return false end local keep = buildKeepSet(row.kind) if keep[row.it] then return false end local g0 = gems() sellRow(row) sellStats.gems = sellStats.gems + math.max(gems() - g0, 0) return true end -- keep `state.keepFree` slots free on both pets and trails local function ensureRoom(need) need = need or state.keepFree local freed = 0 local capNow = cap() for _ = 1, 30 do if capNow - itemCount("pets") >= need then break end if not sellLowest("pets") then break end freed = freed + 1 task.wait(0.08) end for _ = 1, 30 do if capNow - itemCount("trails") >= need then break end if not sellLowest("trails") then break end freed = freed + 1 task.wait(0.08) end return freed end -- ============ EVOLVE ENGINE ============ -- Verified live: evolving needs FIVE non-evolved copies of the same name, and the -- server consumes four of them, leaving one marked evolved. -- pets : petEvolveEvent:FireServer("evolvePet", petName) -- trails: evolveTrailEvent:FireServer("evolveTrail", trailInstance) -- Measured: 5x Red Bunny (1,500 gems each from the pet shop) -> pets 14 -> 10 with -- one evolved Red Bunny left; 5x Red Trail -> trails 19 -> 15 with one evolved. -- globalFunctions.getNumberOfPets / getNumberOfSameTrail count only NON-evolved -- copies, which is exactly the number the /5 gate wants. local evolveStats = { pets = 0, trails = 0, last = {} } local function evolveCounts(kind) local counts = {} for _, row in ipairs(itemRows(kind)) do if not isEvolved(row) then counts[row.name] = (counts[row.name] or 0) + 1 end end return counts end local function evolveScan(kind, onlyKeepList) local counts = evolveCounts(kind) local done = {} local names = {} for name, n in pairs(counts) do if n >= 5 then table.insert(names, name) end end table.sort(names) for _, name in ipairs(names) do if state.evolveAll or not onlyKeepList or state.keepNames[name] then if kind == "pets" then if petEvolveEvent then petEvolveEvent:FireServer("evolvePet", name) end evolveStats.pets = evolveStats.pets + 1 else -- trails take the instance, so hand over a non-evolved copy for _, row in ipairs(itemRows("trails")) do if row.name == name and not isEvolved(row) then if evolveTrailEvent then evolveTrailEvent:FireServer("evolveTrail", row.it) end break end end evolveStats.trails = evolveStats.trails + 1 end evolveStats.last[kind .. "/" .. name] = (evolveStats.last[kind .. "/" .. name] or 0) + 1 table.insert(done, name) task.wait(0.9) end end return done end local function evolveNow() local a = evolveScan("pets") local b = evolveScan("trails") return a, b end local function evolveLoop() while (state.autoEvolve or state.evolvePets or state.evolveTrails) and isCurrent() do local fired = {} if state.autoEvolve or state.evolvePets then for _, n in ipairs(evolveScan("pets")) do table.insert(fired, "pet " .. n) end end if state.autoEvolve or state.evolveTrails then for _, n in ipairs(evolveScan("trails")) do table.insert(fired, "trail " .. n) end end if #fired > 0 then setStatus("Evolved: " .. table.concat(fired, ", "), MONO.rare) notify("Evolved " .. #fired .. " item type(s)", "good") else local ready = {} for kind, label in pairs({ pets = "pets", trails = "trails" }) do local best, bestName = 0, nil for name, n in pairs(evolveCounts(kind)) do if n > best and n >= 2 then best, bestName = n, name end end if bestName then ready[#ready + 1] = string.format("%s %s %d/5", label, bestName, best) end end setStatus(#ready > 0 and ("Evolve watch: " .. table.concat(ready, ", ")) or "Evolve watch: no duplicates yet", MONO.sub) end task.wait(3) end state.autoEvolve, state.evolvePets, state.evolveTrails = false, false, false state.evolveThread = nil end -- ============ EQUIP ENGINE ============ -- The game refuses an equip when every slot is taken (findEmptyPetSlot == nil), -- so v5 unequips the weakest equipped pet first, then equips. Verified: equipping -- into a freed slot lands (pet1 went from Unique/Speedy Sensei to Omega/Soul Fusion Dog). local equipStats = { equipped = 0, unequipped = 0 } local function drainTotals() local t = 0 local rows = itemRows("pets") for _, r in ipairs(rows) do t = t + sellValueOf(r) end return t end local function autoEquipStep() local eq = player:FindFirstChild("equippedPets") if not eq then return 0 end local slots = #eq:GetChildren() if slots == 0 then slots = 4 end local rows = itemRows("pets") if #rows == 0 then return 0 end table.sort(rows, function(a, b) local ra, rb = rankOf(a), rankOf(b) if ra == rb then return sellValueOf(a) > sellValueOf(b) end return ra > rb end) local have = equippedSet() local actions = 0 local wanted = math.min(slots, #rows) for i = 1, wanted do local row = rows[i] if not have[row.it] then -- free a slot if the list is full local occupied = 0 for _ in ipairs(eq:GetChildren()) do occupied = occupied + 1 end if occupied >= slots then -- weak link: lowest rank that is currently equipped local worst for _, c in ipairs(eq:GetChildren()) do local ref = c:FindFirstChild("petReference") if ref and ref.Value then local rk = priceOf[ref.Value.Name] and priceOf[ref.Value.Name].price or 0 if not worst or rk < worst.rank then worst = { ref = ref, rank = rk } end end end if worst and worst.rank < rankOf(row) and equipPetEvent then equipPetEvent:FireServer("unequipPet", worst.ref.Value) equipStats.unequipped = equipStats.unequipped + 1 task.wait(0.35) else break end end if equipPetEvent then equipPetEvent:FireServer("equipPet", row.it) equipStats.equipped = equipStats.equipped + 1 actions = actions + 1 task.wait(0.35) end end end return actions end local function equipLoop() while state.autoEquip and isCurrent() do local n = autoEquipStep() setStatus(n > 0 and ("Equipped " .. n .. " pet(s)") or "Equipped pets already optimal", MONO.accent) task.wait(5) end state.autoEquip = false state.equipThread = nil end -- ============ HATCH ENGINE (v5 flagship) ============ -- The whole game-side hatch is: -- openCrystalRemote:InvokeServer("openCrystal", " Crystal") -- Returns (petName, rarity, imageId, extra). Cost is crystalPrices[name].price in -- Gems. No cooldown was measured; capacity (pets AND trails under maxPetCapacity) -- is the only real gate, which is why the sell engine runs inside this loop. local hatchStats = { attempts = 0, pets = 0, trails = 0, gems = 0, failed = 0 } local function crystalFor(base) local c = crystalByName(base) if c then return c end return crystals[#crystals] end -- most expensive crystal we can still afford above the gem reserve local function bestAffordable() for i = #crystals, 1, -1 do local c = crystals[i] if c.ptype == "Gems" and gems() - c.price >= state.gemReserve then return c.base end end return nil end -- how many hatches, on average, to land a named pet from this crystal local function oddsFor(base, petName) local c = crystalByName(base) if not c then return nil end for _, p in ipairs(c.pool) do if p.name == petName then local chance = math.max(p.chance, 1) return { chance = p.chance, rarity = p.rarity, expected = math.ceil(100 / chance), cost = math.ceil(100 / chance) * c.price } end end return nil end local function hatchOnce() local base = state.hatchChoice if base == "Auto" then base = bestAffordable() if not base then return false, "nothing affordable above the reserve" end end local c = crystalFor(base) if not c then return false, "no such crystal: " .. tostring(base) end if c.ptype == "Gems" and gems() - c.price < state.gemReserve then return false, "gem reserve (" .. shorten(state.gemReserve) .. ")" end if state.autoSell then ensureRoom(state.keepFree) end if cap() - itemCount("pets") < 1 or cap() - itemCount("trails") < 1 then return false, "capacity full, nothing left to sell" end local beforePets, beforeTrails = {}, {} for _, r in ipairs(itemRows("pets")) do beforePets[r.it] = true end for _, r in ipairs(itemRows("trails")) do beforeTrails[r.it] = true end local g0 = gems() local name, rarity = openCrystalRemote:InvokeServer("openCrystal", c.base .. " Crystal") hatchStats.attempts = hatchStats.attempts + 1 hatchStats.gems = hatchStats.gems + (g0 - gems()) state.hatches = state.hatches + 1 if name == nil then hatchStats.failed = hatchStats.failed + 1 return false, "server refused (capacity or price)" end state.rarity[rarity or "?"] = (state.rarity[rarity or "?"] or 0) + 1 -- what did we actually get? local got for _, r in ipairs(itemRows("pets")) do if not beforePets[r.it] then got = r break end end if got then hatchStats.pets = hatchStats.pets + 1 got.kind = "pets" else for _, r in ipairs(itemRows("trails")) do if not beforeTrails[r.it] then got = r break end end if got then hatchStats.trails = hatchStats.trails + 1 end end -- sniper bookkeeping if state.snipePet ~= "" and name == state.snipePet then state.hits[state.snipePet] = (state.hits[state.snipePet] or 0) + 1 notify((state.snipePet .. " hatched! (" .. shorten(c.price) .. " gems each)"), "good") end -- keep the good ones, sell the rest (policy lives in buildKeepSet) if state.autoSell and got then sellIfJunk(got) end return true, nil, name, rarity, c.base end local function hatchLoop() local carry, shownRate = 0, math.max(state.hatchRate, 1) local lastReport, statusAcc = 0, 0 local started = os.clock() while state.hatcher and isCurrent() do local dt = RunService.Heartbeat:Wait() shownRate = math.max(state.hatchRate, 1) carry = math.min(carry + shownRate * dt, 12) local budget = math.floor(carry) carry = carry - budget local stopReason = nil for _ = 1, budget do if not state.hatcher then break end if state.hatchMax > 0 and hatchStats.attempts >= state.hatchMax then stopReason = "reached " .. state.hatchMax .. " hatches" state.hatcher = false break end local ok, err, name = hatchOnce() if not ok then if err and err:find("capacity") then -- genuinely full and nothing sellable: wait for a sell task.wait(0.5) elseif err == "server refused (capacity or price)" then stopReason = "server refused (capacity or price)" state.hatcher = false break elseif err and (err:find("reserve") or err:find("affordable")) then stopReason = err state.hatcher = false break end else statusAcc = statusAcc + 1 if statusAcc >= 5 or os.clock() - lastReport > 1 then statusAcc, lastReport = 0, os.clock() local rar = {} for k, v in ipairs({ "Omega", "Unique", "Epic", "Rare", "Advanced", "Basic" }) do if state.rarity[v] then table.insert(rar, v .. " " .. state.rarity[v]) end end setStatus(string.format("%s: %d hatches %.1f/s %s", state.hatchChoice, state.hatches, shownRate, table.concat(rar, " / ")), MONO.success) end end end if stopReason then setStatus("Hatch stopped: " .. stopReason, MONO.warn) end end state.hatcher = false state.hatchThread = nil local dt = math.max(os.clock() - started, 1) setStatus(string.format("Hatch farm stopped: %d hatches in %.0fs (%.2f/s), %s gems", hatchStats.attempts, dt, hatchStats.attempts / dt, shorten(hatchStats.gems)), MONO.warn) end local function toggleHatch(choice) choice = choice or state.hatchChoice or "Auto" if choice ~= "Auto" then local c = crystalByName(choice) if c then choice = c.base end end if state.hatcher and state.hatchChoice == choice then state.hatcher = false setStatus("Hatcher stopping...", MONO.sub) return end state.hatchChoice = choice state.hatcher = true if not state.hatchThread then state.hatchThread = spawnLoop(hatchLoop) end end -- ============ ORB FARM (unchanged from v4, verified) ============ -- oScript fires exactly this on touch: orbEvent:FireServer("collectOrb", orbName, currentMap.Value) local function currentMap() local name = player:FindFirstChild("currentMap") name = name and name.Value or "City" local f = workspace:FindFirstChild("orbFolder") if f and f:FindFirstChild(name) then return name end if f then for _, c in ipairs(f:GetChildren()) do if #c:GetChildren() > 0 then return c.Name end end end return name end local ORB_BURST_CAP = 400 local function orbLoop() local fired = 0 local map = currentMap() local names = {} for name in pairs(orbs) do table.insert(names, name) end if #names == 0 then names = { "Red Orb" } end table.sort(names) local function orbName() if state.orbChoice == "ALL" then return names[(fired % #names) + 1] end return state.orbChoice or names[1] end local carry, sinceStatus = 0, 0 while state.orbFarming and isCurrent() do local dt = RunService.Heartbeat:Wait() carry = math.min(carry + math.max(state.orbRate, 1) * dt, ORB_BURST_CAP) local budget = math.floor(carry) carry = carry - budget if budget >= 1 then for _ = 1, budget do if orbEvent then orbEvent:FireServer("collectOrb", orbName(), map) end fired = fired + 1 if not state.orbInfinite and fired >= state.orbAmount then break end end sinceStatus = sinceStatus + dt if sinceStatus > 0.25 then sinceStatus = 0 setStatus(string.format("%s x%d (%.0f/s) %s", orbName(), fired, state.orbRate, state.orbInfinite and "infinite" or (fired .. "/" .. state.orbAmount)), MONO.success) end end if not state.orbInfinite and fired >= state.orbAmount then break end end state.orbFarming = false state.orbThread = nil setStatus("Orb farm stopped after " .. fired .. " calls", MONO.warn) end local function toggleOrb(choice) if state.orbFarming and state.orbChoice == choice then state.orbFarming = false setStatus("Orb farm stopping...", MONO.sub) return end state.orbFarming = true state.orbChoice = choice if not state.orbThread then state.orbThread = spawnLoop(orbLoop) end end -- ============ HOOP LOOP (unchanged from v4, verified) ============ -- hoopEvent is server -> client only; the payout happens when the server sees the -- character touch a hoop, so the lever is relocating Workspace.Hoops onto us. local function hrp() local ch = player.Character return ch and ch:FindFirstChild("HumanoidRootPart") end local function hoopLoop() local home = {} local passes = 0 while state.hoopLoop and isCurrent() do local root = hrp() if not root then task.wait(0.5) continue end local folder = workspace:FindFirstChild("Hoops") local list = {} if folder then for _, h in ipairs(folder:GetChildren()) do if h:IsA("BasePart") then if not home[h] then home[h] = h.CFrame end table.insert(list, h) end end end if #list == 0 then task.wait(1) continue end local before = statValue("Hoops") local anchor = root.Position for _, h in ipairs(list) do h.CFrame = CFrame.new(anchor + Vector3.new(0, 2, 0)) end task.wait(1.0) for _, h in ipairs(list) do local o = home[h] if o then h.CFrame = o end end passes = passes + 1 setStatus(string.format("Hoops +%d this pass pass %d (8s debounce each)", statValue("Hoops") - before, passes), MONO.success) task.wait(7.6) end for h, o in pairs(home) do pcall(function() h.CFrame = o end) end state.hoopLoop = false state.hoopThread = nil setStatus("Hoop loop stopped", MONO.warn) end -- ============ QUEST AUTO-COLLECT (unchanged from v4, verified) ============ -- questsScript fires questsEvent:FireServer("collectQuest", questInstance) local function collectQuests() local collected = 0 local qroot = player:FindFirstChild("Quests") if not qroot then return 0 end for _, folderName in ipairs({ "Daily Quests", "Weekly Quests", "Story Quests", "completedQuests" }) do local folder = qroot:FindFirstChild(folderName) if folder then for _, q in ipairs(folder:GetChildren()) do if q:IsA("Folder") then local reqs = q:FindFirstChild("requirements") if reqs and #reqs:GetChildren() > 0 then local done = true for _, r in ipairs(reqs:GetChildren()) do if r:IsA("ValueBase") then local p = r:FindFirstChild("progress") if p and p.Value < r.Value then done = false end end end if done and questsEvent then questsEvent:FireServer("collectQuest", q) collected = collected + 1 state.session.quests = (state.session.quests or 0) + 1 task.wait(0.6) end end end end end end return collected end local function questLoop() while state.quest and isCurrent() do local n = collectQuests() setStatus(n > 0 and ("Collected " .. n .. " quest(s)") or "Quest watch: nothing complete yet", n > 0 and MONO.success or MONO.sub) task.wait(5) end state.quest = false state.questThread = nil end -- ============ SPEED RAMPS (unverified reward, kept for ramp quests) ============ local function rampLoop() local ramps = workspace:FindFirstChild("speedRamps") local index, tries = 1, 0 while state.ramps and isCurrent() do if not ramps or #ramps:GetChildren() == 0 then setStatus("No speedRamps found", MONO.danger) task.wait(3) else local list = ramps:GetChildren() local model = list[((index - 1) % #list) + 1] index = index + 1 local touch for _, d in ipairs(model:GetDescendants()) do if d:IsA("BasePart") and d.Name == "touchPart" then touch = d break end end local root = hrp() if touch and root then root.CFrame = CFrame.new(touch.Position + Vector3.new(0, 3, 0)) if type(firetouchinterest) == "function" then pcall(function() firetouchinterest(root, touch, 0) end) task.wait(0.05) pcall(function() firetouchinterest(root, touch, 1) end) end if speedRampEvent then speedRampEvent:FireServer("usedRamp") end tries = tries + 1 setStatus("Ramp touches: " .. tries .. " (unverified)", MONO.warn) end end task.wait(0.5) end state.ramps = false state.rampThread = nil end -- ============ AUTO REBIRTH (new) ============ -- confirmButton in gameGuiScript: rebirthEvent:FireServer("rebirthRequest") once -- level >= calculateRequiredRebirthLevel(Rebirths.Value, player). local function requiredRebirthLevel() if not GF then return nil end local ok, res = pcall(function() return GF.calculateRequiredRebirthLevel(rebirths(), player) end) return ok and res or nil end local function rebirthLoop() while state.autoRebirth and isCurrent() do local req = requiredRebirthLevel() if req and level() >= req then if rebirthEvent then rebirthEvent:FireServer("rebirthRequest") end state.rebirthsDone = state.rebirthsDone + 1 setStatus(string.format("REBIRTH sent (%d this session, was level %d >= %d)", state.rebirthsDone, level(), req), MONO.rare) task.wait(6) else setStatus(string.format("Auto rebirth: level %d / %d needed (rebirths %d)", level(), req or -1, rebirths()), MONO.sub) task.wait(5) end end state.autoRebirth = false state.rebirthThread = nil end -- ============ ULTIMATE UPGRADES (new) ============ -- Los.secondGameGuiScript: ultimatesRemote:InvokeServer("upgradeUltimate", name) -- costs Rebirths (globalFunctions.calculateUltimateRebirthCost), max 3-10 each. local ULTIMATE_PRIORITY = { "Step Booster", "Gem Booster", "Ethereal Orbs", "Demon Hoops", "Infernal Gems", "+1 Pet Slot", "+10 Item Capacity", "x2 Chest Rewards", "x2 Quest Rewards", "x2 Trail Boosts", "Divine Rebirth", "+1 Daily Spin", } local function ultimateProgress(name) local owned = player:FindFirstChild("ultimatesFolder") and player.ultimatesFolder:FindFirstChild(name) local def = RS:FindFirstChild("gameUltimatesFolder") and RS.gameUltimatesFolder:FindFirstChild(name) local have = owned and owned.Value or 0 local maxUp = def and def:FindFirstChild("maxUpgrades") local cost = nil if GF and def then local ok, res = pcall(function() return GF.calculateUltimateRebirthCost(def, have) end) if ok then cost = res end end return have, maxUp and maxUp.Value or 0, cost end local function ultimateLoop() while state.autoUltimates and isCurrent() do local bought = 0 for _, name in ipairs(ULTIMATE_PRIORITY) do if not state.autoUltimates then break end local have, maxUp, cost = ultimateProgress(name) if cost and have < maxUp and rebirths() >= cost + state.rebirthReserve then local ok, res = pcall(function() return ultimatesRemote:InvokeServer("upgradeUltimate", name) end) if ok and res == true then state.ultimatesBought = state.ultimatesBought + 1 bought = bought + 1 setStatus(string.format("Ultimate bought: %s (%d/%d) for %d rebirths", name, have + 1, maxUp, cost), MONO.rare) task.wait(1.2) else setStatus("Ultimate refused: " .. name, MONO.warn) task.wait(1.2) end end end if bought == 0 then setStatus(string.format("Ultimates: nothing affordable (rebirths %d, reserve %d)", rebirths(), state.rebirthReserve), MONO.sub) end task.wait(4) end state.autoUltimates = false state.ultimateThread = nil end -- ============ CHEST COLLECTOR (new) ============ -- gameGuiScript: checkChestRemote:InvokeServer("Golden Chest") etc., 6h cooldown, -- returns (ok, currency, amount). Touching circleInner is what the game wires up, -- so we stand on it and also invoke directly. local CHESTS = { { label = "Golden Chest", model = "goldenChest" }, { label = "Enchanted Chest", model = "enchantedChest" }, { label = "Magma Chest", model = "magmaChest" }, { label = "Jungle Chest", model = "jungleChest" }, } local function chestLoop() while state.chests and isCurrent() do local got = 0 for _, chest in ipairs(CHESTS) do if not state.chests then break end local model = workspace:FindFirstChild(chest.model) local inner = model and model:FindFirstChild("circleInner", true) if inner and hrp() then hrp().CFrame = CFrame.new(inner.Position + Vector3.new(0, 3, 0)) task.wait(0.4) end local ok, res, currency, amount = pcall(function() return checkChestRemote:InvokeServer(chest.label) end) if ok and res == true then state.chestsOpened = state.chestsOpened + 1 got = got + 1 setStatus(string.format("%s: +%s %s", chest.label, shorten(amount or 0), tostring(currency)), MONO.rare) end task.wait(0.5) end if got == 0 then setStatus("Chests: nothing ready (6h cooldown)", MONO.sub) end task.wait(20) end state.chests = false state.chestThread = nil end -- ============ GUI ============ local old = player.PlayerGui:FindFirstChild("LOS_Autofarm") if old then old:Destroy() end local gui = Instance.new("ScreenGui") gui.Name = "LOS_Autofarm" gui.ResetOnSpawn = false gui.DisplayOrder = 1000 gui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling gui.Parent = player:WaitForChild("PlayerGui") local Main = Instance.new("Frame") Main.Name = "Main" Main.Parent = gui Main.BackgroundColor3 = MONO.bg Main.BackgroundTransparency = 0.05 Main.BorderSizePixel = 0 Main.Position = UDim2.new(0.5, -170, 0.5, -300) Main.Size = UDim2.new(0, 340, 0, 600) Main.ClipsDescendants = true Main.Active = true do local stroke = Instance.new("UIStroke", Main) stroke.Color = MONO.border stroke.Thickness = 1 local corner = Instance.new("UICorner", Main) corner.CornerRadius = UDim.new(0, 10) end local TB = Instance.new("Frame") TB.Name = "TitleBar" TB.Parent = Main TB.BackgroundColor3 = MONO.panel TB.BorderSizePixel = 0 TB.Size = UDim2.new(1, 0, 0, 44) TB.Active = true do local dragging, offset = false, Vector2.new() TB.InputBegan:Connect(function(i) if i.UserInputType == Enum.UserInputType.MouseButton1 then dragging = true offset = Vector2.new(i.Position.X, i.Position.Y) - Main.AbsolutePosition end end) UserInputService.InputChanged:Connect(function(i) if dragging and i.UserInputType == Enum.UserInputType.MouseMovement then local p = Vector2.new(i.Position.X, i.Position.Y) - offset Main.Position = UDim2.new(0, p.X, 0, p.Y) end end) UserInputService.InputEnded:Connect(function(i) if i.UserInputType == Enum.UserInputType.MouseButton1 then dragging = false end end) end local TT = Instance.new("TextLabel") TT.Parent = TB TT.BackgroundTransparency = 1 TT.Position = UDim2.new(0, 16, 0, 0) TT.Size = UDim2.new(1, -100, 1, 0) TT.Font = Enum.Font.GothamBold TT.Text = "LOS AUTOFARM v5" TT.TextColor3 = MONO.text TT.TextSize = 15 TT.TextXAlignment = Enum.TextXAlignment.Left local function titleButton(text, xOff, colour) local b = Instance.new("TextButton") b.Parent = Main b.BackgroundColor3 = colour b.BorderSizePixel = 0 b.Position = UDim2.new(1, xOff, 0, 8) b.Size = UDim2.new(0, 28, 0, 28) b.Font = Enum.Font.GothamBold b.Text = text b.TextColor3 = Color3.new(1, 1, 1) b.TextSize = 13 b.AutoButtonColor = false local corner = Instance.new("UICorner", b) corner.CornerRadius = UDim.new(0, 6) return b end local Minimise = titleButton("_", -72, MONO.panel2) local Close = titleButton("X", -38, MONO.danger) local Status = Instance.new("TextLabel") Status.Name = "Status" Status.Parent = Main Status.BackgroundColor3 = MONO.panel Status.BorderSizePixel = 0 Status.Position = UDim2.new(0, 10, 0, 52) Status.Size = UDim2.new(1, -20, 0, 28) Status.Font = Enum.Font.Gotham Status.Text = "Idle" Status.TextColor3 = MONO.sub Status.TextSize = 12 Status.TextTruncate = Enum.TextTruncate.AtEnd do local c = Instance.new("UICorner", Status) c.CornerRadius = UDim.new(1, 0) end setStatus = function(text, colour) Status.Text = text Status.TextColor3 = colour or MONO.sub end local Toast = Instance.new("TextLabel") Toast.Parent = Main Toast.BackgroundColor3 = MONO.panel2 Toast.BorderSizePixel = 0 Toast.Position = UDim2.new(0, 10, 0, 84) Toast.Size = UDim2.new(1, -20, 0, 22) Toast.Font = Enum.Font.GothamBold Toast.TextSize = 11 Toast.TextColor3 = MONO.text Toast.Visible = false Toast.TextTruncate = Enum.TextTruncate.AtEnd do local c = Instance.new("UICorner", Toast) c.CornerRadius = UDim.new(0, 6) end local toastToken = 0 notify = function(text, tone) toastToken = toastToken + 1 local mine = toastToken Toast.Text = text Toast.TextColor3 = tone == "good" and MONO.success or tone == "bad" and MONO.danger or tone == "warn" and MONO.warn or MONO.text Toast.Visible = true task.delay(3, function() if mine == toastToken then Toast.Visible = false end end) end local SL = Instance.new("TextLabel") SL.Name = "Stats" SL.Parent = Main SL.BackgroundTransparency = 1 SL.Position = UDim2.new(0, 10, 0, 110) SL.Size = UDim2.new(1, -20, 0, 58) SL.Font = Enum.Font.Gotham SL.TextColor3 = MONO.text SL.TextSize = 11 SL.TextXAlignment = Enum.TextXAlignment.Left SL.TextYAlignment = Enum.TextYAlignment.Top SL.Text = "" local SF = Instance.new("ScrollingFrame") SF.Name = "Scroll" SF.Parent = Main SF.BackgroundTransparency = 1 SF.BorderSizePixel = 0 SF.Position = UDim2.new(0, 0, 0, 170) SF.Size = UDim2.new(1, 0, 1, -170) SF.ScrollBarThickness = 5 SF.ScrollBarImageColor3 = MONO.border SF.ScrollBarImageTransparency = 0.15 SF.VerticalScrollBarInset = Enum.ScrollBarInset.ScrollBar SF.AutomaticCanvasSize = Enum.AutomaticSize.Y SF.CanvasSize = UDim2.new(0, 0, 0, 0) local CC = Instance.new("Frame") CC.Parent = SF CC.BackgroundTransparency = 1 CC.Size = UDim2.new(1, -SF.ScrollBarThickness, 0, 0) CC.AutomaticSize = Enum.AutomaticSize.Y local UL = Instance.new("UIListLayout") UL.Parent = CC UL.Padding = UDim.new(0, 6) UL.SortOrder = Enum.SortOrder.LayoutOrder do local pad = Instance.new("UIPadding", CC) pad.PaddingTop = UDim.new(0, 6) pad.PaddingBottom = UDim.new(0, 16) pad.PaddingLeft = UDim.new(0, 10) pad.PaddingRight = UDim.new(0, 10) end -- ============ WIDGETS ============ local ord = 0 local function secLabel(text) ord = ord + 1 local l = Instance.new("TextLabel") l.Parent = CC l.BackgroundTransparency = 1 l.Size = UDim2.new(1, 0, 0, 22) l.Font = Enum.Font.GothamBold l.Text = text l.TextColor3 = MONO.accent l.TextSize = 11 l.TextXAlignment = Enum.TextXAlignment.Left l.LayoutOrder = ord local rule = Instance.new("Frame", l) rule.BackgroundColor3 = MONO.border rule.BorderSizePixel = 0 rule.Position = UDim2.new(0, 0, 1, -3) rule.Size = UDim2.new(1, 0, 0, 1) return l end local function note(text, height) ord = ord + 1 local l = Instance.new("TextLabel") l.Parent = CC l.BackgroundTransparency = 1 l.Size = UDim2.new(1, 0, 0, height or 26) l.Font = Enum.Font.Gotham l.Text = text l.TextColor3 = MONO.sub l.TextSize = 10 l.TextWrapped = true l.TextXAlignment = Enum.TextXAlignment.Left l.TextYAlignment = Enum.TextYAlignment.Top l.LayoutOrder = ord return l end local pillOn = {} local function pill(text, onClick) ord = ord + 1 local b = Instance.new("TextButton") b.Parent = CC b.BackgroundColor3 = MONO.panel2 b.BorderSizePixel = 0 b.Size = UDim2.new(1, 0, 0, 30) b.Font = Enum.Font.GothamBold b.Text = text b.TextColor3 = MONO.text b.TextSize = 12 b.AutoButtonColor = false b.TextTruncate = Enum.TextTruncate.AtEnd b.LayoutOrder = ord local s = Instance.new("UIStroke", b) s.Color = MONO.border s.Thickness = 1 local corner = Instance.new("UICorner", b) corner.CornerRadius = UDim.new(0, 6) b.MouseEnter:Connect(function() TweenService:Create(b, TweenInfo.new(0.12), { BackgroundColor3 = MONO.accent, TextColor3 = MONO.bg }):Play() end) b.MouseLeave:Connect(function() local on = pillOn[b] TweenService:Create(b, TweenInfo.new(0.12), { BackgroundColor3 = on and MONO.accent or MONO.panel2, TextColor3 = on and MONO.bg or MONO.text }):Play() end) b.MouseButton1Click:Connect(onClick) return b end local togglePills = {} local function activePill(btn, isOn, label) table.insert(togglePills, { btn = btn, isOn = isOn, label = label }) return btn end local function refreshPills() for _, p in ipairs(togglePills) do if p.label then local t = p.label() if p.btn.Text ~= t then p.btn.Text = t end end local on = p.isOn() and true or false if on ~= p.on then p.on = on pillOn[p.btn] = on p.btn.BackgroundColor3 = on and MONO.accent or MONO.panel2 p.btn.TextColor3 = on and MONO.bg or MONO.text local s = p.btn:FindFirstChildOfClass("UIStroke") if s then s.Color = on and MONO.accent or MONO.border end end end end local function slider(title, min, max, def, step, fmt, callback) ord = ord + 1 local c = Instance.new("Frame") c.Parent = CC c.BackgroundColor3 = MONO.panel c.BorderSizePixel = 0 c.Size = UDim2.new(1, 0, 0, 44) c.LayoutOrder = ord local cc1 = Instance.new("UICorner", c) cc1.CornerRadius = UDim.new(0, 6) local st = Instance.new("UIStroke", c) st.Color = MONO.border st.Thickness = 1 local lb = Instance.new("TextLabel") lb.Parent = c lb.BackgroundTransparency = 1 lb.Position = UDim2.new(0, 12, 0, 4) lb.Size = UDim2.new(0.65, 0, 0, 16) lb.Font = Enum.Font.Gotham lb.Text = title lb.TextColor3 = MONO.sub lb.TextSize = 11 lb.TextXAlignment = Enum.TextXAlignment.Left local vl = Instance.new("TextLabel") vl.Parent = c vl.BackgroundTransparency = 1 vl.Position = UDim2.new(0.55, 0, 0, 4) vl.Size = UDim2.new(0.45, -12, 0, 16) vl.Font = Enum.Font.GothamBold vl.TextColor3 = MONO.text vl.TextSize = 11 vl.TextXAlignment = Enum.TextXAlignment.Right local tr = Instance.new("Frame") tr.Parent = c tr.BackgroundColor3 = MONO.panel2 tr.BorderSizePixel = 0 tr.Position = UDim2.new(0, 12, 0, 28) tr.Size = UDim2.new(1, -24, 0, 6) local tc = Instance.new("UICorner", tr) tc.CornerRadius = UDim.new(1, 0) local fill = Instance.new("Frame") fill.Parent = tr fill.BackgroundColor3 = MONO.text fill.BorderSizePixel = 0 fill.Size = UDim2.new(0, 0, 1, 0) local fc = Instance.new("UICorner", fill) fc.CornerRadius = UDim.new(1, 0) local knob = Instance.new("Frame") knob.Parent = tr knob.BackgroundColor3 = MONO.text knob.BorderSizePixel = 0 knob.Size = UDim2.new(0, 14, 0, 14) local kc = Instance.new("UICorner", knob) kc.CornerRadius = UDim.new(1, 0) local value = def local dragging = false local function paint() local r = (value - min) / math.max(max - min, 1) vl.Text = fmt and fmt(value) or tostring(value) fill.Size = UDim2.new(r, 0, 1, 0) knob.Position = UDim2.new(r, -7, 0, -4) end local function setFrom(x) local r = math.clamp((x - tr.AbsolutePosition.X) / math.max(tr.AbsoluteSize.X, 1), 0, 1) local raw = min + (max - min) * r value = math.clamp(math.floor(raw / step + 0.5) * step, min, max) paint() if callback then callback(value) end end knob.InputBegan:Connect(function(i) if i.UserInputType == Enum.UserInputType.MouseButton1 then dragging = true end end) UserInputService.InputChanged:Connect(function(i) if dragging and i.UserInputType == Enum.UserInputType.MouseMovement then setFrom(i.Position.X) end end) UserInputService.InputEnded:Connect(function(i) if i.UserInputType == Enum.UserInputType.MouseButton1 then dragging = false end end) tr.InputBegan:Connect(function(i) if i.UserInputType == Enum.UserInputType.MouseButton1 then dragging = true setFrom(i.Position.X) end end) paint() if callback then callback(value) end return { set = function(v) value = v; paint() end } end local function textbox(placeholder, onEnter) ord = ord + 1 local b = Instance.new("TextBox") b.Parent = CC b.BackgroundColor3 = MONO.panel b.BorderSizePixel = 0 b.Size = UDim2.new(1, 0, 0, 30) b.Font = Enum.Font.Gotham b.PlaceholderText = placeholder b.Text = "" b.TextColor3 = MONO.text b.PlaceholderColor3 = MONO.sub b.TextSize = 11 b.ClearTextOnFocus = false b.LayoutOrder = ord local s = Instance.new("UIStroke", b) s.Color = MONO.border s.Thickness = 1 local c = Instance.new("UICorner", b) c.CornerRadius = UDim.new(0, 6) b.FocusLost:Connect(function() onEnter(b.Text) end) return b end -- ============ SECTIONS ============ secLabel("SELL POLICY (what gets auto-sold)") activePill(pill("Auto-sell junk (keeps capacity free)", function() state.autoSell = not state.autoSell end), function() return state.autoSell end) local rankPills = {} for _, mode in ipairs({ "MARKET", "VALUE", "RARITY" }) do local b = pill("Rank by " .. mode, function() state.rankMode = mode notify("ranking by " .. mode, "info") end) rankPills[mode] = b table.insert(togglePills, { btn = b, isOn = function() return state.rankMode == mode end }) end slider("Keep best N pets/trails", 0, 20, state.keepTop, 1, nil, function(v) state.keepTop = v end) slider("Keep N copies of a kept name (evolve fodder)", 0, 10, state.keepDupes, 1, nil, function(v) state.keepDupes = v end) slider("Free slots to hold open", 1, 10, state.keepFree, 1, nil, function(v) state.keepFree = v end) activePill(pill("Keep evolved pets/trails", function() state.keepEvolved = not state.keepEvolved end), function() return state.keepEvolved end) activePill(pill("Evolve only kept names", function() state.evolveAll = not state.evolveAll end), function() return not state.evolveAll end) secLabel("Rarity floor (keep this tier and above, dump below)") for _, r in ipairs({ "OFF", "Basic", "Advanced", "Rare", "Epic", "Unique" }) do local b = pill(r == "OFF" and "No floor (rank only)" or ("Keep " .. r .. " and above"), function() state.sellBelow = r == "OFF" and "Basic" or r notify(r == "OFF" and "rarity floor off" or ("keeping " .. r .. " and above, dumping below"), "info") end) table.insert(togglePills, { btn = b, isOn = function() return r == "OFF" and (RARITY_ORDER[state.sellBelow] or 1) <= 1 or state.sellBelow == r end }) end pill("PRESET: rare-pet farm (e.g. Swift Samurai)", function() state.keepTop = 0 state.keepDupes = 5 state.keepEvolved = true state.sellBelow = "Unique" state.keepNames["Swift Samurai"] = true state.snipePet = "Swift Samurai" state.hatchChoice = "Jungle" state.rankMode = "MARKET" state.autoEvolve = true state.evolvePets, state.evolveTrails = true, true if not state.evolveThread then state.evolveThread = spawnLoop(evolveLoop) end notify("preset: keep+evolve Swift Samurai, dump everything below Unique", "good") setStatus("Preset applied: hatch Jungle, keep Swift Samurai, auto-evolve on", MONO.rare) end) local keepBox = textbox("Add a name to the keep list (empty clears it)", function(text) text = text:gsub("^%s+", ""):gsub("%s+$", "") if text == "" then state.keepNames = {} notify("keep list cleared", "info") else state.keepNames[text] = true notify("kept: " .. text, "good") end keepBox.Text = "" end) pill("Sell junk now", function() local freed = 0 for _ = 1, 30 do local f = ensureRoom(state.keepFree) freed = freed + f if f == 0 then break end end notify(freed > 0 and ("freed " .. freed .. " slots") or "nothing sellable", freed > 0 and "good" or "warn") end) local sellPreviewLabel = note("next to sell: ...", 46) local evolveWatchLabel = note("evolve watch: ...", 46) local keepListLabel = note("keep list: none", 20) secLabel("HATCH FARM (direct openCrystalRemote, no menu, no walk)") slider("Hatches per second", 1, 20, state.hatchRate, 1, nil, function(v) state.hatchRate = v end) slider("Gem reserve", 0, 10000000, state.gemReserve, 100000, function(v) return shorten(v) end, function(v) state.gemReserve = v end) slider("Stop after N hatches (0 = forever)", 0, 5000, state.hatchMax, 50, nil, function(v) state.hatchMax = v end) for _, c in ipairs(crystals) do local label = string.format("%s %s %s", c.base, shorten(c.price), c.ptype) activePill(pill(label, function() toggleHatch(c.base) end), function() return state.hatcher and state.hatchChoice == c.base end) end activePill(pill("AUTO (most expensive affordable)", function() toggleHatch("Auto") end), function() return state.hatcher and state.hatchChoice == "Auto" end) local snipeBox = textbox("Snipe pet name (e.g. Swift Samurai) then Enter", function(text) state.snipePet = text if text == "" then notify("sniper cleared", "info") return end local odds = oddsFor(state.hatchChoice ~= "Auto" and state.hatchChoice or "Jungle", text) if odds then notify(string.format("%s: %s %d%%, ~%d hatches (~%s gems)", text, odds.rarity, odds.chance, odds.expected, shorten(odds.cost)), "good") else notify("no crystal in the live tables drops " .. text, "warn") end end) do local lines = {} for _, c in ipairs(crystals) do if #c.pool > 0 then table.insert(lines, c.base .. ": " .. crystalLabel(c)) end end note("LIVE DROP TABLES (ReplicatedStorage.crystalChances)\n" .. table.concat(lines, "\n"), 150) end secLabel("ORB FARM (pays per call, no rate limit)") slider("Fire rate (calls/sec)", 5, 5000, state.orbRate, 25, nil, function(v) state.orbRate = v end) slider("Fire amount", 100, 1000000, state.orbAmount, 5000, nil, function(v) state.orbAmount = v end) local orbAmountBtn = pill("", function() state.orbInfinite = not state.orbInfinite end) activePill(orbAmountBtn, function() return not state.orbInfinite end, function() return state.orbInfinite and "Amount: infinite (click to cap)" or ("Amount: " .. state.orbAmount .. " calls") end) local orbList = {} for name in pairs(orbs) do table.insert(orbList, name) end table.sort(orbList) activePill(pill("ALL ORBS (rotate every payout type)", function() toggleOrb("ALL") end), function() return state.orbFarming and state.orbChoice == "ALL" end) for _, name in ipairs(orbList) do local info = orbs[name] activePill(pill(string.format("%s -> %s", name, info.stat), function() toggleOrb(name) end), function() return state.orbFarming and state.orbChoice == name end) end note("measured per call: Red 3397 steps, Ethereal 5557 steps, Gem 2836 gems, Yellow 12 exp", 20) secLabel("HOOP LOOP (8s per-hoop debounce)") activePill(pill("Hoop Loop (35 hoops / pass, 8.6s cycle)", function() if state.hoopLoop then state.hoopLoop = false setStatus("Hoop loop stopping...", MONO.sub) return end state.hoopLoop = true if not state.hoopThread then state.hoopThread = spawnLoop(hoopLoop) end end), function() return state.hoopLoop end) secLabel("AUTO EQUIP (best pets into every slot)") activePill(pill("Auto-equip best pets", function() state.autoEquip = not state.autoEquip if state.autoEquip and not state.equipThread then state.equipThread = spawnLoop(equipLoop) end end), function() return state.autoEquip end) pill("Equip best now", function() local n = autoEquipStep() notify(n > 0 and ("equipped " .. n .. " pets") or "already optimal", n > 0 and "good" or "info") end) note("equipping needs a free slot: v5 unequips the weakest equipped pet first, then equips. Equipped pets can never be sold by the sell engine.", 30) secLabel("QUEST AUTO-COLLECT") activePill(pill("Collect completed quests", function() if state.quest then state.quest = false setStatus("Quest collector stopping...", MONO.sub) return end state.quest = true if not state.questThread then state.questThread = spawnLoop(questLoop) end end), function() return state.quest end) secLabel("AUTO EVOLVE (5 non-evolved copies -> 1 evolved)") activePill(pill("Auto evolve everything", function() state.autoEvolve = not state.autoEvolve if state.autoEvolve then state.evolvePets, state.evolveTrails = true, true if not state.evolveThread then state.evolveThread = spawnLoop(evolveLoop) end else state.evolvePets, state.evolveTrails = false, false end end), function() return state.autoEvolve end) activePill(pill("Auto evolve pets only", function() state.evolvePets = not state.evolvePets if state.evolvePets and not state.evolveThread then state.evolveThread = spawnLoop(evolveLoop) end end), function() return state.evolvePets and not state.autoEvolve end) activePill(pill("Auto evolve trails only", function() state.evolveTrails = not state.evolveTrails if state.evolveTrails and not state.evolveThread then state.evolveThread = spawnLoop(evolveLoop) end end), function() return state.evolveTrails and not state.autoEvolve end) pill("Evolve everything ready NOW", function() local a, b = evolveNow() notify(string.format("evolved %d pet name(s), %d trail name(s)", #a, #b), (#a + #b) > 0 and "good" or "warn") end) note("petEvolveEvent:FireServer(\"evolvePet\", name) / evolveTrailEvent:FireServer(\"evolveTrail\", instance). Verified: 5 copies in, 4 consumed, 1 left evolved. Evolution needs 5 copies of the SAME name, so the sell policy keeps duplicates of kept names.", 44) secLabel("AUTO REBIRTH") slider("Keep N rebirths spare", 0, 20, state.rebirthReserve, 1, nil, function(v) state.rebirthReserve = v end) activePill(pill("Auto rebirth when level is enough", function() state.autoRebirth = not state.autoRebirth if state.autoRebirth and not state.rebirthThread then state.rebirthThread = spawnLoop(rebirthLoop) end end), function() return state.autoRebirth end) note("rebirthEvent:FireServer(\"rebirthRequest\") once level >= calculateRequiredRebirthLevel(rebirths, player).", 20) secLabel("ULTIMATE UPGRADES (costs rebirths)") activePill(pill("Auto-buy ultimates", function() state.autoUltimates = not state.autoUltimates if state.autoUltimates and not state.ultimateThread then state.ultimateThread = spawnLoop(ultimateLoop) end end), function() return state.autoUltimates end) note("ultimatesRemote:InvokeServer(\"upgradeUltimate\", name). Priority: Step Booster, Gem Booster, Ethereal Orbs, Demon Hoops, Infernal Gems, slots, chests, quests, trails, Divine Rebirth, spins.", 34) secLabel("CHEST COLLECTOR") activePill(pill("Open golden / enchanted / magma / jungle chests", function() state.chests = not state.chests if state.chests and not state.chestThread then state.chestThread = spawnLoop(chestLoop) end end), function() return state.chests end) note("checkChestRemote:InvokeServer(\"Golden Chest\") etc. 6h cooldown each.", 20) secLabel("SPEED RAMP (unverified)") activePill(pill("Touch speed ramps", function() if state.ramps then state.ramps = false setStatus("Ramp loop stopping...", MONO.sub) return end state.ramps = true if not state.rampThread then state.rampThread = spawnLoop(rampLoop) end end), function() return state.ramps end) -- ============ MINIMISE / CLOSE / HOTKEY ============ local fullSize = Main.Size local function applyMinimise(on) local scroll = Main:FindFirstChild("Scroll") local stats = Main:FindFirstChild("Stats") state.minimised = on if scroll then scroll.Visible = not on end if stats then stats.Visible = not on end Main.Size = on and UDim2.new(0, 340, 0, 86) or fullSize Minimise.Text = on and "+" or "_" end Minimise.MouseButton1Click:Connect(function() applyMinimise(not state.minimised) end) Close.MouseButton1Click:Connect(function() state.orbFarming, state.hoopLoop, state.hatcher, state.quest = false, false, false, false state.evolvePets, state.evolveTrails, state.ramps = false, false, false state.autoRebirth, state.autoUltimates, state.chests, state.autoEquip = false, false, false, false state.autoEvolve = false for _, key in ipairs({ "orbThread", "hoopThread", "hatchThread", "questThread", "petThread", "trailThread", "rampThread", "rebirthThread", "ultimateThread", "chestThread", "equipThread" }) do state[key] = nil end pcall(function() gui:Destroy() end) end) UserInputService.InputBegan:Connect(function(i, processed) if processed then return end if i.KeyCode == Enum.KeyCode.RightShift then gui.Enabled = not gui.Enabled end end) -- ============ SESSION STATS ============ local function itemTotal(kind) local n = 0 for _, r in ipairs(itemRows(kind)) do n = n + 1 end return n end state.session = { t = os.clock(), steps = statValue("Steps"), gems = gems(), exp = statValue("exp"), hoops = statValue("Hoops"), level = level(), rebirths = rebirths(), pets = itemTotal("pets"), trails = itemTotal("trails"), hatches = 0, } local function sessionText() local s = state.session local dt = math.max(os.clock() - s.t, 1) local m = dt / 60 local best = "" for name, count in pairs(state.hits) do best = name .. " x" .. count break end return string.format( "Steps %s (%s/m) Gems %s (%s/m)\nLv %d Rebirths %d Pets %d/%d Trails %d/%d\nHatches %d (%.1f/m) Gems spent %s Sold %d pets / %d trails%s", shorten(statValue("Steps")), shorten((statValue("Steps") - s.steps) / m), shorten(gems()), shorten((gems() - s.gems) / m), level(), rebirths(), itemTotal("pets"), cap(), itemTotal("trails"), cap(), hatchStats.attempts, hatchStats.attempts / m, shorten(hatchStats.gems), sellStats.pets, sellStats.trails, best ~= "" and ("\nSniper: " .. best) or "") end -- ============ PROGRAMMATIC CONTROL (drives the ;los IY plugin) ============ GENV.__LOS_AUTOFARM = { instance = INSTANCE_ID, state = state, crystals = crystals, prices = priceOf, stats = { hatch = hatchStats, sell = sellStats, equip = equipStats }, orbFarm = function(choice) if choice == nil then state.orbFarming = false return end toggleOrb(choice) end, hatch = function(choice) if choice == nil then state.hatcher = false return end toggleHatch(choice) end, hoop = function(on) if on and not state.hoopLoop then state.hoopLoop = true if not state.hoopThread then state.hoopThread = spawnLoop(hoopLoop) end elseif not on then state.hoopLoop = false end end, quests = function(on) if on and not state.quest then state.quest = true if not state.questThread then state.questThread = spawnLoop(questLoop) end elseif not on then state.quest = false end end, evolve = function(which, on) if which == "all" then state.autoEvolve = on ~= false if state.autoEvolve then state.evolvePets, state.evolveTrails = true, true if not state.evolveThread then state.evolveThread = spawnLoop(evolveLoop) end else state.evolvePets, state.evolveTrails = false, false end elseif which == "pets" then state.evolvePets = on ~= false if state.evolvePets and not state.evolveThread then state.evolveThread = spawnLoop(evolveLoop) end elseif which == "trails" then state.evolveTrails = on ~= false if state.evolveTrails and not state.evolveThread then state.evolveThread = spawnLoop(evolveLoop) end end end, evolveNow = evolveNow, evolveReady = function() local out = {} for _, kind in ipairs({ "pets", "trails" }) do for name, n in pairs(evolveCounts(kind)) do if n >= 2 then table.insert(out, string.format("%s %s %d/5", kind, name, n)) end end end table.sort(out) return out end, sellPreview = function(kind, n) return sellPreview(kind or "pets", n or 5) end, rank = function(mode) if mode then state.rankMode = mode end return state.rankMode end, sellFloor = function(r) if r then state.sellBelow = r end return state.sellBelow end, keepDupes = function(n) if n then state.keepDupes = n end return state.keepDupes end, ramps = function(on) if on and not state.ramps then state.ramps = true if not state.rampThread then state.rampThread = spawnLoop(rampLoop) end elseif not on then state.ramps = false end end, sellJunk = function(n) local freed = 0 for _ = 1, n or 20 do local f = ensureRoom(state.keepFree) freed = freed + f if f == 0 then break end end return freed end, sellAll = function() local n = 0 state.keepTop, state.keepDupes = 0, 0 for _ = 1, 80 do if not sellLowest("pets") then break end n = n + 1 task.wait(0.1) end for _ = 1, 80 do if not sellLowest("trails") then break end n = n + 1 task.wait(0.1) end return n end, autoEquip = function(on) state.autoEquip = on and true or false if state.autoEquip and not state.equipThread then state.equipThread = spawnLoop(equipLoop) end end, equipNow = function() return autoEquipStep() end, rebirth = function(on) state.autoRebirth = on and true or false if state.autoRebirth and not state.rebirthThread then state.rebirthThread = spawnLoop(rebirthLoop) end end, ultimates = function(on) state.autoUltimates = on and true or false if state.autoUltimates and not state.ultimateThread then state.ultimateThread = spawnLoop(ultimateLoop) end end, chests = function(on) state.chests = on and true or false if state.chests and not state.chestThread then state.chestThread = spawnLoop(chestLoop) end end, snipe = function(petName, crystal) state.snipePet = petName or "" if crystal then local c = crystalByName(crystal) state.hatchChoice = c and c.base or crystal end if state.snipePet ~= "" then toggleHatch(state.hatchChoice) end local base = crystalByName(state.hatchChoice) and crystalByName(state.hatchChoice).base or "Jungle" return oddsFor(base, state.snipePet) end, keep = function(petName, on) if petName == nil then return state.keepNames end state.keepNames[petName] = on ~= false or nil return state.keepNames end, oneHatch = function(crystal) local saved = state.hatchChoice if crystal then state.hatchChoice = crystal end local ok, err, name, rarity = hatchOnce() state.hatchChoice = saved return ok, err, name, rarity end, collectQuests = collectQuests, stopAll = function() state.orbFarming, state.hoopLoop, state.hatcher, state.quest = false, false, false, false state.evolvePets, state.evolveTrails, state.ramps = false, false, false state.autoRebirth, state.autoUltimates, state.chests, state.autoEquip = false, false, false, false state.autoEvolve = false end, } -- ============ REFRESH LOOP ============ do local acc, accPill = 0, 0 local conn conn = RunService.Heartbeat:Connect(function(dt) if not isCurrent() then conn:Disconnect() return end accPill = accPill + dt if accPill >= 0.2 then accPill = 0 refreshPills() end acc = acc + dt if acc < 1 then return end acc = 0 if SL.Visible then SL.Text = sessionText() end local pd = sellPreview("pets", 3) local td = sellPreview("trails", 2) sellPreviewLabel.Text = "next pets to sell: " .. (#pd > 0 and table.concat(pd, ", ") or "nothing") .. "\nnext trails: " .. (#td > 0 and table.concat(td, ", ") or "nothing") local watch = {} for _, kind in ipairs({ "pets", "trails" }) do for name, n in pairs(evolveCounts(kind)) do if n >= 2 then table.insert(watch, name .. " " .. n .. "/5") end end end table.sort(watch) evolveWatchLabel.Text = "evolve watch (non-evolved copies): " .. (#watch > 0 and table.concat(watch, ", ") or "nothing yet") .. (state.autoEvolve and " [auto ON]" or " [auto off]") local keeps = {} for name in pairs(state.keepNames) do table.insert(keeps, name) end table.sort(keeps) keepListLabel.Text = "keep list: " .. (#keeps > 0 and table.concat(keeps, ", ") or "none") .. " ranking: " .. state.rankMode .. " floor: " .. state.sellBelow end) end print("[LOS Autofarm v5] loaded. Hatch = openCrystalRemote:InvokeServer(\"openCrystal\", \" Crystal\"). " .. #crystals .. " crystals, " .. (function() local n = 0 for _ in pairs(priceOf) do n = n + 1 end return n end)() .. " priced pets/trails.")