Aim assist
A production-quality aim-assist script with:
- FOV gate (only act on targets near the crosshair)
- Confidence gate (filter out low-confidence detections)
- Exponential smoothing (feels human, not robotic)
- Tunable strength
- All settings exposed as GUI controls
Full script
//!gui:section label="Targeting" mode="expanded"
//!gui:slider var=strength label="Aim Strength" min=0 max=1 default=0.5 step=0.05
//!gui:slider var=fovRadius label="FOV Radius (px)" min=10 max=400 default=120
//!gui:slider var=minConfidence label="Min Confidence" min=0 max=1 default=0.6 step=0.05
//!gui:endsection
//!gui:section label="Smoothing" mode="expanded"
//!gui:slider var=smoothness label="Smoothness" min=0 max=1 default=0.6 step=0.05
//!gui:checkbox var=showFov label="Show FOV circle" default=1
//!gui:endsection
// --- Visualization ---
if (settings.showFov) {
drawCircle(center_x, center_y, settings.fovRadius, "#ff7b85", 1);
}
// --- Gates ---
if (confidence < settings.minConfidence) {
return (0, 0);
}
dx = detection.x - center_x;
dy = detection.y - center_y;
dist = hypot(dx, dy);
if (dist > settings.fovRadius) {
return (0, 0);
}
// --- Initialize smoothing state ---
if (!isset(state.smoothX)) {
state.smoothX = 0;
state.smoothY = 0;
}
// --- Compute raw offset, scaled by strength ---
rawX = dx * settings.strength;
rawY = dy * settings.strength;
// --- Exponential smoothing ---
// Higher smoothness slider → slower response → more human feel
// Rate is normalized to dt so it stays consistent at any FPS
rate = (1.0 - settings.smoothness) * 30;
alpha = 1.0 - exp(-rate * dt / 1000);
state.smoothX = state.smoothX + (rawX - state.smoothX) * alpha;
state.smoothY = state.smoothY + (rawY - state.smoothY) * alpha;
// --- Debug monitor ---
monitor("dist", round(dist, 1));
monitor("conf", round(confidence, 2));
return (state.smoothX, state.smoothY);
How it works
Section grouping
The script opens with two //!gui:section blocks, which group related sliders into collapsible categories in the GUI. The first holds "Targeting" sliders, the second holds "Smoothing".
FOV visualization
drawCircle() paints a circle on the preview window so the user can see the FOV gate. Toggling the Show FOV circle checkbox hides it.
Gates
Two guards short-circuit the script when conditions aren't right:
-
Confidence gate — bail out if
confidenceis below the slider threshold -
FOV gate — bail out if the detection is further than
fovRadiuspixels from the crosshair
Both return (0, 0), which produces no aim adjustment.
Smoothing
The smoothing block is the part that makes the assist feel human instead of snapping. We maintain state.smoothX and state.smoothY across frames and update them each frame by a fraction of the raw error:
state.smoothX = state.smoothX + (rawX - state.smoothX) * alpha;
The alpha value is computed from dt (delta time) and the user's smoothness slider. This makes the effective response rate frame-rate independent — the assist behaves the same at 60 Hz capture or 240 Hz capture.
A smoothness of 0 means alpha ≈ 1 (instant, snappy) and a smoothness of 1 means alpha ≈ 0 (very slow, smooth).
Debug monitor
Two monitor() calls expose live values to the monitor panel, so you can watch what the script is seeing while tuning.
Tuning tips
| Symptom | Try |
|---|---|
| Assist snaps too aggressively | Increase Smoothness toward 0.8+ |
| Assist feels sluggish | Lower Smoothness toward 0.3 |
| Assist tries to track everything | Raise Min Confidence to 0.7+ |
| Assist refuses to engage | Raise FOV Radius, lower Min Confidence |
| Assist stutters near the edge of FOV | Add a soft falloff — multiply strength by 1 - (dist / fovRadius) |
Extension ideas
-
Soft falloff — instead of a hard FOV cutoff, scale strength by distance:
strength * (1 - dist / fovRadius) -
Hold-to-aim — only run the script while a button is held:
if (!makcu.right) { return (0, 0); } -
Pose-aware aiming — for YOLO-Pose models, target a specific keypoint:
target = detection.keypoints[KP.NOSE];(see Detection) -
Track velocity — predict where the target will be next frame:
predX = detection.x + detection.velocityX * lead