Aim
Needs the internal running. Declare needs_internal = true in script_info like the rest of this section. aim.can_reach also works without the internal.
A call stages a request and returns immediately. Nothing fires during the call. A false return is normal. It means the built in aimbot owns the shot, the game is unfocused, or another script holds the window. Read aim.diag().last_reason right after the call to see which.
aim.shoot(target, [opts])
aim.shoot(player_or_vec3 [, {bone = "head", button = "attack", backtrack = true,
silent = true, hold_ms = 0}]) -> booleanStages a corrected shot at a player or a world point and presses the button. Returns true when the press was queued.
| Option | Default | Meaning |
|---|---|---|
bone | "head" | Bone to aim at |
button | "attack" | Any button name: attack, ability1 to ability4, item1 to item4, melee, parry and the rest. An unknown name raises an error |
backtrack | true | Let the shot be judged against a recent position of the target. Only works when the user allows it. After a call, aim.diag().last_shot_bt_allowed is true when they do |
silent | true | false keeps your own aim. The button is still pressed, and backtrack still applies |
hold_ms | 0 | Hold the button this long instead of tapping |
With a player, the aim point is the bone, led by the button's projectile speed. abilityN uses that ability's speed and attack uses the gun's. Hitscan is not led.
local function fire(target, opts)
local ok = aim.shoot(target, opts)
if not ok then
local d = aim.diag()
last_reason = d and d.last_reason or "?"
end
return ok
endaim.shoot(target, { bone = "head", button = "attack", backtrack = true })
aim.shoot(target, { bone = "head", button = "attack", backtrack = true, silent = false })
aim.shoot(target, { bone = "chest", button = "ability1", backtrack = true })
aim.shoot(target, { bone = "head", button = "attack", hold_ms = 40 })aim.silent(pitch, yaw, [opts])
aim.silent(pitch, yaw [, {cmds = 2, always = false, distance = 1024,
target = player, bone = "head", button = "attack"}]) -> booleanArms an angle for the next shot without moving the crosshair and without pressing anything. Your own trigger, or input.tap("attack"), fires it. pitch and yaw use the same convention as camera.get_view_angles().
| Option | Default | Meaning |
|---|---|---|
cmds | 2 | How many firing game ticks the angle corrects before it disarms, 2 to 16. A lower value is raised to 2, because the shot can land on the tick after the press |
always | false | Keep the angle armed for the whole window even if nothing fires |
distance | 1024 | Distance along the ray to the aimed point, 16 to 8192 |
target | none | A player. The point becomes that player's led bone, and distance, pitch and yaw are ignored |
bone | "head" | Bone used with target |
button | "attack" | Which projectile speed leads the point |
Pass target = or the target's real distance. With the default distance, the shot usually misses. Without always, the angle waits up to 375 ms for a shot, corrects the first cmds ticks that fire, then disarms. The point is fixed when you call, so call it again every tick while the target is in the cone.
Why a call returns false
- The internal is not running.
- The built in aimbot owns the shot.
- The game window is not focused.
- The game cursor is visible (menu, shop, chat).
- Another script owns the silent window.
- The target is not alive.
The aimbot wins while it holds a lock. The check runs again at the last moment, so aim.shoot can return false even after aim.get_solution() showed owns_shot clear. Turn the aimbot off when you test a script.
Only one script at a time owns the silent window. Ownership lasts 375 ms after that script's last request. A script that unloads or errors loses ownership and its pending presses.
Timing
aim.shootpresses the button once the corrected angle is armed. If arming takes more than 120 ms, the press is dropped andlast_reasonreadspress dropped: staged shot never published.- A press is also dropped when the button is unbound, the game lost focus, or the game cursor appeared.
- A gun shot (
button = "attack", nohold_ms) is corrected for 2 game ticks. Abilities, items, melee, and any call withhold_ms > 0are corrected for the whole 375 ms window.aim.silentusescmdsas its tick budget. - When the budget runs out, the correction stops. The shot still fires, but along your own aim.
- A tap that comes before the weapon can fire again fires nothing.
aim.can_reach(target, [bone], [detail])
aim.can_reach(player [, bone] [, detail]) -> {ok, why, leash [, lat, up, r]} | nil
aim.can_reach(vec3 [, _] [, detail])
aim.can_reach({x =, y =, z =} [, _] [, detail])
aim.can_reach(x, y, z [, detail])Returns whether a silent shot at that point can be made from where you stand. It is cheap, so call it before staging. Works without the internal.
Bounds, in world units: lateral within 100, vertical within 80, radial under 170, and the game's own 150 unit leash from your pawn.
why is one of ok, no_camera, no_pawn, dead, target_dead, behind, lateral, up, radial, leash. leash is how far from your pawn the shot would be taken, checked against the 150 unit limit. It is -1 when the check stopped before measuring it. To add lat, up and r, the three distances, pass true as the last of at least three arguments, for example aim.can_reach(point, nil, true) or aim.can_reach(x, y, z, true). It returns nil only for a player that can no longer be read. A dead target returns ok = false, why = "target_dead".
Write aim.can_reach(p, "head", true). Passing a boolean as the bone raises an error.
if not internal.is_loaded() then print("internal not loaded: nothing here can fire") end
local sol = aim.get_solution()
if sol and sol.owns_shot then print("the aimbot owns the shot: turn the aimbot off for these tests") end
local reach = target and aim.can_reach(target, "head") or nil
if reach and not reach.ok then print("cannot reach: " .. reach.why) endaim.get_solution()
Returns what the built in aimbot decided this tick, or nil when the internal is not running.
Booleans: valid, key_held, target_pending, owns_shot, bt_allowed. Numbers: target_index, requested_tick, bt_depth, fov. Strings: mode (the configured aim mode, for example mouse, silent or hybrid) and source (script, aimbot or none). target is a player object when the index resolves. When valid is true the table also carries x, y, z, yaw, pitch and bone.
Poll owns_shot before calling aim.shoot.
aim.diag()
Counters for script aim calls. Never nil.
| Group | Keys |
|---|---|
| Requests | silent, shots, presses, dropped, pending_presses |
| Refusals | refused_aimbot, refused_input, refused_owner, refused_other, last_reason |
| Last shot | last_shot_req, last_shot_target, last_shot_bt_allowed |
| Ownership | owner (script index holding the window, -1 for none) |
| Reach | reach_calls, reach_ok, reach_last_leash |
last_reason only means something right after a false return. It can be an empty string.
Example
Arm the angle every tick while a target is in the cone, and let the player's own trigger fire:
local target = best_in_fov(fov_deg, range_m, bone)
if not target then return end
local va = camera.get_view_angles()
local armed = aim.silent(va.x, va.y, { cmds = 1, target = target, bone = bone, button = "attack" })
if test_mode and armed and t - last_tap >= 0.7 then
local ammo = me:get_ammo()
if ammo and ammo < 2 then input.tap("reload"); last_tap = t + 1.5; return end
if input.tap("attack") then taps = taps + 1; last_tap = t end
endThe full script is on Silent Aim on Your Shots. See also Input for the button names, Camera for camera.get_view_angles, and Targeting and Prediction for aim math that needs no internal.