A Steam Deck Everywhere
Using gamescope
headless to run steam on a non-logged in system.
Background to Remote Gaming
Remote gaming is something everyone with a beefy desktop wants to do.
The problem is, the current state of Remote Gaming for Linux & Windows is kinda cruddy.
You need to be, first, logged in, second, steam running, thirdly, this all occurring in a secure area so no one can just plop down on your desktop while you are away.
No more, No longer.
Personal Motive
As I approach my big move out of my parents home, I have to leave my chunky desktop behind until I am more settled in my new location.
But I am an addict to playing War Thunder, I admit, It is my relaxation game.
I already know how to run my IDEs remotely, and there is few issues for me in regards to using a remote development system.
But gaming is something I cannot do remotely.
Alternatives
Sunshine
As much as I adore the project, it is kinda janky in my opinion.
Also, it violates the requirement to not be logged-in in person.
Another cloud gaming service
They still exist?
Solution
gamescope
headless!
Here is the script that will make it work for you.
headless-steam.sh
#!/bin/bash
# Below is an extensive explanation of the commands below.
# Launch the given program with dbus, since steam and other programs need it.
# The given program, is gamescope.
# Explanation for the arguments to gamescope
# --backend headless : Headless! This allows `gamescope` to work without a display
# -e : enables steam integration, Needed for steam to work well as expected.
# -o 1 : Sets the minimum FPS to 1 when unfocused. Though may be useless since gamescope is headless
# -r 60 : Sets the maximum FPS to 60, We are streaming, no need to waste power here.
# -f : Sets to "full screen", may be useless for headless.
# -W 1920 : Sets the output width to 1920 pixels, Required for the headless screen to work well.
# -H 1080 : Sets the output height to 1080 pixels, Required the same as for width.
# --prefer-vk-device /dev/dri/renderD129 : This is important for modern systems with multiple GPUs, simply tells vulkan clients to use the correct GPU.
## Use `ls -l /dev/dri/by-path/` and `lshw -c display` to figure out which path is which GPU. (lshw (bus number) should look like the `by-path` identifier).
# --force-grab-cursor : Since some games are funky with the cursor, though may not be needed when headless
# Explanation for the arguments to steam
# -gamepadui : Enables the "gamepad ui", since this will work far better then the clunky desktop UI for remote play. (Also something gamescope something something).
# "$@" : Passes any script arguments onto steam
dbus-launch \
gamescope --backend headless -e -o 1 -r 60 -f -W 1920 -H 1080 --prefer-vk-device /dev/dri/renderD129 --force-grab-cursor -- \
steam -gamepadui "$@"
Usage
Setup
- Install Steam Link on your devices
- Run Steam normally on your desktop.
- Pair your devices together.
Script time
- Save the script above to a file (preferably with the same name) and give it execution permissions.
- Log off the system.
- SSH into your system.
- Run the script.
- See the console go “brr”.
- Open Steam Link, and connect
- Notice you now have a steam deck UI on your other device, and your system is not logged in!
- Happy time!
Notes
- I do not know how this will work for flatpak steam. Sorry!
- You may be able to use this with systemd.
- I wonder if this can be used with systemd to have multiple games running at once on a system.
- I do not know how to perform sound isolation for steam from your desktop, so if you do log in with this script working, you will hear steam.
- I am not responsible for you pressing the steam “power off” button in client (not the steam link app), this will turn your PC off.
- I suggest figuring out how to setup wake-on-lan to turn your PC on remotely.
- Steam Remote Play requires port forwarding
- Use the
screen
command to allow steam to run in the background if you are using SSH, this way if your terminal disconnects, steam keeps running.
Edits
- Gamescope v3.15 introduced
--backend
as an argument, which means the old--headless
argument no longer works. Please use--backend headless
from now on.