How to Add Achievements to Non‑Steam Games on Linux — A Step‑by‑Step Guide
A practical walkthrough to install an open‑source achievement tool and integrate it with Lutris, GOG and Proton on Linux — with configs and tips.
How to Add Achievements to Non‑Steam Games on Linux — A Step‑by‑Step Guide
Want Steam‑like achievement tracking for games you bought on GOG or launch through Lutris? A new open‑source achievement tool has made that possible for many non‑Steam titles on Linux. This guide walks you through installing the tool, wiring it into common Linux launchers (GOG installers, Lutris, Proton), and troubleshooting the usual friction points. You’ll also find example community configs and short clip tips so you can share your achievement moments.
What this tool does and when to use it
The open‑source achievement tool works as a lightweight local achievement server + overlay. It listens for game events (via log files, configurable memory hooks, or plugin APIs when available) and displays unlocks and progress in a small overlay. Use it when:
- You own a non‑Steam copy of a game (GOG, itch, retail) and want achievements without repurchasing on Steam.
- You run games through Lutris or a Proton prefix that isn’t registered with Steam.
- You want a community‑driven collection of achievement definitions for niche games.
Prerequisites
Before you begin, make sure you have:
- A modern Linux distro (Ubuntu, Fedora, Arch or derivatives).
- Git and a compiler toolchain if you plan to build from source.
- Optional: OBS or a shortclip tool to capture achievement clips (see the short clips tips below).
- Familiarity with Lutris or the launcher you use for the target game.
Quick install (two-minute summary)
- Clone the repo:
git clone https://github.com/example/achievement-tool.git - Install dependencies: follow the repo README (pip/npm/apt depending on the stack).
- Run the tool once to create a default config:
./achievement-daemon --generate-config - Point the tool at your game using a community config or create a simple rule that watches the game's log file or process name.
- Wrap your game launch so the daemon starts before the game (see wrappers below) or enable the injector if your game supports it.
Step‑by‑step: Installing from source
If the project distributes binaries or a Flatpak/AppImage you can skip straight to the launcher integration step. To build from source, the typical flow is:
git clone https://github.com/example/achievement-tool.git
cd achievement-tool
# Install Python or Node deps depending on the repo
pip3 install -r requirements.txt # or
npm install
# Build/run
./run.sh
If the repository uses C/C++ or Rust for the core, follow the README for cargo/make instructions. The project usually prints a help text describing flags like --prefix, --config, and --verbose.
Integrating with Lutris
Lutris is flexible and works well with this kind of overlay. Two recommended approaches:
1) Wrapper script (simple and robust)
Create a small shell script that starts the achievement daemon, waits for it to be ready, then launches the game. In Lutris, set that script as the game's executable.
# ~/bin/run_my_game_with_achievements.sh
#!/bin/bash
# Start daemon in the background and log to ~/.config/achievements.log
~/.local/bin/achievement-daemon --config ~/.config/achievements/mygame.json &
ACH_PID=$!
# Wait briefly for startup
sleep 1
# Launch the game's original exe
/path/to/game/executable "$@"
# When the game exits, stop the daemon
kill $ACH_PID
In Lutris: Edit the game > Runner options > set the Executable to the script path, and make sure the Working Directory points to the game's folder.
2) Environment loader / LD_PRELOAD (advanced)
If the achievement tool provides an LD_PRELOAD library for overlays or input capture, add it to Lutris' environment variables:
LD_PRELOAD=/path/to/libachieve.so %command%
Use this only if the tool documents an LD_PRELOAD approach. Ways to break games: LD_PRELOAD can cause crashes if libraries mismatch or when used with Proton/Wine versions that differ.
Integrating with GOG (GOG installers / native builds)
GOG Linux installers often unpack to a game folder with a native executable. Options:
- Use the wrapper script method above and create a desktop shortcut pointing to it.
- Install the tool as a systemd user service so it watches for the game's process name and auto‑attaches when the game starts.
Example systemd user service (simple):
[Unit]
Description=Achievements watcher
[Service]
ExecStart=/home/you/.local/bin/achievement-daemon --watch-process mygame
Restart=on-failure
[Install]
WantedBy=default.target
Enable with systemctl --user enable --now achievements.service. This approach lets you launch the game normally from the desktop and still get achievement tracking.
Integrating with Proton (non‑Steam Proton or Proton‑GE)
Proton complicates matters because it's a Wine layer. For games running under a Proton prefix outside Steam (for example, a custom prefix used by Lutris), use the same wrapper approach but ensure the wrapper launches the Proton loader:
# Example for Proton-GE via a Lutris script
export WINEPREFIX=/path/to/proton/prefix
~/.local/bin/achievement-daemon --config ~/.config/achievements/mygame-proton.json &
/path/to/Proton-6.21-GE-1/run /path/to/game/drive_c/path/to/exe.exe
Key pitfalls: make sure the overlay or injector supports X11/Wayland and Wine's graphics stack. If you use a Vulkan game, check that the tool can overlay Vulkan surfaces, or rely on external on‑screen notifications instead.
Community‑submitted configs (examples)
Community configs are the fastest way to get achievements working for a given title. Below are two short example configs submitted by community members — adapt values to your install paths.
Example: GOG native game (JSON)
{
"game": "My GOG Game",
"exe": "/home/you/Games/MyGOGGame/game_binary",
"triggers": [
{"name": "First Blood", "type": "log", "pattern": "Player defeated first enemy"},
{"name": "Collector", "type": "memory", "address": "0x7ffdf00a", "value": ">=10"}
],
"overlay": {"style": "toast", "duration_ms": 2500}
}
Example: Proton game (TOML)
[game]
name = "My Proton Game"
exe = "/path/to/proton/prefix/drive_c/game.exe"
[[triggers]]
name = "Reached Town"
type = "log"
pattern = "Entered Town Center"
[[triggers]]
name = "Speedrunner"
type = "timer"
condition_ms = 1800000
Drop community configs into ~/.config/achievements/ and point the daemon to them.
Short clips: capturing and sharing achievement moments
Short highlight clips are great for community submission and make it easier for config authors to tune triggers. Quick tips:
- Use OBS Studio: set a short hotkey to save replay buffer clips (configure a 30–60s buffer).
- Use simple command line recorders for lightweight clips, e.g. ffmpeg with X11 capture for brief moments:
ffmpeg -f x11grab -video_size 1280x720 -i :0.0 -t 00:00:30 clip.mp4 - Mark clips with the achievement name in the filename and upload to your community thread so config maintainers can verify triggers.
Troubleshooting: common issues and fixes
Overlay not visible (Wayland vs X11)
Wayland can block overlays. Try:
- Switching to X11 session for testing.
- Using the tool's notification backend (system notifications) instead of an in‑game overlay.
Daemon crashes or won’t inject
Check these logs in order:
- Daemon logs:
~/.local/share/achievement-daemon/logs/latest.log - System journal for user services:
journalctl --user -u achievements.service - Wine/Proton logs if running under Proton: export
WINEDEBUG=+relay,+seh,+tidbefore launching.
Triggers not firing
Common causes and checks:
- Wrong log path — make sure the trigger points to the actual file the game writes.
- Encoding mismatch — some games write in UTF‑16 or with Windows line endings; configure the trigger encoding.
- Memory addresses change between versions — use pattern scanning or community offsets instead of hard addresses.
Game crashes after adding LD_PRELOAD
Remove LD_PRELOAD and try the wrapper approach. If you must use LD_PRELOAD, pick a binary that matches the game’s runtime (glibc version, Wine version) or use the daemon approach that doesn’t inject into the process.
Where to get help and contribute configs
Best places for help:
- Project GitHub Issues: file reproducible reports (include distro, Proton/Wine version, and daemon logs).
- Community threads on Reddit or forums for the tool — share short clips and configs.
- Submit working configs as pull requests to the project repo so others can benefit.
Also consider reading related community pieces on newgame.club — for example, if you’re interested in developer journeys, try From Street Art to Game Design: The Artistic Journey of Indie Developers, or if you want to optimize your travel gaming setup while testing on multiple machines check Streamlined Play: Choosing the Right Gaming Gear for Travel.
Final notes and best practices
Achievement systems for non‑Steam games are a community effort. Keep these best practices in mind:
- Share configs and small clips to speed up validation.
- Prefer log‑based triggers where possible — they are version‑stable compared to raw memory pointers.
- Use wrappers or user systemd services when overlays or injection create instability.
With a little setup, you can enjoy achievement unlocks on the vast library of non‑Steam games on Linux. Try a community config first, record a short clip when you hit a milestone, and consider contributing your setup back so others can play and collect too.
Related Topics
Unknown
Contributor
Senior editor and content strategist. Writing about technology, design, and the future of digital media. Follow along for deep dives into the industry's moving parts.
Up Next
More stories handpicked for you
Pop Icons in Gaming: The Next Era of Interactive Entertainment
The Adrian Clan: Who Will Win the Ultimate Match in Competitive Reality Gaming?
Mental Preparation: Staying Focused Amid Championship Buzz
From Street Art to Game Design: The Artistic Journey of Indie Developers
What Coaches Can Learn from Controversial Game Decisions: A Study in Media Strategies
From Our Network
Trending stories across our publication group