Files
enricobuehler 6d7e6f71c0 release: 0.31.0 — verification pass before the tag
Re-measured every version-table row against the tree rather than
trusting the earlier cut: ABI 25, wire 2, driver 6/min 3, gamepad 3,
index schema 1, event schema 1, edition 2024, MSRV 1.85, 27 crate dirs,
39 workspace members, SDK 0.1.5, plugin-kit 0.4.3, openapi 0.31.0 with
both copies byte-identical, gamescope +pfhdr8 with 10 patch files and
no diff against the tag. All match what the table claims. The C header
diff against v0.30.0 removes exactly two things — the old ABI define and
the ex11 doc paragraph that stated the superseded hi-res rule — so
'addition only' holds.

Three fixes to the text itself:

  * The commit count is now taken at the tip being released (170/113 at
    d7fa5847) instead of at this branch, where it moved every time I
    committed to it.

  * The two NixOS items in Before-you-update are one item. They were
    separated by three unrelated bullets, so the audience that has to
    act on both — builds are failing AND there is now a cache — had to
    find them in two places.

  * A TL;DR line read 'it repaired itself on no retry', which says the
    opposite of what it means.

Checked and left alone: the Gaming Mode 'Switch to Desktop' entry is
presented as a bug users hit, and that is right — v0.30.0's takeover
does stop the display manager on mask-fragile flavors
(gamescope.rs:259 at the tag), so it shipped. Only the mask-vs-stop
detail moved inside this cycle.

Gates: fmt clean, punktfunk-core --lib 273 passed, cargo metadata ok,
Play notes 456/500 and unique, voice scan finds no internal names in the
notes body.
2026-08-20 09:42:02 +02:00

36 KiB
Raw Permalink Blame History

Wire-compatible with 0.30.x — everything you have already paired keeps working, and you can update one side at a time. Nothing in this release changes how a host and a client agree on what to send each other, so an old client on a new host, or the other way round, streams exactly as it does today.

Most of this release is things that were wrong in ways nothing announced. A DualSense's rumble and speaker never actually worked in a game streamed from a Linux host, for five separate reasons stacked on top of each other, and every one of them is fixed. On Windows, ending a session was silently killing the whole host, and launching a game from the library on 0.30 could drop your stream a second later. Android phones and TVs now show the same controller console the desktop does — one interface on three platforms — and the picture on a phone arrives markedly earlier with no dropped frames. On Linux hosts, another device on the box can no longer make your desktop audio stutter, and a Gaming Mode takeover on some machines was starving your controller with a login storm of our own making.

Two things also change how you get Punktfunk in the first place. The Windows client is now an ordinary installer rather than a Store-style package, which is what finally lets Steam launch it — overlay, controller configs, Big Picture. And a Linux host can be set up with a single command, if you would rather not follow a page of them.

TL;DR

  • Windows: the client is a normal installer now, and Steam can launch it. Add it as a non-Steam game and the Steam overlay, your controller configuration and Big Picture all work — which the Store-style package could never do. Read Before you update if you already have it installed.
  • One command sets up a Linux host. curl -fsSL https://punktfunk.unom.io/install.sh | sh takes a machine from nothing to a host you can pair with, including living alongside an existing Sunshine or Apollo. It is a preview; the per-system pages remain the documented way.
  • DualSense rumble and speaker work in-game from a Linux host. The controller was dying 400 ms after it appeared, every message the game sent it was reported as failed, its sound card was invisible to the sound system, and what got through arrived 48 dB too quiet. All fixed; the details are below.
  • Windows: ending a session no longer kills the host, and launching a game no longer drops your stream. The first looked like a mystery reconnect; the second arrived with 0.30.
  • Android has the desktop's console, and a much faster picture. One controller interface across Windows, Linux and Android — including 32-bit TV boxes — and on the reference phone end-to-end latency went from 30 ms to about 18 ms with dropped frames going from 4050 a second to none.
  • Desktop audio on a Linux host no longer stutters because of somebody else's device. In one 15-minute session, 15 % of what the listener heard was silence the host had papered over gaps with — because a controller's sound card, attached over the network and connected to nothing, was setting the pace for the whole box.
  • KDE Plasma 6.6 could refuse to start a session, in your own language, forever. No number of retries helped and there was nothing to fix in System Settings. The host repairs it now.
  • Every client can send its logs to the host. Mac, iPhone, iPad, Apple TV and Android join the Gaming Mode console — and the Apple app finally keeps a log worth sending.
  • Hyprland and Sway users: the default display mode now really turns your desk monitors off during a session. It said it did before and did nothing. Read Before you update.

Before you update

  • Windows client: the download you want has changed, and switching to it costs one re-pair. The default is now punktfunk-client-setup_x64.exe — an ordinary per-user installer, no administrator prompt, which upgrades in place and keeps your saved hosts and pairing. A portable zip and the old Store-style package are still offered as alternates. If you already have the Store-style package and you want the Steam integration, remove it firstGet-AppxPackage unom.Punktfunk | Remove-AppxPackage — and then run the installer: that package keeps its settings, saved hosts and pairing identity inside itself, so you will pair with your hosts once more. If you had added Punktfunk to Steam, add the new one; it lives at %LOCALAPPDATA%\Programs\Punktfunk\punktfunk-client.exe. Nothing on the host side is affected, and if you do not care about Steam, staying on what you have is fine.
  • Steam Deck and Bazzite hosts: two things we told you are no longer true. Taking over Gaming Mode no longer stops your login manager, so Steam's own "Switch to Desktop" works during and after a session instead of hanging until you reboot — and for that reason the takeover no longer needs the punktfunk group. Keep that group only if you use the virtual Steam Deck controller, which still needs it. The comments in the Bazzite host.env we ship changed to match.
  • NixOS hosts: two things, and the first one is that builds were failing outright. The version of our patched compositor that came with the pinned packages had drifted far enough that it no longer accepted our changes, and since HDR is on by default that failure sat on every services.punktfunk.host.enable = true build; the fix moves your nixpkgs input, so expect a rebuild. Second, there is now a binary cache, so that rebuild — and every future one — need not compile the workspace and the compositor from source, which took about an hour. Add the cache and its public key to your configuration; the install guide has the snippet, and the cache serves its own public key. Both of these come undone if your flake overrides Punktfunk's nixpkgs input: every store path changes, so nothing in the cache matches and everything rebuilds. Separately, one of the controller-audio fixes below is a sound-configuration file the other Linux packages install into a system location NixOS does not have; it needs a package override there.
  • Plugin authors: update your dependency. @punktfunk/host 0.1.5 and @punktfunk/plugin-kit 0.4.3 are published, and plugins take them from the registry — so the fix that makes a plugin follow a moved management port, the cap on re-scanning, and the republish-on-restart behaviour below only reach your plugin once it depends on those versions.
  • Hyprland and Sway hosts: the "exclusive" display setting — which is what the default resolves to on these desktops — now genuinely disables your own monitors for the length of a session and brings them back afterwards, exactly as it always has on KDE. Until now it was accepted, reported back as active, and quietly behaved as "extend", so your monitors stayed on. If you would rather keep them on, set the display topology to extend. Two things to know: on Hyprland, bringing the monitors back reloads your Hyprland configuration, which also drops any other runtime tweaks you have applied since login and re-runs its startup commands; and the Sway half is written to the same contract but has not been exercised on a live Sway machine, so if it misbehaves, please say so.
  • Other Linux hosts: several controller-audio fixes arrive as system files inside the host package rather than as code — a device rule, a sound-system policy and a sound-card configuration. They take effect after the package is installed and the controller is reattached (or the machine rebooted).
  • Linux hosts, if you look in your sound settings mid-session: you will now see a virtual output and a recording stream both named after Punktfunk. That is the host's own audio output, and it is not a leak — the troubleshooting guide has a new section on it and on what to do when it tells you another device is clocking your audio.
  • If you moved the host's management port and hand-edited the tray's start-up command to match, you can undo that. The tray, every plugin and the plugin runner now follow the port the host actually bound, so nothing needs telling.

New

  • The Windows client installs like an ordinary program, and Steam can launch it. The download is now a signed per-user installer — no administrator prompt — that puts Punktfunk in your own account and registers what you would expect: the Start-menu entries for Punktfunk and Punktfunk Console, punktfunk:// links, and the punktfunk command on your path. It fetches the Windows runtime it needs if the machine does not have it. The reason this matters beyond tidiness: someone reported that launching through Big Picture did nothing and the Steam overlay never appeared. That was never about the app — it was the shape of the old Store-style package, whose program file lives in a protected folder Steam's "add a non-Steam game" browser cannot open, and which Windows starts in a way that stops the overlay attaching. Steam has to start the program itself, from an ordinary path. Now it can: add it as a non-Steam game and the overlay, your per-game controller configuration and Big Picture launching all work. There is also a portable zip that registers nothing at all — unzip it anywhere, delete the folder to remove it — and the Store-style package remains for the Microsoft Store.
  • One command sets up a Linux host, as a preview. curl -fsSL https://punktfunk.unom.io/install.sh | sh works out which system you are on, installs exactly the packages the documentation would have told you to, and then handles the parts people get stuck on: it notices an existing Sunshine, Apollo or Vibeshine and offers to keep both by moving Punktfunk's management port, puts you in the right group, writes a firewall rule, starts the host and web console, checks they are actually running, and prints your console address, the command for its password and the pairing steps. Everything optional defaults to no. --dry-run shows every command without running any, --uninstall reverses it, and answers can be given up front so it can run unattended. It also catches the two graphics-driver failures that otherwise produce a host that streams badly with no explanation — no driver at all, and a driver the machine refused to load because of Secure Boot. It is labelled preview deliberately: the per-system pages stay the documented route until it has more mileage, and NixOS, SteamOS and Windows are pointed at their own instructions rather than half-handled.
  • Every client can send its logs to the host. In 0.30 this existed only on the Gaming Mode console. Mac, iPhone, iPad and Apple TV get it in the host card's menu and on the controller-driven host options, and Android phones and TVs get it from the console — where the button previously said it was unavailable. On Apple it is new twice over: the app had never kept a log of its own to send, so a report from an Apple TV arrived carrying only the host's half of the story. It now keeps a rolling log — bounded, so it cannot grow without limit — and for the first time that log includes what the streaming engine itself has to say about connections and network problems, which was previously invisible on those devices.
  • The console learns three things from the desktop. Controller haptics and Controller speaker are now switches in the console's Controller tab rather than settings you could only reach elsewhere; each saved machine gets its own Shared clipboard toggle; and you can set a machine's default profile from its menu.
  • The documentation was rewritten, for two audiences. There is a get-started track — one task per page, a couple of minutes each, with real screenshots of the console instead of prose describing it — and a Switching from Sunshine page covering what maps to what and how to run both at once. Every install command on those pages is now quoted from one file that the build checks, so the commands you are given cannot drift from the ones that are tested. Several things the pages had told you were simply wrong and are now corrected — among them that GameStream compatibility is opt-in on every route, a missing step in the Ubuntu and Debian instructions, a missing firewall step on Bazzite, and NixOS getting a page of its own.
  • NixOS users get prebuilt binaries. Every other install channel shipped binaries; Nix compiled the whole workspace and our patched compositor from source — roughly an hour, on the critical path of enabling the host at all. A signed binary cache is now published on every change to the main branch, so a build that once took an hour takes the time it takes to download.
  • Hyprland and Sway hosts can run a session on the virtual display alone. With the display topology on exclusive, your own monitors are switched off while the session runs and switched back on when its display goes away — never all at once, so the desktop is never left with nothing to show, and never a monitor belonging to a second session or a second host on the same machine. Primary is still treated as extend on these desktops, and now says so on its own rather than sharing a warning with exclusive: Wayland has no notion of a primary output, only a focused one, and the streamed display already holds that.
  • The Android app's controller interface is the desktop's. Plug in or pair a controller and the phone or TV shows the same console Windows and Linux do — same screens, same navigation, same motion — instead of an Android-only recreation of it that had to be fixed three times over. It runs on every Android device, including the 32-bit TV boxes that were previously left out. On a phone the console now takes the whole panel, tucking the system bars away for the duration and bringing them back on a swipe, and the library gives the sort bar's height back to the covers unless you have actually pulled it down. Connected controllers is a page of the console itself now, with the permission prompts, the rumble test and the controller-audio self-test where they were before.
  • The Apple gamepad library grows up. On Mac, iPhone, iPad and Apple TV the controller-driven library gets the desktop console's poster grid alongside the shelf, a live sort and view bar (Default · AZ · Platform · Store; Shelf · Grid) that writes the same setting the settings rows do so the two can never disagree, and Collections — group by platform or store, walk the groups, open one, and back out the same way — presented as tiles carrying a fanned deck of up to three covers. The plain touch library learned to sort and group from a toolbar menu too. Every title's platform, which the host had been sending all along and the app was throwing away, now shows in the detail band and drives the grouping.
  • The audio buffer can grow without going silent. Every client keeps a small buffer of sound and adjusts its depth to what the link and the picture are doing. It could shrink gently, one crossfaded frame at a time — but the only way it could grow was to throw everything away and refill from silence. So whenever the picture's timing wandered and the sync loop asked for a little more audio depth, the very next late packet cost a 1560 ms gap. This shape has been with us since roughly 0.24. The buffer now moves toward its target in both directions with the same gentle instrument, on Windows, Linux, Android, Mac, iPhone, iPad and Apple TV alike.
  • The audio threads that feed the speakers run at real priority on the client. The device callback itself already did; the threads decoding audio and rendering controller audio did not, and on a Steam Deck decoding a 1440p120 stream on the same four cores that was a source of clicks. The previous attempt at this was a no-op on the Deck (its user account is not allowed to ask), so the client now goes through whichever door the machine actually offers — including from inside a Flatpak. Windows clients get the same through the system's pro-audio scheduling.
  • A host that is losing audio now says why. The Linux host logs, by name, whichever device is setting the pace for its audio whenever that changes, and warns when it is not the host's own output — because those stalls become your holes. The capture summary also breaks its lost audio down by how long each gap was, so a periodic scheduler on the box and one long outage stop reading identically.
  • Plugins stop re-scanning your library while a game runs. Steam writes to its folders the whole time a game is open, and every write was re-walking the library — 102 times in one 27-minute log. There is now a floor of one re-scan per half-minute per plugin, with nothing lost: whatever changed during the hold is picked up in exactly one trailing scan.

Improved

  • Touching the console does what touching things should. On a touchscreen, swiping across the settings list used to change whichever setting your finger happened to land on — a press was both "focus this" and "choose this". A tap is now a tap, delivered where you put your finger down, and a drag scrolls the list. Using a mouse is unchanged.
  • The Android console is easier on the battery. It only looks for machines on the network while the console is actually in front of you, and it halves its drawing rate after a minute without input.
  • A portable Playnite gets its covers — and a tile of its own. If your Playnite is unzipped somewhere of your choosing rather than installed, its whole library lives beside the program, which put every cover outside the folders the host is allowed to read art from: one reported library synced its games and dropped all 70 covers, with no way round it but setting an environment variable. Those folders are now included, exactly as Steam's are, and finding a portable Playnite at all also gives it the launcher tile it never had. If you set that environment variable as a workaround, you can drop it.
  • Fixing something on the host side no longer needs a cache file deleted. A plugin remembers what it last sent so it does not resend it endlessly — but the host can accept a submission and keep less of it than was sent, which is deliberate, since a cover it cannot serve must not cost you the whole library. Once that happened, the plugin's memory said "nothing to do" forever: you would fix the host and nothing would republish. Restarting, or pressing Sync now, always republishes again.
  • Windows: the plugin runner writes a log file you can read. A field report on a 0.30 host had plugins installed, the runner running, an empty library and "no logs at all" — and that was by design, since the runner's only way to speak was through the host it could not reach. It now writes a plain log file next to its plugin state, and the console's empty-library hint tells you where it is.
  • Apple gamepad screens move like the desktop's. Screen transitions in the Mac, iPhone, iPad and Apple TV controller shell use the same spring the desktop console uses, and they can be interrupted — press B mid-flight and the same spring carries you back. Reduce Motion crossfades instead of snapping.
  • The Apple library fits a phone. The grid fills the width instead of leaving a fifth of it empty on a phone; in a landscape phone's height it holds two rows instead of one; the shoulder-button hint hides on any phone and the sort bar has become a tray you pull down with ▲ and dismiss with ▼, A or B, so the field keeps every point of height it has. Navigating the grid no longer scrolls twice for one move, and a diagonal flick of the stick is one move, not two.
  • Mac: "Capture system shortcuts" can now capture the system's shortcuts. 0.29 taught the Mac client to send ⌘ shortcuts to the host, but only the ones macOS lets an app see — ⌘Q, ⌘W and their like. ⌘Space, ⌘Tab and Mission Control never got that far: macOS hands them to Spotlight and the Dock before any app is asked, so a captured stream still opened Spotlight. With Accessibility access granted, those reach the host too while your input is captured; ⌘⎋ still releases capture and stays local. The grant is optional and only ever asked for from the setting itself, never at stream start — without it, the setting keeps doing what it did in 0.29 and its caption now says exactly that.
  • The on-screen keyboard on Mac and iPad behaves. The row you are typing into flies from its place in the list to a seat directly above the keys and back, instead of the empty row doing the flying while the real one appeared from nowhere; a hardware keyboard types straight into the field while the tray is up, including characters the on-screen grid does not offer; and Esc means Done rather than closing the whole screen.
  • The controller speaker sounds like a speaker. Both controller-audio lanes were compressed with the low-delay voice profile that suits rumble — on the speaker it sounded, in the words of the person who heard it, insanely compressed. The speaker lane now uses the full-quality music coder at a higher bitrate; the rumble lane is unchanged.
  • A silent controller speaker is no longer indistinguishable from broken hardware. On Android the controller speaker is off by default — deliberately, it is a small loudspeaker in your hands — but nothing said so, and one field session spent an evening measuring the host for a speaker that was simply switched off on the phone. The setting now states its default, and the host's controller-audio test tells you up front whether your client would even be asked to play what the test is about to prove works.
  • The virtual controller looks exactly like a real one to the system. It carried a placeholder serial number no real pad has, which leaked into every device name derived from it. Cleared, so anything that matches on those names sees the same text a physical pad produces.

Fixed

  • On KDE Plasma 6.6, a session could refuse to start — in your own language — and stay broken. Plasma 6.6 changed the rules: it will not stream a display it created switched off, and the refusal it sends is a translated sentence with nothing written to any log, because switching a display off is a perfectly ordinary thing to have configured. It also repeated forever, because we deliberately ask for a display named consistently so Plasma remembers your resolution and scale against it — which meant it also remembered "off" and reapplied it to every future session. You could not even fix it in System Settings, since the display exists only for the fraction of a second the request is alive. The host now switches it on and tries again. Separately, that translated refusal used to be mistaken for a temporary problem on any non-English desktop and burned through eight retries over eleven seconds before giving up; it now fails immediately and says what it means.
  • Gaming Mode: "Switch to Desktop" hung until you rebooted. Taking over Gaming Mode used to work by stopping the piece of the system that logs you in, which also happens to be the only thing on the machine able to start a desktop session — so Steam's own switch sat on its dialog forever. The takeover now leaves it running and simply parks the automatic gaming login for the duration. Measured on the machine that reported it: the switch that used to hang brings the desktop up in about ten seconds, and Steam is back within five when the session ends.
  • Wake-on-LAN never worked from a Steam Deck. Waking a sleeping machine needs its network address, and the only two places that ever recorded one were the Windows and Linux desktop windows — neither of which exists in Gaming Mode. So a Deck's saved machines never had one, every wake was skipped in silence, and nothing said so: no packet, no error. All the places that see a machine announce itself now remember it. Two things fall out of the same fix: a Deck's saved machine keeps its icon instead of losing it the moment the network goes quiet, and the advice in punktfunk wake — "connect to it once while it's awake" — is corrected, because connecting never taught it anything.
  • The web console's Virtual displays page showed the same two cards on both tabs. The Streamed-screen and session-lifetime cards sat below the tab strip rather than inside it, so whichever tab you were on you saw them — which read as the Configuration tab's contents leaking into the Live displays tab. They are settings, so they now live in Configuration, and the Live tab is just the live list and its arrangement.
  • Cancelling a connection left you looking at "Cancelling…". The console waited for the machine you were dialling to confirm, which it had no obligation to do — on Android it never did, so the screen stayed until the app was killed, and on the desktop it waited out the dial: fifteen seconds normally, and just over three minutes when the host was holding your request for someone to approve. Pressing B is your decision and now takes effect at once, and the dial is actually abandoned.
  • NixOS hosts could not be built at all. Our patched compositor no longer applied to the version of it that came with the pinned packages, and because HDR is on by default that failure was on the path of every host build. Two more faults were hiding behind it and are fixed in the same breath: the packages we build from turn off the piece that lets a game reach HDR unless explicitly asked, so the compositor would have installed under our name and quietly denied HDR to everything under it; and the cleanup step could not remove files that install into read-only folders.
  • Ending a session killed the entire host on Windows. The service restarted it about six seconds later, so it read as a mystery reconnect rather than a crash — four times on one machine, every one of them a session teardown. The cause was a single log line written at a moment when the logging machinery could already be gone, and the crash handler then hid the evidence by trying to log the same way and failing the same way. Neither happens now, and if anything of that shape ever recurs, the message naming it will actually be written down.
  • Launching a game from a Windows host on 0.30 could drop your stream a second later, with the console reporting nothing running. Almost every Windows launch is a hand-off to Steam, Playnite or the shell — a process that quits a second after the launcher takes over. 0.30 learned to track the process it started, and for a title without any way to recognise its window it took that hand-off's exit as the game's and closed the connection. It would also, in one shape, have asked your whole Steam client to close when the game ended. Both fixed; a title the host cannot track shows as untracked instead of "launching" forever.
  • DualSense rumble and speaker in a game streamed from a Linux host — five faults, in order:
    • The controller vanished 400 ms after it appeared when the newer USB-style transport was on. One of its setup reports was one byte longer than the driver asks for, and USB treats an over-long reply as hostile and tears the whole device down. The report is the right length now, every reply is trimmed to what was asked for, and the host waits for the system to actually adopt the pad before it calls the pad ready.
    • Every message the game sent to the pad was reported as failed, so the one command that switches on rumble, adaptive triggers and the speaker never took, and nothing downstream could show a result. The pad was acknowledging every write with "0 bytes accepted". It acknowledges the bytes it took now — and the Steam Controller 2 shares that path, so its writes were being reported wrong too.
    • The pad's sound card was only readable by the administrator, because it appears at a moment when no desktop session is active to grant access, so the sound system never saw it and games had nowhere to route controller audio. A device rule fixes it, for virtual and physically plugged pads alike.
    • What reached the voice coils was 48 dB too quiet. The sound system starts every new device at what a mixer shows as 40 %, which in real amplitude is about 24 dB — and both the host and the client minted one, so the two stacked. Both ends now pin the controller's volume to unity.
    • The controller's only playback route was a mono output that at least one game overran and crashed on, about 74 seconds in. The pad now presents its proper multi-channel profile from the moment it appears, so that route — and the crash path — never exists, and the coils get their own channels into the bargain.
    • Also on this path: the speaker channel was being forwarded to the wrong side, so you felt rumble but heard nothing; the pad's audio clock ran about 26 % slow under load, backing its own audio up into dropouts and dragging desktop capture down to half delivery with it; and the sound-system policy that keeps a controller from setting the pace for the whole box was set to a value that made it merely last in line rather than excluded, which on a Punktfunk host is still elected. All corrected.
  • Desktop audio on a Linux host stuttered because another device was setting its pace. The host's audio output was a stream pretending to be an output, and a stream never keeps its own time — so the sound system handed the job to the highest-priority running device on the box. On one reporter's host that was a DualSense forwarded over the network: connected to nothing, never sleeping, and unable to keep steady time for something arriving over a link. Every cycle that ran was healthy; the loss was in the gaps between them — 3.9 holes a second, the worst 142 ms, and 15.4 % of a 15-minute session filled with silence the host generated to cover them. The host now creates a real virtual output that keeps its own time inside the sound system, so no hardware or network device can ever be chosen for it. It also turns out the host's audio callback has been running at 2.67 ms rather than the 5 ms it was designed around on every stock Linux host since it was written, because of a rounding rule nobody had accounted for; that is corrected on the same path.
  • A Gaming Mode takeover on a machine that logs itself in flooded the box with logins. On a host set to log its user in automatically, the way the takeover held the desktop's login manager back sat squarely in that manager's retry path — so every automatic login failed in milliseconds and it tried again, with no back-off: 962 logins in under four minutes, the system's buttons re-scanned 5,688 times, a load of 26 on 12 cores, and every program that listens for new devices drowning in the noise. To you it looked like "my DualSense is not detected, or only with an insane delay": the pad enumerated perfectly and then delivered input at about 1.4 Hz. That method of holding back is gone; the takeover now stops the login manager first and only then steps in. If it cannot stop it, it no longer tries anyway — it falls back to streaming the desktop's own session, which is a working stream, rather than fighting a login loop that costs you your controller.
  • Audio hiccups on the client that nothing counted. On the Linux desktop client and the Steam Deck the audio callback was running on the wrong thread at ordinary priority, and when that thread was late the sound system played silence for us and moved on — an underrun no counter ever saw. On the host, the audio pacer measured its schedule against the wall clock while the audio it carried did not, so every small hole left it a little further behind until a bigger hole repaid the debt as a burst of silence frames — one field log showed 3372 % of departures late and the worst nearly 100 ms behind. Both fixed, and holes no longer open and close with a click.
  • A Steam Deck's support bundle covered three seconds instead of the whole session. The video decoder writes a dozen bookkeeping lines per frame, and at 120 fps that flushed the entire log ring — 2,037,456 lines evicted from a 27-minute session, including the one audio line three rounds of investigation had been waiting for. The chatter is filtered before it reaches the ring.
  • Android: the picture arrived late and dropped frames on a phone that could easily keep up. The reference phone decodes a frame in 45 ms and was still showing 30 ms end to end with 4050 skipped frames a second, because it was pacing against a display clock that Android quietly slows down for game processes. Frames are now composited straight onto the display on the panel's real timing, and each one reports back exactly when it landed. On glass: end-to-end 30 ms → about 18 ms, skipped frames 4050 a second → 0. That new path carries the stream's colour properly too — high dynamic range is described by what the two ends agreed on rather than guessed at from the decoder, and ordinary content is labelled so the phone stops washing blacks out to grey — and the status and gesture bars no longer park themselves over the video for the whole session. Whether the panel holds 120 Hz turns out to be the phone maker's power policy, not the app's — nothing an app can ask lifts it — so if you want 120 on such a phone, set your phone's minimum refresh rate.
  • Android: the controller went dead after opening the Controllers or Licences page from the console — every press was dropped until you force-stopped the app. Also, plugging in a controller could leave you on a grey screen for the rest of the session if the console could not draw; it now hands you back to the touch interface instead.
  • Mac, iPad and Apple TV: clicking a host connects to it again. A change earlier in this cycle had made the host card open the game library instead, with "connect" pushed into the menu — the opposite of every other client. Reverted: tap to connect, "Browse Library…" back in the menu, everything else the library work landed kept.
  • The Apple grid's first day on real hardware. A single stick flick was read as up-then-right on the way out of the dead zone; the grid drew over the pinned title; rows vanished while still in view; one step down scrolled the row above half away; and "Copy link" was a face button on a gamepad interface. All addressed — X now opens a small options menu for the title.
  • RPM builds were broken by one stray line, so for a short window the main branch produced no Fedora packages at all. Fixed the same day; no release was affected.

Thanks

Several of these were found because someone sent a log detailed enough to disprove the obvious. The Steam Deck bundle that turned out to hold three seconds of decoder chatter is what made the log-ring bug visible; the audio-clock investigation went through four field logs and a purpose-built probe before a single column in a diagnostic tool named a controller's sound card; and the report of a Windows host with plugins installed, a runner running and nothing to show for it described exactly the failure the runner could not report on its own.

Several more came from reports that were specific about the thing that did not happen, which is what made each of them findable: Big Picture not launching and the Steam overlay never appearing — a report about a program's install shape, not about streaming at all; ⌘Space doing nothing on a Mac with the setting switched on; a Playnite library that synced its games and dropped exactly 70 covers; a Portuguese-language KDE desktop where the same failure looked like a flaky one; a Steam Deck that would not wake a machine and produced no error to look at; and an Apple TV whose log bundle arrived carrying only the host's half — which is the report that got the client a log of its own. Thank you.

For developers

Protocol, ABI, driver and embedder detail — including the version table and the notes on what moved — is in CHANGELOG.md.

The short version: the streaming protocol does not move, and neither does the driver protocol or the plugin contract, so nothing needs re-pairing in any direction. The embedding interface moves one step by pure addition — a single new call that hands an embedder the engine's own log lines, which is what gave the Apple client something worth sending in the first place; adopt it or ignore it, nothing else changed shape. Four things are worth reading before you package or embed this release: the Windows client's default download is now a per-user installer plus a portable zip, with the Store package kept as an alternate; the Linux host package installs three new system files (a device rule, a sound-system policy and a sound-card configuration) that the controller-audio fixes depend on; the Linux desktop-audio capture changed topology by default, with a one-release escape hatch back to the 0.30 shape; and the Android app's Compose console is deleted outright, which removes its screenshot scenes.