game-install-finder
Find local game install paths across PC game launchers. Supports Steam, Heroic, and Lutris.
game-install-finder discovers local launcher libraries, enumerates installed games, and resolves
game install paths by launcher metadata. It currently reads Steam VDF/ACF metadata, Heroic,
Legendary, sideload, and store-cache JSON, and Lutris pga.db metadata. The tool only reads local
files and does not call any game store or launcher web API.
Features
- Detects Steam, Heroic, and Lutris on Windows, Linux, and macOS where local launcher metadata is available.
- Parses Steam
libraryfolders.vdfwith thevdfpackage instead of brittle string splitting. - Includes games from primary and secondary Steam libraries.
- Reads Steam
appmanifest_*.acffiles to report appid, name, install directory, manifest path, and resolved local game path. - Reads Heroic/Legendary
installed.json, Heroic sideload, Heroic store-cache metadata, and Lutrispga.dbinstalled-game metadata. - Supports exact Steam appid lookup and fuzzy installed-game name matching across launchers.
- Emits machine-readable JSON, with optional pretty printing.
- Keeps project virtualenvs and tool caches under
/tmp/game-install-finderthrough./run.sh.
Installation
Install project dependencies with uv through the repository wrapper:
./run.sh uv sync
The wrapper configures the project virtual environment and caches outside the repository:
UV_PROJECT_ENVIRONMENT=/tmp/game-install-finder/.venv
XDG_CACHE_HOME=/tmp/game-install-finder/.cache
PYTHONPYCACHEPREFIX=/tmp/game-install-finder/__pycache__
TMPDIR=/tmp/game-install-finder
Usage
Run the CLI from the repository root:
./run.sh uv run game-install-finder --help
Print the installed version:
./run.sh uv run game-install-finder --version
List installed games:
./run.sh uv run game-install-finder --list-games --pretty
Print the detected Steam installation path:
./run.sh uv run game-install-finder --steam-path --pretty
Use an explicit Steam root instead of auto-detection:
./run.sh uv run game-install-finder --steam-root PATH --list-games --pretty
Use explicit Heroic or Lutris metadata roots instead of auto-detection:
./run.sh uv run game-install-finder --heroic-root PATH --lutris-root PATH --list-games --pretty
Limit list or fuzzy search results to one launcher:
./run.sh uv run game-install-finder --launcher heroic --appid-from-name NAME --pretty
List games from one launcher:
./run.sh uv run game-install-finder --launcher heroic --pretty
Find an installed Steam game by appid:
./run.sh uv run game-install-finder --app-id APPID --pretty
Find an installed game by appid or name:
./run.sh uv run game-install-finder find 730 --pretty
./run.sh uv run game-install-finder find "counter strike" --pretty
Fuzzy match an installed game name:
./run.sh uv run game-install-finder --appid-from-name NAME --pretty
Suppress fuzzy matches below a minimum score:
./run.sh uv run game-install-finder --appid-from-name NAME --cutoff-score 0.8 --pretty
Enable non-fatal parser and discovery warnings:
./run.sh uv run game-install-finder --list-games --debug --pretty
CLI Options
--steam-path Return detected Steam installation path
--steam-root PATH Use this Steam installation path instead of auto-detection
--heroic-root PATH Use this Heroic or Legendary config path instead of auto-detection
--lutris-root PATH Use this Lutris data path instead of auto-detection
--list-games Enumerate installed games
--launcher LAUNCHER Filter installed games by launcher
--app-id APPID Lookup installed game by appid
--appid-from-name NAME Fuzzy match installed game name to appid
--cutoff-score SCORE Minimum fuzzy match score from 0.0 to 1.0
--pretty Pretty-print JSON output
--debug Print non-fatal parser/discovery warnings to stderr
--version Print the installed version and exit
find QUERY Find by appid when QUERY is numeric, otherwise by name
JSON output
All successful commands include steam_path. Additional fields depend on the selected lookup.
--list-games adds games, an array of records shaped like:
{
"appid": "730",
"launcher": "steam",
"name": "Counter-Strike: Global Offensive",
"installdir": "Counter-Strike Global Offensive",
"path": "/home/user/.local/share/Steam/steamapps/common/Counter-Strike Global Offensive",
"exists": true,
"source": "/home/user/.local/share/Steam/steamapps/appmanifest_730.acf",
"library": "/home/user/.local/share/Steam",
"manifest": "/home/user/.local/share/Steam/steamapps/appmanifest_730.acf"
}
--app-id APPID adds:
{
"game": {
"appid": "730",
"launcher": "steam",
"name": "Counter-Strike: Global Offensive"
},
"app_path": "/home/user/.local/share/Steam/steamapps/common/Counter-Strike Global Offensive"
}
find QUERY uses the same output fields as the legacy lookup flags. Digits-only queries use the
--app-id behavior. Every other query uses the --appid-from-name behavior.
Heroic and Lutris records use the same shape and include launcher, name, path, exists, and
source; Steam-only fields such as library, manifest, and installdir are null when they do
not apply. Heroic discovery reads installed.json, store installed metadata such as
gog_store/installed.json, sideload_apps/library.json, and
store_cache/{gog,legendary,nile}_library.json. Sideload entries resolve absolute folder_name
values directly, relative folder_name values under defaultSettings.defaultInstallPath, and
install.executable values to their parent directory.
--appid-from-name NAME adds match, candidates, and score. By default it searches Steam,
Heroic, and Lutris records; use --launcher to narrow the search. If no confident fuzzy match is
found, match is null and candidates still lists the closest installed game names.
Use --cutoff-score SCORE to override the default minimum score; matches below that cutoff are
suppressed while candidates and score remain in the output.
Errors are emitted as JSON and return a non-zero exit code:
{
"error": "Steam installation not found"
}
Dependency requirements
- Python 3.12 or newer for this project.
uvfor dependency management, packaging, and command execution.- Runtime dependency:
vdf, used to parse Steam VDF and ACF metadata. - Heroic metadata is parsed with the Python standard library
json. - Lutris metadata is parsed with the Python standard library
sqlite3. - Development tools:
pytest,pytest-cov,ruff, andty.
Development
Run all project commands through ./run.sh:
./run.sh uv run ruff check . --fix
./run.sh uv run ruff format .
./run.sh uv run ty check src/
./run.sh uv run pytest
Build the package with uv:
./run.sh uv build --no-sources
The repository follows the local agent protocol in AGENTS.md: plans live under docs/plans/,
tests must precede implementation changes, and generated caches must stay outside the repository.
Publishing
PyPI publishing is configured for GitHub Actions Trusted Publishing. The PyPI project should be configured with:
- Project name:
game-install-finder - Owner:
beallio - Repository name:
game-install-finder - Workflow name:
workflow.yml - Environment name:
pypi
Release by pushing a version tag after the GitHub repository and PyPI Trusted Publisher are set up:
git tag -a v0.1.0 -m v0.1.0
git push origin v0.1.0
License
MIT - See LICENSE for details.
Metadata
Release files for game-install-finder 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| game_install_finder-0.4.0.tar.gz | 11.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| game_install_finder-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 24.1 kB
Release files / game_install_finder-0.4.0.tar.gz
| Download URL | game_install_finder-0.4.0.tar.gz |
|---|---|
| Size | 11.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
24437a6a8f2f3c854e3a90e9073000b8e1168d0b552e792cda410b20f5362c5e
|
|
BLAKE2b-256 checksum How to use checksums |
6bd7ffa95f18e43ac39f78ea953ae30c5f343edd659c9165578ef482741bf765
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / game_install_finder-0.4.0-py3-none-any.whl
| Download URL | game_install_finder-0.4.0-py3-none-any.whl |
|---|---|
| Size | 12.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
56446b0597e8cf9bb15980d4a3bebc539c15e2d2f572060c186ccca6a9ed862c
|
|
BLAKE2b-256 checksum How to use checksums |
02b1e20df2f94cedd3613f7ab2bf4a2849f69edffdb56f4c5c1b531275524c52
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|