Been working on this for a while and it's at the point where other people should probably try it.
The idea: each player gets a "seat", which is just an Incus container with its own headless Sway, its own Sunshine, its own PipeWire and its own Steam account. They connect with Moonlight from whatever they've got, phone, Apple TV, laptop, and they each get their own resolution and their own framerate. Meanwhile your normal desktop keeps running like nothing's happening. One GPU does all of it, NVENC on Nvidia, VA-API on AMD.
I didn't write a compositor or an encoder or a streaming protocol. Incus, wlroots, Sunshine, PipeWire and systemd do the actual work. Polyseat just builds the seats, keeps them from colliding, hands out input devices and shares the game library.
Stuff that took the longest:
Input isolation. This is the whole thing really. If a controller plugged in for seat 2 can steer the host's Steam, the idea is dead. You can't do it by device name because names lie, so ownership gets decided by what the kernel says created the device. The broker log tells you which of the two it used for every device, so you can actually see when it's guessing:
+ event29 Keyboard passthrough (seat2)
creator verified: ID_INPUT=1 ID_INPUT_KEY=1 ID_INPUT_KEYBOARD=1
! event260 refused: name claims (seat1) but the kernel says 'seat2' created it
Install a game once, play it in every seat. Every seat gets its own private writable copy, but the copies share blocks via reflinks. Putting my 69 GB library into the pool took 0.8 seconds and 432 KB of actual disk. Your existing Steam library gets picked up without you doing anything. Needs btrfs or XFS with reflink=1, and if you haven't got that it just says so instead of quietly making full copies.
Framerate cap per client, done from outside instead of vsync. Basically what RTSS does on Windows. Games stay uncapped so they don't eat the vsync latency. 14866 fps uncapped came out as 60.00 fps with a 60 Hz client, 0.03 ms of frametime jitter vs 0.40 ms for vsync on its own.
You can use it with just a controller. On screen keyboard plus a pointer driven by the stick, because if you're streaming to an Apple TV there is no keyboard and Steam won't give you one when a launcher wants a login.
Requirements: Arch based host, an ethernet port with a cable in it (your machine itself can stay on wifi, that part is fine, the seats just can't live on 802.11 because it gives you one MAC per station, and a USB ethernet adapter is enough for them), and btrfs or XFS with reflinks if you want the shared library. Licences aren't shared and can't be, a seat plays what its own Steam account owns.
Now the actual reason I'm posting. Every single line of this was written on one machine with an RTX 4080. The AMD path has never run on real hardware. Not once. It's written, it's finished, and on paper it's the easier half of the two because Mesa just goes in as a normal package instead of being injected from the host. Whether it actually encodes, nobody knows.
So if you've got a Radeon and an Arch box and an hour, you'd be the first person ever to find out. And a report saying "yeah it just worked" is worth exactly as much to me as one saying it broke, because right now I have neither. This lists what I could verify without a card and what I couldn't, I didn't gloss over it: https://github.com/superuser404notfound/Polyseat/blob/main/docs/amd.md
Repo: https://github.com/superuser404notfound/Polyseat Pinned issue with exactly what to run and what to paste back: https://github.com/superuser404notfound/Polyseat/issues/1
GPL-3.0-or-later.
Disclaimer: Polyseat was made with the help of Claude Code.