No description
Find a file
joe ab27d114ff
Add Makefile, README, and gitignore
make install puts the scripts in /usr/local/bin (on native Steam's PATH, hence
sudo) and the example config in the invoking user's ~/.config, only if absent so
an existing config is never clobbered. install-config-force overwrites on
request; uninstall removes the scripts and leaves the config. README documents
the components, install, usage, and config format.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 16:44:00 +01:00
bin Add game-launcher-add helper for registering Steam games 2026-06-16 16:44:00 +01:00
config Add launch_options CLI and example config 2026-06-16 16:43:59 +01:00
.gitignore Add Makefile, README, and gitignore 2026-06-16 16:44:00 +01:00
Makefile Add Makefile, README, and gitignore 2026-06-16 16:44:00 +01:00
README.md Add Makefile, README, and gitignore 2026-06-16 16:44:00 +01:00

game-launcher

A small per-game launch-options manager for Steam on Linux.

Steam only lets you set one launch-option string per game, and editing it for tweaks (different resolutions, wrappers like gamemoderun/mangohud/gamescope, Proton env vars, pre/post hooks) is tedious. This project moves all of that into a single config file and an optional picker dialog, so one Steam launch option — game-launcher %command% — drives every game.

Components

Component Installed to Role
launch_options /usr/local/bin/launch_options Python CLI. Resolves a game alias or Steam AppID to a canonical key and prints the launch command for a named mode, or lists games/modes.
game-launcher /usr/local/bin/game-launcher Bash wrapper you set as a game's Steam launch option. Reads $SteamAppId, asks launch_options for the game's modes, shows a yad picker when there's more than one, substitutes %command%, and runs it.
game-launcher-add /usr/local/bin/game-launcher-add Interactive helper. Lists your installed Steam games, lets you pick one, asks for a friendly name, and adds the alias (name + AppID) plus a starter section to your config.
launch_options.ini ~/.config/launch_options.ini Your data: alias map plus a section of named modes per game.

The scripts install to a system directory (/usr/local/bin) rather than ~/.local/bin because native Steam doesn't reliably put ~/.local/bin on the PATH it launches games with, so game-launcher %command% wouldn't resolve. /usr/local/bin is on the standard system PATH that Steam inherits.

launch_options and launch_options.ini are usable on their own (e.g. to print a command); game-launcher is the Steam integration layer on top.

Install

sudo make install

sudo is needed because the scripts go to /usr/local/bin (a system directory on Steam's PATH). The config still lands in the invoking user's ~/.config/launch_options.ini — the Makefile detects $SUDO_USER so it never ends up in /root — and is installed only if you don't already have one (your existing config is never clobbered).

Override locations with the standard variables:

sudo make install PREFIX=/usr            # scripts to /usr/bin
sudo make install BINDIR=/opt/bin
make install-config CONFIGDIR=~/.config  # config only, no sudo

Other targets:

  • make install-config — install just the config (only if absent), no sudo.
  • make install-config-force — (re)install the bundled config, overwriting the existing one.
  • sudo make uninstall — remove the scripts (your config is left in place).
  • make help — list targets and show the resolved install paths.

Requirements

  • python3 (standard library only) for launch_options.
  • bash and yad for game-launcher's picker.
  • Whatever each mode invokes — gamemoderun, mangohud, gamescope, etc.
  • Native Steam (the scripts target /usr/local/bin on its PATH). Flatpak Steam runs sandboxed and won't see host /usr/local/bin without extra setup.
  • Optional: fzf for a nicer game picker in game-launcher-add (it falls back to a numbered menu without it).

Usage

  1. In Steam, set the game's launch option to:

    game-launcher %command%
    

    (Run game-launcher in a terminal with no SteamAppId set and it prints this line for you.)

  2. Add the game to ~/.config/launch_options.ini. The quickest way is:

    game-launcher-add
    

    It lists your installed Steam games, lets you pick one, asks for a friendly name, and writes the alias (name + AppID) plus a starter section for you. Then edit that section to define the game's modes (see below). Or add it by hand.

  3. Launch from Steam. If the game has more than one mode, a picker appears; otherwise it launches directly. Each run is logged to /tmp/game-launcher.log.

You can also query the config directly:

launch_options cs2              # print the 'default' mode's command for cs2
launch_options cs2 fullscreen   # print the 'fullscreen' mode's command
launch_options --list           # list every game and its modes
launch_options --list cs2       # list modes for one game

Config format

~/.config/launch_options.ini is an INI file with two kinds of section.

[aliases] maps any string — a short name or a Steam AppID — to a canonical game key. Mapping the AppID is what lets game-launcher resolve a game from $SteamAppId automatically.

[aliases]
; 730 is CS2's Steam AppID
cs2 = cs2
730 = cs2

Comments must be on their own line. configparser here has inline comments disabled, so a ; after a value is kept as literal text (and in a mode command it's a shell command separator) — not a comment.

[<game-key>] sections define named modes. Each value is a command line containing the %command% placeholder, which is replaced with the actual game invocation Steam would have run. Env vars, wrappers, pre/post hooks (separated by ;), and trailing game args all go here.

[cs2]
default    = SDL_VIDEO_DRIVER=wayland mangohud %command% -w 1920 -h 1440
overlay    = SDL_VIDEO_DRIVER=x11 mangohud %command% -w 1920 -h 1440
fullscreen = %command% -w 2560 -h 1440

A game with a single default mode launches without a prompt; multiple modes trigger the picker. Game keys are matched case-insensitively with whitespace collapsed. Override the config path with the LAUNCH_OPTS_INI environment variable.

[vars] (optional) holds reusable fragments, referenced as %name% in any mode and expanded before launch. Handy for something shared across a game's modes:

[vars]
autoexec = +exec autoexec.cfg

[cs2]
default = mangohud %command% %autoexec% -w 1920 -h 1440
plain   = %command% %autoexec% -w 1920 -h 1440

Only names defined in [vars] are expanded — %command% and shell syntax ($VAR, ${VAR}, $(...)) pass through untouched. Vars may reference other vars. (This is a small custom mechanism, not configparser interpolation, which would collide with %command% and shell ${...}.)

Security note

game-launcher evals the selected mode string, so the config file is trusted, executable input. Only put commands in it you'd be willing to run yourself.