Tribes 3v3 Scripts NO KEY — (Instant Bow & ESP)

Published Updated 0 views
  • 5 scripts
  • 5 NO KEY
  • 0 KEY SYSTEM
  • 5 mobile

Browse 5 Tribes 3v3 scripts in this collection. 5 offer NO KEY access. 5 list mobile support.

Reviewed by RobScript Team

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.

Compare the Tribes 3v3 Scripts

All five are no key, and every listed function worked in our check.

ScriptChoose it forMenu note
Instant Bow plus aim, ESP and movement tools
Menu isn’t adapted for mobile
Auto Bow with a mobile-adapted menu
BobloNEXT interface; adapted from EvilGeniuses
Aim Lock, player ESP and projectile ESP
No extra issue noted in our check
Silent Aim, ESP and Wallbang
Smaller feature set; all listed tools worked
Original Auto Bow and Smart Charge setup
Menu isn’t adapted for mobile

Core functions

Choose the tools you need for aiming, bow shots, and tracking players.

Aim Lock / Silent Aim
Aim Lock follows a target with your camera. Silent Aim redirects your shot without turning your view.
Instant Bow
allison lets you fire on each click without the usual bow draw. You still control each shot.
Auto Bow
Both EvilGeniuses versions draw and fire the bow for you, with Smart Charge settings.
ESP
Shows player information such as names, HP, and distance. MunkeHub also tracks arrows in flight.

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
allison script preview

allison

Developer
allison
Updated
Updated
Working
NO KEY PC MOBILE

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
Limitation: The menu isn’t adapted for mobile.
Copies 1 Discord
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
Access
NO KEY
Tags
PC MOBILE
Languages
English
Compatibility
Delta Arceus X Codex Other

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.

allison Instant Bow — our in-game test.
EvilGeniuses & Robscript Team [Mobile Adaptive]
EvilGeniuses & Robscript Team [Mobile Adaptive] script preview

EvilGeniuses & Robscript Team [Mobile Adaptive]

Developer
EvilGeniuses & Robscript Team
Updated
Updated
Working
NO KEY PC MOBILE OPEN SOURCE

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
Copies 1 GitHub
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
Access
NO KEY
Tags
PC MOBILE OPEN SOURCE
Languages
English
Compatibility
Delta Arceus X Codex Other

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
MunkeHub script preview

MunkeHub

Developer
MunkeHub
Updated
Updated
Working
NO KEY PC MOBILE

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
Copies 0 Discord YouTube
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
Access
NO KEY
Tags
PC MOBILE
Languages
English
Compatibility
Delta Arceus X Codex Other

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
Patsan script preview

Patsan

Developer
Patsan
Updated
Updated
Working
NO KEY PC MOBILE OPEN SOURCE

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
Limitation: Smaller menu than the others: no camera Aim Lock and no movement tools.
Copies 0 Discord
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)
Access
NO KEY
Tags
PC MOBILE OPEN SOURCE
Languages
English
Compatibility
Delta Arceus X Codex Other

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
EvilGeniuses script preview

EvilGeniuses

Developer
EvilGeniuses
Updated
Updated
Working
NO KEY PC MOBILE OPEN SOURCE

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
Limitation: The menu isn’t adapted for mobile.
Copies 0
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
Access
NO KEY
Tags
PC MOBILE OPEN SOURCE
Languages
English
Compatibility
Delta Arceus X Codex Other

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.

How to Use a Tribes 3v3 Script

All five scripts are for Tribes 3v3, the Roblox game by Snick Co. (place 72169370437173). Open it from that link before you run any code. Tribes: Ascend and Tribes 3: Rivals are different games.

  1. Pick a script in the table, open its card and press Copy script.
  2. Open Tribes 3v3 from the link above and join a match.
  3. Paste the code into your executor and run it while the game is open.
  4. Turn on what you need: ESP to mark players, Aim Lock or Silent Aim for your aim. For bow features, equip a bow. With allison, Instant Bow fires when you click. With either EvilGeniuses menu, turn on Auto Bow and close the panel so it can shoot.
Using scripts breaks the Roblox Terms of Use. Accounts can be banned for it, so treat the risk as yours and use an account you can afford to lose.