Steam and Blue Archive on NixOS-WSL

Share
This is an LLM generated summary (GPT-6 Astra) of a troubleshooting session getting the above working, posted for posterity.

Working setup as of 2026-09-05, using WSLg and an NVIDIA RTX 3080. Steam opens and Blue Archive runs; hardware acceleration was verified with glxinfo outside Proton. In-game performance has not been benchmarked.

What went wrong

  • Steam's UI needed GPU-disabled Chromium flags and software rendering to display reliably. Blue Archive must unset that inherited software-rendering flag.
  • There are two container layers: NixOS's Steam FHS environment, then Proton's pressure-vessel runtime. Working host graphics did not imply working graphics inside the game.
  • wsl.useWindowsDriver supplies Nix-store symlinks to /usr/lib/wsl/lib. Proton's own /usr hid those original paths. Forwarding symlinks alone did not expose their targets.
  • WSL's lib and drivers directories are separate mounts. A plain bind of /usr/lib/wsl exposed empty underlying directories; a recursive bind was required.
  • Even after forwarding the files, pressure-vessel replaced LD_LIBRARY_PATH. After fixing that, the loader trace showed D3D12 opening NVIDIA's driver by an absolute /usr/lib/wsl/drivers/.../libnvwgf2umx.so path. A search-path change cannot redirect an absolute filename.
  • Once those paths were restored, Blue Archive reached Unity but crashed in dxgi while using the DXVK/Vulkan path. Selecting WineD3D finally made Blue Archive run. The precise cause of the DXVK crash was not established.

The working fix

Keep wsl.useWindowsDriver = true and graphics support enabled. /etc/nixos/configuration.nix declares the persistent forwarding mount:

fileSystems."/mnt/wsl-gpu" = {
  device = "/usr/lib/wsl";
  fsType = "none";
  options = [ "rbind" "rslave" "nofail" ];
};

rbind includes the nested mounts, rslave prevents mount events from propagating back to the source, and nofail avoids making a failed GPU mount block boot. The Steam package also retains its outer bind from /usr/lib/wsl to /usr/lib64/wsl, with a mountpoint supplied by an extra package.

~/ba-container-env.sh inserts a wrapper inside pressure-vessel, before Proton. It adds /mnt/wsl-gpu/lib to the library search path, then uses Steam's bundled srt-bwrap to:

  1. Preserve the existing container filesystem and device access.
  2. Put a temporary writable overlay over /usr/lib.
  3. Restore pressure-vessel's library overrides beneath that overlay.
  4. Bind /mnt/wsl-gpu at the required /usr/lib/wsl path.

The overlay is temporary; it does not edit Valve's runtime files. This is a working workaround, not a verified upstream NixOS/Proton integration fix.

ba-container-env.sh

#!/usr/bin/env bash
args=("$@")

for i in "${!args[@]}"; do
    if [[ "${args[i]}" == */proton ]]; then
        exec "${args[@]:0:i}" /bin/sh -c '
            export LD_LIBRARY_PATH="/mnt/wsl-gpu/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"

            bwrap="/home/nixos/.local/share/Steam/steamapps/common/SteamLinuxRuntime_4/pressure-vessel/libexec/steam-runtime-tools-0/srt-bwrap"

            exec "$bwrap" \
                --unshare-user \
                --dev-bind / / \
                --overlay-src /usr/lib \
                --tmp-overlay /usr/lib \
                --ro-bind /usr/lib/pressure-vessel /usr/lib/pressure-vessel \
                --ro-bind /mnt/wsl-gpu /usr/lib/wsl \
                -- "$@"
        ' ba-env "${args[@]:i}"
    fi
done

echo "Could not locate Proton in launch command" >&2
exit 1

Blue Archive's current Steam launch options are:

PRESSURE_VESSEL_FILESYSTEMS_RO=/run/opengl-driver:/mnt/wsl-gpu env -u LIBGL_ALWAYS_SOFTWARE GALLIUM_DRIVER=d3d12 MESA_D3D12_DEFAULT_ADAPTER_NAME=NVIDIA PROTON_USE_WINED3D=1 /home/nixos/ba-container-env.sh %command%

Launch through Steam or start-ba, not by invoking Blue Archive directly: the game needs Steam's client context. SteamCMD did not replace that requirement.

Other notes and verification

  • An earlier WSLg shared-memory/copy-mode issue was separate from library discovery. After restarting WSL, Weston reported use_gfxredir = 1.
  • Locale generation and mixed-architecture overlay warnings were not the blockers we fixed. The GLX warning became actionable when Wine also reported failure to initialize OpenGL.
  • Remove LD_PRELOAD, LD_DEBUG, and LD_DEBUG_OUTPUT experiments. The current wrapper has none, and launch options no longer include PROTON_LOG=1.
  • Steam (NixOS) and Blue Archive (NixOS) desktop shortcuts are configured.
  • The wrapper still lives in the home directory and names SteamLinuxRuntime_4; it is not yet packaged declaratively in NixOS.

The persistent mount configuration was built and activated successfully, and systemd registered it. A fresh WSL restart has not yet been verified. After one, check the mount and libraries, then launch Blue Archive:

findmnt -R /mnt/wsl-gpu
ls -l /mnt/wsl-gpu/lib/libd3d12core.so
ls /mnt/wsl-gpu/drivers
start-ba

Avoid removing more graphics settings together: the complete combination works, but each remaining setting has not been independently tested for redundancy.