🔓 Keyless
Prepare to dominate the RNG defense arena in Roll to Defend with this ultimate, game-changing automation script. Designed to eliminate the endless manual tapping, this powerful tool automates your rolling, upgrading, and rebirth cycles so you can build the ultimate defense unit effortlessly. Best of all, this script is completely keyless, giving you instant access to top-tier performance without annoying linkvertise bypasses.
-- Load Rayfield
local Rayfield = loadstring(game:HttpGet('https://sirius.menu/rayfield'))()
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- ========== REMOTES ==========
local RollRequest = ReplicatedStorage:WaitForChild("RollEvents"):WaitForChild("RollRequest")
local PurchaseUpgrade = ReplicatedStorage:WaitForChild("UpgradeRemotes"):WaitForChild("PurchaseUpgrade")
local RequestRebirth = ReplicatedStorage:WaitForChild("RebirthRemotes"):WaitForChild("RequestRebirth")
-- ========== DATA CONTROLLER ==========
local DataController = nil
local function GetDataController()
if DataController then return DataController end
local success, module = pcall(function()
return require(ReplicatedStorage:WaitForChild("Game"):WaitForChild("Controllers"):WaitForChild("DataController"))
end)
if success then DataController = module end
return DataController
end
-- ========== UTILITY HELPERS ==========
-- Universal helper to parse numbers with support for K and M suffixes
local function parseNumber(txt)
if not txt then return nil end
local clean = txt:gsub("[^%dKMkm.]", "")
local num = tonumber(clean:match("[%d.]+"))
if num then
if clean:upper():match("K") then num = num * 1000 end
if clean:upper():match("M") then num = num * 1000000 end
return num
end
return nil
end
-- ========== COIN DETECTION ==========
local cachedCoinUI = nil
local function GetCoins()
local dc = GetDataController()
if dc then
local cash = dc:Get("Cash")
if cash then return cash end
end
local function extractNumber(txt)
if not txt then return nil end
local clean = txt:gsub("[^%d]", "")
local num = tonumber(clean)
if num and num > 1000 then return num end
return nil
end
if cachedCoinUI and cachedCoinUI.Parent then
local val = extractNumber(cachedCoinUI.Text)
if val then return val end
end
for _, child in ipairs(LocalPlayer.PlayerGui:GetDescendants()) do
if child:IsA("TextLabel") or child:IsA("TextButton") then
local val = extractNumber(child.Text)
if val then
cachedCoinUI = child
return val
end
end
end
return nil
end
-- ========== BRAINS DETECTION ==========
local cachedBrainsUI = nil
local function GetBrains()
local dc = GetDataController()
if dc then
local brains = dc:Get("Brains") or dc:Get("Stats.Brains")
if brains then return brains end
end
if cachedBrainsUI and cachedBrainsUI.Parent then
local num = parseNumber(cachedBrainsUI.Text)
if num then return num end
end
for _, child in ipairs(LocalPlayer.PlayerGui:GetDescendants()) do
if (child:IsA("TextLabel") or child:IsA("TextButton")) and child.Text then
local txt = child.Text:lower()
if txt:match("brain") then
local num = parseNumber(child.Text)
if num then
cachedBrainsUI = child
return num
end
end
end
end
return nil
end
-- ========== REQUIRED BRAINS (PRIORITY: DataController → UI Scan) ==========
local cachedRequiredBrainsUI = nil
local function GetRequiredBrains()
-- 1. Try DataController first (most reliable)
local dc = GetDataController()
if dc then
local req = dc:Get("RebirthCost") or dc:Get("BrainsRequired") or dc:Get("RequiredBrains")
if req then return req end
end
-- 2. Check cache
if cachedRequiredBrainsUI and cachedRequiredBrainsUI.Parent then
local num = parseNumber(cachedRequiredBrainsUI.Text)
if num then return num end
end
-- 3. Scan UI for "Brains Needed" or similar
for _, child in ipairs(LocalPlayer.PlayerGui:GetDescendants()) do
if (child:IsA("TextLabel") or child:IsA("TextButton")) and child.Text then
local txt = child.Text:lower()
-- Look for "brains" + "need"/"required"/"cost" or just "brains needed"
if txt:match("brain") and (txt:match("need") or txt:match("required") or txt:match("cost") or txt:match("needed")) then
local num = parseNumber(child.Text)
if num then
cachedRequiredBrainsUI = child
return num
end
-- Check siblings
local parent = child.Parent
if parent then
for _, sibling in ipairs(parent:GetChildren()) do
if sibling ~= child and (sibling:IsA("TextLabel") or sibling:IsA("TextButton")) then
local num2 = parseNumber(sibling.Text)
if num2 then
cachedRequiredBrainsUI = sibling
return num2
end
end
end
end
end
end
end
-- 4. Last resort: scan for any number with K/M near a "Brains" label
local brainsLabel = nil
for _, child in ipairs(LocalPlayer.PlayerGui:GetDescendants()) do
if (child:IsA("TextLabel") or child:IsA("TextButton")) and child.Text and child.Text:lower():match("brain") then
brainsLabel = child
break
end
end
if brainsLabel then
local parent = brainsLabel.Parent
if parent then
for _, sibling in ipairs(parent:GetChildren()) do
if sibling ~= brainsLabel and (sibling:IsA("TextLabel") or sibling:IsA("TextButton")) then
local num = parseNumber(sibling.Text)
if num then
cachedRequiredBrainsUI = sibling
return num
end
end
end
end
end
return nil
end
-- ========== SCAN SKILLS ==========
local function GetAvailableSkills()
local tree = LocalPlayer.PlayerGui:FindFirstChild("Main")
and LocalPlayer.PlayerGui.Main:FindFirstChild("Frames")
and LocalPlayer.PlayerGui.Main:FindFirstChild("SkillTree")
and LocalPlayer.PlayerGui.Main.Frames.SkillTree:FindFirstChild("NodeLayer")
and LocalPlayer.PlayerGui.Main.Frames.SkillTree.NodeLayer:FindFirstChild("TreeCanvas")
if not tree then return {} end
local skills = {}
for _, container in ipairs(tree:GetChildren()) do
if container:IsA("GuiObject") then
local skillId = container.Name
if skillId and skillId ~= "TreeScale" and skillId ~= "UIScale" and not skillId:match("_") then
local priceStuff = container:FindFirstChild("PriceStuff")
if not priceStuff then
local btn = container:FindFirstChild("Button")
if btn then priceStuff = btn:FindFirstChild("PriceStuff") end
end
if priceStuff then
local priceLabel = priceStuff:FindFirstChild("Price")
if priceLabel and (priceLabel:IsA("TextLabel") or priceLabel:IsA("TextButton")) then
local cost = parseNumber(priceLabel.Text or "")
if cost and cost > 0 then
table.insert(skills, {id = skillId, cost = cost})
end
end
end
end
end
end
return skills
end
-- ========== BLACKLIST ==========
local blacklist = {}
local blacklistTimeout = 60
-- ========== RAYFIELD GUI ==========
local Window = Rayfield:CreateWindow({
Name = "Auto Bot",
Icon = 0,
ConfigurationSaving = {Enabled = true, FolderName = "AutoBot", FileName = "Settings"}
})
local MainTab = Window:CreateTab("Main", 4483362458)
-- ===== AUTO ROLL =====
local rollDelay = 0.15
local autoRoll = false
MainTab:CreateToggle({
Name = "Auto Roll",
Default = false,
Callback = function(state)
autoRoll = state
if autoRoll then
task.spawn(function()
while autoRoll do
pcall(RollRequest.FireServer, RollRequest)
task.wait(rollDelay)
end
end)
end
end
})
MainTab:CreateSlider({
Name = "Roll Delay (s)",
Range = {0.05, 0.5},
Increment = 0.01,
Suffix = "s",
CurrentValue = 0.15,
Callback = function(v) rollDelay = v end
})
-- ===== AUTO UPGRADE =====
local upgradeMode = "Most Expensive"
local autoUpgrade = false
MainTab:CreateToggle({
Name = "Auto Upgrade (Smart Skip)",
Default = false,
Callback = function(state)
autoUpgrade = state
if autoUpgrade then
task.spawn(function()
while autoUpgrade do
local coins = GetCoins()
if not coins then
task.wait(2)
continue
end
local skills = GetAvailableSkills()
if #skills == 0 then
task.wait(2)
continue
end
local affordable = {}
for _, s in ipairs(skills) do
if s.cost <= coins then
local blacklisted = false
for _, entry in ipairs(blacklist) do
if entry.id == s.id and tick() - entry.time < blacklistTimeout then
blacklisted = true
break
end
end
if not blacklisted then
table.insert(affordable, s)
end
end
end
if #affordable == 0 then
if #blacklist > 0 and tick() - blacklist[1].time > blacklistTimeout then
blacklist = {}
print("🔄 Cleared blacklist (timeout)")
end
task.wait(1)
continue
end
table.sort(affordable, function(a, b) return a.cost < b.cost end)
local target = (upgradeMode == "Most Expensive") and affordable[#affordable] or affordable[1]
if target then
print("🔼 Trying " .. target.id .. " (cost: " .. target.cost .. ", coins: " .. coins .. ")")
local success, result = pcall(function()
return PurchaseUpgrade:InvokeServer(target.id)
end)
if success and type(result) == "table" and result.success == true then
print("✅ Purchase successful!")
else
local msg = success and result.message or "unknown error"
print("❌ Failed: " .. msg)
table.insert(blacklist, {id = target.id, time = tick()})
print("⏭️ Skipping " .. target.id .. " for " .. blacklistTimeout .. " seconds")
end
end
task.wait(0.5)
end
end)
end
end
})
MainTab:CreateDropdown({
Name = "Priority",
Options = {"Most Expensive", "Cheapest"},
CurrentOption = "Most Expensive",
Callback = function(opt) upgradeMode = opt end
})
-- ===== AUTO REBIRTH =====
local autoRebirth = false
MainTab:CreateToggle({
Name = "Auto Rebirth",
Default = false,
Callback = function(state)
autoRebirth = state
if autoRebirth then
task.spawn(function()
while autoRebirth do
local brains = GetBrains()
local required = GetRequiredBrains()
if brains and required then
if brains >= required then
print("🔄 Rebirth! (brains: " .. brains .. ", required: " .. required .. ")")
pcall(function()
RequestRebirth:FireServer()
end)
task.wait(2)
else
task.wait(1)
end
else
print("❌ Could not detect brains or required values")
print(" Brains: " .. tostring(brains))
print(" Required: " .. tostring(required))
if not required then
print(" 💡 Required brains likely stored in DataController as 'RebirthCost'")
print(" Try using the debug button to scan UI for 'Brains Needed' text")
end
task.wait(3)
end
task.wait(0.5)
end
end)
end
end
})
-- ===== DEBUG =====
local DebugTab = Window:CreateTab("Debug", 4483362458)
DebugTab:CreateButton({
Name = "💰 Check Coins",
Callback = function()
local coins = GetCoins()
print(coins and "✅ Coins: " .. coins or "❌ No coins")
end
})
DebugTab:CreateButton({
Name = "🧠 Check Brains & Required",
Callback = function()
local brains = GetBrains()
local required = GetRequiredBrains()
print("Brains: " .. tostring(brains))
print("Required: " .. tostring(required))
if brains and required then
print("Can Rebirth? " .. tostring(brains >= required))
end
end
})
DebugTab:CreateButton({
Name = "🔍 Scan UI for 'Brains Needed'",
Callback = function()
print("Scanning for text containing 'brain'...")
for _, child in ipairs(LocalPlayer.PlayerGui:GetDescendants()) do
if (child:IsA("TextLabel") or child:IsA("TextButton")) and child.Text then
local txt = child.Text:lower()
if txt:match("brain") then
print(" Found: " .. child.Text .. " (Path: " .. child:GetFullName() .. ")")
end
end
end
print("✅ Done")
end
})
DebugTab:CreateButton({
Name = "🧪 Force Rebirth (Test)",
Callback = function()
print("🔄 Testing rebirth remote...")
pcall(function()
RequestRebirth:FireServer()
print("✅ Rebirth remote fired!")
end)
end
})
DebugTab:CreateButton({
Name = "🔍 List All Skills & Costs",
Callback = function()
local skills = GetAvailableSkills()
if #skills == 0 then print("No skills") return end
print("Found " .. #skills .. " skills:")
for _, s in ipairs(skills) do
print(" " .. s.id .. " : " .. s.cost)
end
end
})
DebugTab:CreateButton({
Name = "🧹 Clear Blacklist",
Callback = function()
blacklist = {}
print("✅ Blacklist cleared")
end
})
-- ===== WARNING =====
local WarnTab = Window:CreateTab("⚠️", 4483362458)
WarnTab:CreateParagraph({
Title = "🚀 AUTO REBIRTH FIXED",
Content = "1. Required brains now checks DataController first (RebirthCost).n2. If that fails, it scans UI for 'Brains Needed' text.n3. Click 'Force Rebirth' to test the remote manually.n4. Click 'Scan UI for Brains Needed' to find the exact text.nnUse an ALT account."
})
No comments yet. Be the first!