Launching steam games with gamescope and mangohud

I installed gamescope and mangohud with nixos config file. I tried to run dota2 annd down of war 3 with
gamescope -e %command% launch option in steam but I didn’t have any success
I also tried /usr/bin/env gamescope -e %command%
I also tried from terminal with gamescope -e steam-run
It seems that the problem is not in the gamescope because I was able to run firefox and steam itself in gamescope context.
My expectation is that steam games run in special environment and I need to twaek some settings
Anyone tried this before ?

Anything started by steam is running inside its FHS container, so you’ll need to override the FHS container to get those commands in PATH.

1 Like

Thanks. Any idea how I can do that ?
Edit:
I tried this but it didn’t work

  nixpkgs.config.packageOverrides = pkgs: {
    steam = pkgs.steam.override {
      extraPkgs = pkgs: with pkgs; [
        gamescope
        mangohud
      ];
    };
  };

I expect that there should be a way to expose some environment stuff but I can’t find the way

Hmm… that should work. Are you sure the override is actually being applied? (you don’t provide pkgs in a more direct way that overrides the nixpkgs options, for example?)

Ok it seem that it changed something there are some missing parts

I tried this

steam-run gamescope ./dota.sh

Which did’t crash immediately which mean gamescope is present in that context

Unfortunately the output do not give me enough feedback to understand whats wrong
I probably need to change the rights of something but I don’t know how and to what

No CAP_SYS_NICE, falling back to regular-priority compute and threads.
Performance will be affected.
wlserver: [backend/headless/backend.c:82] Creating headless backend
vulkan: selecting physical device 'AMD Radeon RX 460 Graphics (RADV POLARIS11)': queue family 1
vulkan: physical device does not support DRM format modifiers
vulkan: supported DRM formats for sampling usage:
vulkan:   0x34325241
vulkan:   0x34325258
vulkan:   0x3231564E
wlserver: Running compositor on wayland display 'gamescope-0'
wlserver: [backend/headless/backend.c:18] Starting headless backend
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us
wlserver: [xwayland/sockets.c:216] No display available in the first 33

Actually, it doesn’t. I’m sure the steam FHS does not contain zsh, but

$ steam-run zsh -c 'echo test'
test

I think steam-run uses your external PATH, not what’s available to steam inside.

isn’t gamescope something you run to have a graphical session, instead of logging into a desktop environment?

I am also curious how to get this working, gamescope can run with vkcube in terminal but not through steam

This is what I would recommend to get all the latency benefits it is supposed to provide, but it can also be launched in a nested mode from within an existing desktop session. I guess the main reason someone would want to do that is probably to use a different screen size than the one used by your top-level DE.

I think most people are doing it this way because those are what all the examples in the readme look like:

I don’t know much about that usecase though as I only use it directly as a graphical sesion via:

1 Like

I Installed zsh in the overlay and ran

steam-run zsh -c 'gamescope --help'

And get the following result which means that gamescope is present

usage: gamescope [options...] -- [command...]

Options:
  --help                         show help message
  -w, --nested-width             game width
  -h, --nested-height            game height
  -r, --nested-refresh           game refresh rate (frames per second)
  -m, --max-scale                maximum scale factor
  -i, --integer-scale            force scale factor to integer
  -W, --output-width             output width
  -H, --output-height            output height
  -n, --nearest-neighbor-filter  use nearest neighbor filtering
  -U, --fsr-upscaling            use AMD FidelityFX™ Super Resolution 1.0 for upscaling
  -Y, --nis-upscaling            use NVIDIA Image Scaling v1.0.3 for upscaling
  --sharpness, --fsr-sharpness   upscaler sharpness from 0 (max) to 20 (min)
  --cursor                       path to default cursor image
  -R, --ready-fd                 notify FD when ready
  --rt                           Use realtime scheduling
  -T, --stats-path               write statistics to path
  -C, --hide-cursor-delay        hide cursor image after delay
  -e, --steam                    enable Steam integration
  --xwayland-count               create N xwayland servers
  --prefer-vk-device             prefer Vulkan device for compositing (ex: 1002:7300)
  --force-orientation            rotate the internal display (left, right, normal, upsidedown)

Nested mode options:
  -o, --nested-unfocused-refresh game refresh rate when unfocused
  -b, --borderless               make the window borderless
  -f, --fullscreen               make the window fullscreen

Embedded mode options:
  -O, --prefer-output            list of connectors in order of preference
  --default-touch-mode           0: hover, 1: left, 2: right, 3: middle, 4: passthrough
  --generate-drm-mode            DRM mode generation algorithm (cvt, fixed)
  --immediate-flips              Enable immediate flips, may result in tearing
  --adaptive-sync                Enable adaptive sync if available (variable rate refresh)

Debug options:
  --disable-layers               disable libliftoff (hardware planes)
  --debug-layers                 debug libliftoff
  --debug-focus                  debug XWM focus
  --synchronous-x11              force X11 connection synchronization
  --debug-hud                    paint HUD with debug info
  --debug-events                 debug X11 events
  --force-composition            disable direct scan-out
  --composite-debug              draw frame markers on alternating corners of the screen when compositing
  --disable-xres                 disable XRes for PID lookup

Keyboard shortcuts:
  Super + F                      toggle fullscreen
  Super + N                      toggle nearest neighbour filtering
  Super + U                      toggle FSR upscaling
  Super + Y                      toggle NIS upscaling
  Super + I                      increase FSR sharpness by 1
  Super + O                      decrease FSR sharpness by 1
  Super + S                      take a screenshot

I still believe that this warning is the clue whats going on

wlserver: [xwayland/sockets.c:99] /tmp/.X11-unix not owned by root or us

Probably this file/socket have wrong owner

Edit:
Look like im right

steam-run zsh -c 'ls -la /tmp/ | grep unix'
drwxrwxrwt  2 nobody nogroup   4096 dec  9 22:51 .font-unix
drwxrwxrwt  2 nobody nogroup   4096 dec 13 18:27 .ICE-unix
drwxrwxrwt  2 nobody nogroup   4096 dec 13 18:27 .X11-unix
drwxrwxrwt  2 nobody nogroup   4096 dec  9 22:51 .XIM-unix

It seems that all of the files in that directory have no user and group
Any idea how I can fix that. Something with the overlay ?

Ok there are more problems to solve Im able to run dota 2 with this command

steam-run mangohud ./dota.sh

But I’m unable to run it from steam with that launch option

mangohud %command%

I’ve still not seen any evidence that the overlay is actually having any effect. Depending on what environment you’re in (nixos, hm, flakes/no), there are a few ways the option could be present but not actually affect pkgs at all.

This seems like the most likely explanation of the issue to me, but there’s no way to know without a lot more context.

How I can provide that evidence

maybe set steam = {}; in the overlay and see if it fails? If the overlay isn’t taking effect it should never try to use it and never notice that it’s not a package. If it does fail, then the code you put in that spot is definitely having an effect.

I tried with this line

find / -name gamescope

And that line poped

/nix/store/5wznpnhr0m1cmchiijgr6asipbm797wv-steam-fhs/usr/bin/gamescope

Which should be enough of a proof

Yeah, that’s conclusive. (At least that something you did since you last gc’ed had an effect anyway. You’d have to trace whether that storepath is the one you’re actually using to be 100% sure) You’ve verified that you still can’t use gamescope %command% as a launch command inside steam? (and you did restart steam, right?)

I manage to delete all old generation and reach state like this

>>> find /nix/store -name gamescope
/nix/store/3kx5faq7cppmbb54ialvzx5invhp35jh-nixos-22.11/nixos/pkgs/applications/window-managers/gamescope
/nix/store/xn5q6qbgmbqx68yi053x7iz3j161j1fj-gamescope-3.11.49/bin/gamescope
/nix/store/0bwrcc28m6zsqvjxs7inqdacd3cg7qsd-system-path/bin/gamescope
/nix/store/jy4zzfrahciwllaigpbdd05gc7lz6bc7-system-path/bin/gamescope

which should mean that gamescope in steam_fhs

After I put gamescope in steam overlay I get this

>>> find /nix/store -name gamescope
/nix/store/mgnsis3cm84vfp1f1knhg95y966gk0pl-steam-usr-target/bin/gamescope
/nix/store/i4742ray4086d2c0pv6vj7cdr403w98a-steam-fhs/usr/bin/gamescope
/nix/store/3kx5faq7cppmbb54ialvzx5invhp35jh-nixos-22.11/nixos/pkgs/applications/window-managers/gamescope
/nix/store/mslpg55qkpj459xdbyb414bz64i5nhs9-steam-usr-target/bin/gamescope
/nix/store/xn5q6qbgmbqx68yi053x7iz3j161j1fj-gamescope-3.11.49/bin/gamescope
/nix/store/k5sc68i2c0yxhzlcja8b06fajbxqs7xv-steam-run-fhs/usr/bin/gamescope
/nix/store/0bwrcc28m6zsqvjxs7inqdacd3cg7qsd-system-path/bin/gamescope
/nix/store/jy4zzfrahciwllaigpbdd05gc7lz6bc7-system-path/bin/gamescope
/nix/store/8qfj4a63rgzbclnj76219lsa3l3iflfs-system-path/bin/gamescope
/nix/store/z56qidvb0b2ad51k6799ilk1iw87f5r3-steam-run-usr-target/bin/gamescope
/nix/store/5wznpnhr0m1cmchiijgr6asipbm797wv-steam-fhs/usr/bin/gamescope

Which should mean that I have gamescope in the fhs in current generation
And It do not wortk. I will restart my machine to be sure that steam is restarted in case pkill -9 steam did’t kill all steam processes

The restart didn’t help
I will continue my investigation later but I strongly believe that the problem lay in the /tmp/.X11-unix ownership

FWIW I’ve been experimenting with gamescope a lot yesterday, it’s been a mess:

  • from a TTY, I can use gamescope to run steam in a session, but it doesn’t have sound
  • steam -gamepadui (to have the same UI as the steam deck) can be run but games windows aren’t shown :woman_facepalming:t3: (not even specific to gamescope)
  • steam flatpak + gamescope flatpak allows to start games with a gamescope command line, and it’s working fine
  • nixos steam + nixos gamescope can’t be used per game because of the /tmp/.X11-unix issue
  • running steam with gamescope entirely is working fine, if so I recommend the following command: gamescope -f -e -U -- steam -tenfoot, it displays steam in big picture mode (otherwise it displays a loading screen and nothing else :woman_facepalming:t3: ), and this doesn’t enforce a resolution for the games/steam, but if you reduce resolution in-game, then FSR kicks in, I find it a lot more practical this way as it’s wrapping steam and all games…
  • I couldn’t get mangohud to work with flatpak (using it from flatpak)
  • with gamescope, you need mangoapp and not mangohud, and it is started differently, like in this example gamescope -- /bin/sh -c 'mangoapp& steam'

Thanks for your effort
I continued my research and found that I waste my time so far :slight_smile:
It seems that steam-run is something not provided or used by valve but nix script
The issue with certain files dont have owner and group is probably caused by bug in that script and have nothing to do with steam unable to run gamescope

#!/nix/store/dsd5gz46hdbdk2rfdimqddhq6m8m8fqs-bash-5.1-p16/bin/bash
blacklist=(/nix /dev /proc /etc)
ro_mounts=()
symlinks=()
for i in /nix/store/k5sc68i2c0yxhzlcja8b06fajbxqs7xv-steam-run-fhs/*; do
  path="/${i##*/}"
  if [[ $path == '/etc' ]]; then
    :
  elif [[ -L $i ]]; then
    symlinks+=(--symlink "$(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink "$i")" "$path")
    blacklist+=("$path")
  else
    ro_mounts+=(--ro-bind "$i" "$path")
    blacklist+=("$path")
  fi
done

if [[ -d /nix/store/k5sc68i2c0yxhzlcja8b06fajbxqs7xv-steam-run-fhs/etc ]]; then
  for i in /nix/store/k5sc68i2c0yxhzlcja8b06fajbxqs7xv-steam-run-fhs/etc/*; do
    path="/${i##*/}"
    # NOTE: we're binding /etc/fonts and /etc/ssl/certs from the host so we
    # don't want to override it with a path from the FHS environment.
    if [[ $path == '/fonts' || $path == '/ssl' ]]; then
      continue
    fi
    ro_mounts+=(--ro-bind "$i" "/etc$path")
  done
fi

declare -a auto_mounts
# loop through all directories in the root
for dir in /*; do
  # if it is a directory and it is not in the blacklist
  if [[ -d "$dir" ]] && [[ ! "${blacklist[@]}" =~ "$dir" ]]; then
    # add it to the mount list
    auto_mounts+=(--bind "$dir" "$dir")
  fi
done

cmd=(
  /nix/store/afizwksh1agch06hx3b1csf4ha2zimb9-bubblewrap-0.7.0/bin/bwrap
  --dev-bind /dev /dev
  --proc /proc
  --chdir "$(pwd)"
  --unshare-user
  
  
  
  --unshare-uts
  --unshare-cgroup
  --die-with-parent
  --ro-bind /nix /nix
  # Our glibc will look for the cache in its own path in `/nix/store`.
  # As such, we need a cache to exist there, because pressure-vessel
  # depends on the existence of an ld cache. However, adding one
  # globally proved to be a bad idea (see #100655), the solution we
  # settled on being mounting one via bwrap.
  # Also, the cache needs to go to both 32 and 64 bit glibcs, for games
  # of both architectures to work.
  --tmpfs /nix/store/4nlgxhb09sdr51nc9hdm8az5b08vzkgx-glibc-2.35-163/etc \
  --symlink /etc/ld.so.conf /nix/store/4nlgxhb09sdr51nc9hdm8az5b08vzkgx-glibc-2.35-163/etc/ld.so.conf \
  --symlink /etc/ld.so.cache /nix/store/4nlgxhb09sdr51nc9hdm8az5b08vzkgx-glibc-2.35-163/etc/ld.so.cache \
  --ro-bind /nix/store/4nlgxhb09sdr51nc9hdm8az5b08vzkgx-glibc-2.35-163/etc/rpc /nix/store/4nlgxhb09sdr51nc9hdm8az5b08vzkgx-glibc-2.35-163/etc/rpc \
  --remount-ro /nix/store/4nlgxhb09sdr51nc9hdm8az5b08vzkgx-glibc-2.35-163/etc \
  --tmpfs /nix/store/bzw74a7dla8iqk2h8wshwi03fbgj2c5h-glibc-2.35-163/etc \
  --symlink /etc/ld.so.conf /nix/store/bzw74a7dla8iqk2h8wshwi03fbgj2c5h-glibc-2.35-163/etc/ld.so.conf \
  --symlink /etc/ld.so.cache /nix/store/bzw74a7dla8iqk2h8wshwi03fbgj2c5h-glibc-2.35-163/etc/ld.so.cache \
  --ro-bind /nix/store/bzw74a7dla8iqk2h8wshwi03fbgj2c5h-glibc-2.35-163/etc/rpc /nix/store/bzw74a7dla8iqk2h8wshwi03fbgj2c5h-glibc-2.35-163/etc/rpc \
  --remount-ro /nix/store/bzw74a7dla8iqk2h8wshwi03fbgj2c5h-glibc-2.35-163/etc \
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/static) /etc/static
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/nix) /etc/nix
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/shells) /etc/shells
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/bashrc) /etc/bashrc
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/zshenv) /etc/zshenv
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/zshrc) /etc/zshrc
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/zinputrc) /etc/zinputrc
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/zprofile) /etc/zprofile
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/passwd) /etc/passwd
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/group) /etc/group
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/shadow) /etc/shadow
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/hosts) /etc/hosts
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/resolv.conf) /etc/resolv.conf
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/nsswitch.conf) /etc/nsswitch.conf
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/profiles) /etc/profiles
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/login.defs) /etc/login.defs
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/sudoers) /etc/sudoers
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/sudoers.d) /etc/sudoers.d
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/localtime) /etc/localtime
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/zoneinfo) /etc/zoneinfo
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/machine-id) /etc/machine-id
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/os-release) /etc/os-release
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/pam.d) /etc/pam.d
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/fonts) /etc/fonts
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/alsa) /etc/alsa
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/asound.conf) /etc/asound.conf
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/ssl/certs) /etc/ssl/certs
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/ca-certificates) /etc/ca-certificates
  --ro-bind-try $(/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin/readlink -m /etc/pki) /etc/pki
  "${ro_mounts[@]}"
  "${symlinks[@]}"
  "${auto_mounts[@]}"
  
  /nix/store/dp8ldvr0gbqlncllny6f2vmm53l9si0k-steam-run-init/bin/steam-run-init "$@"
)
exec "${cmd[@]}"


Edit:
Look like the steam app use similar script. The problem probably lies in bwrap
Maybe there is an argument that can preserve the ownership for those files

Any idea how I can change steam script. I need to test

--bind /tmp/.X11-unix/X0 /tmp/.X11-unix/X0 --setenv DISPLAY :0

In the moment it’s like that

--bind /tmp/.X11-unix/X0 /tmp/.X11-unix/X0

That shouldn’t affect ownership but anyway