{ pkgs, lib, username, inputs, site_config, ... }: { imports = [ ../../modules/desktop-common.nix ../../modules/desktop-jovian.nix ../../modules/no-rgb.nix ./disk.nix ./impermanence.nix ./lact.nix ./vr.nix ./forza-trigger ../../modules/desktop-game-mods.nix inputs.impermanence.nixosModules.impermanence ]; fileSystems."/media/games" = { device = "/dev/disk/by-uuid/1878136e-765d-4784-b204-3536ab4fdac8"; fsType = "f2fs"; options = [ "nofail" ]; }; systemd.targets = { sleep.enable = false; suspend.enable = false; hibernate.enable = false; hybrid-sleep.enable = false; }; networking.hostId = "abf570f9"; # Static IP for consistent SSH access networking.networkmanager.ensureProfiles.profiles.enp7s0-static = { connection = { id = "enp7s0-static"; type = "ethernet"; interface-name = "enp7s0"; autoconnect = true; }; ipv4 = { method = "manual"; address1 = "${site_config.hosts.yarn.ip}/24,${site_config.lan.gateway}"; dns = lib.concatMapStrings (n: "${n};") site_config.dns_servers; }; ipv6.method = "disabled"; }; services.openssh = { enable = true; ports = [ 22 ]; settings = { PasswordAuthentication = false; PermitRootLogin = "yes"; }; }; users.users.${username}.openssh.authorizedKeys.keys = [ site_config.ssh_keys.laptop ]; users.users.root.openssh.authorizedKeys.keys = [ site_config.ssh_keys.laptop site_config.ssh_keys.ci_deploy ]; programs.steam = { remotePlay.openFirewall = true; localNetworkGameTransfers.openFirewall = true; }; environment.systemPackages = [ pkgs.jovian-stubs ]; # yarn is not a Steam Deck jovian.devices.steamdeck.enable = false; # PS5 DualSense adaptive triggers in Forza Horizon 4 / 5. services.forzaTrigger.enable = true; # Declarative game-file mods on top of Steam. # # fh5-no-intro: stub the 40 MB T10/Microsoft Studios cold-start splash. # Two copies live in the install (SD + hires); engine picks one based on # the installed asset profile, so stub both. PCGamingWiki documents both # paths under "Skip intro video". # # fh5-optiscaler: drop OptiScaler v0.9.1 + a FH5-tuned OptiScaler.ini into # the install dir to enable FSR 4 INT8 on this RDNA 3 Navi 32 box. # OptiScaler intercepts FH5's DLSS/XeSS calls and reroutes them through # the bundled FFX SDK. Settings flipped from upstream defaults: # Fsr4Update auto -> true # FSR 4 path required for INT8 RDNA 3 # Dxgi auto -> false # FH5 wiki: required for 0.9 # DlssReactiveMaskBias auto -> 0.65 # FH5 wiki: fixes flickering lights, reduces car ghosting # # Required one-time per-game setup in Steam (Proton picker is not # declarable from NixOS; launch options are written declaratively below): # 1. Properties -> Compatibility: force "GE-Proton" (proton-ge-bin is # already in extraCompatPackages; pick the latest installed). # Steam must be closed when the launch options write happens, or # Steam will overwrite our localconfig.vdf edit on shutdown. # 2. In-game: switch the Upscaling option from FSR 2.2 to DLSS or XeSS # (FSR 2 inputs aren't intercepted). Press Insert to open the Opti # overlay and set the FFX upscaler to FSR 4. # # Caveats: # - OptiScaler.ini is dropped with mode = "init" so in-game overlay edits # persist. The awk-patched template below is only written on first apply # (or after manual deletion). To push a new default into an existing # install: rm OptiScaler.ini in the FH5 dir, then `systemctl start # game-mods`. The DLLs and other static assets stay mode = "create" so # they're updated on every OptiScaler version bump. # - OptiScaler's installation page warns against use with online games. # FH5 has no kernel-mode anti-cheat but Playground does server-side # telemetry. Use at your own risk. # # fh5-vkd3d-no-hvv: append `VKD3D_CONFIG=no_upload_hvv` to FH5's launch # options. Disables vkd3d-proton's host-visible VRAM upload heap, which # works around a Proton stutter/crash on this box. Kept as its own mod # (no files, just env) so the workaround can be removed independently of # OptiScaler when a future Proton release fixes the underlying issue. services.gameMods = let optiPkg = pkgs.optiscaler; # OptiScaler.ini ships with CRLF line endings, so we use awk with explicit # RS/ORS to keep the rewrites line-ending agnostic. The regex is matched # against the CR-stripped record, the original CRLF is restored on output. optiIni = pkgs.runCommand "OptiScaler-fh5.ini" { } '' awk -v RS='\r\n' -v ORS='\r\n' ' /^Fsr4Update=auto$/ { print "Fsr4Update=true"; next } /^Dxgi=auto$/ { print "Dxgi=false"; next } /^DlssReactiveMaskBias=auto$/ { print "DlssReactiveMaskBias=0.65"; next } { print } ' ${optiPkg}/OptiScaler.ini > $out ''; fromOpti = relpath: { source = "${optiPkg}/${relpath}"; mode = "create"; }; in { enable = true; mods."fh5-no-intro" = { steamAppId = 1551360; files."media/UI/Videos/T10_MS_Combined.bk2".empty = true; files."media/UI/Videos/hires/T10_MS_Combined.bk2".empty = true; }; mods."fh5-optiscaler" = { steamAppId = 1551360; # RDNA 3 (Navi 32) FSR 4 path on Linux: # PROTON_FSR4_UPGRADE=1 opts FH5 into Proton's FSR 4 upgrade. # DXIL_SPIRV_CONFIG=wmma_rdna3_... fixes broken visuals on RDNA 3 per # the OptiScaler FSR4 wiki. # Other FH5-targeting mods (e.g. fh5-vkd3d-no-hvv) append their own # entries to this list; the module joins them and adds %command%. launchOptions = [ "PROTON_FSR4_UPGRADE=1" "DXIL_SPIRV_CONFIG=wmma_rdna3_workaround" ]; files = { # OptiScaler.dll is renamed to dxgi.dll so FH5's DLL search order # picks it up as the dxgi shim per the OptiScaler FH5 wiki page. "dxgi.dll" = fromOpti "OptiScaler.dll"; "OptiScaler.ini" = { source = optiIni; # init: drop the patched template once, then leave it alone so # the in-game overlay can persist user tweaks. mode = "init"; }; } // lib.genAttrs [ "D3D12_Optiscaler/D3D12Core.dll" "amd_fidelityfx_dx12.dll" "amd_fidelityfx_framegeneration_dx12.dll" "amd_fidelityfx_upscaler_dx12.dll" "amd_fidelityfx_vk.dll" "dlssg_to_fsr3_amd_is_better.dll" "fakenvapi.dll" "fakenvapi.ini" "libxell.dll" "libxess.dll" "libxess_dx11.dll" "libxess_fg.dll" ] fromOpti; }; mods."fh5-vkd3d-no-hvv" = { steamAppId = 1551360; launchOptions = [ "VKD3D_CONFIG=no_upload_hvv" ]; }; }; }