{ ... }: { flake.nixosModules.systemGaming = { config, lib, pkgs, ... }: let cfg = config.chiasson.system.gaming; launcherPkgs = with pkgs; [ lutris wine winetricks gamemode mangohud goverlay ] ++ lib.optionals cfg.launchers.enableBottles [ bottles ] ++ lib.optionals pkgs.stdenv.isx86_64 [ heroic ]; steamExtraPkgs = if !cfg.steam.steamTinkerLaunch.enable then [ ] else lib.optional (lib.meta.availableOn pkgs.stdenv.hostPlatform pkgs.steamtinkerlaunch) pkgs.steamtinkerlaunch; in { options.chiasson.system.gaming = { enable = lib.mkEnableOption '' Steam (+ firewall toggles), 32-bit GL/Vulkan, gamemode, JACK via PipeWire, launcher bundle. ''; steam = { remotePlay.openFirewall = lib.mkOption { type = lib.types.bool; default = true; description = "Open firewall for Steam Remote Play."; }; dedicatedServer.openFirewall = lib.mkOption { type = lib.types.bool; default = true; description = "Open firewall for Steam dedicated servers."; }; steamTinkerLaunch.enable = lib.mkEnableOption '' [SteamTinkerLaunch](https://github.com/frostworx/steamtinkerlaunch) — Steam wrapper for custom launch options, Proton helpers, and third-party tools. Adds `pkgs.steamtinkerlaunch` next to the launcher package set (`environment.systemPackages` or `launchers.forUsers`). ''; }; graphics = { enable = lib.mkOption { type = lib.types.bool; default = true; description = "`hardware.graphics.enable` (Vulkan/GL stack)."; }; enable32Bit = lib.mkOption { type = lib.types.bool; default = true; description = "`hardware.graphics.enable32Bit` (Steam / Proton 32-bit)."; }; }; gamemode.enable = lib.mkOption { type = lib.types.bool; default = true; description = "`programs.gamemode` (Feral GameMode)."; }; gamescope = { enable = lib.mkEnableOption '' `programs.gamescope` — isolated compositor for Steam/Proton on Wayland (fixes games embedding inside the Steam window). ''; capSysNice = lib.mkOption { type = lib.types.bool; default = true; description = "Allow gamescope to renice itself for smoother frame pacing."; }; }; jack.enable = lib.mkOption { type = lib.types.bool; default = true; description = '' Set `chiasson.system.audio.pipewire.jack.enable` (PipeWire JACK). Requires `chiasson.system.audio.enable` on the host. ''; }; sunshine = { enable = lib.mkEnableOption "Sunshine — self-hosted Moonlight streaming host"; openFirewall = lib.mkOption { type = lib.types.bool; default = true; description = "Open Sunshine/Moonlight ports via `services.sunshine.openFirewall`."; }; capSysAdmin = lib.mkOption { type = lib.types.bool; default = true; description = '' Grant CAP_SYS_ADMIN to Sunshine for DRM/KMS capture (`services.sunshine.capSysAdmin`). ''; }; autoStart = lib.mkOption { type = lib.types.bool; default = true; description = "Start Sunshine with the graphical session."; }; cudaSupport = lib.mkOption { type = lib.types.bool; default = false; description = '' Build Sunshine with CUDA/NVENC (`pkgs.sunshine.override { cudaSupport = true; }`). Enable on NVIDIA hosts for hardware encoding. ''; }; }; launchers = { enableBottles = lib.mkOption { type = lib.types.bool; default = true; description = "Install native `pkgs.bottles` in the launcher bundle."; }; forUsers = lib.mkOption { type = lib.types.nullOr (lib.types.listOf lib.types.str); default = null; description = '' Per-user `packages` for launchers; `null` → `environment.systemPackages`. ''; }; extraPackages = lib.mkOption { type = lib.types.listOf lib.types.package; default = [ ]; description = "Additional packages merged with the default launcher set."; }; }; }; config = lib.mkIf cfg.enable (lib.mkMerge [ { # openldap's upstream test suite is flaky in the Nix sandbox (test017, test001, …). # Disabling checks avoids cascading failures in lutris, apache, gnupg, nfs-utils, etc. # Upstream: https://github.com/NixOS/nixpkgs/issues/514113 nixpkgs.overlays = [ (_: prev: { openldap = prev.openldap.overrideAttrs (_: { doCheck = false; }); }) ]; programs.steam = { enable = true; remotePlay.openFirewall = cfg.steam.remotePlay.openFirewall; dedicatedServer.openFirewall = cfg.steam.dedicatedServer.openFirewall; }; services.sunshine = lib.mkIf cfg.sunshine.enable { enable = true; openFirewall = cfg.sunshine.openFirewall; capSysAdmin = cfg.sunshine.capSysAdmin; autoStart = cfg.sunshine.autoStart; package = pkgs.sunshine.override { cudaSupport = cfg.sunshine.cudaSupport; cudaPackages = pkgs.cudaPackages; }; }; hardware.graphics = lib.mkIf cfg.graphics.enable { enable = true; enable32Bit = cfg.graphics.enable32Bit; }; programs.gamemode.enable = cfg.gamemode.enable; programs.gamescope = lib.mkIf cfg.gamescope.enable { enable = true; inherit (cfg.gamescope) capSysNice; }; chiasson.system.audio.pipewire.jack.enable = lib.mkIf (cfg.jack.enable) (lib.mkDefault true); assertions = [ { assertion = !cfg.enable || !cfg.jack.enable || config.chiasson.system.audio.enable; message = "chiasson.system.gaming with JACK requires `chiasson.system.audio.enable` (PipeWire)."; } ]; } (lib.mkIf (cfg.launchers.forUsers == null) { environment.systemPackages = launcherPkgs ++ steamExtraPkgs ++ cfg.launchers.extraPackages; }) (lib.mkIf (cfg.launchers.forUsers != null) { users.users = lib.genAttrs cfg.launchers.forUsers (_: { packages = launcherPkgs ++ steamExtraPkgs ++ cfg.launchers.extraPackages; }); }) ]); }; }