{ ... }: {
  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 =
        lib.optional (cfg.steam.steamTinkerLaunch.enable && lib.meta.availableOn pkgs.stdenv.hostPlatform pkgs.steamtinkerlaunch) pkgs.steamtinkerlaunch;

      launcherSet = launcherPkgs ++ steamExtraPkgs ++ cfg.launchers.extraPackages;
    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 = launcherSet;
        })
        (lib.mkIf (cfg.launchers.forUsers != null) {
          users.users = lib.genAttrs cfg.launchers.forUsers (_: {
            packages = launcherSet;
          });
        })
      ]);
    };
}
