feat(nb): enable Steam and host support for the portable WoW card #246

Merged
dominik.polakovics merged 1 commit from feat/nb-steam-wow-portable into main 2026-08-01 13:33:40 +02:00

Enables Steam on nb and adds the host-side support the portable WoW 3.3.5a +
AzerothCore SD card needs. The card itself is self-contained and travels between
machines; only the machine-local pieces are declared here.

Steam

hosts/nb/modules/steam.nix already existed but was never imported, and it no
longer evaluated at all — amdvlk has been removed from nixpkgs, so both
hardware.graphics.extraPackages entries pointed at a missing attribute. Now on
RADV, which hardware-configuration.nix already provides.

enable32Bit is mandatory here, not a nicety: Proton is 32-bit by design and
Wow.exe is a 32-bit binary.

The i686 pypy bug, again

Turning on 32-bit graphics re-triggered — from a second direction — the
makePythonWriter bug this host already documents for the 32-bit ALSA plugins.
writers/scripts.nix:1203 guards on

if pythonPackages != pkgs.pypy2Packages || pythonPackages != pkgs.pypy3Packages

a tautology whose operands force the pypy interpreter. fetch-cargo-vendor-util
is itself a writePython3 script, so every Rust package drags it in, and
graphics.nix:145 puts pkgsi686Linux.mesa in the i686 closure.

On i686 pypy fails twice: no i686-linux in meta.platforms, and no
i686-linux source hash in python/default.nix. So allowUnsupportedSystem
does not help — it only moves the error one step down, which I confirmed.

Stubbing pypy2Packages on i686 makes the first comparison cheap and true, so
|| short-circuits and pypy3Packages is never forced either. Nothing ever
built pypy; it was only force-evaluated by that comparison. The stub is scoped
to i686 and leaves the x86_64 set alone, so the existing allowInsecurePredicate
is still doing its job there.

With the root cause handled, services.pipewire.alsa.support32Bit no longer has
to be forced off — and the NixOS Steam module sets it itself, so leaving the
opt-out in place was a hard definition conflict.

The card

  • podman — the card's single host requirement. Not interchangeable with the
    Docker daemon nb already runs: the AzerothCore images are an OCI/overlay
    store Docker cannot read. dockerCompat stays off.
  • fuse-overlayfs — the card's store carries
    containers/storage/overlay/.has-mount-program, so podman refuses it unless a
    mount program is on PATH. Arch always ships one; NixOS does not.
  • A fixed mount at /run/media/dominik/SteamSD. The Steam shortcut's appid
    is a crc32 of the absolute path to Wow.exe, and that path also lands in the
    launch options, config.vdf's CompatToolMapping and the artwork filenames.
    A path that moves between sessions silently becomes a different app — no
    artwork, no compat tool, and a stale mapping key fails with no error at all.
  • WOW_GRAPHROOT moves the podman image store off the card onto the internal
    drive. The card's default keeps the store on itself so images travel, but that
    cannot work across these two machines: the store's db.sql records its own
    graphroot path, and the card mounts under a different user per machine
    (/run/media/deck on the handheld vs /run/media/dominik here), which podman
    rejects outright as a configuration mismatch. It also keeps 44 GB of layer
    reads off a ~165 MB/s card.

uid is already 1000 and /etc/subuid already reads dominik:100000:65536,
which is exactly the base the card's server/mysql ownership was built against —
so no re-chown and no podman system migrate.

Testing

scripts/test-configuration nb passes. Runtime verification still to do after
deploy: that /etc/subuid is unchanged, that podman reads the card's image
store, and whether podman works inside Steam's FHS sandbox (which decides
whether the card's session.sh can bring the server up itself, or whether the
server moves to a host-side user service).

Enables Steam on `nb` and adds the host-side support the portable WoW 3.3.5a + AzerothCore SD card needs. The card itself is self-contained and travels between machines; only the machine-local pieces are declared here. ### Steam `hosts/nb/modules/steam.nix` already existed but was never imported, and it no longer evaluated at all — `amdvlk` has been removed from nixpkgs, so both `hardware.graphics.extraPackages` entries pointed at a missing attribute. Now on RADV, which `hardware-configuration.nix` already provides. `enable32Bit` is mandatory here, not a nicety: Proton is 32-bit by design and `Wow.exe` is a 32-bit binary. ### The i686 pypy bug, again Turning on 32-bit graphics re-triggered — from a second direction — the `makePythonWriter` bug this host already documents for the 32-bit ALSA plugins. `writers/scripts.nix:1203` guards on ```nix if pythonPackages != pkgs.pypy2Packages || pythonPackages != pkgs.pypy3Packages ``` a tautology whose operands force the pypy interpreter. `fetch-cargo-vendor-util` is itself a `writePython3` script, so every Rust package drags it in, and `graphics.nix:145` puts `pkgsi686Linux.mesa` in the i686 closure. On i686 pypy fails twice: no `i686-linux` in `meta.platforms`, and no `i686-linux` source hash in `python/default.nix`. So `allowUnsupportedSystem` does **not** help — it only moves the error one step down, which I confirmed. Stubbing `pypy2Packages` on i686 makes the first comparison cheap and true, so `||` short-circuits and `pypy3Packages` is never forced either. Nothing ever built pypy; it was only force-evaluated by that comparison. The stub is scoped to i686 and leaves the x86_64 set alone, so the existing `allowInsecurePredicate` is still doing its job there. With the root cause handled, `services.pipewire.alsa.support32Bit` no longer has to be forced off — and the NixOS Steam module sets it itself, so leaving the opt-out in place was a hard definition conflict. ### The card - **podman** — the card's single host requirement. Not interchangeable with the Docker daemon `nb` already runs: the AzerothCore images are an OCI/overlay store Docker cannot read. `dockerCompat` stays off. - **fuse-overlayfs** — the card's store carries `containers/storage/overlay/.has-mount-program`, so podman refuses it unless a mount program is on `PATH`. Arch always ships one; NixOS does not. - **A fixed mount at `/run/media/dominik/SteamSD`.** The Steam shortcut's appid is a crc32 of the absolute path to `Wow.exe`, and that path also lands in the launch options, `config.vdf`'s `CompatToolMapping` and the artwork filenames. A path that moves between sessions silently becomes a *different app* — no artwork, no compat tool, and a stale mapping key fails with no error at all. - **`WOW_GRAPHROOT`** moves the podman image store off the card onto the internal drive. The card's default keeps the store on itself so images travel, but that cannot work across these two machines: the store's `db.sql` records its own graphroot path, and the card mounts under a different user per machine (`/run/media/deck` on the handheld vs `/run/media/dominik` here), which podman rejects outright as a configuration mismatch. It also keeps 44 GB of layer reads off a ~165 MB/s card. `uid` is already 1000 and `/etc/subuid` already reads `dominik:100000:65536`, which is exactly the base the card's `server/mysql` ownership was built against — so no re-chown and no `podman system migrate`. ### Testing `scripts/test-configuration nb` passes. Runtime verification still to do after deploy: that `/etc/subuid` is unchanged, that podman reads the card's image store, and whether podman works inside Steam's FHS sandbox (which decides whether the card's `session.sh` can bring the server up itself, or whether the server moves to a host-side user service).
Steam was already written in hosts/nb/modules/steam.nix but never imported,
and it no longer evaluated: amdvlk has been removed from nixpkgs, so both
hardware.graphics.extraPackages entries referenced a missing attribute. Drop
to RADV, which hardware-configuration.nix already provides via
hardware.graphics.enable. Also drop vulkan-headers, vulkan-loader, wlroots and
libdecor from systemPackages — they are libraries, and installing them there
does not put them on any application's linker path.

enable32Bit is required rather than optional: Proton is 32-bit by design and
WoW 3.3.5a's Wow.exe is a 32-bit binary. That turned out to re-trigger, from a
second direction, the makePythonWriter bug this host already documents for the
32-bit ALSA plugins: writers/scripts.nix guards on a tautology whose operands
force the pypy interpreter, fetch-cargo-vendor-util is itself a writePython3
script, and graphics.nix puts pkgsi686Linux.mesa in the closure. On i686 pypy
has neither a meta.platforms entry nor a source hash, so allowUnsupportedSystem
only moves the error one step down. Stub pypy2Packages on i686 so the guard
short-circuits; nothing ever built it, it was only force-evaluated.

With that fixed at the root, services.pipewire.alsa.support32Bit no longer has
to be forced off — and the Steam module sets it itself, so leaving the opt-out
in place was a definition conflict.

wow-portable.nix adds what the AzerothCore SD card needs from this host:
podman (the card's only host requirement; Docker cannot read an OCI/overlay
store), fuse-overlayfs (the card's store carries .has-mount-program and podman
refuses it otherwise), and a fixed mount at /run/media/dominik/SteamSD. The
mount point has to be stable because the Steam shortcut's appid is a crc32 of
the absolute path to Wow.exe, so a path that moves silently becomes a
different app with no artwork and no compat tool.

WOW_GRAPHROOT moves the podman image store off the card onto the internal
drive. The card's default keeps the store on itself so images travel, but the
store's db.sql records its own graphroot path and the card mounts under a
different user per machine (/run/media/deck vs /run/media/dominik), which
podman rejects as a configuration mismatch.
dominik.polakovics deleted branch feat/nb-steam-wow-portable 2026-08-01 13:33:40 +02:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Cloonar/nixos!246
No description provided.