Here is another method that uses Flatpak and
obs-vkcapture
, which don't meet my personal needs but are very likely to be useful for you. In the comments there there is also anobs-gstreamer
method.
Here is another method for recording that has its own GUI for Gaming Mode built with Decky Loader.
Key phrase: very much like, not identical. Always treat this as more unstable than Manjaro and only expect support with it in my comments section here.
- Set a password (if you haven't already) and disable read-only rootfs (yes this means after updating SteamOS [not Steam Client] this will all be deleted and you will have to do all this again if you want to stream again)
passwd
sudo steamos-readonly disable
- (OPTIONAL) The on-Steam Deck OBS guide is written in a way that shouldn't require a separate device to actually execute any commands (the Sunshine guide requires a separate device for Moonlight), but for much less awkward and more efficient CLI activity, especially if you don't have a physical keyboard that's compatible with your Steam Deck, you can enable the SSH server to allow remotely connecting using your preferred keyboard-endowed device
sudo systemctl enable --now sshd
- Set up
pacman
. What you hope to see aftersudo pacman -Syyu
is "there is nothing to do
", or at least very few upgrades available. That means that the repositories currently selected in yourpacman.conf
contain packages very close to the rootfs image thatrauc
last installed, and the fewer packages that differ from your rootfs' preinstalled packages you have to install, the less likely it is you will encounter severe issues.
WARNING: If something goes wrong, this can mess up your rootfs, but luckily there is a backup rootfs in every OFW Steam Deck that you can access with the ・・・ + ⏻ button combination at boot, from which you can recover if that happens.
-
On February 6th, 2024, the precompiled
pacman
package repository that Valve provides for us, steamdeck-packages.steamos.cloud, had 2 active repository sets,-3.5
and-main
-
steamos-select-branch -l
had 5 branches,rel
,rc
,beta
,bc
andmain
-
the
rel
branch had SteamOS 3.5.7 with build number 20231122.1, which was- 6 packages ahead and 20 packages behind the
-3.5
repository set - 6 packages ahead and 44 packages behind the
-main
repository set - For this reason, I think the
-3.5
repository set was the best choice for this branch
- 6 packages ahead and 20 packages behind the
-
the
rc
,beta
andbc
branches ALL had SteamOS 3.5.14 with build number 20240202.1, which was- 0 packages ahead and 2 packages behind the
-3.5
repository set - 3 packages ahead and 41 packages behind the
-main
repository set - For this reason, I think the
-3.5
repository set was the best choice for these branches
- 0 packages ahead and 2 packages behind the
-
the
main
branch had SteamOS 3.6 with build number 20240119.1000, which was- 34 packages ahead and 4 packages behind the
-3.5
repository set - 0 packages ahead and 13 packages behind the
-main
repository set - For this reason, I think the
-main
repository set was the best choice for this branch
- 34 packages ahead and 4 packages behind the
curl https://gist.githubusercontent.com/robertkirkman/753922262259486ec417e5ff8b5b924b/raw/9866b808cf82ccababcc066aafe2da6a51f5b453/pacman.conf | sudo tee /etc/pacman.conf
if [[ $(steamos-select-branch -c) == 'main' ]]; then sudo sed -i 's/3.5/main/g' /etc/pacman.conf; fi
sudo pacman-key --init
sudo pacman-key --populate
sudo pacman -Syyu
- Reinstall all corrupted packages that once contained header files before Valve deleted
/usr/include
You might see a few errors generated by
mkinitcpio
during the post-transaction hooks phase. They are spurious and can be safely ignored.
sudo pacman -S $(pacman -Ql | grep -e include -e pkgconf | cut -d' ' -f1 | awk '!a[$0]++')
- Install some compiler toolchain packages. At this point you could now add as many
pacman
packages as you want and could fit into the 5 GB root partition, bearing in mind that even upstream Arch Linux itself has periodically had packages in their official repositories that break the system when installed, so allpacman
users are expected to have experience with the packages they're installing, use caution, and prepare for the possibility of a bug.
sudo pacman --overwrite=/etc/ld.so.conf.d/fakeroot.conf -S base-devel meson cmake
- (OPTIONAL) Install your preferred terminal emulator (unless you prefer
konsole
which is preinstalled), Launch KDE Plasma Xorg (Desktop Mode), open Steam LIBRARY tab, and add it as a non-Steam game; herekitty
is used as an example. At this time, I would also suggest you add a large number of dummy/duplicate non-Steam game entries for future use, because if you wish to remain in Gaming Mode, you will be able to change preexisting non-Steam game entries to add new shortcuts, which is otherwise impossible without switching to Desktop Mode.
paru -S kitty
- Suggested
kitty
Launch Options in non-Steam game properties:
LD_PRELOAD= %command% --start-as=fullscreen
- Clone the repository of the AUR package for
sunshine
, which is maintained by the upstream developer, apply a patch of my own design that makessunshine
usable in Steam Deck's Gaming Mode, then build and installsunshine
usingmakepkg
git clone https://aur.archlinux.org/sunshine.git
cd sunshine
(curl https://gist.githubusercontent.com/robertkirkman/753922262259486ec417e5ff8b5b924b/raw/2bb65f89ad3a0e0219c2a7f5116ed18fa2c0a8d0/sunshine-aur-steamdeck-gamingmode.patch && echo) | git apply -v
makepkg -si
- Enable DRM capture mode in
sunshine
WARNING:
setcap
is a security risk and after running it, all users and software with executable permission for the affected binary can be considered effectively root-equivalent (in this context, they would definitely be able to see your screen for example). To removesetcap
permissions from any binaries granted this, usesudo setcap -r /path/to/file
.
sudo setcap cap_sys_admin+p $(readlink -f $(which sunshine))
- Create symlink to stub
xrandr
to work aroundError: [xrandr --output HDMI-1 --mode 1920x1080] failed with code [1]
, then runsunshine
:
ln -s /bin/true xrandr
export PATH=$(pwd):$PATH
sunshine &
- Make sure the Steam Deck is connected to Wi-Fi or Ethernet, and identify its local IP address for use in the following steps
ip a
- Now move to the LAN device you would like to connect to the Steam Deck's Sunshine from and install Moonlight and a browser capable of accessing Sunshine's PIN entry box, for example
epiphany
orungoogled-chromium
; example command for an Arch Linux device withyay
Unfortunately, OBS cannot record the
moonlight-qt
window in gamescope without adding the additional overhead of the OBS section below this section, andepiphany
is bugged and does not work ingamescope
, so both of these softwares can only be effectively used to connect to Steam Deck Gaming Mode Sunshine from a separate device.
yay -S moonlight-qt epiphany
- Launch your browser, connect to the Sunshine web server on the Steam Deck where you replace
192.168.12.146
with your Steam Deck's local IP address, accept all warnings (which occur on every default copy of Sunshine) and create a username and password for administration of Sunshine, re-enter the new credentials to log in, then navigate to the "PIN Pairing" entry box
epiphany https://192.168.12.146:47990
- Launch Moonlight and add the Steam Deck's IP address as a new device, then type the PIN provided by Moonlight into the PIN box in the browser window
Sometimes Moonlight will fail to authenticate the first time even if the PIN is correct, just keep trying until you can click on the Steam Deck's entry and see the "Desktop" button.
moonlight
- Click the Steam Deck's entry in Moonlight and the "Desktop" button, you can now see the entire Steam Deck screen and almost every menu and game, with a few exceptions - sometimes the onscreen keyboard and Quick Settings menu are invisible in Moonlight, but overall, Sunshine configured this way is capable of capturing much more, more reliably, than any other software. You can also capture the
moonlight-qt
window using OBS, which works better than the OBS guide below as long as you have this other system to run Moonlight on. Sometimes,sunshine
might crash or Moonlight might spontaneously disconnect; if that happens, just restart both and everything will start working again.
If you use Sunshine+Moonlight for streaming-based netplay (someone playing on Steam Deck while someone else plays on another device), you might want to configure advanced audio settings (such as making sure the person using Moonlight can hear the game audio, but not themselves through your VOIP software like Discord). Steam Deck contains two distinct digital sound controllers that behave almost the exact same way their desktop PC counterparts do, which makes such advanced audio settings both possible and nearly identical to how they would be on a desktop Arch Linux PC. Therefore, for now I consider such settings outside the scope of this guide, but if you struggle with audio settings, let me know and I will consider expanding this to cover that common audio use case.
- Install OBS
paru -S obs-studio
- If you do not have any unused dummy shortcuts to populate with OBS, launch KDE Plasma Xorg (Desktop Mode), open Steam and add OBS to Library as a non-Steam game, then right click on it, click Properties, and place the following text exactly as shown in the Launch Options box:
LD_PRELOAD= QT_QPA_PLATFORM=xcb %command%
- There are three possible capture sources for OBS that currently work in
gamescope
.obs-kmsgrab
used to work, and does still work in Xorg as a test, but I think it would need more updates to work with present-daygamescope
:
Unfortunately, this is a very messy method that encodes twice, stutters a lot, and sometimes looks green.
- Install FFmpeg
WARNING:
setcap
is a security risk and after running it, all users and software with executable permission for the affected binary can be considered effectively root-equivalent (in this context, they would definitely be able to see your screen for example). To removesetcap
permissions from any binaries granted this, usesudo setcap -r /path/to/file
.
paru -S ffmpeg
sudo setcap cap_sys_admin+ep $(readlink -f $(which ffmpeg))
- First create a new Scene in OBS, then add a new Media Source to the Scene and uncheck Local File. Then add the following and click OK
-
Input:
udp://localhost:4444
-
Input Format:
udp
- Switch to
gamescope
, navigate to Library and launch your terminal emulator, then execute this command;ffmpeg
will crash anytime you leave the Steam client window by selecting a game or non-Steam app, and this should automatically restart it
while true; do ffmpeg -thread_queue_size 512 -framerate 60 -device /dev/dri/card1 \
-f kmsgrab -i - -vaapi_device /dev/dri/renderD128 \
-vf 'hwmap=derive_device=vaapi,scale_vaapi=format=nv12' \
-c:v h264_vaapi -bf 1 -f mpegts udp://localhost:4444; done
- You will also need to bind Ctrl+C to actually be able stop this capture with the least difficulty; navigate to "Controller settings" for your terminal emulator's non-Steam game entry and bind buttons to these keys, as pictured below. It is very possible that there is a better way of controlling
ffmpeg
without an external keyboard than this, but unfortunately I haven't found that way yet.
- Navigate to Library, launch OBS and start your stream or recording now.
ffmpeg
will often crash when you switch windows, but wait for a few seconds each time you do. The loop will automatically resetffmpeg
, and anything you can look at should be captured. When you are done, navigate to OBS and stop your stream or recording, then navigate to your terminal emulator and hold down your Ctrl+C keybind for a few seconds to kill theffmpeg
loop
Sometimes,
ffmpeg
will only record a small rectangular portion of the screen and the rest will be black. I don't know exactly why this happens and I haven't found any way to consistently prevent it, but it doesn't happen every single time, so if the source looks incomplete in OBS, kill the loop and try running it again until it looks acceptable.
Build and Install AUR package: suyu-dev-qt6-git
I've been doing this in private this whole time but wanted to document it somewhere. This changes all the time. Sometimes you'll have to edit lots of dependency packages, but sometimes when SteamOS is very close to upstream Arch Linux, it's not necessary to edit anything. This is a snapshot of the steps that were necessary in March 2024.
- Make some space if the 5GB root partition is too full to do this. If you need locales other than English, you would need to change the locale here to yours and also edit
/etc/locale.conf
.
sudo rm -rf /usr/share/{man,doc,gtk-doc}
sudo mv /usr/share/locale/locale.alias .
sudo rm -rf /usr/share/locale/*
sudo mv locale.alias /usr/share/locale/
echo 'es_US.UTF-8 UTF-8' | sudo tee /etc/locale.gen
sudo locale-gen
- Install SteamOS-specific dependencies and build Suyu. Accept all prompts.
paru -S vulkan-headers-git
paru -S suyu-dev-qt6-git
Special thanks to people who helped me with various parts of this guide: scaled#4479 logan2611#2351 kamae#7499 2zd9R#9421 and to the developers of all the software involved
Thank you so much for making this guide! It's exactly what I'm looking for.
Unfortunately though I get an error when trying to build sunshine with your patch:
This sounds like a missing dependency maybe? Any thoughts on what could be wrong are appreciated.