DaggerFall.
External Linux trainer for Devil Daggers. Pure process_vm_readv/writev — no injection, no driver. Auto-bhop, full air control, a click-through Wayland overlay showing where your daggers land, and a sticky aim assist with lead prediction backed by per-tick velocity estimation.
SYSTEM.TOPOLOGY
LAYER 01 / EXTERNAL
process_vm_readv / writev
no injection · no driver
LAYER 02 / CONFIG
Pointer chain resolution
live .conf reload · 40+ params
LAYER 03 / TARGET
Devil Daggers
Linux x86-64 native · Steam
LAYER 04 / OUTPUT
Bhop · Air Control · Overlay · Aim
5 modes · GTK3/Cairo overlay · 500Hz poll
All read/write via process_vm_readv and process_vm_writev. No ptrace, no injection — pure external memory access from an unprivileged process.
Auto-Bhop
Holds the jump at the exact tick it becomes available every cycle. 500Hz polling loop via process_vm_readv — reads the grounded state and fires a writev on the frame it flips.
- process_vm_readv/writev — no ptrace, no injection overhead
- 500Hz poll cadence — 2ms between reads
- Hold space, trainer handles the rest
- Composes with --strafe for combined air control
Strafe / Air Control
Full 3D air control layered on top of bhop. Instant direction changes mid-air, speed preserved through falls, gravity reduced near the ground for longer hang time.
- Direct velocity writes via process_vm_writev each tick
- Gravity reduction below configurable altitude threshold
- 5-parameter model: accel, max speed, friction, boost zone, boost friction
- All parameters live-tunable via config file — no rebuild
- Hard altitude cap to prevent trajectory abuse
Dagger Prediction Overlay
Click-through GTK3 overlay that projects every dagger's floor intersection in real time. Reads the game's dagger pool each frame and simulates trajectory accounting for gravity, initial velocity, and player velocity inheritance.
- GTK3 + gtk-layer-shell — works on Wayland compositors (wlroots, Hyprland)
- Cairo rendering with input-region masking for click-through
- Reads entire live dagger pool, not just the last shot
- Trajectory math: initial_up, gravity, speed scalar, velocity inheritance
- Read-only mode — zero memory writes
Aim Assist
Sticky targeting with lead prediction. Estimates enemy velocity from delta-position across 16ms ticks, leads the aim point ahead, and locks softly with per-axis smoothing.
- Velocity estimated from Δpos over 16ms — no Rigidbody access needed
- Sticky lock: prefers previous frame's target if still valid — no jitter
- FOV cone search with dot-product culling
- Squid gem positioning: picks the correct gem variant based on facing angle
- Height safety filter — never leads below floor or enemy Y
- LMB-gated: only active while holding left mouse button
Live Diagnostics
Real-time overlay showing position, velocity components, horizontal speed, player state, and active physics parameters. Useful for tuning your config values.
- 16ms readout cadence (GTK timer, 62.5Hz)
- Displays: X/Y/Z position, velocity components, horizontal speed
- Player state: ground / air / fall / dead
- Shows active accel, friction, and speed params from your config
Teleportation
Instantly relocates the hero to any XZ coordinate via a single writev on the position struct. Y is preserved — you land at arena floor height.
- Pass --teleport X Z on the command line
- Single writev on hero position offsets
- Y coordinate preserved — no falling through floor
- Useful for getting to specific arena positions quickly
Trajectory math, movement tuning, and lead prediction
The overlay and aim assist both depend on reading live game state and running predictive math. None of this uses hardcoded constants — all physics params come from your config so they stay accurate across game updates.
Bhop Timing
- Reads the grounded flag each tick via process_vm_readv
- Fires writev on the frame the flag flips — exact jump timing
- 500Hz loop keeps the write within 2ms of the transition
- Composes cleanly with strafe mode — shared tick loop
Air Control Model
- Reads hero velocity, applies accel vector toward WASD input direction
- Speed clamped at max_speed param per tick
- Gravity reduced below h_boost_alt threshold — longer hang time
- Separate boost_friction vs ground_friction for skill expression
- All 5 params live-tuneable in config — no recompile
Dagger Trajectory Simulation
- Reads full dagger pool from game memory each overlay frame
- Per-dagger: initial position, velocity, up component, speed scalar
- Applies gravity constant each simulated tick forward
- Player velocity inheritance scalar applied at fire-time
- Floor intersection computed and projected to screen space via Cairo
Aim Lead Prediction
- Enemy velocity estimated as Δpos / Δt across 16ms ticks
- Lead point: enemy_pos + velocity × (distance / projectile_speed)
- Sticky lock: previous frame's target preferred if still in FOV cone
- Squid variants: gem offset computed from body facing angle
- Height clamp: lead point never placed below floor or enemy Y
How it's built
Single-file implementation, ~1.2k lines
Linux-native cross-process memory access — no ptrace overhead, no injection
Click-through overlay window, Wayland compositor compatible
2D rendering for the prediction overlay and diagnostics
Keyboard input (space detection) on an independent X11 display connection
Key-value plaintext config: pointer chain offsets, struct offsets, physics constants. Searched next to binary, cwd, then ~/.config/
Pointer chain resolution
Hero state sits behind a 3-level pointer chain: a global base address → arena struct → hero struct. Each hop is null-checked before the next read — if any pointer is unmapped (e.g. mid-load, dead state), the chain returns a sentinel and the tick loop skips that cycle rather than crashing.
Offset discovery
Offsets are not distributed with the binary — you'll need to find them for your build of the game using static analysis (Ghidra) or a memory scanner. The config file accepts hex values prefixed with 0x, so you can plug in whatever you find without recompiling. See example.conf for the full list of required keys per mode.
CLI flags
No in-game keybinds — DaggerFall is fully external. All modes are launched from the terminal. The --aim and --strafe flags can be combined for simultaneous overlay and movement control.
Installation
Install dependencies
You need libx11-dev, GTK3 development headers, and gtk-layer-shell. On Arch: pacman -S libx11 gtk3 gtk-layer-shell. On Debian/Ubuntu: apt install libx11-dev libgtk-3-dev libgtk-layer-shell-dev.
Clone and build
git clone https://github.com/luinbytes/dagger-fall && cd dagger-fall && gcc -O2 -o daggerfall daggerfall.c -lX11 -lm $(pkg-config --cflags --libs gtk+-3.0 gtk-layer-shell-0). The binary is a single self-contained executable.
Find your offsets
Copy example.conf to daggerfall.conf. You need to find the pointer chain and hero struct layout yourself using Ghidra or a memory scanner — offsets are not provided. The config file documents which keys are required for each mode.
Launch Devil Daggers first, then run
Start the game via Steam, then run ./daggerfall (or with flags) from a terminal. The trainer reads the process PID and memory base on startup. Press Ctrl-C to stop.
Get the source
Open source. Build it yourself with a single gcc command. Offsets not included — you'll need to find those for your game build.