Run it
Copy the script and paste it into your executor.
Config = {
ESP = ,
Aim = ,
SilentAim = ,
AutoBow = ,
SmartCharge = ,
JumpPrediction = ,
NoRecoil = ,
StrafePrediction = ,
StrafeTau = ,
NoSpread = ,
CircleStrafe = ,
CircleStrafeMode = ,
ShowHud = ,
Fly = ,
Speed = ,
SuperJump = ,
AutoMinCharge = ,
AutoMaxFlight = ,
AutoInterval = ,
AutoLostTargetGrace = ,
AutoMaxHold = ,
Trajectory = ,
Names = ,
FOVRadius = ,
MaxDistance = ,
IncludeTrainingDummies = ,
PreferHighArc = ,
TargetPart = ,
TargetRefresh = ,
SelectInterval = ,
TrajectoryInterval = / ,
IdleTrajectoryInterval = / ,
CastStep = / ,
MaxLifetime = ,
MaxTravel = ,
MaxCandidates = ,
ExtraLeadSeconds = ,
RunMathTests = ,
}
Players = :()
RunService = :()
UIS = :()
GuiService = :()
CollectionService = :()
ReplicatedStorage = :()
Workspace = :()
HttpService = :()
player = Players.LocalPlayer
(player RunService:(), )
CONFIG_FILE =
PERSIST = {
, , , , , ,
, , , , , , ,
, , , ,
, , ,
}
fsRead = (readfile) == readfile
fsWrite = (writefile) == writefile
fsIsFile = (isfile) == isfile
()
out = {}
_, key (PERSIST) out[key] = Config[key]
ok, encoded = (() HttpService:(out) )
ok encoded
()
(fsRead fsIsFile)
ok, raw = (()
(CONFIG_FILE) (CONFIG_FILE)
)
ok (raw) ~=
decoded
ok, decoded = (() HttpService:(raw) )
ok (decoded) ~=
_, key (PERSIST)
saved = decoded[key]
saved ~= (saved) == (Config[key]) Config[key] = saved
lastSavedSnapshot
()
fsWrite
encoded = ()
encoded encoded ~= lastSavedSnapshot
(fsWrite, CONFIG_FILE, encoded) lastSavedSnapshot = encoded
()
lastSavedSnapshot = ()
playerGui = player:(, )
(playerGui, )
ROOT_NAME =
old = playerGui:(ROOT_NAME)
old
stop = old:()
stop stop:() stop:(); .()
old.Parent old:()
connections, destructors = {}, {}
active =
renderFailed =
binding = ROOT_NAME .. .. (.(.() * ))
menuBinding = binding ..
stopAuto, installBowAdapters, installRecoilControl
bowAdaptersReady =
autoNote =
windowFocused =
(signal, fn)
connection = signal:(fn)
.(connections, connection)
connection
gui = .()
gui.Name = ROOT_NAME
gui.ResetOnSpawn =
gui.IgnoreGuiInset =
gui.Enabled =
gui.DisplayOrder =
gui.ZIndexBehavior = .ZIndexBehavior.Sibling
gui.Parent = playerGui
shutdown = .()
shutdown.Name =
shutdown.Parent = gui
visuals = .()
visuals.Name = ROOT_NAME
visuals.Parent = Workspace
()
active
active =
RunService:(binding)
RunService:(menuBinding)
_, connection (connections) connection:()
_, destructor (destructors) (destructor)
visuals:()
gui:()
()
(shutdown.Event, unload)
(gui.Destroying, unload)
(class, properties, parent)
object = .(class)
key, value (properties) object[key] = value
object.Parent = parent
object
(object, radius)
(, {CornerRadius = .(, radius)}, object)
PANEL_WIDTH, PANEL_HEIGHT = ,
panel = (, {
Name = , Visible = ,
Position = .(, ), Size = .(PANEL_WIDTH, PANEL_HEIGHT),
BackgroundColor3 = .(, , ), BackgroundTransparency = ,
BorderSizePixel = ,
}, gui)
(panel, )
(, {Color = .(, , ), Thickness = }, panel)
(parent, text, y, height)
(, {
Position = .(, y), Size = .(, -, , height),
BackgroundTransparency = , Text = text, TextSize = ,
Font = .Font.Code, TextColor3 = .(, , ),
TextXAlignment = .TextXAlignment.Left, TextTruncate = .TextTruncate.AtEnd,
TextYAlignment = .TextYAlignment.Center,
}, parent)
title = (panel, , , )
title.Size = .(, -, , )
title.TextColor3 = .(, , )
content = (, {
Position = .(, ), Size = .(, , , -), BackgroundTransparency = ,
}, panel)
(parent, caption, x, y, width, height)
result = (, {
Position = .(x, y), Size = .(width, height),
BackgroundColor3 = .(, , ), BorderSizePixel = ,
TextSize = , Font = .Font.Code, TextColor3 = .(, , ), Text = caption,
}, parent)
(result, )
result
minimize = (panel, , PANEL_WIDTH - , , , )
mouseIconBeforeMenu = UIS.MouseIconEnabled
minimize.Modal =
.(destructors, ()
minimize.Modal =
panel.Visible UIS.MouseIconEnabled = mouseIconBeforeMenu
)
close = (panel, , PANEL_WIDTH - , , , )
close.BackgroundColor3 = .(, , )
(close.Activated, unload)
(minimize.Activated, ()
content.Visible = content.Visible
panel.Size = .(PANEL_WIDTH, content.Visible PANEL_HEIGHT )
minimize.Text = content.Visible
)
buttons = {}
i, entry ({{, }, {, }, {, }})
key, caption = entry[], entry[]
control = (content, caption, + (i - ) * , , , )
buttons[key] = {button = control, caption = caption}
(control.Activated, ()
Config[key] = Config[key]
key == Config.Aim
Config.AutoBow =
stopAuto ()
)
namesButton = (content, , , , , )
partButton = (content, , , , , )
(namesButton.Activated, () Config.Names = Config.Names )
(partButton.Activated, ()
Config.TargetPart = Config.TargetPart ==
)
fovLabel = (content, , , )
fovLabel.Size = .(, )
less = (content, , , , , )
more = (content, , , , , )
(less.Activated, () Config.FOVRadius = .(, Config.FOVRadius - ) )
(more.Activated, () Config.FOVRadius = .(, Config.FOVRadius + ) )
arcButton = (content, , , , , )
(arcButton.Activated, () Config.PreferHighArc = Config.PreferHighArc )
modeButton = (content, , , , , )
autoButton = (content, , , , , )
smartButton = (content, , , , , )
jumpButton = (content, , , , , )
(modeButton.Activated, ()
bowAdaptersReady autoNote = ;
Config.SilentAim = Config.SilentAim
)
(autoButton.Activated, ()
bowAdaptersReady autoNote = ;
Config.AutoBow = Config.AutoBow
Config.AutoBow Config.Aim =
stopAuto ()
)
(smartButton.Activated, () Config.SmartCharge = Config.SmartCharge )
(jumpButton.Activated, () Config.JumpPrediction = Config.JumpPrediction )
recoilButton = (content, , , , , )
(recoilButton.Activated, () Config.NoRecoil = Config.NoRecoil )
spreadButton = (content, , , , , )
(spreadButton.Activated, () Config.NoSpread = Config.NoSpread )
flyButton = (content, , , , , )
(flyButton.Activated, () Config.Fly = Config.Fly )
speedButton = (content, , , , , )
(speedButton.Activated, () Config.Speed = Config.Speed )
jumpBoostButton = (content, , , , , )
(jumpBoostButton.Activated, () Config.SuperJump = Config.SuperJump )
status = (content, , , )
targetLabel = (content, , , )
adapterLabel = (content, , , )
adapterLabel.TextSize =
autoLabel = (content, , , )
autoLabel.TextSize =
(content, , , ).TextSize =
(content, , , ).TextSize =
dragging, dragStart, panelStart, dragInput
dragHandle = (, {
Position = .(, ), Size = .(, -, , ),
BackgroundTransparency = , Text = , AutoButtonColor = ,
}, panel)
(dragHandle.InputBegan, (input)
input.UserInputType == .UserInputType.MouseButton1 input.UserInputType == .UserInputType.Touch
dragging, dragStart, panelStart, dragInput = , input.Position, panel.Position, input
)
(UIS.InputChanged, (input)
dragging
input.UserInputType ~= .UserInputType.MouseMovement input ~= dragInput
delta = input.Position - dragStart
camera = Workspace.CurrentCamera
camera
panel.Position = .(
.(panelStart.X.Offset + delta.X, , .(, camera.ViewportSize.X - PANEL_WIDTH)),
.(panelStart.Y.Offset + delta.Y, , .(, camera.ViewportSize.Y - panel.AbsoluteSize.Y))
)
)
(UIS.InputEnded, (input)
input.UserInputType == .UserInputType.MouseButton1 input == dragInput dragging =
)
ring = (, {
AnchorPoint = .(, ), Position = .(, ),
Size = .(Config.FOVRadius * , Config.FOVRadius * ),
BackgroundTransparency = , BorderSizePixel = ,
}, gui)
(, {CornerRadius = .(, )}, ring)
(, {Color = .(, , ), Transparency = , Thickness = }, ring)
aimDot = (, {
AnchorPoint = .(, ), Size = .(, ),
BackgroundColor3 = .(, , ), BorderSizePixel = , Visible = ,
}, gui)
(aimDot, )
modules = {}
menuCamera
()
menuCamera
previous = menuCamera
menuCamera =
ok, err = (previous.PopMouseUnlock, binding)
ok ( .. (err))
()
desired = active gui.Enabled panel.Visible modules.Camera
desired ((desired.PushMouseUnlock) ~= (desired.PopMouseUnlock) ~= )
desired =
desired == menuCamera
()
desired
ok, err = (desired.PushMouseUnlock, binding)
ok menuCamera = desired
( .. (err))
.(destructors, releaseMenuMouse)
nativeDraw =
drawing =
drawStart, drawDuration = ,
lastTool
heldFallback =
panelHovered =
selected, selectionTime = , -.huge
applyAim
autoHandler, autoOwned, autoReleaseResult
instantAutoFiring =
firingContexts = ({}, {__mode = })
autoNext, autoLastClear, autoStarted = , ,
(panel.MouseEnter, () panelHovered = )
(panel.MouseLeave, () panelHovered = )
(visible)
active
wasVisible = gui.Enabled panel.Visible
visible wasVisible mouseIconBeforeMenu = UIS.MouseIconEnabled
visible
stopAuto ()
gui.Enabled =
content.Visible =
panel.Size = .(PANEL_WIDTH, PANEL_HEIGHT)
minimize.Text =
camera = Workspace.CurrentCamera
camera
panel.Position = .(
.(panel.Position.X.Offset, , .(, camera.ViewportSize.X - PANEL_WIDTH)),
.(panel.Position.Y.Offset, , .(, camera.ViewportSize.Y - PANEL_HEIGHT))
)
panel.Visible = visible
minimize.Modal = visible
dragging, dragInput, panelHovered = , ,
visible
UIS.MouseIconEnabled =
UIS.MouseIconEnabled = mouseIconBeforeMenu
()
(gui:(), syncMenuMouse)
(UIS.InputBegan, (input)
input.KeyCode ~= .KeyCode.Insert
UIS:() GuiService.MenuIsOpen
( (gui.Enabled panel.Visible))
)
RunService:(menuBinding, .RenderPriority.Camera.Value + , ()
active gui.Enabled panel.Visible UIS.MouseIconEnabled =
)
()
()
(path, key)
.(()
cursor = path[]
i = , #path
cursor = cursor cursor:(path[i], )
active cursor
cursor:()
ok, value = (, cursor)
active
ok (value) ~=
( .. key .. )
modules[key] = value
key == ()
key == (value.OnViewEvent) ==
subscribed, disconnect = (value.OnViewEvent, (name, data)
active (data) ~=
name ==
lastTool = player.Character player.Character:()
drawing = data.on ==
selected, selectionTime = , -.huge
drawing
drawStart = .()
drawDuration = (data.time)
name ==
ok, err = ,
applyAim (data.charge) ==
ok, err = (applyAim, .(data.charge, , ), )
drawing, selected = ,
ok ( .. (err))
)
subscribed (disconnect) ==
nativeDraw =
.(destructors, disconnect)
installBowAdapters ()
installRecoilControl ()
)
({ReplicatedStorage, , }, )
({ReplicatedStorage, , }, )
({player, , , }, )
({player, , , }, )
({player, , , , }, )
({player, , , , }, )
({ReplicatedStorage, , }, )
fallbackWeapons = {
short_bow = {kind = , drawTime = , speedMin = , speedMax = , gravity = , radius = , range = },
longbow = {kind = , drawTime = , speedMin = , speedMax = , gravity = , radius = , range = },
crossbow = {kind = , speed = , gravity = , radius = , range = },
musket = {kind = , speed = , gravity = , radius = , range = },
flintlock = {kind = , speed = , gravity = , radius = , range = },
blunderbuss = {kind = , speed = , gravity = , radius = , range = },
throwing_knives = {kind = , speed = , gravity = , radius = , range = },
javelins = {kind = , drawTime = , speedMin = , speedMax = , gravity = , radius = , range = },
harpoon = {kind = , drawTime = , speedMin = , speedMax = , gravity = , radius = , range = },
sling = {kind = , speed = , gravity = , radius = , range = },
bolas = {kind = , speed = , gravity = , radius = , range = },
chakram = {kind = , speed = , gravity = , radius = , range = },
}
AIMABLE_KINDS = {
Bow = , Crossbow = , Musket = , Pistol = , Blunderbuss = ,
Knives = , Javelin = , Sling = ,
}
CHARGE_KINDS = {Bow = , Javelin = }
HITSCAN_KINDS = {Musket = , Pistol = , Blunderbuss = }
aimHitscan =
(kind) CHARGE_KINDS[kind]
()
character = player.Character
tool = character character:()
tool ~= lastTool
drawing, heldFallback = ,
selected, selectionTime = , -.huge
lastTool = tool
tool
id = tool:()
fallback = fallbackWeapons[id]
tuning = fallback
kind = fallback fallback.kind
weapons = modules.Weapons
weapons (weapons.Get) ==
ok, definition = (weapons.Get, id)
ok (definition) == AIMABLE_KINDS[definition.kind]
tuning = definition.tuning tuning
kind = definition.kind
tuning kind AIMABLE_KINDS[kind]
aimHitscan = HITSCAN_KINDS[kind] ==
tool, tuning, id, kind, (kind)
(tuning)
drawing ( nativeDraw heldFallback)
duration = nativeDraw drawDuration (tuning.drawTime )
.((.() - drawStart) / .(, duration), , ),
,
recoilCleanup
installRecoilControl = ()
recoilCleanup active
util = modules.Util
(util) ~=
originals, wrappers = {}, {}
_, name ({, , })
(util[name]) == originals[name] = util[name]
(originals)
name, fn (originals)
wrapped = (...)
active Config.NoRecoil
(...)
wrappers[name] = wrapped
util[name] = wrapped
recoilCleanup = ()
name, fn (originals)
util[name] == wrappers[name] util[name] = fn
.(destructors, () recoilCleanup () )
()
(model, owner, key)
value = model model:(key)
value == owner value = owner:(key)
value
(model, owner)
model == player.Character owner == player model:(Workspace)
(model, owner, ) ==
humanoid = model:()
humanoid humanoid.Health <=
myMatch = (player.Character, player, )
theirMatch = (model, owner, )
myTeam = (player.Character, player, )
theirTeam = (model, owner, )
(myMatch) == myMatch ~=
theirMatch == myMatch theirTeam ~= myTeam ~= theirTeam ~= myTeam
Config.IncludeTrainingDummies CollectionService:(model, )
records = {}
()
visited, valid = {}, {}
(model, owner)
model model:() visited[model]
visited[model] =
(model, owner)
root = model:()
part = model:(Config.TargetPart) model:()
model:() root
root root:() part part:()
valid[model] =
head = model:()
adornee = head head:() head root
record = records[model]
record
highlight = (, {
Adornee = model, DepthMode = .HighlightDepthMode.AlwaysOnTop,
FillColor = .(, , ), FillTransparency = ,
OutlineColor = .(, , ), OutlineTransparency = ,
}, visuals)
billboard = (, {
Adornee = adornee, AlwaysOnTop = ,
Size = .(, ), StudsOffsetWorldSpace = .(, , ),
MaxDistance = Config.MaxDistance,
}, gui)
label = (, {
Size = .(, ), BackgroundTransparency = , TextSize = ,
Font = .Font.Code, TextColor3 = .(, , ),
TextStrokeTransparency = , Text = ,
}, billboard)
record = {highlight = highlight, billboard = billboard, label = label, model = model}
records[model] = record
record.owner, record.root, record.part = owner, root, part
record.humanoid = model:()
record.billboard.Adornee = adornee
_, other (Players:()) (other.Character, other)
_, tag ({, , })
_, model (CollectionService:(tag))
model:() (model, Players:(model))
model, record (records)
valid[model]
selected selected.record == record selected, selectionTime = , -.huge
record.highlight:()
record.billboard:()
records[model] =
()
list, seen = {}, {}
(object)
object seen[object]
seen[object] =
.(list, object)
(visuals)
(player.Character)
_, name ({, })
folder = Workspace:(name)
(folder)
myMatch = (player.Character, player, )
myTeam = (player.Character, player, )
(model, owner)
model model:() myMatch ~= myMatch ~= myTeam ~=
(model, owner, ) == myMatch
(model, owner, ) == myTeam
(model)
_, other (Players:()) (other.Character, other)
_, tag ({, })
_, model (CollectionService:(tag)) (model, )
{list = list, seen = seen, params = {}}
(extra, context)
context = context ()
key = extra
context.params[key] context.params[key]
list = .(context.list)
extra context.seen[extra] .(list, extra)
params = RaycastParams.()
params.FilterType = .RaycastFilterType.Exclude
params.FilterDescendantsInstances = list
params.IgnoreWater =
context.params[key] = params
params
(tool, params)
util = modules.Util
util (util.ShotOrigin) ==
ok, origin = (util.ShotOrigin, tool, )
ok (origin) == origin
character = player.Character
head = character (character:() character:())
head head:()
fallback = head.Position
head.Name == fallback = fallback + .(, , )
muzzle = tool:(, )
handle = tool:()
point = muzzle muzzle:() muzzle.WorldPosition
(handle handle:() handle.Position) fallback
(point - fallback).Magnitude > fallback
delta = point - fallback
delta.Magnitude > Workspace:(fallback, delta, params) fallback
point
(origin, params)
util = modules.Util
util (util.AimDirection) ==
ok, direction = (util.AimDirection, origin)
ok (direction) == direction.Magnitude > direction.Unit
camera = Workspace.CurrentCamera
camera
hit = Workspace:(camera.CFrame.Position, camera.CFrame.LookVector * , params)
point = hit hit.Position camera.CFrame.Position + camera.CFrame.LookVector *
delta = point - origin
delta.Magnitude > delta.Unit camera.CFrame.LookVector
(x)
(x) == x == x .(x) < .huge
(c, x)
y = c[#c]
i = #c - , , - y = y * x + c[i]
y
(c, x)
y = .(c[#c])
i = #c - , , - y = y * .(x) + .(c[i])
y
(c, lo, hi)
#c > c[#c] == .(c)
magnitude =
_, value (c) magnitude = .(magnitude, .(value))
magnitude == #c == {}
i = , #c c[i] = c[i] / magnitude
#c ==
root = -c[] / c[]
root >= lo root <= hi {root} {}
derivative = {}
i = , #c derivative[i - ] = (i - ) * c[i]
boundaries = {lo}
_, value ((derivative, lo, hi))
value > lo value < hi .(boundaries, value)
.(boundaries, hi)
.(boundaries)
roots = {}
(root)
_, existing (roots)
.(existing - root) <
.(roots, root)
_, x (boundaries)
.((c, x)) <= * .(, (c, x))
(x)
i = , #boundaries -
a, b = boundaries[i], boundaries[i + ]
fa, fb = (c, a), (c, b)
(fa < fb > ) (fa > fb < )
_ = ,
middle = (a + b) *
fm = (c, middle)
(fa < fm < ) (fa > fm > )
a, fa = middle, fm
b = middle
((a + b) * )
.(roots)
roots
(origin, target, velocity, speed, gravity, lifetime, targetAcceleration)
(speed) speed <= (lifetime) lifetime <= {}
targetAcceleration = targetAcceleration .zero
relativeGravity = gravity - targetAcceleration
offset = target - origin
offset.Magnitude < {}
c = {
offset:(offset),
* offset:(velocity),
velocity:(velocity) - offset:(relativeGravity) - speed * speed,
-velocity:(relativeGravity),
* relativeGravity:(relativeGravity),
}
i = , #c
c[i] = c[i] * lifetime ^ (i - )
(c[i]) {}
solutions = {}
_, x ((c, / lifetime, ))
time = x * lifetime
launch = offset / time + velocity - * relativeGravity * time
(launch.Magnitude) launch.Magnitude >
.(launch.Magnitude - speed) <= .(, speed * )
.(solutions, {
time = time,
direction = launch.Unit,
impact = target + velocity * time + * targetAcceleration * time * time,
})
solutions
(tuning, charge)
minimum = (tuning.speedMin tuning.speed)
maximum = (tuning.speedMax tuning.speed) minimum
speed = minimum + (maximum - minimum) * charge
gravity = aimHitscan .zero .(, -((tuning.gravity) ), )
speed, gravity, (tuning.radius)
(origin, direction, speed, gravity, duration, params, radius, collect)
position, velocity = origin, direction * speed
points = collect {origin}
age, traveled = ,
age < duration -
dt = .(Config.CastStep, duration - age)
delta = velocity * dt + * gravity * dt * dt
traveled + delta.Magnitude > Config.MaxTravel points, ,
hit
delta.Magnitude >
radius >
hit = Workspace:(position, radius, delta, params)
hit = Workspace:(position, delta, params)
hit
points .(points, position + delta.Unit * hit.Distance)
points, hit,
position = position + delta
velocity = velocity + gravity * dt
traveled = traveled + delta.Magnitude
age = age + dt
points .(points, position)
points, ,
(record, velocity, targetGravity)
root, humanoid = record.root, record.humanoid
standingHeight = root.Size.Y * + .(, humanoid.HipHeight)
humanoid.RigType == .HumanoidRigType.R6
leg = record.model:() record.model:()
leg leg:()
standingHeight = standingHeight + leg.Size.Y
excluded, seen = {visuals}, {[visuals] = }
(model)
model seen[model] seen[model] = ; .(excluded, model)
(record.model)
(player.Character)
_, other (Players:()) (other.Character)
model (records) (model)
params = RaycastParams.()
params.FilterType = .RaycastFilterType.Exclude
params.FilterDescendantsInstances = excluded
params.IgnoreWater, params.RespectCanCollide = ,
params.CollisionGroup = root.CollisionGroup
rootPosition = root.Position
(x, z)
hit = Workspace:(.(x, rootPosition.Y + , z), .(, -, ), params)
hit hit.Normal.Y <
hit.Instance:() hit.Instance.Anchored
hit.Position.Y
firstGround = (rootPosition.X, rootPosition.Z)
firstGround ==
clearance = rootPosition.Y - firstGround - standingHeight
clearance < -
landingTime = (velocity.Y + .(velocity.Y * velocity.Y + * targetGravity * .(, clearance))) / targetGravity
(landingTime) landingTime < landingTime > Config.MaxLifetime +
lastGround = (rootPosition.X + velocity.X * landingTime, rootPosition.Z + velocity.Z * landingTime)
lastGround == .(lastGround - firstGround) >
clearance = rootPosition.Y - lastGround - standingHeight
clearance < -
landingTime = (velocity.Y + .(velocity.Y * velocity.Y + * targetGravity * .(, clearance))) / targetGravity
landingTime, lastGround + standingHeight + record.part.Position.Y - rootPosition.Y
(record, velocity)
position, rootPosition = record.part.Position, record.root.Position
humanoid = record.humanoid
state = humanoid humanoid:()
targetGravity = Workspace.Gravity
now = .()
cached = record.jumpMotion
cached now - cached.sampledAt < cached.root == record.root cached.part == record.part
cached.position == position cached.rootPosition == rootPosition cached.velocity == velocity
cached.state == state cached.gravity == targetGravity cached.enabled == Config.JumpPrediction
cached
motion = {
position = position, rootPosition = rootPosition, velocity = velocity, acceleration = .zero,
root = record.root, part = record.part, sampledAt = now, state = state,
gravity = targetGravity, enabled = Config.JumpPrediction,
}
aimHitscan Config.JumpPrediction humanoid (targetGravity) targetGravity >
(state == .HumanoidStateType.Jumping state == .HumanoidStateType.Freefall)
motion.acceleration = .(, -targetGravity, )
motion.landingTime, motion.landingY = (record, velocity, targetGravity)
record.jumpMotion = motion
motion
(origin, motion, speed, gravity, lifetime, lead)
lead = (lead) .(, lead)
solutions = {}
remainingAirTime = motion.landingTime .(, motion.landingTime - lead) lifetime
remainingAirTime >
position = motion.position + motion.velocity * lead + * motion.acceleration * lead * lead
velocity = motion.velocity + motion.acceleration * lead
solutions = (origin, position, velocity, speed, gravity, .(lifetime, remainingAirTime), motion.acceleration)
motion.landingTime
velocity = .(motion.velocity.X, , motion.velocity.Z)
position = .(motion.position.X, motion.landingY, motion.position.Z) + velocity * lead
_, solution ((origin, position, velocity, speed, gravity, lifetime))
solution.time + lead >= motion.landingTime -
duplicate =
_, existing (solutions)
.(solution.time - existing.time) < duplicate = ;
duplicate .(solutions, solution)
.(solutions, (a, b) a.time < b.time )
solutions
(record, raw)
aimHitscan record.strafe = ; .zero
Config.StrafePrediction record.strafe = ; raw
horizontal = .(raw.X, , raw.Z)
now = .()
s = record.strafe
s
record.strafe = {smooth = horizontal, t = now, conf = , lead = horizontal}
.(horizontal.X, raw.Y, horizontal.Z)
dt = now - s.t
dt < .(s.lead.X, raw.Y, s.lead.Z)
tau = (Config.StrafeTau)
alpha = .(dt / (dt + tau), , )
align =
horizontal.Magnitude > s.smooth.Magnitude >
align = horizontal.Unit:(s.smooth.Unit)
target = .((align + ) / , , )
conf = target < s.conf target (s.conf + alpha * (target - s.conf))
smooth = s.smooth:(horizontal, alpha)
lead = smooth * conf
s.smooth, s.t, s.conf, s.lead = smooth, now, conf, lead
.(lead.X, raw.Y, lead.Z)
(record, origin, speed, gravity)
record.model.Parent record.part.Parent record.root.Parent
(record.model, record.owner) {}
rawVelocity = record.root.AssemblyLinearVelocity
(rawVelocity.Magnitude) rawVelocity.Magnitude > {}
velocity = (record, rawVelocity)
motion = (record, velocity)
solutions = (origin, motion, speed, gravity, Config.MaxLifetime, Config.ExtraLeadSeconds)
Config.PreferHighArc
reverse = {}
i = #solutions, , - .(reverse, solutions[i])
reverse
solutions
(origin, tuning, speed, gravity, radius, force, context)
camera = Workspace.CurrentCamera
camera selected = ;
now = .()
force now - selectionTime < Config.SelectInterval selected
selectionTime = now
range = .(Config.MaxDistance, (tuning.range) Config.MaxDistance)
(record)
record.part.Parent (record.model, record.owner)
(record.part.Position - origin).Magnitude > range
Config.SilentAim
point, onScreen = camera:(record.part.Position)
onScreen point.Z <=
(.(point.X, point.Y) - camera.ViewportSize * ).Magnitude > Config.FOVRadius
params = (record.model, context)
_, solution ((record, origin, speed, gravity))
pitch = .(.(solution.direction.Y, -, ))
pitch >= .(-) pitch <= .()
_, hit, exhausted = (origin, solution.direction, speed, gravity, solution.time, params, radius, )
hit exhausted {record = record, solution = solution}
selected
retained = (selected.record)
retained selected = retained; selected
center = camera.ViewportSize *
candidates = {}
_, record (records)
record.part.Parent (record.model, record.owner)
projected, onScreen = camera:(record.part.Position)
screenDistance = (.(projected.X, projected.Y) - center).Magnitude
distance = (record.part.Position - origin).Magnitude
onScreen projected.Z > screenDistance <= Config.FOVRadius distance <= range
.(candidates, {record = record, score = screenDistance})
.(candidates, (a, b) a.score < b.score )
selected =
i = , .(#candidates, Config.MaxCandidates)
choice = (candidates[i].record)
choice selected = choice; choice
()
renderFailed windowFocused Config.Aim
UIS:() GuiService.MenuIsOpen (panel.Visible panelHovered)
(drawing ( nativeDraw heldFallback))
_, _, _, _, model = ()
(model == Config.SilentAim)
character = player.Character
humanoid = character character:()
humanoid ~= humanoid.Health > (character, player, ) ~=
(origin, direction, cameraPosition)
offset = cameraPosition - origin
along = offset:(direction)
perpendicularSquared = .(, offset:(offset) - along * along)
distance = along + .(.(, * - perpendicularSquared))
(origin + direction * distance - cameraPosition).Unit
(direction)
camera = Workspace.CurrentCamera
camera (direction.Magnitude) direction.Magnitude <
yaw = .(-direction.X, -direction.Z)
pitch = .(.(.(direction.Y, -, )), .(-), .())
nativeCamera = modules.Camera
nativeCamera (nativeCamera.SetLook) == (nativeCamera.SetLook, yaw, pitch)
camera.CFrame = .(camera.CFrame.Position) * .(pitch, yaw, )
applyAim = (forcedCharge, forceCheck, context)
active ()
tool, tuning = ()
tool ()
context = context ()
charge = forcedCharge
charge == charge = (tuning)
speed, gravity, radius = (tuning, charge)
params = (, context)
origin = (tool, params)
origin
choice = (origin, tuning, speed, gravity, radius, forceCheck, context)
choice
Config.SilentAim bowAdaptersReady choice
camera = Workspace.CurrentCamera
originalView = camera.CFrame
()
(originalView.LookVector)
camera.CFrame = originalView
selected =
solution
_ = ,
origin = (tool, params)
origin ()
roots = (choice.record, origin, speed, gravity)
solution = roots[]
solution ()
_, candidate (roots)
.(candidate.time - choice.solution.time) < .(solution.time - choice.solution.time)
solution = candidate
launchPitch = .(.(solution.direction.Y, -, ))
launchPitch < .(-) launchPitch > .() ()
((origin, solution.direction, camera.CFrame.Position))
actual = (origin, params)
actual actual:(solution.direction) <
corrected = camera.CFrame.LookVector + solution.direction - actual
corrected.Magnitude > (corrected.Unit)
finalOrigin = (tool, params)
finalOrigin ()
actualDirection = (finalOrigin, params)
actualDirection ()
endpoint = finalOrigin + actualDirection * speed * solution.time
+ gravity * ( * solution.time * solution.time)
size = choice.record.part.Size
tolerance = radius + .(, .(size.X, size.Y, size.Z) * )
(endpoint - solution.impact).Magnitude > tolerance ()
forceCheck choice.finalCheck .() - choice.finalCheck >= Config.SelectInterval
_, hit, exhausted = (finalOrigin, actualDirection, speed, gravity,
solution.time, (choice.record.model, context), radius, )
hit exhausted ()
choice.finalCheck = .()
choice.solution = solution
choice
(record, origin, tuning, charge, context)
record record.part.Parent (record.model, record.owner)
(record.part.Position - origin).Magnitude > .(Config.MaxDistance, (tuning.range) Config.MaxDistance)
speed, gravity, radius = (tuning, charge)
_, solution ((record, origin, speed, gravity))
pitch = .(.(solution.direction.Y, -, ))
pitch >= .(-) pitch <= .()
_, hit, exhausted = (origin, solution.direction, speed, gravity,
solution.time, (record.model, context), radius, )
hit exhausted {record = record, solution = solution}
(tool, tuning, charge, context)
context = context ()
origin = (tool, (, context))
origin
speed, gravity, radius = (tuning, charge)
(origin, tuning, speed, gravity, radius, , context)
stopAuto = (reason)
owned = autoOwned
autoOwned =
owned
owned.bufferedAt =
owned.drawing
ok, err = (owned.CancelDraw, owned)
ok owned.drawing
owned.drawing =
ok ( .. (err))
owned.m1Down =
equipped = player.Character player.Character:()
owned.ctx owned.ctx.tool == equipped modules.Controller
(modules.Controller.Dispatch, , )
autoNote = .. (Config.AutoBow (reason ) )
.(destructors, () () )
bowHookCleanup
installBowAdapters = ()
active bowHookCleanup
bow, util, controller = modules.Bow, modules.Util, modules.Controller
bow util controller
(bow.Update) ~= (bow.Fire) ~=
(bow.CancelDraw) ~= (bow.Charge) ~=
(util.AssistDirection) ~= (controller.Dispatch) ~=
oldUpdate, oldFire, oldAssist = bow.Update, bow.Fire, util.AssistDirection
blockedAutoShot = {}
updateWrapper, fireWrapper, assistWrapper
updateWrapper = (self, ...)
active self.ctx
equipped = player.Character player.Character:()
self.ctx.tool == equipped autoHandler = self
(self, ...)
fireWrapper = (self, ...)
equipped = player.Character player.Character:()
active self.drawing self.ctx self.ctx.tool ~= equipped
(self, ...)
assisted = Config.Aim windowFocused renderFailed
UIS:() GuiService.MenuIsOpen panel.Visible
charge = self:()
automatic = autoOwned == self
automatic autoReleaseResult =
choice
assisted
Config.SilentAim choice = (equipped, self.tuning, charge)
choice = (charge, )
automatic choice
autoReleaseResult =
()
thread = .()
previous = firingContexts[thread]
shotScope
assisted (Config.SilentAim automatic) choice
shotScope = {record = choice.record, tuning = self.tuning, charge = charge, tool = equipped, automatic = automatic}
firingContexts[thread] = shotScope
firingContexts[thread] =
result = .((oldFire, self, ...))
firingContexts[thread] = previous
result[] result[] == blockedAutoShot
self.bufferedAt =
(self.CancelDraw, self)
self.m1Down =
autoOwned, autoReleaseResult = ,
autoNote =
result[]
automatic
()
Config.AutoBow =
autoNote =
(result[], )
automatic
autoReleaseResult = shotScope ~= shotScope.used ==
autoReleaseResult autoOwned = ; autoNote =
.(result, , result.n)
assistWrapper = (origin, direction, preservePitch, ...)
scope = firingContexts[.()]
equipped = player.Character player.Character:()
scope scope.automatic ( active renderFailed windowFocused
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
-- Generic assist for any projectile weapon fired outside the bow's draw
-- scope (crossbow, musket, flintlock, blunderbuss, knives, sling, etc.).
-- The handler hands us its true muzzle origin here, so redirect the shot
-- the game is about to send. Active in SILENT mode, or during an auto tap.
if not scope and active and not renderFailed and Config.Aim
and (Config.SilentAim or instantAutoFiring) and windowFocused
and not GuiService.MenuIsOpen and not UIS:GetFocusedTextBox()
and typeof(origin) == "Vector3" then
local gtool, gtuning, _, _, gmodel = bowInfo()
if gtool and gtool.Parent == player.Character then
local gcharge = gmodel == "charge" and (select(1, chargeFor(gtuning))) or 1
local gspeed, ggravity, gradius = parameters(gtuning, gcharge)
local okSel, gchoice = pcall(selectTarget, origin, gtuning, gspeed, ggravity, gradius, true, exclusionContext())
if okSel and gchoice and gchoice.solution then
return gchoice.solution.direction
end
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
-- Auto-fire for instant weapons (crossbow / musket / flintlock / blunderbuss /
-- knives / sling / bolas / chakram). There is no draw to manage: when a clear
-- shot exists we tap the native Primary input and let the generic assist above
-- redirect the shot onto the target. Paced by the weapon's own fire interval.
local function updateAutoInstant(now, tool, tuning, weaponId)
if autoOwned then stopAuto("Switched to instant weapon") end
local character = player.Character
local humanoid = character and character:FindFirstChildOfClass("Humanoid")
if 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) then
if Config.AutoBow then autoNote = "Auto: paused; hide menu, release LMB" end
return
end
if now < autoNext then return end
local util = modules.Util
if util and type(util.CanAct) == "function" then
local ok, canAct = pcall(util.CanAct)
if not ok or not canAct then autoNote = "Auto: waiting until weapon can act"; autoNext = now + 0.1; return end
end
if util and type(util.IsMouseUnlocked) == "function" then
local ok, unlocked = pcall(util.IsMouseUnlocked)
if ok and unlocked then autoNote = "Auto: paused: game menu open"; return end
end
if tool:GetAttribute("Reloading") == true then autoNote = "Auto: reloading"; autoNext = now + 0.1; return end
local choice = findShot(tool, tuning, 1)
if not choice then autoNote = "Auto: no clear target in FOV"; autoNext = now + 0.05; return end
selected, selectionTime = choice, -math.huge
instantAutoFiring = true
local ok = pcall(modules.Controller.Dispatch, "Primary", true)
pcall(modules.Controller.Dispatch, "Primary", false)
instantAutoFiring = false
autoNote = ok and "Auto: firing" or "Auto: dispatch failed"
local interval = tonumber(tuning.fireInterval) or tonumber(tuning.cooldown) or 0.3
autoNext = now + math.max(interval + 0.02, Config.AutoInterval)
end
local function updateAutoBow(now, tool, tuning, weaponId, model)
if model == "instant" then return updateAutoInstant(now, tool, tuning, weaponId) end
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, weaponKind, weaponModel = bowInfo()
updateAutoBow(now, tool, tuning, id, weaponModel)
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
saveConfig() -- debounced: writes only when a setting actually changed
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 FIRE ON" or "AUTO FIRE 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"
recoilButton.Text = Config.NoRecoil and "NO RECOIL ON" or "NO RECOIL OFF"
recoilButton.BackgroundColor3 = Config.NoRecoil and Color3.fromRGB(25, 69, 77) or Color3.fromRGB(32, 47, 58)
spreadButton.Text = Config.NoSpread and "NO SPREAD ON" or "NO SPREAD OFF"
spreadButton.BackgroundColor3 = Config.NoSpread and Color3.fromRGB(25, 69, 77) or Color3.fromRGB(32, 47, 58)
flyButton.Text = Config.Fly and "FLY ON" or "FLY OFF"
flyButton.BackgroundColor3 = Config.Fly and Color3.fromRGB(25, 69, 77) or Color3.fromRGB(32, 47, 58)
speedButton.Text = Config.Speed and "SPEED ON" or "SPEED OFF"
speedButton.BackgroundColor3 = Config.Speed and Color3.fromRGB(25, 69, 77) or Color3.fromRGB(32, 47, 58)
jumpBoostButton.Text = Config.SuperJump and "JUMP ON" or "JUMP OFF"
jumpBoostButton.BackgroundColor3 = Config.SuperJump and Color3.fromRGB(25, 69, 77) or Color3.fromRGB(32, 47, 58)
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 (%s) | %d%% %s", id or "?", weaponKind or "?", math.floor(charge * 100),
weaponModel == "instant" and "ready" or (isDrawing and (nativeDraw and "draw" or "estimated") or "preview"))
or "Equip a weapon (bow, crossbow, musket, knives, javelin...)"
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; silent aim covers every weapon")
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)
-- ============================================================================
-- Circle Strafe (+ auto-Fly) + on-screen HUD.
-- Toggle-to-activate, isolated from the aim core. All character movement is
-- client-side CFrame work: it replicates in Roblox, but it is also the most
-- anticheat-visible thing here and Tribes' server movement checks are unknown
-- (no server code in the dump). Edit KEYS below to rebind; tune Config.Circle*.
-- ============================================================================
Config.CircleRadius = Config.CircleRadius or 6 -- studs from target (tight orbit)
Config.CircleHeight = Config.CircleHeight or 2 -- hover height above target root
Config.CircleSpeed = Config.CircleSpeed or 12.0 -- orbit rate (rad/s)
Config.StrafeSmooth = Config.StrafeSmooth or 0.30 -- 0..1 move-toward (lower = smoother)
Config.CircleRange = Config.CircleRange or 120 -- target acquisition range (studs)
local KEYS = {
Strafe = Enum.KeyCode.End, -- toggle: orbit / park behind target (auto-fly)
Mode = Enum.KeyCode.B, -- tap: switch Orbit <-> Behind-Back
}
local toggles, orbitAngle, flying, platformStash = {}, 0, false, nil
local function nearestEnemy(fromPos, maxRange)
local best, bestDist
for _, record in pairs(records) do
local root = record.root
if root and root.Parent and isEnemy(record.model, record.owner)
and record.humanoid and record.humanoid.Health > 0 then
local d = (root.Position - fromPos).Magnitude
if d <= maxRange and (not bestDist or d < bestDist) then best, bestDist = record, d end
end
end
return best
end
-- Ring visualizer (segmented neon circle on the ground under the target) ------
local RING_SEGMENTS = 28
local ringParts = {}
for _ = 1, RING_SEGMENTS do
ringParts[#ringParts + 1] = make("Part", {
Name = "StrafeRing", Anchored = true, CanCollide = false, CanTouch = false,
CanQuery = false, CastShadow = false, Material = Enum.Material.Neon,
Size = Vector3.new(0.14, 0.14, 1), Transparency = 1,
}, visuals)
end
local function hideRing()
for _, p in ipairs(ringParts) do p.Transparency = 1 end
end
local function drawRing(center, radius, color)
for i, p in ipairs(ringParts) do
local a0, a1 = (i - 1) / RING_SEGMENTS * math.pi * 2, i / RING_SEGMENTS * math.pi * 2
local p0 = center + Vector3.new(math.cos(a0), 0, math.sin(a0)) * radius
local p1 = center + Vector3.new(math.cos(a1), 0, math.sin(a1)) * radius
p.Size = Vector3.new(0.14, 0.14, (p1 - p0).Magnitude)
p.CFrame = CFrame.lookAt((p0 + p1) * 0.5, p1)
p.Color, p.Transparency = color, 0.2
end
end
-- On-screen HUD: keybinds + active features ----------------------------------
local hud = make("Frame", {
Name = "KFHud", AnchorPoint = Vector2.new(0, 1), Position = UDim2.new(0, 14, 1, -14),
Size = UDim2.fromOffset(190, 104), BackgroundColor3 = Color3.fromRGB(15, 23, 30),
BackgroundTransparency = 0.25, BorderSizePixel = 0,
}, gui)
make("UICorner", {CornerRadius = UDim.new(0, 7)}, hud)
make("UIStroke", {Color = Color3.fromRGB(47, 83, 90), Thickness = 1}, hud)
local function hudLine(y, size)
return make("TextLabel", {
Position = UDim2.fromOffset(10, y), Size = UDim2.new(1, -20, 0, size + 4),
BackgroundTransparency = 1, Font = Enum.Font.Code, Text = "", TextSize = size,
TextXAlignment = Enum.TextXAlignment.Left, TextColor3 = Color3.fromRGB(221, 231, 237),
}, hud)
end
local hudTitle = hudLine(6, 13); hudTitle.Text = "KINGFISHER"; hudTitle.TextColor3 = Color3.fromRGB(87, 221, 211)
local hudStrafe, hudMode = hudLine(26, 12), hudLine(44, 12)
local hudSpread, hudActive = hudLine(62, 12), hudLine(82, 11)
connect(UIS.InputBegan, function(input, processed)
if processed or UIS:GetFocusedTextBox() then return end
if input.KeyCode == KEYS.Strafe then
toggles[KEYS.Strafe] = not toggles[KEYS.Strafe]
elseif input.KeyCode == KEYS.Mode then
Config.CircleStrafeMode = Config.CircleStrafeMode == "Orbit" and "BehindBack" or "Orbit"
end
end)
-- No Spread (guns): spread is server-side AND the server validates the shot id,
-- so juggling the id to chase a lucky seed just gets shots rejected. The robust
-- route is the game's own aimed-spread -- a gun reports far less spread when
-- aimed (musket ~0.25 deg vs 3.2 deg hip). So No Spread forces the equipped gun
-- into the server's "aimed" state, WITHOUT zooming the camera, collapsing spread
-- to near zero while shots register normally.
local function installNoSpread()
local Gun = modules.Gun
if type(Gun) ~= "table" or type(Gun.Update) ~= "function" then return end
local old = Gun.Update
Gun.Update = function(self, ...)
if active and Config.NoSpread and self and self.ctx and type(self.ctx.send) == "function" then
self.aiming = true
self.aimStart = self.aimStart or 0
if os.clock() - (self.__kfAimSent or 0) > 0.5 then
self.__kfAimSent = os.clock()
pcall(self.ctx.send, "Aim", {on = true, tool = self.ctx.tool})
end
end
return old(self, ...)
end
end
installNoSpread()
Config.FlySpeed = Config.FlySpeed or 60 -- fly studs/sec
Config.SpeedBoost = Config.SpeedBoost or 32 -- extra studs/sec added along move input
Config.JumpPower = Config.JumpPower or 130 -- Super Jump power
local function stopFly(humanoid)
if flying and humanoid and platformStash ~= nil then humanoid.PlatformStand = platformStash end
flying, platformStash = false, nil
end
-- Super-jump stashes/restores jump power. (Speed is a positional nudge in the
-- movement loop, not WalkSpeed, since the game overwrites WalkSpeed every frame.)
local savedJP, savedUseJP, savedJH
local function applyStatMods(humanoid)
if not humanoid then return end
if active and Config.SuperJump then
if savedUseJP == nil then savedUseJP, savedJP, savedJH = humanoid.UseJumpPower, humanoid.JumpPower, humanoid.JumpHeight end
humanoid.UseJumpPower = true
humanoid.JumpPower = Config.JumpPower
elseif savedUseJP ~= nil then
humanoid.UseJumpPower, humanoid.JumpPower, humanoid.JumpHeight = savedUseJP, savedJP, savedJH
savedUseJP = nil
end
end
-- Free-fly: camera-relative WASD + space/shift, while PlatformStand holds physics
local function manualFly(dt, root, humanoid)
if not flying then platformStash = humanoid.PlatformStand; flying = true end
humanoid.PlatformStand = true
local cam = Workspace.CurrentCamera
local move = Vector3.zero
if cam then
local cf = cam.CFrame
if UIS:IsKeyDown(Enum.KeyCode.W) then move += cf.LookVector end
if UIS:IsKeyDown(Enum.KeyCode.S) then move -= cf.LookVector end
if UIS:IsKeyDown(Enum.KeyCode.D) then move += cf.RightVector end
if UIS:IsKeyDown(Enum.KeyCode.A) then move -= cf.RightVector end
if UIS:IsKeyDown(Enum.KeyCode.Space) then move += Vector3.yAxis end
if UIS:IsKeyDown(Enum.KeyCode.LeftShift) then move -= Vector3.yAxis end
end
if move.Magnitude > 0 then move = move.Unit end
root.CFrame = root.CFrame + move * Config.FlySpeed * math.clamp(dt, 0, 0.1)
root.AssemblyLinearVelocity = Vector3.zero
end
-- Unified movement controller (Heartbeat, after physics). Priority:
-- circle strafe (drives its own fly) > standalone fly > nothing. Speed and
-- super jump apply independently. One PlatformStand owner so nothing fights.
connect(RunService.Heartbeat, function(dt)
local char = player.Character
local root = char and char:FindFirstChild("HumanoidRootPart")
local humanoid = char and char:FindFirstChildOfClass("Humanoid")
pcall(applyStatMods, humanoid)
if not (active and not renderFailed and root and humanoid and humanoid.Health > 0) then
if flying then stopFly(humanoid) end
hideRing()
return
end
local busyUI = UIS:GetFocusedTextBox() or GuiService.MenuIsOpen
local target = (Config.CircleStrafe and toggles[KEYS.Strafe] and not busyUI)
and nearestEnemy(root.Position, Config.CircleRange) or nil
if target and target.root then
local tpos = target.root.Position
if not flying then platformStash = humanoid.PlatformStand; flying = true end
humanoid.PlatformStand = true
local desired
if Config.CircleStrafeMode == "BehindBack" then
desired = tpos - target.root.CFrame.LookVector * Config.CircleRadius + Vector3.new(0, Config.CircleHeight, 0)
else
orbitAngle = orbitAngle + Config.CircleSpeed * math.clamp(dt, 0, 0.1)
desired = tpos + Vector3.new(math.cos(orbitAngle), 0, math.sin(orbitAngle)) * Config.CircleRadius
+ Vector3.new(0, Config.CircleHeight, 0)
end
local goal = CFrame.lookAt(desired, Vector3.new(tpos.X, desired.Y, tpos.Z))
root.CFrame = root.CFrame:Lerp(goal, math.clamp(Config.StrafeSmooth, 0.05, 1))
root.AssemblyLinearVelocity = Vector3.zero
drawRing(Vector3.new(tpos.X, tpos.Y - 2.5, tpos.Z), Config.CircleRadius, Color3.fromRGB(120, 200, 255))
return
end
hideRing()
if Config.Fly and not busyUI then
manualFly(dt, root, humanoid)
return
elseif flying then
stopFly(humanoid)
end
-- Speed: nudge the character along its real move input each frame. Survives
-- the game re-setting WalkSpeed; adds on top of normal walking.
if active and Config.Speed and not busyUI and humanoid.MoveDirection.Magnitude > 0.05 then
root.CFrame = root.CFrame + humanoid.MoveDirection * Config.SpeedBoost * math.clamp(dt, 0, 0.1)
end
end)
-- HUD refresh ----------------------------------------------------------------
connect(RunService.Heartbeat, function()
hud.Visible = active and Config.ShowHud == true
if not hud.Visible then return end
local on, off = Color3.fromRGB(120, 230, 150), Color3.fromRGB(150, 160, 170)
hudStrafe.Text = "[" .. KEYS.Strafe.Name .. "] Circle Strafe"
hudStrafe.TextColor3 = toggles[KEYS.Strafe] and on or off
hudMode.Text = "[" .. KEYS.Mode.Name .. "] Mode: " .. (Config.CircleStrafeMode == "BehindBack" and "Behind-Back" or "Orbit")
hudMode.TextColor3 = Color3.fromRGB(200, 200, 210)
hudSpread.Text = "No Spread"
hudSpread.TextColor3 = Config.NoSpread and on or off
local act = {}
if toggles[KEYS.Strafe] then act[#act + 1] = "STRAFE" end
if flying then act[#act + 1] = "FLY" end
if Config.NoSpread then act[#act + 1] = "NOSPREAD" end
hudActive.Text = #act > 0 and ("ACTIVE: " .. table.concat(act, " ")) or "idle"
hudActive.TextColor3 = #act > 0 and Color3.fromRGB(255, 219, 103) or off
end)
table.insert(destructors, function()
hideRing()
local char = player.Character
local humanoid = char and char:FindFirstChildOfClass("Humanoid")
if flying and humanoid and platformStash ~= nil then humanoid.PlatformStand = platformStash end
flying = false
if humanoid and savedUseJP ~= nil then
pcall(function()
humanoid.UseJumpPower, humanoid.JumpPower, humanoid.JumpHeight = savedUseJP, savedJP, savedJH
end)
end
if hud then hud:Destroy() end
end)
print("[Kingfisher] Loaded. Insert: menu. AIM and AUTO FIRE start OFF. SILENT covers all weapons. Toggle [End] Circle Strafe ([B] mode). Click X to unload.")
return {Settings = Config, Unload = unload, RunMathTests = mathTests}
Tribes 3v3