If you want your bow to fire on click, start with allison. If you want Auto Bow with a menu rebuilt for a phone, take the EvilGeniuses & Robscript Team mobile version. The table below covers the rest: Aim Lock, Silent Aim, and the original Auto Bow menu.
All listed features worked during our check. The game is still new, and we found no anti-cheat getting in the way. We expect that may change, so these results can become outdated after updates.
Choose a No-Key Script
allison
Every function worked in our check. Instant Bow is the reason to start here: the bow fires on click instead of waiting for a full draw.
- Speed Settings: Speed Modifier, Fly, Fly Speed, Speed Multiplier
- Aim: Silent Aim, Prediction, Drop Compensation, Target Part, FOV, Show FOV, Snapline, Visible Only, Max Distance, Trajectory Check, Latency Lead, Training Dummies, Lobby / Other Players, Aimlock, Smoothing
- Anti-Aim: Enable Anti-Aim, Yaw Base, Yaw Add, At Target, Disable While Sliding, Manual Anti-Aim, Manual Left, Manual Right, Manual Back, Manual Forward, Pitch, Pitch Modifier, Pitch Jitter Degree, Yaw Modifier, Yaw Modifier Degree, Spin / Sway Speed, Jitter Rate, Visualize Anti-Aim, Visualizer Material, Visualizer Offset
- +2 more
Details
Functions
- Speed Settings: Speed Modifier, Fly, Fly Speed, Speed Multiplier
- Aim: Silent Aim, Prediction, Drop Compensation, Target Part, FOV, Show FOV, Snapline, Visible Only, Max Distance, Trajectory Check, Latency Lead, Training Dummies, Lobby / Other Players, Aimlock, Smoothing
- Anti-Aim: Enable Anti-Aim, Yaw Base, Yaw Add, At Target, Disable While Sliding, Manual Anti-Aim, Manual Left, Manual Right, Manual Back, Manual Forward, Pitch, Pitch Modifier, Pitch Jitter Degree, Yaw Modifier, Yaw Modifier Degree, Spin / Sway Speed, Jitter Rate, Visualize Anti-Aim, Visualizer Material, Visualizer Offset
- Weapons: Instant Bow, Instant Reload, Force Headshot, Kill Aura, Aura Range, Show Circle, Training Dummies, Lobby / Other Players
- Visuals: Enable ESP, Enemies, Teammates, Lobby / Other, Training Dummies, Unit Budget, Max Distance, Visible Check, Box, Box Category Color, Outline Color, Box Fill, Box Glow, Spin Box Fill, Names, Name Text Size, Name Outline, Distance, Weapon Icon, Icon Scale, Health Bar, Health Bar Position, Health Bar Gap, Health Bar Width, Health Bar Outline, Health Bar Outline Color, Health Bar Gradient, Full HP Color, Mid HP Color, Low HP Color, Health Text, Health Text Follow Bar, Hide Health Text At Full HP, Health Text Gradient Color
Change history
- – Added to page!
Script code
loadstring(game:HttpGet("https://api.jnkie.com/api/v1/luascripts/public/bc1281f922e65efff3574f97ec267bd2923fda0064bf2d1971985bc2e2162fbd/download"))()
Instant Bow was our favorite part of allison. The clip below shows the bow firing without the usual draw. You still click for each shot; the two EvilGeniuses versions use Auto Bow to draw and fire for you.
EvilGeniuses & Robscript Team [Mobile Adaptive]
Every function worked in our check. It runs the same bow logic as EvilGeniuses, inside a menu rebuilt by Robscript Team on BobloNEXT.
- Auto Bow: Smart Charge, Minimum Charge, Maximum Early Flight, Auto Update Interval, Lost Target Grace, Maximum Hold
- Visuals: ESP, Names / HP / Distance, Trajectory
- Main: Aim, Auto Bow, Weapon / Charge, Selected Target, Game Adapters, Auto Bow Status, Runtime Status
- +1 more
Details
Functions
- Auto Bow: Smart Charge, Minimum Charge, Maximum Early Flight, Auto Update Interval, Lost Target Grace, Maximum Hold
- Visuals: ESP, Names / HP / Distance, Trajectory
- Main: Aim, Auto Bow, Weapon / Charge, Selected Target, Game Adapters, Auto Bow Status, Runtime Status
- Targeting: Silent Aim, Target Part, Aim FOV, Max Distance, Training Dummies, Jump Prediction, Prefer High Arc, Extra Lead, Max Candidates
Change history
- – Added to page!
Script code
loadstring(game:HttpGet("https://raw.githubusercontent.com/bobloscript/scripts/refs/heads/main/TribesBOBLONEXY", true))()
The mobile layout is the difference, not a new aiming algorithm. The Auto Bow and Smart Charge switches are still there; only the menu was rebuilt.
MunkeHub
Every function on its list worked in our check. Aim Lock follows your target, and the menu has both player ESP and projectile ESP.
- Speed: WalkSpeed, WalkSpeed Value, JumpPower, JumpPower Value
- Movement: Infinite Jump, Fly, Fly Speed, Noclip
- Utility: Anti-AFK, Server Hop, Rejoin Server, Unload Script
- +3 more
Details
Functions
- Speed: WalkSpeed, WalkSpeed Value, JumpPower, JumpPower Value
- Movement: Infinite Jump, Fly, Fly Speed, Noclip
- Utility: Anti-AFK, Server Hop, Rejoin Server, Unload Script
- Aim Lock: Enable Aim Lock, Team Check, Wall Check, Aim Speed, Aim Lock FOV
- Player ESP: ESP Enabled, Team Check, Show Names, Show Health, Show Distance
- Projectile ESP: Projectile ESP
Change history
- – Added to page!
Script code
loadstring(game:HttpGet("https://pastefy.app/5ZgPHsQ0/raw"))()
Aim Lock steers the camera onto the target, so your view goes with it. Projectile ESP tracks arrows in flight, not only players.
Patsan
Every function worked in our check, including Wallbang. Silent Aim corrects the direction of your shot without moving your camera.
- ESP: ESP Names + HP
- Silent Aim: Silent Aim Enabled, Hit Chance %, Max Distance, Target Part
- FOV: FOV Circle, FOV Radius
- +2 more
Details
Functions
- ESP: ESP Names + HP
- Silent Aim: Silent Aim Enabled, Hit Chance %, Max Distance, Target Part
- FOV: FOV Circle, FOV Radius
- Scope Indicator: Target Indicator
- Wallbang: Wallbang (Shoot Through Walls), Wall Check (if Wallbang OFF)
Change history
- – Added to page!
Script code
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local Debris = game:GetService("Debris")
local Workspace = game:GetService("Workspace")
local function getService(name)
local service = game:GetService(name)
if cloneref then
local ok, res = pcall(cloneref, service)
if ok and res then return res end
end
return service
end
local CoreGui = getService("CoreGui")
local LocalPlayer = Players.LocalPlayer
local Mouse = LocalPlayer:GetMouse()
local Camera = Workspace.CurrentCamera
local CFG = {
SilentEnabled = true,
TargetPart = "Head",
HitChance = 100,
MaxDistance = 2500,
WallbangEnabled = true,
WallCheck = false,
FOVEnabled = true,
FOVVisible = true,
FOVRadius = 200,
ESPEnabled = true,
IndicatorEnabled = true,
}
local CurrentTarget = nil
local FOVCircle = nil
if Drawing and Drawing.new then
FOVCircle = Drawing.new("Circle")
FOVCircle.Visible = CFG.FOVVisible
FOVCircle.Radius = CFG.FOVRadius
FOVCircle.Color = Color3.fromRGB(255, 30, 80)
FOVCircle.Thickness = 1.5
FOVCircle.Filled = false
FOVCircle.Transparency = 0.7
FOVCircle.NumSides = 64
end
local function IsEnemy(character)
if not character or character == LocalPlayer.Character then return false end
local outline = character:FindFirstChild("TR_EnemyOutline")
or character:FindFirstChild("TR_EnemyOutline", true)
return outline ~= nil
end
local function IsVisible(targetPart, character)
if CFG.WallbangEnabled then return true end
if not CFG.WallCheck then return true end
local origin = Camera.CFrame.Position
local direction = targetPart.Position - origin
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
local ignore = { LocalPlayer.Character, character, Camera }
local fxF = Workspace:FindFirstChild("FX")
if fxF then table.insert(ignore, fxF) end
local prF = Workspace:FindFirstChild("Projectiles")
if prF then table.insert(ignore, prF) end
params.FilterDescendantsInstances = ignore
return Workspace:Raycast(origin, direction, params) == nil
end
local function ResolvePartName()
if CFG.TargetPart == "Random" then
local opts = {"Head", "HumanoidRootPart", "UpperTorso"}
return opts[math.random(1, #opts)]
end
return CFG.TargetPart
end
local function GetClosestTarget()
local best = nil
local bestDist = CFG.FOVRadius
local mPos = Vector2.new(Mouse.X, Mouse.Y)
local myRoot = LocalPlayer.Character and LocalPlayer.Character:FindFirstChild("HumanoidRootPart")
if not myRoot then return nil end
local candidates = {}
for _, p in pairs(Players:GetPlayers()) do
if p ~= LocalPlayer and p.Character then
table.insert(candidates, {char = p.Character, player = p})
end
end
for _, m in pairs(Workspace:GetChildren()) do
if m:IsA("Model") and m ~= LocalPlayer.Character then
if not Players:GetPlayerFromCharacter(m) then
if m:FindFirstChild("TR_EnemyOutline") or m:FindFirstChild("TR_EnemyOutline", true) then
table.insert(candidates, {char = m, player = nil})
end
end
end
end
for _, c in pairs(candidates) do
local char = c.char
if IsEnemy(char) then
local hum = char:FindFirstChildOfClass("Humanoid")
if hum and hum.Health > 0 then
local partName = ResolvePartName()
local part = char:FindFirstChild(partName)
or char:FindFirstChild("Head")
or char:FindFirstChild("HumanoidRootPart")
if part and part:IsA("BasePart") then
local dist3D = (part.Position - myRoot.Position).Magnitude
if dist3D <= CFG.MaxDistance then
local sPos, onScreen = Camera:WorldToViewportPoint(part.Position)
if onScreen then
local d2 = (Vector2.new(sPos.X, sPos.Y) - mPos).Magnitude
if d2 < bestDist and IsVisible(part, char) then
bestDist = d2
best = {
Player = c.player,
Character = char,
Part = part,
PartName = partName,
ScreenPos = sPos,
Distance = math.floor(dist3D),
}
end
end
end
end
end
end
end
return best
end
local function RollHit()
return math.random(1, 100) <= CFG.HitChance
end
local WeaponAction = ReplicatedStorage:WaitForChild("Remotes"):WaitForChild("WeaponAction")
if hookmetamethod or getrawmetatable then
local oldNamecall
oldNamecall = hookmetamethod(game, "__namecall", newcclosure(function(self, ...)
local method = getnamecallmethod()
local args = {...}
if method == "FireServer" and self == WeaponAction then
if CFG.SilentEnabled and CurrentTarget and RollHit() then
local action = args[1]
if action == "Shoot" and type(args[2]) == "table" then
local data = args[2]
if typeof(data.origin) == "Vector3" and typeof(data.dir) == "Vector3" then
local tPos = CurrentTarget.Part.Position
data.dir = (tPos - data.origin).Unit
args[2] = data
return oldNamecall(self, unpack(args))
end
end
end
end
return oldNamecall(self, ...)
end))
end
if not hookmetamethod and not getrawmetatable then
UserInputService.InputBegan:Connect(function(input, gpe)
if gpe then return end
if input.UserInputType == Enum.UserInputType.MouseButton1 then
if CFG.SilentEnabled and CurrentTarget and RollHit() then
local orig = Camera.CFrame
Camera.CFrame = CFrame.lookAt(orig.Position, CurrentTarget.Part.Position)
task.defer(function() Camera.CFrame = orig end)
end
end
end)
end
local indicatorGui = Instance.new("ScreenGui")
indicatorGui.Name = "ScopeIndicator"
indicatorGui.ResetOnSpawn = false
indicatorGui.IgnoreGuiInset = true
pcall(function() indicatorGui.Parent = CoreGui end)
if not indicatorGui.Parent then indicatorGui.Parent = LocalPlayer:WaitForChild("PlayerGui") end
local indicatorFrame = Instance.new("Frame")
indicatorFrame.Name = "IndFrame"
indicatorFrame.AnchorPoint = Vector2.new(0, 0.5)
indicatorFrame.Position = UDim2.new(0.5, 40, 0.5, 0)
indicatorFrame.Size = UDim2.new(0, 220, 0, 60)
indicatorFrame.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
indicatorFrame.BackgroundTransparency = 0.45
indicatorFrame.BorderSizePixel = 0
indicatorFrame.Visible = false
indicatorFrame.Parent = indicatorGui
Instance.new("UICorner", indicatorFrame).CornerRadius = UDim.new(0, 8)
local indStroke = Instance.new("UIStroke")
indStroke.Color = Color3.fromRGB(255, 40, 40)
indStroke.Thickness = 1.2
indStroke.Transparency = 0.3
indStroke.Parent = indicatorFrame
local indName = Instance.new("TextLabel")
indName.Name = "NameLabel"
indName.AnchorPoint = Vector2.new(0, 0)
indName.Position = UDim2.new(0, 8, 0, 4)
indName.Size = UDim2.new(1, -16, 0, 22)
indName.BackgroundTransparency = 1
indName.Font = Enum.Font.GothamBold
indName.TextSize = 15
indName.TextColor3 = Color3.fromRGB(255, 80, 80)
indName.TextStrokeTransparency = 0.4
indName.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
indName.TextXAlignment = Enum.TextXAlignment.Left
indName.Text = ""
indName.Parent = indicatorFrame
local indInfo = Instance.new("TextLabel")
indInfo.Name = "InfoLabel"
indInfo.AnchorPoint = Vector2.new(0, 0)
indInfo.Position = UDim2.new(0, 8, 0, 28)
indInfo.Size = UDim2.new(1, -16, 0, 22)
indInfo.BackgroundTransparency = 1
indInfo.Font = Enum.Font.Gotham
indInfo.TextSize = 13
indInfo.TextColor3 = Color3.fromRGB(255, 200, 200)
indInfo.TextStrokeTransparency = 0.5
indInfo.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
indInfo.TextXAlignment = Enum.TextXAlignment.Left
indInfo.Text = ""
indInfo.Parent = indicatorFrame
local indDot = Instance.new("Frame")
indDot.Name = "Dot"
indDot.AnchorPoint = Vector2.new(0.5, 0.5)
indDot.Position = UDim2.new(0.5, 20, 0.5, 0)
indDot.Size = UDim2.new(0, 6, 0, 6)
indDot.BackgroundColor3 = Color3.fromRGB(255, 40, 40)
indDot.BorderSizePixel = 0
indDot.Visible = false
indDot.Parent = indicatorGui
Instance.new("UICorner", indDot).CornerRadius = UDim.new(1, 0)
RunService.RenderStepped:Connect(function()
Camera = Workspace.CurrentCamera
CurrentTarget = GetClosestTarget()
if FOVCircle then
FOVCircle.Position = Vector2.new(Mouse.X, Mouse.Y + 36)
FOVCircle.Radius = CFG.FOVRadius
FOVCircle.Visible = CFG.FOVEnabled and CFG.FOVVisible
end
if CFG.IndicatorEnabled and CurrentTarget then
local name = CurrentTarget.Player
and CurrentTarget.Player.Name
or CurrentTarget.Character.Name
indName.Text = "» " .. name
indInfo.Text = " " .. CurrentTarget.PartName .. " | " .. tostring(CurrentTarget.Distance) .. " studs"
indicatorFrame.Visible = true
indDot.Visible = true
if CFG.WallbangEnabled and CFG.WallCheck then
indStroke.Color = Color3.fromRGB(255, 160, 40)
else
indStroke.Color = Color3.fromRGB(255, 40, 40)
end
else
indicatorFrame.Visible = false
indDot.Visible = false
end
end)
local ESPFolder = Instance.new("Folder")
ESPFolder.Name = "SA_ESP"
pcall(function() ESPFolder.Parent = CoreGui end)
if not ESPFolder.Parent then ESPFolder.Parent = LocalPlayer:WaitForChild("PlayerGui") end
local function CreateESP(player)
if player == LocalPlayer then return end
local function Apply(character)
if not character then return end
task.spawn(function()
local head = character:WaitForChild("Head", 5)
local hum = character:WaitForChild("Humanoid", 5)
if not head or not hum then return end
local waited = 0
while waited < 10 do
if character:FindFirstChild("TR_EnemyOutline") or character:FindFirstChild("TR_EnemyOutline", true) then break end
task.wait(0.5)
waited += 0.5
end
if not (character:FindFirstChild("TR_EnemyOutline") or character:FindFirstChild("TR_EnemyOutline", true)) then return end
if not CFG.ESPEnabled then return end
local bb = Instance.new("BillboardGui")
bb.Name = player.Name .. "_ESP"
bb.Adornee = head
bb.Size = UDim2.new(0, 170, 0, 40)
bb.StudsOffset = Vector3.new(0, 3, 0)
bb.AlwaysOnTop = true
bb.Parent = ESPFolder
local lbl = Instance.new("TextLabel")
lbl.Size = UDim2.new(1, 0, 1, 0)
lbl.BackgroundTransparency = 1
lbl.TextColor3 = Color3.fromRGB(255, 60, 60)
lbl.TextStrokeTransparency = 0
lbl.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
lbl.TextSize = 14
lbl.Font = Enum.Font.SourceSansBold
lbl.Text = "[EN] " .. player.Name .. " | " .. math.floor(hum.Health)
lbl.Parent = bb
hum.HealthChanged:Connect(function(hp)
if lbl.Parent then lbl.Text = "[EN] " .. player.Name .. " | " .. math.floor(hp) end
end)
character.Destroying:Connect(function() if bb then bb:Destroy() end end)
end)
end
if player.Character then Apply(player.Character) end
player.CharacterAdded:Connect(Apply)
end
for _, p in pairs(Players:GetPlayers()) do CreateESP(p) end
Players.PlayerAdded:Connect(CreateESP)
local lib = {}
local sections = {}
local workareas = {}
local visible = true
local dbcooper = false
local function tp(ins, pos, time)
if not ins or not ins.Parent then return end
return TweenService:Create(ins, TweenInfo.new(time or 0.5, Enum.EasingStyle.Quart, Enum.EasingDirection.InOut), {Position = pos}):Play()
end
local function getParentGui()
if gethui then local ok, r = pcall(gethui); if ok and r then return r end end
if syn and syn.protect_gui then return CoreGui end
local ok, cg = pcall(function() return CoreGui end)
if ok and cg then return cg end
if LocalPlayer then
local ok2, pg = pcall(function() return LocalPlayer:FindFirstChildOfClass("PlayerGui") end)
if ok2 and pg then return pg end
end
return CoreGui
end
function lib:init(ti, dosplash, visiblekey, deleteprevious)
ti = ti or "Titlebar"
if visiblekey == nil or visiblekey == true then visiblekey = Enum.KeyCode.Insert end
local parentGui = getParentGui()
if deleteprevious then
pcall(function()
for _, old in ipairs(parentGui:GetChildren()) do
if old.Name == "AppleLibraryGUI" and old:FindFirstChild("main") then
tp(old.main, old.main.Position + UDim2.new(0,0,2,0), 0.5)
Debris:AddItem(old, 0.5)
end
end
end)
end
local scrgui = Instance.new("ScreenGui")
scrgui.Name = "AppleLibraryGUI"
scrgui.ResetOnSpawn = false
if syn and syn.protect_gui then pcall(syn.protect_gui, scrgui) end
local ok = pcall(function() scrgui.Parent = parentGui end)
if not ok and LocalPlayer then scrgui.Parent = LocalPlayer:WaitForChild("PlayerGui") end
local main = Instance.new("Frame")
main.Name = "main"; main.Parent = scrgui
main.AnchorPoint = Vector2.new(0.5, 0.5)
main.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
main.BackgroundTransparency = 0.15
main.Position = UDim2.new(0.5, 0, 2, 0)
main.Size = UDim2.new(0, 721, 0, 584)
Instance.new("UICorner", main).CornerRadius = UDim.new(0, 18)
local dragging, dragInput, dragStart, startPos
main.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
dragging = true; dragStart = input.Position; startPos = main.Position
input.Changed:Connect(function() if input.UserInputState == Enum.UserInputState.End then dragging = false end end)
end
end)
main.InputChanged:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then dragInput = input end
end)
UserInputService.InputChanged:Connect(function(input)
if input == dragInput and dragging then
local d = input.Position - dragStart
main.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + d.X, startPos.Y.Scale, startPos.Y.Offset + d.Y)
end
end)
local workarea = Instance.new("Frame")
workarea.Name = "workarea"; workarea.Parent = main
workarea.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
workarea.Position = UDim2.new(0.364, 0, 0, 0)
workarea.Size = UDim2.new(0, 458, 0, 584)
Instance.new("UICorner", workarea).CornerRadius = UDim.new(0, 18)
local wch = Instance.new("Frame"); wch.Parent = workarea; wch.BackgroundColor3 = Color3.fromRGB(255,255,255); wch.BorderSizePixel = 0; wch.Size = UDim2.new(0,18,0.999,0)
local search = Instance.new("Frame"); search.Parent = main; search.BackgroundColor3 = Color3.fromRGB(255,255,255)
search.Position = UDim2.new(0.026,0,0.096,0); search.Size = UDim2.new(0,225,0,34)
Instance.new("UICorner", search).CornerRadius = UDim.new(0,9)
local stb = Instance.new("TextBox"); stb.Parent = search; stb.BackgroundTransparency = 1; stb.ClipsDescendants = true
stb.Position = UDim2.new(0.06,0,0,0); stb.Size = UDim2.new(0,210,0,34)
stb.Font = Enum.Font.Gotham; stb.PlaceholderText = "Search"; stb.Text = ""
stb.TextColor3 = Color3.fromRGB(95,95,95); stb.TextSize = 22; stb.TextXAlignment = Enum.TextXAlignment.Left
local sidebar = Instance.new("ScrollingFrame"); sidebar.Name = "sidebar"; sidebar.Parent = main
sidebar.Active = true; sidebar.BackgroundTransparency = 1; sidebar.BorderSizePixel = 0
sidebar.Position = UDim2.new(0.025,0,0.182,0); sidebar.Size = UDim2.new(0,233,0,463)
sidebar.CanvasSize = UDim2.new(0,0,0,0); sidebar.ScrollBarThickness = 2
local sll = Instance.new("UIListLayout"); sll.Parent = sidebar; sll.SortOrder = Enum.SortOrder.LayoutOrder; sll.Padding = UDim.new(0,5)
sll:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function() sidebar.CanvasSize = UDim2.new(0,0,0,sll.AbsoluteContentSize.Y+10) end)
stb:GetPropertyChangedSignal("Text"):Connect(function()
local t = string.upper(stb.Text)
for _, b in ipairs(sidebar:GetChildren()) do
if b:IsA("TextButton") then b.Visible = (t == "" or string.find(string.upper(b.Text), t, 1, true) ~= nil) end
end
end)
local btns = Instance.new("Frame"); btns.Parent = main; btns.BackgroundTransparency = 1; btns.Size = UDim2.new(0,105,0,57)
local bll = Instance.new("UIListLayout"); bll.Parent = btns; bll.FillDirection = Enum.FillDirection.Horizontal; bll.HorizontalAlignment = Enum.HorizontalAlignment.Center; bll.VerticalAlignment = Enum.VerticalAlignment.Center; bll.Padding = UDim.new(0,10)
local function dot(c, parent)
local b = Instance.new("TextButton"); b.Parent = parent; b.BackgroundColor3 = c; b.Size = UDim2.new(0,16,0,16); b.AutoButtonColor = false; b.Text = ""
Instance.new("UICorner", b).CornerRadius = UDim.new(1,0); return b
end
local closeBtn = dot(Color3.fromRGB(254,94,86), btns)
closeBtn.MouseButton1Click:Connect(function()
tp(main, main.Position + UDim2.new(0,0,2,0), 0.5); task.wait(0.5); scrgui:Destroy()
end)
local minimizeBtn = dot(Color3.fromRGB(255,189,46), btns)
dot(Color3.fromRGB(39,200,63), btns)
local title = Instance.new("TextLabel"); title.Parent = main; title.BackgroundTransparency = 1
title.Position = UDim2.new(0.389,0,0.035,0); title.Size = UDim2.new(0,400,0,15)
title.Font = Enum.Font.Gotham; title.TextColor3 = Color3.fromRGB(0,0,0); title.TextSize = 28; title.TextXAlignment = Enum.TextXAlignment.Left; title.Text = ti
tp(main, UDim2.new(0.5, 0, 0.5, 0), 1)
local window = {}
function window:ToggleVisible()
if dbcooper then return end; visible = not visible; dbcooper = true
if visible then tp(main, UDim2.new(0.5,0,0.5,0), 0.5); task.wait(0.5); dbcooper = false
else tp(main, main.Position + UDim2.new(0,0,2,0), 0.5); task.wait(0.5); dbcooper = false end
end
if visiblekey then
minimizeBtn.MouseButton1Click:Connect(function() window:ToggleVisible() end)
UserInputService.InputBegan:Connect(function(input, gpe)
if not gpe and input.KeyCode == visiblekey then window:ToggleVisible() end
end)
end
function window:Divider(name)
local d = Instance.new("TextLabel"); d.Parent = sidebar; d.BackgroundTransparency = 1; d.Size = UDim2.new(0,226,0,26)
d.Font = Enum.Font.Gotham; d.Text = name or ""; d.TextColor3 = Color3.fromRGB(95,95,95); d.TextSize = 21; d.TextXAlignment = Enum.TextXAlignment.Left; d.TextYAlignment = Enum.TextYAlignment.Bottom
end
function window:TempNotify(t1, t2)
pcall(function()
for _, v in next, scrgui:GetChildren() do if v.Name == "tempnotif" then v.Position = v.Position + UDim2.new(0,0,0,130) end end
local tn = Instance.new("Frame"); tn.Name = "tempnotif"; tn.Parent = scrgui; tn.AnchorPoint = Vector2.new(0.5,0.5)
tn.BackgroundColor3 = Color3.fromRGB(255,255,255); tn.BackgroundTransparency = 0.15; tn.Position = UDim2.new(1,-250,0.08,0); tn.Size = UDim2.new(0,380,0,80); tn.ZIndex = 4
Instance.new("UICorner", tn).CornerRadius = UDim.new(0,14)
local l1 = Instance.new("TextLabel"); l1.Parent = tn; l1.BackgroundTransparency = 1; l1.Position = UDim2.new(0.04,0,0.08,0); l1.Size = UDim2.new(0.92,0,0,24); l1.ZIndex = 4
l1.Font = Enum.Font.GothamMedium; l1.Text = t1 or ""; l1.TextColor3 = Color3.fromRGB(60,60,60); l1.TextSize = 20; l1.TextXAlignment = Enum.TextXAlignment.Left
local l2 = Instance.new("TextLabel"); l2.Parent = tn; l2.BackgroundTransparency = 1; l2.Position = UDim2.new(0.04,0,0.44,0); l2.Size = UDim2.new(0.92,0,0,40); l2.ZIndex = 4
l2.Font = Enum.Font.Gotham; l2.Text = t2 or ""; l2.TextColor3 = Color3.fromRGB(95,95,95); l2.TextSize = 15; l2.TextWrapped = true; l2.TextXAlignment = Enum.TextXAlignment.Left
Debris:AddItem(tn, 4)
end)
end
function window:Section(name)
local sbtn = Instance.new("TextButton"); sbtn.Parent = sidebar; sbtn.BackgroundColor3 = Color3.fromRGB(21,103,251); sbtn.BackgroundTransparency = 1
sbtn.Size = UDim2.new(0,226,0,37); sbtn.ZIndex = 2; sbtn.AutoButtonColor = false; sbtn.Font = Enum.Font.Gotham; sbtn.Text = name or ""; sbtn.TextColor3 = Color3.fromRGB(0,0,0); sbtn.TextSize = 21
Instance.new("UICorner", sbtn).CornerRadius = UDim.new(0,9)
table.insert(sections, sbtn)
local wm = Instance.new("ScrollingFrame"); wm.Parent = workarea; wm.Active = true; wm.BackgroundTransparency = 1; wm.BorderSizePixel = 0
wm.Position = UDim2.new(0.039,0,0.096,0); wm.Size = UDim2.new(0,422,0,512); wm.ZIndex = 3; wm.CanvasSize = UDim2.new(0,0,0,0); wm.ScrollBarThickness = 2; wm.Visible = false
local wll = Instance.new("UIListLayout"); wll.Parent = wm; wll.HorizontalAlignment = Enum.HorizontalAlignment.Center; wll.SortOrder = Enum.SortOrder.LayoutOrder; wll.Padding = UDim.new(0,5)
wll:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function() wm.CanvasSize = UDim2.new(0,0,0,wll.AbsoluteContentSize.Y+10) end)
table.insert(workareas, wm)
local sec = {}
function sec:Select()
for _, v in next, sections do v.BackgroundTransparency = 1; v.TextColor3 = Color3.fromRGB(0,0,0) end
sbtn.BackgroundTransparency = 0; sbtn.TextColor3 = Color3.fromRGB(255,255,255)
for _, v in next, workareas do v.Visible = false end; wm.Visible = true
end
function sec:Divider(n) local d = Instance.new("TextLabel"); d.Parent = wm; d.BackgroundTransparency = 1; d.Size = UDim2.new(0,418,0,50); d.Font = Enum.Font.Gotham; d.Text = n or ""; d.TextColor3 = Color3.fromRGB(0,0,0); d.TextSize = 25; d.TextXAlignment = Enum.TextXAlignment.Left; d.TextYAlignment = Enum.TextYAlignment.Bottom end
function sec:Label(n) local l = Instance.new("TextLabel"); l.Parent = wm; l.BackgroundTransparency = 1; l.Size = UDim2.new(0,418,0,30); l.Font = Enum.Font.Gotham; l.Text = n or ""; l.TextColor3 = Color3.fromRGB(95,95,95); l.TextSize = 18; l.TextWrapped = true end
function sec:Button(n, cb)
local b = Instance.new("TextButton"); b.Parent = wm; b.BackgroundColor3 = Color3.fromRGB(216,216,216); b.BackgroundTransparency = 1; b.Size = UDim2.new(0,418,0,37)
b.ZIndex = 2; b.Font = Enum.Font.Gotham; b.Text = n or ""; b.TextColor3 = Color3.fromRGB(21,103,251); b.TextSize = 21
Instance.new("UICorner", b).CornerRadius = UDim.new(0,9)
local s = Instance.new("UIStroke"); s.ApplyStrokeMode = Enum.ApplyStrokeMode.Border; s.Color = Color3.fromRGB(21,103,251); s.Thickness = 1; s.Parent = b
if cb then b.MouseButton1Click:Connect(function() pcall(cb) end) end
end
function sec:Switch(n, def, cb)
local mode = def or false
local tl = Instance.new("TextLabel"); tl.Parent = wm; tl.BackgroundTransparency = 1; tl.Size = UDim2.new(0,418,0,37)
tl.Font = Enum.Font.Gotham; tl.Text = n or ""; tl.TextColor3 = Color3.fromRGB(95,95,95); tl.TextSize = 21; tl.TextXAlignment = Enum.TextXAlignment.Left
local fr = Instance.new("TextButton"); fr.Parent = tl; fr.Position = UDim2.new(0.833,0,0.027,0); fr.Size = UDim2.new(0,70,0,36); fr.Text = ""; fr.AutoButtonColor = false
Instance.new("UICorner", fr).CornerRadius = UDim.new(5,0)
local tb = Instance.new("TextButton"); tb.Parent = fr; tb.BackgroundColor3 = Color3.fromRGB(255,255,255); tb.Size = UDim2.new(0,34,0,34); tb.AutoButtonColor = false; tb.Text = ""
Instance.new("UICorner", tb).CornerRadius = UDim.new(5,0)
if mode then tb.Position = UDim2.new(0,35,0,1); fr.BackgroundColor3 = Color3.fromRGB(21,103,251)
else tb.Position = UDim2.new(0,1,0,1); fr.BackgroundColor3 = Color3.fromRGB(216,216,216) end
local function tog()
mode = not mode; if cb then pcall(cb, mode) end
if mode then tb:TweenPosition(UDim2.new(0,35,0,1),"In","Sine",0.1,true); fr.BackgroundColor3 = Color3.fromRGB(21,103,251)
else tb:TweenPosition(UDim2.new(0,1,0,1),"In","Sine",0.1,true); fr.BackgroundColor3 = Color3.fromRGB(216,216,216) end
end
fr.MouseButton1Click:Connect(tog); tb.MouseButton1Click:Connect(tog)
end
function sec:Slider(n, min, max, def, cb)
min = min or 0; max = max or 100; def = math.clamp(def or min, min, max)
local sl = Instance.new("TextLabel"); sl.Parent = wm; sl.BackgroundTransparency = 1; sl.Size = UDim2.new(0,418,0,45)
sl.Font = Enum.Font.Gotham; sl.Text = (n or "Slider")..": "..tostring(def); sl.TextColor3 = Color3.fromRGB(95,95,95); sl.TextSize = 21; sl.TextXAlignment = Enum.TextXAlignment.Left
local bg = Instance.new("TextButton"); bg.Parent = sl; bg.BackgroundColor3 = Color3.fromRGB(216,216,216); bg.Position = UDim2.new(0.44,0,0.3,0); bg.Size = UDim2.new(0,233,0,16); bg.Text = ""; bg.AutoButtonColor = false
Instance.new("UICorner", bg).CornerRadius = UDim.new(1,0)
local fill = Instance.new("Frame"); fill.Parent = bg; fill.BackgroundColor3 = Color3.fromRGB(21,103,251); fill.Size = UDim2.new((def-min)/(max-min),0,1,0)
Instance.new("UICorner", fill).CornerRadius = UDim.new(1,0)
local sliding = false
local function upd(input) local p = math.clamp((input.Position.X - bg.AbsolutePosition.X)/bg.AbsoluteSize.X,0,1); local v = math.floor(min+((max-min)*p)); fill.Size = UDim2.new(p,0,1,0); sl.Text = (n or "Slider")..": "..tostring(v); if cb then pcall(cb, v) end end
bg.InputBegan:Connect(function(i) if i.UserInputType == Enum.UserInputType.MouseButton1 or i.UserInputType == Enum.UserInputType.Touch then sliding = true; upd(i) end end)
UserInputService.InputEnded:Connect(function(i) if i.UserInputType == Enum.UserInputType.MouseButton1 or i.UserInputType == Enum.UserInputType.Touch then sliding = false end end)
UserInputService.InputChanged:Connect(function(i) if sliding and (i.UserInputType == Enum.UserInputType.MouseMovement or i.UserInputType == Enum.UserInputType.Touch) then upd(i) end end)
end
function sec:Dropdown(n, opts, def, cb)
opts = opts or {}; local sel = def or opts[1] or "Select"; local opened = false
local dl = Instance.new("TextLabel"); dl.Parent = wm; dl.BackgroundTransparency = 1; dl.Size = UDim2.new(0,418,0,37)
dl.Font = Enum.Font.Gotham; dl.Text = n or "Dropdown"; dl.TextColor3 = Color3.fromRGB(95,95,95); dl.TextSize = 21; dl.TextXAlignment = Enum.TextXAlignment.Left
local db = Instance.new("TextButton"); db.Parent = dl; db.BackgroundColor3 = Color3.fromRGB(240,240,240); db.Position = UDim2.new(0.442,0,0.027,0); db.Size = UDim2.new(0,233,0,34)
db.Font = Enum.Font.Gotham; db.Text = tostring(sel).." v"; db.TextColor3 = Color3.fromRGB(21,103,251); db.TextSize = 18
Instance.new("UICorner", db).CornerRadius = UDim.new(0,9)
local of = Instance.new("Frame"); of.Parent = wm; of.BackgroundColor3 = Color3.fromRGB(245,245,245); of.Size = UDim2.new(0,418,0,#opts*32); of.Visible = false
Instance.new("UICorner", of).CornerRadius = UDim.new(0,9)
local oll = Instance.new("UIListLayout"); oll.Parent = of; oll.SortOrder = Enum.SortOrder.LayoutOrder
for _, o in ipairs(opts) do
local ob = Instance.new("TextButton"); ob.Parent = of; ob.BackgroundTransparency = 1; ob.Size = UDim2.new(1,0,0,32)
ob.Font = Enum.Font.Gotham; ob.Text = tostring(o); ob.TextColor3 = Color3.fromRGB(95,95,95); ob.TextSize = 18
ob.MouseButton1Click:Connect(function() sel = o; db.Text = tostring(sel).." v"; of.Visible = false; opened = false; if cb then pcall(cb, sel) end end)
end
db.MouseButton1Click:Connect(function() opened = not opened; of.Visible = opened end)
end
sbtn.MouseButton1Click:Connect(function() sec:Select() end)
return sec
end
return window
end
local window = lib:init("Silent Aim + Wallbang", false, Enum.KeyCode.Insert, true)
window:Divider("Combat")
local aimSec = window:Section("Silent Aim")
aimSec:Divider("Silent Aim Settings")
aimSec:Switch("Silent Aim Enabled", CFG.SilentEnabled, function(v) CFG.SilentEnabled = v end)
aimSec:Slider("Hit Chance %", 1, 100, CFG.HitChance, function(v) CFG.HitChance = v end)
aimSec:Slider("Max Distance", 100, 5000, CFG.MaxDistance, function(v) CFG.MaxDistance = v end)
aimSec:Dropdown("Target Part", {"Head", "HumanoidRootPart", "UpperTorso", "Random"}, CFG.TargetPart, function(v) CFG.TargetPart = v end)
aimSec:Divider("FOV")
aimSec:Switch("FOV Circle", CFG.FOVVisible, function(v) CFG.FOVVisible = v; CFG.FOVEnabled = v end)
aimSec:Slider("FOV Radius", 50, 500, CFG.FOVRadius, function(v) CFG.FOVRadius = v end)
aimSec:Divider("Scope Indicator")
aimSec:Switch("Target Indicator", CFG.IndicatorEnabled, function(v)
CFG.IndicatorEnabled = v
if not v then indicatorFrame.Visible = false; indDot.Visible = false end
end)
aimSec:Label("Shows target name + body part near crosshair")
local wbSec = window:Section("Wallbang")
wbSec:Divider("Wallbang Settings")
wbSec:Switch("Wallbang (Shoot Through Walls)", CFG.WallbangEnabled, function(v)
CFG.WallbangEnabled = v
if v then CFG.WallCheck = false end
window:TempNotify("Wallbang", v and "ON — стреляет сквозь стены" or "OFF")
end)
wbSec:Switch("Wall Check (if Wallbang OFF)", CFG.WallCheck, function(v)
CFG.WallCheck = v
if v then CFG.WallbangEnabled = false end
end)
wbSec:Label("Wallbang ON → стреляет в ближайшего врага")
wbSec:Label("даже если он за стеной, через стены.")
wbSec:Label("Wall Check ON → стреляет ТОЛЬКО по видимым.")
wbSec:Label("(Wallbang и Wall Check взаимоисключающие)")
window:Divider("Visuals")
local espSec = window:Section("ESP")
espSec:Divider("ESP Settings")
espSec:Switch("ESP Names + HP", CFG.ESPEnabled, function(v)
CFG.ESPEnabled = v
for _, ch in pairs(ESPFolder:GetChildren()) do
if ch:IsA("BillboardGui") then ch.Enabled = v end
end
end)
espSec:Label("Показывает [EN] ник | HP над врагами")
espSec:Label("Враги определяются по TR_EnemyOutline")
aimSec:Select()
Silent Aim bends the shot toward the target while your camera stays where you point it, so you can watch a different angle. That is the opposite trade from Aim Lock in MunkeHub.
EvilGeniuses
Every function worked in our check. Auto Bow handles the draw and the release, and Smart Charge sets how far it charges before firing.
- ESP: ESP ON, NAMES ON
- Aim: AIM OFF, AIM FOV, AIM: CAMERA
- ARC: ARC ON, ARC: LOW / FAST
- +2 more
Details
Functions
- ESP: ESP ON, NAMES ON
- Aim: AIM OFF, AIM FOV, AIM: CAMERA
- ARC: ARC ON, ARC: LOW / FAST
- Target: TARGET: TORSO
- Bow: AUTO BOW OFF, SMART CHARGE ON, JUMP LEAD ON
Change history
- – Added to page!
Script code
-- Kingfisher / Tribes 3v3 -- standalone client/executor script
-- Original implementation. No downloads, forged remote calls, or external UI libraries.
-- GUI controls: ESP, aim, arc, names, target part, FOV, minimize and unload.
-- Enable AIM in the panel; aim follows only during a bow draw. Insert toggles the menu.
-- Optional native bow automation and scoped silent direction; both start OFF.
-- Jump prediction models gravity and an estimated landing. Native events give charge.
-- Run in the live game client; a saveinstance lacks the server needed for a full match.
local Config = {
ESP = true,
Aim = false,
SilentAim = false,
AutoBow = false,
SmartCharge = true,
JumpPrediction = true,
AutoMinCharge = 0.35,
AutoMaxFlight = 0.75,
AutoInterval = 0.05,
AutoLostTargetGrace = 0.4,
AutoMaxHold = 3,
Trajectory = true,
Names = true,
FOVRadius = 180,
MaxDistance = 650,
IncludeTrainingDummies = true,
PreferHighArc = false,
TargetPart = "UpperTorso",
TargetRefresh = 0.25,
SelectInterval = 0.05,
TrajectoryInterval = 1 / 30,
IdleTrajectoryInterval = 1 / 10,
CastStep = 1 / 45,
MaxLifetime = 5,
MaxTravel = 1200,
MaxCandidates = 3,
ExtraLeadSeconds = 0,
RunMathTests = false,
}
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UIS = game:GetService("UserInputService")
local GuiService = game:GetService("GuiService")
local CollectionService = game:GetService("CollectionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local player = Players.LocalPlayer
assert(player and RunService:IsClient(), "[Kingfisher] Run this in the game client.")
local playerGui = player:WaitForChild("PlayerGui", 15)
assert(playerGui, "[Kingfisher] PlayerGui did not load.")
local ROOT_NAME = "__KingfisherTribes_v1"
local old = playerGui:FindFirstChild(ROOT_NAME)
if old then
local stop = old:FindFirstChild("Shutdown")
if stop and stop:IsA("BindableEvent") then stop:Fire(); task.wait() end
if old.Parent then old:Destroy() end
end
local connections, destructors = {}, {}
local active = true
local renderFailed = false
local binding = ROOT_NAME .. "_" .. tostring(math.floor(os.clock() * 1000000))
local menuBinding = binding .. "_Menu"
local stopAuto, installBowAdapters
local bowAdaptersReady = false
local autoNote = "Auto: OFF"
local windowFocused = true
local function connect(signal, fn)
local connection = signal:Connect(fn)
table.insert(connections, connection)
return connection
end
local gui = Instance.new("ScreenGui")
gui.Name = ROOT_NAME
gui.ResetOnSpawn = false
gui.IgnoreGuiInset = true
gui.Enabled = true
gui.DisplayOrder = 1000
gui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
gui.Parent = playerGui
local shutdown = Instance.new("BindableEvent")
shutdown.Name = "Shutdown"
shutdown.Parent = gui
local visuals = Instance.new("Folder")
visuals.Name = ROOT_NAME
visuals.Parent = Workspace
local function unload()
if not active then return end
active = false
RunService:UnbindFromRenderStep(binding)
RunService:UnbindFromRenderStep(menuBinding)
for _, connection in ipairs(connections) do connection:Disconnect() end
for _, destructor in ipairs(destructors) do pcall(destructor) end
visuals:Destroy()
gui:Destroy()
print("[Kingfisher] Unloaded.")
end
connect(shutdown.Event, unload)
connect(gui.Destroying, unload)
local function make(class, properties, parent)
local object = Instance.new(class)
for key, value in pairs(properties) do object[key] = value end
object.Parent = parent
return object
end
local function rounded(object, radius)
make("UICorner", {CornerRadius = UDim.new(0, radius)}, object)
end
local PANEL_WIDTH, PANEL_HEIGHT = 342, 410
local panel = make("Frame", {
Name = "Menu", Visible = true,
Position = UDim2.fromOffset(20, 90), Size = UDim2.fromOffset(PANEL_WIDTH, PANEL_HEIGHT),
BackgroundColor3 = Color3.fromRGB(15, 23, 30), BackgroundTransparency = 0.04,
BorderSizePixel = 0,
}, gui)
rounded(panel, 9)
make("UIStroke", {Color = Color3.fromRGB(47, 83, 90), Thickness = 1}, panel)
local function textLabel(parent, text, y, height)
return make("TextLabel", {
Position = UDim2.fromOffset(12, y), Size = UDim2.new(1, -24, 0, height),
BackgroundTransparency = 1, Text = text, TextSize = 13,
Font = Enum.Font.Code, TextColor3 = Color3.fromRGB(221, 231, 237),
TextXAlignment = Enum.TextXAlignment.Left, TextTruncate = Enum.TextTruncate.AtEnd,
TextYAlignment = Enum.TextYAlignment.Center,
}, parent)
end
local title = textLabel(panel, "KINGFISHER / TRIBES", 8, 24)
title.Size = UDim2.new(1, -96, 0, 24)
title.TextColor3 = Color3.fromRGB(87, 221, 211)
local content = make("Frame", {
Position = UDim2.fromOffset(0, 42), Size = UDim2.new(1, 0, 1, -42), BackgroundTransparency = 1,
}, panel)
local function button(parent, caption, x, y, width, height)
local result = make("TextButton", {
Position = UDim2.fromOffset(x, y), Size = UDim2.fromOffset(width, height),
BackgroundColor3 = Color3.fromRGB(32, 47, 58), BorderSizePixel = 0,
TextSize = 13, Font = Enum.Font.Code, TextColor3 = Color3.new(1, 1, 1), Text = caption,
}, parent)
rounded(result, 5)
return result
end
local minimize = button(panel, "-", PANEL_WIDTH - 76, 8, 28, 26)
local mouseIconBeforeMenu = UIS.MouseIconEnabled
minimize.Modal = true -- Free the cursor only while the menu is visible.
table.insert(destructors, function()
minimize.Modal = false
if panel.Visible then UIS.MouseIconEnabled = mouseIconBeforeMenu end
end)
local close = button(panel, "X", PANEL_WIDTH - 40, 8, 28, 26)
close.BackgroundColor3 = Color3.fromRGB(91, 44, 49)
connect(close.Activated, unload)
connect(minimize.Activated, function()
content.Visible = not content.Visible
panel.Size = UDim2.fromOffset(PANEL_WIDTH, content.Visible and PANEL_HEIGHT or 42)
minimize.Text = content.Visible and "-" or "+"
end)
local buttons = {}
for i, entry in ipairs({{"ESP", "ESP"}, {"Aim", "AIM"}, {"Trajectory", "ARC"}}) do
local key, caption = entry[1], entry[2]
local control = button(content, caption, 12 + (i - 1) * 108, 0, 102, 32)
buttons[key] = {button = control, caption = caption}
connect(control.Activated, function()
Config[key] = not Config[key]
if key == "Aim" and not Config.Aim then
Config.AutoBow = false
if stopAuto then stopAuto("Aim disabled") end
end
end)
end
local namesButton = button(content, "NAMES ON", 12, 42, 102, 30)
local partButton = button(content, "TARGET: TORSO", 120, 42, 210, 30)
connect(namesButton.Activated, function() Config.Names = not Config.Names end)
connect(partButton.Activated, function()
Config.TargetPart = Config.TargetPart == "Head" and "UpperTorso" or "Head"
end)
local fovLabel = textLabel(content, "AIM FOV: 180 px", 85, 26)
fovLabel.Size = UDim2.fromOffset(225, 26)
local less = button(content, "-", 254, 84, 32, 28)
local more = button(content, "+", 298, 84, 32, 28)
connect(less.Activated, function() Config.FOVRadius = math.max(40, Config.FOVRadius - 20) end)
connect(more.Activated, function() Config.FOVRadius = math.min(400, Config.FOVRadius + 20) end)
local arcButton = button(content, "ARC: LOW / FAST", 12, 124, 318, 30)
connect(arcButton.Activated, function() Config.PreferHighArc = not Config.PreferHighArc end)
local modeButton = button(content, "AIM: CAMERA", 12, 164, 156, 30)
local autoButton = button(content, "AUTO BOW OFF", 174, 164, 156, 30)
local smartButton = button(content, "SMART CHARGE ON", 12, 202, 156, 30)
local jumpButton = button(content, "JUMP LEAD ON", 174, 202, 156, 30)
connect(modeButton.Activated, function()
if not bowAdaptersReady then autoNote = "Silent: native adapter unavailable"; return end
Config.SilentAim = not Config.SilentAim
end)
connect(autoButton.Activated, function()
if not bowAdaptersReady then autoNote = "Auto: native adapter unavailable"; return end
Config.AutoBow = not Config.AutoBow
if Config.AutoBow then Config.Aim = true
elseif stopAuto then stopAuto("OFF") end
end)
connect(smartButton.Activated, function() Config.SmartCharge = not Config.SmartCharge end)
connect(jumpButton.Activated, function() Config.JumpPrediction = not Config.JumpPrediction end)
local status = textLabel(content, "Loading game adapters...", 241, 20)
local targetLabel = textLabel(content, "Enable AIM, then draw your bow", 263, 20)
local adapterLabel = textLabel(content, "Charge: waiting | Origin: fallback", 285, 18)
adapterLabel.TextSize = 11
local autoLabel = textLabel(content, "Auto: OFF", 307, 18)
autoLabel.TextSize = 11
textLabel(content, "Auto runs with this menu hidden.", 332, 17).TextSize = 11
textLabel(content, "Insert: hide/show menu. [X]: unload.", 350, 16).TextSize = 11
local dragging, dragStart, panelStart, dragInput
local dragHandle = make("TextButton", {
Position = UDim2.fromOffset(0, 0), Size = UDim2.new(1, -84, 0, 40),
BackgroundTransparency = 1, Text = "", AutoButtonColor = false,
}, panel)
connect(dragHandle.InputBegan, function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
dragging, dragStart, panelStart, dragInput = true, input.Position, panel.Position, input
end
end)
connect(UIS.InputChanged, function(input)
if not dragging then return end
if input.UserInputType ~= Enum.UserInputType.MouseMovement and input ~= dragInput then return end
local delta = input.Position - dragStart
local camera = Workspace.CurrentCamera
if not camera then return end
panel.Position = UDim2.fromOffset(
math.clamp(panelStart.X.Offset + delta.X, 0, math.max(0, camera.ViewportSize.X - PANEL_WIDTH)),
math.clamp(panelStart.Y.Offset + delta.Y, 0, math.max(0, camera.ViewportSize.Y - panel.AbsoluteSize.Y))
)
end)
connect(UIS.InputEnded, function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input == dragInput then dragging = false end
end)
local ring = make("Frame", {
AnchorPoint = Vector2.new(0.5, 0.5), Position = UDim2.fromScale(0.5, 0.5),
Size = UDim2.fromOffset(Config.FOVRadius * 2, Config.FOVRadius * 2),
BackgroundTransparency = 1, BorderSizePixel = 0,
}, gui)
make("UICorner", {CornerRadius = UDim.new(1, 0)}, ring)
make("UIStroke", {Color = Color3.fromRGB(79, 200, 211), Transparency = 0.55, Thickness = 1}, ring)
local aimDot = make("Frame", {
AnchorPoint = Vector2.new(0.5, 0.5), Size = UDim2.fromOffset(7, 7),
BackgroundColor3 = Color3.fromRGB(255, 219, 103), BorderSizePixel = 0, Visible = false,
}, gui)
rounded(aimDot, 4)
local modules = {}
local menuCamera
local function releaseMenuMouse()
if not menuCamera then return end
local previous = menuCamera
menuCamera = nil
local ok, err = pcall(previous.PopMouseUnlock, binding)
if not ok then warn("[Kingfisher] Mouse unlock cleanup failed: " .. tostring(err)) end
end
local function syncMenuMouse()
local desired = active and gui.Enabled and panel.Visible and modules.Camera or nil
if desired and (type(desired.PushMouseUnlock) ~= "function" or type(desired.PopMouseUnlock) ~= "function") then
desired = nil
end
if desired == menuCamera then return end
releaseMenuMouse()
if desired then
local ok, err = pcall(desired.PushMouseUnlock, binding)
if ok then menuCamera = desired
else warn("[Kingfisher] Native menu mouse control unavailable: " .. tostring(err)) end
end
end
table.insert(destructors, releaseMenuMouse)
local nativeDraw = false
local drawing = false
local drawStart, drawDuration = 0, 1
local lastTool
local heldFallback = false
local panelHovered = false
local selected, selectionTime = nil, -math.huge
local applyAim -- The native Release callback runs immediately before the bow computes its shot.
local autoHandler, autoOwned, autoReleaseResult
local firingContexts = setmetatable({}, {__mode = "k"})
local autoNext, autoLastClear, autoStarted = 0, 0, 0
connect(panel.MouseEnter, function() panelHovered = true end)
connect(panel.MouseLeave, function() panelHovered = false end)
local function setMenuVisible(visible)
if not active then return end
local wasVisible = gui.Enabled and panel.Visible
if visible and not wasVisible then mouseIconBeforeMenu = UIS.MouseIconEnabled end
if visible then
if stopAuto then stopAuto("Paused: menu open") end
gui.Enabled = true
content.Visible = true
panel.Size = UDim2.fromOffset(PANEL_WIDTH, PANEL_HEIGHT)
minimize.Text = "-"
local camera = Workspace.CurrentCamera
if camera then
panel.Position = UDim2.fromOffset(
math.clamp(panel.Position.X.Offset, 0, math.max(0, camera.ViewportSize.X - PANEL_WIDTH)),
math.clamp(panel.Position.Y.Offset, 0, math.max(0, camera.ViewportSize.Y - PANEL_HEIGHT))
)
end
end
panel.Visible = visible
minimize.Modal = visible
dragging, dragInput, panelHovered = false, nil, false
if visible then
UIS.MouseIconEnabled = true
else
UIS.MouseIconEnabled = mouseIconBeforeMenu
-- Removing Modal lets the game's camera/shift-lock control the mouse again.
end
syncMenuMouse()
end
connect(gui:GetPropertyChangedSignal("Enabled"), syncMenuMouse)
-- Register menu controls before loading adapters or building gameplay visuals.
connect(UIS.InputBegan, function(input)
if input.KeyCode ~= Enum.KeyCode.Insert then return end
if UIS:GetFocusedTextBox() or GuiService.MenuIsOpen then return end
setMenuVisible(not (gui.Enabled and panel.Visible))
end)
RunService:BindToRenderStep(menuBinding, Enum.RenderPriority.Camera.Value + 4, function()
if active and gui.Enabled and panel.Visible then UIS.MouseIconEnabled = true end
end)
setMenuVisible(true)
print("[Kingfisher] Menu ready. Insert hides/shows it.")
local function loadModule(path, key)
task.spawn(function()
local cursor = path[1]
for i = 2, #path do
cursor = cursor and cursor:WaitForChild(path[i], 12)
if not active or not cursor then return end
end
if not cursor:IsA("ModuleScript") then return end
local ok, value = pcall(require, cursor)
if not active then return end
if not ok or type(value) ~= "table" then
warn("[Kingfisher] " .. key .. " unavailable; using fallback.")
return
end
modules[key] = value
if key == "Camera" then syncMenuMouse() end
if key == "Controller" and type(value.OnViewEvent) == "function" then
local subscribed, disconnect = pcall(value.OnViewEvent, function(name, data)
if not active or type(data) ~= "table" then return end
if name == "Draw" then
lastTool = player.Character and player.Character:FindFirstChildOfClass("Tool")
drawing = data.on == true
selected, selectionTime = nil, -math.huge
if drawing then
drawStart = os.clock()
drawDuration = tonumber(data.time) or 1
end
elseif name == "Release" then
local ok, err = true, nil
if applyAim and type(data.charge) == "number" then
ok, err = pcall(applyAim, math.clamp(data.charge, 0, 1), true)
end
drawing, selected = false, nil
if not ok then warn("[Kingfisher] Release adjustment failed: " .. tostring(err)) end
end
end)
if subscribed and type(disconnect) == "function" then
nativeDraw = true
table.insert(destructors, disconnect)
end
end
if installBowAdapters then installBowAdapters() end
end)
end
loadModule({ReplicatedStorage, "Shared", "Weapons"}, "Weapons")
loadModule({ReplicatedStorage, "Shared", "Camera"}, "Camera")
loadModule({player, "PlayerScripts", "Combat", "Util"}, "Util")
loadModule({player, "PlayerScripts", "Combat", "Controller"}, "Controller")
loadModule({player, "PlayerScripts", "Combat", "Handlers", "Bow"}, "Bow")
loadModule({ReplicatedStorage, "Shared", "Combat"}, "Combat")
local fallbackBows = {
short_bow = {drawTime = 0.5, speedMin = 120, speedMax = 250, gravity = 55, radius = 0.3, range = 400},
longbow = {drawTime = 1.1, speedMin = 160, speedMax = 380, gravity = 32, radius = 0.28, range = 600},
}
local function bowInfo()
local character = player.Character
local tool = character and character:FindFirstChildOfClass("Tool")
if tool ~= lastTool then
drawing, heldFallback = false, false
selected, selectionTime = nil, -math.huge
lastTool = tool
end
if not tool then return nil end
local id = tool:GetAttribute("WeaponId")
local tuning = fallbackBows[id]
local weapons = modules.Weapons
if weapons and type(weapons.Get) == "function" then
local ok, definition = pcall(weapons.Get, id)
if ok and type(definition) == "table" and definition.kind == "Bow" then
tuning = definition.tuning or tuning
end
end
if not tuning then return nil end
return tool, tuning, id
end
local function chargeFor(tuning)
if drawing or (not nativeDraw and heldFallback) then
local duration = nativeDraw and drawDuration or (tuning.drawTime or 1)
return math.clamp((os.clock() - drawStart) / math.max(0.001, duration), 0, 1), true
end
return 1, false -- Idle visualization is explicitly a full-draw preview.
end
local function attribute(model, owner, key)
local value = model and model:GetAttribute(key)
if value == nil and owner then value = owner:GetAttribute(key) end
return value
end
local function isEnemy(model, owner)
if model == player.Character or owner == player or not model:IsDescendantOf(Workspace) then return false end
if attribute(model, owner, "Alive") == false then return false end
local humanoid = model:FindFirstChildOfClass("Humanoid")
if not humanoid or humanoid.Health <= 0 then return false end
local myMatch = attribute(player.Character, player, "MatchId")
local theirMatch = attribute(model, owner, "MatchId")
local myTeam = attribute(player.Character, player, "Team")
local theirTeam = attribute(model, owner, "Team")
if type(myMatch) == "string" and myMatch ~= "" then
return theirMatch == myMatch and theirTeam ~= nil and myTeam ~= nil and theirTeam ~= myTeam
end
return Config.IncludeTrainingDummies and CollectionService:HasTag(model, "TrainingDummy")
end
local records = {}
local function refreshTargets()
local visited, valid = {}, {}
local function visit(model, owner)
if not model or not model:IsA("Model") or visited[model] then return end
visited[model] = true
if not isEnemy(model, owner) then return end
local root = model:FindFirstChild("HumanoidRootPart")
local part = model:FindFirstChild(Config.TargetPart) or model:FindFirstChild("Torso")
or model:FindFirstChild("Head") or root
if not root or not root:IsA("BasePart") or not part or not part:IsA("BasePart") then return end
valid[model] = true
local head = model:FindFirstChild("Head")
local adornee = head and head:IsA("BasePart") and head or root
local record = records[model]
if not record then
local highlight = make("Highlight", {
Adornee = model, DepthMode = Enum.HighlightDepthMode.AlwaysOnTop,
FillColor = Color3.fromRGB(243, 87, 89), FillTransparency = 0.8,
OutlineColor = Color3.fromRGB(255, 146, 127), OutlineTransparency = 0.1,
}, visuals)
local billboard = make("BillboardGui", {
Adornee = adornee, AlwaysOnTop = true,
Size = UDim2.fromOffset(220, 42), StudsOffsetWorldSpace = Vector3.new(0, 2.4, 0),
MaxDistance = Config.MaxDistance,
}, gui)
local label = make("TextLabel", {
Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, TextSize = 12,
Font = Enum.Font.Code, TextColor3 = Color3.new(1, 1, 1),
TextStrokeTransparency = 0.25, Text = "",
}, billboard)
record = {highlight = highlight, billboard = billboard, label = label, model = model}
records[model] = record
end
record.owner, record.root, record.part = owner, root, part
record.humanoid = model:FindFirstChildOfClass("Humanoid")
record.billboard.Adornee = adornee
end
for _, other in ipairs(Players:GetPlayers()) do visit(other.Character, other) end
for _, tag in ipairs({"Combatant", "Bot", "TrainingDummy"}) do
for _, model in ipairs(CollectionService:GetTagged(tag)) do
if model:IsA("Model") then visit(model, Players:GetPlayerFromCharacter(model)) end
end
end
for model, record in pairs(records) do
if not valid[model] then
if selected and selected.record == record then selected, selectionTime = nil, -math.huge end
record.highlight:Destroy()
record.billboard:Destroy()
records[model] = nil
end
end
end
local function exclusionContext()
local list, seen = {}, {}
local function add(object)
if object and not seen[object] then
seen[object] = true
table.insert(list, object)
end
end
add(visuals)
add(player.Character)
for _, name in ipairs({"FX", "Projectiles"}) do
local folder = Workspace:FindFirstChild(name)
add(folder)
end
local myMatch = attribute(player.Character, player, "MatchId")
local myTeam = attribute(player.Character, player, "Team")
local function teammate(model, owner)
if model and model:IsA("Model") and myMatch ~= nil and myMatch ~= "" and myTeam ~= nil
and attribute(model, owner, "MatchId") == myMatch
and attribute(model, owner, "Team") == myTeam then
add(model)
end
end
for _, other in ipairs(Players:GetPlayers()) do teammate(other.Character, other) end
for _, tag in ipairs({"Combatant", "Bot"}) do
for _, model in ipairs(CollectionService:GetTagged(tag)) do teammate(model, nil) end
end
return {list = list, seen = seen, params = {}}
end
local function exclusions(extra, context)
context = context or exclusionContext()
local key = extra or false
if context.params[key] then return context.params[key] end
local list = table.clone(context.list)
if extra and not context.seen[extra] then table.insert(list, extra) end
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = list
params.IgnoreWater = true
context.params[key] = params
return params
end
local function shotOrigin(tool, params)
local util = modules.Util
if util and type(util.ShotOrigin) == "function" then
local ok, origin = pcall(util.ShotOrigin, tool, "Muzzle")
if ok and typeof(origin) == "Vector3" then return origin end
end
local character = player.Character
local head = character and (character:FindFirstChild("Head") or character:FindFirstChild("HumanoidRootPart"))
if not head or not head:IsA("BasePart") then return nil end
local fallback = head.Position
if head.Name == "HumanoidRootPart" then fallback = fallback + Vector3.new(0, 1.5, 0) end
local muzzle = tool:FindFirstChild("Muzzle", true)
local handle = tool:FindFirstChild("Handle")
local point = muzzle and muzzle:IsA("Attachment") and muzzle.WorldPosition
or (handle and handle:IsA("BasePart") and handle.Position) or fallback
if (point - fallback).Magnitude > 7 then return fallback end
local delta = point - fallback
if delta.Magnitude > 0.001 and Workspace:Raycast(fallback, delta, params) then return fallback end
return point
end
local function shotDirection(origin, params)
local util = modules.Util
if util and type(util.AimDirection) == "function" then
local ok, direction = pcall(util.AimDirection, origin)
if ok and typeof(direction) == "Vector3" and direction.Magnitude > 0.001 then return direction.Unit end
end
local camera = Workspace.CurrentCamera
if not camera then return nil end
local hit = Workspace:Raycast(camera.CFrame.Position, camera.CFrame.LookVector * 1000, params)
local point = hit and hit.Position or camera.CFrame.Position + camera.CFrame.LookVector * 1000
local delta = point - origin
return delta.Magnitude > 0.001 and delta.Unit or camera.CFrame.LookVector
end
-- Original numeric solver. Coefficients are in ascending powers.
local function finite(x)
return type(x) == "number" and x == x and math.abs(x) < math.huge
end
local function polynomialValue(c, x)
local y = c[#c]
for i = #c - 1, 1, -1 do y = y * x + c[i] end
return y
end
local function polynomialScale(c, x)
local y = math.abs(c[#c])
for i = #c - 1, 1, -1 do y = y * math.abs(x) + math.abs(c[i]) end
return y
end
local function polynomialRoots(c, lo, hi)
while #c > 1 and c[#c] == 0 do table.remove(c) end
local magnitude = 0
for _, value in ipairs(c) do magnitude = math.max(magnitude, math.abs(value)) end
if magnitude == 0 or #c == 1 then return {} end
for i = 1, #c do c[i] = c[i] / magnitude end
if #c == 2 then
local root = -c[1] / c[2]
return root >= lo and root <= hi and {root} or {}
end
local derivative = {}
for i = 2, #c do derivative[i - 1] = (i - 1) * c[i] end
local boundaries = {lo}
for _, value in ipairs(polynomialRoots(derivative, lo, hi)) do
if value > lo and value < hi then table.insert(boundaries, value) end
end
table.insert(boundaries, hi)
table.sort(boundaries)
local roots = {}
local function add(root)
for _, existing in ipairs(roots) do
if math.abs(existing - root) < 1e-8 then return end
end
table.insert(roots, root)
end
for _, x in ipairs(boundaries) do
if math.abs(polynomialValue(c, x)) <= 1e-12 * math.max(1e-30, polynomialScale(c, x)) then
add(x)
end
end
for i = 1, #boundaries - 1 do
local a, b = boundaries[i], boundaries[i + 1]
local fa, fb = polynomialValue(c, a), polynomialValue(c, b)
if (fa < 0 and fb > 0) or (fa > 0 and fb < 0) then
for _ = 1, 44 do
local middle = (a + b) * 0.5
local fm = polynomialValue(c, middle)
if (fa < 0 and fm < 0) or (fa > 0 and fm > 0) then
a, fa = middle, fm
else
b = middle
end
end
add((a + b) * 0.5)
end
end
table.sort(roots)
return roots
end
local function intercepts(origin, target, velocity, speed, gravity, lifetime, targetAcceleration)
if not finite(speed) or speed <= 0 or not finite(lifetime) or lifetime <= 0 then return {} end
targetAcceleration = targetAcceleration or Vector3.zero
local relativeGravity = gravity - targetAcceleration
local offset = target - origin
if offset.Magnitude < 0.001 then return {} end
local c = {
offset:Dot(offset),
2 * offset:Dot(velocity),
velocity:Dot(velocity) - offset:Dot(relativeGravity) - speed * speed,
-velocity:Dot(relativeGravity),
0.25 * relativeGravity:Dot(relativeGravity),
}
for i = 1, #c do
c[i] = c[i] * lifetime ^ (i - 1)
if not finite(c[i]) then return {} end
end
local solutions = {}
for _, x in ipairs(polynomialRoots(c, 0.000001 / lifetime, 1)) do
local time = x * lifetime
local launch = offset / time + velocity - 0.5 * relativeGravity * time
if finite(launch.Magnitude) and launch.Magnitude > 0
and math.abs(launch.Magnitude - speed) <= math.max(0.0001, speed * 0.00001) then
table.insert(solutions, {
time = time,
direction = launch.Unit,
impact = target + velocity * time + 0.5 * targetAcceleration * time * time,
})
end
end
return solutions
end
local function parameters(tuning, charge)
local minimum = tonumber(tuning.speedMin or tuning.speed) or 120
local maximum = tonumber(tuning.speedMax or tuning.speed) or minimum
local speed = minimum + (maximum - minimum) * charge
return speed, Vector3.new(0, -(tonumber(tuning.gravity) or 55), 0), tonumber(tuning.radius) or 0.3
end
local function trace(origin, direction, speed, gravity, duration, params, radius, collect)
local position, velocity = origin, direction * speed
local points = collect and {origin} or nil
local age, traveled = 0, 0
while age < duration - 1e-7 do
local dt = math.min(Config.CastStep, duration - age)
local delta = velocity * dt + 0.5 * gravity * dt * dt
if traveled + delta.Magnitude > Config.MaxTravel then return points, nil, true end
local hit
if delta.Magnitude > 0.0001 then
if radius > 0 then
hit = Workspace:Spherecast(position, radius, delta, params)
else
hit = Workspace:Raycast(position, delta, params)
end
end
if hit then
if points then table.insert(points, position + delta.Unit * hit.Distance) end
return points, hit, false
end
position = position + delta
velocity = velocity + gravity * dt
traveled = traveled + delta.Magnitude
age = age + dt
if points then table.insert(points, position) end
end
return points, nil, false
end
-- Landing is a bounded estimate on nearby, nearly level static ground. A ledge,
-- moving platform or slope keeps the airborne model instead of inventing a floor.
local function estimateLanding(record, velocity, targetGravity)
local root, humanoid = record.root, record.humanoid
local standingHeight = root.Size.Y * 0.5 + math.max(0, humanoid.HipHeight)
if humanoid.RigType == Enum.HumanoidRigType.R6 then
local leg = record.model:FindFirstChild("Left Leg") or record.model:FindFirstChild("Right Leg")
if not leg or not leg:IsA("BasePart") then return nil end
standingHeight = standingHeight + leg.Size.Y
end
local excluded, seen = {visuals}, {[visuals] = true}
local function exclude(model)
if model and not seen[model] then seen[model] = true; table.insert(excluded, model) end
end
exclude(record.model)
exclude(player.Character)
for _, other in ipairs(Players:GetPlayers()) do exclude(other.Character) end
for model in pairs(records) do exclude(model) end
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = excluded
params.IgnoreWater, params.RespectCanCollide = true, true
params.CollisionGroup = root.CollisionGroup
local rootPosition = root.Position
local function groundAt(x, z)
local hit = Workspace:Raycast(Vector3.new(x, rootPosition.Y + 1, z), Vector3.new(0, -192, 0), params)
if not hit or hit.Normal.Y < 0.98 then return nil end
if hit.Instance:IsA("BasePart") and not hit.Instance.Anchored then return nil end
return hit.Position.Y
end
local firstGround = groundAt(rootPosition.X, rootPosition.Z)
if firstGround == nil then return nil end
local clearance = rootPosition.Y - firstGround - standingHeight
if clearance < -0.5 then return nil end
local landingTime = (velocity.Y + math.sqrt(velocity.Y * velocity.Y + 2 * targetGravity * math.max(0, clearance))) / targetGravity
if not finite(landingTime) or landingTime < 0 or landingTime > Config.MaxLifetime + 1 then return nil end
local lastGround = groundAt(rootPosition.X + velocity.X * landingTime, rootPosition.Z + velocity.Z * landingTime)
if lastGround == nil or math.abs(lastGround - firstGround) > 0.5 then return nil end
-- Recompute for the checked landing surface; the small allowed height change
-- limits extrapolation error without tracing a whole character trajectory.
clearance = rootPosition.Y - lastGround - standingHeight
if clearance < -0.5 then return nil end
landingTime = (velocity.Y + math.sqrt(velocity.Y * velocity.Y + 2 * targetGravity * math.max(0, clearance))) / targetGravity
return landingTime, lastGround + standingHeight + record.part.Position.Y - rootPosition.Y
end
local function targetMotion(record, velocity)
local position, rootPosition = record.part.Position, record.root.Position
local humanoid = record.humanoid
local state = humanoid and humanoid:GetState()
local targetGravity = Workspace.Gravity
local now = os.clock()
local cached = record.jumpMotion
if cached and now - cached.sampledAt < 0.05 and cached.root == record.root and cached.part == record.part
and cached.position == position and cached.rootPosition == rootPosition and cached.velocity == velocity
and cached.state == state and cached.gravity == targetGravity and cached.enabled == Config.JumpPrediction then
return cached
end
local motion = {
position = position, rootPosition = rootPosition, velocity = velocity, acceleration = Vector3.zero,
root = record.root, part = record.part, sampledAt = now, state = state,
gravity = targetGravity, enabled = Config.JumpPrediction,
}
if Config.JumpPrediction and humanoid and finite(targetGravity) and targetGravity > 0
and (state == Enum.HumanoidStateType.Jumping or state == Enum.HumanoidStateType.Freefall) then
motion.acceleration = Vector3.new(0, -targetGravity, 0)
motion.landingTime, motion.landingY = estimateLanding(record, velocity, targetGravity)
end
record.jumpMotion = motion
return motion
end
local function motionIntercepts(origin, motion, speed, gravity, lifetime, lead)
lead = finite(lead) and math.max(0, lead) or 0
local solutions = {}
local remainingAirTime = motion.landingTime and math.max(0, motion.landingTime - lead) or lifetime
if remainingAirTime > 0 then
local position = motion.position + motion.velocity * lead + 0.5 * motion.acceleration * lead * lead
local velocity = motion.velocity + motion.acceleration * lead
solutions = intercepts(origin, position, velocity, speed, gravity, math.min(lifetime, remainingAirTime), motion.acceleration)
end
if motion.landingTime then
local velocity = Vector3.new(motion.velocity.X, 0, motion.velocity.Z)
local position = Vector3.new(motion.position.X, motion.landingY, motion.position.Z) + velocity * lead
for _, solution in ipairs(intercepts(origin, position, velocity, speed, gravity, lifetime)) do
if solution.time + lead >= motion.landingTime - 0.00001 then
local duplicate = false
for _, existing in ipairs(solutions) do
if math.abs(solution.time - existing.time) < 0.00001 then duplicate = true; break end
end
if not duplicate then table.insert(solutions, solution) end
end
end
end
table.sort(solutions, function(a, b) return a.time < b.time end)
return solutions
end
local function solveRecord(record, origin, speed, gravity)
if not record.model.Parent or not record.part.Parent or not record.root.Parent
or not isEnemy(record.model, record.owner) then return {} end
local velocity = record.root.AssemblyLinearVelocity
if not finite(velocity.Magnitude) or velocity.Magnitude > 1000 then return {} end
local motion = targetMotion(record, velocity)
local solutions = motionIntercepts(origin, motion, speed, gravity, Config.MaxLifetime, Config.ExtraLeadSeconds)
if Config.PreferHighArc then
local reverse = {}
for i = #solutions, 1, -1 do table.insert(reverse, solutions[i]) end
return reverse
end
return solutions
end
local function selectTarget(origin, tuning, speed, gravity, radius, force, context)
local camera = Workspace.CurrentCamera
if not camera then selected = nil; return nil end
local now = os.clock()
if not force and now - selectionTime < Config.SelectInterval then return selected end
selectionTime = now
local range = math.min(Config.MaxDistance, tonumber(tuning.range) or Config.MaxDistance)
local function check(record)
if not record.part.Parent or not isEnemy(record.model, record.owner)
or (record.part.Position - origin).Magnitude > range then return nil end
if Config.SilentAim then
local point, onScreen = camera:WorldToViewportPoint(record.part.Position)
if not onScreen or point.Z <= 0
or (Vector2.new(point.X, point.Y) - camera.ViewportSize * 0.5).Magnitude > Config.FOVRadius then return nil end
end
local params = exclusions(record.model, context)
for _, solution in ipairs(solveRecord(record, origin, speed, gravity)) do
local pitch = math.asin(math.clamp(solution.direction.Y, -1, 1))
if pitch >= math.rad(-80) and pitch <= math.rad(78) then
local _, hit, exhausted = trace(origin, solution.direction, speed, gravity, solution.time, params, radius, false)
if not hit and not exhausted then return {record = record, solution = solution} end
end
end
return nil
end
-- FOV is an acquisition rule. Ballistic camera elevation must not break a draw lock.
if selected then
local retained = check(selected.record)
if retained then selected = retained; return selected end
end
local center = camera.ViewportSize * 0.5
local candidates = {}
for _, record in pairs(records) do
if record.part.Parent and isEnemy(record.model, record.owner) then
local projected, onScreen = camera:WorldToViewportPoint(record.part.Position)
local screenDistance = (Vector2.new(projected.X, projected.Y) - center).Magnitude
local distance = (record.part.Position - origin).Magnitude
if onScreen and projected.Z > 0 and screenDistance <= Config.FOVRadius and distance <= range then
table.insert(candidates, {record = record, score = screenDistance})
end
end
end
table.sort(candidates, function(a, b) return a.score < b.score end)
selected = nil
for i = 1, math.min(#candidates, Config.MaxCandidates) do
local choice = check(candidates[i].record)
if choice then selected = choice; return choice end
end
return nil
end
local function allowedToAim()
if renderFailed or not windowFocused or not Config.Aim or not (drawing or (not nativeDraw and heldFallback))
or UIS:GetFocusedTextBox() or GuiService.MenuIsOpen or (panel.Visible and panelHovered) then return false end
local character = player.Character
local humanoid = character and character:FindFirstChildOfClass("Humanoid")
return humanoid ~= nil and humanoid.Health > 0 and attribute(character, player, "Alive") ~= false
end
-- Make the camera's 1000-stud endpoint lie on the desired muzzle ray.
local function cameraDirection(origin, direction, cameraPosition)
local offset = cameraPosition - origin
local along = offset:Dot(direction)
local perpendicularSquared = math.max(0, offset:Dot(offset) - along * along)
local distance = along + math.sqrt(math.max(1, 1000 * 1000 - perpendicularSquared))
return (origin + direction * distance - cameraPosition).Unit
end
local function setView(direction)
local camera = Workspace.CurrentCamera
if not camera or not finite(direction.Magnitude) or direction.Magnitude < 0.001 then return end
local yaw = math.atan2(-direction.X, -direction.Z)
local pitch = math.clamp(math.asin(math.clamp(direction.Y, -1, 1)), math.rad(-80), math.rad(78))
local nativeCamera = modules.Camera
if nativeCamera and type(nativeCamera.SetLook) == "function" then pcall(nativeCamera.SetLook, yaw, pitch) end
camera.CFrame = CFrame.new(camera.CFrame.Position) * CFrame.fromEulerAnglesYXZ(pitch, yaw, 0)
end
applyAim = function(forcedCharge, forceCheck, context)
if not active or not allowedToAim() then return nil end
local tool, tuning = bowInfo()
if not tool or not allowedToAim() then return nil end
context = context or exclusionContext()
local charge = forcedCharge
if charge == nil then charge = chargeFor(tuning) end
local speed, gravity, radius = parameters(tuning, charge)
local params = exclusions(nil, context)
local origin = shotOrigin(tool, params)
if not origin then return nil end
local choice = selectTarget(origin, tuning, speed, gravity, radius, forceCheck, context)
if not choice then return nil end
if Config.SilentAim then return bowAdaptersReady and choice or nil end
local camera = Workspace.CurrentCamera
local originalView = camera.CFrame
local function reject()
setView(originalView.LookVector)
camera.CFrame = originalView
selected = nil
return nil
end
local solution
-- Re-evaluate because the game's third-person ShotOrigin depends on camera direction.
for _ = 1, 3 do
origin = shotOrigin(tool, params)
if not origin then return reject() end
local roots = solveRecord(choice.record, origin, speed, gravity)
solution = roots[1]
if not solution then return reject() end
-- Preserve the collision-approved arc if several roots exist.
for _, candidate in ipairs(roots) do
if math.abs(candidate.time - choice.solution.time) < math.abs(solution.time - choice.solution.time) then
solution = candidate
end
end
local launchPitch = math.asin(math.clamp(solution.direction.Y, -1, 1))
if launchPitch < math.rad(-80) or launchPitch > math.rad(78) then return reject() end
setView(cameraDirection(origin, solution.direction, camera.CFrame.Position))
local actual = shotDirection(origin, params)
if actual and actual:Dot(solution.direction) < 0.999999 then
local corrected = camera.CFrame.LookVector + solution.direction - actual
if corrected.Magnitude > 0.001 then setView(corrected.Unit) end
end
end
local finalOrigin = shotOrigin(tool, params)
if not finalOrigin then return reject() end
local actualDirection = shotDirection(finalOrigin, params)
if not actualDirection then return reject() end
local endpoint = finalOrigin + actualDirection * speed * solution.time
+ gravity * (0.5 * solution.time * solution.time)
local size = choice.record.part.Size
local tolerance = radius + math.max(0.25, math.min(size.X, size.Y, size.Z) * 0.35)
if (endpoint - solution.impact).Magnitude > tolerance then return reject() end
if forceCheck or not choice.finalCheck or os.clock() - choice.finalCheck >= Config.SelectInterval then
local _, hit, exhausted = trace(finalOrigin, actualDirection, speed, gravity,
solution.time, exclusions(choice.record.model, context), radius, false)
if hit or exhausted then return reject() end
choice.finalCheck = os.clock()
end
choice.solution = solution
return choice
end
local function clearRecordShot(record, origin, tuning, charge, context)
if not record or not record.part.Parent or not isEnemy(record.model, record.owner) then return nil end
if (record.part.Position - origin).Magnitude > math.min(Config.MaxDistance, tonumber(tuning.range) or Config.MaxDistance) then return nil end
local speed, gravity, radius = parameters(tuning, charge)
for _, solution in ipairs(solveRecord(record, origin, speed, gravity)) do
local pitch = math.asin(math.clamp(solution.direction.Y, -1, 1))
if pitch >= math.rad(-80) and pitch <= math.rad(78) then
local _, hit, exhausted = trace(origin, solution.direction, speed, gravity,
solution.time, exclusions(record.model, context), radius, false)
if not hit and not exhausted then return {record = record, solution = solution} end
end
end
return nil
end
local function findShot(tool, tuning, charge, context)
context = context or exclusionContext()
local origin = shotOrigin(tool, exclusions(nil, context))
if not origin then return nil end
local speed, gravity, radius = parameters(tuning, charge)
return selectTarget(origin, tuning, speed, gravity, radius, true, context)
end
stopAuto = function(reason)
local owned = autoOwned
autoOwned = nil
if owned then
-- Cancel before releasing the native input; a release alone would fire.
owned.bufferedAt = nil
if owned.drawing then
local ok, err = pcall(owned.CancelDraw, owned)
if not ok or owned.drawing then
owned.drawing = false -- Never turn a failed cancellation into a release shot.
if not ok then warn("[Kingfisher] Native draw cancellation failed: " .. tostring(err)) end
end
end
owned.m1Down = false
local equipped = player.Character and player.Character:FindFirstChildOfClass("Tool")
if owned.ctx and owned.ctx.tool == equipped and modules.Controller then
pcall(modules.Controller.Dispatch, "Primary", false)
end
end
autoNote = "Auto: " .. (Config.AutoBow and (reason or "OFF") or "OFF")
end
table.insert(destructors, function() stopAuto("OFF") end)
local bowHookCleanup
installBowAdapters = function()
if not active or bowHookCleanup then return end
local bow, util, controller = modules.Bow, modules.Util, modules.Controller
if not bow or not util or not controller or not nativeDraw
or type(bow.Update) ~= "function" or type(bow.Fire) ~= "function"
or type(bow.CancelDraw) ~= "function" or type(bow.Charge) ~= "function"
or type(util.AssistDirection) ~= "function" or type(controller.Dispatch) ~= "function" then return end
local oldUpdate, oldFire, oldAssist = bow.Update, bow.Fire, util.AssistDirection
local blockedAutoShot = {}
local updateWrapper, fireWrapper, assistWrapper
updateWrapper = function(self, ...)
if active and self.ctx then
local equipped = player.Character and player.Character:FindFirstChildOfClass("Tool")
if self.ctx.tool == equipped then autoHandler = self end
end
return oldUpdate(self, ...)
end
fireWrapper = function(self, ...)
local equipped = player.Character and player.Character:FindFirstChildOfClass("Tool")
if not active or not self.drawing or not self.ctx or self.ctx.tool ~= equipped then
return oldFire(self, ...)
end
local assisted = Config.Aim and windowFocused and not renderFailed
and not UIS:GetFocusedTextBox() and not GuiService.MenuIsOpen and not panel.Visible
local charge = self:Charge()
local automatic = autoOwned == self
if automatic then autoReleaseResult = false end
local choice
if assisted then
if Config.SilentAim then choice = findShot(equipped, self.tuning, charge)
else choice = applyAim(charge, true) end
end
if automatic and not choice then
autoReleaseResult = false
stopAuto("Waiting for a clear shot")
return
end
local thread = coroutine.running()
local previous = firingContexts[thread]
local shotScope
if assisted and (Config.SilentAim or automatic) and choice then
shotScope = {record = choice.record, tuning = self.tuning, charge = charge, tool = equipped, automatic = automatic}
firingContexts[thread] = shotScope
else firingContexts[thread] = nil end
local result = table.pack(pcall(oldFire, self, ...))
firingContexts[thread] = previous
if not result[1] and result[2] == blockedAutoShot then
self.bufferedAt = nil
pcall(self.CancelDraw, self)
self.m1Down = false
autoOwned, autoReleaseResult = nil, false
autoNote = "Auto: canceled; shot path changed"
return
end
if not result[1] then
if automatic then
stopAuto("Native release failed")
Config.AutoBow = false
autoNote = "Auto: ERROR; see output and re-enable"
end
error(result[2], 0)
end
if automatic then
autoReleaseResult = shotScope ~= nil and shotScope.used == true
if not autoReleaseResult then autoOwned = nil; autoNote = "Auto: native release canceled" end
end
return table.unpack(result, 2, result.n)
end
assistWrapper = function(origin, direction, preservePitch, ...)
local scope = firingContexts[coroutine.running()]
local equipped = player.Character and player.Character:FindFirstChildOfClass("Tool")
if scope and scope.automatic and (not active or renderFailed or not windowFocused
or not Config.Aim or not Config.AutoBow or panel.Visible or GuiService.MenuIsOpen
or UIS:GetFocusedTextBox() or scope.tool ~= equipped or scope.tool.Parent ~= player.Character
or typeof(origin) ~= "Vector3") then
error(blockedAutoShot, 0)
end
if active and not renderFailed and Config.Aim and scope and (Config.SilentAim or scope.automatic)
and scope.tool == equipped and scope.tool.Parent == player.Character
and typeof(origin) == "Vector3" then
-- The bow supplies its actual muzzle origin here, after its Release event.
local ok, choice = pcall(function()
return clearRecordShot(scope.record, origin, scope.tuning, scope.charge, exclusionContext())
end)
if ok and choice then scope.used = true; return choice.solution.direction end
if scope.automatic then error(blockedAutoShot, 0) end
end
return oldAssist(origin, direction, preservePitch, ...)
end
local function restore()
if bow.Update == updateWrapper then bow.Update = oldUpdate end
if bow.Fire == fireWrapper then bow.Fire = oldFire end
if util.AssistDirection == assistWrapper then util.AssistDirection = oldAssist end
end
local ok, err = pcall(function()
bow.Update, bow.Fire, util.AssistDirection = updateWrapper, fireWrapper, assistWrapper
end)
if not ok then
pcall(restore)
autoNote = "Native bow adapter unavailable"
warn("[Kingfisher] Bow adapter could not be installed: " .. tostring(err))
return
end
bowHookCleanup = restore
bowAdaptersReady = true
table.insert(destructors, function()
table.clear(firingContexts)
autoHandler = nil
bowAdaptersReady = false
restore()
end)
end
installBowAdapters()
local function readyToRelease(charge, choice, tuning, weaponId)
if not choice then return false end
if charge >= 0.995 then return true end
if not Config.SmartCharge or charge < Config.AutoMinCharge or choice.solution.time > Config.AutoMaxFlight then return false end
local maximum = tonumber(tuning.damage) or 0
local minimum = tonumber(tuning.damageMin) or maximum
local damage = minimum + (maximum - minimum) * charge
local combat = modules.Combat
if combat and type(combat.DrawnShot) == "function" then
local ok, amount = pcall(combat.DrawnShot, tuning, charge)
if ok and type(amount) == "number" then damage = amount end
end
if modules.Util and type(modules.Util.ItemBonus) == "function" then
local ok, bonus = pcall(modules.Util.ItemBonus, weaponId)
if ok and finite(bonus) and bonus > 0 then damage = damage * bonus end
end
-- This is a base-damage estimate; armor and server-side modifiers are not known.
local humanoid = choice.record.humanoid
return humanoid ~= nil and humanoid.Health > 0 and damage >= humanoid.Health
end
local function updateAutoBow(now, tool, tuning, weaponId)
local character = player.Character
local humanoid = character and character:FindFirstChildOfClass("Humanoid")
local blocked = not active or renderFailed or not Config.AutoBow or not Config.Aim or not bowAdaptersReady
or not windowFocused or panel.Visible or GuiService.MenuIsOpen or UIS:GetFocusedTextBox()
or not tool or not humanoid or humanoid.Health <= 0 or attribute(character, player, "Alive") == false
or UIS:IsMouseButtonPressed(Enum.UserInputType.MouseButton1)
if blocked then
if autoOwned then stopAuto("Paused")
elseif Config.AutoBow then autoNote = "Auto: paused; hide menu, release LMB" end
return
end
local handler = autoHandler
if not handler or not handler.ctx or handler.ctx.tool ~= tool then
if autoOwned then stopAuto("Weapon changed") end
autoNote = "Auto: waiting for native bow; re-equip"
return
end
if autoOwned and autoOwned ~= handler then stopAuto("Weapon changed") end
if now < autoNext then return end
autoNext = now + Config.AutoInterval
local util = modules.Util
if type(util.CanAct) == "function" then
local ok, canAct = pcall(util.CanAct)
if not ok or not canAct then stopAuto("Waiting until bow can act"); return end
end
if type(util.IsMouseUnlocked) == "function" then
local ok, unlocked = pcall(util.IsMouseUnlocked)
if ok and unlocked then stopAuto("Paused: game menu open"); return end
end
if not autoOwned then
if handler.drawing then autoNote = "Auto: manual draw"; return end
local plan = findShot(tool, tuning, 1)
if not plan then autoNote = "Auto: no clear target in FOV"; return end
autoOwned, autoStarted, autoLastClear = handler, now, now
local ok = pcall(modules.Controller.Dispatch, "Primary", true)
if not ok or not handler.drawing then
stopAuto("Waiting for cooldown/ammo")
autoNext = now + 0.2
return
end
selected = plan
selectionTime = -math.huge
end
if not handler.drawing then stopAuto("Ready"); return end
local charge = math.clamp(handler:Charge(), 0, 1)
local choice = findShot(tool, tuning, charge)
if choice then autoLastClear = now end
if not choice and now - autoLastClear > Config.AutoLostTargetGrace then
-- A low-charge bow may be out of range; keep drawing if full charge still reaches.
if not findShot(tool, tuning, 1) then stopAuto("Target lost or blocked"); return end
autoLastClear = now
end
if now - autoStarted > math.max(Config.AutoMaxHold, (tuning.drawTime or 1) + 0.5) then
stopAuto("Charge timed out")
return
end
if readyToRelease(charge, choice, tuning, weaponId) then
autoReleaseResult = nil
local ok, err = pcall(modules.Controller.Dispatch, "Primary", false)
if not ok then stopAuto("Release failed"); warn("[Kingfisher] Auto release: " .. tostring(err)); return end
if autoReleaseResult == false then autoNext = now + 0.2; return end
if handler.drawing then stopAuto("Release was not accepted"); return else autoOwned = nil end
autoNote = "Auto: released; waiting for cooldown"
autoNext = now + 0.1
else
autoNote = string.format("Auto: charging %d%% | %s", math.floor(charge * 100), choice and "clear shot" or "waiting for range")
end
end
local trajectoryParts = {}
local function trajectoryPart()
return make("Part", {
Name = "Arc", Anchored = true, CanCollide = false, CanTouch = false, CanQuery = false,
CastShadow = false, Material = Enum.Material.Neon, Transparency = 1,
Size = Vector3.new(0.065, 0.065, 1),
}, visuals)
end
for _ = 1, 72 do table.insert(trajectoryParts, trajectoryPart()) end
local impactMarker = make("Part", {
Name = "PredictedImpact", Shape = Enum.PartType.Ball, Size = Vector3.new(0.45, 0.45, 0.45),
Anchored = true, CanCollide = false, CanTouch = false, CanQuery = false,
CastShadow = false, Material = Enum.Material.Neon, Transparency = 1,
}, visuals)
local function hideTrajectory()
for _, part in ipairs(trajectoryParts) do part.Transparency = 1 end
impactMarker.Transparency = 1
end
local function displayTrajectory(points, blocked)
if not points or #points < 2 then hideTrajectory(); return end
local count = math.min(#trajectoryParts, #points - 1)
local color = blocked and Color3.fromRGB(255, 125, 83) or Color3.fromRGB(67, 220, 208)
for i, part in ipairs(trajectoryParts) do
if i <= count then
local a = points[math.floor((i - 1) * (#points - 1) / count) + 1]
local b = points[math.floor(i * (#points - 1) / count) + 1]
local distance = (b - a).Magnitude
if distance > 0.001 then
part.Size = Vector3.new(0.065, 0.065, distance)
part.CFrame = CFrame.lookAt((a + b) * 0.5, b)
part.Color, part.Transparency = color, 0.12
else part.Transparency = 1 end
else part.Transparency = 1 end
end
impactMarker.Position = points[#points]
impactMarker.Color, impactMarker.Transparency = color, 0.15
end
connect(UIS.InputBegan, function(input, processed)
if renderFailed or processed or UIS:GetFocusedTextBox() then return end
if input.UserInputType == Enum.UserInputType.MouseButton1 and not nativeDraw
and not (panel.Visible and panelHovered) then
local tool, tuning = bowInfo()
if tool then
heldFallback = true
drawStart, drawDuration = os.clock(), tuning.drawTime or 1
selected, selectionTime = nil, -math.huge
end
end
end)
connect(UIS.InputEnded, function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
local ok, err = true, nil
if not nativeDraw and heldFallback then ok, err = pcall(applyAim, nil, true) end
heldFallback = false
if not nativeDraw then selected = nil end
if not ok then warn("[Kingfisher] Estimated release adjustment failed: " .. tostring(err)) end
end
end)
connect(UIS.WindowFocusReleased, function()
windowFocused = false
stopAuto("Paused: window unfocused")
drawing, heldFallback, selected = false, false, nil
dragging = false
end)
connect(UIS.WindowFocused, function() windowFocused = true end)
connect(player.CharacterAdded, function()
stopAuto("Respawned")
autoHandler = nil
drawing, heldFallback, selected, lastTool = false, false, nil, nil
selectionTime = -math.huge
end)
local function mathTests()
local zero = Vector3.zero
local function test(name, target, velocity, speed, gravity, lifetime, expected)
local roots = intercepts(zero, target, velocity, speed, gravity, lifetime)
assert(#roots == #expected, name .. ": wrong root count " .. tostring(#roots))
for i, solution in ipairs(roots) do
assert(math.abs(solution.time - expected[i]) < 0.001, name .. ": wrong time")
local endpoint = solution.direction * speed * solution.time + gravity * (0.5 * solution.time ^ 2)
assert((endpoint - target - velocity * solution.time).Magnitude < 0.01, name .. ": endpoint miss")
end
end
test("linear", Vector3.new(100, 0, 0), Vector3.new(10, 0, 0), 50, zero, 10, {2.5})
test("outrunning", Vector3.new(100, 0, 0), Vector3.new(60, 0, 0), 50, zero, 10, {})
test("two arcs", Vector3.new(100, 0, 0), zero, 50, Vector3.new(0, -10, 0), 12, {2.0430964, 9.7890631})
test("tangent", Vector3.new(250, 0, 0), zero, 50, Vector3.new(0, -10, 0), 12, {7.0710678})
test("unreachable", Vector3.new(251, 0, 0), zero, 50, Vector3.new(0, -10, 0), 12, {})
test("lifetime", Vector3.new(100, 0, 0), zero, 50, Vector3.new(0, -10, 0), 5, {2.0430964})
test("coincident", zero, zero, 50, zero, 5, {})
test("zero speed", Vector3.new(100, 0, 0), zero, 0, zero, 5, {})
print("[Kingfisher] 8 ballistic tests passed.")
return true
end
local nextRefresh, nextTrajectory, nextUI = 0, 0, 0
local function render()
if not active or renderFailed then return end
local now = os.clock()
local camera = Workspace.CurrentCamera
if not camera then return end
if now >= nextRefresh then refreshTargets(); nextRefresh = now + Config.TargetRefresh end
local tool, tuning, id = bowInfo()
updateAutoBow(now, tool, tuning, id)
local charge, isDrawing = 1, false
local choice, castContext
if tool then
charge, isDrawing = chargeFor(tuning)
if allowedToAim() then
castContext = exclusionContext()
choice = applyAim(nil, false, castContext)
end
else selected = nil end
if not allowedToAim() then selected = nil end
ring.Visible = Config.Aim and tool ~= nil and not GuiService.MenuIsOpen
ring.Position = UDim2.fromOffset(camera.ViewportSize.X * 0.5, camera.ViewportSize.Y * 0.5)
ring.Size = UDim2.fromOffset(Config.FOVRadius * 2, Config.FOVRadius * 2)
aimDot.Visible = false
if choice then
local point, visible = camera:WorldToViewportPoint(choice.solution.impact)
if visible then aimDot.Position = UDim2.fromOffset(point.X, point.Y); aimDot.Visible = true end
end
if now >= nextTrajectory then
nextTrajectory = now + (isDrawing and Config.TrajectoryInterval or Config.IdleTrajectoryInterval)
if tool and Config.Trajectory then
castContext = castContext or exclusionContext()
local params = exclusions(nil, castContext)
local origin = shotOrigin(tool, params)
local direction = choice and Config.SilentAim and choice.solution.direction or (origin and shotDirection(origin, params))
if direction then
local speed, gravity, radius = parameters(tuning, charge)
local duration = choice and choice.solution.time or Config.MaxLifetime
local points, hit, exhausted = trace(origin, direction, speed, gravity, duration, params, radius, true)
displayTrajectory(points, hit ~= nil or exhausted)
else hideTrajectory() end
else hideTrajectory() end
end
if now >= nextUI then
nextUI = now + 0.1
for key, item in pairs(buttons) do
item.button.Text = item.caption .. (Config[key] and " ON" or " OFF")
item.button.BackgroundColor3 = Config[key] and Color3.fromRGB(25, 69, 77) or Color3.fromRGB(60, 50, 54)
end
namesButton.Text = Config.Names and "NAMES ON" or "NAMES OFF"
partButton.Text = Config.TargetPart == "Head" and "TARGET: HEAD" or "TARGET: TORSO"
fovLabel.Text = string.format("AIM FOV: %d px", Config.FOVRadius)
arcButton.Text = Config.PreferHighArc and "ARC: HIGH / LOB" or "ARC: LOW / FAST"
modeButton.Text = Config.SilentAim and "AIM: SILENT" or "AIM: CAMERA"
autoButton.Text = Config.AutoBow and "AUTO BOW ON" or "AUTO BOW OFF"
smartButton.Text = Config.SmartCharge and "SMART CHARGE ON" or "SMART CHARGE OFF"
jumpButton.Text = Config.JumpPrediction and "JUMP LEAD ON" or "JUMP LEAD OFF"
modeButton.BackgroundColor3 = Config.SilentAim and Color3.fromRGB(25, 69, 77) or Color3.fromRGB(32, 47, 58)
autoButton.BackgroundColor3 = Config.AutoBow and Color3.fromRGB(25, 69, 77) or Color3.fromRGB(32, 47, 58)
autoLabel.Text = autoNote
adapterLabel.Text = (nativeDraw and "Charge: native" or "Charge: estimated") .. (modules.Util and " | Origin: native" or " | Origin: fallback")
for _, record in pairs(records) do
local alive = record.root.Parent and isEnemy(record.model, record.owner)
local distance = alive and (record.root.Position - camera.CFrame.Position).Magnitude or math.huge
local enabled = Config.ESP and alive and distance <= Config.MaxDistance
record.highlight.Enabled = enabled
record.billboard.Enabled = enabled and Config.Names
record.highlight.OutlineColor = choice and choice.record == record
and Color3.fromRGB(255, 219, 103) or Color3.fromRGB(255, 146, 127)
if enabled then
record.label.Text = string.format("%s | %d HP | %d st",
record.owner and record.owner.DisplayName or record.model.Name,
math.max(0, math.floor(record.humanoid.Health)), math.floor(distance))
end
end
status.Text = tool and string.format("%s | %d%% %s", id, math.floor(charge * 100),
isDrawing and (nativeDraw and "draw" or "estimated") or "preview") or "Equip Wood Bow or Headhunter"
targetLabel.Text = choice and string.format("%s | %.2fs flight", choice.record.model.Name, choice.solution.time)
or (allowedToAim() and "No clear, reachable target in FOV" or "Enable AIM, then draw your bow")
end
end
if Config.RunMathTests then
local ok, err = pcall(mathTests)
if not ok then unload(); error(err) end
end
RunService:BindToRenderStep(binding, Enum.RenderPriority.Camera.Value + 3, function()
local ok, err = pcall(render)
if not ok then
-- Keep the menu and its key binding alive so a failed feature cannot erase the UI.
renderFailed = true
stopAuto("Stopped after error")
RunService:UnbindFromRenderStep(binding)
drawing, heldFallback, selected = false, false, nil
ring.Visible, aimDot.Visible = false, false
hideTrajectory()
for _, record in pairs(records) do
record.highlight.Enabled = false
record.billboard.Enabled = false
end
status.Visible, targetLabel.Visible, adapterLabel.Visible, autoLabel.Visible = false, false, false, false
make("TextLabel", {
Name = "RuntimeError", Position = UDim2.fromOffset(12, 241),
Size = UDim2.fromOffset(318, 85), BackgroundTransparency = 1,
Font = Enum.Font.Code, TextSize = 11, TextColor3 = Color3.fromRGB(255, 146, 127),
TextXAlignment = Enum.TextXAlignment.Left, TextYAlignment = Enum.TextYAlignment.Top,
TextWrapped = true, Text = "Features stopped; rerun script.\n" .. tostring(err):sub(1, 160),
}, content)
setMenuVisible(true)
warn("[Kingfisher] Features stopped after runtime error (menu stays available): " .. tostring(err))
end
end)
print("[Kingfisher] Loaded. Insert: menu. AIM and AUTO BOW start OFF. Choose CAMERA or SILENT; hide the menu for automatic bow use. Click X to unload.")
return {Settings = Config, Unload = unload, RunMathTests = mathTests}
Auto Bow only runs while the menu is closed, so switch it on and hide the panel. The arc button swaps between a low, fast shot and a high lob.