Created
December 27, 2025 04:45
-
-
Save ryzen885/05b6ea3cbdd263338d16599049e14e0c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -- Auto Perry Script for Blade Ball | |
| -- Fully replicates game's parry remotes and parameters | |
| -- Includes GUI toggles for Auto Perry, Auto Spam, Trigger Box | |
| local Players = game:GetService("Players") | |
| local RunService = game:GetService("RunService") | |
| local ReplicatedStorage = game:GetService("ReplicatedStorage") | |
| local UserInputService = game:GetService("UserInputService") | |
| local player = Players.LocalPlayer | |
| -- ==== SETUP REMOTES AND KEYS ==== | |
| local PropertyChangeOrder = {} | |
| -- Wait until the 3 remotes with '\n' in name are detected | |
| repeat | |
| task.wait() | |
| PropertyChangeOrder = {} | |
| for _, obj in pairs(game:GetDescendants()) do | |
| if obj:IsA("RemoteEvent") and string.find(obj.Name, "\n") then | |
| table.insert(PropertyChangeOrder, obj) | |
| end | |
| end | |
| until #PropertyChangeOrder >= 3 | |
| local ShouldPlayerJump = PropertyChangeOrder[1] | |
| local MainRemote = PropertyChangeOrder[2] | |
| local GetOpponentPosition = PropertyChangeOrder[3] | |
| -- Extract hash keys from internal closure (same as your code) | |
| local HashOne, HashTwo, HashThree | |
| for _, func in pairs(getgc(true)) do | |
| if type(func) == "function" and islclosure(func) then | |
| local info = debug.info(func, "s") | |
| if info and info:find("SwordsController") then | |
| if debug.getinfo(func).linedefined == 276 then | |
| HashOne = debug.getconstants(func)[62] | |
| HashTwo = debug.getconstants(func)[64] | |
| HashThree = debug.getconstants(func)[65] | |
| break | |
| end | |
| end | |
| end | |
| end | |
| -- Extract Parry_Key from GUI connections (same as your code) | |
| local Parry_Key | |
| local hotbarBlock = player.PlayerGui:WaitForChild("Hotbar"):WaitForChild("Block") | |
| local conns = getconnections(hotbarBlock.Activated) | |
| for _, conn in pairs(conns) do | |
| local func = conn.Function | |
| if func and not islclosure(func) then | |
| local upvals = getupvalues(func) | |
| for _, upv in pairs(upvals) do | |
| if type(upv) == "function" then | |
| Parry_Key = getupvalue(getupvalue(upv, 2), 17) | |
| break | |
| end | |
| end | |
| end | |
| if Parry_Key then break end | |
| end | |
| -- Safety check | |
| if not (ShouldPlayerJump and MainRemote and GetOpponentPosition and HashOne and HashTwo and HashThree and Parry_Key) then | |
| warn("Auto Perry: Failed to initialize remotes or keys.") | |
| return | |
| end | |
| -- ==== PARSE PARAMS FUNCTION (from your code) ==== | |
| local function Parry(...) | |
| ShouldPlayerJump:FireServer(HashOne, Parry_Key, ...) | |
| MainRemote:FireServer(HashTwo, Parry_Key, ...) | |
| GetOpponentPosition:FireServer(HashThree, Parry_Key, ...) | |
| end | |
| -- Copy of Auto_Parry.Parry_Data function from your code (simplified) | |
| local function Parry_Data(Parry_Type) | |
| local Camera = workspace.CurrentCamera | |
| local Vector2_Mouse_Location | |
| local Last_Input = UserInputService:GetLastInputType() | |
| local isMobile = UserInputService.TouchEnabled and not UserInputService.MouseEnabled | |
| if Last_Input == Enum.UserInputType.MouseButton1 or Last_Input == Enum.UserInputType.MouseButton2 or Last_Input == Enum.UserInputType.Keyboard then | |
| local Mouse_Location = UserInputService:GetMouseLocation() | |
| Vector2_Mouse_Location = {Mouse_Location.X, Mouse_Location.Y} | |
| else | |
| Vector2_Mouse_Location = {Camera.ViewportSize.X / 2, Camera.ViewportSize.Y / 2} | |
| end | |
| if isMobile then | |
| Vector2_Mouse_Location = {Camera.ViewportSize.X / 2, Camera.ViewportSize.Y / 2} | |
| end | |
| local Events = {} | |
| for _, v in pairs(workspace.Alive:GetChildren()) do | |
| if v ~= player.Character and v.PrimaryPart then | |
| local worldPos = v.PrimaryPart.Position | |
| local screenPos, isOnScreen = Camera:WorldToScreenPoint(worldPos) | |
| if isOnScreen then | |
| Events[tostring(v)] = screenPos | |
| end | |
| end | |
| end | |
| if Parry_Type == 'Camera' then | |
| return {0, Camera.CFrame, Events, Vector2_Mouse_Location} | |
| elseif Parry_Type == 'Backwards' then | |
| local Backwards_Direction = Camera.CFrame.LookVector * -10000 | |
| Backwards_Direction = Vector3.new(Backwards_Direction.X, 0, Backwards_Direction.Z) | |
| return {0, CFrame.new(Camera.CFrame.Position, Camera.CFrame.Position + Backwards_Direction), Events, Vector2_Mouse_Location} | |
| elseif Parry_Type == 'Straight' then | |
| local Aimed_Player = nil | |
| local Closest_Distance = math.huge | |
| local Mouse_Vector = Vector2.new(Vector2_Mouse_Location[1], Vector2_Mouse_Location[2]) | |
| for _, v in pairs(workspace.Alive:GetChildren()) do | |
| if v ~= player.Character and v.PrimaryPart then | |
| local worldPos = v.PrimaryPart.Position | |
| local screenPos, isOnScreen = Camera:WorldToScreenPoint(worldPos) | |
| if isOnScreen then | |
| local playerScreenPos = Vector2.new(screenPos.X, screenPos.Y) | |
| local distance = (Mouse_Vector - playerScreenPos).Magnitude | |
| if distance < Closest_Distance then | |
| Closest_Distance = distance | |
| Aimed_Player = v | |
| end | |
| end | |
| end | |
| end | |
| if Aimed_Player then | |
| return {0, CFrame.new(player.Character.PrimaryPart.Position, Aimed_Player.PrimaryPart.Position), Events, Vector2_Mouse_Location} | |
| else | |
| return {0, CFrame.new(player.Character.PrimaryPart.Position, player.Character.PrimaryPart.Position + Vector3.new(0,0,1)), Events, Vector2_Mouse_Location} | |
| end | |
| elseif Parry_Type == 'Random' then | |
| return {0, CFrame.new(Camera.CFrame.Position, Vector3.new(math.random(-4000, 4000), math.random(-4000, 4000), math.random(-4000, 4000))), Events, Vector2_Mouse_Location} | |
| elseif Parry_Type == 'High' then | |
| local High_Direction = Camera.CFrame.UpVector * 10000 | |
| return {0, CFrame.new(Camera.CFrame.Position, Camera.CFrame.Position + High_Direction), Events, Vector2_Mouse_Location} | |
| elseif Parry_Type == 'Left' then | |
| local Left_Direction = Camera.CFrame.RightVector * 10000 | |
| return {0, CFrame.new(Camera.CFrame.Position, Camera.CFrame.Position - Left_Direction), Events, Vector2_Mouse_Location} | |
| elseif Parry_Type == 'Right' then | |
| local Right_Direction = Camera.CFrame.RightVector * 10000 | |
| return {0, CFrame.new(Camera.CFrame.Position, Camera.CFrame.Position + Right_Direction), Events, Vector2_Mouse_Location} | |
| elseif Parry_Type == 'RandomTarget' then | |
| local candidates = {} | |
| for _, v in pairs(workspace.Alive:GetChildren()) do | |
| if v ~= player.Character and v.PrimaryPart then | |
| local screenPos, isOnScreen = Camera:WorldToScreenPoint(v.PrimaryPart.Position) | |
| if isOnScreen then | |
| table.insert(candidates, { | |
| character = v, | |
| screenXY = { screenPos.X, screenPos.Y } | |
| }) | |
| end | |
| end | |
| end | |
| if #candidates > 0 then | |
| local pick = candidates[math.random(1, #candidates)] | |
| local lookCFrame = CFrame.new(player.Character.PrimaryPart.Position, pick.character.PrimaryPart.Position) | |
| return {0, lookCFrame, Events, pick.screenXY} | |
| else | |
| return {0, Camera.CFrame, Events, {Camera.ViewportSize.X/2, Camera.ViewportSize.Y/2}} | |
| end | |
| end | |
| return {} | |
| end | |
| -- ==== GUI SETUP ==== | |
| local Library = {} -- Simple GUI creation helper | |
| function Library:CreateToggle(text, position, parent) | |
| local button = Instance.new("TextButton") | |
| button.Size = UDim2.new(0, 160, 0, 30) | |
| button.Position = position | |
| button.BackgroundColor3 = Color3.fromRGB(30, 30, 30) | |
| button.TextColor3 = Color3.fromRGB(255, 255, 255) | |
| button.Font = Enum.Font.SourceSansBold | |
| button.TextSize = 20 | |
| button.Text = text .. ": OFF" | |
| button.Parent = parent | |
| button.AutoButtonColor = true | |
| return button | |
| end | |
| local screenGui = Instance.new("ScreenGui") | |
| screenGui.Name = "AutoPerryGUI" | |
| screenGui.Parent = player:WaitForChild("PlayerGui") | |
| screenGui.ResetOnSpawn = false | |
| local frame = Instance.new("Frame") | |
| frame.Size = UDim2.new(0, 200, 0, 150) | |
| frame.Position = UDim2.new(0, 20, 0.5, -75) | |
| frame.BackgroundColor3 = Color3.fromRGB(20, 20, 20) | |
| frame.BorderSizePixel = 0 | |
| frame.Parent = screenGui | |
| frame.Active = true | |
| frame.Draggable = true | |
| local title = Instance.new("TextLabel") | |
| title.Size = UDim2.new(1, 0, 0, 30) | |
| title.BackgroundTransparency = 1 | |
| title.Text = "Auto Perry - Blade Ball" | |
| title.Font = Enum.Font.SourceSansBold | |
| title.TextSize = 22 | |
| title.TextColor3 = Color3.fromRGB(0, 170, 255) | |
| title.Parent = frame | |
| local toggles = {} | |
| toggles.autoPerry = Library:CreateToggle("Auto Perry", UDim2.new(0, 20, 0, 40), frame) | |
| toggles.autoSpam = Library:CreateToggle("Auto Spam", UDim2.new(0, 20, 0, 80), frame) | |
| toggles.triggerBox = Library:CreateToggle("Trigger Box", UDim2.new(0, 20, 0, 120), frame) | |
| local states = { | |
| autoPerry = false, | |
| autoSpam = false, | |
| triggerBox = false, | |
| } | |
| for name, btn in pairs(toggles) do | |
| btn.MouseButton1Click:Connect(function() | |
| states[name] = not states[name] | |
| btn.Text = name:gsub("^%l", string.upper) .. ": " .. (states[name] and "ON" or "OFF") | |
| btn.BackgroundColor3 = states[name] and Color3.fromRGB(0, 170, 255) or Color3.fromRGB(30, 30, 30) | |
| end) | |
| end | |
| -- ==== HELPER FUNCTIONS ==== | |
| local function getBall() | |
| for _, ball in pairs(workspace.Balls:GetChildren()) do | |
| if ball:GetAttribute("realBall") then | |
| return ball | |
| end | |
| end | |
| return nil | |
| end | |
| local function isCharacterRed() | |
| local hrp = player.Character and player.Character:FindFirstChild("HumanoidRootPart") | |
| if hrp then | |
| local c = hrp.Color | |
| -- Adjust threshold as needed | |
| return c.R > 0.7 and c.G < 0.3 and c.B < 0.3 | |
| end | |
| return false | |
| end | |
| -- ==== MAIN LOOP ==== | |
| local parryCooldown = 0.5 | |
| local lastParryTime = 0 | |
| RunService.RenderStepped:Connect(function() | |
| if not player.Character or not player.Character:FindFirstChild("HumanoidRootPart") then return end | |
| local now = tick() | |
| local ball = getBall() | |
| if not ball then return end | |
| local dist = (ball.Position - player.Character.HumanoidRootPart.Position).Magnitude | |
| -- Auto Perry: parry once per cooldown when ball is close | |
| if states.autoPerry and dist <= 10 and now - lastParryTime >= parryCooldown then | |
| local params = Parry_Data("Camera") | |
| Parry(table.unpack(params)) | |
| lastParryTime = now | |
| end | |
| -- Auto Spam: parry rapidly when ball is close | |
| if states.autoSpam and dist <= 10 then | |
| local params = Parry_Data("Camera") | |
| Parry(table.unpack(params)) | |
| end | |
| -- Trigger Box: parry when character turns red | |
| if states.triggerBox and isCharacterRed() then | |
| local params = Parry_Data("Camera") | |
| Parry(table.unpack(params)) | |
| end | |
| end) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment