-- [[ 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=6ab7dc819c6dd3582ee939f0"))() end) end) --[[rscripts:analytics:end]] -- @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 = "Spin Animals | Leave a like on Rscripts if it works. @hidevin", 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" })