Spin Animals is a roll-and-collect game: spin for an animal, keep the good ones, equip the best lineup and let the pedestals earn income. The loop is short but constant, and this script runs it end to end without a key. What runs automatically Auto roll keeps spinning, with auto buy eggs so you never run out of things to roll. Auto equip best re-checks the lineup on a 30-second cycle and swaps in anything stronger you picked up. The upgrade side covers the four stats that matter — luck, cash multiplier, roll speed and walk speed — and spends as soon as an upgrade is affordable. Auto rebirth resets the run when the requirement is met, so the multiplier keeps climbing. Income Auto level pedestal handles the pedestal upgrades, and auto collect income picks up what your animals earn instead of leaving it on the map. How to use it Load the script in Spin Animals, open the menu and enable auto roll first. Watch a batch and confirm the eggs are actually being bought and rolled, then add the upgrade and rebirth parts. Auto equip is the one option worth leaving on permanently, since it only ever improves your lineup. No key is required. The source is open, so the logic can be read and adjusted instead of taken on trust. Mobile has not been tested, so use a desktop executor. The build suits idle sessions: rolls continue, income is collected, and the pedestal keeps levelling while you are elsewhere.
331 lines · 12.8 KB
-- @hidevin | Spin Animals | place 101259833410724 -- Game lock: never execute outside Spin Animals. if game.PlaceId ~= 101259833410724 then warn("[@hidevin] Wrong game. Locked to Spin Animals (101259833410724).") return end -- Design tokens (UI_STYLE.json): bg #0d0d0d, card #282828, border #3a3a3a, -- radius 10, font Inter/Segoe UI, heading #ffffff bold, label #a0a0a0, -- toggle pill green/blue, slider track #444444 fill #5865F2 white handle. -- GAME_FEATURES.md tab rules applied below. ObsidianUltra API per llms.txt + Example.lua. local repo = "https://raw.githubusercontent.com/joustingmatch/ObsidianUltra/main/" local Library = loadstring(game:HttpGet(repo .. "Library.lua"))() local ThemeManager = loadstring(game:HttpGet(repo .. "addons/ThemeManager.lua"))() local SaveManager = loadstring(game:HttpGet(repo .. "addons/SaveManager.lua"))() local Options = Library.Options local Toggles = Library.Toggles local Players = game:GetService("Players") local ReplicatedStorage = game:GetService("ReplicatedStorage") local VirtualUser = game:GetService("VirtualUser") local LocalPlayer = Players.LocalPlayer local Remotes = ReplicatedStorage:WaitForChild("Remotes", 20) local GetSnapshot = Remotes and Remotes:WaitForChild("GetSnapshot", 10) local RequestRoll = Remotes and Remotes:WaitForChild("RequestRoll", 10) local RequestBuyEgg = Remotes and Remotes:WaitForChild("RequestBuyEgg", 10) local RequestBuyUpgrade = Remotes and Remotes:WaitForChild("RequestBuyUpgrade", 10) local RequestRebirth = Remotes and Remotes:WaitForChild("RequestRebirth", 10) local RequestEquipBest = Remotes and Remotes:WaitForChild("RequestEquipBest", 10) local EGG_NAMES = { "Wooden", "Stone", "Copper", "Silver", "Gold", "Amber", "Emerald", "Amethyst", "Sapphire", "Ruby", "Obsidian", "Frost", "Rainbow", "Toxic", "Celestial", "Dragon", } local EGG_INDEX = {} for i, n in ipairs(EGG_NAMES) do EGG_INDEX[n] = i end local UPGRADE_IDS = { "luck", "cash", "rollSpeed", "walkSpeed" } local UPGRADE_LABEL = { luck = "Luck", cash = "Cash Multiplier", rollSpeed = "Roll Speed", walkSpeed = "Walk Speed" } local function snapshot() if not GetSnapshot then return nil end local ok, res = pcall(GetSnapshot.InvokeServer, GetSnapshot) if ok and type(res) == "table" then return res end return nil end local function ownPlot() local plots = workspace:FindFirstChild("Map") if plots then plots = plots:FindFirstChild("Plots") end if not plots then return nil end for _, p in ipairs(plots:GetChildren()) do if p:GetAttribute("Owner") == LocalPlayer.UserId then return p end end return nil end local Window = Library:CreateWindow({ Title = "@hidevin", Footer = "", NotifySide = "Right", ShowCustomCursor = true, DisableSearch = true, Minimizable = true, EnableSidebarResize = true, }) Window:SetCornerRadius(10) pcall(function() Library.Scheme.AccentColor = Color3.fromRGB(88, 101, 242) if Library.Scheme.BlueColor then Library.Scheme.BlueColor = Color3.fromRGB(80, 155, 255) end end) local Tabs = { Main = Window:AddTab("Main", "user"), Farming = Window:AddTab("Farming", "sprout"), Inventory = Window:AddTab("Inventory", "backpack"), Rebirth = Window:AddTab("Rebirth", "refresh-ccw"), ["UI Settings"] = Window:AddTab("UI Settings", "settings"), } -- Main: dashboard only, no mechanics. local MainBox = Tabs.Main:AddLeftGroupbox("Status") MainBox:AddLabel("Spin Animals", true, "GameName") MainBox:AddLabel("Session info below.", true, "SessionInfo") MainBox:AddStatGrid("MainStats", { Columns = 3, Items = { { Value = "0", Text = "Money" }, { Value = "0/s", Text = "Income" }, { Value = "0", Text = "Rolls" }, }, }) task.spawn(function() local t0 = os.clock() while not Library.Unloaded do task.wait(1) local s = snapshot() if s and Library.Labels and Library.Labels.MainStats then pcall(function() Library.Labels.MainStats:SetValue("Money", tostring(math.floor(tonumber(s.money) or 0))) Library.Labels.MainStats:SetValue("Income", string.format("%d/s", math.floor(tonumber(s.incomePerSecond) or 0))) Library.Labels.MainStats:SetValue("Rolls", tostring(s.rolls or 0)) end) end if Options.SessionInfo then local el = math.floor(os.clock() - t0) pcall(function() Options.SessionInfo:SetText(string.format("Session: %02d:%02d:%02d", el / 3600, (el % 3600) / 60, el % 60)) end) end end end) -- Farming: Collect + Pedestal sub-tabs (2+ types => sub-tabs required). local FarmCollect = Tabs.Farming:AddSubTab("Collect", "coins") local FarmPedestal = Tabs.Farming:AddSubTab("Pedestal", "arrow-up") FarmCollect:AddLeftGroupbox("Resource Collecting"):AddToggle("AutoCollectIncome", { Text = "Auto-Collect Income", Default = false, Tooltip = "Teleports onto your plot CollectMoney pads (touch collect).", }) FarmPedestal:AddLeftGroupbox("Stand Leveling"):AddToggle("AutoLevelPedestal", { Text = "Auto Level Pedestal", Default = false, Tooltip = "Fires your plot pedestal prompts every 1s.", }) Toggles.AutoCollectIncome:OnChanged(function() task.spawn(function() while Toggles.AutoCollectIncome.Value and not Library.Unloaded do pcall(function() local plot = ownPlot() local char = LocalPlayer.Character local hrp = char and char:FindFirstChild("HumanoidRootPart") if plot and hrp then -- Distant firetouchinterest is rejected by the server -- (verified: no money change). Physical step-on works -- (verified 26 -> 1.13M). Walk pads, then restore pos. local orig = hrp.CFrame for _, d in ipairs(plot:GetDescendants()) do if not Toggles.AutoCollectIncome.Value then break end if d.Name == "CollectMoney" and d:IsA("BasePart") then pcall(function() hrp.CFrame = d.CFrame + Vector3.new(0, 3, 0) end) task.wait(0.35) end end pcall(function() hrp.CFrame = orig end) end end) task.wait(1) end end) end) Toggles.AutoLevelPedestal:OnChanged(function() task.spawn(function() while Toggles.AutoLevelPedestal.Value and not Library.Unloaded do pcall(function() local plot = ownPlot() if plot then for _, d in ipairs(plot:GetDescendants()) do if d:IsA("ProximityPrompt") and d.Name == "_PedPrompt" and d.Enabled then pcall(fireproximityprompt, d) end end if fireclickdetector then for _, d in ipairs(plot:GetDescendants()) do if d:IsA("ClickDetector") and d.Name == "_PedClick" then pcall(fireclickdetector, d) end end end end end) task.wait(1) end end) end) -- Inventory: Purchasing/Collecting vs Upgrading/Enhancing split. local InvBuy = Tabs.Inventory:AddSubTab("Eggs & Rolls", "egg") local InvUp = Tabs.Inventory:AddSubTab("Upgrades & Pets", "arrow-up") local BuyBox = InvBuy:AddLeftGroupbox("Purchasing") BuyBox:AddDropdown("EggSelect", { Values = EGG_NAMES, Default = {}, Multi = true, Text = "Buy Shop Items (Eggs)", Tooltip = "Which eggs Auto Buy Eggs targets.", Searchable = true, SelectAllButtons = true, }) BuyBox:AddToggle("AutoBuyEggs", { Text = "Auto Buy Eggs", Default = false }) BuyBox:AddToggle("AutoRoll", { Text = "Auto Roll", Default = false, Tooltip = "Invokes RequestRoll every 1s." }) local UpBox = InvUp:AddLeftGroupbox("Stat Upgrades") UpBox:AddToggle("AutoUpLuck", { Text = "Auto-Upgrade Luck", Default = false }) UpBox:AddToggle("AutoUpCash", { Text = "Auto-Upgrade Cash Multiplier", Default = false }) UpBox:AddToggle("AutoUpRollSpeed", { Text = "Auto-Upgrade Roll Speed", Default = false }) UpBox:AddToggle("AutoUpWalkSpeed", { Text = "Auto-Upgrade Walk Speed", Default = false }) local PetBox = InvUp:AddRightGroupbox("Pet Management") PetBox:AddToggle("AutoEquipBest", { Text = "Auto Equip Best (30s)", Default = false }) Toggles.AutoBuyEggs:OnChanged(function() task.spawn(function() while Toggles.AutoBuyEggs.Value and not Library.Unloaded do pcall(function() local sel = Options.EggSelect.Value local list = {} if type(sel) == "table" then for name, on in pairs(sel) do if on and EGG_INDEX[name] then table.insert(list, EGG_INDEX[name]) end end end if #list == 0 then local s = snapshot() local nextEgg = math.min((tonumber(s and s.eggsOwned) or 0) + 1, #EGG_NAMES) list = { nextEgg } end table.sort(list) for _, idx in ipairs(list) do if not Toggles.AutoBuyEggs.Value then break end if RequestBuyEgg then RequestBuyEgg:FireServer(idx) end task.wait(0.25) end end) task.wait(1) end end) end) Toggles.AutoRoll:OnChanged(function() task.spawn(function() while Toggles.AutoRoll.Value and not Library.Unloaded do pcall(function() if RequestRoll then RequestRoll:InvokeServer() end end) task.wait(1) end end) end) local function autoUpgradeLoop(toggleName, id) Toggles[toggleName]:OnChanged(function() task.spawn(function() while Toggles[toggleName].Value and not Library.Unloaded do pcall(function() if RequestBuyUpgrade then RequestBuyUpgrade:FireServer(id) end end) task.wait(1) end end) end) end autoUpgradeLoop("AutoUpLuck", "luck") autoUpgradeLoop("AutoUpCash", "cash") autoUpgradeLoop("AutoUpRollSpeed", "rollSpeed") autoUpgradeLoop("AutoUpWalkSpeed", "walkSpeed") Toggles.AutoEquipBest:OnChanged(function() task.spawn(function() while Toggles.AutoEquipBest.Value and not Library.Unloaded do pcall(function() if RequestEquipBest then RequestEquipBest:FireServer() end end) task.wait(30) end end) end) -- Rebirth: only because mechanic exists. local RebirthBox = Tabs.Rebirth:AddLeftGroupbox("Rebirth") RebirthBox:AddToggle("AutoRebirth", { Text = "Auto-Rebirth", Default = false }) Toggles.AutoRebirth:OnChanged(function() task.spawn(function() while Toggles.AutoRebirth.Value and not Library.Unloaded do pcall(function() if RequestRebirth then RequestRebirth:FireServer() end end) task.wait(1) end end) end) -- UI Settings: config + anti-afk on by default. local MenuGroup = Tabs["UI Settings"]:AddLeftGroupbox("Menu") MenuGroup:AddLabel("Menu bind"):AddKeyPicker("MenuKeybind", { Default = "RightShift", NoUI = true, Text = "Menu keybind" }) MenuGroup:AddToggle("AntiAFK", { Text = "Anti-AFK", Default = true }) MenuGroup:AddSlider("UICornerSlider", { Text = "Corner Radius", Default = 10, Min = 0, Max = 20, Rounding = 0, Callback = function(v) Window:SetCornerRadius(v) end, }) MenuGroup:AddButton("Unload", function() Library:Unload() end) Library.ToggleKeybind = Options.MenuKeybind local afkConn = nil local function setAntiAfk(on) if afkConn then pcall(function() afkConn:Disconnect() end) afkConn = nil end if on then afkConn = LocalPlayer.Idled:Connect(function() pcall(function() VirtualUser:Button2Down(Vector2.new(0, 0), workspace.CurrentCamera.CFrame) end) task.wait(1) pcall(function() VirtualUser:Button2Up(Vector2.new(0, 0), workspace.CurrentCamera.CFrame) end) end) end end setAntiAfk(true) Toggles.AntiAFK:OnChanged(function() setAntiAfk(Toggles.AntiAFK.Value) end) Library:OnUnload(function() if afkConn then pcall(function() afkConn:Disconnect() end) end end) ThemeManager:SetLibrary(Library) SaveManager:SetLibrary(Library) SaveManager:IgnoreThemeSettings() SaveManager:SetIgnoreIndexes({ "MenuKeybind" }) ThemeManager:SetFolder("hidevin") SaveManager:SetFolder("hidevin/SpinAnimals") SaveManager:BuildConfigSection(Tabs["UI Settings"]) ThemeManager:ApplyToTab(Tabs["UI Settings"]) SaveManager:LoadAutoloadConfig() Library:Notify({ Title = "@hidevin", Description = "Spin Animals loaded.", Time = 4, Type = "Success" })
Share what works, ask a question, or report an issue.
No comments yet