{
  config,
  lib,
  pkgs,
  username,
  inputs,
  ...
}:
let
  cfg = config.gaming;
  p = with pkgs; {
    games = [
      openttd
      prismlauncher # MineCraft
    ];
    tools = [
      dolphin-emu
      xboxdrv
      ## Other
      inputs.aaru.packages.${pkgs.system}.default
      adwsteamgtk
      chiaki-ng
      inputs.nix-game-preservation.packages.${pkgs.system}.discimagecreator
      ffmpeg
      flips
      gst_all_1.gstreamer
      gst_all_1.gstreamermm
      gst_all_1.gst-plugins-rs
      gst_all_1.gst-plugins-bad
      gst_all_1.gst-plugins-base
      gst_all_1.gst-plugins-good
      gst_all_1.gst-plugins-ugly
      gst_all_1.gst-libav
      gst_all_1.gst-vaapi
      gswatcher
      igir
      innoextract
      mpg123
      parsec-bin
      python313Packages.lnkparse3
      x264
      x265
      xvidcore
      ## Wine
      inputs.nix-gaming.packages.${pkgs.system}.wine-discord-ipc-bridge
      inputs.nix-gaming.packages.${pkgs.system}.wine-tkg
      winetricks
      # wineWowPackages.stagingFull
      ## One-and-dones
      glxinfo
      /*
           jpsxdec
           mame.tools
           mmv
           nsz
           ps3-disc-dumper
           renderdoc
           vgmplay-libvgm
           vgmstream
           vgmtools
           vgmtrans
           vulkan-tools
      */
    ];
  };
in
{
  options = {
    gaming = {
      enable = lib.mkEnableOption "Enable Gaming module in NixOS";
    };
  };
  config = lib.mkIf cfg.enable {
    # Custom modules
    coolercontrol.enable = true;
    gamemode.enable = true;
    gamescope.enable = true;
    lact.enable = true;
    mangohud.enable = true;
    obs.enable = true;
    steam.enable = true;
    sunshine.enable = true;

    boot = {
      extraModprobeConfig = ''
        options v4l2loopback devices=1 video_nr=1 card_label="OBS Cam" exclusive_caps=1
      '';
      extraModulePackages = with config.boot.kernelPackages; [
        v4l2loopback
      ];
      # initrd = {
      #   kernelModules = [
      #   ];
      # };
      kernelParams = [
        # "usbhid.mousepoll=8" # Reduce mouse polling rate to 125hz
        "gpu_sched.sched_policy=0" # https://gitlab.freedesktop.org/drm/amd/-/issues/2516#note_2119750
        "amdgpu.mcbp=0"
        "tsc=reliable"
        "clocksource=tsc"
        "preempt=full" # https://reddit.com/r/linux_gaming/comments/1g0g7i0/god_of_war_ragnarok_crackling_audio/lr8j475/?context=3#lr8j475
      ];
      kernel = {
        sysctl = {
          # "kernel.sched_cfs_bandwidth_slice_us" = 3000;
          # "net.ipv4.tcp_fin_timeout" = 5;
          "vm.max_map_count" = 2147483642;
          "vm.mmap_min_addr" = 0; # SheepShaver
          # https://github.com/CachyOS/CachyOS-Settings/blob/master/usr/lib/sysctl.d/99-cachyos-settings.conf
          "fs.file-max" = 2097152;
          "fs.inotify.max_user_watches" = 524288;
          "net.core.netdev_max_backlog" = 16384;
          "net.core.somaxconn" = 8192;
          "net.ipv4.tcp_slow_start_after_idle" = 0;
        };
      };
    };

    # environment = {
    #   sessionVariables = {
    #     # https://reddit.com/r/linux_gaming/comments/1c2ey6u/vrr_newbie_questions_plasma_6_wayland_amd/kzasm0j/?context=3#kzasm0j
    #     KWIN_DRM_DELAY_VRR_CURSOR_UPDATES = "1";
    #     KWIN_FORCE_SW_CURSOR = "1";
    #   };
    # };

    hardware = {
      new-lg4ff.enable = true;
      uinput.enable = true;
      xone.enable = true;
      xpadneo.enable = true;
    };

    networking = {
      firewall = {
        allowedUDPPorts = [
          # Moonlight
          5353
          47998
          47999
          48000
          48002
          48010
        ];
        allowedTCPPorts = [
          # Moonlight
          47984
          47989
          48010
        ];
      };
    };

    nix.settings = {
      extra-substituters = [
        "https://nix-gaming.cachix.org"
        "https://nix-citizen.cachix.org"
      ];
      extra-trusted-public-keys = [
        "nix-citizen.cachix.org-1:lPMkWc2X8XD4/7YPEEwXKKBg+SVbYTVrAaLA2wQTKCo="
        "nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4="
      ];
    };

    nixpkgs.config.permittedInsecurePackages = [
      # "freeimage-unstable-2021-11-01" # Trenchbroom / SLADE
    ];

    services = {
      hardware = {
        openrgb = {
          enable = true;
          package = pkgs.openrgb-with-all-plugins;
        };
      };
      # joycond.enable = true;
      # ratbagd.enable = true;
      scx = {
        enable = true;
        package = pkgs.scx.rustscheds;
        scheduler = "scx_rusty";
      };
      # udev = {
      #   extraRules = ''
      #     # https://wiki.archlinux.org/title/Improving_performance#Changing_I/O_scheduler
      #     # HDD
      #     ACTION=="add|change", KERNEL=="sd[a-z]*", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="bfq"

      #     # SSD
      #     ACTION=="add|change", KERNEL=="sd[a-z]*|mmcblk[0-9]*", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="bfq"

      #     # NVMe SSD
      #     ACTION=="add|change", KERNEL=="nvme[0-9]*", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="none"
      #   '';
      #   packages = with pkgs; [
      #     game-devices-udev-rules
      #     # https://wiki.archlinux.org/title/Gamepad#Motion_controls_taking_over_joypad_controls_and/or_causing_unintended_input_with_joypad_controls
      #     (writeTextFile {
      #       name = "51-disable-DS3-and-DS4-motion-controls.rules";
      #       text = ''
      #         SUBSYSTEM=="input", ATTRS{name}=="*Controller Motion Sensors", RUN+="${pkgs.coreutils}/bin/rm %E{DEVNAME}", ENV{ID_INPUT_JOYSTICK}=""
      #       '';
      #       destination = "/etc/udev/rules.d/51-disable-DS3-and-DS4-motion-controls.rules";
      #     })
      #     # https://reddit.com/r/linux_gaming/comments/1fu4ggk/can_someone_explain_dualsense_to_me/lpwxv12/?context=3#lpwxv12
      #     (writeTextFile {
      #       name = "51-disable-dualsense-sound-and-vibration.rules";
      #       text = ''
      #         KERNEL=="hidraw*", ATTRS{idVendor}=="054c", ATTRS{idProduct}=="0ce6", MODE="0660", TAG+="uaccess"
      #         KERNEL=="hidraw*", KERNELS=="*054C:0CE6*", MODE="0660", TAG+="uaccess"
      #         ATTRS{idVendor}=="054c", ATTRS{idProduct}=="0ce6", ENV{PULSE_IGNORE}="1", ENV{ACP_IGNORE}="1"
      #       '';
      #       destination = "/etc/udev/rules.d/51-disable-dualsense-sound-and-vibration.rules";
      #     })
      #   ];
      # };
    };

    security = {
      pam = {
        loginLimits = [
          {
            domain = "*";
            item = "memlock";
            type = "hard";
            value = "unlimited";
          }
          {
            domain = "*";
            item = "memlock";
            type = "soft";
            value = "unlimited";
          }
          {
            domain = "*";
            item = "nofile";
            type = "hard";
            value = "1048576";
          }
          {
            domain = "*";
            item = "nofile";
            type = "soft";
            value = "16777216";
          }
        ];
      };
    };

    services = {
      input-remapper = {
        enable = true;
        # enableUdevRules = true;
      };
    };

    systemd = {
      extraConfig = ''
        DefaultLimitNOFILE=1048576
      '';
      tmpfiles = {
        rules = [
          # https://wiki.archlinux.org/title/Gaming#Make_the_changes_permanent
          "w /proc/sys/vm/compaction_proactiveness - - - - 0"
          "w /proc/sys/vm/watermark_boost_factor - - - - 1"
          "w /proc/sys/vm/min_free_kbytes - - - - 1048576"
          "w /proc/sys/vm/watermark_scale_factor - - - - 500"
          "w /sys/kernel/mm/lru_gen/enabled - - - - 5"
          "w /proc/sys/vm/zone_reclaim_mode - - - - 0"
          "w /proc/sys/vm/page_lock_unfairness - - - - 1"
          "w /proc/sys/kernel/sched_child_runs_first - - - - 0"
          "w /proc/sys/kernel/sched_autogroup_enabled - - - - 1"
          "w /proc/sys/kernel/sched_cfs_bandwidth_slice_us - - - - 3000"
          "w /sys/kernel/debug/sched/base_slice_ns  - - - - 3000000"
          "w /sys/kernel/debug/sched/migration_cost_ns - - - - 500000"
          "w /sys/kernel/debug/sched/nr_migrate - - - - 8"
        ];
      };
    };

    home-manager.users.${username} =
      {
        inputs,
        config,
        ...
      }:
      {
        # imports = [
        #   ../apps/ludusavi
        # ];
        home.file = {
          desktop-entry-mangohud =
            let
              configFile = pkgs.fetchurl {
                url = "https://raw.githubusercontent.com/flightlessmango/MangoHud/master/data/MangoHud.conf";
                hash = "sha256-hAZePm8o5/55IlSghWKhBJBi63JtKJQzGYDUn69u1oM=";
              };
            in
            {
              enable = true;
              text = ''
                [Desktop Entry]
                Comment=Create a new MangoHud config from template
                Icon=text-x-makefile
                Name=MangoHud Config...
                Type=Link
                URL[$e]=file:${configFile}
              '';
              target = "${config.xdg.dataHome}/templates/mangohud.desktop";
            };
        };
        home.sessionVariables = {
          # https://gitlab.com/OpenMW/openmw/-/issues/6185
          OSG_VERTEX_BUFFER_HINT = "VERTEX_BUFFER_OBJECT";
        };
        services = {
          flatpak = {
            overrides = {
              "dev.opengoal.OpenGOAL" = {
                Context = {
                  filesystems = [ "${config.home.homeDirectory}/Games/opengoal" ];
                };
                Environment = {
                  PULSE_SINK = "Game";
                };
              };
              "io.github.noxworld_dev.OpenNox" = {
                Context = {
                  filesystems = [
                    "!home"
                    "${config.home.homeDirectory}/Games/nox"
                  ];
                };
                Environment = {
                  PULSE_SINK = "Game";
                };
              };
              "io.openrct2.OpenRCT2" = {
                Context = {
                  filesystems = [ "${config.home.homeDirectory}/Games/rollercoaster-tycoon" ];
                };
                Environment = {
                  PULSE_SINK = "Game";
                };
              };
              "net.shadps4.shadPS4" = {
                Context = {
                  filesystems = [
                    "${config.home.homeDirectory}/Games"
                    "xdg-data/games"
                    "!home"
                  ];
                };
                Environment = {
                  PULSE_SINK = "Game";
                };
              };
              "org.ryujinx.Ryujinx" = {
                Context = {
                  filesystems = [
                    "${config.home.homeDirectory}/Games"
                    "/mnt/crusader/Games/Rom/Other/Switch"
                    "xdg-data/games"
                    "!home"
                  ];
                };
                Environment = {
                  PULSE_SINK = "Game";
                };
              };
            };
            packages = [
              "com.github.optyfr.JRomManager"
              "org.freedesktop.Platform.VulkanLayer.MangoHud/x86_64/24.08"
              "org.freedesktop.Platform.VulkanLayer.gamescope/x86_64/24.08"
            ];
          };
        };
      };
  };
}
