Running a server
rustmc.yml
On this page
- worlds.<dimension>.simulation-distance
- worlds.<dimension>.anti-xray.enabled
- worlds.<dimension>.anti-xray.hidden-blocks
- spawning.mob-caps.monster
- spawning.mob-caps.creature
- spawning.mob-caps.ambient
- spawning.mob-caps.axolotls
- spawning.mob-caps.underground_water_creature
- spawning.mob-caps.water_creature
- spawning.mob-caps.water_ambient
- spawning.creature-spawn-period
- loot.block-drop-multiplier
- loot.mob-drop-multiplier
- worldgen.generate-chunks
- worldgen.generator
- chunks.builders
- chunks.chunk-cache-mib
- chunks.region-cache-mib
- chunks.column-cache-mib
- plugins.stop-fuel-multiple
- world-reset.allow-plugins
- rustmc.extra-commands
- fake-players.enabled
- mcp.enabled
- mcp.host
- mcp.port
- mcp.token
- bedrock.enabled
- bedrock.host
- bedrock.port
- bedrock.allow-unauthenticated
- portal.enabled
- portal.url
- portal.session-minutes
- portal.link-minutes
- portal.allow-insecure
- portal.proxy-header
- pack-host.enabled
- pack-host.host
- pack-host.port
- pack-host.url
- pack-host.directory
- pack-host.max-pack-mib
- backups.enabled
- backups.directory
- backups.interval-minutes
- backups.keep-recent
- backups.keep-daily
- backups.keep-weekly
- backups.max-total-gib
- backups.min-free-gib
- backups.max-mib-per-second
- backups.compression-level
- backups.only-after-play
- web-map.enabled
- web-map.host
- web-map.port
- web-map.render
- web-map.radius
- web-map.title
- web-map.fog
- web-map.url
- web-map.cache-mib
- web-map.live.redraw-seconds
- web-map.live.threads
- web-map.players.show
- web-map.players.names
- web-map.players.interval-seconds
- web-map.players.hide-sneaking
- web-map.players.hide-invisible
- diagnostics.thread-names
- diagnostics.traffic-counters
- diagnostics.profile-at-start
- diagnostics.profile-report
- plugin-ports.<plugin>.<grant>.port
- plugin-ports.<plugin>.<grant>.mode
- plugin-ports.<plugin>.<grant>.host
- plugin-ports.<plugin>.<grant>.max-connections
- plugin-ports.<plugin>.<grant>.max-connections-per-ip
- plugin-ports.<plugin>.<grant>.max-message-kib
- plugin-ports.<plugin>.<grant>.timeout-seconds
- plugin-ports.<plugin>.<grant>.max-queued-kib
- plugin-outbound.<plugin>.<grant>.url
- plugin-outbound.<plugin>.<grant>.private
- plugin-outbound.<plugin>.<grant>.timeout-seconds
- plugin-outbound.<plugin>.<grant>.max-request-kib
- network.enabled
- network.name
- network.listen
- network.secret
- network.peers.<peer>.address
- network.peers.<peer>.join
- network.channels.<plugin>
- Plugin ports
- Plugin outbound
- Network
rustmc.yml sits beside server.properties (or is named with --rustmc-yml <path>). It expands
server.properties; every property stays authoritative. An absent file and the default file
(docs/rustmc.default.yml) are the same server, and that server is vanilla: every default is the
game's own value, or -- for the keys marked invisible -- a size of this server's own caches or
threads that no client can observe.
The file is a YAML subset: nested mappings of scalars, # comments, quoted strings. Unknown keys
and wrong types stop the server with the line at fault. <dimension> is one of
minecraft:overworld, minecraft:the_nether, minecraft:the_end. <plugin> is a plugin's
name, <grant> any name you give that port or URL, and <peer> another server's network name, each in
letters, digits, - and _. No port is granted by default, so plugin-ports is not in the default
file, and nor are plugin-outbound, network.peers or network.channels.
| Key | Type | Default | Origin |
|---|---|---|---|
worlds.<dimension>.simulation-distance | int or null | null | vanilla |
worlds.<dimension>.anti-xray.enabled | bool | false | invisible |
worlds.<dimension>.anti-xray.hidden-blocks | string or null | null | invisible |
spawning.mob-caps.monster | int | 70 | vanilla |
spawning.mob-caps.creature | int | 10 | vanilla |
spawning.mob-caps.ambient | int | 15 | vanilla |
spawning.mob-caps.axolotls | int | 5 | vanilla |
spawning.mob-caps.underground_water_creature | int | 5 | vanilla |
spawning.mob-caps.water_creature | int | 5 | vanilla |
spawning.mob-caps.water_ambient | int | 20 | vanilla |
spawning.creature-spawn-period | int | 400 | vanilla |
loot.block-drop-multiplier | float | 1.0 | vanilla |
loot.mob-drop-multiplier | float | 1.0 | vanilla |
worldgen.generate-chunks | bool | true | vanilla |
worldgen.generator | string or null | null | vanilla |
chunks.builders | int or null | null | invisible |
chunks.chunk-cache-mib | int | 128 | invisible |
chunks.region-cache-mib | int | 64 | invisible |
chunks.column-cache-mib | int | 16 | invisible |
plugins.stop-fuel-multiple | int | 5 | invisible |
world-reset.allow-plugins | bool | false | invisible |
rustmc.extra-commands | bool | false | vanilla |
fake-players.enabled | bool | false | vanilla |
mcp.enabled | bool | false | invisible |
mcp.host | string | 127.0.0.1 | invisible |
mcp.port | int | 25585 | invisible |
mcp.token | string | "" | invisible |
bedrock.enabled | bool | false | invisible |
bedrock.host | string | 0.0.0.0 | invisible |
bedrock.port | int | 19132 | invisible |
bedrock.allow-unauthenticated | bool | false | invisible |
portal.enabled | bool | false | invisible |
portal.url | string | "" | invisible |
portal.session-minutes | int | 60 | invisible |
portal.link-minutes | int | 5 | invisible |
portal.allow-insecure | bool | false | invisible |
portal.proxy-header | string | "" | invisible |
pack-host.enabled | bool | false | invisible |
pack-host.host | string | 127.0.0.1 | invisible |
pack-host.port | int | 25586 | invisible |
pack-host.url | string | "" | invisible |
pack-host.directory | string | packs | invisible |
pack-host.max-pack-mib | int | 250 | invisible |
backups.enabled | bool | false | invisible |
backups.directory | string | backups | invisible |
backups.interval-minutes | int | 360 | invisible |
backups.keep-recent | int | 4 | invisible |
backups.keep-daily | int | 7 | invisible |
backups.keep-weekly | int | 4 | invisible |
backups.max-total-gib | int | 0 | invisible |
backups.min-free-gib | int | 10 | invisible |
backups.max-mib-per-second | int | 50 | invisible |
backups.compression-level | int | 1 | invisible |
backups.only-after-play | bool | true | invisible |
web-map.enabled | bool | false | invisible |
web-map.host | string | 0.0.0.0 | invisible |
web-map.port | int | 8100 | invisible |
web-map.render | string | on-create | invisible |
web-map.radius | int | 1024 | invisible |
web-map.title | string | World map | invisible |
web-map.fog | string | off | invisible |
web-map.url | string | `` | invisible |
web-map.cache-mib | int | 128 | invisible |
web-map.live.redraw-seconds | int | 30 | invisible |
web-map.live.threads | int | 2 | invisible |
web-map.players.show | bool | false | invisible |
web-map.players.names | bool | false | invisible |
web-map.players.interval-seconds | int | 5 | invisible |
web-map.players.hide-sneaking | bool | true | invisible |
web-map.players.hide-invisible | bool | true | invisible |
diagnostics.thread-names | bool | true | invisible |
diagnostics.traffic-counters | bool | true | invisible |
diagnostics.profile-at-start | int | 0 | invisible |
diagnostics.profile-report | string or null | null | invisible |
plugin-ports.<plugin>.<grant>.port | int or null | null | invisible |
plugin-ports.<plugin>.<grant>.mode | string | tcp | invisible |
plugin-ports.<plugin>.<grant>.host | string | 127.0.0.1 | invisible |
plugin-ports.<plugin>.<grant>.max-connections | int | 32 | invisible |
plugin-ports.<plugin>.<grant>.max-connections-per-ip | int | 8 | invisible |
plugin-ports.<plugin>.<grant>.max-message-kib | int | 64 | invisible |
plugin-ports.<plugin>.<grant>.timeout-seconds | int | 30 | invisible |
plugin-ports.<plugin>.<grant>.max-queued-kib | int | 1024 | invisible |
plugin-outbound.<plugin>.<grant>.url | string or null | null | invisible |
plugin-outbound.<plugin>.<grant>.private | bool | false | invisible |
plugin-outbound.<plugin>.<grant>.timeout-seconds | int | 30 | invisible |
plugin-outbound.<plugin>.<grant>.max-request-kib | int | 256 | invisible |
network.enabled | bool | false | invisible |
network.name | string | "" | invisible |
network.listen | string | 127.0.0.1:25700 | invisible |
network.secret | string | "" | invisible |
network.peers.<peer>.address | string | "" | invisible |
network.peers.<peer>.join | string | "" | invisible |
network.channels.<plugin> | string | "" | invisible |
worlds.<dimension>.simulation-distance
The simulation distance of one world, in chunks: how far from a player that world ticks entities, random-ticks blocks and spawns creatures. null inherits simulation-distance from server.properties. The client is still told the server's own value, as the game tells it.
- Accepts: null, or a whole number from 2 to 32.
- Default:
null. - Vanilla:
PlayerList.setSimulationDistance applies the one simulation-distance property to every level: for (ServerLevel level : this.server.getAllLevels()) level.getChunkSource().setSimulationDistance(simulationDistance). - Shown to take effect by
takes_effect_worlds_dimension_simulation_distance.
worlds.<dimension>.anti-xray.enabled
Sends hidden blocks with no open face as the rock around them, and sends them as themselves the moment one opens. Read at startup. A world with this on builds its own chunk packets rather than serving pregenerate's prepared ones; see docs/anti-xray.md for the cost.
- Accepts: true or false.
- Default:
false. - Invisible to clients: The game has no such thing. A client playing fair never sees a block it could not have seen, because a masked block is behind a solid face on every side.
- Shown to take effect by
takes_effect_worlds_dimension_anti_xray_enabled.
worlds.<dimension>.anti-xray.hidden-blocks
What anti-xray hides in this world, comma separated. null is every ore, ancient debris, chests, barrels and spawners. A name that is not a block stops the server at startup.
- Accepts: null, or a string.
- Default:
null. - Invisible to clients: Which blocks are hidden changes nothing a client playing fair can see.
- Shown to take effect by
takes_effect_worlds_dimension_anti_xray_hidden_blocks.
spawning.mob-caps.monster
Natural-spawn cap for the monster category, per 289 spawnable chunks globally and per player locally.
- Accepts: a whole number from 0 to 100000.
- Default:
70. - Vanilla:
MobCategory.<init> max argument, read by NaturalSpawner.SpawnState.canSpawnForCategoryGlobal and LocalMobCapCalculator.canSpawn. - Shown to take effect by
takes_effect_spawning_mob_caps_monster.
spawning.mob-caps.creature
Natural-spawn cap for the creature category (the passive animals).
- Accepts: a whole number from 0 to 100000.
- Default:
10. - Vanilla:
MobCategory.<init> max argument, read by NaturalSpawner.SpawnState.canSpawnForCategoryGlobal and LocalMobCapCalculator.canSpawn. - Shown to take effect by
takes_effect_spawning_mob_caps_creature.
spawning.mob-caps.ambient
Natural-spawn cap for the ambient category (bats).
- Accepts: a whole number from 0 to 100000.
- Default:
15. - Vanilla:
MobCategory.<init> max argument, read by NaturalSpawner.SpawnState.canSpawnForCategoryGlobal and LocalMobCapCalculator.canSpawn. - Shown to take effect by
takes_effect_spawning_mob_caps_ambient.
spawning.mob-caps.axolotls
Natural-spawn cap for the axolotls category.
- Accepts: a whole number from 0 to 100000.
- Default:
5. - Vanilla:
MobCategory.<init> max argument, read by NaturalSpawner.SpawnState.canSpawnForCategoryGlobal and LocalMobCapCalculator.canSpawn. - Shown to take effect by
takes_effect_spawning_mob_caps_axolotls.
spawning.mob-caps.underground_water_creature
Natural-spawn cap for the underground_water_creature category (glow squid).
- Accepts: a whole number from 0 to 100000.
- Default:
5. - Vanilla:
MobCategory.<init> max argument, read by NaturalSpawner.SpawnState.canSpawnForCategoryGlobal and LocalMobCapCalculator.canSpawn. - Shown to take effect by
takes_effect_spawning_mob_caps_underground_water_creature.
spawning.mob-caps.water_creature
Natural-spawn cap for the water_creature category (squid, dolphins).
- Accepts: a whole number from 0 to 100000.
- Default:
5. - Vanilla:
MobCategory.<init> max argument, read by NaturalSpawner.SpawnState.canSpawnForCategoryGlobal and LocalMobCapCalculator.canSpawn. - Shown to take effect by
takes_effect_spawning_mob_caps_water_creature.
spawning.mob-caps.water_ambient
Natural-spawn cap for the water_ambient category (fish).
- Accepts: a whole number from 0 to 100000.
- Default:
20. - Vanilla:
MobCategory.<init> max argument, read by NaturalSpawner.SpawnState.canSpawnForCategoryGlobal and LocalMobCapCalculator.canSpawn. - Shown to take effect by
takes_effect_spawning_mob_caps_water_ambient.
spawning.creature-spawn-period
Ticks between natural-spawn passes for the persistent category (creatures). Every other category is tried every tick.
- Accepts: a whole number from 1 to 1000000.
- Default:
400. - Vanilla:
ServerChunkCache.tickChunks: boolean spawnPersistent = level.getGameTime() % 400L == 0L. - Shown to take effect by
takes_effect_spawning_creature_spawn_period.
loot.block-drop-multiplier
Multiplies the count of every stack a block's loot table drops when it is broken or blown up. A fractional remainder becomes one more item with that probability; 0 drops nothing.
- Accepts: a number from 0 to 64.
- Default:
1.0. - Vanilla:
Block.dropResources: getDrops(state, level, pos, blockEntity, entity, tool).forEach(stack -> popResource(level, pos, stack)), each stack as rolled. - Shown to take effect by
takes_effect_loot_block_drop_multiplier.
loot.mob-drop-multiplier
Multiplies the count of every stack a dying creature's loot table drops. Equipment and carried blocks are not scaled.
- Accepts: a number from 0 to 64.
- Default:
1.0. - Vanilla:
LivingEntity.dropFromLootTable: lootTable.getRandomItems(params, this.getLootTableSeed(), stack -> this.spawnAtLocation(level, stack)), each stack as rolled. - Shown to take effect by
takes_effect_loot_mob_drop_multiplier.
worldgen.generate-chunks
Whether a chunk that is not on disk is generated from the world's seed. false leaves unexplored chunks empty (the same as the --no-generate flag).
- Accepts: true or false.
- Default:
true. - Vanilla:
ChunkMap.scheduleChunkGeneration: every chunk not read from disk runs the ChunkStatus pipeline from the level's generator. - Shown to take effect by
takes_effect_worldgen_generate_chunks.
worldgen.generator
The generator plugin new chunks are made with, by name: which version of the game's world generation shapes terrain, biomes, decoration and structures. null is the newest compiled into this build, the version this server speaks. --generator on the command line overrides it. A name this build does not have stops the server at startup with the list of names it does. Chunks already saved are never regenerated.
- Accepts: null, or a string.
- Default:
null. - Vanilla:
WorldGenSettings / NoiseBasedChunkGenerator: the server generates with the worldgen code and data of its own version, the jar's own, and has no other to choose. - Shown to take effect by
takes_effect_worldgen_generator.
chunks.builders
Threads that may build chunks at once. null asks the machine (its available parallelism, at most 16). The --builders flag wins over this.
- Accepts: null, or a whole number from 1 to 64.
- Default:
null. - Invisible to clients: Only how many threads generate chunks; the chunks are the same whichever thread builds them, so nothing on the wire depends on it.
- Shown to take effect by
takes_effect_chunks_builders.
chunks.chunk-cache-mib
Memory for encoded chunk packets kept for reuse, in MiB.
- Accepts: a whole number from 1 to 1048576.
- Default:
128. - Invisible to clients: A cache of packets already built: a miss rebuilds the same bytes, so the size changes memory and speed, never what is sent.
- Shown to take effect by
takes_effect_chunks_chunk_cache_mib.
chunks.region-cache-mib
Memory for region-file data kept in memory, in MiB.
- Accepts: a whole number from 1 to 1048576.
- Default:
64. - Invisible to clients: A read cache over the region files: a miss reads the same bytes from disk.
- Shown to take effect by
takes_effect_chunks_region_cache_mib.
chunks.column-cache-mib
Memory for decoded chunk columns kept to be read again, in MiB. Nothing depends on a column staying here: one that falls out is read back from its region file.
- Accepts: a whole number from 1 to 1048576.
- Default:
16. - Invisible to clients: Holds columns past what tickets keep loaded; ticking follows tickets, not this cache, so an evicted column is re-read unchanged.
- Shown to take effect by
takes_effect_chunks_column_cache_mib.
plugins.stop-fuel-multiple
How much work a WebAssembly plugin may do as the server stops, as a multiple of what one ordinary call may: its shutdown hook usually saves everything it holds at once, and running out part-way through stops it with the save unfinished.
- Accepts: a whole number from 1 to 1000.
- Default:
5. - Invisible to clients: A budget on plugins' own code at shutdown, after every player has gone; no connection sees it.
- Shown to take effect by
takes_effect_plugins_stop_fuel_multiple.
world-reset.allow-plugins
Lets a plugin have the world reset the next time the server starts (the schedule_world_reset host call, for a gamemode with wipes): before the world opens, its directory is renamed aside with the time in its name and a fresh world is made with a new seed. Nothing is deleted, but everything in the world -- builds, player inventories, the End -- starts again. Off, the call is refused, and a reset already asked for is left undone and said so at every start.
- Accepts: true or false.
- Default:
false. - Invisible to clients: Decides only whether a plugin's request is honoured when the server starts; the world a client is sent is whatever world is there.
- Shown to take effect by
takes_effect_world_reset_allow_plugins.
rustmc.extra-commands
Offers this server's own commands, which the game does not have: /cookie, /plugins, /raid and /save. Off, they are unknown commands and absent from the command tree. The RUSTMC_EXTRA_COMMANDS environment variable turns them on as well.
- Accepts: true or false.
- Default:
false. - Vanilla:
Commands.<init> registers the dedicated tree without them; RaidCommand only if (SharedConstants.IS_RUNNING_IN_IDE). - Shown to take effect by
takes_effect_rustmc_extra_commands.
fake-players.enabled
Offers /fakeplayer to the console and level-4 operators: spawn, remove, list, and make speak or run commands a server-side player with no connection behind it, for testing moderation, permissions and the like on a live server. It joins and leaves as a player does, is never saved, is left out of the server list's count and the web map, and is removed at shutdown. Off, /fakeplayer is an unknown command.
- Accepts: true or false.
- Default:
false. - Vanilla:
Commands.<init> registers no such command. - Shown to take effect by
takes_effect_fake_players_enabled.
mcp.enabled
Serves the MCP endpoint: JSON-RPC over HTTP POST at /mcp, through which an AI assistant such as Claude Code can run console commands and read the server's state (players, entities, blocks, chunks, the log). Every request must carry Authorization: Bearer <mcp.token>. See docs/mcp.md.
- Accepts: true or false.
- Default:
false. - Invisible to clients: A separate HTTP listener on its own port, bound to localhost by default; nothing on a game connection changes whether it is on or off.
- Shown to take effect by
takes_effect_mcp_enabled.
mcp.host
The address the MCP endpoint binds. The default takes connections from this machine only; anything else exposes console access to the network, guarded by the token alone.
- Accepts: a string.
- Default:
127.0.0.1. - Invisible to clients: Where the separate MCP listener binds; the game connection is not involved.
- Shown to take effect by
takes_effect_mcp_host.
mcp.port
The TCP port of the MCP endpoint. 0 binds whatever port is free, printed at startup.
- Accepts: a whole number from 0 to 65535.
- Default:
25585. - Invisible to clients: The port of the separate MCP listener; the game connection is not involved.
- Shown to take effect by
takes_effect_mcp_port.
mcp.token
The bearer token every MCP request must present. Left empty, a random one is generated on the first start with the endpoint enabled and written back here, as server.properties gets its management-server-secret.
- Accepts: a string.
- Default:
"". - Invisible to clients: A credential for the separate MCP listener; the game connection is not involved.
- Shown to take effect by
takes_effect_mcp_token.
bedrock.enabled
Lets Minecraft: Bedrock Edition clients (1.26.50) join, on UDP, into the same world as Java players. Each Bedrock player is translated onto the Java connection path, so the game treats them as any other player. They appear as their gamertag with a leading ..
- Accepts: true or false.
- Default:
false. - Invisible to clients: A separate UDP listener on its own port; no Java connection changes whether it is on or off, and off is the server as it was.
- Shown to take effect by
takes_effect_bedrock_enabled.
bedrock.host
The address the Bedrock listener binds. The default takes clients from anywhere, as the Java port does.
- Accepts: a string.
- Default:
0.0.0.0. - Invisible to clients: Where the separate Bedrock listener binds; the Java connection is not involved.
- Shown to take effect by
takes_effect_bedrock_host.
bedrock.port
The UDP port of the Bedrock listener: 19132 is the one a Bedrock client tries first. 0 binds whatever port is free, printed at startup.
- Accepts: a whole number from 0 to 65535.
- Default:
19132. - Invisible to clients: The port of the separate Bedrock listener; the Java connection is not involved.
- Shown to take effect by
takes_effect_bedrock_port.
bedrock.allow-unauthenticated
Lets in a Bedrock client that Xbox Live has not vouched for, under whatever name it claims -- for tests and nothing else. Off, every Bedrock player must be signed in to Xbox Live and is checked against the authorisation service's keys.
- Accepts: true or false.
- Default:
false. - Invisible to clients: Decides who the separate Bedrock listener admits; nothing on a Java connection changes.
- Shown to take effect by
takes_effect_bedrock_allow_unauthenticated.
portal.enabled
Serves the web portal on the management port (server.properties' management-server-enabled must be true too): a page at /portal/ for operators to manage the server from a browser. An operator of level 3 or more signs in with a one-time link from /portal in game; the owner can also sign in with the management secret. See docs/portal.md.
- Accepts: true or false.
- Default:
false. - Invisible to clients: Served on the management port, which no game connection uses; off, that port is vanilla's exactly.
- Shown to take effect by
takes_effect_portal_enabled.
portal.url
The page's public address when the portal is reached through a TLS tunnel or a proxy, as https://host/portal -- what /portal links open, and the browser origin the portal accepts. Empty: the management port on localhost.
- Accepts: a string.
- Default:
"". - Invisible to clients: Served on the management port, which no game connection uses; off, that port is vanilla's exactly.
- Shown to take effect by
takes_effect_portal_url.
portal.session-minutes
How long a portal session lasts without being used, in minutes. A session also ends when its player stops being an operator.
- Accepts: a whole number from 1 to 10080.
- Default:
60. - Invisible to clients: Served on the management port, which no game connection uses; off, that port is vanilla's exactly.
- Shown to take effect by
takes_effect_portal_session_minutes.
portal.link-minutes
How long a /portal link may wait before it is used, in minutes. A link works once.
- Accepts: a whole number from 1 to 60.
- Default:
5. - Invisible to clients: Served on the management port, which no game connection uses; off, that port is vanilla's exactly.
- Shown to take effect by
takes_effect_portal_link_minutes.
portal.allow-insecure
Serves the portal without TLS on an address other machines can reach. Off, the portal refuses to start there: sign-in links and sessions would cross the network in plain text.
- Accepts: true or false.
- Default:
false. - Invisible to clients: Served on the management port, which no game connection uses; off, that port is vanilla's exactly.
- Shown to take effect by
takes_effect_portal_allow_insecure.
portal.proxy-header
Behind a tunnel or proxy on this machine, the header it puts the visitor's address in: CF-Connecting-IP for a Cloudflare Tunnel, X-Real-IP or X-Forwarded-For (its last entry) for nginx or Caddy. Sign-in attempts are limited per address, and behind a proxy every visitor would otherwise be localhost. Empty believes no header. Name only a header your proxy always sets: a visitor can send any header the proxy passes on.
- Accepts: a string.
- Default:
"". - Invisible to clients: Served on the management port, which no game connection uses; off, that port is vanilla's exactly.
- Shown to take effect by
takes_effect_portal_proxy_header.
pack-host.enabled
Serves resource packs over HTTP from this server, so a plugin or the operator can offer a pack without a web host of its own: the .zip files in pack-host.directory at /
- Accepts: true or false.
- Default:
false. - Invisible to clients: A separate HTTP listener on its own port, bound to localhost by default; no game connection changes whether it is on or off.
- Shown to take effect by
takes_effect_pack_host_enabled.
pack-host.host
The address the pack host binds. The default takes connections from this machine only, which no other player's client can reach; a public server binds 0.0.0.0 (or puts a proxy in front) and sets pack-host.url.
- Accepts: a string.
- Default:
127.0.0.1. - Invisible to clients: Where the separate pack-host listener binds; the game connection is not involved.
- Shown to take effect by
takes_effect_pack_host_host.
pack-host.port
The TCP port of the pack host. 0 binds whatever port is free, printed at startup.
- Accepts: a whole number from 0 to 65535.
- Default:
25586. - Invisible to clients: The port of the separate pack-host listener; the game connection is not involved.
- Shown to take effect by
takes_effect_pack_host_port.
pack-host.url
The address clients are told to fetch packs from, up to the path: http://packs.example.com:25586, say, when the bound address is not the one players reach (a proxy, a tunnel, a public IP). Empty uses http://
- Accepts: a string.
- Default:
"". - Invisible to clients: Only the URLs plugins are handed change; a client is offered a pack only when a plugin pushes one.
- Shown to take effect by
takes_effect_pack_host_url.
pack-host.directory
The directory whose .zip files are served, relative to the server's own files or absolute. Only files directly inside it, with names of letters, digits, dots, - and _; created when the host starts.
- Accepts: a string.
- Default:
packs. - Invisible to clients: Read only by the separate pack-host listener; the game connection is not involved.
- Shown to take effect by
takes_effect_pack_host_directory.
pack-host.max-pack-mib
The largest pack served or hosted, in MiB. 250 is the most a Java client downloads; a bigger file is refused rather than sent.
- Accepts: a whole number from 1 to 1024.
- Default:
250. - Invisible to clients: Caps what the separate pack-host listener sends; the game connection is not involved.
- Shown to take effect by
takes_effect_pack_host_max_pack_mib.
backups.enabled
Takes a backup of the world, the server's files and plugin data every backups.interval-minutes, during play. Off by default because it needs disk space somebody has thought about. /backup now works either way. See docs/backups.md.
- Accepts: true or false.
- Default:
false. - Invisible to clients: Copies files on a background thread; no game connection changes.
- Shown to take effect by
takes_effect_backups_enabled.
backups.directory
Where backups go: relative to the server's files, or absolute. Another drive survives this one failing.
- Accepts: a string.
- Default:
backups. - Invisible to clients: A folder on the server's machine; no client is told about it.
- Shown to take effect by
takes_effect_backups_directory.
backups.interval-minutes
How many minutes apart scheduled backups are.
- Accepts: a whole number from 5 to 10080.
- Default:
360. - Invisible to clients: A timer on a background thread; no client can tell.
- Shown to take effect by
takes_effect_backups_interval_minutes.
backups.keep-recent
How many of the newest backups are always kept.
- Accepts: a whole number from 0 to 1000.
- Default:
4. - Invisible to clients: Which backup files stay on disk; no client can tell.
- Shown to take effect by
takes_effect_backups_keep_recent.
backups.keep-daily
How many days keep their newest backup, counting days that have one.
- Accepts: a whole number from 0 to 1000.
- Default:
7. - Invisible to clients: Which backup files stay on disk; no client can tell.
- Shown to take effect by
takes_effect_backups_keep_daily.
backups.keep-weekly
How many weeks keep their newest backup, counting weeks that have one.
- Accepts: a whole number from 0 to 1000.
- Default:
4. - Invisible to clients: Which backup files stay on disk; no client can tell.
- Shown to take effect by
takes_effect_backups_keep_weekly.
backups.max-total-gib
The most all backups together may take, in GiB; the oldest go first, and the newest is never deleted. 0 is no limit beyond backups.min-free-gib.
- Accepts: a whole number from 0 to 1000000.
- Default:
0. - Invisible to clients: Which backup files stay on disk; no client can tell.
- Shown to take effect by
takes_effect_backups_max_total_gib.
backups.min-free-gib
The space, in GiB, a backup must leave free on its drive and on the world's. Short of it, older backups go, then the backup stops and says so, deleting its partial file.
- Accepts: a whole number from 0 to 1000000.
- Default:
10. - Invisible to clients: Decides whether a backup file is written; no client can tell.
- Shown to take effect by
takes_effect_backups_min_free_gib.
backups.max-mib-per-second
The most a backup reads, in MiB a second, on top of running at background priority on one thread. 0 is no limit.
- Accepts: a whole number from 0 to 100000.
- Default:
50. - Invisible to clients: Paces a background thread; no client can tell.
- Shown to take effect by
takes_effect_backups_max_mib_per_second.
backups.compression-level
The gzip level, 0 to 9. Region files are compressed already, so higher levels cost much and win little.
- Accepts: a whole number from 0 to 9.
- Default:
1. - Invisible to clients: How a backup file is packed; no client can tell.
- Shown to take effect by
takes_effect_backups_compression_level.
backups.only-after-play
Skips a scheduled backup when nobody has been online since the last one. /backup now always runs.
- Accepts: true or false.
- Default:
true. - Invisible to clients: Decides whether a backup file is written; no client can tell.
- Shown to take effect by
takes_effect_backups_only_after_play.
web-map.enabled
Draws the overworld from above as PNG images at one pixel a block, and serves them with a page that lays them out as one map at http://<web-map.host>:<web-map.port>/. With render: on-create or on-plugin-signal, terrain drawn once and never again; with render: live, the world as it stands, drawn when asked for. See docs/web-map.md.
- Accepts: true or false.
- Default:
false. - Invisible to clients: A separate HTTP listener on its own port and a render on a thread of its own; no game connection changes whether it is on or off.
- Shown to take effect by
takes_effect_web_map_enabled.
web-map.host
The address the web map binds. The default takes connections from anywhere, with no login: anyone who can reach this host on web-map.port sees the map. 127.0.0.1 keeps it to this machine (behind a reverse proxy, say).
- Accepts: a string.
- Default:
0.0.0.0. - Invisible to clients: Where the separate web-map listener binds; the game connection is not involved.
- Shown to take effect by
takes_effect_web_map_host.
web-map.port
The TCP port of the web map. 0 binds whatever port is free, printed at startup.
- Accepts: a whole number from 0 to 65535.
- Default:
8100. - Invisible to clients: The port of the separate web-map listener; the game connection is not involved.
- Shown to take effect by
takes_effect_web_map_port.
web-map.render
When a world's map is drawn. on-create: as soon as the server runs a world that has no map, from the generator's terrain alone. on-plugin-signal: when a plugin calls render_web_map for the world (Rusty, once its monuments stand), from the chunks as they then stand plus the generator's terrain everywhere else. Either way, once per world: the map is kept in
- Accepts: a string.
- Default:
on-create. - Invisible to clients: Decides only when the web map's images are drawn; nothing is sent to a client.
- Shown to take effect by
takes_effect_web_map_render.
web-map.radius
How far from spawn, in blocks, the map reaches in a world without an island border (a rusty-island world is drawn to its border instead). Chunks nobody has visited are drawn from the generator without being saved, so a larger radius costs render time, not disk.
- Accepts: a whole number from 16 to 30000.
- Default:
1024. - Invisible to clients: Sizes only the web map's images; nothing is sent to a client.
- Shown to take effect by
takes_effect_web_map_radius.
web-map.title
What the web map's page is called: its heading, its browser tab, and map.json's title. The server's name, say, so a player sees which server's map it is. Shown as text, never as markup.
- Accepts: a string.
- Default:
World map. - Invisible to clients: Names only the separate web-map listener's page; nothing is sent to a game client.
- Shown to take effect by
takes_effect_web_map_title.
web-map.fog
Hides the map where nobody has been. off: the whole area is shown. shared: a chunk shows once any player has been within their view distance of it, for everyone. per-player: each viewer sees where they have been, once signed in with /map link (the shared fog until then). Hidden ground is fog on the server, so nothing under it is sent. What has been explored is kept in
- Accepts: a string.
- Default:
off. - Invisible to clients: Decides only what the separate web-map listener serves; nothing is sent to a game client.
- Shown to take effect by
takes_effect_web_map_fog.
web-map.url
The web map's public address, as players reach it (https://map.example.org/ behind a proxy, say), for the sign-in links /map link gives with web-map.fog: per-player. Empty is this server's web-map.host and web-map.port.
- Accepts: a string.
- Default: ``.
- Invisible to clients: Only goes into the link /map link prints; nothing else about the game changes.
- Shown to take effect by
takes_effect_web_map_url.
web-map.cache-mib
The memory, in MiB, the web map may hold encoded tiles in, in a mode that serves tiles from memory (render: live). The least recently asked-for go first; a tile let go is drawn again when it is next asked for.
- Accepts: a whole number from 1 to 65536.
- Default:
128. - Invisible to clients: Bounds only the separate web-map listener's memory; nothing is sent to a game client.
- Shown to take effect by
takes_effect_web_map_cache_mib.
web-map.live.redraw-seconds
With render: live, the least time between two drawings of one tile, in seconds. A tile whose chunks changed is drawn again when it is next asked for, but no sooner than this after its last drawing; until then the last one is served.
- Accepts: a whole number from 1 to 86400.
- Default:
30. - Invisible to clients: Paces only the separate web-map listener's drawing; nothing is sent to a game client.
- Shown to take effect by
takes_effect_web_map_live_redraw_seconds.
web-map.live.threads
With render: live, how many threads draw tiles. More requests than they can take wait their turn in a short queue, and past it are answered 503; no thread is ever added for a burst.
- Accepts: a whole number from 1 to 64.
- Default:
2. - Invisible to clients: Sizes only the web map's own drawing threads, off the tick; nothing is sent to a game client.
- Shown to take effect by
takes_effect_web_map_live_threads.
web-map.players.show
Shows online players on the web map as dots, from /players.json, which does not exist while this is off: no player's position is ever computed for the map or served. Only players in the mapped world, at whole-block positions; a player can leave themselves off with /map hide. See docs/web-map.md for what each setting exposes.
- Accepts: true or false.
- Default:
false. - Invisible to clients: Decides only what the separate web-map listener serves; nothing is sent to a game client.
- Shown to take effect by
takes_effect_web_map_players_show.
web-map.players.names
Labels each player's dot with their name. Off, a dot is anonymous: the map shows where somebody is, never who.
- Accepts: true or false.
- Default:
false. - Invisible to clients: Decides only what the separate web-map listener serves; nothing is sent to a game client.
- Shown to take effect by
takes_effect_web_map_players_names.
web-map.players.interval-seconds
How often the players on the web map move: positions are read at most this often and the page asks again this often, so the map is always up to this many seconds behind.
- Accepts: a whole number from 1 to 3600.
- Default:
5. - Invisible to clients: Paces only the separate web-map listener's answers; nothing is sent to a game client.
- Shown to take effect by
takes_effect_web_map_players_interval_seconds.
web-map.players.hide-sneaking
Leaves crouching players off the web map, as the game hides a crouching player's name tag.
- Accepts: true or false.
- Default:
true. - Invisible to clients: Decides only what the separate web-map listener serves; nothing is sent to a game client.
- Shown to take effect by
takes_effect_web_map_players_hide_sneaking.
web-map.players.hide-invisible
Leaves invisible players off the web map: anyone under the invisibility effect, and spectators, whom other players cannot see either. A vanish plugin that works by either is honoured with it.
- Accepts: true or false.
- Default:
true. - Invisible to clients: Decides only what the separate web-map listener serves; nothing is sent to a game client.
- Shown to take effect by
takes_effect_web_map_players_hide_invisible.
diagnostics.thread-names
Names every thread the server makes for what it does -- rustmc-worker and rustmc-blocking for the runtime, chunk-builder, bedrock-pump, plugin-storage and the rest -- so a profile can say which thread the processor time went to. false gives every thread the name it had before: tokio's own for the runtime, none for those that had none. Read at startup.
- Accepts: true or false.
- Default:
true. - Invisible to clients: It decides only what the server measures about itself and reports to its owner; nothing a client is sent changes.
- Shown to take effect by
takes_effect_diagnostics_thread_names.
diagnostics.traffic-counters
Counts each connection's bytes in and out, before and after compression, and the chunks sent, for a profile's report and the health report (/spark health). Each count is one atomic add. false stops counting for connections made after startup.
- Accepts: true or false.
- Default:
true. - Invisible to clients: It decides only what the server measures about itself and reports to its owner; nothing a client is sent changes.
- Shown to take effect by
takes_effect_diagnostics_traffic_counters.
diagnostics.profile-at-start
Profiles the first this many seconds of the server, as /spark profiler would, and stops: for a run nobody is at the console of, such as a load test. Nought takes no profile. Write it somewhere with profile-report.
- Accepts: a whole number from 0 to 600.
- Default:
0. - Invisible to clients: It decides only what the server measures about itself and reports to its owner; nothing a client is sent changes.
- Shown to take effect by
takes_effect_diagnostics_profile_at_start.
diagnostics.profile-report
A file every finished profile is written to as JSON, replacing the last: its sections, its threads' processor time and its traffic. Relative to the directory rustmc.yml is in. null writes none.
- Accepts: null, or a string.
- Default:
null. - Invisible to clients: It decides only what the server measures about itself and reports to its owner; nothing a client is sent changes.
- Shown to take effect by
takes_effect_diagnostics_profile_report.
plugin-ports.<plugin>.<grant>.port
Gives the plugin named <plugin> a port, under a name of your choosing that it asks for: <grant>. Nothing opens without this. A plugin is handed bytes from the internet through it, so grant only what you mean to expose. It is plain TCP or HTTP/1.1 with no TLS: read Plugin ports at the end of this file first. null grants nothing; nought binds whatever port is free.
- Accepts: null, or a whole number from 0 to 65535.
- Default:
null. - Invisible to clients: A plugin port is its own listener, opened only for a plugin the owner named; no game connection sees it.
- Shown to take effect by
takes_effect_plugin_ports_plugin_grant_port.
plugin-ports.<plugin>.<grant>.mode
How the port is spoken: tcp hands the plugin bytes, http hands it whole requests.
- Accepts: a string.
- Default:
tcp. - Invisible to clients: A plugin port is its own listener, opened only for a plugin the owner named; no game connection sees it.
- Shown to take effect by
takes_effect_plugin_ports_plugin_grant_mode.
plugin-ports.<plugin>.<grant>.host
The IP address the port binds. The default is this machine alone: write 0.0.0.0 to take connections from anywhere, and firewall it. For anything carrying credentials stay on loopback behind a TLS reverse proxy or tunnel. An address, never a name.
- Accepts: a string.
- Default:
127.0.0.1. - Invisible to clients: A plugin port is its own listener, opened only for a plugin the owner named; no game connection sees it.
- Shown to take effect by
takes_effect_plugin_ports_plugin_grant_host.
plugin-ports.<plugin>.<grant>.max-connections
How many connections the grant holds open at once. Past it a new one is refused.
- Accepts: a whole number from 1 to 4096.
- Default:
32. - Invisible to clients: A plugin port is its own listener, opened only for a plugin the owner named; no game connection sees it.
- Shown to take effect by
takes_effect_plugin_ports_plugin_grant_max_connections.
plugin-ports.<plugin>.<grant>.max-connections-per-ip
How many of those may come from one address. IPv6 counts one /64 as one address, and a client can hold many of those, so max-connections is the real cap.
- Accepts: a whole number from 1 to 4096.
- Default:
8. - Invisible to clients: A plugin port is its own listener, opened only for a plugin the owner named; no game connection sees it.
- Shown to take effect by
takes_effect_plugin_ports_plugin_grant_max_connections_per_ip.
plugin-ports.<plugin>.<grant>.max-message-kib
The most a tcp client may send on one connection, or the size of one http request. Past it the connection is closed. An http grant will not open unless a request this size fits three quarters of max-queued-kib; a tcp client's bytes flow through the queue, so there it may be larger.
- Accepts: a whole number from 1 to 2048.
- Default:
64. - Invisible to clients: A plugin port is its own listener, opened only for a plugin the owner named; no game connection sees it.
- Shown to take effect by
takes_effect_plugin_ports_plugin_grant_max_message_kib.
plugin-ports.<plugin>.<grant>.timeout-seconds
How long a connection may last from start to finish, however busy, so a client sending a byte at a time gets nowhere. It also bounds a plugin that never answers.
- Accepts: a whole number from 1 to 3600.
- Default:
30. - Invisible to clients: A plugin port is its own listener, opened only for a plugin the owner named; no game connection sees it.
- Shown to take effect by
takes_effect_plugin_ports_plugin_grant_timeout_seconds.
plugin-ports.<plugin>.<grant>.max-queued-kib
The most bytes waiting on the grant, for the plugin or for a client. A quarter is kept for what goes out. Past it the server stops reading, and a plugin sending more is told no.
- Accepts: a whole number from 1 to 1048576.
- Default:
1024. - Invisible to clients: A plugin port is its own listener, opened only for a plugin the owner named; no game connection sees it.
- Shown to take effect by
takes_effect_plugin_ports_plugin_grant_max_queued_kib.
plugin-outbound.<plugin>.<grant>.url
Lets the plugin named <plugin> send web requests to this URL, under a name of your choosing that it asks for: <grant>. The plugin adds only a path under the URL's own, starting with /. Before its first ? that path may hold only letters, digits, - . _ ~ / and %XX escapes other than %2e, %2f, %5c, %25 and %00, and no segment of it may be . or start with ... After the ? it may hold letters, digits, - . _ ~, those same escapes, and = & + , : @ /. Any other path is refused, so it cannot climb out of the URL's however the far end decodes it. The host and port are always the URL's. https://, or http:// only when the grant is private, with no user or password, query or fragment; anything else stops the server. null grants nothing. Read Plugin outbound at the end of this file first.
- Accepts: null, or a string.
- Default:
null. - Invisible to clients: An outbound grant only lets a plugin the owner named send web requests from this server; no game connection sees it.
- Shown to take effect by
takes_effect_plugin_outbound_plugin_grant_url.
plugin-outbound.<plugin>.<grant>.private
Lets the grant use plain http and reach this machine and its network: loopback, private and link-local addresses. Off, the URL must be https and every address it resolves to public. The log warns the first time a private grant is used.
- Accepts: true or false.
- Default:
false. - Invisible to clients: An outbound grant only lets a plugin the owner named send web requests from this server; no game connection sees it.
- Shown to take effect by
takes_effect_plugin_outbound_plugin_grant_private.
plugin-outbound.<plugin>.<grant>.timeout-seconds
How long one request may take from start to finish, answer and all. A long poll waits up to this.
- Accepts: a whole number from 1 to 120.
- Default:
30. - Invisible to clients: An outbound grant only lets a plugin the owner named send web requests from this server; no game connection sees it.
- Shown to take effect by
takes_effect_plugin_outbound_plugin_grant_timeout_seconds.
plugin-outbound.<plugin>.<grant>.max-request-kib
The largest body the plugin may send in one request. A larger one is refused before anything is sent.
- Accepts: a whole number from 1 to 2048.
- Default:
256. - Invisible to clients: An outbound grant only lets a plugin the owner named send web requests from this server; no game connection sees it.
- Shown to take effect by
takes_effect_plugin_outbound_plugin_grant_max_request_kib.
network.enabled
Links this server to the others named under network.peers, so plugins can publish to each other (network_publish), see who is on every server (network_players) and send players between them (network_send). With it on, the server will not start unless network.name, network.listen and every peer are sound and network.secret is at least 32 characters. See the Network section of docs/rustmc-yml.md.
- Accepts: true or false.
- Default:
false. - Invisible to clients: The link is a listener and connections of its own, between this server and others the owner named; no game connection sees it.
- Shown to take effect by
takes_effect_network_enabled.
network.name
This server's name on the network, what its peers list it under and what a player's server tag shows: letters, digits, - and _, at most 32. Every server on one network needs its own.
- Accepts: a string.
- Default:
"". - Invisible to clients: The link is a listener and connections of its own, between this server and others the owner named; no game connection sees it.
- Shown to take effect by
takes_effect_network_name.
network.listen
The ip:port this server's link listens on for its peers. Keep it on loopback when the servers share a machine, or on a private network address otherwise: the link is authenticated but not encrypted.
- Accepts: a string.
- Default:
127.0.0.1:25700. - Invisible to clients: The link is a listener and connections of its own, between this server and others the owner named; no game connection sees it.
- Shown to take effect by
takes_effect_network_listen.
network.secret
The secret every server on the network shares, at least 32 characters: each link proves both ends hold it before anything is sent, and it never crosses the wire. Generate a long random one, put the same value in every server's file, and keep this file private. It is never written to the log.
- Accepts: a string.
- Default:
"". - Invisible to clients: The link is a listener and connections of its own, between this server and others the owner named; no game connection sees it.
- Shown to take effect by
takes_effect_network_secret.
network.peers.<peer>.address
Where the peer's link listens (its network.listen), host:port. This server connects out to it, and again with a growing wait while it is down.
- Accepts: a string.
- Default:
"". - Invisible to clients: The link is a listener and connections of its own, between this server and others the owner named; no game connection sees it.
- Shown to take effect by
takes_effect_network_peers_peer_address.
network.peers.<peer>.join
The public address players are sent to by network_send, host:port or a host for port 25565. Empty, nobody can be sent there. The peer needs accepts-transfers=true in its server.properties.
- Accepts: a string.
- Default:
"". - Invisible to clients: The link is a listener and connections of its own, between this server and others the owner named; no game connection sees it.
- Shown to take effect by
takes_effect_network_peers_peer_join.
network.channels.<plugin>
The channel namespaces a plugin may publish and subscribe to besides its own name, comma-separated: moderation, chat, or * for every one. Without an entry a plugin may use only <its name>:....
- Accepts: a string.
- Default:
"". - Invisible to clients: The link is a listener and connections of its own, between this server and others the owner named; no game connection sees it.
- Shown to take effect by
takes_effect_network_channels_plugin.
Plugin ports
What a plugin-ports grant exposes, and what it does not protect:
- There is no TLS. A port speaks plain TCP or plain HTTP/1.1, so anyone on the path can read and
change it. For anything carrying credentials, keep
hoston loopback and put a TLS reverse proxy or a tunnel in front. - A public port is firewalled by you. Binding
0.0.0.0takes connections from anywhere the machine is reachable. Allow only the sources that need it. The server logs a warning when anhttpgrant opens on anything but loopback. - Votifier has its own crypto: v1 RSA and v2 HMAC, checked for every vote. It is the one protocol here that is fit to face the internet directly, with its keys in the plugin's own config.
- HTTP is deliberately small: one request per connection, always
Connection: close, with no chunked input, no keep-alive and no HTTP/2. AHEADis answered without its body. - Limits are per grant, not per plugin or per server, so two grants hold twice as much.
max-connectionsis the real cap. The per-address limit counts one IPv6 /64 as one address, and a client with a wider range than that can use several.- A grant follows the name in a plugin's manifest, so it goes to whichever plugin you installed under that name. Install only what you trust with the port.
Plugin outbound
A plugin-outbound grant lets one plugin send GET requests, and POST requests with a body,
with headers of its choosing, to one URL you write. The plugin names the grant and a path under the URL, never
the URL, and no redirect is followed. private: true lets a plugin reach this machine's network:
plain http, this machine, and the private and link-local addresses around it, which a public
grant refuses. Give it only for a service on your own network that you mean that plugin to talk
to, and keep its credentials in the plugin's secret settings rather than in the URL. A grant
follows the name in a plugin's manifest, as a port does.
Network
network links servers into one network without a proxy: plugins publish to each other, see who
is on every server, and send players across with the game's transfer packet. Each server connects
out to every peer and accepts each peer's connection, so every server names every other:
network:
enabled: true
name: survival
listen: 127.0.0.1:25700
secret: "a long random string, the same on every server"
peers:
rusty:
address: 127.0.0.1:25701
join: rusty.example.net:25567
channels:
chat: "moderation"
- Bind the link to loopback or a private network. Both ends prove they hold
secretbefore anything else is sent, but the traffic is not encrypted: anyone on the path can read it. For servers on different machines, use a private network or a tunnel, and firewall the port. - The secret is the network. A server that holds it can speak for any plugin's channels on every other. At least 32 characters, never logged, and the server refuses to start without it.
- Players are sent to
join, notaddress. The peer needsaccepts-transfers=truein itsserver.properties, or the client is turned away at its door. - Delivery is best effort. A message is sent to the peers whose link is up and is gone if the
link drops first;
network_serverssays which are up. Each frame is at most 1 MiB, and a peer sending more than 200 messages a second (bursts of 400) has the rest dropped. - A channel belongs to a plugin. A plugin publishes and subscribes only under its own name
(
chat:...) and the namespacesnetwork.channels.<plugin>adds.
From docs/rustmc-yml.md in the RustMC repository at bbd81209ad.