mangohud-logger-steamos/README.md
Gavin Nugent aeb84a3d68 Support SteamOS Game Mode: global logging via MANGOHUD_CONFIG
The previous override targeted gamescope-session-plus only. On stock
SteamOS (/usr/lib/steamos/gamescope-session) that override is never
sourced and the session forces MANGOHUD_CONFIGFILE=<tmp>/no_display,
so no logs were produced. Detect the session flavor and, on SteamOS,
set MANGOHUD_CONFIG in environment.d — it overrides the forced config
file and enables logging globally with no per-game launch options.
Verified with a vkcube precedence test (412-row CSV) and end-to-end in
a live SteamOS 3.9 Game Mode session (DREDGE, 1039-row mangoapp CSV).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 22:29:50 +01:00

180 lines
7.3 KiB
Markdown
Executable file

# mangohud-logger
One-touch toggle for MangoHud CSV logging on Linux gaming-launcher systems
(SteamOS Game Mode, DeckShift, super-alt-S, plain `gamescope-session-plus`, or
any setup that already uses MangoHud).
Run the script — it switches logging on if it's off, off if it's on. CSV
samples land in `~/Downloads/mango-logs/`. That's the entire interface.
## Why this exists
Getting MangoHud to *actually* write logs from a Steam-via-gamescope game
turns out to be a multi-step setup, and every step has a non-obvious gotcha.
Worse, the *right* setup differs depending on which gamescope session manager
your distro ships. This script detects that and handles it so you don't have to.
## What it changes
The script writes marker-tagged files (so it can clean them up on disable, and
won't trample anything you wrote by hand):
1. **`~/.config/MangoHud/MangoHud.conf`** — appends a marker-bracketed block
with `output_folder`, `autostart_log=1`, `log_duration=0` (= until you
quit), `log_interval=100`, `toggle_logging=Shift_L+F2`, and a
`no_display=0` override. (Also serves as the on/off state marker.)
2. **`~/.config/environment.d/95-mangohud-logger.conf`** — contains:
- `MANGOHUD=1` so the Vulkan loader auto-injects MangoHud into every game.
- `MANGOHUD_CONFIG=<inline copy of the logging keys>`. This is the important
one for SteamOS Game Mode — see [Game Mode](#steamos-game-mode) below.
Requires a logout/login to take effect (systemd-user only reads
`environment.d/*.conf` at session start).
3. **`~/.config/gamescope-session-plus/sessions.d/steam`** — *only written on
the `gamescope-session-plus` session flavor* (see flavor detection below).
A user-level override that unsets the system's `MANGOHUD_CONFIGFILE` and
turns off `STEAM_USE_MANGOAPP`. Not written on stock SteamOS.
When you toggle it off, the script removes everything it wrote.
## Session-flavor detection
Game Mode is launched differently on different distros, and the fix differs
too. On enable, the script detects which one you have (`detect_gs_flavor`):
| Flavor | Detected by | What the script does |
|--------|-------------|----------------------|
| `plus` | `/usr/share/gamescope-session-plus/sessions.d/steam` exists | Writes the `sessions.d/steam` override (file #3). |
| `steamos` | `/usr/lib/steamos/gamescope-session` exists | Skips file #3; relies on `MANGOHUD_CONFIG` (file #2). See below. |
| `none` | neither | Desktop-only; `MANGOHUD=1` is enough for Vulkan games. |
## SteamOS Game Mode
Stock SteamOS (e.g. 3.x "holo") launches Game Mode via
`/usr/lib/steamos/gamescope-session`, **not** `gamescope-session-plus`. That
session script unconditionally does:
```bash
export STEAM_USE_MANGOAPP=1
export MANGOHUD_CONFIGFILE="$tmpdir/mangohud.config" # written with just "no_display"
```
and it **sources no user override file** — so the old `sessions.d/steam` trick
does nothing here, and you can't override `STEAM_USE_MANGOAPP` from
`environment.d` (the session exports it afterwards).
**How logging actually works here:** the on-screen overlay in Game Mode is
**mangoapp** (a compositor overlay), and mangoapp *is* MangoHud — it can write
CSV logs itself. Steam launches mangoapp with your systemd user environment, so
it inherits the `MANGOHUD_CONFIG` from file #2. `MANGOHUD_CONFIG` takes
precedence over the session's `no_display` `MANGOHUD_CONFIGFILE`, so mangoapp
picks up `autostart_log`/`output_folder` and logs every game — **no per-game
launch options needed.**
Notes:
- Logs are named **`mangoapp_<timestamp>.csv`** (the logger is mangoapp, not the
in-game layer), so a file spans a Game Mode session rather than one-per-game.
- **You must fully restart into Game Mode once after enabling** (log out/in or
reboot) so mangoapp inherits `MANGOHUD_CONFIG`. If you enable while already in
Game Mode, that session won't have it and nothing logs.
- Verified on SteamOS 3.9 with MangoHud 0.8.3-rc1: a Proton game (DREDGE) in
Game Mode produced a 1039-row `mangoapp_*.csv` of real fps/frametime data.
**Per-game fallback** (if you don't want to restart the session, or want the
in-game Vulkan layer instead of mangoapp): set this in a game's
*Steam → Properties → Launch Options*:
```
MANGOHUD_CONFIGFILE=$HOME/.config/MangoHud/MangoHud.conf mangohud %command%
```
## Gotchas it works around
- **`no_display` blocks `autostart_log`.** MangoHud's `autostart_log` rides on
the render hook that `no_display` disables, so the log never starts. The
script's block ends with `no_display=0`. Tradeoff: while logging is on, the
HUD is visible during games.
- **The system session forces a `no_display` config file.** Both session
flavors export `MANGOHUD_CONFIGFILE` pointing at a temp file containing only
`no_display`, which would suppress your real config. On `plus` the script
unsets that var; on `steamos` the `MANGOHUD_CONFIG` env var overrides it.
- **Steam uses `mangoapp` instead of the in-game Vulkan layer in Game Mode.**
`STEAM_USE_MANGOAPP=1`. On `steamos` you can't turn this off globally — so the
script leans into it and lets mangoapp do the logging (see above). On `plus`
the override sets `STEAM_USE_MANGOAPP=0` to use the in-game layer.
- **`log_duration=0` means "log forever".** Empirically `0` = log until you quit
or hit the toggle key.
- **`MANGOHUD=1` only injects the Vulkan layer.** OpenGL-only games still need
`mangohud %command%` in Steam launch options or an `LD_PRELOAD` wrapper.
## Install
Requires `mangohud` (and `lib32-mangohud` for 32-bit games). On Arch / SteamOS:
```bash
sudo pacman -S mangohud lib32-mangohud
```
Then:
```bash
git clone https://github.com/28allday/mangohud-logger-steamos.git
cd mangohud-logger-steamos
chmod +x mangohud-logger.sh
./mangohud-logger.sh
```
Or copy the script anywhere on `$PATH`:
```bash
install -Dm755 mangohud-logger.sh ~/.local/bin/mangohud-logger
mangohud-logger
```
## Usage
```bash
./mangohud-logger.sh
```
No flags, no subcommands. First run enables; second run disables. After the
first enable, **log out and back in** (Game Mode users: fully restart into Game
Mode) so the env vars become effective. You only need to do that once.
In-game keys (set by the script's MangoHud block):
| Key | Action |
|---|---|
| `Shift+F2` | Toggle logging on/off mid-game |
| Your existing `toggle_hud` key | Hide the HUD overlay (logging keeps running) |
CSV files appear in `~/Downloads/mango-logs/`. Drop them into
<https://flightlessmango.com/> for graphs, or open in a spreadsheet.
## Compatibility
- **SteamOS Game Mode** (`/usr/lib/steamos/gamescope-session`) — logs via
mangoapp; see [Game Mode](#steamos-game-mode).
- **DeckShift** ([28allday/DeckShift](https://github.com/28allday/DeckShift))
— gamescope-session-plus based.
- **super-alt-S** ([28allday/super-alt-S-cachy-deckmode](https://github.com/28allday/super-alt-S-cachy-deckmode))
— KDE-Plasma gaming mode on CachyOS.
- **Plain `gamescope-session-plus`** on any Arch-based distro.
- **Steam without gamescope** — works too; the gamescope override becomes a no-op.
- **Non-systemd distros** — the `environment.d` file won't be read; set
`MANGOHUD=1` (and `MANGOHUD_CONFIG`) via your distro's env-var mechanism.
## Honours XDG
Log folder is `$XDG_DOWNLOAD_DIR/mango-logs` (resolved via `xdg-user-dir`),
config dir is `$XDG_CONFIG_HOME` — works on non-English locales.
## License
MIT