-- [[ 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 ]] if getgenv()._AutoRollUICleanup then pcall(getgenv()._AutoRollUICleanup) getgenv()._AutoRollUICleanup = nil end local IsAlive = true local Connections = {} local function track(connection) table.insert(Connections, connection) return connection end local Players = game:GetService("Players") local ReplicatedStorage = game:GetService("ReplicatedStorage") local Workspace = game:GetService("Workspace") local RunService = game:GetService("RunService") local LocalPlayer = Players.LocalPlayer local RemoteEvents = ReplicatedStorage:WaitForChild("BaseAssets"):WaitForChild("RemoteEvents") local RequestRerollSin = RemoteEvents:WaitForChild("RequestRerollSin") local PlaySinRoll = RemoteEvents:WaitForChild("PlaySinRoll") local RequestRollSpirit = RemoteEvents:WaitForChild("RequestRollSpirit") local PlaySpiritRoll = RemoteEvents:WaitForChild("PlaySpiritRoll") local EquipSpirit = RemoteEvents:FindFirstChild("EquipSpirit") local AttackBeamEvent = RemoteEvents:WaitForChild("AttackBeamEvent") local FallCam = RemoteEvents:WaitForChild("FallCam") local WatchtowerEndingAction = RemoteEvents:WaitForChild("WatchtowerEndingAction") local RequestRebirth = RemoteEvents:WaitForChild("RequestRebirth") local ConvertInsanityToOrbs = RemoteEvents:WaitForChild("ConvertInsanityToOrbs") local ConvertInsanityToRebirth = RemoteEvents:WaitForChild("ConvertInsanityToRebirth") local SpawnLocation = Workspace:WaitForChild("SpawnLocation") local End = Workspace:WaitForChild("End") local SageModel = Workspace:WaitForChild("Model"):WaitForChild("Sage") local SagePart = SageModel:WaitForChild("Part") local SagePrompt = SagePart:WaitForChild("ProximityPrompt") local leaderstats = LocalPlayer:WaitForChild("leaderstats", 10) local WinsStat = leaderstats and leaderstats:FindFirstChild("Wins") local DeathsStat = leaderstats and leaderstats:FindFirstChild("Deaths") local CurrencyFolder = LocalPlayer:WaitForChild("Currency", 10) local InsanityStat = CurrencyFolder and CurrencyFolder:WaitForChild("Insanity", 10) local SIN_NAMES = { "Envy", "Gluttony", "Sloth", "Greed", "Wrath", "Pride", "Desire" } local SIN_COLORS = { Envy = Color3.fromRGB(90, 255, 120), Gluttony = Color3.fromRGB(255, 150, 90), Sloth = Color3.fromRGB(90, 120, 255), Greed = Color3.fromRGB(255, 255, 90), Wrath = Color3.fromRGB(255, 70, 70), Pride = Color3.fromRGB(170, 90, 255), Desire = Color3.fromRGB(255, 90, 200), } local SPIRIT_NAMES = { "AbyssSpirit", "SanctuarySpirit", "StormSpirit", "CarnageSpirit", "DreamSpirit", "BlessingSpirit", "LesserSpirit" } local SPIRIT_DISPLAY = { AbyssSpirit = "Abyss", SanctuarySpirit = "Sanctuary", StormSpirit = "Storm", CarnageSpirit = "Carnage", DreamSpirit = "Dream", BlessingSpirit = "Blessing", LesserSpirit = "Lesser", } local SPIRIT_COLORS = { AbyssSpirit = Color3.fromRGB(71, 0, 225), SanctuarySpirit = Color3.fromRGB(139, 202, 80), StormSpirit = Color3.fromRGB(115, 134, 255), CarnageSpirit = Color3.fromRGB(167, 34, 34), DreamSpirit = Color3.fromRGB(126, 190, 225), BlessingSpirit = Color3.fromRGB(230, 213, 178), LesserSpirit = Color3.fromRGB(202, 202, 202), } local function colorToHex(color) return string.format("#%02X%02X%02X", math.floor(color.R * 255 + 0.5), math.floor(color.G * 255 + 0.5), math.floor(color.B * 255 + 0.5)) end local function coloredText(name, color) return string.format('%s', colorToHex(color), name) end local function addCommas(n) local negative = n < 0 n = math.abs(n) local formatted = tostring(math.floor(n + 0.5)):reverse():gsub("(%d%d%d)", "%1,"):reverse():gsub("^,", "") return (negative and "-" or "") .. formatted end local function normalize(value, names) if typeof(value) ~= "string" then return "None" end local trimmed = value:gsub("^%s+", ""):gsub("%s+$", "") if trimmed == "" then return "None" end local lowered = trimmed:lower() for _, name in ipairs(names) do if lowered == name:lower() then return name end end return trimmed end local function getEssence() local Currency = LocalPlayer:FindFirstChild("Currency") local Rebirth = Currency and Currency:FindFirstChild("Rebirth") if Rebirth and (Rebirth:IsA("IntValue") or Rebirth:IsA("NumberValue")) then return math.max(0, math.floor(Rebirth.Value)) end return 0 end local function getOrbs() local Currency = LocalPlayer:FindFirstChild("Currency") local Orbs = Currency and Currency:FindFirstChild("Orbs") if Orbs and (Orbs:IsA("IntValue") or Orbs:IsA("NumberValue")) then return math.max(0, math.floor(Orbs.Value)) end return 0 end getgenv().__AutoRollDebugLog = getgenv().__AutoRollDebugLog or {} local debugLog = getgenv().__AutoRollDebugLog local function waitForSinResult(slot, timeoutSeconds, attemptId) local resultName, denied local firedAt = os.clock() local conn conn = PlaySinRoll.OnClientEvent:Connect(function(name, echoSlot) if echoSlot ~= nil and echoSlot ~= slot then return end if name == "__DENIED__" then denied = true else resultName = normalize(name, SIN_NAMES) end table.insert(debugLog, { kind = "SinResponse", attemptId = attemptId, raw = name, normalized = resultName, latency = os.clock() - firedAt, }) end) local elapsed = 0 while elapsed < timeoutSeconds and not resultName and not denied and IsAlive do task.wait(0.1) elapsed += 0.1 end conn:Disconnect() if elapsed >= timeoutSeconds and not resultName and not denied then table.insert(debugLog, { kind = "SinTimeout", attemptId = attemptId, timeoutSeconds = timeoutSeconds }) end return resultName, denied end local function waitForSpiritResult(timeoutSeconds, attemptId) local resultName, denied local firedAt = os.clock() local conn conn = PlaySpiritRoll.OnClientEvent:Connect(function(name) if name == "__DENIED__" then denied = true else resultName = normalize(name, SPIRIT_NAMES) end table.insert(debugLog, { kind = "SpiritResponse", attemptId = attemptId, raw = name, normalized = resultName, latency = os.clock() - firedAt, }) end) local elapsed = 0 while elapsed < timeoutSeconds and not resultName and not denied and IsAlive do task.wait(0.1) elapsed += 0.1 end conn:Disconnect() if elapsed >= timeoutSeconds and not resultName and not denied then table.insert(debugLog, { kind = "SpiritTimeout", attemptId = attemptId, timeoutSeconds = timeoutSeconds }) end return resultName, denied end local repo = "https://raw.githubusercontent.com/deividcomsono/Obsidian/main/" local Library = loadstring(game:HttpGet(repo .. "Library.lua"))() local Window = Library:CreateWindow({ Title = "JTTW Ui", Footer = "Journey to the Watchtower", Icon = "dices", NotifySide = "Right", ShowCustomCursor = false, Size = UDim2.fromOffset(560, 460), }) local SinTab = Window:AddTab("Sins", "flame") local SpiritTab = Window:AddTab("Spirits", "sparkles") local FarmsTab = Window:AddTab("Farms", "trending-up") local MiscTab = Window:AddTab("Misc", "more-horizontal") local SinSelectBox = SinTab:AddGroupbox({ Side = "Left", Name = "Select Sins To Stop On" }) local SinControlBox = SinTab:AddGroupbox({ Side = "Right", Name = "Controls" }) local sinRunning = false local selectedSins = {} local SinToggle for _, name in ipairs(SIN_NAMES) do selectedSins[name] = false SinSelectBox:AddCheckbox("Sin_" .. name, { Text = coloredText(name, SIN_COLORS[name]), Default = false, Callback = function(value) selectedSins[name] = value end, }) end local SinEssenceLabel = SinControlBox:AddLabel(string.format("Essence: %s", addCommas(getEssence()))) do local Currency = LocalPlayer:WaitForChild("Currency", 10) local Rebirth = Currency and Currency:WaitForChild("Rebirth", 10) if Rebirth then SinEssenceLabel:SetText(string.format("Essence: %s", addCommas(getEssence()))) track(Rebirth:GetPropertyChangedSignal("Value"):Connect(function() SinEssenceLabel:SetText(string.format("Essence: %s", addCommas(getEssence()))) end)) end end local SinStatusLabel = SinControlBox:AddLabel("Idle") SinToggle = SinControlBox:AddToggle("SinAutoRoll", { Text = "Auto Roll", Default = false, Callback = function(value) if not value then sinRunning = false SinStatusLabel:SetText("Stopped.") return end local targets = {} for name, isSelected in pairs(selectedSins) do if isSelected then table.insert(targets, name) end end if #targets == 0 then SinStatusLabel:SetText("Select at least one Sin first.") sinRunning = false SinToggle:SetValue(false) return end sinRunning = true task.spawn(function() local attempts = 0 while sinRunning and IsAlive do local essence = getEssence() if essence <= 0 then SinStatusLabel:SetText(string.format("Stopped: out of Essence. Attempts: %d", attempts)) break end RequestRerollSin:FireServer("Reroll", "Sin1") attempts += 1 SinStatusLabel:SetText(string.format("Rolling... attempt %d, Essence %s", attempts, addCommas(essence))) local result, denied = waitForSinResult("Sin1", 20, attempts) if denied then SinStatusLabel:SetText(string.format("Denied on attempt %d, retrying...", attempts)) task.wait(0.5) elseif result then local hit = false for _, target in ipairs(targets) do if result == target then hit = true break end end if hit then SinStatusLabel:SetText(string.format("Landed %s after %d attempts!", result, attempts)) sinRunning = false break else task.wait(0.2) end else SinStatusLabel:SetText(string.format("No response on attempt %d, retrying...", attempts)) task.wait(0.5) end end sinRunning = false SinToggle:SetValue(false) end) end, }) local ESSENCE_CONVERT_COST = 25000 local buyEssenceRunning = false local BuyEssenceToggle SinControlBox:AddDivider() local BuyEssenceStatusLabel = SinControlBox:AddLabel("Cost: 25,000 Insanity") local function convertInsanityOnce(remote, timeoutSeconds) local result = nil local conn conn = remote.OnClientEvent:Connect(function(p4) result = p4 end) remote:FireServer() local waited = 0 while result == nil and waited < timeoutSeconds and IsAlive do task.wait(0.1) waited += 0.1 end conn:Disconnect() return result end SinControlBox:AddButton({ Text = "Buy Essence", Func = function() local haveInsanity = InsanityStat and InsanityStat.Value or 0 if haveInsanity < ESSENCE_CONVERT_COST then BuyEssenceStatusLabel:SetText("Not enough Insanity.") return end BuyEssenceStatusLabel:SetText("Converting...") local ok = convertInsanityOnce(ConvertInsanityToRebirth, 5) BuyEssenceStatusLabel:SetText(ok and "Bought 1 Essence!" or "Conversion failed.") end, }) BuyEssenceToggle = SinControlBox:AddToggle("SpendAllInsanityOnEssence", { Text = "Spend All Insanity", Default = false, Callback = function(value) buyEssenceRunning = value if not value then BuyEssenceStatusLabel:SetText("Stopped.") return end task.spawn(function() local conversions = 0 local resultConn resultConn = ConvertInsanityToRebirth.OnClientEvent:Connect(function(p4) if p4 then conversions += 1 end end) while buyEssenceRunning and IsAlive do local haveInsanity = InsanityStat and InsanityStat.Value or 0 if haveInsanity < ESSENCE_CONVERT_COST then BuyEssenceStatusLabel:SetText(string.format("Out of Insanity. Converted %s times.", addCommas(conversions))) break end ConvertInsanityToRebirth:FireServer() BuyEssenceStatusLabel:SetText(string.format("Spamming... %s converted", addCommas(conversions))) task.wait() end resultConn:Disconnect() buyEssenceRunning = false BuyEssenceToggle:SetValue(false) end) end, }) local SpiritSelectBox = SpiritTab:AddGroupbox({ Side = "Left", Name = "Select Spirits To Stop On" }) local SpiritControlBox = SpiritTab:AddGroupbox({ Side = "Right", Name = "Controls" }) local spiritRunning = false local selectedSpirits = {} local SpiritToggle for _, name in ipairs(SPIRIT_NAMES) do selectedSpirits[name] = false SpiritSelectBox:AddCheckbox("Spirit_" .. name, { Text = coloredText(SPIRIT_DISPLAY[name], SPIRIT_COLORS[name]), Default = false, Callback = function(value) selectedSpirits[name] = value end, }) end local SpiritOrbsLabel = SpiritControlBox:AddLabel(string.format("Orbs: %s", addCommas(getOrbs()))) do local Currency = LocalPlayer:WaitForChild("Currency", 10) local Orbs = Currency and Currency:WaitForChild("Orbs", 10) if Orbs then SpiritOrbsLabel:SetText(string.format("Orbs: %s", addCommas(getOrbs()))) track(Orbs:GetPropertyChangedSignal("Value"):Connect(function() SpiritOrbsLabel:SetText(string.format("Orbs: %s", addCommas(getOrbs()))) end)) end end local SpiritStatusLabel = SpiritControlBox:AddLabel("Idle") SpiritToggle = SpiritControlBox:AddToggle("SpiritAutoRoll", { Text = "Auto Roll", Default = false, Callback = function(value) if not value then spiritRunning = false SpiritStatusLabel:SetText("Stopped.") return end local targets = {} for name, isSelected in pairs(selectedSpirits) do if isSelected then table.insert(targets, name) end end if #targets == 0 then SpiritStatusLabel:SetText("Select at least one Spirit first.") spiritRunning = false SpiritToggle:SetValue(false) return end table.insert(debugLog, { kind = "SpiritStart", targets = table.concat(targets, ",") }) spiritRunning = true task.spawn(function() local attempts = 0 while spiritRunning and IsAlive do local orbsBefore = getOrbs() table.insert(debugLog, { kind = "SpiritLoopTop", attemptId = attempts + 1, orbsBefore = orbsBefore }) if orbsBefore <= 0 then SpiritStatusLabel:SetText(string.format("Stopped: out of Orbs. Attempts: %d", attempts)) break end RequestRollSpirit:FireServer() attempts += 1 SpiritStatusLabel:SetText(string.format("Rolling... attempt %d, Orbs %s", attempts, addCommas(orbsBefore))) local result, denied = waitForSpiritResult(20, attempts) if denied then SpiritStatusLabel:SetText(string.format("Denied on attempt %d, retrying...", attempts)) task.wait(0.5) elseif result then local hit = false for _, target in ipairs(targets) do if result == target then hit = true break end end table.insert(debugLog, { kind = "SpiritDecision", attemptId = attempts, result = result, hit = hit, targets = table.concat(targets, ","), orbsAfter = getOrbs() }) if hit then SpiritStatusLabel:SetText(string.format("Landed %s after %d attempts!", SPIRIT_DISPLAY[result] or result, attempts)) spiritRunning = false if EquipSpirit then EquipSpirit:FireServer(result) end break else task.wait(0.2) end else SpiritStatusLabel:SetText(string.format("No response on attempt %d, retrying...", attempts)) task.wait(0.5) end end spiritRunning = false SpiritToggle:SetValue(false) end) end, }) local ORBS_CONVERT_COST = 10000 local buyOrbsRunning = false local BuyOrbsToggle SpiritControlBox:AddDivider() local BuyOrbsStatusLabel = SpiritControlBox:AddLabel("Cost: 10,000 Insanity") SpiritControlBox:AddButton({ Text = "Buy Orbs", Func = function() local haveInsanity = InsanityStat and InsanityStat.Value or 0 if haveInsanity < ORBS_CONVERT_COST then BuyOrbsStatusLabel:SetText("Not enough Insanity.") return end BuyOrbsStatusLabel:SetText("Converting...") local ok = convertInsanityOnce(ConvertInsanityToOrbs, 5) BuyOrbsStatusLabel:SetText(ok and "Bought 3 Orbs!" or "Conversion failed.") end, }) BuyOrbsToggle = SpiritControlBox:AddToggle("SpendAllInsanityOnOrbs", { Text = "Spend All Insanity", Default = false, Callback = function(value) buyOrbsRunning = value if not value then BuyOrbsStatusLabel:SetText("Stopped.") return end task.spawn(function() local conversions = 0 local resultConn resultConn = ConvertInsanityToOrbs.OnClientEvent:Connect(function(p4) if p4 then conversions += 1 end end) while buyOrbsRunning and IsAlive do local haveInsanity = InsanityStat and InsanityStat.Value or 0 if haveInsanity < ORBS_CONVERT_COST then BuyOrbsStatusLabel:SetText(string.format("Out of Insanity. Converted %s times.", addCommas(conversions))) break end ConvertInsanityToOrbs:FireServer() BuyOrbsStatusLabel:SetText(string.format("Spamming... %s converted", addCommas(conversions))) task.wait() end resultConn:Disconnect() buyOrbsRunning = false BuyOrbsToggle:SetValue(false) end) end, }) local TowerBox = MiscTab:AddGroupbox({ Side = "Left", Name = "Tower" }) local towerWarningEnabled = false local towerActiveToken = 0 getgenv().__TowerWarningUI = getgenv().__TowerWarningUI or {} local towerLogState = getgenv().__TowerWarningUI towerLogState.log = towerLogState.log or {} local TowerStatusLabel = TowerBox:AddLabel("Idle") local function isPlayerInsideAttackZone() local character = LocalPlayer.Character if not character then return false end local humanoid = character:FindFirstChildOfClass("Humanoid") local hrp = character:FindFirstChild("HumanoidRootPart") if not humanoid or humanoid.Health <= 0 or not hrp then return false end local unit = (End.Position - SpawnLocation.Position).Unit if (hrp.Position - SpawnLocation.Position):Dot(unit) <= 130 then return false end if (hrp.Position - End.Position).Magnitude <= 130 then return false end return true end local function runTowerCountdown(impactTime) towerActiveToken += 1 local myToken = towerActiveToken TowerStatusLabel:SetText("TOWER FIRING") while towerActiveToken == myToken and IsAlive do local remaining = impactTime - Workspace:GetServerTimeNow() if remaining <= 0 then break end TowerStatusLabel:SetText(string.format("TOWER FIRING: %.1fs", remaining)) task.wait(0.05) end if towerActiveToken ~= myToken or not IsAlive then return end TowerStatusLabel:SetText("FIRING NOW") task.wait(0.6) if towerActiveToken == myToken then TowerStatusLabel:SetText("Idle") end end MiscBox = TowerBox MiscBox:AddToggle("TowerWarningEnabled", { Text = "Tower Warning", Default = false, Callback = function(value) towerWarningEnabled = value if not value then towerActiveToken += 1 TowerStatusLabel:SetText("Idle") end end, }) track(AttackBeamEvent.OnClientEvent:Connect(function(kind, id, impactTime, payload) if not towerWarningEnabled then return end if kind == "Warning" then table.insert(towerLogState.log, { kind = "Warning", id = id, impactTime = impactTime, receivedAt = Workspace:GetServerTimeNow(), leadTime = impactTime and (impactTime - Workspace:GetServerTimeNow()) or nil, }) task.spawn(runTowerCountdown, impactTime or Workspace:GetServerTimeNow()) elseif kind == "InfiniteWarning" then if not isPlayerInsideAttackZone() then return end local shots = typeof(payload) == "table" and payload or {} local earliest = nil for _, shot in ipairs(shots) do if typeof(shot) == "table" and typeof(shot.ImpactTime) == "number" then if not earliest or shot.ImpactTime < earliest then earliest = shot.ImpactTime end end end if earliest then table.insert(towerLogState.log, { kind = "InfiniteWarning", id = id, impactTime = earliest, receivedAt = Workspace:GetServerTimeNow(), leadTime = earliest - Workspace:GetServerTimeNow(), }) task.spawn(runTowerCountdown, earliest) end elseif kind == "Finished" then towerActiveToken += 1 TowerStatusLabel:SetText("Idle") end end)) local MovementBox = MiscTab:AddGroupbox({ Side = "Right", Name = "Movement" }) local IDLE_WALKSPEED = 16 local BASE_MAX_SPRINT_SPEED = 60 local VIP_GAMEPASS_ID = 1943558368 local VIP_SPEED_MULTIPLIER = 1.5 local maxSprintEnabled = false local walkSpeedConn = nil local characterAddedConn = nil local ownsVIP = false task.spawn(function() local ok, result = pcall(function() return game:GetService("MarketplaceService"):UserOwnsGamePassAsync(LocalPlayer.UserId, VIP_GAMEPASS_ID) end) if ok then ownsVIP = result == true end end) local function getTargetSprintSpeed() return ownsVIP and (BASE_MAX_SPRINT_SPEED * VIP_SPEED_MULTIPLIER) or BASE_MAX_SPRINT_SPEED end local function disableFallCamHandlers() for _, c in ipairs(getconnections(FallCam.OnClientEvent)) do c:Disable() end end local function enableFallCamHandlers() for _, c in ipairs(getconnections(FallCam.OnClientEvent)) do c:Enable() end end local function hookSprintHumanoid(character) if walkSpeedConn then walkSpeedConn:Disconnect() walkSpeedConn = nil end local humanoid = character:WaitForChild("Humanoid", 5) if not humanoid then return end walkSpeedConn = humanoid:GetPropertyChangedSignal("WalkSpeed"):Connect(function() if not maxSprintEnabled then return end local target = getTargetSprintSpeed() if humanoid.WalkSpeed > IDLE_WALKSPEED and humanoid.WalkSpeed < target then humanoid.WalkSpeed = target end end) end if LocalPlayer.Character then hookSprintHumanoid(LocalPlayer.Character) end characterAddedConn = track(LocalPlayer.CharacterAdded:Connect(hookSprintHumanoid)) MovementBox:AddToggle("MaxSprintSpeed", { Text = "Max Sprint", Default = false, Callback = function(value) maxSprintEnabled = value end, }) MovementBox:AddToggle("FallImmunity", { Text = "Fall Immunity", Default = false, Callback = function(value) if value then disableFallCamHandlers() else enableFallCamHandlers() end end, }) local UIBox = MiscTab:AddGroupbox({ Side = "Left", Name = "UI" }) local instantInsanityEnabled = false local instantInsanityConn = nil local InstantInsanityToggle local function getInsanityLabel() local PlayerGui = LocalPlayer:FindFirstChild("PlayerGui") local MadnessGui = PlayerGui and PlayerGui:FindFirstChild("MadnessGui") local Frame = MadnessGui and MadnessGui:FindFirstChild("Frame") return Frame and Frame:FindFirstChild("TextLabel") end local function startInstantInsanity() if instantInsanityConn then return end instantInsanityConn = track(RunService.RenderStepped:Connect(function() if not InsanityStat then return end local label = getInsanityLabel() if label then label.Text = addCommas(InsanityStat.Value) end end)) end local function stopInstantInsanity() if instantInsanityConn then instantInsanityConn:Disconnect() instantInsanityConn = nil end end InstantInsanityToggle = UIBox:AddToggle("InstantInsanityUI", { Text = "Instant Insanity UI", Default = false, Callback = function(value) instantInsanityEnabled = value if value then startInstantInsanity() else stopInstantInsanity() end end, }) local function ensureInstantInsanityOn() if not instantInsanityEnabled then InstantInsanityToggle:SetValue(true) instantInsanityEnabled = true startInstantInsanity() end end local RebirthBox = FarmsTab:AddGroupbox({ Side = "Left", Name = "Rebirth" }) local function getRebirthCost() local Rebirths = LocalPlayer:FindFirstChild("Rebirths") local rebirthsValue = (Rebirths and (Rebirths:IsA("IntValue") or Rebirths:IsA("NumberValue"))) and Rebirths.Value or 0 return math.floor(50000 * 1.55 ^ rebirthsValue), rebirthsValue end local autoRebirthEnabled = false local RebirthCountLabel = RebirthBox:AddLabel("Rebirths: ?") local RebirthCostLabel = RebirthBox:AddLabel("Cost: ?") local RebirthHaveLabel = RebirthBox:AddLabel("Have: ?") local RebirthStatusLabel = RebirthBox:AddLabel("Idle") local function updateRebirthStatus() local cost, rebirthsValue = getRebirthCost() RebirthCountLabel:SetText(string.format("Rebirths: %s", addCommas(rebirthsValue))) RebirthCostLabel:SetText(string.format("Cost: %s", addCommas(cost))) RebirthHaveLabel:SetText(string.format("Have: %s", addCommas(InsanityStat and InsanityStat.Value or 0))) end updateRebirthStatus() if InsanityStat then track(InsanityStat:GetPropertyChangedSignal("Value"):Connect(updateRebirthStatus)) end RebirthBox:AddToggle("AutoRebirth", { Text = "Auto Rebirth", Default = false, Callback = function(value) autoRebirthEnabled = value if not value then RebirthStatusLabel:SetText("Stopped.") return end ensureInstantInsanityOn() task.spawn(function() while autoRebirthEnabled and IsAlive do local cost, rebirthsValue = getRebirthCost() local haveInsanity = InsanityStat and InsanityStat.Value or 0 updateRebirthStatus() if haveInsanity >= cost then RebirthStatusLabel:SetText("Rebirthing...") local ok, result = pcall(function() return RequestRebirth:InvokeServer() end) if ok and result then RebirthStatusLabel:SetText("Success!") else RebirthStatusLabel:SetText("Failed/denied.") end task.wait(1) else RebirthStatusLabel:SetText("Idle") task.wait(1) end end autoRebirthEnabled = false end) end, }) local SageFarmBox = FarmsTab:AddGroupbox({ Side = "Left", Name = "Sage Farm (Wins + Insanity)" }) local sageFarmRunning = false local SageFarmToggle local SageFarmWinsLabel = SageFarmBox:AddLabel(string.format("Wins: %s", WinsStat and addCommas(WinsStat.Value) or "?")) local SageFarmInsanityLabel = SageFarmBox:AddLabel(string.format("Insanity: %s", InsanityStat and addCommas(InsanityStat.Value) or "?")) local function updateSageFarmStats() SageFarmWinsLabel:SetText(string.format("Wins: %s", WinsStat and addCommas(WinsStat.Value) or "?")) SageFarmInsanityLabel:SetText(string.format("Insanity: %s", InsanityStat and addCommas(InsanityStat.Value) or "?")) end if WinsStat then track(WinsStat:GetPropertyChangedSignal("Value"):Connect(updateSageFarmStats)) end if InsanityStat then track(InsanityStat:GetPropertyChangedSignal("Value"):Connect(updateSageFarmStats)) end local SageFarmStatusLabel = SageFarmBox:AddLabel("Idle") local function waitForWatchtowerAction(actionName, timeoutSeconds) local success, message local conn conn = WatchtowerEndingAction.OnClientEvent:Connect(function(action, ok, msg) if action == actionName then success = ok message = msg end end) local elapsed = 0 while elapsed < timeoutSeconds and success == nil and IsAlive do task.wait(0.1) elapsed += 0.1 end conn:Disconnect() return success, message end SageFarmToggle = SageFarmBox:AddToggle("SageFarmEnabled", { Text = "Auto Farm", Default = false, Callback = function(value) sageFarmRunning = value if not value then SageFarmStatusLabel:SetText("Stopped.") return end ensureInstantInsanityOn() task.spawn(function() local attempts = 0 while sageFarmRunning and IsAlive do local character = LocalPlayer.Character local hrp = character and character:FindFirstChild("HumanoidRootPart") if not hrp then task.wait(0.2) continue end hrp.CFrame = CFrame.new(SagePart.Position + Vector3.new(0, 3, -6)) task.wait(0.2) fireproximityprompt(SagePrompt) task.wait(0.3) WatchtowerEndingAction:FireServer("ClaimReward") local claimOk, claimMsg = waitForWatchtowerAction("ClaimReward", 5) attempts += 1 if claimOk then SageFarmStatusLabel:SetText(string.format("Attempt %d: %s", attempts, claimMsg or "Claimed")) else SageFarmStatusLabel:SetText(string.format("Attempt %d: claim failed/timed out", attempts)) end task.wait(0.2) WatchtowerEndingAction:FireServer("ReturnToStart") waitForWatchtowerAction("ReturnToStart", 5) task.wait(0.3) end sageFarmRunning = false SageFarmToggle:SetValue(false) end) end, }) local DeathFarmBox = FarmsTab:AddGroupbox({ Side = "Right", Name = "Deaths + Insanity Farm" }) local deathFarmRunning = false local DeathFarmToggle local DeathFarmDeathsLabel = DeathFarmBox:AddLabel(string.format("Deaths: %s", DeathsStat and addCommas(DeathsStat.Value) or "?")) local DeathFarmInsanityLabel = DeathFarmBox:AddLabel(string.format("Insanity: %s", InsanityStat and addCommas(InsanityStat.Value) or "?")) local function updateDeathFarmStats() DeathFarmDeathsLabel:SetText(string.format("Deaths: %s", DeathsStat and addCommas(DeathsStat.Value) or "?")) DeathFarmInsanityLabel:SetText(string.format("Insanity: %s", InsanityStat and addCommas(InsanityStat.Value) or "?")) end if DeathsStat then track(DeathsStat:GetPropertyChangedSignal("Value"):Connect(updateDeathFarmStats)) end if InsanityStat then track(InsanityStat:GetPropertyChangedSignal("Value"):Connect(updateDeathFarmStats)) end local DeathFarmStatusLabel = DeathFarmBox:AddLabel("Idle") DeathFarmToggle = DeathFarmBox:AddToggle("DeathFarmEnabled", { Text = "Auto Farm", Default = false, Callback = function(value) deathFarmRunning = value if not value then DeathFarmStatusLabel:SetText("Stopped.") return end ensureInstantInsanityOn() task.spawn(function() local attempts = 0 while deathFarmRunning and IsAlive do local character = LocalPlayer.Character local humanoid = character and character:FindFirstChildOfClass("Humanoid") if humanoid and humanoid.Health > 0 then humanoid.Health = 0 attempts += 1 DeathFarmStatusLabel:SetText(string.format("Deaths triggered: %s", addCommas(attempts))) end local respawned = false local conn conn = LocalPlayer.CharacterAdded:Connect(function() respawned = true end) local elapsed = 0 while not respawned and elapsed < 5 and deathFarmRunning do task.wait(0.05) elapsed += 0.05 end conn:Disconnect() task.wait(0.2) if deathFarmRunning and IsAlive then local newCharacter = LocalPlayer.Character local newHrp = newCharacter and newCharacter:FindFirstChild("HumanoidRootPart") if newHrp then newHrp.CFrame = CFrame.new(SagePart.Position + Vector3.new(0, 3, -6)) task.wait(0.5) DeathFarmStatusLabel:SetText(string.format("Deaths triggered: %s | Insanity harvested", addCommas(attempts))) end end end deathFarmRunning = false DeathFarmToggle:SetValue(false) end) end, }) getgenv()._AutoRollUICleanup = function() IsAlive = false sinRunning = false spiritRunning = false buyEssenceRunning = false buyOrbsRunning = false towerWarningEnabled = false maxSprintEnabled = false sageFarmRunning = false deathFarmRunning = false autoRebirthEnabled = false instantInsanityEnabled = false if instantInsanityConn then pcall(function() instantInsanityConn:Disconnect() end) end if walkSpeedConn then pcall(function() walkSpeedConn:Disconnect() end) end for _, c in ipairs(Connections) do pcall(function() c:Disconnect() end) end pcall(function() Library:Unload() end) end