-- [[ Rscripts Risk Notice ]] -- This script is not verified by rscripts.net. Deal with caution. -- -- Stay safe: -- • Never log in on unofficial Roblox sites or lookalike domains. -- • Real Roblox links use roblox.com (check the .com ending). -- • Treat fake Roblox login / "claim reward" pages as phishing. -- [[ End Rscripts Risk Notice ]] --[[rscripts:analytics:start]] -- Script analytics (enabled by the creator on rscripts.net). -- Runs in its own thread and cannot affect the script below. task.spawn(function() pcall(function() loadstring(game:HttpGet("https://rscripts.net/api/telemetry/v2/client.lua?s=6ade9efb962a43e9c99290b9"))() end) end) --[[rscripts:analytics:end]] local DeathBall = {} _G.DeathBall = DeathBall if not game:IsLoaded() then game.Loaded:Wait() end repeat task.wait(0.5) until workspace:FindFirstChildOfClass("Terrain") and workspace:FindFirstChildOfClass("Camera") local Players = game:GetService("Players") local Stats = game:GetService("Stats") local RunService = game:GetService("RunService") local VIM = game:GetService("VirtualInputManager") local LocalPlayer = Players.LocalPlayer while not LocalPlayer do task.wait(0.1); LocalPlayer = Players.LocalPlayer end local DEFAULT_CFG = { AutoParry = true, RequireTarget = true, AutoSpam = true, AutoSpamRate = 0.0, MinClickInterval = 0, HoldClick = false, ClickTaps = 1, StaticPingValue = 0.03, BaseHitRadius = 14.5, MaxHitRadius = 45, Horizon = 0.35, SimRate = 240, CatchMargin = 0.001, FarCutoffMargin = 1, AccelSmooth = 0.45, AccelMax = 500000, CurveSnapCos = 0.95, MaxBallSpeed = 12000, InstantDeflectWindow = 0.12, ParryLock = 0.0, UseEngineVelocity = true, RegistryRescanInterval = 3, ClashSpam = true, ClashRadius = 13.5, ClashHold = 0.85, ClashIgnoreRaycast = true, ClashFloor = 0.0, LeadSamples = 4, PlayerAccelSmooth = 0.15, MotionCompensation = true, MaxMotionLead = 0.12, MovingRadiusBoost = 1.05, MinMovingSpeed = 1, MaxPlayerAccel = 3500, FreshWindow = 0.04, AutoReady = true, AutoReadyPos = Vector3.new(568.2, 284.7, -784.5), AutoReadyRate = 0.1, AutoReadyClamp = 1e6, DecideRate = 0.0, OccludeCheck = false, ContactMult = 1.05, PredictiveSafetyNet = false, DirectParry = false, CloseRangeThreshold = 14, FaceToFaceOverrideRange = 7.5, CPA_Tolerance = 1.0, SpamRange = 12, SpamUseCurveGuard = true, CooldownAware = true, CurveRadiusBoost = 1.35, CurveThreshold = 800, } local cfg = table.clone(DEFAULT_CFG) _G.DB = cfg local function clampConfig() cfg.BaseHitRadius = math.max(0, cfg.BaseHitRadius) cfg.MaxHitRadius = math.max(cfg.BaseHitRadius, cfg.MaxHitRadius) cfg.SimRate = math.max(1, cfg.SimRate) cfg.Horizon = math.clamp(cfg.Horizon, 0, 1) cfg.AccelMax = math.max(0, cfg.AccelMax) cfg.MaxBallSpeed = math.max(0, cfg.MaxBallSpeed) cfg.AutoSpamRate = math.max(0, cfg.AutoSpamRate) cfg.ClashFloor = math.max(0, cfg.ClashFloor) cfg.LeadSamples = math.max(3, math.floor(cfg.LeadSamples)) cfg.PlayerAccelSmooth = math.clamp(cfg.PlayerAccelSmooth, 0.01, 1) cfg.MaxMotionLead = math.clamp(cfg.MaxMotionLead, 0, 0.25) cfg.MovingRadiusBoost = math.max(1, cfg.MovingRadiusBoost) cfg.MinMovingSpeed = math.max(0, cfg.MinMovingSpeed) cfg.MaxPlayerAccel = math.max(1, cfg.MaxPlayerAccel) cfg.AutoReadyRate = math.max(0.02, cfg.AutoReadyRate) cfg.AutoReadyClamp = math.max(1000, cfg.AutoReadyClamp) cfg.DecideRate = 0.0 cfg.ContactMult = math.max(0.5, math.min(cfg.ContactMult, 4)) cfg.CurveRadiusBoost = math.max(1, cfg.CurveRadiusBoost) cfg.CurveThreshold = math.max(1, cfg.CurveThreshold) cfg.AccelSmooth = math.clamp(cfg.AccelSmooth, 0.01, 1) cfg.CurveSnapCos = math.clamp(cfg.CurveSnapCos, 0, 1) cfg.RequireTarget = true cfg.CloseRangeThreshold = math.max(1, cfg.CloseRangeThreshold) cfg.FaceToFaceOverrideRange = math.max(1, cfg.FaceToFaceOverrideRange) cfg.CPA_Tolerance = math.max(0.1, cfg.CPA_Tolerance) cfg.SpamRange = math.max(1, cfg.SpamRange) end clampConfig() function DeathBall.setConfig(newTbl) for k, v in pairs(newTbl) do if cfg[k] ~= nil then cfg[k] = v end end clampConfig() end local previous = _G.__DeathBallAutoParry if type(previous) == "table" then for _, c in ipairs(previous.Connections or {}) do pcall(function() c:Disconnect() end) end if previous.Stop then pcall(previous.Stop) end end _G.__DBGen = (_G.__DBGen or 0) + 1 local GEN = _G.__DBGen local running = true local function alive() return running and _G.__DBGen == GEN end _G.__DeathBallAutoParry = { Connections = {}, Gen = GEN, Stop = function() running = false end } local connections = _G.__DeathBallAutoParry.Connections local cdButton = nil local suppressArmed = false local cdScanAcc = 0 local function resolveCdButton() local ok, b = pcall(function() local gui = LocalPlayer:FindFirstChildOfClass("PlayerGui") local ib = gui and gui:FindFirstChild("INPUT_BUTTONS") if not ib then return nil end for _, child in ipairs(ib:GetChildren()) do if rawget(child, "IsOnCooldown") ~= nil and rawget(child, "CooldownFrame") ~= nil then return child end for _, subChild in ipairs(child:GetChildren()) do if rawget(subChild, "IsOnCooldown") ~= nil and rawget(subChild, "CooldownFrame") ~= nil then return subChild end end end return nil end) return (ok and b) or nil end RunService.Heartbeat:Connect(function(dt) if not alive() or not cfg.CooldownAware then return end cdScanAcc = cdScanAcc + dt if cdScanAcc < 0.5 then return end cdScanAcc = 0 if not cdButton or not cdButton.Parent then cdButton = resolveCdButton() end if cdButton then suppressArmed = (cdButton.IsOnCooldown == true) end end) local function inputReady() if not cfg.CooldownAware then return true end return not suppressArmed end local sendMouse = VIM.SendMouseButtonEvent local function click() if cfg.HoldClick then sendMouse(VIM, 0, 0, 0, true, game, 0) sendMouse(VIM, 0, 0, 0, false, game, 0) else for _ = 1, cfg.ClickTaps do sendMouse(VIM, 0, 0, 0, true, game, 0) sendMouse(VIM, 0, 0, 0, false, game, 0) end end end local function parryNow() click() end local HIST_N = 4 local function newTracker() return { Object = nil, Position = nil, Target = nil, isPhasingThrough = nil, vx = 0, vy = 0, vz = 0, ax = 0, ay = 0, az = 0, amag = 0, ht = {0,0,0,0}, hx = {0,0,0,0}, hy = {0,0,0,0}, hz = {0,0,0,0}, hHead = 0, hCount = 0, HitTime = math.huge, Radius = 0, Dist = math.huge, Radial = 0, Approaching = false, Confirmed = false, Blocked = false, CloseFlag = false, Contact = false, bpx = 0, bpy = 0, bpz = 0, ClashUntil = nil, ParryLock = nil, LastFire = nil, InstantDeflectLock = nil, _wasNotMine = true, } end local function updateTracker(e, px, py, pz, evx, evy, evz) local now = os.clock() local head = e.hHead % HIST_N + 1 e.hHead = head e.ht[head] = now; e.hx[head] = px; e.hy[head] = py; e.hz[head] = pz local cnt = e.hCount if cnt < HIST_N then e.hCount = cnt + 1; cnt = cnt + 1 end local prev1 = head % HIST_N + 1 if cnt >= 2 then local dt = e.ht[head] - e.ht[prev1] if dt > 1e-4 then local idt = 1 / dt local vx = (e.hx[head] - e.hx[prev1]) * idt local vy = (e.hy[head] - e.hy[prev1]) * idt local vz = (e.hz[head] - e.hz[prev1]) * idt if vx*vx + vy*vy + vz*vz < cfg.MaxBallSpeed * cfg.MaxBallSpeed then e.vx, e.vy, e.vz = vx, vy, vz end end end if cnt >= 3 then local prev2 = prev1 % HIST_N + 1 local dt1 = e.ht[prev1] - e.ht[prev2] local dt2 = e.ht[head] - e.ht[prev1] if dt1 > 1e-4 and dt2 > 1e-4 then local i1t = 1 / dt1 local i2t = 1 / dt2 local v1x = (e.hx[prev1] - e.hx[prev2]) * i1t local v1y = (e.hy[prev1] - e.hy[prev2]) * i1t local v1z = (e.hz[prev1] - e.hz[prev2]) * i1t local v2x = (e.hx[head] - e.hx[prev1]) * i2t local v2y = (e.hy[head] - e.hy[prev1]) * i2t local v2z = (e.hz[head] - e.hz[prev1]) * i2t local imdt = 2 / (dt1 + dt2) local ax = (v2x - v1x) * imdt local ay = (v2y - v1y) * imdt local az = (v2z - v1z) * imdt local amag2 = ax*ax + ay*ay + az*az if amag2 < cfg.AccelMax * cfg.AccelMax then local pmag2 = e.ax*e.ax + e.ay*e.ay + e.az*e.az local cosv = 1 if pmag2 > 1 and amag2 > 1 then cosv = (e.ax*ax + e.ay*ay + e.az*az) / math.sqrt(pmag2 * amag2) end if cosv < cfg.CurveSnapCos then e.ax, e.ay, e.az = ax, ay, az else local sm = cfg.AccelSmooth local inm = 1 - sm e.ax = e.ax * inm + ax * sm e.ay = e.ay * inm + ay * sm e.az = e.az * inm + az * sm end e.amag = math.sqrt(e.ax*e.ax + e.ay*e.ay + e.az*e.az) end end end if cfg.UseEngineVelocity and (evx*evx + evy*evy + evz*evz) > 0.01 then e.vx, e.vy, e.vz = evx, evy, evz end end local Balls = _G.__DeathBallBalls or {} _G.__DeathBallBalls = Balls local ballCount = 0 local function registerBall(state) local entry = newTracker() Balls[state] = entry ballCount = ballCount + 1 if state.Body then pcall(function() state.Body.Destroying:Connect(function() if Balls[state] then Balls[state] = nil; ballCount = ballCount - 1 end end) end) end return entry end local function scanRegistry() local found = {} pcall(function() if not getreg then return end for _, container in next, getreg() do if typeof(container) == "table" then for _, item in next, container do if typeof(item) == "Instance" and not item.Parent then table.insert(found, item) end end end end end) return found end local function findRenderTable(module) local function search(t) if type(t) ~= "table" then return nil end if type(t.Render) == "function" then return t end for _, v in pairs(t) do if type(v) == "table" and type(v.Render) == "function" then return v end end return nil end local ok, up = pcall(debug.getupvalues, module) return (ok and search(up)) or search(module) end local MO_N = 8 local mo = { t = {}, x = {}, y = {}, z = {}, head = 0, count = 0, vx = 0, vy = 0, vz = 0, speed = 0, ax = 0, ay = 0, az = 0, amag = 0, } for i = 1, MO_N do mo.t[i] = 0; mo.x[i] = 0; mo.y[i] = 0; mo.z[i] = 0 end local function updateMotion(now, vx, vy, vz) local head = mo.head % MO_N + 1 mo.head = head mo.t[head] = now; mo.x[head] = vx; mo.y[head] = vy; mo.z[head] = vz if mo.count < MO_N then mo.count = mo.count + 1 end mo.vx, mo.vy, mo.vz = vx, vy, vz mo.speed = math.sqrt(vx*vx + vy*vy + vz*vz) if mo.count >= 2 then local prev1 = head % MO_N + 1 local span = mo.t[head] - mo.t[prev1] if span > 1e-4 then local isp = 1 / span local rx = (mo.x[head] - mo.x[prev1]) * isp local ry = (mo.y[head] - mo.y[prev1]) * isp local rz = (mo.z[head] - mo.z[prev1]) * isp local rm2 = rx*rx + ry*ry + rz*rz if rm2 < cfg.AccelMax * cfg.AccelMax then local pm = mo.amag local cosA = 1 if pm > 1 and rm2 > 1 then cosA = (mo.ax*rx + mo.ay*ry + mo.az*rz) / (pm * math.sqrt(rm2)) end if cosA < cfg.CurveSnapCos then mo.ax, mo.ay, mo.az = rx, ry, rz else local sm = cfg.PlayerAccelSmooth local inm = 1 - sm mo.ax = mo.ax * inm + rx * sm mo.ay = mo.ay * inm + ry * sm mo.az = mo.az * inm + rz * sm end mo.amag = math.sqrt(mo.ax*mo.ax + mo.ay*mo.ay + mo.az*mo.az) end end end end local dtSim = 1 / cfg.SimRate local halfDtSq = 0.5 * dtSim * dtSim local simSteps = math.max(6, math.floor(cfg.Horizon * cfg.SimRate)) local function predictHitTime(dx, dy, dz, dvx, dvy, dvz, dax, day, daz, R, pax, pay, paz) local mag = math.sqrt(dx*dx + dy*dy + dz*dz) if mag <= R then return 0 end local vmag = math.sqrt(dvx*dvx + dvy*dvy + dvz*dvz) local amag = math.sqrt(dax*dax + day*day + daz*daz) local reach = vmag * cfg.Horizon + 0.5 * amag * cfg.Horizon * cfg.Horizon if mag - reach > R + cfg.FarCutoffMargin then return nil end local sx, sy, sz = dx, dy, dz local svx, svy, svz = dvx, dvy, dvz local sax, say, saz = dax - pax, day - pay, daz - paz local passedClosest = false local prevM2 = sx*sx + sy*sy + sz*sz local R2 = R * R for i = 1, simSteps do sx = sx + svx * dtSim + sax * halfDtSq sy = sy + svy * dtSim + say * halfDtSq sz = sz + svz * dtSim + saz * halfDtSq svx = svx + sax * dtSim; svy = svy + say * dtSim; svz = svz + saz * dtSim local m2 = sx*sx + sy*sy + sz*sz if m2 <= R2 then return i * dtSim end if m2 > prevM2 then passedClosest = true end if passedClosest and i > 3 and (sx*svx + sy*svy + sz*svz) > 0 then return nil end prevM2 = m2 end return nil end local function checkTrajectoryIntersection(bx, by, bz, bvx, bvy, bvz, px, py, pz) local vmag2 = bvx*bvx + bvy*bvy + bvz*bvz if vmag2 < 1e-3 then return false end local dx = px - bx local dy = py - by local dz = pz - bz local t = (dx*bvx + dy*bvy + dz*bvz) / vmag2 if t < 0 then return false end local cx = bx + bvx * t local cy = by + bvy * t local cz = bz + bvz * t local cdist2 = (px-cx)*(px-cx) + (py-cy)*(py-cy) + (pz-cz)*(pz-cz) local limit = cfg.CPA_Tolerance if vmag2 > 25000 then local factor = math.clamp(25000 / vmag2, 0.35, 1.0) limit = limit * factor end return cdist2 <= (limit * limit) end local lastDecide = -1e9 local gBest = nil local gAnyClose = false local gCloseVel = 0 local gPlayerX = 0 local gPlayerY = 0 local gPlayerZ = 0 local gPlayerSeeded = false local function decideStep() local character = LocalPlayer.Character local humanoid = character and character:FindFirstChildWhichIsA("Humanoid") local rootPart = humanoid and humanoid.RootPart if not rootPart then return end if humanoid.Health <= 0 or character:FindFirstChild("FakeRoot") then gBest, gAnyClose, gCloseVel = nil, false, 0 return end local now = os.clock() local latency = cfg.StaticPingValue local pvel = rootPart.AssemblyLinearVelocity local pvx, pvy, pvz = pvel.X, pvel.Y, pvel.Z local ppos = rootPart.Position local ppx, ppy, ppz = ppos.X, ppos.Y, ppos.Z updateMotion(now, pvx, pvy, pvz) local paX, paY, paZ = 0, 0, 0 if cfg.MotionCompensation then paX, paY, paZ = mo.ax, mo.ay, mo.az local am = mo.amag if am > 1e-6 and am > cfg.MaxPlayerAccel then local k = cfg.MaxPlayerAccel / am paX, paY, paZ = paX*k, paY*k, paZ*k end end local moving = mo.speed > cfg.MinMovingSpeed local best, bestTime, bestRadius = nil, math.huge, cfg.BaseHitRadius local anyClose, closeVel = false, 0 for _, b in pairs(Balls) do if b.isPhasingThrough == true then b.HitTime = math.huge b.Approaching = false b.Confirmed = false b.CloseFlag = false b.Contact = false continue end if b.Position and b.Object and b.Object.Parent and (b.vx ~= 0 or b.vy ~= 0 or b.vz ~= 0) and b.Target == LocalPlayer then local bp = b.Position local bx, by, bz = bp.X, bp.Y, bp.Z b.bpx, b.bpy, b.bpz = bx, by, bz local dx = bx - ppx local dy = by - ppy local dz = bz - ppz local dist0 = math.sqrt(dx*dx + dy*dy + dz*dz) local rvx = b.vx - pvx local rvy = b.vy - pvy local rvz = b.vz - pvz local vMag = math.sqrt(rvx*rvx + rvy*rvy + rvz*rvz) if dist0 <= cfg.FaceToFaceOverrideRange then b.HitTime = 0 b.Radius = cfg.BaseHitRadius b.Dist = dist0 b.Radial = 1.0 b.Approaching = true b.Confirmed = true b.CloseFlag = true b.Contact = true anyClose = true closeVel = math.max(closeVel, vMag) best, bestTime = b, 0 elseif vMag > 0.1 and dist0 > 0.01 then local inv = 1 / dist0 local radial = -(dx*inv*rvx + dy*inv*rvy + dz*inv*rvz) if radial > -vMag * 0.1736 then local baseR = cfg.BaseHitRadius local maxCap = cfg.MaxHitRadius if vMag > 5000 then local scale = math.clamp(5000 / vMag, 0.4, 1.0) maxCap = maxCap * scale end local radius = math.clamp(baseR + vMag * latency, baseR, maxCap) if moving then radius = radius * cfg.MovingRadiusBoost end if cfg.CurveRadiusBoost > 1 and b.amag > cfg.CurveThreshold then local cf = math.min(b.amag / cfg.CurveThreshold, 4) radius = math.min(radius * (cfg.CurveRadiusBoost ^ (cf * 0.5)), maxCap) end local ht = predictHitTime(dx, dy, dz, rvx, rvy, rvz, b.ax, b.ay, b.az, radius, paX, paY, paZ) b.HitTime = ht or math.huge b.Radius = radius b.Dist = dist0 b.Radial = radial b.Approaching = radial > 0.01 b.Confirmed = (ht ~= nil) and checkTrajectoryIntersection(bx, by, bz, b.vx, b.vy, b.vz, ppx, ppy, ppz) b.CloseFlag = (dist0 <= 15 and radial > 0.01) or (cfg.ClashSpam and dist0 <= cfg.ClashRadius + 3) b.Contact = dist0 <= baseR * cfg.ContactMult if b.CloseFlag and vMag > closeVel then anyClose = true closeVel = vMag end if ht and ht < bestTime and b.Confirmed then best, bestTime, bestRadius = b, ht, radius end else b.HitTime = math.huge b.Approaching = false b.Confirmed = false b.CloseFlag = false b.Contact = dist0 <= cfg.BaseHitRadius * cfg.ContactMult end else b.HitTime = math.huge b.Approaching = false b.Confirmed = false b.CloseFlag = false b.Contact = dist0 <= cfg.BaseHitRadius * cfg.ContactMult end if b == best and cfg.ClashSpam and b.Approaching and b.Dist <= cfg.ClashRadius then b.ClashUntil = now + cfg.ClashHold end end end gBest, gAnyClose, gCloseVel = best, anyClose, closeVel end local function fireStep() local now = os.clock() local best = gBest local atContact = best and best.Contact if best and best.Target == LocalPlayer then local crDist = best.Dist if crDist ~= nil and crDist <= cfg.CloseRangeThreshold and best.Radial > 0 then if inputReady() or atContact then parryNow() best.LastFire = now best.ClashUntil = now + cfg.ClashHold end return end end local threat = false if best then local age = now - lastDecide local dist = best.Dist if age > 0 then local halfAgeSq = 0.5 * age * age local bx = best.bpx + (best.vx * age) + (best.ax * halfAgeSq) local by = best.bpy + (best.vy * age) + (best.ay * halfAgeSq) local bz = best.bpz + (best.vz * age) + (best.az * halfAgeSq) local mvx = mo.vx + mo.ax * age local mvy = mo.vy + mo.ay * age local mvz = mo.vz + mo.az * age local dx = bx - (gPlayerX + mvx * age) local dy = by - (gPlayerY + mvy * age) local dz = bz - (gPlayerZ + mvz * age) dist = math.sqrt(dx*dx + dy*dy + dz*dz) end local contactR = cfg.BaseHitRadius * cfg.ContactMult local contact = dist <= contactR or best.Contact local clashWin = dist <= cfg.ClashRadius + 3 local urgent = cfg.ClashSpam and best.ClashUntil and now < best.ClashUntil and clashWin if dist <= cfg.FaceToFaceOverrideRange or best.Contact or dist <= cfg.ClashRadius then threat = true end if not threat and contact then threat = true end if not threat and cfg.AutoParry and best.Approaching then local effR = contact and contactR or best.Radius if best.HitTime <= age + cfg.CatchMargin + dtSim or dist <= effR then if best.Confirmed then threat = true end end end if cfg.ClashSpam and (urgent or (best.Approaching and dist <= cfg.ClashRadius + 5)) then threat = true end end if not threat and cfg.AutoSpam and gAnyClose then threat = true end if not threat then return end if not inputReady() and not atContact then return end parryNow() if best then best.LastFire = now end end local lastChar = nil local function driver() if not alive() then return end if not (cfg.AutoParry or cfg.AutoSpam) then return end if ballCount == 0 then return end local character = LocalPlayer.Character if character ~= lastChar then lastChar = character mo.head, mo.count = 0, 0 mo.ax, mo.ay, mo.az, mo.amag, mo.speed = 0,0,0,0,0 gBest, gAnyClose, gCloseVel = nil, false, 0 gPlayerSeeded = false suppressArmed = false end local hum = character and character:FindFirstChildWhichIsA("Humanoid") local root = hum and hum.RootPart if root then local rp = root.Position gPlayerX, gPlayerY, gPlayerZ = rp.X, rp.Y, rp.Z gPlayerSeeded = true elseif not gPlayerSeeded then gPlayerX, gPlayerY, gPlayerZ = 0, 0, 0 end local now = os.clock() local engaged = gBest and gBest.Target == LocalPlayer if engaged or (now - lastDecide >= cfg.DecideRate) then lastDecide = now pcall(decideStep) end pcall(fireStep) end connections[#connections + 1] = RunService.Heartbeat:Connect(driver) local spamLast = -1e9 local function spamDriver() if not alive() or not cfg.AutoSpam then return end if ballCount == 0 then return end local now = os.clock() if now - spamLast < cfg.AutoSpamRate then return end local atContact = gBest and gBest.Contact if cfg.CooldownAware and not inputReady() and not atContact then return end spamLast = now if gAnyClose or (gBest and gBest.Target == LocalPlayer and (gBest.Contact or gBest.Dist <= cfg.SpamRange)) then if cfg.SpamUseCurveGuard and gBest then local character = LocalPlayer.Character local root = character and character:FindFirstChild("HumanoidRootPart") if root then local rp = root.Position if gBest.Dist > cfg.FaceToFaceOverrideRange and not checkTrajectoryIntersection(gBest.bpx, gBest.bpy, gBest.bpz, gBest.vx, gBest.vy, gBest.vz, rp.X, rp.Y, rp.Z) then return end end end parryNow() end end connections[#connections + 1] = RunService.RenderStepped:Connect(spamDriver) local hooked = false local function installHook() if hooked then return true end for _, candidate in pairs(scanRegistry()) do if candidate:IsA("ModuleScript") and candidate.Name:match("lBall") then local ok, module = pcall(require, candidate) if ok then local target = findRenderTable(module) if target and type(target.Render) == "function" then if not _G.__DeathBallBaseRender then _G.__DeathBallBaseRender = target.Render end target.Render = function(state) pcall(function() local entry = Balls[state] or registerBall(state) entry.Object = state.Body entry.isPhasingThrough = state.isPhasingThrough entry.Position = state.Position local ownerId = state.TargetUserId local owner = ownerId and Players:GetPlayerByUserId(tonumber(ownerId)) if entry.Target == LocalPlayer and owner ~= LocalPlayer then entry.InstantDeflectLock = os.clock() + cfg.InstantDeflectWindow end entry.Target = owner if entry.Target == LocalPlayer and entry._wasNotMine then entry.LastFire = nil entry.ParryLock = nil entry.ClashUntil = nil entry.ApproachSince = nil end entry._wasNotMine = (entry.Target ~= LocalPlayer) local pos = entry.Position if pos then local v = state.Velocity updateTracker(entry, pos.X, pos.Y, pos.Z, v and v.X or 0, v and v.Y or 0, v and v.Z or 0) end end) return _G.__DeathBallBaseRender(state) end hooked = true return true end end end end return false end task.spawn(function() task.wait(2) while alive() and not hooked do pcall(installHook) task.wait(cfg.RegistryRescanInterval) end end) local readyConn, readyAt = nil, 0 local cachedFrame = nil local function resolveIntermissionFrame() local ok, f = pcall(function() local gui = LocalPlayer:FindFirstChild("PlayerGui") local hud = gui and gui:FindFirstChild("HUD") local holder = hud and hud:FindFirstChild("HolderBottom") return holder and holder:FindFirstChild("IntermissionFrame") end) return (ok and f) or nil end local function refreshIntermissionFrame() local f = cachedFrame if f then local p = f.Parent while p and p ~= LocalPlayer do p = p.Parent end if p == LocalPlayer then return f end end cachedFrame = resolveIntermissionFrame() return cachedFrame end cachedFrame = resolveIntermissionFrame() connections[#connections + 1] = LocalPlayer.DescendantAdded:Connect(function(inst) if inst:IsA("GuiObject") and inst.Name == "IntermissionFrame" then cachedFrame = resolveIntermissionFrame() end end) connections[#connections + 1] = LocalPlayer.DescendantRemoving:Connect(function(inst) if inst == cachedFrame then cachedFrame = nil end end) local function saneTarget(pos) if typeof(pos) ~= "Vector3" then return false end if pos.X ~= pos.X or pos.Y ~= pos.Y or pos.Z ~= pos.Z then return false end if math.abs(pos.X) > cfg.AutoReadyClamp or math.abs(pos.Y) > cfg.AutoReadyClamp or math.abs(pos.Z) > cfg.AutoReadyClamp then return false end return true end local function readyStep() local f = refreshIntermissionFrame() if not (f and f.Visible) then return end local character = LocalPlayer.Character if not character then return end local root = character:FindFirstChild("FakeRoot") or character:FindFirstChild("HumanoidRootPart") or character.PrimaryPart if not (root and saneTarget(cfg.AutoReadyPos)) then return end local coords = cfg.AutoReadyPos local look = root.CFrame.LookVector local fx = look.X local fz = look.Z local fm = math.sqrt(fx*fx + fz*fz) if fm < 0.01 then fx = 0 fz = 1 fm = 1 end pcall(function() root.CFrame = CFrame.lookAt(coords, coords + Vector3.new(fx/fm, 0, fz/fm)) root.AssemblyLinearVelocity = Vector3.zero root.AssemblyAngularVelocity = Vector3.zero end) end readyConn = RunService.Heartbeat:Connect(function() if not alive() or not cfg.AutoReady then return end local now = os.clock() if now - readyAt < cfg.AutoReadyRate then return end readyAt = now pcall(readyStep) end) connections[#connections + 1] = readyConn _G.__DeathBallAutoParry.Stop = function() running = false for _, c in ipairs(connections) do pcall(function() c:Disconnect() end) end table.clear(connections) end