Commit 0179e0d

HPCesia <me@hpcesia.com>
2026-06-22 17:59:00
Implement game role
1 parent 61a981f
modules/game/gamepad.nix
@@ -0,0 +1,31 @@
+{
+  den.aspects.game.gamepad = {
+    nixos = {
+      pkgs,
+      config,
+      ...
+    }: {
+      hardware = {
+        uinput.enable = true;
+        xone.enable = true;
+        xpadneo.enable = true;
+      };
+
+      boot = {
+        extraModulePackages = [
+          config.boot.kernelPackages.xpadneo
+        ];
+        extraModprobeConfig = ''
+          options bluetooth disable_ertm=Y
+        '';
+        kernelModules = [
+          "hid_microsoft"
+        ];
+      };
+
+      services.udev.packages = [
+        pkgs.game-devices-udev-rules
+      ];
+    };
+  };
+}
modules/game/heroic.nix
@@ -0,0 +1,39 @@
+{lib, ...}: {
+  den.aspects.game.heroic = {
+    cacheHome = {config, ...}: {
+      directories = [
+        "${config.xdg.configHome}/heroic"
+        "${config.xdg.stateHome}/Heroic"
+      ];
+    };
+
+    homeManager = {
+      osConfig,
+      pkgs,
+      ...
+    }: {
+      home.packages = with pkgs; [
+        heroic
+      ];
+
+      xdg.configFile = lib.mergeAttrsList (
+        map
+        (w: {"heroic/tools/proton/${w.pname}".source = w.steamcompattool;})
+        osConfig.programs.steam.extraCompatPackages
+      );
+    };
+  };
+
+  den.aspects.game.heroic.themes = {
+    catppuccin = {
+      homeManager = {pkgs, ...}: {
+        xdg.configFile."heroic/themes".source = "${pkgs.fetchFromGitHub {
+          owner = "catppuccin";
+          repo = "heroic";
+          rev = "1248e2d24721aa1cc54f185b1b851826207a2b46";
+          hash = "sha256-JcLvp/7F+lmU8FVkrMvgtnu087XLS1T3/3X6OrA/yOg=";
+        }}/themes";
+      };
+    };
+  };
+}
modules/game/hoyo.nix
@@ -0,0 +1,38 @@
+{
+  den.aspects.game.hoyo = {
+    nixos = {
+      networking.hosts = {
+        "0.0.0.0" = [
+          "osuspider.yuanshen.com"
+          "overseauspider.yuanshen.com"
+          "uspider.yuanshen.com"
+
+          "log-upload-os.hoyoverse.com"
+          "log-upload-os.mihoyo.com"
+          "apm-log-upload-os.hoyoverse.com"
+          # "zzz-log-upload-os.hoyoverse.com"
+          "log-upload.mihoyo.com"
+          "ys-log-upload.mihoyo.com"
+          "ys-log-upload-os.hoyoverse.com"
+          "hkrpg-log-upload-os.hoyoverse.com"
+          "dump.gamesafe.qq.com"
+          "devlog-upload.mihoyo.com"
+
+          "globaldp-prod-cn01.bhsr.com"
+          # "globaldp-prod-cn01.juequling.com"
+
+          "sg-public-data-api.hoyoverse.com"
+          "public-data-api.mihoyo.com"
+
+          "prd-lender.cdp.internal.unity3d.com"
+          "thind-prd-knob.data.ie.unity3d.com"
+          "thind-gke-usc.prd.data.corp.unity3d.com"
+          "cdp.cloud.unity3d.com"
+          "remote-config-proxy-prd.uca.cloud.unity3d.com"
+
+          "pc.crashsight.wetest.net"
+        ];
+      };
+    };
+  };
+}
modules/game/ludusavi.nix
@@ -0,0 +1,17 @@
+{
+  den.aspects.game.ludusavi = {
+    persistHome = {config, ...}: {
+      directories = [
+        "${config.xdg.configHome}/ludusavi"
+      ];
+    };
+
+    homeManager = {pkgs, ...}: {
+      # Use ludusavi to avoid add every Linux native game's
+      # data folder into persistence.
+      home.packages = with pkgs; [
+        ludusavi
+      ];
+    };
+  };
+}
modules/game/lutris.nix
@@ -0,0 +1,41 @@
+{
+  den.aspects.game.lutris = {
+    persistHome = {config, ...}: {
+      directories = [
+        "${config.xdg.configHome}/lutris"
+      ];
+    };
+
+    cacheHome = {config, ...}: {
+      directories = [
+        "${config.xdg.dataHome}/lutris"
+      ];
+    };
+
+    homeManager = {
+      pkgs,
+      osConfig,
+      ...
+    }: {
+      programs.lutris = {
+        enable = true;
+        steamPackage = osConfig.programs.steam.package;
+        defaultWinePackage = pkgs.nur.repos.hpcesia.dwproton-bin;
+        protonPackages = [
+          pkgs.proton-ge-bin
+          pkgs.nur.repos.hpcesia.dwproton-bin
+        ];
+        winePackages = [
+          pkgs.wineWow64Packages.full
+        ];
+        extraPackages = with pkgs; [
+          winetricks
+          gamescope
+          gamemode
+          mangohud
+          bubblewrap
+        ];
+      };
+    };
+  };
+}
modules/game/minecraft.nix
@@ -0,0 +1,17 @@
+{
+  den.aspects.game.minecraft = {
+    cacgeHome = {config, ...}: {
+      directories = [
+        "${config.xdg.dataHome}/PrismLauncher"
+      ];
+    };
+
+    homeManager = {pkgs, ...}: {
+      home.packages = with pkgs; [
+        (prismlauncher.override {
+          additionalPrograms = [ffmpeg-headless];
+        })
+      ];
+    };
+  };
+}
modules/game/steam.nix
@@ -0,0 +1,66 @@
+{
+  den.aspects.game.steam = {
+    cacheHome = {config, ...}: {
+      directories = [
+        "${config.xdg.configHome}/millennium"
+        "${config.xdg.dataHome}/millennium"
+        "${config.xdg.dataHome}/Steam"
+        ".steam"
+      ];
+    };
+
+    nixos = {pkgs, ...}: let
+      millennium-src = pkgs.fetchFromGitHub {
+        owner = "SteamClientHomebrew";
+        repo = "Millennium";
+        rev = "v3.3.1";
+        hash = "sha256-nqNRtEkYgXawzpw/xCAgMSyaHKl5GFvzKm8WOoaUN24=";
+      };
+      millennium = pkgs.callPackage "${millennium-src}/packages/nix/millennium.nix" {inherit millennium-src;};
+      millennium-steam = pkgs.callPackage "${millennium-src}/packages/nix/steam.nix" {inherit millennium;};
+    in {
+      hardware = {
+        steam-hardware.enable = true;
+      };
+
+      programs.steam = {
+        enable = true;
+        dedicatedServer.openFirewall = true;
+
+        extraCompatPackages = [
+          pkgs.proton-ge-bin
+          pkgs.nur.repos.vladexa.proton-cachyos-v3
+          pkgs.nur.repos.hpcesia.dwproton-bin
+        ];
+
+        package = millennium-steam.override {
+          extraEnv = {
+            MANGOHUD = true;
+            OBS_VKCAPTURE = true;
+            PROTON_ENABLE_WAYLAND = true;
+            PROTON_ENABLE_HDR = true;
+            PROTON_USE_NTSYNC = true;
+            PROTON_USE_WOW64 = true;
+          };
+        };
+      };
+
+      # https://steamdeck-packages.steamos.cloud/archlinux-mirror/jupiter-main/os/x86_64/steamos-customizations-jupiter-20250117.1-1-any.pkg.tar.zst
+      boot.kernel.sysctl = {
+        # 20-shed.conf
+        "kernel.sched_cfs_bandwidth_slice_us" = 3000;
+        # 20-net-timeout.conf
+        # This is required due to some games being unable to reuse their TCP ports
+        # if they're killed and restarted quickly - the default timeout is too large.
+        "net.ipv4.tcp_fin_timeout" = 5;
+        # 30-splitlock.conf
+        # Prevents intentional slowdowns in case games experience split locks
+        # This is valid for kernels v6.0+
+        "kernel.split_lock_mitigate" = 0;
+        # 30-vm.conf
+        # USE MAX_INT - MAPCOUNT_ELF_CORE_MARGIN.
+        "vm.max_map_count" = 2147483642;
+      };
+    };
+  };
+}
modules/game/utils.nix
@@ -0,0 +1,58 @@
+{
+  den.aspects.game.utils = {
+    cacheHome = {config, ...}: {
+      directories = [
+        "${config.xdg.userDirs.extraConfig.GAMES}"
+      ];
+    };
+
+    nixos = {pkgs, ...}: {
+      programs.gamemode = {
+        enable = true;
+      };
+
+      # load ntsync
+      boot.kernelModules = ["ntsync"];
+      # make ntsync device accessible
+      services.udev.packages = [
+        (pkgs.writeTextFile {
+          name = "ntsync-udev-rules";
+          text = ''KERNEL=="ntsync", MODE="0660", TAG+="uaccess"'';
+          destination = "/etc/udev/rules.d/70-ntsync.rules";
+        })
+      ];
+    };
+
+    homeManager = {config, ...}: {
+      xdg.userDirs = {
+        extraConfig = {
+          GAMES = "${config.home.homeDirectory}/Games";
+        };
+      };
+
+      programs.mangohud = {
+        enable = true;
+        settings = {
+          fps = true;
+          frametime = true;
+
+          # Hardware stats
+          cpu_stats = true;
+          cpu_temp = true;
+          cpu_power = true;
+          cpu_mhz = true;
+          gpu_stats = true;
+          gpu_temp = true;
+          gpu_power = true;
+          gpu_core_clock = true;
+          gpu_mem_clock = true;
+          ram = true;
+          vram = true;
+
+          # Keybinds
+          toggle_hud = "Shift_R+F12";
+        };
+      };
+    };
+  };
+}
modules/roles/game.nix
@@ -1,6 +1,8 @@
 {den, ...}: {
   den.aspects.roles.game = {
     includes = with den.aspects; [
+      game.gamepad
+      game.utils
     ];
   };
 }
modules/users/hpcesia/default.nix
@@ -37,6 +37,11 @@
       ++ (den.lib.policy.when
         ({host, ...}: host.hasAspect den.aspects.roles.game)
         (with den.aspects; [
+          game.heroic
+          game.hoyo
+          game.ludusavi
+          game.minecraft
+          game.steam
         ]));
   };