AimBuddy
0.3.0-beta.3 · GitHub
More about this app
On-device aim assistant for Android games: real-time screen capture, object detection and target-tracking overlays; optional assisted input through Shizuku injectInputEvent.
AimBuddy
AimBuddy is an AI-based Android aim assistant for real-time screen capture, object detection, target tracking, visual guidance overlays, and optional assisted input.
Project in Brief
- Platform: Android (arm64-v8a)
- App stack: Kotlin + Jetpack Compose + native C++ (JNI)
- Inference: NCNN runtime with Vulkan GPU acceleration (YOLOv26n)
- Training: Python pipeline with Ultralytics, PyTorch, and NCNN export
Runtime Modes
| Mode | Backend | Requires | Features |
|---|---|---|---|
| Visual Assist | none | - | Screen capture, YOLO inference, target tracking, ESP overlays |
| Assisted Input (root) | uinput virtual touchscreen |
Root access | ESP + low-latency touch injection that runs in parallel with the user's finger (separate input stream, real touchscreen is never grabbed) |
| Assisted Input (non-root) | Shizuku injectInputEvent |
Shizuku service + permission | Same parallel-touch behavior with no root, using a virtual deviceId so the aim contact dispatches alongside physical touches |
If neither backend is available, the app stays in Visual Assist Mode and the menu still loads.
Feature Highlights
- Simultaneous user + aim touch on both backends so you can move and aim at the same time.
- Streamer mode - toggle in the ESP tab sets
FLAG_SECUREso the overlay disappears from screen recordings, screenshots, and screen mirroring while staying visible on your own screen. - Chinese (中文) UI language in addition to English. Drop a CJK TTF at
app/src/main/assets/fonts/cjk.ttfto render glyphs. - Event-driven aim loop - first touch lands within one inference cycle of target acquisition; no polling.
- Velocity lead prediction scaled to the measured pipeline delay, so running targets are actually led instead of trailed.
- Adaptive crop that shrinks under GPU pressure to keep
< 10msinference.
How It Works
flowchart LR
A[Screen Capture] --> B[Frame Buffer]
B --> C[YOLO Inference]
C --> D[Target Tracker]
D --> E[Aim Controller]
E --> F[Touch Injection]
C --> G[ESP Overlay]
D --> G
- Capture: MediaProjection captures the game screen at 1280x720.
- Detect: YOLOv26n runs on the GPU via NCNN to detect enemies.
- Track: DeepSORT-style tracker maintains target identity across frames.
- Aim: PD controller steers aim with velocity lead and jitter suppression.
- Render: ESP overlay draws boxes, snap lines, and an ImGui settings menu.
Device Requirements
Runtime (Android Device)
| Item | Minimum | Recommended |
|---|---|---|
| Android | 11 (API 30) | 13+ |
| ABI | arm64-v8a | Snapdragon 888+ |
| Graphics | OpenGL ES 3.1 | OpenGL ES 3.2 + Vulkan |
| RAM | 6 GB | 8 GB+ |
| Storage | 2 GB free | 5 GB+ free |
| Root or Shizuku | Not required for ESP | Either one enables aim assist |
Training (Windows PC)
| Item | Minimum | Recommended |
|---|---|---|
| OS | Windows 10 64-bit | Windows 11 64-bit |
| Python | 3.10 to 3.12 | 3.11 |
| CPU | 4 cores | 8+ cores |
| RAM | 8 GB | 16 GB+ |
| Storage | 15 GB free | 30 GB+ free |
| GPU | CPU-only supported | NVIDIA with CUDA 12.1 |
Quick Start
1. Build and Install
./gradlew.bat clean assembleDebug
./gradlew.bat installDebug
Prerequisites:
- Android SDK 35
- Android NDK 29.0.13113456 rc1
- CMake 3.22.1
- Java 11+
2. First Launch
- Open AimBuddy on your device.
- Grant overlay permission when prompted.
- Pick a backend for aim assist (optional):
- Approve root access for the
uinputbackend, or - Install Shizuku, start the service, and grant the Shizuku permission for the non-root backend. See docs/ShizukuSetup.md for a step-by-step beginner guide.
- Skip both to run in visual-assist mode (ESP only).
- Approve root access for the
- Grant MediaProjection screen capture permission.
- The overlay appears with ESP boxes and a floating settings icon.
3. Train Your Own Model (Optional)
cd training
scripts\00_automate.bat
This single command runs: env setup -> frame extraction -> teacher auto-labelling -> negative mining (if you've dropped frames into raw_frames/negatives/) -> stable train/valid/test split -> dataset validation -> training at imgsz=640 with strong augmentations -> NCNN export at imgsz=256 -> deploy to app/src/main/assets/models/ -> active-learning sweep that surfaces the next batch of frames worth labelling. State checkpoints at each step so re-running resumes from the last failure.
The only manual touch points are:
- Drop gameplay video into
training/videos/. - (Optional) Drop no-enemy frames into
training/raw_frames/negatives/. - Spot-check
training/dataset/train/labels/after the auto-label step and delete obviously-wrong boxes (Roboflow / labelImg take minutes vs the hours of from-scratch labelling).
See the Training Guide for the per-step scripts and the bigger explanation of why this works.
Build Details
Debug Build
./gradlew.bat clean assembleDebug
Release Build
./gradlew.bat clean assembleRelease
Without a configured release keystore this signs with your local debug key and prints a warning. Such an APK is fine for local testing but must not be shared. See Release Signing.
Manual APK Install
adb install -r app/build/outputs/apk/debug/app-debug.apk
If an install fails with "App not installed as package conflicts with an
existing package", a build of com.aimbuddy signed with a different
certificate is still registered on the device. Remove it for every user profile
and retry:
adb uninstall com.aimbuddy
adb shell pm uninstall --user 0 com.aimbuddy
adb shell pm list packages -u | findstr aimbuddy REM should print nothing
The last command also lists uninstalled-but-retained packages, which are the usual cause when you are sure the app is not installed.
Release Signing
Android identifies an installed app by the pair (applicationId, signing
certificate). Every published AimBuddy APK must therefore be signed with one
fixed key. If the certificate changes between releases, users cannot upgrade
and the installer reports a package conflict.
Generate the key once and keep it safe (losing it means every user must uninstall before their next update):
keytool -genkeypair -v -keystore upload.jks -alias aimbuddy `
-keyalg RSA -keysize 4096 -validity 10000
Local release builds. Create keystore.properties in the repo root
(git-ignored):
storeFile=upload.jks
storePassword=<store password>
keyAlias=aimbuddy
keyPassword=<key password>
CI. The workflow feeds the same key to Gradle through
AIMBUDDY_KEYSTORE_FILE, AIMBUDDY_KEYSTORE_PASSWORD, AIMBUDDY_KEY_ALIAS,
and AIMBUDDY_KEY_PASSWORD, populated from the repository secrets listed below.
Base64-encode the keystore for the KEYSTORE_BASE64 secret:
[Convert]::ToBase64String([IO.File]::ReadAllBytes("upload.jks")) | Set-Clipboard
Each release run prints the signer's SHA-256 fingerprint to the job summary. Compare it against the previous release. It must be identical.
Training and Export
From the repository root:
cd training
scripts\07_run_full_pipeline.bat
This runs environment setup, dataset validation, training, and NCNN export.
Key outputs:
| Output | Location |
|---|---|
| Reports | training/outputs/reports/ |
| Weights | training/outputs/runs/detect/train/weights/ |
| NCNN export | training/outputs/export/ |
| Deployment target | app/src/main/assets/models/ |
Individual scripts:
scripts\00_automate.bat REM End-to-end: videos -> NCNN -> deploy
scripts\01_setup_environment.bat
scripts\02_extract_frames.bat
scripts\03_validate_dataset.bat
scripts\04_train_adaptive.bat
scripts\05_train_manual.bat
scripts\06_export_ncnn.bat
scripts\07_run_full_pipeline.bat
scripts\08_auto_label.bat REM Teacher (yolov8x) labels raw_frames
scripts\09_mine_negatives.bat REM Adds empty-label samples
scripts\10_active_learning.bat REM Surfaces next-iter review pool
Releases (CI)
Releases are fully automated by .github/workflows/release.yml. The workflow runs whenever a push to master modifies CHANGELOG.md. It:
- Reads the top non-Unreleased
## [x.y.z] - YYYY-MM-DDheading fromCHANGELOG.md. - Skips if
v<version>already tagged or ifaimbuddy.versionNameingradle.propertiesdoes not match. - Builds the release APK on
ubuntu-latestwith JDK 17, Android SDK 35, NDK 29, CMake 3.22.1, and a Gradle cache. - Signs the APK with the upload keystore. These repository secrets are required, and the job fails rather than publishing an unsigned or debug-signed APK that users could not upgrade:
KEYSTORE_BASE64(base64-encoded JKS upload keystore)KEYSTORE_PASSWORDKEY_ALIASKEY_PASSWORD
- Verifies the APK signature and prints the certificate SHA-256 to the job summary.
- Creates a GitHub Release tagged
v<version>with the changelog section as release notes and the APK attached.
To cut a release: bump aimbuddy.versionName (and aimbuddy.versionCode) in gradle.properties, add a new ## [x.y.z] - YYYY-MM-DD heading to CHANGELOG.md, push to master. The workflow handles everything else.
Documentation
| Document | Contents |
|---|---|
| Architecture | System design, threading, data flow, module reference, input-injection backends |
| Shizuku Setup | Step-by-step setup for the non-root touch backend |
| Settings Guide | Every setting explained, presets, tuning workflow |
| Performance | Pipeline targets, adaptive crop, memory budget, overlay render cap |
| Training | Dataset workflow, auto-labelling, active learning, NCNN export |
| Troubleshooting | Build, runtime, and training issue resolution |
| Changelog | Versioned history of behavior changes |
| Contributing | Code standards, PR process, validation requirements |
Repository Layout
app/ Android app and native runtime
src/main/
java/ Kotlin sources (MainActivity, services)
cpp/ C++ native code
aimbot/ Target tracker, aim controller
detector/ YOLO inference (NCNN)
input/ Touch injection (uinput)
renderer/ ESP overlay, ImGui menu
utils/ Settings, math, logging
assets/models/ NCNN model files
training/ Python training pipeline
scripts/ Batch scripts for each step
config/ Training configuration
dataset/ Training data (not committed)
outputs/ Reports, weights, exports
docs/ Technical documentation
External Credits
Android App and Runtime
Training and Export
See training/requirements.txt and app/build.gradle for exact dependency versions.
License
This project is released under the AimBuddy Community Free Use License v1.0.
Key terms:
- Free use, modification, and redistribution are allowed.
- Selling or commercial monetization is not allowed.
- Derivative works must remain free and use the same license.
- Attribution to the original project is required.
- Software is provided as-is with no warranty and no liability.
See LICENSE for full terms.
Legal and Usage Notice
Use this project only in authorized environments and only where local law, platform policy, and software terms allow such testing.
How Shizuku is used
Can automatically aim in games by injecting synthetic touch moves through Shizuku via `injectInputEvent`.
This is an AI-assisted analysis of Shizuku-related usages in the app's public source code. It is best effort, so it may not catch every single usage.
How this app uses Shizuku
AimBuddy uses Shizuku to enable assisted touch input during gameplay.
- Assisted aim touches: automatically presses, drags and releases a synthetic touchscreen contact at the detected target position through Shizuku, so aim follows targets while the user's own fingers stay usable.
Android APIs or commands used
android.hardware.input.IInputManager.injectInputEventandroid.hardware.input.IInputManager$Stub.asInterface
Notable details
Without Shizuku approval, aim assist stays visual only with detection overlays and screen capture, without synthetic touches.
Changelog
What's new for version 0.3.0-beta.3
Release signing fix, correct in-app version reporting, and a 61% smaller APK.
Fixed
- Installing a release APK failed with "App not installed as package conflicts with an existing package". The release build type was signed with
signingConfigs.debug, whose keystore is per-machine and is regenerated from scratch on a clean CI runner, so every build carried a different signing certificate. Android keys an installed app on (applicationId, certificate), so no two AimBuddy APKs could be installed over one another. Release builds now use a dedicated, stable keystore supplied throughkeystore.propertiesor theAIMBUDDY_KEYSTORE_*environment variables. - The ImGui window title and the Info tab reported
v0.0.0-devin every build. Gradle passedAIMBUDDY_VERSIONto CMake as a cache variable, which the compiler never sees, andCMakeLists.txtnever promoted it to a preprocessor define, soutils/i18n.halways fell through to its default. CMake now defines it for the compiler and warns if Gradle fails to supply it.
Performance
- Release APK shrank from 32.59 MB to 12.66 MB.
proguard-rules.procarried a blanket-keep class androidx.compose.** { *; }, which disabled R8 shrinking across every Compose artifact and pinned the whole ofmaterial-icons-extendedinto the dex. The app references nine icons; dex dropped from 21.64 MB to 2.07 MB with all nine retained. - Dropped v1 (JAR) signing. It is only consulted below API 24 and
minSdkis 30, so its per-entry digests inMANIFEST.MFandCERT.SFwere roughly 93 KB of dead weight. v2 and v3 remain enabled.
Changed
- The release workflow now requires the signing secrets and fails instead of publishing an unsigned or debug-signed APK, verifies the APK signature after building, and prints the signer's SHA-256 fingerprint to the job summary so certificate drift is caught before release.
- Release assets are named
AimBuddy-v<version>.apk; the misleading-signed/-unsignedsuffix is gone. - Local release builds without a configured keystore still fall back to the debug key for convenience, but now warn that the APK must not be distributed; the same fallback is a hard error when
CIis set.
Upgrade note
- Because earlier APKs were signed with throwaway keys, this release cannot be installed over an existing AimBuddy build. Uninstall the old version first (
adb uninstall com.aimbuddy, or long-press the app icon → Uninstall). Subsequent releases will upgrade in place.
Permissions
7 permissions requested