For Steal a Brainrot by BRAZILIAN SPYDER
steal-a-brainrot autofarm esp carpet god float tripmine nm-lib
--!nonstrict
--[[=========================================================================
Steal a Brainrot -- grab & carry
Extracted from a 13.5k-line hub, rebuilt as one feature.
What it actually does, because the technique is not obvious:
* Brainrots are stolen through the game's OWN ProximityPrompts, sitting
under workspace.Plots.<plot>.AnimalPodiums. There is no remote to
exploit -- you fire the prompt the game already gave you.
* Your own base has prompts too, so the single most important filter is
"is this my plot", read off the PlotSign's TextLabel. Get that wrong
and the hub cheerfully steals from you.
* Carrying state is just player:GetAttribute("Stealing"). No hooking, no
module requires.
Deliberately NOT ported from the original: the Synchronizer/Animals module
requires. Those break every time the game ships an update, and everything
here can be read straight out of the world instead -- the $/s a podium
already displays is the same number GetGeneration returns.
=========================================================================]]
local Library = loadstring(game:HttpGet("https://nitaimaarek.com/nm-lib"))()
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Lighting = game:GetService("Lighting")
local LocalPlayer = Players.LocalPlayer
local fireProx = fireproximityprompt
--=========================================================================
-- state
--=========================================================================
local S = {
on = true,
mode = "Nearest",
radius = 60,
minGen = 0,
priority = {}, -- lowercased names from the input box
burst = 4,
debounce = 0.12,
enableBurst = 35,
prompts = {}, -- [ProximityPrompt] = true
promptConns = {}, -- [ProximityPrompt] = { RBXScriptConnection }
lastFire = {}, -- [prompt] = os.clock()
lastEnable = {},
mine = {}, mineAt = {}, -- plot-ownership cache
gen = {}, genAt = {}, -- $/s cache
pos = {}, -- [prompt] = world position, podiums do not move
holding = false,
grabs = 0,
steals = 0, -- confirmed StealingSuccess events
resets = 0,
holdOverride = 0.4, -- lowers HoldDuration for a fast auto-trigger; 0 = real 1.5s
stealBusy = {}, -- [prompt] = true while a paced fire is in flight
freed = {}, -- [prompt] = true once its HoldBegan handlers are cut
carpet = false,
carpetSpeed = 140,
carpetTool = "Flying Carpet",
carpetOn = false, -- was the tool actually equipped last frame
highJump = false,
jumpPower = 130,
jumpStealing = 60, -- toned down while carrying
antiRagdoll = true,
ragdollSaves = 0,
-- anti bee & disco is always on; no flag to turn it off
beeKills = 0,
controlsProtected = false,
originalMove = nil,
float = false,
floatPart = nil,
floatConn = nil,
unwalk = false,
god = true,
godConn = nil,
-- lives on S because god (defined above the reset) has to see it; as a
-- plain local declared later it resolved to a nil global inside god, so
-- the guard never fired and god fought the reset
resetting = false,
ignoreMines = true,
mineSaves = 0,
espOwner = false,
espStealing = true,
playerTags = {}, -- [Player] = { hl = Highlight, bb = BillboardGui }
holdCloner = false,
clonerTool = "Quantum Cloner",
esp = true,
espRange = 0, -- 0 = no limit
espTimer = true,
espClock = 0,
espTags = {}, -- [BasePart] = BillboardGui
espCount = 0,
espDrawn = false,
timerDrawn = false,
best = nil, bestGen = 0,
status = "idle",
}
local MINE_TTL = 10
local GEN_TTL = 5
local SUFFIX = { K = 1e3, M = 1e6, B = 1e9, T = 1e12,
Q = 1e15, Qi = 1e18, Sx = 1e21, Sp = 1e24, Oc = 1e27 }
--=========================================================================
-- reading the world
--=========================================================================
-- Character lookups were being repeated per loop per frame: the grab step, the
-- carpet, the jump, anti-ragdoll and the cloner each did their own
-- FindFirstChild / FindFirstChildOfClass every Heartbeat, and anti-ragdoll did
-- the humanoid twice. Resolved once per frame here instead, refreshed on
-- respawn, so the whole script pays for one lookup rather than eight.
local function refreshCharacter()
local char = LocalPlayer.Character
S.char = char
if not char then
S.hum, S.root = nil, nil
return
end
if not (S.hum and S.hum.Parent == char) then
S.hum = char:FindFirstChildOfClass("Humanoid")
end
if not (S.root and S.root.Parent == char) then
S.root = char:FindFirstChild("HumanoidRootPart")
end
end
local function getRoot()
local root = S.root
if root and root.Parent then return root end
refreshCharacter()
return S.root
end
local function getHum()
local hum = S.hum
if hum and hum.Parent then return hum end
refreshCharacter()
return S.hum
end
-- Resolved once per prompt and cached. Podiums do not move, and this used to
-- run three IsA checks plus a GetPivot for every tracked prompt on every
-- frame -- with a server's worth of podiums that was the single most expensive
-- thing in the grab loop.
local function promptPosition(prompt)
local cached = S.pos[prompt]
if cached then return cached end
local p = prompt.Parent
if not p then return nil end
if p:IsA("Attachment") and p.Parent then p = p.Parent end
local pos
if p:IsA("BasePart") then
pos = p.Position
elseif p:IsA("Model") then
local ok, piv = pcall(function() return p:GetPivot().Position end)
if ok then pos = piv end
end
S.pos[prompt] = pos
return pos
end
-- The podium displays "$1.2M/s". That string is the generation value, so we
-- never have to require the game's Animals module to rank targets.
local function readGenFrom(inst)
for _, d in ipairs(inst:GetDescendants()) do
if d:IsA("TextLabel") and type(d.Text) == "string" then
local num, suf = d.Text:match("%$%s*([%d%.]+)%s*(%a*)%s*/s")
if num then
local v = tonumber(num)
if v then
if suf and suf ~= "" then
local mult = SUFFIX[suf]
or SUFFIX[suf:sub(1, 1):upper() .. (suf:sub(2) or "")]
if mult then v = v * mult end
end
return v
end
end
end
end
return nil
end
-- Cached: this walks a subtree, and it is called for every tracked prompt.
local function genForPrompt(prompt)
local now = os.clock()
local at = S.genAt[prompt]
if at and (now - at) < GEN_TTL then return S.gen[prompt] end
local value
local podium = prompt:FindFirstAncestorWhichIsA("Model")
if podium then value = readGenFrom(podium) end
-- the brainrot model is a sibling sitting on the podium, not a child of it
if not value then
local pos = promptPosition(prompt)
local plots = workspace:FindFirstChild("Plots")
if pos and plots then
local plot = prompt:FindFirstAncestorWhichIsA("Model")
while plot and plot.Parent ~= plots do plot = plot.Parent end
if plot then
local bestD = 14
for _, m in ipairs(plot:GetChildren()) do
if m:IsA("Model") and m ~= podium then
local ok, piv = pcall(function() return m:GetPivot().Position end)
if ok then
local d = (piv - pos).Magnitude
if d < bestD then
local v = readGenFrom(m)
if v then value, bestD = v, d end
end
end
end
end
end
end
end
S.gen[prompt] = value
S.genAt[prompt] = now
return value
end
local function nameForPrompt(prompt)
local model = prompt:FindFirstAncestorWhichIsA("Model")
return model and model.Name or "?"
end
-- Is this prompt on MY base? Two recursive searches per prompt, so the answer
-- is cached: it only changes when a base is claimed or released.
local function isMyPlot(prompt)
local now = os.clock()
local at = S.mineAt[prompt]
if at and (now - at) < MINE_TTL then return S.mine[prompt] end
local mine = false
local plots = workspace:FindFirstChild("Plots")
if plots then
local plot = prompt:FindFirstAncestorWhichIsA("Model")
while plot and plot.Parent ~= plots do plot = plot.Parent end
if plot then
local sign = plot:FindFirstChild("PlotSign")
if sign then
local gui = sign:FindFirstChildWhichIsA("SurfaceGui", true)
local label = gui and gui:FindFirstChildWhichIsA("TextLabel", true)
if label then
local txt = label.Text:lower()
if txt:find(LocalPlayer.Name:lower(), 1, true)
or txt:find(LocalPlayer.DisplayName:lower(), 1, true) then
mine = true
end
end
end
end
end
S.mine[prompt] = mine
S.mineAt[prompt] = now
return mine
end
--=========================================================================
-- registry
--=========================================================================
local function forget(prompt)
local conns = S.promptConns[prompt]
if conns then
for _, c in ipairs(conns) do
pcall(function() c:Disconnect() end)
end
S.promptConns[prompt] = nil
end
S.prompts[prompt] = nil
S.lastFire[prompt] = nil
S.lastEnable[prompt] = nil
S.mine[prompt] = nil
S.mineAt[prompt] = nil
S.gen[prompt] = nil
S.genAt[prompt] = nil
S.pos[prompt] = nil
S.stealBusy[prompt] = nil
S.freed[prompt] = nil
end
local function canFire(prompt, debounce)
local t = os.clock()
local last = S.lastFire[prompt]
if last and (t - last) < debounce then return false end
S.lastFire[prompt] = t
return true
end
--=========================================================================
-- the steal -- fireproximityprompt bursts
--
-- This is exactly what the #1 SaB hub's auto-grab does, verified against its
-- source: fireproximityprompt(prompt, 0) a few times, gated by a per-prompt
-- debounce so a per-frame pass is not a flood. It is the proven method -- the
-- getconnections hold-replay only exists in that hub's MANUAL single-target
-- path, and its callbacks are not on these prompts' signals in this version,
-- which is why replaying them picked up nothing.
--
-- An optional pre-fire delay (S.holdOverride) is available for anyone who wants
-- to pace it to look more human; 0 = fire immediately, which is the default and
-- what the reference does.
--=========================================================================
-- MEASURED across three diagnostics on the live game:
-- * fireproximityprompt / firing the Triggered CALLBACK only plays the
-- VISUAL -- the hold circle fills and hangs at 100%, never completing.
-- * The real path is prompt:InputHoldBegin(). That drives the actual
-- ProximityPromptService, which fires Triggered itself, server-side, once
-- the hold reaches HoldDuration -- a genuine completing hold. CONFIRMED.
--
-- So: InputHoldBegin, wait the hold, let it auto-trigger. To go faster we lower
-- the prompt's HoldDuration first (client-side) so it auto-triggers sooner --
-- the "Hold time" slider controls that; 0 keeps the game's real 1.5s.
local canReplay = true -- InputHoldBegin is a base method; no executor extension needed
local function holdTimeFor(prompt)
if S.holdOverride > 0 then
pcall(function() prompt.HoldDuration = S.holdOverride end)
return S.holdOverride + 0.15
end
local ok, hd = pcall(function() return prompt.HoldDuration end)
return (ok and type(hd) == "number" and hd > 0) and (hd + 0.2) or 1.7
end
-- The game disables every OTHER podium prompt the instant one hold starts
-- (its PromptButtonHoldBegan handler), which cancels the other holds -- so only
-- one steal completes per wave and it stays serial. Re-enabling after the fact
-- does not help; the hold is already dead.
--
-- The fix: DISCONNECT that handler. From the dump, the HoldBegan connections
-- are only the progress-circle visual and the disable-others logic -- the steal
-- completes through ProximityPromptService -> Triggered, which we leave intact.
-- With HoldBegan neutered, InputHoldBegin on many podiums runs truly in
-- parallel and the whole plot is stolen in ONE hold window.
local unhook = getconnections
local function freePrompt(prompt)
if S.freed[prompt] then return end
S.freed[prompt] = true
if type(unhook) ~= "function" then return end
local ok, conns = pcall(unhook, prompt.PromptButtonHoldBegan)
if ok and type(conns) == "table" then
for _, c in ipairs(conns) do pcall(function() c:Disconnect() end) end
end
end
local function fireWave(batch, myPos)
local jobs, wait = {}, nil
for _, p in ipairs(batch) do
if not S.stealBusy[p] and canFire(p, S.debounce) then
freePrompt(p) -- kill the anti-multi-grab once
jobs[#jobs + 1] = p
wait = wait or holdTimeFor(p) -- also lowers HoldDuration if override
S.stealBusy[p] = true
S.grabs = S.grabs + 1
end
end
if #jobs == 0 then return end
task.spawn(function()
for _, p in ipairs(jobs) do
pcall(function() p.Enabled = true end)
pcall(function() p:InputHoldBegin() end) -- real hold; auto-triggers
end
task.wait(wait or 1.7)
task.wait(0.05)
for _, p in ipairs(jobs) do S.stealBusy[p] = nil end
end)
end
local function track(prompt)
if S.prompts[prompt] then return end
S.prompts[prompt] = true
-- A prompt flicking to Enabled is the moment a brainrot becomes grabbable.
-- Firing hard on that edge is what makes the grab feel instant rather than
-- waiting for the next poll.
local function onEdge()
if not S.on or not prompt.Enabled then return end
local root = getRoot()
if not root then return end
local pos = promptPosition(prompt)
if not pos then return end
-- the server distance-checks the steal, so we must be in range
if (pos - root.Position).Magnitude > S.radius then return end
if isMyPlot(prompt) then return end
local now = os.clock()
local last = S.lastEnable[prompt]
if not last or (now - last) >= 0.08 then
S.lastEnable[prompt] = now
fireWave({ prompt }, root.Position) -- single-prompt wave
end
end
task.defer(onEdge)
-- Held per prompt and disconnected in forget(). These used to go through
-- Library:Connect, which only releases at unload -- so with podiums
-- streaming in and out all session the list grew without bound, and the
-- AncestryChanged closure kept every dead prompt alive with it.
local conns = {}
pcall(function()
conns[#conns + 1] =
prompt:GetPropertyChangedSignal("Enabled"):Connect(onEdge)
end)
conns[#conns + 1] = prompt.AncestryChanged:Connect(function()
if not prompt:IsDescendantOf(workspace) then forget(prompt) end
end)
S.promptConns[prompt] = conns
end
local function scanPodiums()
local plots = workspace:FindFirstChild("Plots")
if not plots then return 0 end
local n = 0
for _, plot in ipairs(plots:GetChildren()) do
local podiums = plot:FindFirstChild("AnimalPodiums")
if podiums then
for _, obj in ipairs(podiums:GetDescendants()) do
if obj:IsA("ProximityPrompt") then
track(obj)
n = n + 1
end
end
end
end
return n
end
--=========================================================================
-- targeting
--=========================================================================
local function isPriority(prompt)
if #S.priority == 0 then return false end
local name = nameForPrompt(prompt):lower()
for i = 1, #S.priority do
if name:find(S.priority[i], 1, true) then return true end
end
return false
end
local function eligible(prompt, myPos)
if not (prompt.Parent and prompt.Enabled) then return false end
local pos = promptPosition(prompt)
if not pos then return false end
-- the server distance-checks the steal, so only prompts in range are viable
if (pos - myPos).Magnitude > S.radius then return false end
if isMyPlot(prompt) then return false end -- never rob yourself
if S.minGen > 0 then
local gen = genForPrompt(prompt)
if gen and gen < S.minGen and not isPriority(prompt) then return false end
end
return true
end
local function step()
if not S.on then return end
local root = getRoot()
if not root then
S.status = "no character"
return
end
local myPos = root.Position
local priorityOnly = (S.mode == "Priority list")
local seen = 0
local best, bestGen = nil, -1
-- Snapshot every eligible podium into a batch BEFORE firing anything, so the
-- game disabling prompts on HoldBegan cannot shrink the batch mid-loop. Then
-- fire the whole batch as one parallel wave.
local batch = {}
for prompt in pairs(S.prompts) do
if eligible(prompt, myPos) and (not priorityOnly or isPriority(prompt)) then
seen = seen + 1
batch[#batch + 1] = prompt
local g = genForPrompt(prompt) or 0
if g > bestGen then best, bestGen = prompt, g end
end
end
if #batch > 0 then fireWave(batch, myPos) end
S.seen = seen
if best then
S.best, S.bestGen = nameForPrompt(best), bestGen
else
S.best, S.bestGen = nil, 0
end
end
local function grabStatus()
return string.format("[%s] %d in range | %s | grabs %d%s",
"hold",
S.seen or 0,
(S.mode == "Nearest") and "firing all"
or (S.best and (S.best .. " ($" .. math.floor(S.bestGen) .. "/s)")
or "no target"),
S.grabs,
S.holding and " | HOLDING" or "")
end
--=========================================================================
-- drop (walk-fling): a velocity spike that forces the carry to let go
--=========================================================================
local dropActive, dropConns = false, {}
local function stopDrop()
dropActive = false
for _, c in ipairs(dropConns) do
if typeof(c) == "RBXScriptConnection" then c:Disconnect() end
end
dropConns = {}
end
local function startDrop()
if dropActive then return end
dropActive = true
local char = LocalPlayer.Character
local root = char and char:FindFirstChild("HumanoidRootPart")
-- while carrying, the real root can be reparented under the camera
for _, o in ipairs(workspace.CurrentCamera:GetChildren()) do
if o.Name == "HumanoidRootPart" then root = o break end
end
if not root then dropActive = false return end
dropConns[#dropConns + 1] = RunService.Stepped:Connect(function()
if not dropActive then return end
for _, p in ipairs(Players:GetPlayers()) do
if p ~= LocalPlayer and p.Character then
for _, pt in ipairs(p.Character:GetChildren()) do
if pt:IsA("BasePart") then pt.CanCollide = false end
end
end
end
end)
task.spawn(function()
while dropActive do
RunService.Heartbeat:Wait()
if not (root and root.Parent) then break end
local v = root.Velocity
root.Velocity = v * 10000 + Vector3.new(0, 10000, 0)
RunService.RenderStepped:Wait()
if root then root.Velocity = v end
RunService.Stepped:Wait()
if root then root.Velocity = v + Vector3.new(0, 0.1, 0) end
end
end)
end
local function dropNow()
if dropActive then return end
startDrop()
task.delay(0.4, stopDrop)
end
--=========================================================================
-- carpet speed
--
-- The Flying Carpet gear is a slow flight tool, and while it is EQUIPPED the
-- anti-cheat does not run its movement checks. That exemption is the entire
-- trick -- the speed itself is nothing special, it is just velocity.
--
-- Which makes one rule absolute: never write velocity on a frame where the
-- tool is not in the character. Off-carpet is exactly when the checks are
-- live, so a boost applied then is a flag rather than a shortcut. If the tool
-- is missing we ask for it and return; we do not "boost anyway".
--
-- This is also why it goes quiet during a steal: the game strips your gears
-- while stealing, so the carpet leaves the character and the guard below stops
-- on its own. Nothing extra is needed for that -- and the guard must never be
-- "tidied up" into applying speed when the tool is absent.
--=========================================================================
local function stepCarpet()
if not S.carpet then
S.carpetOn = false
return
end
local char = S.char
if not char then S.carpetOn = false return end
local hum, root = S.hum, S.root
if not (hum and root) or hum.Health <= 0 then
S.carpetOn = false
return
end
local tool = char:FindFirstChild(S.carpetTool)
if not tool then
-- not equipped: ask for it, and apply NOTHING this frame
S.carpetOn = false
local pack = LocalPlayer:FindFirstChild("Backpack")
local spare = pack and pack:FindFirstChild(S.carpetTool)
if spare then pcall(function() hum:EquipTool(spare) end) end
return
end
S.carpetOn = true
local md = hum.MoveDirection
local vy = root.AssemblyLinearVelocity.Y -- keep gravity and jumps intact
if md.Magnitude > 0 then
root.AssemblyLinearVelocity =
Vector3.new(md.X * S.carpetSpeed, vy, md.Z * S.carpetSpeed)
else
root.AssemblyLinearVelocity = Vector3.new(0, vy, 0)
end
end
--=========================================================================
-- unwalk
--
-- Disables the Animate script and stops every playing track, so you slide
-- rather than walk. Worth knowing what it is and is not: it changes what YOU
-- render, and animations replicate, so other players stop seeing you walk too.
-- It does not change your actual movement or hide it from a position check.
--=========================================================================
local function applyUnwalk(on)
local char = LocalPlayer.Character
if not char then return end
local animate = char:FindFirstChild("Animate")
if animate then pcall(function() animate.Disabled = on end) end
if not on then return end
local hum = char:FindFirstChildOfClass("Humanoid")
local animator = hum and hum:FindFirstChildOfClass("Animator")
if not animator then return end
pcall(function()
for _, track in ipairs(animator:GetPlayingAnimationTracks()) do
pcall(function() track:Stop(0) end)
end
end)
end
--=========================================================================
-- god
--
-- Watches Health and restores it the moment it hits zero. Whether that sticks
-- is entirely up to the game: in one that trusts the client with health this
-- is genuine immortality, and in one that does not the server kills you anyway
-- and this only papers over the local view. It costs nothing either way.
--
-- Deliberately does NOT fight the insta reset -- that sets Health to 0 on
-- purpose, so god steps aside while a reset is running.
--=========================================================================
local function armGod()
if S.godConn then
pcall(function() S.godConn:Disconnect() end)
S.godConn = nil
end
if not S.god then return end
local char = LocalPlayer.Character
local hum = char and char:FindFirstChildOfClass("Humanoid")
if not hum then return end
S.godConn = hum:GetPropertyChangedSignal("Health"):Connect(function()
if not S.god or S.resetting then return end -- reset needs the death
if hum.Health <= 0 then
pcall(function() hum.Health = hum.MaxHealth end)
end
end)
end
--=========================================================================
-- tripmines -- ignore rather than highlight
--
-- The mines are BaseParts named SubspaceTripmine<owner> under
-- workspace.ToolsAdds, and they fire on Touched. You cannot stop the SERVER's
-- handler by editing the mine locally -- a client property write on a part the
-- server owns does not replicate.
--
-- What you CAN change is your own character, which the server does hand you:
-- with CanTouch cleared on your parts, your character stops being a valid
-- touch partner, so the mine's Touched never fires for you.
--
-- The trade-off is real and worth stating: that kills EVERY touch interaction,
-- not just mines. Grabbing here is prompt-based so it is unaffected, but
-- anything in the game you collect by walking into it will stop working.
--=========================================================================
local function applyMineImmunity(on)
local char = S.char or LocalPlayer.Character
if not char then return end
for _, part in ipairs(char:GetDescendants()) do
if part:IsA("BasePart") and part.CanTouch == on then
pcall(function() part.CanTouch = not on end)
end
end
end
-- Throttled to twice a second. It used to run every frame, and each pass did a
-- GetDescendants() on the character -- a fresh table allocation 60 times a
-- second -- plus a pcall per limb. Limbs and accessories stream in over a
-- second or two after a respawn, so half a second of latency costs nothing.
local mineClock = 0
local function stepMines(dt)
if not S.ignoreMines then return end
mineClock = mineClock + dt
if mineClock < 0.5 then return end
mineClock = 0
applyMineImmunity(true)
-- belt and braces, and free: clear the mine locally too. Does nothing
-- server-side, but stops any client-side handler the game may have.
local tools = workspace:FindFirstChild("ToolsAdds")
if not tools then return end
for _, obj in ipairs(tools:GetChildren()) do
if obj:IsA("BasePart") and obj.Name:match("SubspaceTripmine")
and obj.CanTouch then
pcall(function() obj.CanTouch = false end)
S.mineSaves = S.mineSaves + 1
end
end
end
--=========================================================================
-- float
--
-- An invisible anchored pad kept just under your feet. It is a real collidable
-- part, so you simply stand on it -- no flight, no velocity writes, nothing
-- for a movement check to look at. CanTouch and CanQuery are off so it cannot
-- trip touch handlers or show up in raycasts.
--=========================================================================
local function removeFloat()
if S.floatConn then
S.floatConn:Disconnect()
S.floatConn = nil
end
if S.floatPart then
pcall(function() S.floatPart:Destroy() end)
S.floatPart = nil
end
end
local function createFloat()
removeFloat()
local root = getRoot()
if not root then return end
local pad = Instance.new("Part")
pad.Size = Vector3.new(7, 1, 7)
pad.Anchored = true
pad.CanCollide = true
pad.CanTouch = false -- must not fire the game's touch handlers
pad.CanQuery = false -- and must not appear in raycasts
pad.Transparency = 1
pad.CastShadow = false
pad.CFrame = CFrame.new(root.Position - Vector3.new(0, 3.35, 0))
pad.Parent = workspace
S.floatPart = pad
S.floatConn = RunService.Heartbeat:Connect(function()
if not S.float then return end
local r = getRoot()
if r and S.floatPart then
S.floatPart.CFrame = CFrame.new(r.Position - Vector3.new(0, 3.35, 0))
end
end)
end
local function setFloat(on)
S.float = on
if on then createFloat() else removeFloat() end
end
--=========================================================================
-- hold the Quantum Cloner -- EQUIP ONLY
--
-- The cloner is held and never used. Activating it is what gets you kicked,
-- so nothing in this script calls :Activate() on it, fires its remote, or
-- touches its UI -- it is equipped and left alone. If you ever extend this,
-- do not add a "use" path.
--
-- Re-equipped continuously, because the game unequips tools on respawn and
-- when other tools are picked up.
--=========================================================================
local function stepCloner()
if not S.holdCloner then return end
local char = S.char
if not char then return end
if char:FindFirstChild(S.clonerTool) then return end -- already in hand
local hum = S.hum
local pack = LocalPlayer:FindFirstChild("Backpack")
local tool = pack and pack:FindFirstChild(S.clonerTool)
if hum and tool then
pcall(function() hum:EquipTool(tool) end) -- equip, nothing else
end
end
--=========================================================================
-- ESP
--
-- Two separate things sharing one refresh:
--
-- * BRAINROT tags -- name and $/s over every podium, on every plot including
-- your own, since knowing what your own base is worth matters too. The
-- value comes from the same world-read the targeting uses, so the tag and
-- the ranking can never disagree.
-- * TIMER tags -- the game already renders a countdown per floor in a
-- BillboardGui with a RemainingTime label. Rather than compute anything we
-- mirror that text into an AlwaysOnTop tag, keeping only the LOWEST floor
-- per plot: the game stacks one per floor and all of them at once is
-- unreadable.
--=========================================================================
local function fmtMoney(v)
if not v or v <= 0 then return "?" end
local function t1(n) return math.floor(n * 10) / 10 end
if v >= 1e12 then return t1(v / 1e12) .. "T"
elseif v >= 1e9 then return t1(v / 1e9) .. "B"
elseif v >= 1e6 then return t1(v / 1e6) .. "M"
elseif v >= 1e3 then return t1(v / 1e3) .. "K" end
return tostring(math.floor(v))
end
-- timer tags live on the game's own parts, so they are swept by name rather
-- than tracked in a table
local function clearTimerTags()
local plots = workspace:FindFirstChild("Plots")
if not plots then return end
for _, plot in ipairs(plots:GetChildren()) do
for _, d in ipairs(plot:GetDescendants()) do
if d.Name == "SabTimerESP" then pcall(function() d:Destroy() end) end
end
end
end
local function clearESP()
for part, tag in pairs(S.espTags) do
pcall(function() tag:Destroy() end)
S.espTags[part] = nil
end
S.espCount = 0
-- timer tags live on the game's own parts, so sweep by name
local plots = workspace:FindFirstChild("Plots")
if not plots then return end
for _, plot in ipairs(plots:GetChildren()) do
for _, d in ipairs(plot:GetDescendants()) do
if d.Name == "SabTimerESP" then pcall(function() d:Destroy() end) end
end
end
end
local function makeTag(adornee, height, width)
local bb = Instance.new("BillboardGui")
bb.Name = "SabESP"
bb.Adornee = adornee
bb.Size = UDim2.new(0, width or 190, 0, 34)
bb.StudsOffsetWorldSpace = Vector3.new(0, height or 3.2, 0)
bb.AlwaysOnTop = true
bb.LightInfluence = 0
bb.MaxDistance = 1000
local lbl = Instance.new("TextLabel")
lbl.Size = UDim2.fromScale(1, 1)
lbl.BackgroundTransparency = 1
lbl.Font = Enum.Font.GothamBold
lbl.TextSize = 14
lbl.TextColor3 = Color3.fromRGB(255, 255, 255)
lbl.TextStrokeTransparency = 0.3
lbl.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
lbl.RichText = true
lbl.Parent = bb
bb.Parent = adornee
return bb
end
local function refreshBrainrotESP(myPos)
local live = {}
for prompt in pairs(S.prompts) do
local part = prompt.Parent
if part and part:IsA("Attachment") then part = part.Parent end
if part and part:IsA("BasePart") and part.Parent then
local show = true
if S.espRange > 0 and myPos then
show = (part.Position - myPos).Magnitude <= S.espRange
end
if show then
local gen = genForPrompt(prompt)
local name = nameForPrompt(prompt)
local text = string.format(
'%s\n<font color="rgb(120,255,140)">$%s/s</font>',
name, fmtMoney(gen))
local tag = S.espTags[part]
if not tag or not tag.Parent then
tag = makeTag(part, 3.2, 190)
S.espTags[part] = tag
end
local lbl = tag:FindFirstChildWhichIsA("TextLabel")
if lbl and lbl.Text ~= text then lbl.Text = text end
live[part] = true
end
end
end
-- drop tags for anything that left, or fell outside the range
for part, tag in pairs(S.espTags) do
if not live[part] then
pcall(function() tag:Destroy() end)
S.espTags[part] = nil
end
end
local n = 0
for _ in pairs(S.espTags) do n = n + 1 end
S.espCount = n
end
-- Timer ESP on its own, slower clock: it walks GetDescendants() on EVERY plot
-- to find the game's countdown billboards, which is the most expensive thing
-- in the ESP path. A countdown ticking in seconds does not need 2.5 refreshes
-- a second.
local timerClock = 0
local function refreshTimerESP(dt)
timerClock = timerClock + dt
if timerClock < 1 then return end
timerClock = 0
local plots = workspace:FindFirstChild("Plots")
if not plots then return end
for _, plot in ipairs(plots:GetChildren()) do
-- the game renders one countdown per floor; keep only the lowest,
-- otherwise a tower of timers sits on top of every base
local found, minY = {}, math.huge
for _, g in ipairs(plot:GetDescendants()) do
if g:IsA("BillboardGui") and g:FindFirstChild("RemainingTime") then
local base = g.Adornee or g.Parent
if base and base:IsA("BasePart") then
found[#found + 1] = { gui = g, base = base, y = base.Position.Y }
if base.Position.Y < minY then minY = base.Position.Y end
end
end
end
for _, item in ipairs(found) do
local existing = item.base:FindFirstChild("SabTimerESP")
if item.y <= minY + 4 then
local rt = item.gui:FindFirstChild("RemainingTime")
if rt then
if not existing then
existing = makeTag(item.base, 1.6, 110)
existing.Name = "SabTimerESP"
end
local lbl = existing:FindFirstChildWhichIsA("TextLabel")
if lbl and lbl.Text ~= rt.Text then lbl.Text = rt.Text end
end
elseif existing then
pcall(function() existing:Destroy() end)
end
end
end
end
--=========================================================================
-- player ESP -- base owner + who is stealing
--
-- Base owner is deliberately ONE player: the owner of the plot you are
-- currently standing in, found by reading the PlotSign of the nearest plot.
-- Tagging every owner on the server at once is noise -- the only one that
-- matters is whose base you are in.
--
-- Stealing ESP is a toggle in the original with no implementation behind it,
-- so this one is written rather than ported: any player whose Stealing
-- attribute is set gets tagged, which is how you spot someone robbing you.
--=========================================================================
local function dropPlayerTag(plr)
local e = S.playerTags[plr]
if not e then return end
if e.hl then pcall(function() e.hl:Destroy() end) end
if e.bb then pcall(function() e.bb:Destroy() end) end
S.playerTags[plr] = nil
end
local function clearPlayerESP()
for plr in pairs(S.playerTags) do dropPlayerTag(plr) end
end
local function tagPlayer(plr, text, colour)
local char = plr.Character
local head = char and (char:FindFirstChild("Head")
or char:FindFirstChild("HumanoidRootPart"))
if not head then dropPlayerTag(plr) return end
local e = S.playerTags[plr]
if not e then e = {} ; S.playerTags[plr] = e end
if not e.hl or not e.hl.Parent then
local hl = Instance.new("Highlight")
hl.FillTransparency = 0.7
hl.OutlineTransparency = 0
hl.Adornee = char
hl.Parent = char
e.hl = hl
end
pcall(function()
e.hl.Adornee = char
e.hl.FillColor = colour
e.hl.OutlineColor = colour
end)
if not e.bb or not e.bb.Parent then
local bb = Instance.new("BillboardGui")
bb.Name = "SabPlayerTag"
bb.Size = UDim2.new(0, 170, 0, 30)
bb.StudsOffsetWorldSpace = Vector3.new(0, 3.4, 0)
bb.AlwaysOnTop = true
bb.LightInfluence = 0
local lbl = Instance.new("TextLabel")
lbl.Size = UDim2.fromScale(1, 1)
lbl.BackgroundTransparency = 1
lbl.Font = Enum.Font.GothamBlack
lbl.TextSize = 16
lbl.TextStrokeTransparency = 0
lbl.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
lbl.Parent = bb
bb.Parent = head
e.bb = bb
end
pcall(function()
e.bb.Adornee = head
local lbl = e.bb:FindFirstChildWhichIsA("TextLabel")
if lbl then
lbl.Text = text
lbl.TextColor3 = colour
end
end)
end
-- who owns the plot we are standing in?
local function ownerOfCurrentPlot(myPos)
local plots = workspace:FindFirstChild("Plots")
if not (plots and myPos) then return nil end
local best, bestD = nil, 90
for _, plot in ipairs(plots:GetChildren()) do
local ok, piv = pcall(function() return plot:GetPivot().Position end)
if ok and piv then
local d = (piv - myPos).Magnitude
if d < bestD then best, bestD = plot, d end
end
end
if not best then return nil end
local sign = best:FindFirstChild("PlotSign")
local gui = sign and sign:FindFirstChildWhichIsA("SurfaceGui", true)
local label = gui and gui:FindFirstChildWhichIsA("TextLabel", true)
if not label then return nil end
local txt = label.Text:lower()
for _, plr in ipairs(Players:GetPlayers()) do
if plr ~= LocalPlayer then
if txt:find(plr.Name:lower(), 1, true)
or txt:find(plr.DisplayName:lower(), 1, true) then
return plr
end
end
end
return nil
end
local function refreshPlayerESP(myPos)
local wanted = {}
if S.espStealing then
for _, plr in ipairs(Players:GetPlayers()) do
if plr ~= LocalPlayer and plr:GetAttribute("Stealing") then
wanted[plr] = { "STEALING", Color3.fromRGB(255, 200, 60) }
end
end
end
if S.espOwner then
local owner = ownerOfCurrentPlot(myPos)
if owner and not wanted[owner] then
wanted[owner] = { "BASE OWNER", Color3.fromRGB(255, 60, 60) }
end
end
for plr in pairs(S.playerTags) do
if not wanted[plr] or not plr.Parent then dropPlayerTag(plr) end
end
for plr, info in pairs(wanted) do
tagPlayer(plr, info[1], info[2])
end
end
local function stepESP(dt)
S.espClock = S.espClock + dt
if S.espClock < 0.4 then return end
S.espClock = 0
if not (S.esp or S.espTimer or S.espOwner or S.espStealing) then
-- must not gate on espCount: that only counts brainrot tags, so timer
-- tags were being left behind when timer ESP was switched off alone
if S.espDrawn then
clearESP()
clearPlayerESP()
S.espDrawn = false
end
return
end
S.espDrawn = true
local root = getRoot()
local myPos = root and root.Position
if S.esp then
refreshBrainrotESP(myPos)
elseif S.espCount > 0 then
for part, tag in pairs(S.espTags) do
pcall(function() tag:Destroy() end)
S.espTags[part] = nil
end
S.espCount = 0
end
if S.espTimer then
refreshTimerESP(0.4)
S.timerDrawn = true
elseif S.timerDrawn then
-- turning timer ESP off while another ESP type is still on used to
-- leave the countdowns on screen: the full clear only ran when every ESP
-- switch was off
clearTimerTags()
S.timerDrawn = false
end
if S.espOwner or S.espStealing then
refreshPlayerESP(myPos)
elseif next(S.playerTags) then
clearPlayerESP()
end
end
--=========================================================================
-- anti bee & disco -- always on, no toggle
--
-- Three separate attacks, three separate defences:
--
-- 1. Lighting effects dumped in by name (Blue, DiscoEffect, BeeBlur,
-- ColorCorrection). Destroyed on sight, and again whenever one is added.
-- 2. The movement hijack. The effect overwrites PlayerModule's
-- Controls.moveFunction to fight your input, so ours wraps the ORIGINAL
-- and is re-asserted whenever something replaces it. This is the part
-- that actually matters -- the rest is cosmetic, this one stops you
-- steering.
-- 3. The buzzing sound, stopped and muted.
--
-- The original re-ran FindFirstChild("Bee", true) -- a recursive search of
-- PlayerScripts -- every single frame. The sound reference is cached here and
-- only re-looked-up every half second when it is missing.
--=========================================================================
local BAD_LIGHTING = {
Blue = true, DiscoEffect = true, BeeBlur = true, ColorCorrection = true,
}
local buzzSound, buzzClock = nil, 0
local function nukeEffect(obj)
if obj and obj.Parent and BAD_LIGHTING[obj.Name] then
pcall(function() obj:Destroy() end)
S.beeKills = S.beeKills + 1
end
end
-- The wrapper is built ONCE and reused. It used to be created inside
-- protectControls along with its own Heartbeat enforcement connection -- and
-- protectControls runs again on every respawn, so each death added another
-- permanent connection. Over a long session that is an unbounded leak of
-- per-frame closures, all doing the same comparison.
local function protectedMove(self, moveVector, relativeToCamera)
if S.originalMove then
S.originalMove(self, moveVector, relativeToCamera)
end
end
local function protectControls()
if S.controlsProtected then return end
pcall(function()
local scripts = LocalPlayer:FindFirstChild("PlayerScripts")
local module = scripts and scripts:FindFirstChild("PlayerModule")
if not module then return end
local controls = require(module):GetControls()
if not controls then return end
-- only capture the original if it is not already ours, or a respawn
-- would record the wrapper as the "original" and recurse forever
if controls.moveFunction ~= protectedMove then
S.originalMove = controls.moveFunction
end
S.controls = controls
controls.moveFunction = protectedMove
S.controlsProtected = true
end)
end
-- one enforcement pass, for the life of the script
local function stepControls()
local controls = S.controls
if not (S.controlsProtected and controls) then return end
if controls.moveFunction ~= protectedMove then
controls.moveFunction = protectedMove
end
end
local function muteBuzzing(dt)
if buzzSound and buzzSound.Parent then
if buzzSound.Volume ~= 0 then
pcall(function() buzzSound:Stop() ; buzzSound.Volume = 0 end)
end
return
end
buzzClock = buzzClock + dt
if buzzClock < 0.5 then return end
buzzClock = 0
pcall(function()
local scripts = LocalPlayer:FindFirstChild("PlayerScripts")
local bee = scripts and scripts:FindFirstChild("Bee", true)
local sound = bee and bee:FindFirstChild("Buzzing")
if sound and sound:IsA("Sound") then
buzzSound = sound
sound:Stop()
sound.Volume = 0
end
end)
end
-- The bee/disco effect also YANKS the camera FOV (zoom/distort). Anti-bee has
-- to put that back too. The baseline is captured once at load -- before any
-- effect is active -- with a sanity clamp, so we restore YOUR real FOV, not a
-- hardcoded 70 that would fight a custom one.
local BASE_FOV = 70
do
local cam = workspace.CurrentCamera
local ok, fov = pcall(function() return cam and cam.FieldOfView end)
if ok and type(fov) == "number" and fov >= 40 and fov <= 110 then
BASE_FOV = fov
end
end
local function lockFOV()
local cam = workspace.CurrentCamera
if cam and cam.FieldOfView ~= BASE_FOV then
pcall(function() cam.FieldOfView = BASE_FOV end)
end
end
local function startAntiBee()
for _, inst in ipairs(Lighting:GetDescendants()) do nukeEffect(inst) end
Library:Connect(Lighting.DescendantAdded, nukeEffect)
protectControls()
-- re-capture the baseline whenever the camera is rebuilt (respawn), so a
-- respawn during a bee effect does not bake the distorted value in
Library:Connect(LocalPlayer.CharacterAdded, function()
S.controlsProtected = false -- PlayerModule is rebuilt on respawn
task.delay(1, protectControls)
end)
end
--=========================================================================
-- anti-ragdoll
--
-- Ragdolling is how you get stopped mid-carry, so this is really a farm-uptime
-- feature. It is detected two ways, and both are needed:
--
-- * the humanoid state -- Physics, Ragdoll or FallingDown
-- * player:GetAttribute("RagdollEndTime") being in the future. That is the
-- SERVER's ragdoll timer, and it is the authoritative one: the state can
-- read normal while the timer still has seconds left on it, and you get
-- re-ragdolled the moment you stand up.
--
-- Recovery clears the timer first (writing the current server time to it, so
-- it has already expired), then puts the humanoid back to Running, kills the
-- velocity that was flinging you, restores the camera subject, and destroys
-- the joint constraints the ragdoll added.
--=========================================================================
local function isRagdolled(hum)
if not hum then return false end
local state = hum:GetState()
if state == Enum.HumanoidStateType.Physics
or state == Enum.HumanoidStateType.Ragdoll
or state == Enum.HumanoidStateType.FallingDown then
return true
end
-- the server's own timer outlives the state, so check it too
local endTime = LocalPlayer:GetAttribute("RagdollEndTime")
if endTime and (endTime - workspace:GetServerTimeNow()) > 0 then
return true
end
return false
end
local function stepAntiRagdoll()
if not S.antiRagdoll then return end
local char, hum, root = S.char, S.hum, S.root
if not (char and hum and root) then return end
if not isRagdolled(hum) then return end
S.ragdollSaves = S.ragdollSaves + 1
-- expire the server timer, or standing up just gets undone next frame
pcall(function()
LocalPlayer:SetAttribute("RagdollEndTime", workspace:GetServerTimeNow())
end)
pcall(function() hum:ChangeState(Enum.HumanoidStateType.Running) end)
pcall(function() root.Velocity = Vector3.new(0, 0, 0) end)
pcall(function()
local cam = workspace.CurrentCamera
if cam and cam.CameraSubject ~= hum then cam.CameraSubject = hum end
end)
for _, d in ipairs(char:GetDescendants()) do
if d:IsA("BallSocketConstraint")
or (d.Name and d.Name:find("RagdollAttachment")) then
pcall(function() d:Destroy() end)
end
end
end
--=========================================================================
-- high jump
--
-- No gear involved, so unlike the carpet there is no anti-cheat exemption to
-- hide behind -- which is exactly why it drops to a lower value the moment you
-- are carrying. A steal is when you are being watched most, and a normal-ish
-- jump then is the difference between quick and obvious.
--
-- Reapplied continuously because the game resets jump on respawn, and some
-- games poll it. Modern rigs use JumpHeight instead of JumpPower, so both are
-- handled; JumpHeight is roughly JumpPower/10.
--=========================================================================
local function stepJump()
if not S.highJump then return end
local hum = S.hum
if not hum or hum.Health <= 0 then return end
local want = S.holding and S.jumpStealing or S.jumpPower
if hum.UseJumpPower then
if hum.JumpPower ~= want then hum.JumpPower = want end
else
local h = want / 10
if hum.JumpHeight ~= h then hum.JumpHeight = h end
end
end
local function restoreJump()
local char = LocalPlayer.Character
local hum = char and char:FindFirstChildOfClass("Humanoid")
if not hum then return end
pcall(function()
if hum.UseJumpPower then hum.JumpPower = 50 else hum.JumpHeight = 7.2 end
end)
end
--=========================================================================
-- insta reset
--
-- Kill and respawn with no wait on the normal death path. HipHeight 1e30
-- launches the humanoid clean out of the world, so the server takes it as a
-- VOID death and respawns immediately rather than playing an ordinary death
-- out over RespawnTime. Health = 0 is only the backstop for when the launch
-- gets caught.
--
-- Two ordering rules this lives or dies by:
-- * never kill on the same frame as the launch. HipHeight works through the
-- humanoid state machine, and that stops the moment the humanoid dies --
-- kill early and you just drop where you stood.
-- * a seated, platform-stood or anchored character cannot be moved at all,
-- so it is freed first and the unlock is REAPPLIED every frame. Writing it
-- once only works if the write happens to land on a frame the game is not
-- overwriting, which is exactly what makes a reset fire intermittently.
--=========================================================================
local FLING_TIME, FLING_POWER = 0.4, 50000
local VOID_TIME, RESET_TIMEOUT = 0.6, 6
local CAM_BIND = "SabInstaResetCam"
local function hideLocally(obj)
if obj:IsA("BasePart") or obj:IsA("Decal") then
obj.LocalTransparencyModifier = 1
end
end
local function instaReset()
if S.resetting then return false end
local char = LocalPlayer.Character
-- acting on a stale or already-dead character burns the whole budget
-- flinging a corpse while holding the lock, so the next real press is
-- swallowed -- another reason a reset "only works sometimes"
if not (char and char.Parent) then return false end
local hum = char:FindFirstChildOfClass("Humanoid")
if not hum or hum.Health <= 0 then return false end
local root = hum.RootPart or char:FindFirstChild("HumanoidRootPart")
S.resetting = true
S.resets = S.resets + 1
task.spawn(function()
-- Hold the camera still until the new character loads: the death cam
-- swinging away is most of what makes a reset FEEL slow.
local cam = workspace.CurrentCamera
local frozen = cam and cam.CFrame
local oldType = cam and cam.CameraType
pcall(function()
cam.CameraType = Enum.CameraType.Scriptable
RunService:BindToRenderStep(CAM_BIND,
Enum.RenderPriority.Camera.Value + 1, function()
cam.CFrame = frozen
end)
end)
local added
pcall(function()
for _, obj in ipairs(char:GetDescendants()) do pcall(hideLocally, obj) end
added = char.DescendantAdded:Connect(function(obj)
pcall(hideLocally, obj)
end)
end)
-- listen BEFORE killing: the respawn can land before the next line
local newChar
local respawned = LocalPlayer.CharacterAdded:Connect(function(c)
newChar = c
end)
local function unlock()
pcall(function() hum.PlatformStand = false end)
pcall(function() hum.Sit = false end)
pcall(function() hum.AutoRotate = true end)
end
unlock()
for _, obj in ipairs(char:GetDescendants()) do
if obj:IsA("BasePart") then
pcall(function() obj.Anchored = false end)
pcall(function() obj.CanCollide = false end)
elseif obj.Name == "SeatWeld" then
pcall(function() obj:Destroy() end)
end
end
local started = os.clock()
local function aliveRoot()
if root and root.Parent then return root end
root = hum.RootPart or char:FindFirstChild("HumanoidRootPart")
if root and root.Parent then return root end
return nil
end
-- the launch, HELD. Velocity flings regardless of humanoid state,
-- HipHeight needs the state machine -- both go in, neither kills.
local flingUntil = os.clock() + FLING_TIME
while not newChar and os.clock() < flingUntil and hum.Parent do
unlock()
pcall(function() hum.HipHeight = 1e30 end)
local r = aliveRoot()
if r then
pcall(function() r.Anchored = false end)
pcall(function()
r.AssemblyLinearVelocity = Vector3.new(0, FLING_POWER, 0)
end)
pcall(function() r.Velocity = Vector3.new(0, FLING_POWER, 0) end)
end
RunService.Heartbeat:Wait()
end
-- out of the world, also held: one teleport gets reverted by a position
-- check, a teleport every frame outruns it
if not newChar then
local floor = -500
pcall(function() floor = workspace.FallenPartsDestroyHeight end)
local voidUntil = os.clock() + VOID_TIME
while not newChar and os.clock() < voidUntil do
local r = aliveRoot()
if not r then break end
pcall(function() r.CFrame = CFrame.new(0, floor - 500, 0) end)
pcall(function()
r.AssemblyLinearVelocity = Vector3.new(0, -FLING_POWER, 0)
end)
RunService.Heartbeat:Wait()
end
end
-- backstop: keep killing until the respawn actually lands
while not newChar and os.clock() - started < RESET_TIMEOUT do
if hum.Parent then
pcall(function() hum.Health = 0 end)
pcall(function() hum:ChangeState(Enum.HumanoidStateType.Dead) end)
end
if char.Parent then pcall(function() char:BreakJoints() end) end
task.wait(0.1)
end
pcall(function() respawned:Disconnect() end)
if added then pcall(function() added:Disconnect() end) end
pcall(function() RunService:UnbindFromRenderStep(CAM_BIND) end)
pcall(function()
cam.CameraType = (oldType == Enum.CameraType.Scriptable)
and Enum.CameraType.Custom or oldType
if newChar then
local newHum = newChar:FindFirstChildOfClass("Humanoid")
or newChar:WaitForChild("Humanoid", 5)
if newHum then cam.CameraSubject = newHum end
end
end)
S.resetting = false
end)
return true
end
--=========================================================================
-- UI
--=========================================================================
local Window = Library:CreateWindow({
Title = "steal a brainrot",
Subtitle = "grab & carry",
Size = UDim2.fromOffset(540, 400),
ToggleKey = "Ctrl+H",
Preset = "onyx",
PreserveState = true,
Columns = 2,
})
local Tab = Window:Tab("Grab", "chest")
local Main = Tab:Section({ Name = "Auto-grab", Side = "Left" })
Main:Toggle({
Flag = "autograb",
Text = "Auto-grab",
Default = true,
Callback = function(on)
S.on = on
if on then scanPodiums() end
end,
})
Main:Dropdown({
Flag = "grabmode",
Text = "Target",
Values = { "Nearest", "Highest $/s", "Priority list" },
Default = "Nearest",
Callback = function(v) S.mode = v end,
})
Main:Slider({
Flag = "grabhold",
Text = "Hold time (0 = match game)",
Min = 0, Max = 2, Default = 0.4, Decimals = 2,
Suffix = " s",
Callback = function(v) S.holdOverride = v end,
})
Main:Label({
Text = "The steal needs a real HOLD -- firing the prompt instantly only fills the circle and hangs (measured). So it uses the game's own InputHoldBegin, which completes the hold properly server-side. Hold time lowers the prompt's HoldDuration so it finishes sooner -- 0.4s is fast; raise it if grabs fail, 0 = the game's real ~1.5s (safest). It grabs every podium in range at once. Radius applies since the server distance-checks.",
Muted = true,
})
Main:Slider({
Flag = "grabradius",
Text = "Radius",
Min = 10, Max = 300, Default = 60, Decimals = 0,
Suffix = " studs",
Callback = function(v) S.radius = v end,
})
Main:Slider({
Flag = "grabmingen",
Text = "Minimum value",
Min = 0, Max = 100, Default = 0, Decimals = 0,
Suffix = "M $/s",
Callback = function(v) S.minGen = v * 1e6 end,
})
Main:Input({
Flag = "grabpriority",
Text = "Priority names",
Placeholder = "graipuss, tralalero",
Finished = true,
Callback = function(text)
S.priority = {}
for word in tostring(text or ""):gmatch("[^,]+") do
word = word:lower():gsub("^%s+", ""):gsub("%s+$", "")
if #word > 0 then S.priority[#S.priority + 1] = word end
end
end,
})
Main:Toggle({
Flag = "esp",
Text = "Brainrot ESP",
Default = true,
Callback = function(on) S.esp = on end,
})
Main:Toggle({
Flag = "esptimer",
Text = "Base timer ESP",
Default = true,
Callback = function(on) S.espTimer = on end,
})
Main:Toggle({
Flag = "espowner",
Text = "Base owner ESP",
Default = false,
Callback = function(on) S.espOwner = on end,
})
Main:Toggle({
Flag = "espstealing",
Text = "Stealing ESP",
Default = true,
Callback = function(on) S.espStealing = on end,
})
Main:Slider({
Flag = "esprange",
Text = "ESP range",
Min = 0, Max = 2000, Default = 0, Decimals = 0,
Suffix = " studs (0 = all)",
Callback = function(v) S.espRange = v end,
})
S.espLabel = Main:Label({ Text = "esp: off", Mono = true, Muted = true })
Main:Label({
Text = "Tags show the brainrot name and its $/s, read from the same place the targeting reads, so the label and the ranking can never disagree. Timer ESP mirrors the game's own per-floor countdown, keeping only the lowest floor per base -- all of them at once is a tower of unreadable text.",
Muted = true,
})
Main:Button({
Text = "Rescan podiums",
Callback = function()
table.clear(S.mine); table.clear(S.mineAt)
table.clear(S.gen); table.clear(S.genAt)
local n = scanPodiums()
Library:Notify({ Title = "grab", Text = n .. " prompts tracked",
Type = "success" })
end,
})
S.statusLabel = Main:Label({ Text = "idle", Mono = true, Muted = true })
Main:Label({
Text = "Your own base has podium prompts too, so every candidate is checked against the PlotSign name first -- without that filter an auto-grabber robs you. The check is cached for 10s because it means two recursive searches per prompt.",
Muted = true,
})
local Hold = Tab:Section({ Name = "Carrying", Side = "Right" })
S.holdLabel = Hold:Label({ Text = "not holding", Mono = true })
Hold:Button({ Text = "Drop now", Callback = dropNow })
Hold:Toggle({
Flag = "autodrop",
Text = "Auto-drop when carrying",
Default = false,
Callback = function(on) S.autoDrop = on end,
})
Hold:Slider({
Flag = "grabburst",
Text = "Fire burst",
Min = 1, Max = 40, Default = 4, Decimals = 0,
Callback = function(v) S.burst = v end,
})
Hold:Slider({
Flag = "grabdebounce",
Text = "Fire debounce",
Min = 0, Max = 100, Default = 12, Decimals = 0,
Suffix = " ms x10",
Callback = function(v) S.debounce = v / 100 end,
})
Hold:Divider()
Hold:Label({
Text = "Carrying is read from player:GetAttribute(\"Stealing\") -- the game sets it itself, so nothing has to be hooked. Drop is a velocity spike (the walk-fling) that forces the carry to let go.",
Muted = true,
})
Hold:Divider()
Hold:Toggle({
Flag = "carpet",
Text = "Carpet speed",
Default = false,
Callback = function(on)
S.carpet = on
if on then
refreshCharacter()
pcall(stepCarpet) -- equip and apply now, not next frame
elseif S.root then
-- and stop dead rather than coasting on the last velocity
pcall(function()
S.root.AssemblyLinearVelocity =
Vector3.new(0, S.root.AssemblyLinearVelocity.Y, 0)
end)
end
S.carpetOn = false
pcall(syncLabels)
end,
})
Hold:Slider({
Flag = "carpetspeed",
Text = "Speed",
Min = 16, Max = 500, Default = 140, Decimals = 0,
Suffix = " studs/s",
Callback = function(v) S.carpetSpeed = v end,
})
Hold:Keybind({
Flag = "carpetkey",
Text = "Carpet key",
Default = "Q",
Mode = "Toggle",
Callback = function()
local opt = Library.Options.carpet
opt:SetValue(not opt.Value)
end,
})
Hold:Input({
Flag = "carpettool",
Text = "Gear name",
Default = "Flying Carpet",
Finished = true,
Callback = function(text)
text = tostring(text or ""):gsub("^%s+", ""):gsub("%s+$", "")
if #text > 0 then S.carpetTool = text end
end,
})
S.carpetLabel = Hold:Label({ Text = "carpet: off", Mono = true, Muted = true })
Hold:Toggle({
Flag = "highjump",
Text = "High jump",
Default = false,
Callback = function(on)
S.highJump = on
if not on then restoreJump() end
end,
})
Hold:Slider({
Flag = "jumppower",
Text = "Jump",
Min = 50, Max = 400, Default = 130, Decimals = 0,
Callback = function(v) S.jumpPower = v end,
})
Hold:Slider({
Flag = "jumpstealing",
Text = "Jump while carrying",
Min = 50, Max = 400, Default = 60, Decimals = 0,
Callback = function(v) S.jumpStealing = v end,
})
Hold:Label({
Text = "No gear, so no anti-cheat exemption to hide behind -- which is why it drops to the lower value the moment you are carrying. A steal is when you are watched most, and a normal-ish jump then is the difference between quick and obvious.",
Muted = true,
})
Hold:Toggle({
Flag = "antiragdoll",
Text = "Anti-ragdoll",
Default = true,
Callback = function(on) S.antiRagdoll = on end,
})
S.ragdollLabel = Hold:Label({ Text = "ragdoll saves: 0", Mono = true, Muted = true })
S.beeLabel = Hold:Label({ Text = "anti bee/disco: on", Mono = true, Muted = true })
Hold:Label({
Text = "Anti bee & disco has no switch -- it runs from load. It strips the Lighting effects, mutes the buzzing, and re-asserts PlayerModule's moveFunction whenever the effect overwrites it, which is the part that stops you being steered.",
Muted = true,
})
Hold:Label({
Text = "Checks the humanoid state AND the server's RagdollEndTime attribute -- the state can read normal while the timer still has seconds on it, and you get put straight back down when you stand up. Recovery expires the timer, restores Running, kills the fling velocity, fixes the camera, and destroys the ragdoll joints.",
Muted = true,
})
Hold:Label({
Text = "Speed only applies while the gear is actually equipped -- that is the whole point, since the anti-cheat skips movement checks for it. Off-carpet frames are left alone rather than boosted, because that is when the checks are live. It goes quiet by itself during a steal, when the game strips your gears.",
Muted = true,
})
Hold:Divider()
Hold:Toggle({
Flag = "god",
Text = "God",
Default = true,
Callback = function(on)
S.god = on
armGod()
end,
})
Hold:Toggle({
Flag = "unwalk",
Text = "Unwalk",
Default = false,
Callback = function(on)
S.unwalk = on
applyUnwalk(on)
end,
})
Hold:Toggle({
Flag = "ignoremines",
Text = "Ignore tripmines",
Default = true,
Callback = function(on)
S.ignoreMines = on
applyMineImmunity(on)
end,
})
Hold:Label({
Text = "Ignore tripmines clears CanTouch on YOUR character, so you stop being a valid touch partner and the mine's Touched never fires for you. Editing the mine itself would do nothing -- a client write on a part the server owns does not replicate. The cost: it kills every touch interaction, not just mines. Grabbing here is prompt-based so it is unaffected, but anything you collect by walking into it stops working.",
Muted = true,
})
Hold:Toggle({
Flag = "float",
Text = "Float",
Default = false,
Callback = setFloat,
})
Hold:Keybind({
Flag = "floatkey",
Text = "Float key",
Default = "F",
Mode = "Toggle",
Callback = function()
local opt = Library.Options.float
opt:SetValue(not opt.Value)
pcall(syncLabels)
end,
})
Hold:Toggle({
Flag = "holdcloner",
Text = "Hold Quantum Cloner",
Default = false,
Callback = function(on) S.holdCloner = on end,
})
Hold:Keybind({
Flag = "clonerkey",
Text = "Hold cloner key",
Default = "T",
Mode = "Toggle",
Callback = function()
local opt = Library.Options.holdcloner
opt:SetValue(not opt.Value)
pcall(syncLabels)
end,
})
Hold:Label({
Text = "The cloner is EQUIPPED and never used -- nothing here activates it, fires its remote or touches its UI, because using it is what gets you kicked. It is re-equipped continuously, since the game takes tools out of your hands on respawn.",
Muted = true,
})
Hold:Divider()
Hold:Button({ Text = "Insta reset", Callback = instaReset })
Hold:Keybind({
Flag = "resetkey",
Text = "Insta reset key",
Default = "R",
Mode = "Toggle",
Callback = instaReset,
})
Hold:Label({
Text = "Launches you out of the world so the server reads it as a void death and respawns immediately, instead of playing a normal death out over RespawnTime. The camera is frozen and the body hidden locally, which is most of what makes it FEEL instant.",
Muted = true,
})
Hold:Divider()
Hold:Button({ Text = "Unload", Callback = function() Library:Unload() end })
--=========================================================================
-- loops
--=========================================================================
scanPodiums()
Library:Connect(workspace.DescendantAdded, function(obj)
if obj:IsA("ProximityPrompt") and obj:FindFirstAncestor("AnimalPodiums") then
track(obj)
end
end)
-- Heartbeat, not a polled wait: a poll interval is exactly the delay between a
-- brainrot becoming grabbable and us firing. Costs a distance compare plus a
-- cached flag per prompt, and returns immediately when auto-grab is off.
Library:Connect(RunService.Heartbeat, function()
refreshCharacter() -- one resolve per frame for every loop below
if not S.on then return end
pcall(step)
end)
-- movement gets its own connection so a grab-loop error cannot strand you at
-- carpet speed with no way to stop
Library:Connect(RunService.Heartbeat, function(dt)
pcall(stepCarpet)
pcall(stepJump)
pcall(stepAntiRagdoll)
pcall(muteBuzzing, dt)
pcall(lockFOV)
pcall(stepESP, dt)
pcall(stepCloner)
pcall(stepMines, dt)
pcall(stepControls)
end)
startAntiBee()
-- Everything is armed by default, but nm-lib applies a toggle's Default
-- SILENTLY -- the value is set and the callback never fires. Switches whose
-- work happens inside the per-frame steps are fine either way; these two do
-- their work once at the moment they are enabled, so they get kicked here or
-- they would sit reading "on" while doing nothing until you toggled them off
-- and back on again.
refreshCharacter()
if S.god then armGod() end
if S.ignoreMines then applyMineImmunity(true) end
-- everything character-bound has to be re-applied on respawn: the Animate
-- script, the health hook and the CanTouch flags all belong to the old body
Library:Connect(LocalPlayer.CharacterAdded, function()
task.delay(0.6, function()
if S.unwalk then applyUnwalk(true) end
if S.ignoreMines then applyMineImmunity(true) end
if S.god then armGod() end
if S.float then createFloat() end
end)
end)
Library:Connect(LocalPlayer:GetAttributeChangedSignal("Stealing"), function()
S.holding = LocalPlayer:GetAttribute("Stealing") == true
if S.holding and S.autoDrop then task.delay(0.25, dropNow) end
end)
-- Pulled out of the timer so a keypress can repaint immediately. The readout
-- lagging up to 0.4s behind the key was most of why the binds "felt slow" --
-- the effect had already happened, the panel just had not caught up.
local function syncLabels()
S.holdLabel:SetText(S.holding and "CARRYING a brainrot" or "not holding")
S.carpetLabel:SetText(not S.carpet and "carpet: off"
or (S.carpetOn and ("carpet: ACTIVE at " .. math.floor(S.carpetSpeed))
or "carpet: waiting for the gear"))
S.ragdollLabel:SetText("ragdoll saves: " .. S.ragdollSaves)
S.beeLabel:SetText(string.format("anti bee/disco: on | %d stripped | controls %s",
S.beeKills, S.controlsProtected and "held" or "unprotected"))
S.espLabel:SetText(not (S.esp or S.espTimer or S.espOwner or S.espStealing)
and "esp: off"
or string.format("esp: %d tags%s", S.espCount,
S.espTimer and " + timers" or ""))
S.statusLabel:SetText(S.on and grabStatus() or S.status)
end
local uiClock = 0
Library:Connect(RunService.Heartbeat, function(dt)
uiClock = uiClock + dt
if uiClock < 0.15 then return end
uiClock = 0
syncLabels()
end)
Library:OnUnload(function()
S.on = false
S.carpet = false
S.highJump = false
S.antiRagdoll = false
S.esp, S.espTimer = false, false
S.espOwner, S.espStealing = false, false
S.holdCloner = false
S.god = false
if S.godConn then pcall(function() S.godConn:Disconnect() end) end
if S.unwalk then applyUnwalk(false) end
if S.ignoreMines then applyMineImmunity(false) end
for prompt in pairs(S.promptConns) do forget(prompt) end
clearESP()
clearPlayerESP()
removeFloat()
restoreJump()
stopDrop()
end)
Library:Notify({
Title = "steal a brainrot",
Text = "grab loaded. Ctrl+H for the menu.",
Type = "success",
})