Psst... Lumi the AI assistant says hi! You're awesome for using accessibility tools.Skip to content
luinbytes.dev
← Back to projects
Game TrainerOpen Source

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.

Lines of C~1.2k
Source file1
Modes5
Bhop poll500Hz
01 / Features

All read/write via process_vm_readv and process_vm_writev. No ptrace, no injection — pure external memory access from an unprivileged process.

01

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
02

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
03

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
04

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
05

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
06

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
02 / Physics Models

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
03 / Technical Details

How it's built

C / GNU99

Single-file implementation, ~1.2k lines

process_vm_readv/writev

Linux-native cross-process memory access — no ptrace overhead, no injection

GTK3 + gtk-layer-shell

Click-through overlay window, Wayland compositor compatible

Cairo

2D rendering for the prediction overlay and diagnostics

Xlib

Keyboard input (space detection) on an independent X11 display connection

.conf config system

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.

04 / Controls

CLI flags

Movement
(no flag)Auto-bhop only — hold space
--strafeBhop + full air control (hold space + WASD)
Overlay
--aimDagger landing prediction + aim assist overlay
--diagLive diagnostics readout (pos, vel, state)
Utility
--teleport X ZInstantly move hero to XZ coordinates
Composition
--strafe --aimAir control + overlay simultaneously

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.

05 / Setup

Installation

01

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.

02

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.

03

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.

04

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.