nixos-config/modules/minecraft/server.nix

2578 lines
92 KiB
Nix

{
system,
config,
lib,
options,
pkgs,
...
}:
with lib; let
inherit (pkgs) papermc;
cfg = config.services.minecraft;
opt = options.services.minecraft;
serverProperties = pkgs.writeText "server.properties" ''
${generators.toKeyValue {} cfg.properties.extraConfig}
'';
whitelistJson = pkgs.writeText "whitelist.json" ''
${builtins.toJSON cfg.whitelist}
'';
bukkitYaml = pkgs.writeText "bukkit.yml" ''
${generators.toYAML {} cfg.bukkit-yml}
'';
spigotYaml = pkgs.writeText "spigot.yml" ''
${generators.toYAML {} cfg.spigot-yml}
'';
paperYaml = pkgs.writeText "paper.yml" ''
${generators.toYAML {} cfg.paper-yml}
'';
in {
options.services.minecraft = {
enable = mkOption {
default = false;
type = types.bool;
description = "Enable minecraft server";
};
stateDir = mkOption {
default = "/var/lib/minecraft";
type = types.str;
description = "Path to the minecraft server state directory";
};
properties = {
allow-flight = mkOption {
default = false;
type = types.bool;
description = "Allow flight";
};
allow-nether = mkOption {
default = true;
type = types.bool;
description = "Allow nether";
};
broadcast-console-to-ops = mkOption {
default = true;
type = types.bool;
description = "Broadcast console to ops";
};
broadcast-rcon-to-ops = mkOption {
default = true;
type = types.bool;
description = "Broadcast rcon to ops";
};
difficulty = mkOption {
default = "normal";
type = types.enum ["peacful" "easy" "normal" "hard"];
description = "Difficulty";
};
enable-command-block = mkOption {
default = false;
type = types.bool;
description = "Enable command block";
};
enable-jmx-monitoring = mkOption {
default = false;
type = types.bool;
description = "Enable JMX monitoring";
};
enable-rcon = mkOption {
default = false;
type = types.bool;
description = "Enable rcon";
};
sync-chunk-writes = mkOption {
default = true;
type = types.bool;
description = "Sync chunk writes";
};
enable-status = mkOption {
default = true;
type = types.bool;
description = "Enable status";
};
enable-query = mkOption {
default = false;
type = types.bool;
description = "Enable query";
};
entity-broadcast-range-percentage = mkOption {
default = 100;
type = types.ints.between 10 1000;
description = "Entity broadcast range percentage";
};
force-gamemode = mkOption {
default = false;
type = types.bool;
description = "Force gamemode";
};
function-permission-level = mkOption {
default = 2;
type = types.ints.between 1 4;
description = "Function permission level";
};
gamemode = mkOption {
default = "survival";
type = types.enum ["survival" "creative" "adventure" "spectator"];
description = "Gamemode";
};
generate-structures = mkOption {
default = true;
type = types.bool;
description = "Generate structures";
};
generator-settings = mkOption {
default = "";
type = types.oneOf [types.str (types.attrsOf types.anything)];
description = "Generator settings";
apply = val:
if (builtins.isString val)
then val
else builtins.toJSON val;
};
hardcore = mkOption {
default = false;
type = types.bool;
description = "Hardcore";
};
level-name = mkOption {
default = "world";
type = types.str;
description = "Level name";
};
level-seed = mkOption {
default = "";
type = types.str;
description = "Level seed";
};
level-type = mkOption {
default = "default";
type = types.enum ["default" "flat" "largeBiomes" "amplified"];
description = "Level type";
};
max-players = mkOption {
default = 20;
type = types.ints.unsigned;
description = "Max players";
};
max-tick-time = mkOption {
default = 60000;
type = types.int;
description = "Max tick time";
};
world-size = mkOption {
default = 29999984;
type = types.ints.between 1 29999984;
description = "World size";
};
motd = mkOption {
default = "A Minecraft server";
type = types.str;
description = "Message of the day";
};
network-compression-threshold = mkOption {
default = 256;
type = types.int;
description = "Network compression threshold";
};
online-mode = mkOption {
default = true;
type = types.bool;
description = "Online mode";
};
permission-level = mkOption {
default = 4;
type = types.ints.between 0 4;
description = "Permission level";
};
player-idle-timeout = mkOption {
default = 0;
type = types.ints.unsigned;
description = "Player idle timeout";
};
prevent-proxy-connections = mkOption {
default = false;
type = types.bool;
description = "Prevent proxy connections";
};
pvp = mkOption {
default = true;
type = types.bool;
description = "PvP";
};
query-port = mkOption {
default = 25565;
type = types.port;
description = "Query port";
};
rate-limit = mkOption {
default = 0;
type = types.ints.unsigned;
description = "Rate limit";
};
rcon-password-file = mkOption {
default = null;
type = types.nullOr types.str;
description = "Rcon password file";
};
rcon-port = mkOption {
default = 25575;
type = types.port;
description = "Rcon port";
};
resource-pack = mkOption {
default = "";
type = types.str;
description = "Resource pack";
};
resource-pack-prompt = mkOption {
default = "";
type = types.str;
description = "Resource pack prompt";
};
resource-pack-sha1 = mkOption {
default = "";
type = types.str;
description = "Resource pack sha1";
};
require-resource-pack = mkOption {
default = false;
type = types.bool;
description = "Require resource pack";
};
server-ip = mkOption {
default = "";
type = types.str;
description = "Server ip";
};
server-port = mkOption {
default = 25565;
type = types.port;
description = "Server port";
};
simulation-distance = mkOption {
default = 10;
type = types.ints.between 3 32;
description = "Simulation distance";
};
snooper-enabled = mkOption {
default = true;
type = types.bool;
description = "Snooper enabled";
};
spawn-animals = mkOption {
default = true;
type = types.bool;
description = "Enable animals";
};
spawn-monsters = mkOption {
default = true;
type = types.bool;
description = "Enable monsters";
};
spawn-npcs = mkOption {
default = true;
type = types.bool;
description = "Enable npcs";
};
spawn-protection = mkOption {
default = 16;
type = types.ints.between 0 256;
description = "Spawn protection";
};
use-native-transport = mkOption {
default = true;
type = types.bool;
description = "Use native transport";
};
view-distance = mkOption {
default = 10;
type = types.ints.between 3 32;
description = "View distance";
};
white-list = mkOption {
default = cfg.whitelist != [];
type = types.bool;
description = "White list";
};
enforce-whitelist = mkOption {
default = false;
type = types.bool;
description = "Enforce whitelist";
};
extraConfig = mkOption {
default = {};
type = types.attrsOf types.anything;
description = "Extra configuration to be added to the minecraft server properties file";
};
};
bukkit-yml = {
settings = {
allow-end = mkOption {
default = true;
type = types.bool;
description = "Allow end";
};
warn-on-overload = mkOption {
default = true;
type = types.bool;
description = "Warn on overload";
};
permissions-file = mkOption {
default = "permissions.yml";
type = types.str;
description = "Permissions file";
};
update-folder = mkOption {
default = "update";
type = types.str;
description = "Update folder";
};
ping-packet-limit = mkOption {
default = 100;
type = types.ints.between 0 1000;
description = "Ping packet limit";
};
use-exact-login-location = mkOption {
default = false;
type = types.bool;
description = "Use exact login location";
};
world-container = mkOption {
default = "world";
type = types.str;
description = "World container";
};
plugin-profiling = mkOption {
default = false;
type = types.bool;
description = "Plugin profiling";
};
connection-throttle = mkOption {
default = 0;
type = types.ints.unsigned;
description = "Connection throttle";
};
query-plugins = mkOption {
default = true;
type = types.bool;
description = "Query plugins";
};
deprecated-verbose = mkOption {
default = "default";
type = types.enum [true false "default"];
description = "Deprecated verbose";
};
shutdown-message = mkOption {
default = "Server closed";
type = types.str;
description = "Shutdown message";
};
};
spawn-limits = {
monsters = mkOption {
default = 70;
type = types.ints.unsigned;
description = "Max monsters";
};
animals = mkOption {
default = 15;
type = types.ints.unsigned;
description = "Max animals";
};
water-animals = mkOption {
default = 5;
type = types.ints.unsigned;
description = "Max water animals";
};
ambient = mkOption {
default = 15;
type = types.ints.unsigned;
description = "Max ambient";
};
};
chunk-gc = {
period-in-ticks = mkOption {
default = 600;
type = types.ints.unsigned;
description = "Period in ticks";
};
load-threshold = mkOption {
default = 0;
type = types.ints.unsigned;
description = "Load threshold";
};
};
ticks-per = {
animal-spawns = mkOption {
default = 400;
type = types.ints.unsigned;
description = "Animal spawns";
};
monster-spawns = mkOption {
default = 1;
type = types.ints.unsigned;
description = "Monster spawns";
};
autosave = mkOption {
default = 6000;
type = types.ints.unsigned;
description = "Autosave";
};
};
};
spigot-yml = {
settings = {
debug = mkOption {
default = false;
type = types.bool;
description = "Debug";
};
bungeecord = mkOption {
default = false;
type = types.bool;
description = "Bungeecord";
};
timout-time = mkOption {
default = 60;
type = types.ints.unsigned;
description = "Timeout time";
};
restart-on-crash = mkOption {
default = true;
type = types.bool;
description = "Restart on crash";
};
restart-script = mkOption {
default = "./start.sh";
type = types.str;
description = "Restart script";
};
netty-threads = mkOption {
default = 4;
type = types.ints.unsigned;
description = "Netty threads";
};
log-villager-deaths = mkOption {
default = false;
type = types.bool;
description = "Log villager deaths";
};
log-named-deaths = mkOption {
default = false;
type = types.bool;
description = "Log named deaths";
};
sample-count = mkOption {
default = 12;
type = types.ints.unsigned;
description = "Sample count";
};
player-shuffle = mkOption {
default = 0;
type = types.ints.unsigned;
description = "Player shuffle";
};
user-cache-size = mkOption {
default = 1000;
type = types.ints.unsigned;
description = "User cache size";
};
save-user-cache-on-stop-only = mkOption {
default = false;
type = types.bool;
description = "Save user cache on stop only";
};
moved-wrongly-threshold = mkOption {
default = 0.0625;
type = types.float;
description = "Moved wrongly threshold";
};
moved-too-quickly-multiplier = mkOption {
default = 10.0;
type = types.float;
description = "Moved too quickly multiplier";
};
};
messages = {
whitelist = mkOption {
default = "You are not whitelisted on this server!";
type = types.str;
description = "Whitelist message";
};
unknown-command = mkOption {
default = "Unknown command. Type \"/help\" for help.";
type = types.str;
description = "Unknown command message";
};
server-full = mkOption {
default = "The server is full!";
type = types.str;
description = "Server full message";
};
outdated-client = mkOption {
default = "Outdated client! Please use {0}";
type = types.str;
description = "Outdated client message";
};
outdated-server = mkOption {
default = "Outdated server! I'm still on {0}";
type = types.str;
description = "Outdated server message";
};
restart = mkOption {
default = "Server is restarting";
type = types.str;
description = "Restart message";
};
};
advancements = {
disable-saving = mkOption {
default = false;
type = types.bool;
description = "Disable saving";
};
disabled = mkOption {
default = [];
type = types.listOf types.str;
description = "Disabled Advancements";
};
};
config-version = mkOption {
default = 12;
type = types.ints.unsigned;
description = "Config version";
};
stats = {
disable-saving = mkOption {
default = false;
type = types.bool;
description = "Disable saving";
};
};
commands = {
replace-commands = mkOption {
default = ["setblock" "summon" "testforblock" "tellraw"];
type = types.listOf types.str;
description = "Replace commands";
};
spam-exclusions = mkOption {
default = ["/skill"];
type = types.listOf types.str;
description = "Spam exclusions";
};
silent-commandblock-console = mkOption {
default = false;
type = types.bool;
description = "Silent commandblock console";
};
log = mkOption {
default = true;
type = types.bool;
description = "Log";
};
tab-complete = mkOption {
default = 0;
type = types.int;
description = "Tab complete";
};
send-namespaced = mkOption {
default = true;
type = types.bool;
description = "Send namespaced";
};
};
players = {
disable-saving = mkOption {
default = false;
type = types.bool;
description = "Disable saving";
};
};
world-settings = mkOption {
default = {};
type = types.attrsOf (types.submodule {
options = {
below-zero-generation-in-existing-chunks = mkOption {
default = true;
type = types.bool;
description = "Below zero generation in existing chunks";
};
verbose = mkOption {
default = false;
type = types.bool;
description = "Verbose";
};
enable-zombie-pigmen-portal-spawns = mkOption {
default = true;
type = types.bool;
description = "Enable zombie pigmen portal spawns";
};
merge-radius.item = mkOption {
default = 2.5;
type = types.float;
description = "Merge radius.item";
};
merge-radius.exp = mkOption {
default = 3.0;
type = types.float;
description = "Merge radius.exp";
};
item-despawn-rate = mkOption {
default = 3000;
type = types.int;
description = "Item despawn rate";
};
view-distance = mkOption {
default = "default";
type = type.oneOf [types.int types.str];
description = "View distance";
};
simulation-distance = mkOption {
default = "default";
type = type.oneOf [types.int types.str];
description = "Simulation distance";
};
thunder-chance = mkOption {
default = 100000;
type = types.int;
description = "Thunder chance";
};
wither-spawn-sound-radius = mkOption {
default = 0;
type = types.int;
description = "Wither spawn sound radius";
};
arrow-despawn-rate = mkOption {
default = 1200;
type = types.int;
description = "Arrow despawn rate";
};
trident-despawn-rate = mkOption {
default = 1200;
type = types.int;
description = "Trident despawn rate";
};
hanging-tick-frequency = mkOption {
default = 100;
type = types.int;
description = "Hanging tick frequency";
};
zombie-aggressive-towards-villager = mkOption {
default = true;
type = types.bool;
description = "Zombie aggressive towards villager";
};
nerf-spawner-mobs = mkOption {
default = false;
type = types.bool;
description = "Nerf spawner mobs";
};
mob-spawn-range = mkOption {
default = 8;
type = types.int;
description = "Mob spawn range";
};
end-portal-sound-radius = mkOption {
default = 0;
type = types.int;
description = "End portal sound radius";
};
entity-activation-range = {
animals = mkOption {
default = 32;
type = types.int;
description = "Entity activation range.animals";
};
monsters = mkOption {
default = 32;
type = types.int;
description = "Entity activation range.monsters";
};
raiders = mkOption {
default = 48;
type = types.int;
description = "Entity activation range.raiders";
};
misc = mkOption {
default = 16;
type = types.int;
description = "Entity activation range.misc";
};
water = mkOption {
default = 16;
type = types.int;
description = "Entity activation range.water";
};
villagers = mkOption {
default = 32;
type = types.int;
description = "Entity activation range.villagers";
};
flying-monsters = mkOption {
default = 32;
type = types.int;
description = "Entity activation range.flying-monsters";
};
wake-up-inactive = {
animals-max-per-tick = mkOption {
default = 4;
type = types.int;
description = "Entity activation range.wake-up-inactive.animals-max-per-tick";
};
animals-every = mkOption {
default = 1200;
type = types.int;
description = "Entity activation range.wake-up-inactive.animals-every";
};
animals-for = mkOption {
default = 100;
type = types.int;
description = "Entity activation range.wake-up-inactive.animals-for";
};
monsters-max-per-tick = mkOption {
default = 8;
type = types.int;
description = "Entity activation range.wake-up-inactive.monsters-max-per-tick";
};
monsters-every = mkOption {
default = 400;
type = types.int;
description = "Entity activation range.wake-up-inactive.monsters-every";
};
monsters-for = mkOption {
default = 100;
type = types.int;
description = "Entity activation range.wake-up-inactive.monsters-for";
};
villagers-max-per-tick = mkOption {
default = 4;
type = types.int;
description = "Entity activation range.wake-up-inactive.villagers-max-per-tick";
};
villagers-every = mkOption {
default = 600;
type = types.int;
description = "Entity activation range.wake-up-inactive.villagers-every";
};
villagers-for = mkOption {
default = 100;
type = types.int;
description = "Entity activation range.wake-up-inactive.villagers-for";
};
flying-monsters-max-per-tick = mkOption {
default = 8;
type = types.int;
description = "Entity activation range.wake-up-inactive.flying-monsters-max-per-tick";
};
flying-monsters-every = mkOption {
default = 200;
type = types.int;
description = "Entity activation range.wake-up-inactive.flying-monsters-every";
};
flying-monsters-for = mkOption {
default = 100;
type = types.int;
description = "Entity activation range.wake-up-inactive.flying-monsters-for";
};
};
villagers-work-immunity-after = mkOption {
default = 100;
type = types.int;
description = "Entity activation range.villagers-work-immunity-after";
};
villagers-work-immunity-for = mkOption {
default = 20;
type = types.int;
description = "Entity activation range.villagers-work-immunity-for";
};
villagers-active-for-panic = mkOption {
default = true;
type = types.bool;
description = "Entity activation range.villagers-active-for-panic";
};
tick-inactive-villagers = mkOption {
default = true;
type = types.bool;
description = "Entity activation range.tick-inactive-villagers";
};
ignore-spectators = mkOption {
default = false;
type = types.bool;
description = "Entity activation range.ignore-spectators";
};
};
entity-tracking-range = {
players = mkOption {
default = 48;
type = types.int;
description = "Entity tracking range.players";
};
animals = mkOption {
default = 48;
type = types.int;
description = "Entity tracking range.animals";
};
monsters = mkOption {
default = 48;
type = types.int;
description = "Entity tracking range.monsters";
};
misc = mkOption {
default = 32;
type = types.int;
description = "Entity tracking range.misc";
};
other = mkOption {
default = 64;
type = types.int;
description = "Entity tracking range.other";
};
};
ticks-per.hopper-transfer = mkOption {
default = 8;
type = types.int;
description = "Ticks per.hopper-transfer";
};
ticks-per.hopper-check = mkOption {
default = 1;
type = types.int;
description = "Ticks per.hopper-check";
};
hopper-amount = mkOption {
default = 1;
type = types.int;
description = "Hopper amount";
};
dragon-death-sound-radius = mkOption {
default = 0;
type = types.int;
description = "Dragon death sound radius";
};
seed-village = mkOption {
default = 10387312;
type = types.int;
description = "Seed village";
};
seed-desert = mkOption {
default = 14357617;
type = types.int;
description = "Seed desert";
};
seed-igloo = mkOption {
default = 14357618;
type = types.int;
description = "Seed igloo";
};
seed-jungle = mkOption {
default = 14357619;
type = types.int;
description = "Seed jungle";
};
seed-swamp = mkOption {
default = 14357620;
type = types.int;
description = "Seed swamp";
};
seed-monument = mkOption {
default = 10387313;
type = types.int;
description = "Seed monument";
};
seed-shipwreck = mkOption {
default = 165745295;
type = types.int;
description = "Seed shipwreck";
};
seed-ocean = mkOption {
default = 14357621;
type = types.int;
description = "Seed ocean";
};
seed-outpost = mkOption {
default = 165745296;
type = types.int;
description = "Seed outpost";
};
seed-endcity = mkOption {
default = 10387313;
type = types.int;
description = "Seed endcity";
};
seed-slime = mkOption {
default = 987234911;
type = types.int;
description = "Seed slime";
};
seed-bastion = mkOption {
default = 30084232;
type = types.int;
description = "Seed bastion";
};
seed-fortress = mkOption {
default = 30084232;
type = types.int;
description = "Seed fortress";
};
seed-mansion = mkOption {
default = 10387319;
type = types.int;
description = "Seed mansion";
};
seed-fossil = mkOption {
default = 14357921;
type = types.int;
description = "Seed fossil";
};
seed-portal = mkOption {
default = 34222645;
type = types.int;
description = "Seed portal";
};
seed-stronghold = mkOption {
default = "default";
type = types.oneOf [types.int types.str];
description = "Seed stronghold";
};
hunger = {
jump-walk-exhaustion = mkOption {
default = 0.05;
type = types.float;
description = "Hunger.jump-walk-exhaustion";
};
jump-sprint-exhaustion = mkOption {
default = 0.20;
type = types.float;
description = "Hunger.jump-sprint-exhaustion";
};
combat-exhaustion = mkOption {
default = 0.1;
type = types.float;
description = "Hunger.combat-exhaustion";
};
regen-exhaustion = mkOption {
default = 6.0;
type = types.float;
description = "Hunger.regen-exhaustion";
};
swim-multiplier = mkOption {
default = 0.01;
type = types.float;
description = "Hunger.swim-multiplier";
};
sprint-multiplier = mkOption {
default = 0.1;
type = types.float;
description = "Hunger.sprint-multiplier";
};
other-multiplier = mkOption {
default = 0.0;
type = types.float;
description = "Hunger.other-multiplier";
};
};
max-tnt-per-tick = mkOption {
default = 100;
type = types.int;
description = "Max tnt per tick";
};
max-tick-time = {
tile = mkOption {
default = 50;
type = types.int;
description = "Max tick time.tile";
};
entity = mkOption {
default = 50;
type = types.int;
description = "Max tick time.entity";
};
};
growth = {
cactus-modifier = mkOption {
default = 100;
type = types.int;
description = "Growth.cactus-modifier";
};
cane-modifier = mkOption {
default = 100;
type = types.int;
description = "Growth.cane-modifier";
};
melon-modifier = mkOption {
default = 100;
type = types.int;
description = "Growth.melon-modifier";
};
mushroom-modifier = mkOption {
default = 100;
type = types.int;
description = "Growth.mushroom-modifier";
};
pumpkin-modifier = mkOption {
default = 100;
type = types.int;
description = "Growth.pumpkin-modifier";
};
sapling-modifier = mkOption {
default = 100;
type = types.int;
description = "Growth.sapling-modifier";
};
beetroot-modifier = mkOption {
default = 100;
type = types.int;
description = "Growth.beetroot-modifier";
};
carrot-modifier = mkOption {
default = 100;
type = types.int;
description = "Growth.carrot-modifier";
};
potato-modifier = mkOption {
default = 100;
type = types.int;
description = "Growth.potato-modifier";
};
wheat-modifier = mkOption {
default = 100;
type = types.int;
description = "Growth.wheat-modifier";
};
netherwart-modifier = mkOption {
default = 100;
type = types.int;
description = "Growth.netherwart-modifier";
};
vine-modifier = mkOption {
default = 100;
type = types.int;
description = "Growth.vine-modifier";
};
cocoa-modifier = mkOption {
default = 100;
type = types.int;
description = "Growth.cocoa-modifier";
};
bamboo-modifier = mkOption {
default = 100;
type = types.int;
description = "Growth.bamboo-modifier";
};
sweetberry-modifier = mkOption {
default = 100;
type = types.int;
description = "Growth.sweetberry-modifier";
};
kelp-modifier = mkOption {
default = 100;
type = types.int;
description = "Growth.kelp-modifier";
};
twistingvines-modifier = mkOption {
default = 100;
type = types.int;
description = "Growth.twistingvines-modifier";
};
weepingvines-modifier = mkOption {
default = 100;
type = types.int;
description = "Growth.weepingvines-modifier";
};
cavevines-modifier = mkOption {
default = 100;
type = types.int;
description = "Growth.cavevines-modifier";
};
glowberry-modifier = mkOption {
default = 100;
type = types.int;
description = "Growth.glowberry-modifier";
};
};
};
});
};
};
paper-yml = {
verbose = mkOption {
default = false;
type = types.bool;
description = "Verbose";
};
messages = {
kick = {
authentication-servers-shut-down = mkOption {
default = "";
type = types.str;
description = "Kick.authentication-servers-shut-down";
};
connection-throttle = mkOption {
default = "Connection throttled! Please wait before reconnecting.";
type = types.str;
description = "Kick.connection-throttle";
};
flying-player = mkOption {
default = "Flying is not enabled on this server.";
type = types.str;
description = "Kick.flying-player";
};
flying-vehicle = mkOption {
default = "Flying is not enabled on this server.";
type = types.str;
description = "Kick.flying-vehicle";
};
};
no-permission = mkOption {
default = "&cI'm sorry, but you do not have permission to perform this command.\nPlease contact the server administrators if you believe this is in error.";
type = types.str;
description = "No-permission";
};
};
timings = {
enabled = mkOption {
default = true;
type = types.bool;
description = "Enabled";
};
verbose = mkOption {
default = true;
type = types.bool;
description = "Verbose";
};
url = mkOption {
default = "https://timings.aikar.co/";
type = types.str;
description = "Url";
};
server-name-privacy = mkOption {
default = false;
type = types.bool;
description = "Server-name-privacy";
};
hidden-config-entries = mkOption {
default = ["database" "settings.bungeecord-addresses" "setitngs.velocity-support.secret"];
type = types.listOf types.str;
description = "Hidden-config-entries";
};
history-interval = mkOption {
default = 300;
type = types.int;
description = "History-interval";
};
history-length = mkOption {
default = 3600;
type = types.int;
description = "History-length";
};
server-name = mkOption {
default = "Unknown Server";
type = types.str;
description = "Server-name";
};
};
config-version = mkOption {
default = 25;
type = types.int;
description = "Config-version";
};
settings = {
use-display-name-in-quit-message = mkOption {
default = false;
type = types.bool;
description = "Settings.use-display-name-in-quit-message";
};
load-permissions-yml-before-plugins = mkOption {
default = true;
type = types.bool;
description = "Settings.load-permissions-yml-before-plugins";
};
region-file-cache-size = mkOption {
default = 256;
type = types.int;
description = "Settings.region-file-cache-size";
};
enable-player-collisions = mkOption {
default = true;
type = types.bool;
description = "Settings.enable-player-collisions";
};
save-empty-scoreboard-teams = mkOption {
default = false;
type = types.bool;
description = "Settings.save-empty-scoreboard-teams";
};
bungee-online-mode = mkOption {
default = true;
type = types.bool;
description = "Settings.bungee-online-mode";
};
incoming-packet-spam-threshold = mkOption {
default = 300;
type = types.int;
description = "Settings.incoming-packet-spam-threshold";
};
use-alternative-luck-formula = mkOption {
default = false;
type = types.bool;
description = "Settings.use-alternative-luck-formula";
};
velocity-support = {
enabled = mkOption {
default = false;
type = types.bool;
description = "Velocity-support.enabled";
};
online-mode = mkOption {
default = false;
type = types.bool;
description = "Velocity-support.online-mode";
};
secret = mkOption {
default = "";
type = types.str;
description = "Velocity-support.secret";
};
};
console-has-all-permissions = mkOption {
default = false;
type = types.bool;
description = "Settings.console-has-all-permissions";
};
player-auto-save-rate = mkOption {
default = -1;
type = types.int;
description = "Settings.player-auto-save-rate";
};
max-player-auto-save-per-tick = mkOption {
default = -1;
type = types.int;
description = "Settings.max-player-auto-save-per-tick";
};
fix-target-selector-tag-completion = mkOption {
default = true;
type = types.bool;
description = "Settings.fix-target-selector-tag-completion";
};
lag-compensate-block-breaking = mkOption {
default = true;
type = types.bool;
description = "Settings.lag-compensate-block-breaking";
};
send-full-pos-for-hard-colliding-entities = mkOption {
default = true;
type = types.bool;
description = "Settings.send-full-pos-for-hard-colliding-entities";
};
time-command-affects-all-worlds = mkOption {
default = false;
type = types.bool;
description = "Settings.time-command-affects-all-worlds";
};
max-joins-per-tick = mkOption {
default = 3;
type = types.int;
description = "Settings.max-joins-per-tick";
};
track-plugin-scoreboards = mkOption {
default = false;
type = types.bool;
description = "Settings.track-plugin-scoreboards";
};
fix-entity-position-desync = mkOption {
default = true;
type = types.bool;
description = "Settings.fix-entity-position-desync";
};
log-player-ip-addresses = mkOption {
default = true;
type = types.bool;
description = "Settings.log-player-ip-addresses";
};
console = {
enable-brigadier-highlighting = mkOption {
default = false;
type = types.bool;
description = "Console.enable-brigadier-highlighting";
};
enable-brigadier-completion = mkOption {
default = true;
type = types.bool;
description = "Console.enable-brigadier-completion";
};
};
suggest-player-names-when-null-tab-completions = mkOption {
default = true;
type = types.bool;
description = "Settings.suggest-player-names-when-null-tab-completions";
};
watchdog = {
early-warning-every = mkOption {
default = 5000;
type = types.int;
description = "Watchdog.early-warning-every";
};
early-warning-delay = mkOption {
default = 10000;
type = types.int;
description = "Watchdog.early-warning-delay";
};
};
spam-limiter = {
tab-spam-increment = mkOption {
default = 1;
type = types.int;
description = "Spam-limiter.tab-spam-increment";
};
tab-spam-limit = mkOption {
default = 500;
type = types.int;
description = "Spam-limiter.tab-spam-limit";
};
recipe-spam-increment = mkOption {
default = 1;
type = types.int;
description = "Spam-limiter.recipe-spam-increment";
};
recipe-spam-limit = mkOption {
default = 20;
type = types.int;
description = "Spam-limiter.recipe-spam-limit";
};
};
book-size = {
page-max = mkOption {
default = 2560;
type = types.int;
description = "Book-size.page-max";
};
total-multiplier = mkOption {
default = 0.98;
type = types.float;
description = "Book-size.total-multiplier";
};
};
loggers = {
deobfuscate-stacktraces = mkOption {
default = true;
type = types.bool;
description = "Loggers.deobfuscate-stacktraces";
};
};
item-validation = {
display-name = mkOption {
default = 8192;
type = types.int;
description = "Item-validation.display-name";
};
loc-name = mkOption {
default = 8192;
type = types.int;
description = "Item-validation.loc-name";
};
lore-line = mkOption {
default = 8192;
type = types.int;
description = "Item-validation.lore-line";
};
book = {
title = mkOption {
default = 8192;
type = types.int;
description = "Item-validation.book.title";
};
author = mkOption {
default = 8192;
type = types.int;
description = "Item-validation.book.author";
};
page = mkOption {
default = 16384;
type = types.int;
description = "Item-validation.book.page";
};
};
};
chunk-loading = {
min-load-radius = mkOption {
default = 2;
type = types.int;
description = "Chunk-loading.min-load-radius";
};
max-concurrent-sends = mkOption {
default = 2;
type = types.int;
description = "Chunk-loading.max-concurrent-sends";
};
autoconfig-send-distance = mkOption {
default = true;
type = types.bool;
description = "Chunk-loading.autoconfig-send-distance";
};
target-player-chunk-send-rate = mkOption {
default = 100.0;
type = types.float;
description = "Chunk-loading.target-player-chunk-send-rate";
};
global-max-chunk-send-rate = mkOption {
default = -1.0;
type = types.float;
description = "Chunk-loading.global-max-chunk-send-rate";
};
enable-frustum-priority = mkOption {
default = true;
type = types.bool;
description = "Chunk-loading.enable-frustum-priority";
};
global-max-chunk-load-rate = mkOption {
default = -1.0;
type = types.float;
description = "Chunk-loading.global-max-chunk-load-rate";
};
player-max-concurrent-loads = mkOption {
default = 20.0;
type = types.float;
description = "Chunk-loading.player-max-concurrent-loads";
};
global-max-concurrent-loads = mkOption {
default = 500.0;
type = types.float;
description = "Chunk-loading.global-max-concurrent-loads";
};
};
async-chunks = {
threads = mkOption {
default = -1;
type = types.int;
description = "Async-chunks.threads";
};
};
packet-limiter = {
kick-message = mkOption {
default = "&cSent too many packets";
type = types.str;
description = "Packet-limiter.kick-message";
};
limits = {
all = {
interval = mkOption {
default = 7.0;
type = types.float;
description = "Packet-limiter.limits.all.interval";
};
max-packet-rate = mkOption {
default = 500.0;
type = types.float;
description = "Packet-limiter.limits.all.max-packet-rate";
};
};
PacketPlayInAutoRecipe = {
interval = mkOption {
default = 4.0;
type = types.float;
description = "Packet-limiter.limits.PcketPlayInAutoRecipe.interval";
};
max-packet-rate = mkOption {
default = 5.0;
type = types.float;
description = "Packet-limiter.limits.PcketPlayInAutoRecipe.max-packet-rate";
};
action = mkOption {
default = "DROP";
type = types.str;
description = "Packet-limiter.limits.PcketPlayInAutoRecipe.action";
};
};
};
};
};
world-settings = mkOption {
default = {
default = {};
};
type = types.attrsOf (types.submodule {
options = {
water-over-lava-flow-speed = mkOption {
default = 5;
type = types.int;
description = "World-settings.type.options.water-over-lava-flow-speed";
};
grass-spread-tick-rate = mkOption {
default = 1;
type = types.int;
description = "World-settings.type.options.grass-spread-tick-rate";
};
game-mechanics = {
disable-chest-cat-detection = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.game-mechanics.disable-chest-cat-detection";
};
nerf-pigmen-from-nether-portals = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.game-mechanics.nerf-pigmen-from-nether-portals";
};
disable-player-crits = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.game-mechanics.disable-player-crits";
};
disable-sprint-interruption-on-attack = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.game-mechanics.disable-sprint-interruption-on-attack";
};
shield-blocking-delay = mkOption {
default = 5;
type = types.int;
description = "World-settings.type.options.game-mechanics.shield-blocking-delay";
};
disable-end-credits = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.game-mechanics.disable-end-credits";
};
disable-unloaded-chunk-enderpearl-exploit = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.game-mechanics.disable-unloaded-chunk-enderpearl-exploit";
};
disable-relative-projectile-velocity = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.game-mechanics.disable-relative-projectile-velocity";
};
disable-mob-spawner-spawn-egg-transformation = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.game-mechanics.disable-mob-spawner-spawn-egg-transformation";
};
scan-for-legacy-ender-dragon = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.game-mechanics.scan-for-legacy-ender-dragon";
};
fix-curing-zombie-villager-discount-exploit = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.game-mechanics.fix-curing-zombie-villager-discount-exploit";
};
disable-pillager-patrols = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.game-mechanics.disable-pillager-patrols";
};
pillager-patrols = {
spawn-chance = mkOption {
default = 0.2;
type = types.float;
description = "World-settings.type.options.game-mechanics.pillager-patrols.spawn-chance";
};
spawn-delay = {
per-player = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.game-mechanics.pillager-patrols.spawn-delay.per-player";
};
ticks = mkOption {
default = 12000;
type = types.int;
description = "World-settings.type.options.game-mechanics.pillager-patrols.spawn-delay.ticks";
};
};
start = {
per-player = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.game-mechanics.pillager-patrols.start.per-player";
};
day = mkOption {
default = 5;
type = types.int;
description = "World-settings.type.options.game-mechanics.pillager-patrols.start.day";
};
};
};
};
use-faster-eigencraft-redstone = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.use-faster-eigencraft-redstone";
};
nether-ceiling-void-damage-height = mkOption {
default = 0;
type = types.int;
description = "World-settings.type.options.nether-ceiling-void-damage-height";
};
only-players-collide = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.only-players-collide";
};
allow-vehicle-collisions = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.allow-vehicle-collisions";
};
fix-items-merging-through-walls = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.fix-items-merging-through-walls";
};
keep-spawn-loaded = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.keep-spawn-loaded";
};
parrots-are-unaffected-by-player-movement = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.parrots-are-unaffected-by-player-movement";
};
disable-explosion-knockback = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.disable-explosion-knockback";
};
allow-non-player-entities-on-scoreboards = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.allow-non-player-entities-on-scoreboards";
};
portal-search-radius = mkOption {
default = 128;
type = types.int;
description = "World-settings.type.options.portal-search-radius";
};
portal-create-radius = mkOption {
default = 16;
type = types.int;
description = "World-settings.type.options.portal-create-radius";
};
portal-search-vanilla-dimension-scaling = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.portal-search-vanilla-dimension-scaling";
};
anti-xray = {
enabled = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.anti-xray.enabled";
};
engine-mode = mkOption {
default = 1;
type = types.int;
description = "World-settings.type.options.anti-xray.engine-mode";
};
max-block-height = mkOption {
default = 64;
type = types.int;
description = "World-settings.type.options.anti-xray.max-block-height";
};
update-radius = mkOption {
default = 2;
type = types.int;
description = "World-settings.type.options.anti-xray.update-radius";
};
lava-obscures = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.anti-xray.lava-obscures";
};
use-permissions = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.anti-xray.use-permissions";
};
hidden-blocks = mkOption {
default = [
"copper_ore"
"deepslate_copper_ore"
"gold_ore"
"deepslate_gold_ore"
"iron_ore"
"deepslate_iron_ore"
"coal_ore"
"deepslate_coal_ore"
"lapis_ore"
"deepslate_lapis_ore"
"mossy_cobblestone"
"obsidian"
"chest"
"diamond_ore"
"deepslate_diamond_ore"
"redstone_ore"
"deepslate_redstone_ore"
"clay"
"emerald_ore"
"deepslate_emerald_ore"
"ender_chest"
];
type = types.listOf types.str;
description = "World-settings.type.options.anti-xray.hidden-blocks";
};
replacement-blocks = mkOption {
default = ["stone" "oak_planks" "deepslate"];
type = types.listOf types.str;
description = "World-settings.type.options.anti-xray.replacement-blocks";
};
};
armor-stands-do-collision-entity-lookups = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.armor-stands-do-collision-entity-lookups";
};
disable-thunder = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.disable-thunder";
};
skeleton-horse-thunder-spawn-rate = mkOption {
default = 0.01;
type = types.float;
description = "World-settings.type.options.skeleton-horse-thunder-spawn-rate";
};
disable-ice-and-snow = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.disable-ice-and-snow";
};
keep-spawn-loaded-range = mkOption {
default = 10;
type = types.int;
description = "World-settings.type.options.keep-spawn-loaded-range";
};
fix-climbing-bypassing-cramming-rule = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.fix-climbing-bypassing-cramming-rule";
};
container-update-tick-rate = mkOption {
default = 1;
type = types.int;
description = "World-settings.type.options.container-update-tick-rate";
};
fixed-chunk-inhabited-time = mkOption {
default = -1;
type = types.int;
description = "World-settings.type.options.fixed-chunk-inhabited-time";
};
remove-corrupt-tile-entities = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.remove-corrupt-tile-entities";
};
prevent-tnt-from-moving-in-water = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.prevent-tnt-from-moving-in-water";
};
iron-golems-can-spawn-in-air = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.iron-golems-can-spawn-in-air";
};
show-sign-click-command-failure-msgs-to-player = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.show-sign-click-command-failure-msgs-to-player";
};
max-leash-distance = mkOption {
default = 10.0;
type = types.float;
description = "World-settings.type.options.max-leash-distance";
};
armor-stands-tick = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.armor-stand-tick";
};
non-player-arrow-despawn-rate = mkOption {
default = -1;
type = types.int;
description = "World-settings.type.options.non-player-arrow-despawn-rate";
};
creative-arrow-despawn-rate = mkOption {
default = -1;
type = types.int;
description = "World-settings.type.options.create-arrow-despawn-rate";
};
spawner-nerfed-mobs-should-jump = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.spawner-nerfed-mobs-should-jump";
};
entities-target-with-follow-range = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.entities-target-with-follow-range";
};
wateranimal-spawn-height = {
maximum = mkOption {
default = "default";
type = types.oneOf [types.int types.str];
description = "World-settings.type.options.wateranimal-spawn-height.maximum";
};
minimum = mkOption {
default = "default";
type = types.oneOf [types.int types.str];
description = "World-settings.type.options.wateranimal-spawn-height.minimum";
};
};
zombies-target-turtle-eggs = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.zombies-target-turtle-eggs";
};
zombie-villager-infection-chance = mkOption {
default = -1.0;
type = types.float;
description = "World-settings.type.options.zombie-villager-infection-chance";
};
all-chunks-are-slime-chunks = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.all-chunks-are-slime-chunks";
};
mob-spawner-tick-rate = mkOption {
default = 1;
type = types.int;
description = "World-settings.type.options.mob-spawner-tick-rate";
};
per-player-mob-spawns = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.per-player-mob-spawns";
};
light-queue-size = mkOption {
default = 20;
type = types.int;
description = "World-settings.type.options.light-queue-size";
};
auto-save-interval = mkOption {
default = -1;
type = types.int;
description = "World-settings.type.options.auto-save-interval";
};
enable-treasure-maps = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.enable-treasure-maps";
};
treasure-maps-return-already-discovered = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.treasure-maps-return-already-discovered";
};
split-overstacked-loot = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.split-overstacked-loot";
};
delay-chunk-unloads-by = mkOption {
default = 16;
type = types.int;
description = "World-settings.type.options.delay-chunk-unloads-by";
};
disable-teleportation-suffocation-check = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.disable-teleportation-suffocation-check";
};
generator-settings = {
flat-bedrock = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.generator-settings.flat-bedrock";
};
};
piglins-guard-chests = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.piglins-guard-chests";
};
should-remove-dragon = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.should-remove-dragon";
};
max-auto-save-chunks-per-tick = mkOption {
default = 24;
type = types.int;
description = "World-settings.type.options.max-auto-save-chunks-per-tick";
};
baby-zombie-movement-modifier = mkOption {
default = 0.5;
type = types.float;
description = "World-settings.type.options.baby-zombie-movement-modifier";
};
optimize-explosions = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.optimize-explosions";
};
use-vanilla-world-scoreboard-name-coloring = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.use-vanilla-world-scoreboard-name-coloring";
};
prevent-moving-into-unloaded-chunks = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.prevent-moving-into-unloaded-chunks";
};
count-all-mobs-for-spawning = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.count-all-mobs-for-spawning";
};
spawn-limits = {
monster = mkOption {
default = -1;
type = types.int;
description = "World-settings.type.options.spawn-limits.monster";
};
creature = mkOption {
default = -1;
type = types.int;
description = "World-settings.type.options.spawn-limits.creature";
};
ambient = mkOption {
default = -1;
type = types.int;
description = "World-settings.type.options.spawn-limits.ambient";
};
axolotls = mkOption {
default = -1;
type = types.int;
description = "World-settings.type.options.spawn-limits.axolotls";
};
underground_water_creature = mkOption {
default = -1;
type = types.int;
description = "World-settings.type.options.spawn-limits.underground_water_creature";
};
water_creature = mkOption {
default = -1;
type = types.int;
description = "World-settings.type.options.spawn-limits.water_creature";
};
water_ambient = mkOption {
default = -1;
type = types.int;
description = "World-settings.type.options.spawn-limits.water_ambient";
};
};
ender-dragons-death-always-places-dragon-egg = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.ender-dragons-death-always-places-dragon-egg";
};
experience-merge-max-value = mkOption {
default = -1;
type = types.int;
description = "World-settings.type.options.experience-merge-max-value";
};
allow-using-signs-inside-spawn-protection = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.allow-using-signs-inside-spawn-protection";
};
wandering-trader = {
spawn-minute-length = mkOption {
default = 1200;
type = types.int;
description = "World-settings.type.options.wandering-trader.spawn-minute-length";
};
spawn-day-length = mkOption {
default = 24000;
type = types.int;
description = "World-settings.type.options.wandering-trader.spawn-day-length";
};
spawn-chance-failure-increment = mkOption {
default = 25;
type = types.int;
description = "World-settings.type.options.wandering-trader.spawn-chance-failure-increment";
};
spawn-chance-min = mkOption {
default = 25;
type = types.int;
description = "World-settings.type.options.wandering-trader.spawn-chance-min";
};
spawn-chance-max = mkOption {
default = 75;
type = types.int;
description = "World-settings.type.options.wandering-trader.spawn-chance-max";
};
};
door-breaking-difficulty = {
zombie = mkOption {
default = ["HARD"];
type = types.listOf (types.enum ["EASY" "NORMAL" "HARD"]);
};
vindicator = mkOption {
default = ["NORMAL" "HARD"];
type = types.listOf (types.enum ["EASY" "NORMAL" "HARD"]);
};
};
max-growth-height = {
cactus = mkOption {
default = 3;
type = types.int;
description = "World-settings.type.options.max-growth-height.cactus";
};
reeds = mkOption {
default = 3;
type = types.int;
description = "World-settings.type.options.max-growth-height.reeds";
};
bamboo = {
max = mkOption {
default = 16;
type = types.int;
description = "World-settings.type.options.max-growth-height.bamboo.max";
};
min = mkOption {
default = 11;
type = types.int;
description = "World-settings.type.options.max-growth-height.bamboo.min";
};
};
};
fishing-time-range = {
MinimumTicks = mkOption {
default = 100;
type = types.int;
description = "World-settings.type.options.fishing-time-range.MinimumTicks";
};
MaximumTicks = mkOption {
default = 600;
type = types.int;
description = "World-settings.type.options.fishing-time-range.MaximumTicks";
};
};
despawn-ranges = {
monster = {
soft = mkOption {
default = 32;
type = types.int;
description = "World-settings.type.options.despawn-ranges.monster.soft";
};
hard = mkOption {
default = 128;
type = types.int;
description = "World-settings.type.options.despawn-ranges.monster.hard";
};
};
creature = {
soft = mkOption {
default = 32;
type = types.int;
description = "World-settings.type.options.despawn-ranges.monster.soft";
};
hard = mkOption {
default = 128;
type = types.int;
description = "World-settings.type.options.despawn-ranges.monster.hard";
};
};
ambient = {
soft = mkOption {
default = 32;
type = types.int;
description = "World-settings.type.options.despawn-ranges.monster.soft";
};
hard = mkOption {
default = 128;
type = types.int;
description = "World-settings.type.options.despawn-ranges.monster.hard";
};
};
axolotls = {
soft = mkOption {
default = 32;
type = types.int;
description = "World-settings.type.options.despawn-ranges.monster.soft";
};
hard = mkOption {
default = 128;
type = types.int;
description = "World-settings.type.options.despawn-ranges.monster.hard";
};
};
underground_water_creature = {
soft = mkOption {
default = 32;
type = types.int;
description = "World-settings.type.options.despawn-ranges.monster.soft";
};
hard = mkOption {
default = 128;
type = types.int;
description = "World-settings.type.options.despawn-ranges.monster.hard";
};
};
water_creature = {
soft = mkOption {
default = 32;
type = types.int;
description = "World-settings.type.options.despawn-ranges.monster.soft";
};
hard = mkOption {
default = 128;
type = types.int;
description = "World-settings.type.options.despawn-ranges.monster.hard";
};
};
water_ambient = {
soft = mkOption {
default = 32;
type = types.int;
description = "World-settings.type.options.despawn-ranges.monster.soft";
};
hard = mkOption {
default = 64;
type = types.int;
description = "World-settings.type.options.despawn-ranges.monster.hard";
};
};
misc = {
soft = mkOption {
default = 32;
type = types.int;
description = "World-settings.type.options.despawn-ranges.monster.soft";
};
hard = mkOption {
default = 128;
type = types.int;
description = "World-settings.type.options.despawn-ranges.monster.hard";
};
};
};
falling-block-height-nerf = mkOption {
default = 0;
type = types.int;
description = "World-settings.type.options.falling-block-height-nerf";
};
tnt-entity-height-nerf = mkOption {
default = 0;
type = types.int;
description = "World-settings.type.options.tnt-entity-height-nerf";
};
slime-spawn-height = {
swamp-biome = {
maximum = mkOption {
default = 70.0;
type = types.float;
description = "World-settings.type.options.slime-spawn-height.swamp-biome.maximum";
};
minimum = mkOption {
default = 50.0;
type = types.float;
description = "World-settings.type.options.slime-spawn-height.swamp-biome.minimum";
};
};
slime-chunk = {
maximum = mkOption {
default = 40.0;
type = types.float;
description = "World-settings.type.options.slime-spawn-height.slime-chunk.maximum";
};
};
};
frosted-ice = {
enabled = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.frosted-ice.enabled";
};
delay = {
min = mkOption {
default = 20;
type = types.int;
description = "World-settings.type.options.frosted-ice.delay.min";
};
max = mkOption {
default = 40;
type = types.int;
description = "World-settings.type.options.frosted-ice.delay.max";
};
};
};
lootables = {
auto-replenish = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.lootables.auto-replenish";
};
restrict-player-reloot = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.lootables.restrict-player-reloot";
};
reset-seed-on-fill = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.lootables.reset-seed-on-fill";
};
max-refills = mkOption {
default = -1;
type = types.int;
description = "World-settings.type.options.lootables.max-refills";
};
refresh-min = mkOption {
default = "12h";
type = types.str;
description = "World-settings.type.options.lootables.refresh-min";
};
refresh-max = mkOption {
default = "2d";
type = types.str;
description = "World-settings.type.options.lootables.refresh-max";
};
};
filter-nbt-data-from-spawn-eggs-and-related = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.filter-nbt-data-from-spawn-eggs-and-related";
};
max-entity-collisions = mkOption {
default = 8;
type = types.int;
description = "World-settings.type.options.max-entity-collisions";
};
disable-creeper-lingering-effect = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.disable-creeper-lingering-effect";
};
duplicate-uuid-resolver = mkOption {
default = "saferegen";
type = types.str;
description = "World-settings.type.options.duplicate-uuid-resolver";
};
duplicate-uuid-safegen-delete-range = mkOption {
default = 32;
type = types.int;
description = "World-settings.type.options.duplicate-uuid-safegen-delete-range";
};
hopper = {
cooldown-when-full = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.hopper.cooldown-when-full";
};
disable-move-event = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.hopper.disable-move-event";
};
ignore-occluding-blocks = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.hopper.ignore-occluding-blocks";
};
};
mob-effects = {
undead-immune-to-certain-effects = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.mob-effects.undead-immune-to-certain-effects";
};
spiders-immune-to-poison-effect = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.mob-effects.spiders-immune-to-poison-effect";
};
immune-to-wither-effects = {
wither = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.mob-effects.immune-to-wither-effects.wither";
};
wither-skeleton = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.mob-effects.immune-to-wither-effects.wither-skeleton";
};
};
};
update-pathfinding-on-block-update = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.update-pathfinding-on-block-update";
};
phantoms-do-not-spawn-on-creative-players = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.phantoms-do-not-spawn-on-creative-players";
};
phantoms-only-attack-insomniacs = mkOption {
default = true;
type = types.bool;
description = "World-settings.type.options.phantoms-only-attack-insomniacs";
};
mobs-can-always-pick-up-loot = {
zombies = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.mobs-can-always-pick-up-loot.zombies";
};
skeletons = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.mobs-can-always-pick-up-loot.skeletons";
};
};
map-item-frame-cursor-update-interval = mkOption {
default = 10;
type = types.int;
description = "World-settings.type.options.map-item-frame-cursor-update-interval";
};
allow-player-cramming-damage = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.allow-player-cramming-damage";
};
anticheat = {
obfuscation = {
hide-itemmeta = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.anticheat.obfuscation.hide-itemmeta";
};
hide-durability = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.anticheat.obfuscation.hide-durability";
};
};
};
monster-spawn-max-light-level = mkOption {
default = -1;
type = types.int;
description = "World-settings.type.options.monster-spawn-max-light-level";
};
map-item-frame-cursor-limit = mkOption {
default = 128;
type = types.int;
description = "World-settings.type.options.map-item-frame-cursor-limit";
};
feature-seeds = {
generate-random-seeds-for-all = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.feature-seeds.generate-random-seeds-for-all";
};
};
entity-per-chunk-save-limit = {
experience_orb = mkOption {
default = -1;
type = types.int;
description = "World-settings.type.options.entity-per-chunk-save-limit.experience-orb";
};
snowball = mkOption {
default = -1;
type = types.int;
description = "World-settings.type.options.entity-per-chunk-save-limit.snowball";
};
ender_pearl = mkOption {
default = -1;
type = types.int;
description = "World-settings.type.options.entity-per-chunk-save-limit.ender_pearl";
};
arrow = mkOption {
default = -1;
type = types.int;
description = "World-settings.type.options.entity-per-chunk-save-limit.arrow";
};
fireball = mkOption {
default = -1;
type = types.int;
description = "World-settings.type.options.entity-per-chunk-save-limit.fireball";
};
small_fireball = mkOption {
default = -1;
type = types.int;
description = "World-settings.type.options.entity-per-chunk-save-limit.small_fireball";
};
};
alt-item-despawn-rate = {
enabled = mkOption {
default = false;
type = types.bool;
description = "World-settings.type.options.alt-item-despawn-rate.enabled";
};
items = mkOption {
default = {};
type = types.attrsOf types.int;
description = "World-settings.type.options.alt-item-despawn-rate.items";
};
};
tick-rates = {
sensor = {
villager = {
secondarypoisensor = mkOption {
default = 40;
type = types.int;
description = "World-settings.type.options.tick-rates.sensor.villager.secondarypoisensor";
};
};
};
behavior = {
villager = {
validatenearbypoi = mkOption {
default = -1;
type = types.int;
description = "World-settings.type.options.tick-rates.behavior.villager.validatenearbypoi";
};
};
};
};
};
});
};
};
whitelist = mkOption {
default = [];
type = types.listOf (types.submodule {
options = {
uuid = mkOption {
type = types.str;
description = "UUID of the whitelist entry";
};
name = mkOption {
type = types.str;
description = "Name of the whitelist entry";
};
};
});
};
plugins = mkOption {
default = [];
type = types.listOf (types.submodule {
options = {
package = mkOption {
type = types.package;
description = "Package name of the plugin";
};
startScript = mkOption {
type = types.nullOr (types.oneOf [types.str types.package]);
description = "Start script of the plugin";
};
};
});
description = "List of plugins to load";
};
};
config = mkIf cfg.enable {
services.minecraft.properties.extraConfig = with cfg.properties;
lib.mkDefault {
inherit allow-flight allow-nether broadcast-console-to-ops broadcast-rcon-to-ops;
inherit difficulty enable-command-block enable-jmx-monitoring enable-rcon sync-chunk-writes;
inherit enable-status enable-query entity-broadcast-range-percentage force-gamemode;
inherit function-permission-level gamemode generate-structures generator-settings hardcore;
inherit level-name level-seed level-type max-players max-tick-time motd;
inherit network-compression-threshold online-mode permission-level player-idle-timeout;
inherit prevent-proxy-connections pvp rate-limit resource-pack resource-pack-prompt;
inherit resource-pack-sha1 require-resource-pack server-ip server-port;
inherit simulation-distance snooper-enabled spawn-animals spawn-monsters spawn-npcs;
inherit spawn-protection use-native-transport view-distance white-list enforce-whitelist;
"query.port" = query-port;
"rcon.port" = rcon-port;
};
systemd.services.minecraft = {
description = "Minecraft Server";
after = ["network.target"];
wantedBy = ["multi-user.target"];
path = [papermc];
preStart = let
plugins =
builtins.map
(plugin: ''
cp ${plugin.package} plugins
${
if plugin.startScript != null
then ''
${plugin.startScript}
''
else ""
}
'')
cfg.plugins;
in ''
cd $HOME
# Agree to the EULA
echo "eula=true" > eula.txt
# Update the server properties
cat ${serverProperties} > server.properties
${
if cfg.properties.rcon-password-file != null
then ''
echo "rcon.password=$(cat ${builtins.toString cfg.properties.rcon-password-file})" >> server.properties
''
else ""
}
# Update the whitelist
cat ${whitelistJson} > whitelist.json
# Update the bukkit yml
cat ${bukkitYaml} > bukkit.yml
# Update the spigot yml
cat ${spigotYaml} > spigot.yml
# Update the paper yml
cat ${paperYaml} > paper.yml
# Update the plugins
mkdir -p plugins
rm -rf plugins/*.jar
${builtins.toString plugins}
'';
serviceConfig = {
Type = "simple";
User = "minecraft";
Group = "minecraft";
WorkingDirectory = cfg.stateDir;
ExecStart = "${papermc}/bin/minecraft-server -Xms8G -Xmx8G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -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";
Restart = "always";
RuntimeDirectory = "minecraft";
RuntimeDirectoryMode = "0755";
UMask = "0027";
ReadWritePaths = [cfg.stateDir]; # Grant access to the state directory
CapabilityBoundingSet = "";
# Security
NoNewPrivileges = true;
# Sandboxing
ProtectSystem = "strict";
ProtectHome = true;
PrivateTmp = true;
PrivateDevices = true;
PrivateUsers = true;
ProtectHostname = true;
ProtectClock = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectKernelLogs = true;
ProtectControlGroups = true;
RestrictAddressFamilies = ["AF_UNIX AF_INET AF_INET6"];
LockPersonality = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
PrivateMounts = true;
};
environment = {
USER = "minecraft";
HOME = cfg.stateDir;
};
};
users.users.minecraft = {
description = "Minecraft Server";
home = cfg.stateDir;
useDefaultShell = true;
group = "minecraft";
isSystemUser = true;
};
users.groups.minecraft = {};
systemd.tmpfiles.rules = [
"d '${cfg.stateDir}' 0750 minecraft minecraft - -"
];
};
}