- rebuild-check.sh + punktfunk-rebuild-check.service (enabled, ordered Before=punktfunk-host): ldd-probes the host binary at session start — milliseconds when healthy, a full update.sh rebuild only when a SteamOS update actually broke its library links. update.sh restarts go --no-block so the check → update.sh → restart chain can't deadlock against the unit ordering. update.sh retrofits the unit. - installer summary: web console is https (the unit serves TLS). - docs: steamos-host.md (runner in the build step, keep-list + auto rebuild = updates survive hands-free), gamescope.md (Gaming Mode touch = single-finger pointer, exact taps, no multi-touch), plugins.mdx (SteamOS runner note), scripts/steamdeck/README.md (rebuild-check, runner payload, keep list, honest packaging trade-off + the CI-prebuilt future direction). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
8.9 KiB
title, description
| title | description |
|---|---|
| SteamOS (Host) | Run a punktfunk host on SteamOS — stream its Game Mode (or desktop) to your other devices. One script, built on-device and ABI-matched to SteamOS. |
This is for using a SteamOS device as the host — streaming from it to a laptop, TV, phone, or another device. (For the usual case — streaming to a Steam Deck — see Install a Client, which uses the Flatpak + Decky plugin.)
We support SteamOS as a host mainly with an eye to the upcoming Steam Machine — a living-room, desktop-class SteamOS box is a natural always-on streaming host. The Steam Deck is the SteamOS device we can test on today, so it's what these instructions are validated against; the same on-device build works on any SteamOS 3 system.
New here? Read Security & Safe Use first — a streaming host is remote control of the machine, so keep it on a trusted LAN or VPN and require pairing.
SteamOS is an immutable, read-only Arch base, so the host isn't a system package. Instead a single script builds the host natively inside a Debian-trixie distrobox (ABI-matched to SteamOS's FFmpeg/glibc — the binary then runs natively on SteamOS) and wires it up as systemd user services. Building on-device means a rebuild always matches the running OS, so a SteamOS update can't leave you with a binary linked against the wrong libraries. Encode is VAAPI on the AMD GPU (auto-detected; NVENC on NVIDIA).
Heads up: in our testing the Steam Deck's WiFi tx topped out around ~250 Mbps of goodput regardless of band — enough for 1080p/1440p60, not 4K. This looked like a hardware/driver packet-rate limit rather than a bandwidth ceiling, but it's one device measured on one network: other SteamOS hardware, newer drivers, or a less congested band may do better. A wired dock sidesteps it entirely. See Configuration for bitrate guidance.
Prerequisites
- A SteamOS device on SteamOS 3 (e.g. a Steam Deck, LCD or OLED). Steady WiFi or, better, a wired dock.
- distrobox installed (no root needed). If
distroboxisn't found:Make surecurl -sfL https://raw.githubusercontent.com/89luca89/distrobox/main/install | sh -s -- --prefix ~/.local~/.local/binis on yourPATH(re-open the terminal). - The first build downloads a container image + toolchain (~1 GB) and takes ~10–15 minutes. Later rebuilds are incremental.
1. Get the source
In Desktop Mode open Konsole (or ssh in), then:
git clone https://git.unom.io/unom/punktfunk ~/punktfunk
2. Run the installer
bash ~/punktfunk/scripts/steamdeck/install.sh
It is idempotent — safe to re-run. In one pass it:
- creates the
pf2Debian-trixie distrobox and installs the build toolchain, - builds
punktfunk-host, the web console, and the plugin/script runner (so the console's plugin store works out of the box — the runner service itself stays opt-in), - writes config to
~/.config/punktfunk/(a generated web-console login password), - raises the UDP socket buffers to 32 MB, installs the gamepad udev rule + the
vhci-hcdautoload and adds you to theinputgroup (virtual gamepads / native Steam Deck controller passthrough), seeds the KDE RemoteDesktop grant for Desktop-mode input, and registers all of it on SteamOS's atomic-update keep list so OS updates carry it over — this step prompts for yoursudopassword (a stock Steam Deck requires one; without it gamepad passthrough and the UDP tuning are skipped), - installs + starts the
punktfunk-hostandpunktfunk-websystemd user services (with linger, so they run without a login session) plus a boot-time rebuild check that repairs the host automatically if a SteamOS update ever breaks its library links.
Useful flags:
| Flag | Effect |
|---|---|
--open |
Accept unpaired clients (trust-on-first-use) — convenient on a fully trusted LAN. Default is PIN pairing required. |
--no-gamestream |
Run a secure native-only host — skip the GameStream/Moonlight-compat planes (see below). Default keeps them on so stock Moonlight works. |
--no-web |
Skip the management web console. |
--src=DIR |
Build from source at DIR instead of ~/punktfunk. |
When it finishes it prints the web-console URL and how to pair.
GameStream/Moonlight compat is on by default. The native
punktfunk/1plane (used by punktfunk's own clients — SPAKE2 PIN pairing, per-direction AEAD) is always on and is the secure path. The installer also enables the GameStream/Moonlight-compat planes so stock Moonlight works — but those carry inherent on-path weaknesses (pairing over plain HTTP; legacy control encryption that can reuse GCM nonces), so enable them only on a trusted LAN. If you only ever use native clients, install with--no-gamestreamfor a host with no GameStream surface at all.
First install — reboot once before streaming. KWin only authorizes Desktop-mode screen capture on a fresh session, and the new
inputgroup (native Steam Deck controller passthrough) only takes effect on a new login — so after the first install, reboot the Deck (a re-run that changes nothing doesn't need it). Streaming Game Mode with a generic Xbox pad works right away; Desktop capture and the native Steam Deck controller need the reboot. If a client connects and every session ends withKWin does not expose zkde_screencast_unstable_v1or the pad shows up as an Xbox 360 controller, you haven't rebooted yet.
3. Pair a device
By default the host requires PIN pairing (secure). Two ways to pair:
- Web console (printed at the end of step 2): open
https://<device-ip>:47992(self-signed host cert — your browser warns once; trust it and continue), arm pairing, and enter the PIN on your client. - From the client directly: pick this host (it advertises over mDNS as
_punktfunk._udp) and enter the PIN the host shows.
On a trusted home LAN you can instead install with --open and skip pairing entirely.
Console login password
The installer generates a random console login password (printed at the end of step 2) and writes it
to ~/.config/punktfunk/web.env. To read it back or set your own, see
The Web Console.
4. Verify
systemctl --user status punktfunk-host # active (running)
journalctl --user -u punktfunk-host -f # watch a client connect
Connect from a native client, or from Moonlight (unless you
installed with --no-gamestream). In Game Mode the host attaches to the running gamescope session and
streams it at your client's resolution; in Desktop Mode it streams the KDE desktop. The host
auto-detects which session is live per connection. See Steam / gamescope for the
attach-vs-managed detail and known limits.
Updating
After pulling new source, rebuild and restart in one step (config + pairings persist):
git -C ~/punktfunk pull # or rsync new source in
bash ~/punktfunk/scripts/steamdeck/update.sh
Notes & limits
- Single session at a time at custom resolutions — two clients requesting different modes will thrash the managed session. Pick one mode per session.
- Keep the device awake. On handhelds, Game Mode auto-suspends on idle, which drops the host off the network mid stream — disable auto-suspend (Settings → Power) for a headless host.
- Native Steam Deck controller passthrough presents the client's pad as a real Steam Deck
controller (paddles, trackpads, gyro) via a virtual USB device — that needs the
inputgroup and thevhci-hcdmodule live, so it only works after the first-install reboot above; until then the pad degrades to a generic Xbox 360 controller (still fully playable). If you're streaming to another Steam Deck, also set Steam Input to Off for Punktfunk on that Deck — see Stream to a Steam Deck. - It survives OS updates — automatically. SteamOS A/B updates rebuild
/etcand can move library versions; the installer defends both sides. The system tuning (gamepad udev rule,vhci-hcd, UDP buffers) is registered on SteamOS's own atomic-update keep list (/etc/atomic-update.conf.d/), so updates carry it over; and a boot-time check (punktfunk-rebuild-check) probes the host binary and re-runs the build only if the new OS actually broke its library links — you should never need to intervene. (Re-runningupdate.shby hand still works and is harmless.) - Deeper reference (services, container, manual steps):
scripts/steamdeck/README.md.
Trouble? See Troubleshooting and Pairing.