{
  pkgs,
  config,
  lib,
  ...
}: let
  service = "minecraft_modded";
  cfg = config.gameservers.${service};
  sec = config.sops.secrets;
  servers = {
    cobblemon = {
      data_dir = "/var/lib/gameservers/minecraft_modded/cobblemon";
      start_file = "start.sh";
    };
  };
in {
  options.gameservers.${service} = {
    enable = lib.mkEnableOption "enables ${service}";
    url = lib.mkOption {
      type = lib.types.str;
      default = "mc.recoil.pro";
      description = "set domain for ${service}";
    };
    data_dir = lib.mkOption {
      type = lib.types.str;
      default = "/var/lib/gameservers/${service}";
      description = "set data directory for ${service}";
    };
    ids = lib.mkOption {
      type = lib.types.int;
      default = 25565;
      description = "set uid and pid of ${service} user (matches port by default)";
    };
    backup = lib.mkOption {
      type = lib.types.bool;
      default = false;
      description = "enable backups for ${service}";
    };
    motd = lib.mkOption {
      type = lib.types.nullOr lib.types.str;
      default = "velocity";
    };
    backup_repo = lib.mkOption {
      type = lib.types.path;
      default = "/holocron/archives/gameservers/minecraft/modded";
      description = "path to take hourly backups to with borg!";
    };
  };

  config = lib.mkIf cfg.enable {

    # declare ${service} user
    users.users.minecraft = lib.mkDefault {
      description = "minecraft server user";
      uid = lib.mkForce cfg.ids;
      isSystemUser = true;
      shell = pkgs.bash;
      group = "minecraft";
      extraGroups = [];
    };

    systemd.tmpfiles.rules =
      lib.attrsets.mapAttrsToList (
        name: cfg: "d ${cfg.data_dir} 0770 minecraft minecraft -"
      )
      servers;

    # Create a systemd service per server running in tmux
    systemd.services =
      lib.attrsets.mapAttrs (name: srv: {
        description = "minecraft_recpro: ${name}";
        after = ["network.target"];
        wants = ["network.target"];
        serviceConfig = {
          User = "minecraft";
          Group = "minecraft";
          WorkingDirectory = srv.data_dir;
          UMask = "0007";
          ExecStart = "${pkgs.openjdk21}/bin/java -Xms4G -Xmx12G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true @libraries/net/neoforged/neoforge/21.1.211/unix_args.txt";
          #ExecStart = "${srv.data_dir}/${srv.start_file}";
          Restart = "on-failure";
          KillMode = "process";
        };
        wantedBy = ["multi-user.target"];
      })
      servers;

    environment.systemPackages = with pkgs; [openjdk21 mcrcon];

    #    services.mysql = {
    #      enable = true;
    #      package = pkgs.mariadb;
    #      ensureDatabases = ["minecraft_recpro_db"];
    #      ensureUsers = [
    #        {
    #          name = "minecraft";
    #          ensurePermissions = {"minecraft_recpro_db.*" = "ALL PRIVILEGES";};
    #        }
    #      ];
    #      initialScript = pkgs.writeText "minecraft_recpro-init.sql" ''
    #        CREATE USER IF NOT EXISTS 'minecraft_recpro'@'localhost' IDENTIFIED BY 'IKNOWTHISISBADIJUSTNEEDTHISTOWORKRNPLS';
    #        GRANT ALL PRIVILEGES ON minecraft_recpro_db.* TO 'minecraft_recpro'@'localhost';
    #        FLUSH PRIVILEGES;
    #      '';
    #    };

    # open firewall
    networking.firewall.allowedTCPPorts = [25778];

    #    sops.secrets = {
    #      "velocity_forwarding" = {
    #        owner = "minecraft";
    #        group = "minecraft";
    #        path = "/var/lib/gameservers/minecraft_recpro/velocity/forwarding.secret";
    #        mode = "0400";
    #      };
    #      "minecraft_recpro_db_passwd" = {
    #        owner = "mysql";
    #        group = "mysql";
    #      };
    #    };

    # backups minecraft_recpro with borg!
    services.borgbackup.jobs.${service} = {
      archiveBaseName = service;
      repo = cfg.backup_repo;
      paths = lib.flatten (
        lib.attrValues (
          lib.mapAttrs (_: srv:
            [srv.data_dir]
            ++ (
              if builtins.hasAttr "db_dump" srv
              then [srv.db_dump]
              else []
            ))
          servers
        )
      );
      compression = "auto,zstd";
      #preHook = "systemctl start mysql-backup.service";
      startAt = "*-*-* *:00:00";
      group = "archives";
      encryption.mode = "repokey-blake2";
      encryption.passCommand = "cat ${config.sops.secrets."borg_passwd".path}";
      extraArgs = ["--verbose" "--show-rc" "--umask" "0007"];
      extraCreateArgs = ["--list" "--stats" "--filter" "AME"];
      prune.keep = {
        within = "1d"; # Keep all archives from the last day
        hourly = 24;
        daily = 7;
        weekly = 12;
        monthly = -1; # Keep at least one archive for each month
      };
    };
  };
}
