# Minecraft Server Hosting - everything RE:NODE has published

> A Minecraft server on RE:NODE: plans, how the panel runs it, and every tutorial RE:NODE has published about it.

Generated from https://www.renode.space/game-servers/minecraft, the live catalogue, the deploy docs, the panel guides and the RE:NODE blog. English. Source of truth for anything that changes: https://www.renode.space/game-servers/minecraft.

> This file is trimmed to stay under 400,000 characters: every post is listed with its link, but only the newest ones are included in full. Open a post's link for its text.

Contents: what it is, plans and prices, panel how-to, tutorials, rules for the assistant.

## What it is

Paper servers: the same Minecraft, several times faster than vanilla, with plugin support.

### What comes with every Minecraft server

- Configured before you see it: The install runs, the configuration is written and the server starts. No first-boot checklist, and nothing left on a default password shared with every other Minecraft server on the internet.
- The real console: Live output, command input and the server's own logs - not a filtered summary. Web-server noise is folded behind a counter you can switch off.
- Files and SFTP: A full file manager with an editor, plus SFTP credentials. Upload mods, edit configs, pull a world down to your machine.
- 2-2 backup slots: Taken on demand or on a schedule, restored with a button. Deleting a server takes its backups with it, on purpose.
- 1 port allocated: Add and remove ports yourself from the Network tab, including the query and RCON ports where the game wants them.
- People on the same server: Invite friends or staff with granular permissions - console only, files only, no billing - through subusers, roles and teams.

### Which Minecraft plan do you need?

Memory is what decides whether a server holds together, so start there. The Starter tier gives 2 GB and 1 vCPU, which suits a private group. The Advanced tier at 6 GB is where most public servers sit, and Premium at 14 GB exists for the servers that stay full.

Storage matters more than people expect once mods and backups are involved - plans here run from 15 GB to 100 GB of NVMe. Moving up or down a tier later does not rebuild your world; it changes the limits on the container you already have.

If you are not sure, take the middle tier. It is cheaper to move up after a busy weekend than to spend one explaining lag to your players.

More game servers: https://www.renode.space/ai/game-servers.md

### General questions

### Getting started

**How quickly is my server ready?**

Game, app, web and database servers are created the moment payment clears, usually inside a minute. The game or runtime is installed and started for you, and the console is live in your browser while it happens. VDS and dedicated servers are prepared by hand and delivered within 24 hours.

**Do I need to configure anything before it works?**

No. The install runs, the configuration is written, and admin passwords are generated for your server rather than shared with everybody else's. The exception is four games whose publisher issues a credential to a person - those say so on the shop before you pay, and ask for it on a Setup tab afterwards.

**Which games need a key from me?**

Counter-Strike 2 needs a Steam game-server token, Don't Starve Together a Klei cluster token, FiveM a Cfx.re licence, and DayZ, Project Zomboid, 7 Days to Die, Arma 3 and Unturned need a Steam account or token of your own. We cannot create any of them and we never share one between customers. Your server is built immediately and the installation waits until you paste yours in.

**Can I try before buying?**

There is no free tier. The entry plans start at $1.50 a month precisely so that trying something costs about as much as a coffee.

**Can Claude or ChatGPT set my project up?**

Yes, and the panel gives it what it needs. On a server's Console tab, pick a purpose and press Connect AI: the panel copies a private link with the runtime, the port the code must read from SERVER_PORT, the code path, the GitHub branch, the databases and the limits. Paste it into Claude, ChatGPT or any assistant that can open links; the same link followed by /mcp works as an MCP server URL. It stops by itself after 7 days unused. You can also connect Claude, or any MCP client, to your whole account at https://panel.renode.space/api/client/mcp. Linked repositories get a pre-flight check that shows what will break before a deploy, no AI needed. No password or token is ever shown to the assistant - the AI setup page explains it all.

### Running the server

**Do I get full file access?**

Yes - a complete file manager with an in-browser editor, plus SFTP credentials. There is no plan on which the file manager is disabled or read-only.

**Can I install mods and plugins?**

Yes. Upload them through the file manager or SFTP, or use the game's own workshop support where it has any. Nothing here whitelists which mods you are allowed to run.

**Can other people help me run it?**

Yes. Invite subusers with granular permissions - console only, files only, no billing - or build a team with a role and grant it access to several servers at once. Permissions are a union, so nobody loses access they were given elsewhere.

**What happens if my server runs out of memory?**

New servers are configured so the kernel stops the container and it restarts clean, rather than swapping and dragging the whole machine down. If a server restarts repeatedly we warn you on the server page and open a support ticket before anything is suspended - you get told twice before it stops.

**Is the CPU limit a hard limit?**

Yes, and it cannot be breached: the container is throttled to the share you bought. A server sitting at 100% is slow, not broken, and is never suspended for it.

### Backups and safety

**Are backups included?**

Every plan carries backup slots - two on the entry tiers, more further up. Take them on demand or on a schedule, and restore with a button rather than a support ticket.

**Where are backups stored?**

Off the machine they protect. A backup sitting on the same disk as the thing it is insuring covers you deleting your world and covers nothing at all about the disk failing.

**What happens to my backups if I cancel?**

Deleting a server deletes its backups with it, deliberately and including locked ones. Download anything you want to keep first - the panel lets you.

### Billing

**How do I pay?**

PayPal, card, your wallet balance, or bank transfer. Every method produces a proper invoice you can download or print, with our details and the bank account on it while it is unpaid.

**Can I pay in Georgian lari?**

The panel displays every figure in lari at the National Bank of Georgia's published rate, marks converted figures as approximate, and always shows the amount that will actually be charged. Invoices stay in the currency they were raised in, because an invoice is a demand for a specific amount.

**What happens when my subscription is due?**

An invoice is raised and emailed to you seven days before expiry, and again on the day. Paying it settles that same document rather than raising a second one.

**Can I upgrade or downgrade later?**

Yes, and it does not rebuild anything. Changing plan changes the limits on the container you already have - your world, files and database stay exactly where they are.

**Do you offer refunds?**

There is no automatic refund button. If a server cannot do what it was sold to do, open a ticket and we will sort it out - including refunding you. We would rather fix the plan than argue about the policy.

### Support and the honest bits

**How do I get help?**

Open a ticket from the panel - it reaches every member of staff and every administrator, not a queue aimed at nobody in particular. Attach a screenshot if it helps; attachments are private to your ticket rather than sitting at a guessable public URL. Discord is there for faster, less formal questions.

**Where are the servers?**

Germany, on hardware we run. That is one location: if you need players in another region on a low ping, say so before buying rather than after.

**Is there an uptime guarantee?**

We measure node availability every five minutes and report it in the panel rather than printing a number with four decimal places we have not earned. If something is down you will usually hear it from us first.

**Who actually runs this?**

A small team that writes the panel, the shop and the automation itself. When something is wrong the fix is a code change, which is why the list of things wrong keeps getting shorter.

## Plans and prices

Read from the live catalogue at 2026-10-15 22:30 UTC. Prices are in US dollars per month; checkout also takes Georgian lari and bills for 1, 3, 6, 12 or 24 months. Prices change - re-check on https://www.renode.space/game-servers/minecraft or in the panel shop at https://panel.renode.space before quoting one.

| Plan | Price / month | Memory | CPU | NVMe disk | Databases | Backups | Ports |
|---|---|---|---|---|---|---|---|
| Starter | $5 | 2 GB | 1 vCPU | 15 GB | 1 | 2 | 1 |
| Standard | $9 | 4 GB | 1.5 vCPU | 30 GB | 1 | 2 | 1 |
| Advanced | $14 | 6 GB | 2 vCPU | 50 GB | 1 | 2 | 1 |
| Pro | $22 | 10 GB | 2.5 vCPU | 75 GB | 1 | 2 | 1 |
| Premium | $34 | 14 GB | 3.5 vCPU | 100 GB | 1 | 2 | 1 |


## Panel how-to

From the panel guides at https://www.renode.space/guides.

### Ordering a server

Ordering takes about a minute and happens in three screens: find what you want to run, pick a plan, and pay. Pay by card or PayPal and the server is set up the moment the payment goes through - you can watch it install in its console.

- Takes: About a minute
- Pay with: Card, PayPal or bank transfer
- Billed for: 1, 3, 6, 12 or 24 months
- Prices in: US dollars or Georgian lari

Open the shop and find what you want to run:

1. Sign in to the panel and open the shop. The tabs along the top are the product lines: VDS, Game Servers, App Hosting, Web Hosting and Databases.
2. Find your game - there is a search box - and press View plans. The card already shows the lowest price and the range of memory on offer.

Compare the plans and pick one:

3. Every plan lists its memory, CPU and NVMe storage, roughly how many players it suits, and what is included - updates, backup slots, file and SFTP access.
4. Press Get Started on the one you want. Not sure? Start smaller: you can move to a bigger plan later without losing your world.

Choose how long, then pay:

5. Pick a billing period - 1, 3, 6, 12 or 24 months. The total for the whole period is shown before you pay, so there are no surprises.
6. Pay with PayPal, or press Debit or Credit Card - paying by card does not need a PayPal account. The server is created as soon as the payment completes.

Paying by bank transfer instead: Prefer to pay from your bank? Choose bank transfer at checkout. The server is set up once the payment arrives, usually the next working day.

1. Switch the payment tab to Bank transfer. The account details for Bank of Georgia and TBC Bank appear, each with a Copy button.
2. Press Order & get invoice, then pay that invoice from your banking app, quoting the reference on it.

After you pay:

- The server appears under My Servers and installs itself. Open it to watch the install in the console.
- Your orders, invoices and subscriptions are under Finances in the side menu.
- Stuck at any step? Open Support in the side menu and raise a ticket.

### The console

Live output, a command line, power controls and the resource graphs. It is the server's own output rather than a filtered summary - if the game prints it, you see it.

- Start, stop, restart and kill, with the current state always visible.
- Command history with the arrow keys, and tab completion for common commands.
- Web-server noise - the internet knocking on doors that are not there - is folded behind a count you can switch off. A real error always prints.
- Graphs for memory, CPU and disk against your limits, so whether it is the plan or the mod is answerable.

### Files and SFTP

A complete file manager with an editor in the browser, plus SFTP credentials for the tools you already use. Upload a modpack, fix a config, pull a world down to your machine.

- Drag files in, or upload a folder. Archives can be unpacked in place.
- Edit any text file with syntax highlighting and save without downloading it.
- PDFs and images preview in the panel rather than downloading first.
- SFTP on the same credentials - use FileZilla, WinSCP or your editor's remote mode.

### Backups

Take one before you try something. Restore it when the something goes wrong. Lock the ones that matter so they are not rotated away.

- Slots on every plan - two on the entry tiers, more further up.
- Take one on demand, or on a schedule you set.
- Download any backup to your own machine.

> Important: Deleting a server deletes its backups, including the locked ones. A lock stops you removing a backup by accident; it is not a claim on the disk after the server is gone. Download what you want to keep before you cancel.

### Subusers, roles and teams

Give somebody the console without giving them your files, or the files without your billing. Three separate ideas, kept apart deliberately.

- A role holds permissions - what may be done.
- A team holds people.
- A grant joins a team to a server with a role, so adding a moderator to the team gives them the same access everywhere at once.
- Invite by link, by a join code, or by email address - and require approval on the codes if you would rather vet people.
- Access can be time-boxed, and expiry stops working immediately rather than overnight.

### Scheduled tasks

Restart nightly, back up before the restart, announce it to players first. Tasks run in order with delays between them, so a schedule can be a small routine rather than one action.

- Send a console command - a warning to players, a save, a world flush.
- Take a backup.
- Power actions: start, stop, restart.

### Games that need a key from you

A few games want a credential their publisher issues to a person - a Steam game-server token, a Steam account that owns the server files, a Klei cluster token, a Cfx.re licence. We cannot create one and we never share one between customers.

> Note: Those games say so on the shop before you pay. Your server is built immediately, and the game installation is held until you paste the value into a Setup tab, because installing without it produces a server with no game files in it and no explanation.

## Tutorials

65 posts, newest first. The newest 19 follow in full after the list; open the link for the rest.

- [All the Mods 10 server setup: files, Java 21 and RAM](https://www.renode.space/blog/all-the-mods-10-server-setup) (2026-10-15): Set up an All the Mods 10 server step by step: the server files, NeoForge install, Java 21, user_jvm_args.txt, RAM by player count and the crashes people hit.
- [All the Mods 9 vs 10: which to run on a server](https://www.renode.space/blog/all-the-mods-9-vs-10) (2026-10-15): ATM9 or ATM10 for a group server: Minecraft and loader versions, what changes in play, RAM and CPU cost, stability, and why a world cannot move between them.
- [How to set up BungeeCord: jar, config.yml and backends](https://www.renode.space/blog/bungeecord-setup-guide) (2026-10-15): Set up a BungeeCord proxy step by step: the official jar, every config.yml key that matters, backend settings, firewalling and the errors people hit first.
- [EssentialsX config.yml: the settings that matter](https://www.renode.space/blog/essentialsx-config-yml-guide) (2026-10-15): What to change in EssentialsX config.yml: economy keys, teleport cooldowns, home limits, chat formats, spawn on join, AntiBuild, GeoIP and reloading safely.
- [EssentialsX kits, warps, homes and spawn: full setup](https://www.renode.space/blog/essentialsx-kits-warps-and-homes) (2026-10-15): Set up EssentialsX kits with delays and permissions, per-warp access, home limits by rank with sethome-multiple, and a working /spawn with EssentialsX Spawn.
- [How to enable datapacks in Minecraft: worlds and servers](https://www.renode.space/blog/how-to-enable-datapacks-in-minecraft) (2026-10-15): Enable a datapack in a new world, an existing world or on a server: the Data Packs screen, /datapack enable, server.properties keys and experimental packs.
- [Minecraft join and quit messages: hide or change them](https://www.renode.space/blog/minecraft-join-and-quit-messages) (2026-10-15): How to hide or change Minecraft join and leave messages: why vanilla cannot, EssentialsX custom-join-message, silent join for staff, vanish and first-join.
- [Minecraft ops.json example: whitelist, bans and usercache](https://www.renode.space/blog/minecraft-ops-json-whitelist-json-explained) (2026-10-15): What ops.json, whitelist.json, the ban lists and usercache.json hold, a working example of each, and how to edit them without the server undoing it.
- [Minecraft shop plugins: ChestShop vs QuickShop-Hikari](https://www.renode.space/blog/minecraft-player-shops-chestshop-quickshop) (2026-10-15): Pick and set up a player shop plugin on Paper: ChestShop, QuickShop-Hikari or EssentialsX signs, admin shops that do not print money, dupes and pricing.
- [PaperMC download API: scripting Paper, Velocity and Folia jars](https://www.renode.space/blog/papermc-download-api) (2026-10-15): Download Paper, Velocity and Folia from a script: the Fill v3 API that replaced v2, stable channels, sha256 checks, User-Agent rules and a curl + jq updater.
- [All the Mods server: ATM10 and ATM9 setup](https://www.renode.space/blog/minecraft-all-the-mods-server) (2026-10-07): Run an All the Mods server: the server files, RAM for ATM10 and ATM9, slow first starts, chunk loading, pre-generation, and updating without losing the world.
- [Minecraft anarchy server: exploits and limits](https://www.renode.space/blog/minecraft-anarchy-server-guide) (2026-10-07): Run a no-rules Minecraft anarchy server that stays up: Paper's packet and book limits, lag machines, elytra and chunk generation, map size on disk, and attacks.
- [Bedrock Dedicated Server setup and add-ons](https://www.renode.space/blog/minecraft-bedrock-dedicated-server-guide) (2026-10-07): Run Minecraft Bedrock Dedicated Server: installing it, every server.properties key that matters, port 19132, allowlist and permissions, add-ons, backups and consoles.
- [BungeeCord vs Velocity: Minecraft proxies](https://www.renode.space/blog/minecraft-bungeecord-vs-velocity) (2026-10-07): BungeeCord and Velocity compared: forwarding security, plugin support, performance and config, plus a step-by-step migration from BungeeCord to Velocity.
- [Minecraft corrupted chunks and recovery](https://www.renode.space/blog/minecraft-chunk-errors-and-world-corruption) (2026-10-07): Fix corrupted Minecraft chunks and region files: what the log errors mean, finding the bad region, MCA Selector, restoring one region from backup, and prevention.
- [Cobblemon server setup and performance](https://www.renode.space/blog/minecraft-cobblemon-server-guide) (2026-10-07): Run a Cobblemon server on Fabric or NeoForge: dependencies, the main.json settings that matter, spawn and despawn tuning, player data and RAM.
- [Minecraft crash reports: watchdog and lag](https://www.renode.space/blog/minecraft-crash-reports-explained) (2026-10-07): Read a Minecraft server crash report: the sections that matter, watchdog thread dumps, the Can't keep up warning, and how to find the plugin in a stack trace.
- [Create mod server: setup, trains and lag](https://www.renode.space/blog/minecraft-create-mod-server) (2026-10-07): Run the Create mod on a Forge or NeoForge server: versions and addons, RAM, the server config limits, and why contraptions and trains cause lag.
- [Minecraft custom items: ItemsAdder, Oraxen, Nexo](https://www.renode.space/blog/minecraft-custom-items-and-itemsadder) (2026-10-07): How custom items, blocks and furniture work on a Paper server, ItemsAdder vs Oraxen vs Nexo, hosting the generated resource pack, and what it costs.
- [Minecraft custom world generation and seeds](https://www.renode.space/blog/minecraft-custom-world-generation) (2026-10-07): Custom terrain on a Minecraft server: worldgen datapacks like Terralith and Tectonic, seeds and level-type, plugin generators, and what pre-generation costs.
- [DiscordSRV setup: Minecraft to Discord chat](https://www.renode.space/blog/minecraft-discord-integration-discordsrv) (2026-10-07): Connect a Minecraft server to Discord with DiscordSRV: creating the bot, intents, the chat bridge, a console channel done safely, account linking and role sync.
- [Minecraft entity lag: limits and ClearLag](https://www.renode.space/blog/minecraft-entity-cleanup-and-clearlag) (2026-10-07): Control dropped items, XP orbs and entity buildup with Paper despawn and merge settings, safe kill commands, and why ClearLag should be the last resort.
- [Fabric server performance mods: Lithium, C2ME](https://www.renode.space/blog/minecraft-fabric-server-performance-mods) (2026-10-07): Which Fabric performance mods belong on a server - Lithium, FerriteCore, ModernFix, Krypton, C2ME and friends - what each one changes, and how to test them.
- [Minecraft Folia: when multithreading pays off](https://www.renode.space/blog/minecraft-folia-regionised-multithreading) (2026-10-07): What Folia actually changes about the tick loop, which plugins run on it, the hardware it was built for, and why most servers should stay on Paper.
- [Minecraft hardcore server: deathbans and revives](https://www.renode.space/blog/minecraft-hardcore-server) (2026-10-07): Run a hardcore Minecraft server for a group: hardcore=true, what happens on death, lives and deathbans with a small datapack, revives, resets and fair rules.
- [Minecraft holograms, scoreboards and TAB list](https://www.renode.space/blog/minecraft-holograms-scoreboards-and-tab) (2026-10-07): Set up DecentHolograms, a sidebar scoreboard and the TAB plugin with PlaceholderAPI, keep refresh rates sane, and know when vanilla commands are enough.
- [Minecraft BedWars and minigames server](https://www.renode.space/blog/minecraft-minigames-server-bedwars) (2026-10-07): Run BedWars and other minigames on Paper: choosing a plugin, building arenas, resetting maps after each game, and laying out lobby and game servers behind a proxy.
- [Modpack server from CurseForge or Modrinth](https://www.renode.space/blog/minecraft-modpack-server-curseforge-modrinth) (2026-10-07): Turn a CurseForge or Modrinth modpack into a working server: server packs, manifest.json, .mrpack files, stripping client-only mods, and keeping players in sync.
- [Multiverse-Core: multiple Minecraft worlds](https://www.renode.space/blog/minecraft-multiverse-multiple-worlds) (2026-10-07): Run several worlds on one Paper server with Multiverse-Core: creating and importing worlds, portals, per-world inventories, settings, and what each world costs.
- [MySQL for Minecraft plugins and networks](https://www.renode.space/blog/minecraft-mysql-for-plugins) (2026-10-07): Which Minecraft plugins need MySQL, how to connect LuckPerms, CoreProtect and others, sizing connection pools, and sharing data safely across a network.
- [NeoForge server setup: install to first boot](https://www.renode.space/blog/minecraft-neoforge-server-setup) (2026-10-07): Install a NeoForge Minecraft server step by step: the installer, run.sh and user_jvm_args.txt, Java versions, the first boot, configs and the errors you will hit.
- [Minecraft NPCs: Citizens vs FancyNpcs](https://www.renode.space/blog/minecraft-npcs-citizens-and-fancynpcs) (2026-10-07): Add NPCs to a Minecraft server: Citizens and FancyNpcs compared, skins, click commands, what NPCs cost in tick time, and the problems people hit.
- [Purpur and Pufferfish vs Paper compared](https://www.renode.space/blog/minecraft-purpur-and-pufferfish-forks) (2026-10-07): What Purpur and Pufferfish add on top of Paper, the purpur.yml and pufferfish.yml settings worth knowing, and the real risks of running a fork of a fork.
- [Minecraft rank stores and Tebex: what to sell](https://www.renode.space/blog/minecraft-rank-store-tebex-rules) (2026-10-07): What the Minecraft Usage Guidelines allow in a server store, how to design ranks and crates that pass, and how to wire Tebex packages to LuckPerms safely.
- [Minecraft redstone lag: clocks and hoppers](https://www.renode.space/blog/minecraft-redstone-lag-and-limits) (2026-10-07): What redstone, hoppers, pistons and clocks cost a server, how to find the contraption behind a lag spike, and the Paper settings that keep it in check.
- [Minecraft server security checklist](https://www.renode.space/blog/minecraft-server-security-checklist) (2026-10-07): A Minecraft server security checklist: online-mode and offline risks, whitelist, ops, RCON and query, plugin sources, Log4Shell, proxies and panel accounts.
- [Minecraft Skyblock server: islands and plugins](https://www.renode.space/blog/minecraft-skyblock-server-setup) (2026-10-07): Set up a Skyblock server on Paper: void worlds, BentoBox and other island plugins, island spacing, economy, ore generators and the farms that cause lag.
- [Minecraft villager and mob farm lag](https://www.renode.space/blog/minecraft-villager-and-mob-farm-lag) (2026-10-07): Why villagers and mob farms eat tick time, how to count them, the Paper and Spigot settings that tame them, and farm rules players will actually accept.
- [Minecraft proximity voice chat on a server](https://www.renode.space/blog/minecraft-voice-chat-server-mods) (2026-10-07): Add proximity voice chat to a Minecraft server with Simple Voice Chat: the UDP port, voice_host, config keys, groups, Bedrock limits and running it behind a proxy.
- [Minecraft world backup and restore](https://www.renode.space/blog/minecraft-world-backup-and-restore) (2026-10-07): Which Minecraft server folders to back up, how to take a consistent copy with save-off and save-all, and how to restore a world, one area or one player.
- [Minecraft datapacks: installing and debugging](https://www.renode.space/blog/minecraft-datapacks-guide) (2026-09-21): Install a datapack on a server, get the load order right, survive the 1.21 folder rename, add Vanilla Tweaks, and read the log when a pack does nothing.
- [Minecraft economy: EssentialsX, Vault, shops](https://www.renode.space/blog/minecraft-economy-essentialsx-vault) (2026-09-21): Set up a server economy: what Vault actually does, EssentialsX balances and command costs, shop plugins, a database-backed provider, and stopping inflation.
- [Geyser and Floodgate: Bedrock on Java servers](https://www.renode.space/blog/minecraft-geyser-bedrock-crossplay) (2026-09-21): How Geyser and Floodgate let Bedrock players join a Paper server: the extra UDP port, the config keys, usernames and whitelists, and what does not translate.
- [Minecraft grief protection and anti-cheat](https://www.renode.space/blog/minecraft-grief-protection-and-anti-cheat) (2026-09-21): CoreProtect rollbacks, claim plugins, Paper anti-xray and the honest limits of anti-cheat, plus the free hardening most servers never switch on.
- [Minecraft JVM flags and Java versions](https://www.renode.space/blog/minecraft-jvm-flags-and-java-versions) (2026-09-21): Which Java version each Minecraft release needs, how to size the heap against a container limit, what every flag in Aikar's set does, and what does nothing.
- [LuckPerms guide: groups, nodes and contexts](https://www.renode.space/blog/minecraft-luckperms-guide) (2026-09-21): How to set up LuckPerms groups, inheritance, per-world contexts and the web editor on a Paper server, with the permission nodes you will actually need.
- [Minecraft MOTD, server icon and resource packs](https://www.renode.space/blog/minecraft-motd-icon-and-resource-packs) (2026-09-21): Format a two-line MOTD with colour codes, add a 64x64 server-icon.png, and host, hash and force a resource pack that clients will actually download.
- [Minecraft Paper optimisation: fix your TPS](https://www.renode.space/blog/minecraft-paper-optimization-guide) (2026-09-21): Which Paper config file does what, and the settings that actually raise TPS: view and simulation distance, mob spawning, activation ranges, hoppers and chunks.
- [Minecraft server commands cheat sheet](https://www.renode.space/blog/minecraft-server-commands-cheatsheet) (2026-09-21): Operator commands, target selectors, execute and the gamerules worth changing, with the console rules and the four commands that can lose you a world.
- [Minecraft server.properties: every key](https://www.renode.space/blog/minecraft-server-properties-explained) (2026-09-21): Every key in a Minecraft server.properties file, its default, and what to actually set it to - view distance, difficulty, whitelist, MOTD, RCON and query.
- [Minecraft server setup: Java, jar, EULA and ops](https://www.renode.space/blog/minecraft-server-setup-guide) (2026-09-21): Build a Minecraft Java server from nothing: the right Java version, the server jar, eula.txt, the first start, port 25565, and your first op.
- [Minecraft SMP launch checklist](https://www.renode.space/blog/minecraft-smp-launch-checklist) (2026-09-21): What to settle before you invite anyone to a Minecraft SMP: rules, software, seed and border, server.properties, permissions, protection, backups and the address.
- [Minecraft lag diagnosis with spark](https://www.renode.space/blog/minecraft-spark-profiler-lag-diagnosis) (2026-09-21): Read a spark report properly: MSPT against TPS, the sources and flat views, and how to pin lag on a named plugin, an entity backlog or a chunk load.
- [Minecraft Velocity network: lobby and servers](https://www.renode.space/blog/minecraft-velocity-proxy-network) (2026-09-21): Run several Minecraft servers behind one address with Velocity: modern forwarding, the secret file, backend settings, shared permissions and what breaks.
- [Minecraft web maps: Dynmap, BlueMap, squaremap](https://www.renode.space/blog/minecraft-web-maps-dynmap-bluemap) (2026-09-21): Compare Dynmap, BlueMap and squaremap: default ports and why a web map needs a second port allocation, render cost, disk use, and keeping bases off it.
- [How much RAM does a Minecraft server need?](https://www.renode.space/blog/how-much-ram-does-a-minecraft-server-need) (2026-08-18): A straight answer by player count, view distance and mod load, why a bigger heap stops helping, and how to prove memory is the problem.
- [Modded Minecraft servers without crashes](https://www.renode.space/blog/modded-minecraft-without-the-crashes) (2026-08-04): Forge, NeoForge and Fabric on a server: installing a pack, the Java version matrix, reading a crash report, and the settings that cause most failures.
- [Paper, Fabric or vanilla: which to run](https://www.renode.space/blog/paper-fabric-or-vanilla) (2026-07-28): What each Minecraft server jar is for, plugins versus mods, the Paper forks worth knowing, and how to switch between them without losing the world.
- [Minecraft Bedrock vs Java hosting](https://www.renode.space/blog/minecraft-bedrock-vs-java-hosting) (2026-06-12): Two different programs, not two editions: ports, config files, add-ons versus plugins, sizing, the Geyser bridge, and why worlds do not move between them.
- [Minecraft plugins worth installing](https://www.renode.space/blog/minecraft-plugins-worth-installing) (2026-06-05): The short list that earns its tick time: permissions, protection, logging, backups and a profiler. Plus how to install them and what quietly wrecks a server.
- [Minecraft world border and Chunky pre-gen](https://www.renode.space/blog/minecraft-world-border-and-pregeneration) (2026-05-29): Why chunk generation is the most expensive thing your server does, how to set a world border, and how to pre-generate inside it with Chunky overnight.
- [Minecraft whitelist and permissions](https://www.renode.space/blog/minecraft-whitelist-and-permissions) (2026-05-22): Why operator is not a role, how the whitelist and ops.json really work, and a LuckPerms group ladder that survives a community growing.
- [Upgrading a Minecraft server version safely](https://www.renode.space/blog/minecraft-version-upgrades) (2026-05-15): Worlds convert forward and never back. The Java version each release needs, the upgrade order that works, what breaks plugins, and how to roll back.
- [Minecraft TPS drops: causes and fixes in order](https://www.renode.space/blog/why-tps-drops-and-what-to-do) (2026-03-06): Ticks are a fixed 50 ms budget. What overspends it, how to read MSPT and a spark report to find the real cause, and the fixes ranked by what they cost.
- [SRV records for Minecraft servers](https://www.renode.space/blog/srv-records-for-minecraft) (2025-12-05): How a Java client resolves an SRV record, the exact fields to enter at your registrar, the mistakes that fail silently, and the dig commands that prove it.

---

### All the Mods 10 server setup: files, Java 21 and RAM

Published 2026-10-15 by RE:NODE Team. https://www.renode.space/blog/all-the-mods-10-server-setup

An All the Mods 10 server is the pack's `ServerFiles` zip, Java 21, and one start script. The current release at the time of writing, ATM10 8.2, is Minecraft 1.21.1 on NeoForge `21.1.251` with 464 mods in the server folder; the zip is about 1.2 GB and already contains the NeoForge installer. You unpack it, run `startserver.sh`, accept the EULA, and wait several minutes for the first start. Memory is set in `user_jvm_args.txt`, which ships with `-Xms4G -Xmx8G`. Treat 8 GB of heap as the floor for a small group and put it inside a container with at least 2 GB more than that. Most of the trouble comes from what the script does without telling you, and the rest of this guide goes through it.

The broader ATM picture (which packs exist, how chunk loading slows a server over months, updating safely) is in [All the Mods server: ATM10 and ATM9 setup](https://www.renode.space/blog/minecraft-all-the-mods-server). General modpack handling, such as building a server from a client export, is in [modpack servers from CurseForge or Modrinth](https://www.renode.space/blog/minecraft-modpack-server-curseforge-modrinth). This post goes deeper on the ATM10 install itself: what each file does, what each script line does, and what to change.

#### Downloading the right server files

ATM10 is published on CurseForge. Each release has the client pack as its main file and a separate server pack attached as an additional file, named `ServerFiles-<version>.zip`. For 8.2 that is `ServerFiles-8.2.zip`. On the pack's Files tab, open the release your players are on and look under Additional Files. Do not build a server from the client zip. The server files already have the client-only mods removed, and they come with the scripts and the JVM arguments file.

Match the version exactly. ATM10 has had dozens of releases since it launched (5.x, 6.x, 7.x and now 8.x), and the CurseForge app updates players' clients when a new one appears. A server on 8.1 with players on 8.2 will refuse them, or let them in and then fail on mismatched content. Write the version in your Discord and update server and players on the same day.

There are also spin-offs with their own server files. ATM10 Lite is a smaller pack, ATM10 To The Sky is a skyblock variant, and there is now an Aeronautics edition. Everything below applies to all of them, but the version numbers, mod counts and memory needs are different. Read the start script in whichever zip you download rather than assuming it matches this one.

What is in the 8.2 zip:

| Path | What it is |
| --- | --- |
| `mods/` | 464 jars, client-only mods already removed |
| `config/`, `defaultconfigs/` | Pack configuration; `defaultconfigs/` seeds per-world configs |
| `kubejs/` | Recipe and loot changes the pack depends on |
| `datapacks/` | Pack datapacks, copied into new worlds |
| `neoforge-21.1.251-installer.jar` | The loader installer, so no download is needed |
| `startserver.sh`, `startserver.bat` | Install-and-run scripts for Linux and Windows |
| `user_jvm_args.txt` | Memory and garbage collector flags |
| `server-icon.png` | The icon shown in the server list |

There is no `eula.txt`, no `server.properties` and no world. The first run creates all three.

#### NeoForge and Java 21

Minecraft 1.21.1 needs Java 21, and the ATM10 script checks for it. It runs `java -fullversion`, takes the major version, and refuses to start below 21 with `Minecraft 1.21 requires Java 21 - found Java 17`. If Java is missing altogether you get `Minecraft 1.21 requires Java 21 - Java not found`. The check is `-ge 21`, so a newer Java passes it. NeoForge for 1.21.1 was built and tested against 21, though, and Java 21 is what you should run. On a machine with several Java installs, point the script at the right one with the `ATM10_JAVA` environment variable, set to the full path of the `java` binary.

The loader version is pinned in the first lines of the script:

startserver.sh (8.2):

```bash
NEOFORGE_VERSION=21.1.251
# To use a specific Java runtime, set an environment variable named ATM10_JAVA
# To disable automatic restarts, set an environment variable named ATM10_RESTART to false.
# To install the pack without starting the server, set ATM10_INSTALL_ONLY to true.
```

Do not upgrade NeoForge on your own. Every ATM release pins a build. 8.1 to 8.2 moved from `21.1.249` to `21.1.251`, and the pack was tested on that build. A newer build is usually fine, but when it is not, you get a crash that nobody else on that pack version has seen. [NeoForge server setup](https://www.renode.space/blog/minecraft-neoforge-server-setup) explains the installer and the `libraries/` layout it produces. For an ATM server, the rule is simple: run the build the script names.

#### What startserver.sh actually does

The script is short. Reading it once explains most first-start problems. In order:

1. It checks that Java exists.
2. If there is no `libraries/` folder, it installs NeoForge. It uses the bundled installer if present and downloads it from `maven.neoforged.net` otherwise, then runs `java -jar neoforge-21.1.251-installer.jar -installServer`.
3. If there is no `server.properties`, it writes one with five lines: `allow-flight=true`, `motd=All the Mods 10`, `max-tick-time=180000`, `simulation-distance=5` and `view-distance=8`.
4. If `ATM10_INSTALL_ONLY=true`, it stops there.
5. It checks that Java is at least 21.
6. It starts the server in a loop. When the process exits, it waits 10 seconds and starts it again, unless `ATM10_RESTART=false`.

```diagram
title: What the ATM10 start script does on each run
start = startserver.sh | checks Java
lib = libraries/ present? | skip install if yes
inst = NeoForge installer | -installServer
props = server.properties | written if missing
run = Launch server | java @argfiles nogui
loop = Exit | restart after 10 s
start -> lib
lib -> inst : no
inst -> props
lib -> props : yes
props -> run
run -> loop
loop -> run : restart loop
```

The launch line is the part to understand:

```bash
java @user_jvm_args.txt \
  @libraries/net/neoforged/neoforge/21.1.251/unix_args.txt nogui
```

There is no server jar. The `@` arguments are Java argument files. The first holds your memory and GC flags. The second, written by the installer, holds the classpath and main class for that exact NeoForge build. The version number is part of that path, and that causes the update problem covered under crashes below.

Three behaviours catch people out:

- **The defaults are written only once.** If a `server.properties` already exists, for example from a host's default install or a previous server, the script leaves it alone. You do not get `allow-flight=true` or the 180-second watchdog, and the first jetpack flight kicks a player for flying. Add those lines yourself.
- **The restart loop does not care why the server stopped.** On the very first run the server writes `eula.txt` with `eula=false` and exits, and the script restarts it every 10 seconds, forever, until you edit that file. Under a panel that has its own restart handling, the script's loop and the panel's can also fight. When a panel or systemd supervises the process, set `ATM10_RESTART=false` and let the supervisor do the restarting.
- **Under `set -eu` the script stops on errors**, except the Java line, where the exit code is caught on purpose so the loop can continue. A crashing server therefore restarts quietly every 10 seconds. Read the log, not the uptime.

A clean first install on your own Linux machine looks like this:

```bash
$ mkdir -p /srv/atm10 && cd /srv/atm10
$ unzip ~/ServerFiles-8.2.zip
$ chmod +x startserver.sh
$ ATM10_INSTALL_ONLY=true ./startserver.sh   # install NeoForge, write properties
$ echo "eula=true" > eula.txt                # after reading the EULA
$ ATM10_RESTART=false ./startserver.sh
```

Installing first and accepting the EULA before the real start skips the restart loop, so the server goes straight to building the world.

#### user_jvm_args.txt, line by line

ATM10 ships this file, comments trimmed:

user_jvm_args.txt:

```text
-Xms4G
-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
```

These are the widely used G1 flags tuned for Minecraft, often called Aikar's flags. You only need to touch two lines.

- **`-Xmx` is the heap ceiling.** It is the number that decides whether the pack fits. Raise it for more players or a mature world. Never set it to the whole memory of the machine or container.
- **`-Xms` is the starting heap.** Combined with `-XX:+AlwaysPreTouch`, the JVM claims and touches all of `-Xms` at startup. With the shipped values, 4 GB is committed before a single mod loads. Setting `-Xms` equal to `-Xmx` is common and avoids resizing, but the full heap is then committed from the first second. Make sure the container really has that much plus overhead, or the server is killed during startup instead of an hour later.
- **Leave the G1 flags alone** unless you are measuring. They are reasonable for a heap from 6 to 16 GB. If you go past 12 GB, some guides raise `G1HeapRegionSize` to `16M` and the new-generation percentages, which is a tuning step and not a fix for lag. [JVM flags and Java versions](https://www.renode.space/blog/minecraft-jvm-flags-and-java-versions) explains what each one changes.

There is one rule for where memory is set. If a panel or wrapper also passes `-Xmx` on the command line, two values compete, and the result depends on the order. Pick one place, usually this file, and remove the other.

#### RAM and CPU by player count

The shipped `-Xmx8G` is what the pack's authors consider a working minimum, and that matches experience. Below 8 GB, ATM10 starts, but garbage collection runs constantly once players spread out, and the first busy evening ends in an out-of-memory crash. The container needs more than the heap, because Java also uses memory for metaspace (the classes of 464 mods), thread stacks, direct buffers and the JIT. On a pack this size that overhead is roughly 1.5 to 2.5 GB.

| Players | `-Xmx` in user_jvm_args.txt | Container or plan |
| --- | --- | --- |
| 1-3, fresh world | 8G | 10 GB |
| 4-8, a few bases | 10G | 12-14 GB |
| 8-15, mature world | 12G | 14-16 GB |
| 15+ or heavy automation | 14G+ | 16 GB+, and profile first |

A few notes on the table:

- **Players cost less than worlds.** A player standing still costs little. A player generating new terrain, or a base full of Mekanism and AE2 machines force-loaded around the clock, costs a lot. Four players with large factories can need more than ten who mostly explore pre-generated ground.
- **CPU is the other half.** Minecraft's main tick is one thread, so per-core speed decides how much automation the server can carry before it drops below 20 TPS. Extra cores help chunk generation, garbage collection and networking. Plan on at least two fast cores and three or more for a busy server.
- **More heap is not always better.** A 20 GB heap on a server that uses 9 GB only makes each full collection longer. Size from what spark reports, not from the size of the plan. [How much RAM a Minecraft server needs](https://www.renode.space/blog/how-much-ram-does-a-minecraft-server-need) covers how to read the numbers.

On RE:NODE, the Minecraft tiers that fit ATM10 are Pro at 10 GB and Premium at 14 GB, with 2.5 and 3.5 vCPU. Pro is right for a small group with `-Xmx8G`. Premium suits a busy server with `-Xmx12G`. The 2 to 6 GB tiers will not run this pack, and we would rather say so than sell one for it. If the container reaches its memory limit, the kernel stops it and the server restarts clean rather than swapping, so the headroom between `-Xmx` and the plan is the setting that matters most.

#### Installing on a panel

On a hosted panel the steps are the same, but you run them through the file manager and console instead of a shell. RE:NODE's Minecraft line installs Paper with the matching Java version, the EULA accepted and a world generated. An ATM10 server replaces that install with your own upload. There is no modpack installer, and nothing on the panel reads a CurseForge pack.

1. Take a backup of the default install, then stop the server.
2. Delete the Paper files you do not need: the server jar, `plugins/` and the generated world folders.
3. Upload `ServerFiles-8.2.zip` through the file manager or SFTP and unpack it in place.
4. Edit the existing `server.properties` and add `allow-flight=true` and `max-tick-time=180000`, because the script will not write them over an existing file.
5. Set memory in `user_jvm_args.txt` so `-Xmx` sits 2 GB or more under the plan.
6. Make sure the startup runs the ATM script, or the same `java @user_jvm_args.txt @libraries/...` line, with `ATM10_RESTART=false` so the panel controls restarts. If the Startup tab does not expose what you need, open a ticket and ask.
7. Start the server and watch the console until `Done`.

[SFTP and the file manager](https://www.renode.space/blog/sftp-and-the-file-manager) has the connection details. A 1.2 GB upload is more reliable over SFTP than through a browser on a slow line.

#### Pre-generating the world

The ATM10 server files include spark and FTB Chunks, but not a pre-generator. Terrain in this pack is expensive, with extra ores, modded structures and several added dimensions. Players exploring on jetpacks or elytra generate chunks faster than one tick thread can handle, and everybody feels the stutter. Pre-generating moves that work to a time when nobody is online.

Chunky has a NeoForge build for 1.21.1 and runs on the server only, so players do not need it. Add the jar to `mods/`, restart, and run:

```text
/chunky world minecraft:overworld
/chunky center 0 0
/chunky radius 4000
/chunky start
/chunky worldborder
```

`/chunky pause` and `/chunky continue` let you stop at the start of play and resume overnight. Progress survives a restart. On ATM10, a 4,000-block radius takes hours rather than minutes, and the region files grow by several gigabytes. Run it with nobody online and check free disk before you begin. Use tab completion on `/chunky world` to pre-generate the Nether, the End and whichever modded dimensions your players live in. Leave mining dimensions alone, since they are meant to be reset. [World borders and pre-generation](https://www.renode.space/blog/minecraft-world-border-and-pregeneration) covers timing and file sizes in more detail.

Also check the item-clear setting. The pack ships Crash Utilities with item clear switched on in `config/crashutilities-server.toml`. Every 5 minutes, if more than 1,000 dropped items are loaded, it warns in chat and deletes them all. That keeps entity lag down. It also surprises players who lose a dropped stack, so tell them, or raise `maximum` if your group would rather keep the items.

#### Common crash causes and fixes

**The console stops mid-line with no crash report.** The process was killed from outside, almost always for memory. `-Xmx` plus overhead went over the container limit, often during world generation or startup with a large `-Xms`. Lower the heap or move up a plan. A real Java out-of-memory error, by contrast, prints `java.lang.OutOfMemoryError` and usually writes a crash report.

**`Error: could not open 'libraries/net/neoforged/neoforge/<version>/unix_args.txt'`.** You updated the pack to a release with a newer NeoForge build. The script saw an existing `libraries/` folder and skipped the installer, then tried to launch a build that is not installed. Run the installer by hand (`java -jar neoforge-<version>-installer.jar -installServer`), or delete `libraries/` and run the script so it installs fresh.

**`has been compiled by a more recent version of the Java Runtime (class file version 65.0)`.** The server is running on Java 17 (class file version 61). Class version 65 is Java 21. Switch the runtime, or set `ATM10_JAVA`.

**The server restarts every 10 seconds and nobody can join.** Either `eula.txt` still says `false`, or the server crashes on start and the script's loop hides it. Scroll up to the first error after the restart message.

**`Failed to bind to port` on start.** Another process, often a second copy left running by a double restart loop, holds port 25565. Stop everything, confirm nothing is running, and start once. On a panel, use the port the plan assigns, not a value copied from a guide.

**The watchdog kills the server during heavy generation.** You see `A single server tick took 60.00 seconds` and a thread dump. `max-tick-time` is still at the vanilla `60000` because the script never wrote its default. Set `180000`. Do not set `-1`, which lets a truly hung server hang forever.

**The server crashes when someone enters one area.** A block entity in that chunk crashes on every tick. The crash report names the block and its coordinates. Restore that region from a backup or remove the block. [Chunk errors and world corruption](https://www.renode.space/blog/minecraft-chunk-errors-and-world-corruption) covers the tools, and [crash reports explained](https://www.renode.space/blog/minecraft-crash-reports-explained) shows how to find the guilty mod in a stack trace.

**Missing registry entries after an update.** A release removed a mod, and the world still contains its blocks. NeoForge warns at load, and confirming deletes them permanently. Read the changelog before updating, and keep the backup from before the update until you are sure.

> [!WARNING]
> Update with the server stopped. Replace `mods/`, `config/`, `defaultconfigs/` and `kubejs/` completely rather than copying over them. Keep `world/`, `server.properties`, the player lists and your own `user_jvm_args.txt`. If the NeoForge version in the new `startserver.sh` changed, run the installer before the first start.

Take that backup somewhere other than the server's own disk. On RE:NODE, backup slots come with every plan, are stored off the machine, restore with one button, and can be locked so rotation does not delete the pre-update copy while you test. [Backups that actually restore](https://www.renode.space/blog/backups-that-actually-restore) explains why you should test a restore before you need one.

#### FAQ

##### What Java version does an All the Mods 10 server need?

Java 21. ATM10 is Minecraft 1.21.1, and the start script refuses to run on anything older. A newer Java passes the script's check, but the pack and NeoForge are tested on 21, so use 21.

##### Is 6 GB enough for an ATM10 server?

Not for real play. With a 6 GB container, the heap would have to sit near 4 GB once overhead is counted. The pack loads, but garbage collection takes over as soon as players explore. Use an 8 GB heap in a container of 10 GB or more.

##### Do I need to download NeoForge separately?

No. The 8.2 server files include the NeoForge installer, and the script runs it on the first start. Running it again is only needed when a pack update moves to a new NeoForge build.

##### Where do I change the server's RAM?

In `user_jvm_args.txt`: the `-Xmx` line for the ceiling and `-Xms` for the starting heap. If your panel also sets memory on the command line, use one or the other, not both.

##### Can I run the server without the restart loop?

Yes. Set the environment variable `ATM10_RESTART=false`, and the script exits when the server stops. Do this whenever a panel, systemd or another supervisor already restarts the server.

##### Can players join ATM10 To The Sky or ATM10 Lite on the same server?

No. Each is a different pack with its own server files and mod list. Players must run the same pack and the same version as the server.

RE:NODE Minecraft plans run Paper by default and go up to 14 GB with 3.5 vCPU. An ATM10 server is your own upload, which the file manager unpacks in place. Every plan includes SFTP, an unfiltered console for the long first start, and off-machine backup slots that restore with a button.

[See Minecraft plans](https://www.renode.space/game-servers/minecraft)

---

### All the Mods 9 vs 10: which to run on a server

Published 2026-10-15 by RE:NODE Team. https://www.renode.space/blog/all-the-mods-9-vs-10

For a new group server in 2026, pick All the Mods 10 unless you have a specific reason not to. It runs on NeoForge for Minecraft 1.21.1 with Java 21, it is the pack the All the Mods team is actively developing, and it has the newer vanilla content. All the Mods 9 runs on Forge for Minecraft 1.20.1 with Java 17, and it is the right choice in three cases: your group already has an ATM9 world worth keeping, a mod you care about only exists in the 1.20.1 version, or your players want a pack whose quest line and balance have had years to settle. The hardware cost is similar - both want an 8 GB heap as a floor and more for a busy group - with ATM10 a little heavier because it carries more mods. And there is no upgrade path between them: an ATM9 world does not become an ATM10 world, so the choice you make on day one is the one you live with.

The practical side of running either pack - server files, start scripts, chunk loading, pre-generation, updating without losing the world - is in the [All the Mods server guide](https://www.renode.space/blog/minecraft-all-the-mods-server). This post is about choosing between the two, and about the parts of an ATM9 setup that differ from ATM10.

#### The two packs side by side

Both are "kitchen sink" packs: a very large collection of tech, magic, exploration and storage mods, tied together by a quest book and an end-game item, the ATM Star, that needs a bit of nearly everything. The skeleton is the same. The base underneath is not.

| | All the Mods 9 | All the Mods 10 |
| --- | --- | --- |
| Minecraft | 1.20.1 | 1.21.1 |
| Loader | Forge (47.x line) | NeoForge (21.1.x line) |
| Java | 17 | 21 |
| Mods | Roughly 400+ | Roughly 450-500 |
| State | Mature, slower updates | Active development |

Mod counts move with every release and are only a rough guide; the pack's CurseForge page shows the current list for each version. The loader version is pinned by each pack release too. Use the version the server files install and never upgrade Forge or NeoForge on its own.

Both packs have side variants worth knowing about when you choose:

- **To the Sky** - a skyblock version of each pack (ATM9 To the Sky, ATM10 To the Sky). World generation is close to free, so these run noticeably lighter. See [skyblock server setup](https://www.renode.space/blog/minecraft-skyblock-server-setup) for the general approach.
- **Lighter cuts** - ATM9 has a "No Frills" variant and ATM10 has a "Lite" variant, both trimming the mod list. If your hardware is tight or your group finds the full pack overwhelming, look at these before cutting mods yourself.

Everything below is about the main packs, but the same reasoning applies to the variants.

#### What actually changes in play

Most of the mods your group has heard of are in both: Create, Applied Energistics 2, Mekanism, Botania, Ars Nouveau, Twilight Forest, the Allthemodium ores and dimensions, and the usual storage and utility mods. A player who knew ATM9 will recognise most of ATM10 within an hour. The differences that matter are smaller and more specific.

##### Vanilla content

ATM10 sits on 1.21.1, so it has everything Mojang added between 1.20.1 and 1.21: trial chambers and the trial spawner, the breeze and the bogged, the mace, the crafter block, armadillos and wolf armour. ATM9 on 1.20.1 has cherry groves, archaeology, the sniffer and camels, but none of the 1.21 content. For a group that plays modded mostly for the mods this is a minor point. For a group that wants the newest vanilla structures to explore, it settles the question.

##### Mod versions and availability

Not every mod made the jump to NeoForge 1.21.1, and some mods changed substantially when they did. A few practical consequences:

- **A favourite niche mod may be 1.20.1 only.** If one player's whole reason for joining is a specific mod, check that it is in the ATM10 list before you commit. Adding a 1.20.1 Forge mod to a 1.21.1 NeoForge pack is not possible.
- **Recipes and progression were reworked.** ATM10's quest book and ATM Star recipe are not a copy of ATM9's. Players who finished ATM9 should expect a familiar shape with different details.
- **Mod behaviour on the newer version can differ.** Machines that were lag-free in one version can be heavier in the other, and the reverse. There is no general rule, which is why profiling on your own server (covered below) beats any forum claim.

##### Maturity

ATM9 has had a long run. Most of its crash bugs and balance problems were found and fixed by the thousands of servers that ran it, and its quest line is complete. ATM10 has been the main pack for a while now and is stable for normal play, but it still receives mod updates and changes more often - which is both the benefit (fixes and new content) and the cost (more frequent updates to manage on a server).

#### RAM and CPU cost

The two packs cost about the same to host. ATM10 is somewhat heavier at startup and in memory because it loads more mods, and Java 21 does not change that much in either direction. The real driver of cost on both is the world, not the pack: how much has been generated, how many chunks are force-loaded, and what is running in them.

| Players | Heap (`-Xmx`) | Plan / container |
| --- | --- | --- |
| 1-3, new world | 8 GB | 10 GB |
| 4-8 | 10 GB | 12 GB |
| 8-15, mature world | 12 GB | 14 GB or more |

These figures hold for both packs. The ATM10 server files set `-Xmx8G` in `user_jvm_args.txt`; check what the ATM9 server files you download set, and raise it if it is lower than the table. The gap between heap and container is deliberate. Java uses memory outside the heap - metaspace for the classes of several hundred mods, thread stacks, buffers - and on packs this size that is one to two gigabytes. A heap set to the full plan gets the process killed from outside during chunk generation, with no crash report. [How much RAM a Minecraft server needs](https://www.renode.space/blog/how-much-ram-does-a-minecraft-server-need) has the arithmetic.

user_jvm_args.txt:

```text
-Xms4G
-Xmx10G
```

CPU is where both packs hurt. Minecraft runs each dimension's tick on one thread, and kitchen-sink packs put a lot of work in that tick: machines, pipes, block entities, mob farms. Clock speed matters more than core count, though a second and third core help with chunk generation, garbage collection and networking. As a rough guide, plan two fast cores for a small group and three or more for a busy server. [CPU vs RAM for game servers](https://www.renode.space/blog/cpu-vs-ram-for-game-servers) explains how to tell which one you are short of before paying for more.

Startup time differs more than steady-state cost. ATM10 loads more mods and more recipes, so a cold start takes longer - several minutes on the first start, two or three afterwards on good hardware, with ATM9 usually a little quicker. That matters for scheduled restarts: a nightly restart on either pack means a few minutes of downtime, not a few seconds.

Disk is similar for both: the server files unpack to over a gigabyte, more after the loader installs its libraries, and a mature world with several explored dimensions runs to several gigabytes before backups. Plan generously.

#### Stability and updates

Stability on a big modded server comes mostly from two things you control - leaving headroom on memory and not letting the world grow unbounded - and one you do not: how many bugs the pack version still has.

On that last point ATM9 has the edge. It has been played for a long time, its last releases changed little, and a server that is set up properly tends to stay up. The trade-off is that you get few new fixes; if you hit a bug in a mod's 1.20.1 version, it may never be patched.

ATM10 moves faster. Updates bring mod fixes and sometimes new mods, and they occasionally bring new problems. On a server that means:

- **Do not update on release day.** Wait a few days, read the issues players report, then update.
- **Back up before every update** and keep that backup until the new version has run cleanly for a week.
- **Update server and players together.** A client launcher that auto-updates before the server is the most common cause of "mod rejections" on join.

The update procedure itself - replace `mods/`, `config/`, `defaultconfigs/` and `kubejs/` from the new server files, keep `world/` and your own settings - is the same for both packs and is laid out in the [All the Mods server guide](https://www.renode.space/blog/minecraft-all-the-mods-server). When an update goes wrong, [what to do when a mod update breaks](https://www.renode.space/blog/what-to-do-when-a-mod-update-breaks) is the recovery plan.

> [!WARNING]
> Removed mods take their blocks with them. If a pack update drops a mod, everything built from it vanishes from the world on the next start. Read the changelog for removals before updating, on either pack.

#### Which one to pick for your group

Most groups can decide from one of these situations.

**A new group, no existing world.** ATM10. It is the current pack, it has the newer vanilla content, and your server will keep getting fixes for the life of the world.

**You already have an ATM9 world.** Stay on ATM9 for that world. The world cannot move to ATM10 (see the next section), and a long-running server's value is the builds in it. Start an ATM10 server alongside it if people want the new pack, but do not shut down a world your group is still playing.

**Players who finished ATM9 and want something new.** ATM10. The quests and the Star recipe are different enough to be a fresh run.

**Small hardware budget.** Either pack's lighter variant, or a To the Sky version. Cutting a full kitchen-sink pack down to fit a small plan rarely works well; the variants were built for exactly that.

**A specific mod that only exists on 1.20.1.** ATM9. Check before you decide, not after the world is a month old.

**Players with weaker PCs.** The client side matters too. Both packs want around 8 GB allocated to the game on a player's machine and a reasonably quick CPU. ATM10's extra mods make it a little heavier to load. If several players are on older laptops, a lighter variant is kinder to them than either main pack.

Whatever you pick, decide it as a group before the first start and write the exact pack version in your Discord. "ATM10" is not a version; "ATM10 5.2" is.

#### Why an ATM9 world cannot be upgraded to ATM10

This is the question that comes up most, and the answer is simple: you cannot convert an ATM9 world into an ATM10 world in any way that keeps the modded content. Vanilla Minecraft upgrades worlds from 1.20.1 to 1.21.1 itself, but a modded world is mostly modded data, and that is where it breaks:

- **Different loader.** ATM9 runs Forge, ATM10 runs NeoForge. On 1.21.1 these are separate ecosystems; mods were rebuilt, and many changed how they store their data.
- **Changed item storage.** Minecraft 1.20.5 replaced item NBT with data components. Vanilla migrates its own items; mods have to handle their own, and in a pack of several hundred mods many do not migrate 1.20.1 data at all.
- **Removed and renamed content.** Blocks, items and entities that were renamed, merged or dropped between versions simply disappear when the world loads. Machines lose their contents, storage networks lose their items.
- **New world generation.** Chunks generated by ATM9 would sit next to ATM10 terrain with hard seams, and modded structures and ores would be wrong in every chunk already generated.

The All the Mods team does not support moving a world between major pack versions, and the honest summary is that the result, if it loads at all, is a world with broken bases. The same goes in reverse, and the same goes for any other pair of major modded versions - see [Minecraft version upgrades](https://www.renode.space/blog/minecraft-version-upgrades) for what vanilla and plugin servers can and cannot carry forward.

What you can carry over:

- **Player memories and screenshots.** Not a joke - the most common outcome is a final "last day" event on the old world, then a fresh start.
- **Server settings.** `server.properties`, `whitelist.json`, `ops.json` and `banned-players.json` use the same formats and can be copied across.
- **Builds, with effort.** A schematic tool can save a build's vanilla blocks and paste them into the new world. Modded blocks in the schematic will not survive unless the same mod with the same block exists in ATM10, and even then their contents usually do not.

> [!NOTE]
> Keep the ATM9 world. Stop the server, take a full backup, download it, and keep it. Groups ask to visit old worlds more often than you would expect, and you can start it again any time on ATM9 server files of the same version.

#### ATM9 server setup basics

Setting up ATM9 follows the same pattern as ATM10, with Forge in place of NeoForge and Java 17 in place of 21. The short version:

1. On the ATM9 CurseForge page, open the files list, pick the release your players will use, and download its server files from the additional files.
2. Unpack it into an empty server folder. You get `mods/`, `config/`, `defaultconfigs/`, `kubejs/`, a `startserver.sh` and `startserver.bat`, and `user_jvm_args.txt`.
3. Make sure the server runs Java 17. Forge for 1.20.1 targets it; running it on a different Java version is a common source of startup failures. [JVM flags and Java versions](https://www.renode.space/blog/minecraft-jvm-flags-and-java-versions) shows how to check which one is in use.
4. Set the heap in `user_jvm_args.txt` to suit the table above.
5. Run the start script. On first run it installs Forge and its libraries, then starts the server. Accept the EULA in `eula.txt` and start again.
6. Wait through the first start; it generates configs and the world and takes several minutes.

```bash
$ unzip ServerFiles-<version>.zip -d /srv/atm9
$ cd /srv/atm9
$ java -version
$ chmod +x startserver.sh
$ ./startserver.sh
```

Two `server.properties` lines matter on ATM9 exactly as on ATM10:

server.properties:

```properties
allow-flight=true
max-tick-time=180000
```

`allow-flight=true` stops vanilla kicking players for flying with jetpacks and flight items. `max-tick-time` raises the watchdog from its default of 60 seconds so a heavy chunk generation does not kill the server. Use `/forge tps` on ATM9 (on ATM10 it is `/neoforge tps`) to see tick time per dimension. [server.properties explained](https://www.renode.space/blog/minecraft-server-properties-explained) has the rest of the file, and [NeoForge server setup](https://www.renode.space/blog/minecraft-neoforge-server-setup) covers how the ATM10 side installs if you are running both.

On RE:NODE the Minecraft line installs Paper by default, so either ATM pack is your own upload: there is no one-click modpack installer and nothing in the panel reads a CurseForge pack. The file manager unpacks the server files zip in place, the console shows the long first start unfiltered with memory and CPU graphs against your plan's limits, and the Startup tab is where the launch variables go. Backup slots on every plan are stored off the machine and restore with a button - which is what you want before every pack update.

#### Running both on one budget

Some groups want to keep the ATM9 world alive while starting ATM10. Two kitchen-sink servers running side by side need two full sets of memory; there is no sharing between them. Options that do not double the bill:

- **Archive the ATM9 world.** Back it up, stop the server, and only start it for events.
- **Run ATM9 on a smaller plan with fewer players.** A world that only gets visited occasionally needs less CPU, though it still needs its 8 GB heap to load at all.
- **Turn off force-loaded chunks on the old world.** If nobody is playing it, nothing needs to tick while they are away. In FTB Chunks, force-loading can be limited per player in the server config.

The second server also needs its own port. Players connect to each by address and port, or by a hostname with an SRV record - see [SRV records for Minecraft](https://www.renode.space/blog/srv-records-for-minecraft) for giving each server a clean name.

#### FAQ

##### Is ATM10 harder to run than ATM9?

Slightly. It loads more mods, so it starts more slowly and uses a bit more memory, but the difference is small next to what a mature world with many force-loaded bases costs on either pack. Plan the same plan size for both and let the world, not the pack, decide when you need more.

##### Can I use Java 21 for ATM9?

Forge for 1.20.1 targets Java 17, and that is what to use unless the pack's release notes say otherwise. Some setups run on newer Java, but when a 1.20.1 pack fails at startup with a class or module error, the wrong Java version is the first thing to rule out.

##### Can players on ATM9 join an ATM10 server?

No. The client and server must run the same pack at the same version. A player on ATM9 connecting to an ATM10 server is refused with a list of mismatched mods, and so is a player on a different ATM10 release.

##### Will ATM9 keep getting updates?

It has had a long run and its updates have slowed; ATM10 is where development is. Check the files page on CurseForge for the latest release date before planning a long server around ATM9, and expect fixes for 1.20.1-only bugs to be rare.

##### Should I wait for All the Mods 11 instead?

Only if your group would not start a world for months anyway. A new major pack takes a long time to settle, and early versions change often. A group that wants to play now is better served by ATM10 today than by an unfinished successor.

RE:NODE Minecraft plans go up to 14 GB of memory with CPU that scales with the tier; ATM9 or ATM10 is your own upload, unpacked in place in the file manager. Backup slots on every plan restore with a button, so the old world can stay archived while the new one starts.

[See Minecraft plans](https://www.renode.space/game-servers/minecraft)

---

### How to set up BungeeCord: jar, config.yml and backends

Published 2026-10-15 by RE:NODE Team. https://www.renode.space/blog/bungeecord-setup-guide

Setting up BungeeCord takes four steps: download `BungeeCord.jar` from md_5's build server, start it once so it writes `config.yml`, point that file at your backend servers, and change three settings on each backend so it accepts players through the proxy and nobody else. The first three take ten minutes. The fourth is where networks get broken into, because a BungeeCord backend trusts whatever identity a connection claims, so it has to be unreachable from the internet or protected by BungeeGuard.

Before you start, one honest note. For a brand new network, Velocity is the better proxy: it is faster, PaperMC maintains it, and its modern forwarding protects backends without a firewall. [BungeeCord vs Velocity](https://www.renode.space/blog/minecraft-bungeecord-vs-velocity) explains the difference, and [the Velocity network guide](https://www.renode.space/blog/minecraft-velocity-proxy-network) is the setup if you go that way. BungeeCord is still maintained, still widely run, and the right choice when a plugin you depend on only exists for it. If that is you, this is the setup, done properly.

#### What BungeeCord does, and what it does not

BungeeCord is a proxy that speaks the Minecraft protocol. Players connect to it, it authenticates them with Mojang once, then opens its own connection to a backend server and relays packets both ways. Typing `/server survival` makes the proxy drop the lobby connection and open one to survival while the player's own connection stays up. That is the whole trick: several separate Minecraft servers, one address, no disconnect between them.

It holds no world, ticks no entities and runs no Bukkit plugins. That has three consequences people discover the hard way:

- **Plugins do not cross over.** Paper and Spigot plugins go on the backends. Only BungeeCord plugins - built against the BungeeCord API - go in the proxy's `plugins` folder.
- **Player data is per backend.** Inventories, homes, balances and `ops.json` live on each backend separately. The proxy shares none of it.
- **It does not translate versions.** The client and the backend it lands on must speak the same protocol. BungeeCord accepts a wide range of client versions at its own door, but a 1.21 client still cannot play on a 1.20 backend unless ViaVersion sits somewhere in the chain.

It also does not make a laggy world faster. If one survival world is struggling, a proxy adds a hop and changes nothing else. A proxy is for several distinct servers under one name.

```diagram
title: One public port, backends reachable only by the proxy
players = Players | Java edition
proxy = BungeeCord | public :25565
lobby = Lobby | 127.0.0.1:25566
survival = Survival | 127.0.0.1:25567
creative = Creative | 127.0.0.1:25568
players -> proxy : TCP 25565
proxy -> lobby : ip_forward
proxy -> survival
proxy -> creative
```

#### Requirements and sizing

The proxy is light. It spends CPU on compression and encryption and very little memory on anything else.

| Network size | Proxy heap | Proxy CPU |
| --- | --- | --- |
| Up to 50 players | 256-512 MB | Under one core |
| 50-300 players | 512 MB - 1 GB | One core |
| 300+ players | 1-2 GB | One to two cores |

Run it on a current Java. The jar has historically been undemanding, but recent builds track modern Java, and since your Paper backends need Java 21 for current Minecraft versions anyway, use Java 21 for the proxy too and keep one runtime to think about. [Minecraft JVM flags and Java versions](https://www.renode.space/blog/minecraft-jvm-flags-and-java-versions) covers which Java goes with which game version.

The money goes on the backends. A network of a proxy, a lobby and two gamemodes is four processes, each with its own memory limit, and the lobby should be the smallest of the backends because it simulates almost nothing.

#### Downloading the official BungeeCord.jar

BungeeCord has one official source: md_5's Jenkins build server at `ci.md-5.net`, linked from the SpigotMC site. The file is called `BungeeCord.jar` and the latest successful build is always at a stable path:

```bash
$ mkdir -p ~/network/proxy && cd ~/network/proxy
$ wget -O BungeeCord.jar \
    https://ci.md-5.net/job/BungeeCord/lastSuccessfulBuild/artifact/bootstrap/target/BungeeCord.jar
```

There is no installer and no BuildTools step - unlike Spigot itself, the proxy jar is distributed ready to run. Avoid "BungeeCord download" mirrors on random hosting sites. Some are simply stale; some have shipped modified jars. If a page offers you a BungeeCord jar with a version number in the file name, it did not come from md_5.

Waterfall, the fork you will still see recommended in older tutorials, is no longer developed. Do not start a new network on it.

#### First start and the files it creates

Start the proxy once with a small heap:

```bash
$ java -Xms512M -Xmx512M -jar BungeeCord.jar
```

It generates its files, binds to its default port and waits. Type `end` in the console to stop it cleanly. You now have:

| File or folder | What it is |
| --- | --- |
| `config.yml` | The whole proxy configuration |
| `modules/` | Built-in command modules (`cmd_server`, `cmd_list`, `cmd_send` and so on) |
| `modules.yml` | Where the modules are fetched from |
| `plugins/` | BungeeCord plugins, empty at first |
| `proxy.log.0` | The current log, rotated to `.1`, `.2` |

Two defaults in the generated file catch nearly everyone. The listener binds to port `25577`, not `25565`, and the example server entry points at `localhost:25565`. That arrangement assumes you will move your existing Minecraft server off `25565` and put the proxy in front of it on a different port - most people want the opposite, so change both. The default `max_players` on the listener is `1`, which only affects the number shown in the server list, but it makes a working network look broken.

#### config.yml, key by key

This is a complete, working configuration for a proxy with three backends on the same machine. Comments mark the keys you must change.

config.yml:

```yaml
online_mode: true
ip_forward: true
network_compression_threshold: 256
connection_throttle: 4000
connection_throttle_limit: 3
player_limit: -1
timeout: 30000
log_commands: false
log_pings: false
prevent_proxy_connections: false
listeners:
- host: 0.0.0.0:25565
  motd: '&bThe Longhouse Network'
  max_players: 200
  tab_list: GLOBAL_PING
  tab_size: 60
  force_default_server: true
  priorities:
  - lobby
  forced_hosts:
    survival.example.com: survival
  ping_passthrough: false
  query_enabled: false
  query_port: 25565
  proxy_protocol: false
  bind_local_address: true
servers:
  lobby:
    address: 127.0.0.1:25566
    motd: 'Lobby'
    restricted: false
  survival:
    address: 127.0.0.1:25567
    motd: 'Survival'
    restricted: false
  creative:
    address: 127.0.0.1:25568
    motd: 'Creative'
    restricted: false
```

##### The listener block

`listeners` is a list, and almost every network has exactly one entry.

- `host` is the address and port the proxy binds. `0.0.0.0:25565` means every interface on the standard port. On a panel host it must match the allocation you were given.
- `motd` and `max_players` are what the server list shows. Colour codes use `&`.
- `priorities` is the ordered list of servers a player is tried against on login. The first that accepts them wins. Every name here must exist under `servers`, spelled identically, or players get the fallback error in the troubleshooting section.
- `force_default_server: true` sends every player to the first priority server on every login. With `false`, BungeeCord's reconnect module sends them back to the last server they were on, which is what you want for a survival-first network and not for a lobby-first one.
- `forced_hosts` maps the hostname a player typed to a server, so `survival.example.com` skips the lobby. Each hostname needs DNS pointing at the proxy.
- `ping_passthrough: true` shows a backend's MOTD and player count in the list instead of the proxy's own. Leave it `false` unless you have a reason.
- `tab_list` is `GLOBAL_PING`, `GLOBAL` or `SERVER`. `SERVER` lets each backend control its own tab list, which is what tab plugins on the backends expect.
- `proxy_protocol: true` is only for when something like HAProxy or a TCP load balancer sits in front of BungeeCord and sends PROXY protocol headers. Turn it on without that and every connection fails.

##### Global keys

- `online_mode: true` - the proxy authenticates players with Mojang. Leave this on. Turning it off creates a cracked network where anyone can log in as anyone.
- `ip_forward: true` - passes each player's real IP, UUID and skin to the backends. Off by default, and with it off every player arrives on the backends with the proxy's address and an offline-mode UUID. Turn it on; it pairs with the backend setting in the next section.
- `network_compression_threshold: 256` - packets above this many bytes are compressed. The default is right for traffic to players.
- `connection_throttle` and `connection_throttle_limit` - how many logins one IP may make inside the window, in milliseconds. Raise the limit if many players share one address, such as a school or a LAN party.
- `player_limit: -1` - a hard cap across the whole proxy, `-1` for none. Different from `max_players`, which is only the displayed number.
- `timeout: 30000` - milliseconds before an unresponsive connection is dropped.

##### The servers block

Each entry is a name, an `address` and a `restricted` flag. The name is what `/server <name>` and `priorities` use, and what plugins on the backends use when they send players around, so pick short, lowercase names and never rename them casually. `restricted: true` means a player needs the `bungeecord.server.<name>` permission to connect - useful for a staff-only build server.

##### Query and the built-in permissions

`query_enabled` turns on the GameSpy4 query protocol that some server-list sites and status bots use, on UDP `query_port`. Most networks leave it off. If you enable it, the port is UDP, and on a host with fixed allocations it has to be one you actually have - [game server ports explained](https://www.renode.space/blog/game-server-ports-explained) covers why query ports exist.

The generated file also contains a `groups` block with `md_5` as an example admin, and a `permissions` block that gives the `default` group `/server` and `/glist`. This tiny built-in system works, but it knows nothing about ranks. Remove the `md_5` entry, add your own username to `admin` if you want, and plan to replace it with LuckPerms on the proxy - [the LuckPerms guide](https://www.renode.space/blog/minecraft-luckperms-guide) shows how to scope proxy permissions with a `server` context.

#### What to change on every backend

Each backend is an ordinary Spigot or Paper server. Three files change.

server.properties (backend):

```properties
server-ip=127.0.0.1
server-port=25566
online-mode=false
```

spigot.yml (backend):

```yaml
settings:
  bungeecord: true
```

bukkit.yml (backend):

```yaml
settings:
  connection-throttle: -1
```

Why each one:

- `online-mode=false` is required. The proxy already authenticated the player; a backend in online mode would try to do it again, and the proxy refuses with `Server is online mode!`.
- `bungeecord: true` in `spigot.yml` makes the backend read the forwarded IP and UUID that `ip_forward` sends. Without it, players get offline-mode UUIDs and lose their data the moment you fix it later.
- `connection-throttle: -1` in `bukkit.yml` stops the backend rate-limiting logins. Every login comes from the proxy's address, so the backend's own throttle would otherwise kick legitimate players during busy moments with "Connection throttled".

On Paper, also check `config/paper-global.yml` (or `paper.yml` before 1.19): `proxies.bungee-cord.online-mode` should be `true`, telling Paper the identities arriving through the proxy were verified. Plugins that care about premium accounts read it.

Each backend needs its own port, and every backend must run the same Minecraft version as the clients that reach it, or carry ViaVersion. Restart the backends after these changes; `spigot.yml` is not reloaded live. [server.properties explained](https://www.renode.space/blog/minecraft-server-properties-explained) covers the other settings worth trimming on a lobby, such as `view-distance` and `spawn-protection`.

#### Firewalling the backends

Here is why this matters. A backend with `online-mode=false` and `bungeecord: true` believes any handshake that claims to carry forwarded data. Anyone who can reach its port can connect with a crafted handshake saying they are your operator, and the backend lets them in with that player's UUID, permissions and inventory. Public tools do exactly this, and scanners find open backends quickly.

> [!WARNING]
> After setting up, try to join each backend directly by its own address and port. If you get in, the network is open to anyone pretending to be anyone. Do not announce the address until every backend refuses you.

There are three ways to close the hole, in order of strength.

1. **Bind to localhost.** When the proxy and the backends share a machine, `server-ip=127.0.0.1` on each backend makes them unreachable from outside. This is the simplest and best option, and it is what the example config above uses.
2. **Firewall the ports.** When backends are on other machines, allow their ports only from the proxy's address, and deny everyone else. The `ufw` example below does this.
3. **BungeeGuard.** When you cannot firewall - on most shared panel hosts each server is a separate container with its own public port - install BungeeGuard on the proxy and on every backend. The proxy plugin generates a secret token and adds it to forwarded data; the backend plugin holds that token in its `allowed-tokens` list and rejects connections without it. It is the same idea as Velocity's modern forwarding, bolted on.

For option 2, on a backend whose proxy lives at `203.0.113.10`, the rule order matters - `ufw` applies the first match, so the allow goes in before the deny:

```bash
$ sudo ufw allow from 203.0.113.10 to any port 25566 proto tcp
$ sudo ufw deny 25566/tcp
```

On RE:NODE every server, proxy or backend, is its own container with its own public allocation, so option 1 and option 2 are not available to you between servers. BungeeGuard on the proxy and every backend is the setup to use there, and the direct-join test above is how you confirm it works. The broader list of things to lock down is in [the Minecraft server security checklist](https://www.renode.space/blog/minecraft-server-security-checklist).

#### Running it, plugins and commands

Start the backends first, then the proxy. Order is not strictly required, but a proxy that starts with no backend up will kick the first players with the fallback error.

```bash
$ java -Xms512M -Xmx512M -XX:+UseG1GC -jar BungeeCord.jar
```

Proxy plugins go in `plugins/` as jars, and the proxy has to be restarted to load them. BungeeCord has a `/greload` command, but it does not reload plugins and has never been reliable for much beyond the server list - most admins restart the proxy instead, which disconnects everyone, so batch changes and restart at a quiet hour. Typical proxy plugins are LuckPerms (BungeeCord build), BungeeGuard, ViaVersion if you want it on the proxy, Geyser and Floodgate for Bedrock players ([Geyser and Bedrock crossplay](https://www.renode.space/blog/minecraft-geyser-bedrock-crossplay)), and a network chat or ban plugin. Check each download page says BungeeCord, not Spigot - a Bukkit plugin in the proxy's folder fails to load with an error at startup.

| Command | Permission | Effect |
| --- | --- | --- |
| `/server <name>` | `bungeecord.command.server` | Move yourself |
| `/glist` | `bungeecord.command.list` | Players on each server |
| `/send <player> <server>` | `bungeecord.command.send` | Move someone else |
| `/find <player>` | `bungeecord.command.find` | Which server they are on |
| `/alert <message>` | `bungeecord.command.alert` | Broadcast to the network |
| `/ip <player>` | `bungeecord.command.ip` | Show a player's address |
| `/greload` | `bungeecord.command.reload` | Re-read `config.yml` |
| `end` | `bungeecord.command.end` | Stop the proxy (console) |

Backend plugins that send players between servers - selector menus, lobby signs, minigame return-to-lobby - talk to the proxy over the `BungeeCord` plugin messaging channel. They need nothing installed on the proxy, but they do need the server names in `config.yml` to match what you configured in them.

Once the proxy works, put a hostname on it with an `A` record and an `SRV` record so players type `mc.example.com` with no port - [SRV records for Minecraft](https://www.renode.space/blog/srv-records-for-minecraft) has the exact record.

#### Troubleshooting the first-time errors

**"If you wish to use IP forwarding, please enable it in your BungeeCord config as well!"** The backend has `bungeecord: true` in `spigot.yml`, but the proxy is not forwarding. Set `ip_forward: true` in the proxy's `config.yml` and restart the proxy. You also see this when someone connects to the backend directly, bypassing the proxy - which, if it works at all, tells you the backend is reachable from outside.

**"Could not connect to a default or fallback server, please try again later"**, usually followed by `Connection refused`. The proxy tried every server in `priorities` and none answered. Check in order: is the backend actually running; does the `address` in `servers` match the backend's `server-ip` and `server-port`; is the name in `priorities` spelled exactly like the key under `servers`; and, if the backend is on another machine, does your firewall let the proxy through. A backend bound to `127.0.0.1` is unreachable from a proxy on a different machine.

**`Server is online mode!`** The backend still has `online-mode=true`. Set it to `false` and restart.

**Everyone logs in as a fresh player with no inventory.** UUIDs are arriving in offline form, so `ip_forward` is off on the proxy or `bungeecord` is off on the backend. Stop and fix it before more people play; each login creates player data you will have to clean up.

**`Connection throttled! Please wait before reconnecting.`** from a backend during busy periods. The backend's `connection-throttle` in `bukkit.yml` is still on; set it to `-1`.

**`Address already in use` on startup.** Something else holds the listener port, often a backend still on `25565` after you moved the proxy there. Move the backend or change `host`.

**`Outdated server!` or `Outdated client!`** The client and the backend versions differ. Keep every backend on the client's version or add ViaVersion. [Minecraft version upgrades](https://www.renode.space/blog/minecraft-version-upgrades) covers the order to update a network in.

**Players can join but the server list shows 1 slot.** That is the default `max_players: 1` on the listener. It is cosmetic; change it to the number you want shown.

#### FAQ

##### Where do I download BungeeCord.jar safely?

From md_5's Jenkins at `ci.md-5.net`, the `lastSuccessfulBuild` artifact of the BungeeCord job, which the SpigotMC site links to. It is distributed as a ready jar with no BuildTools step. Mirrors on other sites are unnecessary and sometimes stale or modified.

##### Should I use BungeeCord or Velocity for a new network?

Velocity, unless a plugin you need only exists for BungeeCord. Velocity's modern forwarding is signed, so backends reject direct connections without a firewall or BungeeGuard, and it handles more players per core. BungeeCord works, but needs that extra protection to be safe.

##### Do backends need the same plugins as the proxy?

No, they are separate worlds. Bukkit, Spigot and Paper plugins go on backends; BungeeCord plugins go on the proxy. A few, such as LuckPerms, Floodgate and BungeeGuard, publish both builds and run in both places, each with the build made for it.

##### Why does BungeeCord default to port 25577?

Because it assumes you already have a Minecraft server on `25565` and are putting the proxy beside it. Most networks swap them: the proxy takes `25565` so players need no port, and the backends move to other ports.

##### Can backends run different Minecraft versions?

Only if every client can still talk to the backend it lands on. The proxy does not translate versions. Either keep all backends on one version or install ViaVersion, on the proxy or on each backend but not both.

##### Is offline mode on the backends dangerous?

On its own, very. It is safe only when the backends cannot be reached except through the proxy: bound to `127.0.0.1`, firewalled to the proxy's address, or protected by BungeeGuard. Test by joining a backend directly; it must refuse you.

Each proxy and backend is its own RE:NODE server from 2 GB, with Paper and the matching Java version on the backends. Plugins such as BungeeGuard go in through the file manager or per-server SFTP, extra ports are added on the Network tab, and backup slots and schedules come with every tier.

[See Minecraft plans](https://www.renode.space/game-servers/minecraft)

---

### EssentialsX config.yml: the settings that matter

Published 2026-10-15 by RE:NODE Team. https://www.renode.space/blog/essentialsx-config-yml-guide

EssentialsX's `config.yml` is about 1,400 lines long, and on a typical survival server you need to change perhaps twenty of them. The ones that matter are the teleport cooldown and warm-up, the `sethome-multiple` home ranks, the economy block (`starting-balance`, `currency-symbol`, `min-money`, `max-money`), the chat `format` and `group-formats`, and the spawn keys that decide where a new player lands. Several sections do nothing unless the matching module jar is installed, and most changes apply with `/essentials reload` - but not all of them. This guide goes through the file in the order you will actually edit it, with the real defaults from the current 2.x config, and points out where the comments in the file are easy to misread.

#### Where config.yml lives, and the modules it configures

After the first start, EssentialsX creates its folder beside every other plugin:

```text
plugins/Essentials/
  config.yml      the file this guide is about
  kits.yml        kit contents, including the 'tools' first-join kit
  worth.yml       sell prices for /sell and /worth
  spawn.yml       spawn points set with /setspawn
  userdata/       one YAML file per player: balance, homes, nickname
  warps/          one file per warp
```

The core jar does the bulk of the work: homes, warps, teleports, kits, the economy, nicknames, AFK, mail. Everything else is a separate module jar, downloaded from the same place as the core and kept at exactly the same version. A mismatched module is a common cause of a stack trace at startup after an update.

| Module | What it adds | Section in config.yml |
| --- | --- | --- |
| EssentialsX Chat | Chat formatting, local chat radius | `chat:` |
| EssentialsX Spawn | `/spawn`, `/setspawn`, first-join handling | `newbies:` and the spawn keys |
| EssentialsX Protect | Damage, explosion and physics switches | `protect:` (`prevent`, `disable`) |
| EssentialsX AntiBuild | Build permissions, item blacklists | `protect:` (`alert`, `blacklist`) |
| EssentialsX GeoIP | Country on login and `/whois` | its own `plugins/EssentialsGeoIP/config.yml` |
| EssentialsX Discord | A chat bridge to Discord | its own folder |

The important thing about that table is the right-hand column. The `chat:` section is in the core config whether or not you have the Chat module, and editing it with no Chat jar installed does nothing at all - there is no warning, the setting is simply never read. If a change seems to be ignored, check the module is in `plugins/` before you check anything else. Install only the modules you use; each one registers listeners on a server that runs its game logic on one thread. The broader question of what to install is in [Minecraft plugins worth installing](https://www.renode.space/blog/minecraft-plugins-worth-installing).

The file header lists the YAML rules worth knowing before your first edit: spaces only, never tabs; indentation is the structure; an apostrophe inside single-quoted text is written twice (`don''t`); text with symbols goes in quotes; and the file must be saved as UTF-8, not ANSI, if you use any accented letter or currency symbol other than `$`.

#### Teleports: cooldowns, warm-ups and safety

Four keys control how teleporting feels, and they are the first thing players notice.

plugins/Essentials/config.yml:

```yaml
teleport-safety: true
teleport-cooldown: 0
teleport-delay: 0
teleport-invulnerability: 4
tpa-accept-cancellation: 120
```

`teleport-cooldown` is the gap, in seconds, required between teleports. It is one shared timer across `/home`, `/tp`, `/spawn`, `/warp` and the rest, not a separate timer per command, so a 30-second cooldown means a player who just went home cannot also `/spawn` for 30 seconds. On a survival server a value between 10 and 60 stops teleport spam without feeling punitive.

`teleport-delay` is the warm-up: the player stands still for that many seconds before the teleport happens, and moving or being attacked cancels it. This is the setting that stops someone escaping a fight with `/home`, and on a PvP server it matters far more than the cooldown. Three to five seconds is the usual range; anything above ten and players stop using homes and start building nether highways, which may be what you want.

`teleport-invulnerability` gives a few seconds in which the player cannot be hurt by other players, or hurt them, after a command teleport. It is there so a `/tpa` into a fight is not an instant death, and so it cannot be used as an ambush.

`teleport-safety` decides what happens when the destination is unsafe - lava, a drop, inside a block. With `true`, Essentials moves the player to the nearest safe spot; with `false`, the teleport is cancelled with a warning. Leave it on. `tpa-accept-cancellation` is how long a `/tpa` request waits before it expires.

Three permissions bend these rules for staff:

| Permission | Effect |
| --- | --- |
| `essentials.teleport.cooldown.bypass` | Ignores `teleport-cooldown` |
| `essentials.teleport.timer.bypass` | Skips the `teleport-delay` warm-up |
| `essentials.teleport.timer.move` | May move during the warm-up without cancelling |

Give them to groups, not individuals - the [LuckPerms guide](https://www.renode.space/blog/minecraft-luckperms-guide) covers inheritance, so that a VIP group that skips the warm-up does not quietly pass the bypass on to a group you did not intend.

If you want different cooldowns for different commands, `teleport-cooldown` is the wrong tool. The newer `command-cooldowns` block sets one per command, works for commands from other plugins too, and by default survives a restart (`command-cooldown-persistence: true`):

```yaml
command-cooldowns:
  home: 30
  spawn: 10
  tpr: 600
```

Commands are written without the slash. Wildcards work, and a key that starts with `^` is treated as a regular expression.

#### Homes and the sethome-multiple limits

The home limit is the setting most often configured wrongly, because it depends on two permissions rather than one.

```yaml
sethome-multiple:
  default: 3
  vip: 5
  staff: 10
```

The names under `sethome-multiple` are home ranks, and they do not need to match your permission groups. A player gets more than one home only if they have `essentials.sethome.multiple`; with that node alone they get the `default` number. To get a rank's number they need both `essentials.sethome.multiple` and `essentials.sethome.multiple.vip`. A player who has the rank node but not the base node stays on one home, which is the source of nearly every "I set VIP to 5 homes and they still have 1" thread. `essentials.sethome.multiple.unlimited` removes the limit entirely.

So a working setup for three tiers looks like this, in LuckPerms terms:

```text
$ lp group default permission set essentials.sethome.multiple true
$ lp group vip permission set essentials.sethome.multiple.vip true
$ lp group staff permission set essentials.sethome.multiple.staff true
```

Lowering a limit later does not delete homes a player has already set; it only stops them setting more. If you are cutting the limit as part of a wipe or a rebalance, say so in advance.

The other home keys are small but worth a decision:

- `spawn-if-no-home: true` sends a player who types `/home` with no home set to spawn. Set it to `false` if `/home` should simply fail.
- `confirm-home-overwrite: false` - turn this on, because `/sethome` with an existing name replaces it without asking, and players do it by accident.
- `world-home-permissions: false` - set to `true` with `essentials.worlds.<worldname>` to stop people using `/home` to cross into a world they should not reach. On a server with a creative world beside survival, that is how inventories leak between them; [running multiple worlds with Multiverse](https://www.renode.space/blog/minecraft-multiverse-multiple-worlds) covers the wider problem.

Charging for homes belongs in `command-costs`, covered next.

#### The economy block

The economy is part of the core jar. The design side - Vault, shop plugins, faucets and sinks, moving balances to a database - is covered in [the EssentialsX and Vault economy guide](https://www.renode.space/blog/minecraft-economy-essentialsx-vault). This section is just the keys and their defaults.

plugins/Essentials/config.yml:

```yaml
starting-balance: 0
command-costs:
  home: 50
  sethome: 500
  back: 100
  kit-tools: 1500
currency-symbol: '$'
currency-symbol-suffix: false
max-money: 10000000000000
min-money: -10000
economy-log-enabled: false
minimum-pay-amount: 0.001
```

`starting-balance` is paid once, when a player's userdata file is created on their first join. Changing it later does nothing for anyone who has already joined.

`currency-symbol` can be any character, provided the file is saved as UTF-8 - a pound or euro sign in a file saved as ANSI appears in game as a question mark or garbage. For symbols written after the number, set `currency-symbol-suffix: true`. Number formatting is separate: uncomment `currency-format: "#,##0.00"` to control decimals, and `currency-symbol-format-locale` (for example `de-DE` for `1.234,50`) for which character separates thousands.

`min-money` defaults to `-10000`, and its comment explains what that means: a player can only go negative if they hold `essentials.eco.loan`. So by default nobody is in debt, but the floor is there for anyone you grant loans to. Setting it to `0` disables overdrafts completely, whatever the permissions say. `max-money` defaults to ten trillion; the file itself warns that extremely large numbers can have unintended consequences, and a ceiling a player could actually reach is a more useful number.

`command-costs` charges per use. The key is the command name, and kits use `kit-<name>`. The Chat module's shout and question modes can be charged as `chat-shout` and `chat-question`. Anyone with `essentials.nocommandcost.<command>` or `essentials.nocommandcost.all` pays nothing, and a wildcard such as `essentials.*` on a staff group includes those - so test prices with an ordinary account.

The rest of the block, briefly:

| Key | Default | What it does |
| --- | --- | --- |
| `economy-log-enabled` | `false` | Logs sign trades and `/sell` to `trade.log` |
| `economy-log-update-enabled` | `false` | Also logs every Vault transaction - noisy |
| `pay-excludes-ignore-list` | `false` | Blocks `/pay` to someone ignoring you |
| `show-zero-baltop` | `true` | Shows empty balances in `/baltop` |
| `baltop-requirements` | `0`, `0` | Minimum balance and playtime to be listed |
| `baltop-entry-limit` | `-1` | Caps cached baltop entries on big servers |

The file's own comment on `economy-log-update-enabled` says it fills the log quickly and is meant for testing; leave it off in normal running. After changing `show-zero-baltop`, run `/baltop force`, because the list is cached.

`sell-multipliers` lets a rank sell for more than the `worth.yml` price: `default: 1.0`, `double: 2.0`, and the permission `essentials.sell.multiplier.<rank>`. It is a faucet. A 2x multiplier on a farmable item doubles the rate at which money enters the server, so price it with that in mind.

#### Chat formatting with EssentialsX Chat

None of this works without the Chat module. With it installed, the `chat:` section controls the format and range of every message.

```yaml
chat:
  radius: 0
  format: '<{DISPLAYNAME}> {MESSAGE}'
  group-formats:
    default: '&7{DISPLAYNAME}&7:&r {MESSAGE}'
    admin: '&c[{GROUP}]&r {DISPLAYNAME}&7:&f {MESSAGE}'
  world-aliases:
    world_nether: "&cN&r"
```

`radius: 0` is global chat. Any other number makes chat local to that many blocks. Players with `essentials.chat.shout` can still reach everyone by starting a message with `!`, those with `essentials.chat.question` with `?`, and `essentials.chat.spy` sees everything regardless of distance. Local chat changes a server's character more than any other single setting - quiet servers feel empty with it on, so turn it on only if there are enough people for nearby conversations to happen.

The placeholders you will actually use are `{DISPLAYNAME}`, `{USERNAME}`, `{NICKNAME}`, `{PREFIX}`, `{SUFFIX}`, `{GROUP}`, `{WORLDNAME}` and `{WORLD}` (the alias from `world-aliases`), plus `{MESSAGE}`.

Two traps catch nearly everyone:

- **Double prefixes.** `{DISPLAYNAME}` already includes the prefix and suffix from your permissions plugin. A format of `{PREFIX} {DISPLAYNAME}` prints the rank twice. Use `{DISPLAYNAME}` alone, or `{PREFIX}{NICKNAME}{SUFFIX}` if you want to place them yourself.
- **Group names are case-sensitive.** The key under `group-formats` must match the group name exactly - and if a LuckPerms group has a display name set, the display name is what Essentials sees. A format that never applies is almost always a capital letter or a display name.

Prefixes come from LuckPerms through Vault, so both need to be installed for `{PREFIX}` to show anything. Colour codes in the format string use `&`; whether players can use colours in their own messages is a separate set of permissions. `paper-chat-events: true` uses Paper's modern chat events and is the one chat setting that needs a full restart to change - switch it off only if another chat plugin conflicts.

If you bridge chat to Discord, the Discord side keeps its own format; [DiscordSRV and Discord integration](https://www.renode.space/blog/minecraft-discord-integration-discordsrv) covers the alternative to the Essentials module.

#### Spawn, first join and respawning

The Spawn module owns three moments: a player's first join, every join after that, and respawn after death.

```yaml
newbies:
  announce-format: '&dWelcome {DISPLAYNAME}&d to the server!'
  spawnpoint: newbies
  kit: tools
spawn-on-join: false
respawn-at-home: false
respawn-at-home-bed: true
respawn-at-anchor: false
respawn-listener-priority: high
spawn-join-listener-priority: high
```

Set the spawns in game rather than in the file. Stand where everyone should appear and run `/setspawn`; stand at the new-player arrival point and run `/setspawn newbies`. That second name is what `spawnpoint: newbies` refers to. If you do not want a separate new-player spawn, set `spawnpoint: none` and new players use the world's spawn. `/setspawn <group>` works for any group name, which is how staff can arrive somewhere different from everyone else.

`kit: tools` hands out the `tools` kit from `kits.yml` on first join, regardless of cost, permissions or the kit's cooldown. Check that kit actually contains what you want; the default is a starter set, and a first-join kit is a small faucet in its own right. `announce-format` set to `''` turns the welcome broadcast off.

`spawn-on-join` is the "spawn on join" setting people search for. `true` sends every player to spawn on every login; it also accepts a group name or a list of groups, so you can send only `default` players to spawn while ranked players log in where they left:

```yaml
spawn-on-join:
  - default
  - guests
```

Anyone with `essentials.spawn-on-join.exempt` is left where they logged out. On a lobby or hub this should be `true`; on a survival server it is usually `false`, because being pulled back to spawn on every login is irritating once people have a base.

Respawning is decided by the `respawn-at-` keys. `respawn-at-home: true` sends a dead player to their first home, or to their bed if `respawn-at-home-bed` is also true. `respawn-at-anchor` controls whether respawn anchors in the Nether are honoured.

The two listener priorities are where Essentials meets other plugins that also move players around. If Multiverse or a lobby plugin should decide where players respawn, set `respawn-listener-priority: lowest`; `none` gives vanilla behaviour; `highest` forces Essentials to win. Both priorities only change on a full restart.

#### AntiBuild and GeoIP

AntiBuild is the module that locks people out of their own server. Its main switches sit under `protect:` in the core config:

```yaml
protect:
  disable:
    build: true
    use: true
    warn-on-build-disallow: true
  alert:
    on-placement: LAVA,TNT,LAVA_BUCKET
    on-use: LAVA_BUCKET
    on-break:
  blacklist:
    placement: LAVA,TNT,LAVA_BUCKET
    usage: LAVA_BUCKET
    break:
    piston:
    dispenser:
```

With the AntiBuild jar installed and `build: true` (the default), anyone without `essentials.build` cannot place or break blocks, and with `use: true` cannot use items either. That is correct for a server where new players must be accepted before they build, and a disaster if you dropped the jar in because it came in the same download. Either grant `essentials.build` to the `default` group, or set both `build` and `use` to `false` and keep AntiBuild only for its blacklists.

The blacklists take Bukkit material names, comma separated. `placement` and `usage` default to lava and TNT; `break` can protect something like `BEDROCK`, and `piston` and `dispenser` block those machines from moving or firing a material. `essentials.protect.exemptplacement`, `exemptusage` and `exemptbreak` let staff through. The `alert` lists send a message to anyone with `essentials.protect.alerts` when someone places or uses a listed material, which is a cheap early warning for lava griefing. For finer control there are per-material nodes such as `essentials.build.place.<material>`. AntiBuild is a blunt instrument; for real grief protection with claims and block logs, see [grief protection and anti-cheat](https://www.renode.space/blog/minecraft-grief-protection-and-anti-cheat).

The Protect module shares the same `protect:` section, under `prevent:` and the damage switches in `disable:` (`fall`, `pvp`, `drown`, `lavadmg` and others). Turning off PvP for the whole server is `protect.disable.pvp: true`.

GeoIP has its own file, `plugins/EssentialsGeoIP/config.yml`:

plugins/EssentialsGeoIP/config.yml:

```yaml
database:
  show-cities: false
  download-if-missing: true
  license-key: ""
  update:
    enable: true
    by-every-x-days: 30
show-on-login: true
show-on-whois: true
```

It uses MaxMind's GeoLite2 database, which can no longer be downloaded anonymously. Create a free MaxMind account, generate a licence key, and paste it into `license-key`; without it the download fails and the module logs an error on every start. Once it works, staff with `essentials.geoip.show` see each player's country on login and in `/whois`, and `essentials.geoip.hide` keeps a player's location out of it.

Think before installing it. Showing staff where players connect from is personal data, it is rarely needed on a small server, and behind a proxy it reports the proxy's location for everyone unless player IPs are forwarded - the setup in [Velocity proxy networks](https://www.renode.space/blog/minecraft-velocity-proxy-network) handles that.

#### Reloading, and when a restart is needed

The file header says it plainly: after editing, run `/essentials reload` (or `/ess reload`). From the server console, the command has no slash - `essentials reload` - because the console is the server's input, not a chat box. This re-reads `config.yml`, kits, worth and the language files without touching the rest of the server.

Some changes do not apply on reload:

- `respawn-listener-priority` and `spawn-join-listener-priority` - their comments say restart.
- `chat.paper-chat-events` - restart.
- Adding, removing or updating any module jar - restart.
- `show-zero-baltop` - reload, then `/baltop force`.

What you should never use is the server-wide `/reload`, or a plugin manager that hot-loads jars. It reloads every plugin at once, Essentials included, and leaves listeners and tasks half-registered in ways that look like bugs in whichever plugin breaks first. Paper warns about it in the console for good reason. A restart takes seconds.

A reload that seems to do nothing usually means the YAML did not parse. Watch the console as you run it: a tab character, a missing space after a colon or an unescaped apostrophe produces an error naming the line, and Essentials will not have applied your edit. On RE:NODE the file manager's editor highlights YAML syntax, which catches most indentation mistakes before you save, and the console shows the reload output live. Take a backup from the panel before a large edit - it is one button to restore - and keep a copy of the working `config.yml` beside it. [Backing up and restoring a Minecraft world](https://www.renode.space/blog/minecraft-world-backup-and-restore) covers what else belongs in that backup.

#### Troubleshooting

**A setting is ignored completely.** Its module is not installed, or the YAML did not parse. The `chat:`, `newbies:` and `protect:` sections all depend on module jars.

**Players have one home whatever the rank.** They have the rank node, such as `essentials.sethome.multiple.vip`, without the base node `essentials.sethome.multiple`. They need both.

**Ranks appear twice in chat.** The format uses `{PREFIX}` and `{DISPLAYNAME}` together. Drop `{PREFIX}`.

**A group format never applies.** Capitalisation, or a LuckPerms display name. Run `lp user <name> info` and copy the group name exactly.

**Nobody can build after an update.** AntiBuild was installed with the other modules. Grant `essentials.build` to `default` or set `protect.disable.build` and `use` to `false`.

**The currency symbol shows as a question mark.** The file was saved as ANSI. Save it as UTF-8 and reload.

**Teleports keep being cancelled.** That is `teleport-delay` working: the player moved or was hit. Give staff `essentials.teleport.timer.move` if they need to keep moving.

**New players do not arrive at the new-player spawn.** `/setspawn newbies` was never run, or another plugin handles join location. Check `spawn-join-listener-priority` and restart after changing it.

#### FAQ

##### Is EssentialsX economy enabled by default?

Yes. The economy is part of the core jar and works from the first start, with no module to install. Balances, `/pay`, `/balance` and `/baltop` work immediately; other plugins reach it through Vault.

##### Does /essentials reload apply every change?

Most of them. Listener priorities, `paper-chat-events` and any change to the installed module jars need a full restart. Everything in the economy, teleport, home and chat format sections applies on reload.

##### How do I stop players using /back after death?

Death locations are recorded for `/back` only for players with `essentials.back.ondeath`. Leave that node off the `default` group, or put a price on `back` in `command-costs` if you want it available but expensive.

##### Can I set a different spawn for each rank?

Yes. Stand at each point and run `/setspawn <group>` with the group name. Players are sent to the spawn of their group, falling back to the default spawn.

##### Do I need the GeoIP module?

Rarely. It shows staff each player's country, which helps with ban evasion on a large public server and is personal data you then hold. It also needs a MaxMind licence key to download its database.

RE:NODE Minecraft servers run Paper with the matching Java version and a world already generated, from $5 a month. Upload EssentialsX and its modules through the file manager or SFTP, edit `config.yml` in the browser with YAML highlighting, and take a backup before a big change - restoring is one button.

[See Minecraft plans](https://www.renode.space/game-servers/minecraft)

---

### EssentialsX kits, warps, homes and spawn: full setup

Published 2026-10-15 by RE:NODE Team. https://www.renode.space/blog/essentialsx-kits-warps-and-homes

EssentialsX kits live in `plugins/Essentials/kits.yml`, each with an item list and a `delay` in seconds, and a player may only claim a kit if they hold `essentials.kits.<name>`. Warps are made with `/setwarp` and become individually lockable once `per-warp-permission` is switched on. Home limits come from the `sethome-multiple` table in `config.yml`, matched against `essentials.sethome.multiple.<tier>` nodes. `/spawn` is not in the main jar at all - it needs the separate EssentialsX Spawn module. Those four facts explain nearly every "the kit does not work" message on a fresh Paper server, and the rest of this guide is the detail behind them.

Balances, `/pay`, `worth.yml` and shops are covered in [the EssentialsX and Vault economy guide](https://www.renode.space/blog/minecraft-economy-essentialsx-vault). This post is about the movement and starter-gear half of the plugin, which is where most survival servers actually spend their configuration time.

#### Where EssentialsX keeps kits, warps, homes and spawns

EssentialsX is several jars. The main `EssentialsX` jar contains kits, warps, homes, teleport requests and the economy. `EssentialsXSpawn` is a separate download that adds `/spawn`, `/setspawn`, first-join handling and respawn rules. Install the main jar and only the modules you actually use - each one adds event listeners to a server whose main thread is shared by everything.

Each feature stores its data in a different place, and knowing which file holds what saves a lot of guessing when something goes missing:

```text
plugins/Essentials/
  config.yml        settings for everything, including sethome-multiple
  kits.yml          kit definitions and delays
  spawn.yml         spawn points, written by /setspawn (Spawn module)
  warps/
    mine.yml        one file per warp
    shop.yml
  userdata/
    <uuid>.yml      each player's homes and kit cooldown timestamps
```

Three consequences follow. Homes belong to the player file, so deleting a player's `userdata` file wipes their homes and kit cooldowns along with their balance. Warps are one small file each, so you can copy a warp from a test server by copying its file. And kits are definitions only - who has claimed what, and when, is recorded per player, not in `kits.yml`.

Older EssentialsX versions kept kits under a `kits:` section inside `config.yml`. Current builds read `kits.yml` and move an old section across when they upgrade. If you are following an old tutorial that tells you to edit kits in `config.yml`, that is why nothing changes.

#### Writing kits in kits.yml

A kit is a name, a delay and a list of items. The default file ships with one kit called `tools`, which is a good template:

plugins/Essentials/kits.yml:

```yaml
kits:
  tools:
    delay: 10
    items:
      - stone_pickaxe 1
      - stone_shovel 1
      - stone_axe 1
  starter:
    delay: -1
    items:
      - iron_sword 1 sharpness:2 name:&bStarter_Sword lore:Given_on_day_one
      - bread 16
      - torch 32
      - leather_chestplate 1 color:139,69,19
      - $250
      - /broadcast {player} has started their journey
```

Each item line is the same item syntax `/give` uses in EssentialsX: the material name, the amount, then optional metadata.

- **Enchantments** are `enchantment:level` pairs such as `sharpness:2` or `efficiency:4`. Use the modern enchantment names on current versions.
- **`name:`** sets the display name. Spaces are written as underscores, and `&` colour codes work.
- **`lore:`** sets lore lines. Underscores become spaces and a `|` starts a new line.
- **`color:`** takes an RGB triple for leather armour.
- A line starting with **`$`** gives money through the economy, so `$250` pays the player 250 on claim. That needs a working economy, which the main jar provides.
- A line starting with **`/`** runs as a console command when the kit is claimed. `{player}` is replaced with the player's name. This is how you give items from other plugins, grant a permission, or announce something.

Material names must match the server version. A kit written for 1.20 that names an item renamed or added later will fail to load that line, and the console says so on startup or on claim. The kit itself still loads, minus the broken line, which is why players sometimes report "the kit is missing the sword" rather than "the kit is broken".

Edits to `kits.yml` take effect after `/essentials reload` or a restart. Reload is fine for kits; it is not a general-purpose tool for other plugins.

##### Making kits in game with /createkit

Writing NBT-heavy items by hand is tedious, so EssentialsX can capture your inventory instead. Fill your inventory with exactly what the kit should contain, then run:

```bash
/createkit starter -1
/createkit daily 86400
```

The first argument is the kit name, the second the delay in seconds. The command needs `essentials.createkit`. With `pastebin-createkit: false` in `config.yml` (the default on current builds) the kit is written straight into `kits.yml`; with it set to `true`, the plugin uploads the kit to a paste service and gives you a link to copy from, which is what older guides describe.

`/createkit` keeps enchantments, names, lore and most item data. Recent builds on Paper can also store kit items in a serialised form that preserves everything an item carries, including data from other plugins; whether yours does depends on the EssentialsX version and an option in `config.yml`, so check your own file rather than relying on a tutorial. Either way, open `kits.yml` after creating a kit and read what was written. It is the only way to be certain a custom item survived the trip.

The other kit commands:

| Command | Permission | What it does |
| --- | --- | --- |
| `/kit` or `/kits` | `essentials.kit` | Lists kits the player may use |
| `/kit <name>` | `essentials.kits.<name>` | Claims a kit |
| `/kit <name> <player>` | `essentials.kit.others` | Gives a kit to someone else |
| `/showkit <name>` | `essentials.showkit` | Shows the contents without claiming |
| `/delkit <name>` | `essentials.delkit` | Deletes the kit definition |
| `/kitreset <name> [player]` | `essentials.kitreset` | Clears the cooldown (newer builds) |

#### Kit delays, one-time kits and costs

`delay` is measured in seconds from the moment of the last claim. A few values come up constantly:

| `delay` | Meaning |
| --- | --- |
| `0` | No cooldown at all |
| `3600` | Once an hour |
| `86400` | Once a day |
| `604800` | Once a week |
| `-1` | Once, ever |

The cooldown is stored in the player's `userdata` file under `timestamps`, keyed by kit name. That has two practical effects. Renaming a kit resets every player's cooldown on it, because the old timestamp no longer matches anything. And a one-time kit is only one-time while the player file exists; wiping userdata hands every starter kit out again.

Players with `essentials.kit.exemptdelay` ignore the delay entirely. Give that to staff testing kits, never to a donor rank by accident through inheritance - an unlimited daily kit is an item duplicator with a permission node on it.

To charge for a kit, use `command-costs` in `config.yml`. The key is `kit-` followed by the kit name:

plugins/Essentials/config.yml:

```yaml
command-costs:
  kit-tools: 0
  kit-daily: 500
  warp: 10
  home: 25
```

The cost is taken through the economy on each use, and a player who cannot afford it is refused. Charging a little for a repeatable kit is a quiet way to stop it becoming a farm, and the same section prices teleports, which comes up again below.

#### Kit permissions and the first-join kit

Kit access is two nodes, and most broken setups have only one of them:

- `essentials.kit` allows the `/kit` command itself.
- `essentials.kits.<name>` allows that particular kit. `essentials.kits.*` allows all of them.

A player with `essentials.kit` but no kit nodes sees an empty list. A player with `essentials.kits.starter` but no `essentials.kit` cannot run the command. In LuckPerms, a sensible split looks like this:

```bash
/lp group default permission set essentials.kit true
/lp group default permission set essentials.kits.starter true
/lp group default permission set essentials.kits.tools true
/lp group vip permission set essentials.kits.vip true
/lp group admin permission set essentials.kit.exemptdelay true
```

If `vip` inherits from `default`, VIPs get the starter and tools kits as well, which is usually what you want. [The LuckPerms guide](https://www.renode.space/blog/minecraft-luckperms-guide) explains inheritance and why setting nodes on groups rather than individual players keeps this auditable.

To hand a kit out automatically on a player's first join, use the `newbies` section of `config.yml`. It belongs to EssentialsX Spawn, so it does nothing unless that module is installed:

plugins/Essentials/config.yml:

```yaml
newbies:
  announce-format: '&dWelcome {DISPLAYNAME}&d to the server!'
  spawnpoint: newbies
  kit: starter
```

`kit` names the kit given on first join, regardless of the player's kit permissions. Set it to an empty string to give nothing. `spawnpoint` names a spawn set with `/setspawn newbies`, so new players can arrive at a tutorial area while everyone else respawns at the main spawn. If you give the starter kit this way, make the same kit `delay: -1` and leave its permission off the default group, or new players will claim it a second time from `/kit`.

#### Warps: /setwarp and per-warp permissions

A warp is a named location anyone with permission can teleport to. Stand where the warp should land, facing the way players should face on arrival, and run `/setwarp <name>`. The position, including pitch and yaw, is saved to `warps/<name>.yml`.

| Command | Permission | What it does |
| --- | --- | --- |
| `/setwarp <name>` | `essentials.setwarp` | Creates or moves a warp |
| `/warp` | `essentials.warp.list` | Lists warps, paged |
| `/warp <name>` | `essentials.warp` | Teleports to a warp |
| `/warp <name> <player>` | `essentials.warp.others` | Sends someone else |
| `/delwarp <name>` | `essentials.delwarp` | Removes a warp |

By default, anyone with `essentials.warp` can use every warp. That is fine for a server with a `shop`, a `mine` and an `end` portal, and wrong the moment you have a staff area or a donor island. Switch per-warp access on in `config.yml`:

plugins/Essentials/config.yml:

```yaml
per-warp-permission: true
```

From then on each warp needs its own node, `essentials.warps.<name>`, and `essentials.warps.*` grants all of them. The warp list only shows warps the player can use, which is the main reason to turn this on even if every warp is public: you can add a hidden `staffroom` without it appearing in everyone's list.

```bash
/lp group default permission set essentials.warps.spawn true
/lp group default permission set essentials.warps.shop true
/lp group default permission set essentials.warps.mine true
/lp group vip permission set essentials.warps.vipisland true
/lp group mod permission set essentials.warps.* true
```

> [!WARNING]
> Turning on `per-warp-permission` on a live server takes every warp away from every player until the new nodes are in place. Add the `essentials.warps.<name>` nodes first, then flip the setting and reload, or players will report that warps are broken within seconds.

`/setwarp` on an existing name silently moves the warp. Keep `essentials.setwarp` with the people who build the server, and keep `essentials.delwarp` narrower still. A warp pointed at a world that is no longer loaded - common after removing a Multiverse world - fails with an error about the world rather than the warp, which is a clue worth knowing; [running multiple worlds with Multiverse](https://www.renode.space/blog/minecraft-multiverse-multiple-worlds) covers loading and unloading worlds cleanly.

#### Homes and the sethome-multiple limits

`/sethome` saves a named location to the player's own file, and `/home` returns to it. With one home the name is optional and defaults to `home`. With several, players name them: `/sethome base`, `/sethome farm`, `/home farm`. Running `/home` with several homes and no name lists them.

The limit is controlled by this table in `config.yml`, shown here with its shipped values:

plugins/Essentials/config.yml:

```yaml
sethome-multiple:
  default: 3
  vip: 5
  staff: 10
```

The keys are arbitrary names, not group names. Each one maps to a permission node:

- `essentials.sethome.multiple` - required before a player can have more than one home at all.
- `essentials.sethome.multiple.<key>` - grants that tier's number, so `essentials.sethome.multiple.vip` allows 5.
- `essentials.sethome.multiple.unlimited` - no limit.

A player with several tier nodes gets the highest number among them, so inheritance does not cause a VIP to fall back to 3. A player without `essentials.sethome.multiple` gets one home, whatever the table says. That single missing node is behind most "my rank should have five homes" tickets. Add your own tiers freely - `legend: 15` together with `essentials.sethome.multiple.legend` on the right group is all it takes.

```bash
/lp group default permission set essentials.sethome true
/lp group default permission set essentials.home true
/lp group default permission set essentials.delhome true
/lp group default permission set essentials.sethome.multiple true
/lp group vip permission set essentials.sethome.multiple.vip true
/lp group mod permission set essentials.home.others true
```

`essentials.home.others` lets staff visit a player's home with `/home <player>:<homename>`, which is useful for investigating grief reports and unnecessary for anyone else.

A few related settings in the same file are worth deciding on deliberately:

- `spawn-if-no-home` - when true, `/home` with no homes set sends the player to spawn rather than erroring.
- `update-bed-at-daytime` - lets players set their bed spawn by clicking a bed during the day, so `/home bed` points somewhere sensible.
- `world-home-permissions` - when true, a home in a world requires permission for that world. Useful for keeping homes out of a resource world you reset.

Homes are a convenience that changes how a survival server plays. Unlimited free homes turn the world into a set of teleport destinations, and nobody builds roads. The usual compromise is a low count for new players, a few more for ranks, and a small `home` cost in `command-costs`.

#### /spawn with EssentialsX Spawn

Without the Spawn module there is no `/spawn` command from EssentialsX. Download `EssentialsXSpawn` at the same version as the main jar - mismatched versions are a common cause of startup errors - and put both in `plugins/`.

Then stand at your spawn and run `/setspawn`. That writes the location to `spawn.yml`. `/setspawn <group>` sets a separate spawn for one permission group, so a VIP group can arrive at its own hub, and `/setspawn newbies` creates the first-join point the `newbies` section refers to.

| Command | Permission | What it does |
| --- | --- | --- |
| `/setspawn [group]` | `essentials.setspawn` | Sets the default or a group spawn |
| `/spawn` | `essentials.spawn` | Teleports to your spawn |
| `/spawn <player>` | `essentials.spawn.others` | Sends someone to spawn |

The module also takes over where players arrive after death and on join. The settings that matter:

plugins/Essentials/config.yml:

```yaml
respawn-at-home: false
spawn-on-join: false
respawn-listener-priority: high
spawn-join-listener-priority: high
```

What each one decides:

- `respawn-at-home` sends dead players to their home instead of spawn. Most survival servers leave it off and let the bed decide.
- `spawn-on-join` sends players to spawn every time they log in. It accepts `true`, `false`, or a group name or list of groups, so you can send only `default` players to spawn while ranks log in where they left. Staff with `essentials.spawn-on-join.exempt` are skipped.
- The two listener priorities decide who wins when another plugin also wants to move players on respawn or join. If a lobby plugin or Multiverse keeps overriding your spawn, this is the dial.

> [!NOTE]
> `/setspawn` does not move the vanilla world spawn. The `spawn-protection` radius in `server.properties` is centred on the vanilla spawn, so set both: run `/setworldspawn` at the same place, or set `spawn-protection=0` and protect the area with a region plugin instead.

That last point catches many servers: players cannot break blocks somewhere that looks like open countryside, because the invisible 16-block protection square sits around the original world spawn, not the one EssentialsX uses. [server.properties explained](https://www.renode.space/blog/minecraft-server-properties-explained) covers `spawn-protection` and why it only ever applies to non-operators.

#### Teleport delays, cooldowns and safety

Every EssentialsX teleport - `/home`, `/warp`, `/spawn`, `/tpa`, `/back` - runs through the same settings, so tune them once:

plugins/Essentials/config.yml:

```yaml
teleport-cooldown: 0
teleport-delay: 0
teleport-invulnerability: 4
teleport-safety: true
```

| Setting | Effect |
| --- | --- |
| `teleport-delay` | Seconds the player must stand still first |
| `teleport-cooldown` | Seconds before they may teleport again |
| `teleport-invulnerability` | Seconds of protection on arrival |
| `teleport-safety` | Refuses or adjusts unsafe destinations |

A short `teleport-delay`, three to five seconds, is the single most effective setting against combat logging by teleport: the player has to stand still while being hit, and moving cancels it. Staff can bypass it with `essentials.teleport.timer.bypass`, and the cooldown with `essentials.teleport.cooldown.bypass`. Leave `teleport-safety` on; it stops a home set over lava, or a warp whose floor somebody mined out, from killing whoever uses it.

Combined with `command-costs`, these settings decide how much the world map matters on your server. Free, instant, unlimited teleports make distance meaningless. A few seconds of delay and a small fee keep most of the convenience while making a long walk occasionally the better option.

#### Backing up homes, warps and kits

Everything in this guide is small YAML under `plugins/Essentials/`, and none of it is part of the world folder. A world backup alone restores the terrain and loses every home, warp and kit cooldown since the plugin data was last saved; a plugin backup alone does the reverse. Back up the two together. [Minecraft world backup and restore](https://www.renode.space/blog/minecraft-world-backup-and-restore) covers what to include and how to roll back safely.

On RE:NODE, Minecraft servers run Paper with the matching Java version, and EssentialsX jars go in through the file manager or SFTP like any other plugin. The file manager has a syntax-highlighting editor for `kits.yml` and `config.yml`, which helps with YAML indentation, and backup slots on every game plan cover the whole server directory, plugin data included. Take one before switching on `per-warp-permission` or editing `sethome-multiple` on a live server.

#### Troubleshooting

**"You do not have permission to use that kit."** The player has `essentials.kit` but not `essentials.kits.<name>`. Check the exact kit name in the node; it is the key in `kits.yml`, lowercase.

**The kit list is empty.** Same cause from the other side: no `essentials.kits.*` nodes at all, or the kits failed to load. Look for a YAML error on startup; a tab character or a missing space after a colon stops the whole file loading.

**Edits to kits in `config.yml` do nothing.** Kits moved to `kits.yml`. Edit that file and run `/essentials reload`.

**A kit item is missing on claim.** One item line uses a material name the server version does not know. The console names the line.

**Players are stuck at one home.** They lack `essentials.sethome.multiple`. The tier node alone is not enough.

**`/spawn` is an unknown command.** EssentialsX Spawn is not installed, or failed to load because its version does not match the main jar.

**Players respawn at the wrong place.** Another plugin is handling respawn at a higher priority, or `respawn-at-home` is on. Check Multiverse and any lobby plugin, then adjust `respawn-listener-priority`.

**A warp says the world does not exist.** The world it points at was renamed or unloaded. Recreate the warp in a loaded world.

#### FAQ

##### How do I make a kit that can only be claimed once?

Set `delay: -1` on it, or create it with `/createkit <name> -1`. The claim is recorded in the player's userdata file, so it stays one-time unless that file is deleted or the kit is renamed.

##### Can I give a kit automatically to new players?

Yes, with EssentialsX Spawn installed: set `kit:` in the `newbies` section of `config.yml` to the kit name. It is given on first join whatever the player's kit permissions are.

##### How do I give a rank more homes?

Add a line to `sethome-multiple`, for example `vip: 5`, then give that rank both `essentials.sethome.multiple` and `essentials.sethome.multiple.vip`. The player gets the highest tier they hold.

##### Can I hide some warps from the warp list?

Turn on `per-warp-permission`. Players then see and use only the warps they hold `essentials.warps.<name>` for, so a staff warp without a public node is invisible to everyone else.

##### Do I need EssentialsX Spawn if I use another spawn plugin?

No, and running two plugins that both handle join and respawn locations invites conflicts. Pick one. If you keep EssentialsX Spawn, adjust its listener priorities rather than fighting the other plugin.

##### Why can players not break blocks near spawn even though it is not protected?

Vanilla `spawn-protection` is centred on the world spawn, not the EssentialsX spawn. Move the world spawn with `/setworldspawn` or set `spawn-protection=0`.

Minecraft servers on RE:NODE run Paper with the matching Java version, the EULA accepted and a world already generated. Plugins go up through the file manager or SFTP, and every game plan includes backup slots you can run on demand or from the Schedules tab. From $5 a month.

[See Minecraft plans](https://www.renode.space/game-servers/minecraft)

---

### How to enable datapacks in Minecraft: worlds and servers

Published 2026-10-15 by RE:NODE Team. https://www.renode.space/blog/how-to-enable-datapacks-in-minecraft

To enable a datapack in Minecraft Java Edition, put the pack (a `.zip` or a folder with `pack.mcmeta` at its top) into the world's `datapacks` folder and load the world. On a new singleplayer world you can do it from the Create New World screen: More, then Data Packs, then move the pack from Available to Selected. On an existing world or a server, drop the file into `world/datapacks/` and run `/reload`, or enable it by name with `/datapack enable "file/<name>"`. New packs found in that folder are switched on automatically unless something has marked them disabled, and most of this post is about the cases where that happens.

Datapacks are a Java Edition feature. Bedrock has no datapacks; its equivalent is behaviour packs, which are installed and enabled through a completely different route.

#### The quick answer, by situation

There are four places a pack can be enabled, and they do not share a screen or a command:

| Where you play | How to enable | Takes effect |
| --- | --- | --- |
| New singleplayer world | Create New World, More, Data Packs | When the world is created |
| Existing singleplayer world | World folder, `datapacks`, reload | On next load or `/reload` |
| Dedicated server | `world/datapacks/`, then `/datapack enable` | Immediately |
| Realm | Upload a world that already has the pack | After the upload |

Two commands do almost all the work once you are in a world or a server console:

```bash
$ datapack list
$ datapack enable "file/house-rules.zip"
```

The rest of this post goes through each route step by step, then covers the things that make a pack show up as disabled: experimental feature packs, `pack_format` warnings, safe mode and the server's own start-up settings. Installing, ordering, writing and debugging packs in depth is in the [Minecraft datapacks guide](https://www.renode.space/blog/minecraft-datapacks-guide), and none of that is repeated here.

#### Singleplayer: enabling packs when you create a world

The Create New World screen is the only place in the game with a proper interface for datapacks, and it only exists before the world does.

1. From the title screen choose Singleplayer, then Create New World.
2. Open the More tab and click Data Packs. On versions before the tabbed screen arrived (around 1.19.4), Data Packs is a button directly on the create screen.
3. Click Open Pack Folder. A file browser opens on a temporary folder. Copy your `.zip` files or pack folders into it. On current versions you can also drag a zip straight onto the game window and confirm the copy.
4. Back in the game the pack appears in the Available column on the left. Hover over it and click the arrow to move it into Selected on the right.
5. Click Done, set the rest of the world up as usual, and create it.

The game copies every selected pack into the new world's own `datapacks` folder, so the world carries its packs with it from then on. Order in the Selected column matters when two packs change the same file: packs higher in the list override those below them, and the built-in vanilla data always sits at the bottom.

If a pack does not appear in Available at all, the game could not read it as a pack. The usual reason is a zip with a wrapper folder inside it, so `pack.mcmeta` is one level too deep. That and the other structural problems are covered in the [datapacks guide](https://www.renode.space/blog/minecraft-datapacks-guide).

> [!TIP]
> Ticking the Allow Cheats (or Allow Commands) option while you are on this screen saves trouble later. Without it, enabling or disabling a pack in this world afterwards means opening it to LAN with commands allowed every time.

#### Singleplayer: adding a pack to a world you already have

There is no Data Packs button for an existing world. You add the file by hand:

1. From Singleplayer, select the world, click Edit, then Open World Folder. The folder for that save opens in your file browser.
2. Open the `datapacks` folder inside it. Create it if it is missing; the name is exactly `datapacks`, lowercase, no space.
3. Copy the pack in, either as the zip or as the unpacked folder.
4. Load the world.

On Windows the saves live in `%APPDATA%\.minecraft\saves\<world name>\`, if you would rather go there directly. The world folder name is not always the same as the name shown in the menu, which is why the Edit route is safer.

When the world loads, the game compares the packs in the folder with the lists stored in `level.dat`. A pack it has never seen before is enabled automatically. That is the whole procedure for most people: copy, load, done.

If the world is already open, you do not need to quit. Run `/reload` and the game rescans the folder, enables any new packs and reloads everything. Running a command needs cheats, so on a world created without them you can open it to LAN with Allow Commands on, which grants them for that session only. Check the result:

```bash
$ /datapack list enabled
```

The pack should appear as `file/<name>`. If it appears only under `/datapack list available`, the game found it but something is holding it disabled, and the section on that below is where to go next.

#### Dedicated servers: the folder, the commands and reloading

A server reads packs from one place: the `datapacks` folder inside the main world directory, whose name comes from `level-name` in `server.properties` (`world` by default). On Paper the nether and the end are separate folders, but packs placed in `world_nether` or `world_the_end` are ignored; only the main world's folder counts.

Upload the pack, then either restart the server or reload it from the console. On a running server the sequence looks like this:

```bash
$ minecraft:reload
$ datapack list
$ datapack enable "file/vt-graves.zip"
```

A few rules that save time:

- The name is `file/` followed by the file or folder name exactly as it appears on disk, including `.zip` when it is a zip. Quote it, because of the slash.
- `/datapack enable` and `/datapack disable` trigger a reload by themselves. You do not need to run `/reload` afterwards.
- `/reload` on its own also picks up new packs and enables them, as long as they are not on the disabled list.
- On Paper, Spigot and their forks, plain `/reload` is Bukkit's plugin reload, which is unsafe on a live server. Use `minecraft:reload`, which is the vanilla datapack reload.
- From the console you type commands without the leading slash. In game they need it, and they need operator level 2.

The full command set:

| Command | What it does |
| --- | --- |
| `datapack list` | Shows enabled and available packs |
| `datapack list available` | Only packs found but not enabled |
| `datapack list enabled` | Only packs currently on |
| `datapack enable "file/x"` | Turns a pack on, placed last by default |
| `datapack enable "file/x" first` | Turns it on with lowest priority |
| `datapack enable "file/x" before "file/y"` | Places it relative to another pack |
| `datapack disable "file/x"` | Turns a pack off and reloads |

Positions matter only when two packs replace the same file. The [datapacks guide](https://www.renode.space/blog/minecraft-datapacks-guide) explains how the order decides which one wins.

Disabling a pack does not delete it. The file stays in the folder and the pack is added to the disabled list in `level.dat`, which is why it will not come back on its own after a restart. To remove it for good, disable it, stop the server and delete the file. Disabling a pack that added recipes, loot or functions is harmless; disabling one that added dimensions or biomes to a world that used them is not, so take a backup first.

On RE:NODE, Minecraft servers run Paper with the world already generated, so `world/datapacks/` exists the first time you open the file manager. Packs go in through the browser or over SFTP (see [SFTP and the file manager](https://www.renode.space/blog/sftp-and-the-file-manager)), and the panel console takes `minecraft:reload` and `datapack` commands directly, with history and tab completion.

#### initial-enabled-packs and initial-disabled-packs

Since 1.19.3, `server.properties` has two keys that decide which packs a brand new world starts with:

server.properties:

```properties
initial-enabled-packs=vanilla
initial-disabled-packs=
```

Both take comma-separated pack names. They apply once, when the server generates the world, and are ignored for a world that already exists. That trips people up: adding a pack name to `initial-enabled-packs` and restarting an existing server changes nothing at all.

They are useful in two situations. The first is turning on experimental feature packs on a dedicated server, which has no create-world screen; that is covered in the next section. The second is keeping a pack off from the start. If you preload a `datapacks` folder before the first launch, every pack in it is enabled when the world generates; listing one in `initial-disabled-packs` keeps it in the folder but switched off until somebody enables it.

server.properties:

```properties
initial-enabled-packs=vanilla,trade_rebalance
initial-disabled-packs=file/test-pack
```

The rest of the file, key by key, is in [server.properties explained](https://www.renode.space/blog/minecraft-server-properties-explained).

#### Experimental packs: the Experiments screen and feature flags

Mojang ships upcoming features as built-in packs that are off by default. Turning one on changes world generation or game mechanics, so the game treats them differently from ordinary packs: they set feature flags on the world, and feature flags can only be set when the world is created.

Which experimental packs exist depends entirely on the version. Each one is added for a preview and removed once its feature ships in a normal release. As examples: around 1.19.3 and 1.19.4 there were `update_1_20` and `bundle`; 1.20.5 shipped `update_1_21`; `trade_rebalance` has been present for several releases; 1.21.2 added `minecart_improvements` and `redstone_experiments`. Names from an older guide may simply not exist on your version, so check rather than copy.

To see the ones your version actually has:

- In singleplayer, Create New World, More, then Experiments. Each toggle there is one experimental pack. On older versions they appear in the Data Packs screen instead, marked as experimental.
- On a server, run `datapack list` and look for built-in names other than `vanilla` and `file/...` entries. The release notes for your version are the authoritative list.

On a dedicated server, the only clean way to enable one is `initial-enabled-packs` before the world exists:

1. Stop the server.
2. Move or delete the existing world folder (keep a copy if you want it).
3. Set `initial-enabled-packs=vanilla,<experiment name>` in `server.properties`.
4. Start the server so it generates a new world with that flag set.

Running `datapack enable` on an experimental pack in an existing world fails with a message that the required feature flags are not enabled in this world. That is not a bug; it is the game refusing to bolt experimental blocks and mechanics onto a world that was not generated for them.

> [!WARNING]
> Experiments are labelled experimental for a reason. A world created with them may not open cleanly in the next release, and they cannot be switched off later. Use a fresh, disposable world, not the server everyone has spent months building.

#### pack_format warnings and incompatible packs

Every pack declares a `pack_format` in its `pack.mcmeta`, a number that tracks the data format of one Minecraft version or a range of them. When the number does not match what your game expects, the pack is flagged as incompatible.

In singleplayer the Data Packs screen shows the pack in red with a note that it was made for an older or a newer version of Minecraft. You can still select it; the game asks you to confirm. In the server console there is no prompt, and the pack loads anyway.

Whether an incompatible pack works is a separate question from whether it loads. A mismatched number with files in the right layout often works perfectly. A matching number with files in the old layout does nothing. The common case is a pack built for 1.20 on a 1.21 server: it enables cleanly, `/datapack list` shows it, and it has no effect, because 1.21 renamed the folders inside packs from plural to singular. The table of format numbers and the folder rename are both in the [datapacks guide](https://www.renode.space/blog/minecraft-datapacks-guide).

The practical rule: download the build of the pack made for your exact Minecraft version. Ready-made packs such as Vanilla Tweaks ask for the version before you download for this reason. Only edit `pack_format` yourself when you know the files inside are already in the right shape.

#### Why a datapack shows as disabled

`datapack list` separates enabled packs from available ones. A pack that is in the folder but stuck under available has one of these causes, in roughly this order of likelihood:

1. **Someone disabled it earlier.** `/datapack disable`, or deselecting it in a Data Packs screen, records it in the disabled list in `level.dat`. Packs on that list are not re-enabled by a reload or a restart. Enable it by name.
2. **It needs a feature flag the world lacks.** An experimental pack, or a third-party pack that declares it needs one, cannot be enabled on a world created without that experiment.
3. **It was listed in `initial-disabled-packs`** when the world was generated, which put it on the disabled list from the first tick.
4. **The world was opened in safe mode.** When a pack fails to load badly enough, singleplayer offers to open the world in safe mode with only vanilla data, and a dedicated server refuses to start and suggests the `--safeMode` launch flag. Both load without your packs; once the faulty pack is fixed or removed, enable the others again and check the list.
5. **The pack failed to load.** A broken JSON file or a bad function does not always disable the whole pack, but the console prints an error naming the file at load or reload. Read the log before changing anything else.

And if the pack is not in either list, the server never found it: wrong folder (a nether folder, or a world folder that `level-name` does not point at), a zip with a wrapper folder, or a file name that is really `pack.zip.zip` because Windows hides extensions.

A small but frequent mistake belongs here too: `datapack enable "file/graves"` fails with an unknown pack error when the file on disk is `graves.zip`. Copy the exact name from `datapack list available`; tab completion in the console fills it in correctly.

#### Realms, LAN worlds and servers are not the same

Realms is Mojang's hosted service, and on Java Edition it gives you no file access. There is no `datapacks` folder to upload into and no console. The route is indirect:

1. Build the world in singleplayer with the packs you want, enabled and working.
2. In the Realm's configuration, use the option to upload a world, and pick that save.
3. The upload replaces the world in that Realm slot, packs included.

After that, `/datapack` commands work for an operator in the Realm, so you can disable or reorder packs already there. Adding a new pack later means repeating the upload, which replaces the Realm's world with your local copy. Download the Realm's world first, add the pack locally, and upload that, or you will roll back everything players did since your last copy. Bedrock Realms do not take datapacks at all; they use add-ons.

A LAN world is just your singleplayer world opened to other players, so its packs are managed exactly as in the singleplayer sections above, on your machine.

A dedicated server is the only one of the three where you control the files directly, can see the log, and can enable or remove packs while people are playing. If a group has outgrown uploading worlds back and forth, that is usually why. Moving a singleplayer world with its packs onto a server is the same as moving any world: upload the world folder, `datapacks` included, and point `level-name` at it. [Minecraft world backup and restore](https://www.renode.space/blog/minecraft-world-backup-and-restore) covers moving and restoring worlds safely.

#### FAQ

##### Do I need to restart the server after adding a datapack?

No. Upload it and run `minecraft:reload` from the console, or enable it by name with `datapack enable`, which reloads by itself. A restart also works and is the safer option if the pack adds world generation.

##### Why does /datapack enable say the pack does not exist?

The name is wrong. It must be `file/` plus the exact file or folder name, including `.zip`, in quotes. Run `datapack list available` and copy it from there.

##### Can I turn on experimental features in a world I already have?

Not through the game. Experimental packs set feature flags that are fixed at world creation. Create a new world with the experiment selected, or on a server set `initial-enabled-packs` and let it generate a fresh world.

##### Does every player need the datapack installed?

No. Datapacks run on the server, or on the host's machine for a LAN world. Players only need a resource pack if the datapack uses custom textures or models, and that is a separate file.

##### Do datapacks work on Bedrock Edition?

No. Datapacks are Java only. Bedrock uses behaviour packs, and a Java datapack cannot be converted by renaming files.

##### Will enabling a datapack change my existing world?

Recipes, loot, advancements and functions apply as soon as the pack loads. World generation packs only affect chunks generated after they were enabled, so explored areas stay as they were and new terrain may not join neatly at the edge.

Minecraft servers on RE:NODE run Paper with the matching Java version and a generated world, so the `datapacks` folder is ready for your first upload through the file manager or SFTP. The console takes `datapack` commands directly, and backup slots with one-button restore are on every plan. From $5 a month.

[See Minecraft plans](https://www.renode.space/game-servers/minecraft)

---

### Minecraft join and quit messages: hide or change them

Published 2026-10-15 by RE:NODE Team. https://www.renode.space/blog/minecraft-join-and-quit-messages

Vanilla Minecraft has no setting that hides or changes the yellow "joined the game" and "left the game" lines. There is no gamerule, no `server.properties` key and no datapack hook for them. To change them you need a plugin, and on a Paper server the usual answer is EssentialsX: `custom-join-message` and `custom-quit-message` in its `config.yml`, where `"none"` keeps the vanilla message and `""` hides it completely. Staff who should arrive unannounced get `allow-silent-join-quit: true` plus the `essentials.silentjoin` and `essentials.silentquit` permissions. The one request no config file covers is "show the message to everyone except the player who joined" - that needs a few lines of Skript or a tiny plugin, both shown below.

#### Why vanilla has no switch for it

The join message is not text the server writes. When a player logs in, the server sends every connected client a translatable component - the key `multiplayer.player.joined` with the player's name as its argument - and each client renders it in its own language. Leaving uses `multiplayer.player.left`, and a player whose name has changed since their last visit gets `multiplayer.player.joined.renamed`, the "(formerly known as ...)" line. The broadcast goes to everyone online, including the player who just arrived, and it is also printed to the server console.

Mojang added gamerules for many broadcast messages over the years - death messages, advancement announcements, command feedback - but never one for joins and quits. That is the whole reason this question keeps coming up: people search the gamerule list, find `showDeathMessages` and `announceAdvancements`, and assume a join equivalent must exist. It does not. Recent versions have also been renaming gamerules (1.21.11 moved them to lowercase-with-underscores names such as `show_death_messages`), so if you are hunting for the death or advancement switch, tab-complete `/gamerule` on your own version rather than trusting an old list.

What vanilla does have, for completeness:

- **A server resource pack can override the translation.** Setting `multiplayer.player.joined` to an empty string in a pack's language file changes what clients display, but it only works for players who accept the pack, it leaves an empty chat line on some versions, and it changes the text in singleplayer too while the pack is loaded. It is a curiosity, not a fix. [MOTD, icon and resource packs](https://www.renode.space/blog/minecraft-motd-icon-and-resource-packs) covers how a server pack is delivered.
- **Nothing on the console side.** The console log line cannot be suppressed without a plugin either.

On a vanilla or Fabric server, then, the honest answer is "switch to Paper, or find a mod that patches the message". The rest of this guide assumes Paper or a Paper fork, which is what most plugin servers run.

#### What Paper and Spigot can and cannot change

Neither Paper nor Spigot exposes the join message in its own config files. `spigot.yml` has a `messages:` block, but it covers the whitelist kick, unknown command, server full, outdated client and server, and restart texts - not joins. Paper's `config/paper-global.yml` has a `messages:` section with one related key:

config/paper-global.yml:

```yaml
messages:
  use-display-name-in-quit-message: false
```

With `true`, the quit message uses the player's display name (which a nickname or prefix plugin may have changed) instead of their username. It does not hide the message, and there is no matching key for joins.

What Paper does give you is the API. Every join fires a `PlayerJoinEvent` whose message any plugin can replace or clear, and every quit fires a `PlayerQuitEvent` likewise. Paper uses Adventure components for these, so a plugin can set a fully formatted message with hex colours, hover text and click actions. That is how EssentialsX, vanish plugins and chat plugins all do it - and it is also why two of them installed together can fight over the same message, covered in troubleshooting below.

| Where | Join/quit control | Notes |
| --- | --- | --- |
| Vanilla, Fabric | None | Only mods or a resource pack hack |
| `spigot.yml` | None | Other kick and error texts only |
| `paper-global.yml` | Quit name only | `use-display-name-in-quit-message` |
| Plugins | Full | Through the join and quit events |

#### EssentialsX custom-join-message and custom-quit-message

If EssentialsX is already on the server, you do not need anything else for the common cases. The keys sit in `plugins/Essentials/config.yml` in the core jar, so no module is required. The defaults:

plugins/Essentials/config.yml:

```yaml
custom-join-message: "none"
custom-quit-message: "none"
custom-new-username-message: "none"
hide-join-quit-messages-above: -1
```

The two values that matter are easy to mix up, and plenty of forum answers get them backwards:

- `"none"` means **Essentials does not touch the message** - players see the normal vanilla "joined the game" line.
- `""` (an empty string) means **hide the message entirely**.

So hiding both messages for everyone is:

```yaml
custom-join-message: ""
custom-quit-message: ""
```

Then run `/essentials reload` (from the console, `essentials reload` with no slash) and test by logging in on a second account. The general mechanics of the file - YAML rules, what needs a restart, which sections depend on module jars - are in [the EssentialsX config.yml guide](https://www.renode.space/blog/essentialsx-config-yml-guide), so they are not repeated here.

To replace the message instead of hiding it, write your own text with `&` colour codes and the placeholders Essentials provides:

| Placeholder | Becomes |
| --- | --- |
| `{PLAYER}` | The display name (nickname, prefix) |
| `{USERNAME}` | The account name |
| `{PREFIX}` / `{SUFFIX}` | Prefix and suffix from the permissions plugin |
| `{ONLINE}` | Players online now |
| `{UNIQUE}` | Unique players who have ever joined |
| `{UPTIME}` | How long the server has been running |

```yaml
custom-join-message: "&8[&a+&8] &7{USERNAME}"
custom-quit-message: "&8[&c-&8] &7{USERNAME}"
```

That compact `[+] name` / `[-] name` style is popular on busy servers because it carries the information in a quarter of the space. A friendlier small-server version might be `"&e{PLAYER} &7has arrived - {ONLINE} online"`.

A few details worth knowing before you settle on a format:

- **`{PLAYER}` versus `{USERNAME}`.** `{PLAYER}` includes whatever the display name has picked up - a `/nick`, a rank prefix from LuckPerms through Vault. If your chat format already shows ranks, a join line with `{PLAYER}` can be long and noisy. `{USERNAME}` is always the plain account name.
- **Prefixes need Vault.** `{PREFIX}` and `{SUFFIX}` come from your permissions plugin through Vault. With LuckPerms but no Vault they come out empty. [The LuckPerms guide](https://www.renode.space/blog/minecraft-luckperms-guide) covers setting prefixes per group.
- **Quote the value.** A message starting with `&` or containing a colon has to be in quotes or the YAML will not parse, and Essentials quietly keeps the old value.

##### Renamed players

`custom-new-username-message` is used instead of `custom-join-message` when a returning player has changed their Mojang username since their last visit. With its default of `"none"`, Essentials uses your normal custom join message for them too. If you want to point out renames, it also accepts `{OLDUSERNAME}`. If you set a custom join message, check this key as well, otherwise renamed players get a message in a different style from everybody else.

##### Hiding messages only when the server is busy

`hide-join-quit-messages-above` is the setting large servers want and small ones do not. With `-1` (the default) messages are always shown. Set it to a number and join and quit messages stop once that many players are online:

```yaml
hide-join-quit-messages-above: 40
```

On a server with sixty people and constant churn, join spam pushes real conversation off the screen; on a server with eight friends, the join line is how you know someone is on. This key lets the same config serve both phases of a server's life.

#### Hiding a player's own join message from them

The topic that brings many people here is narrower: everyone else should see "Alex joined the game", but Alex should not, because they already know, and on a server with a welcome message or MOTD in chat it is one more line pushing the useful text away.

No EssentialsX key does this. The join event has one message that is broadcast to everyone; it has no per-recipient list. The way round it is to clear the event's message and send your own copy to every player except the one who joined. In Skript, if you already run it:

plugins/Skript/scripts/joinmessage.sk:

```text
on join:
    set join message to ""
    loop all players:
        loop-player is not player
        send "&e%player% joined the game" to loop-player
```

The `loop-player is not player` line is the condition that skips the joining player. Skript is a heavy plugin to install for this alone, though. If you or someone on your team writes Java, the same thing is a dozen lines in a Paper plugin's listener:

JoinListener.java:

```text
@EventHandler
public void onJoin(PlayerJoinEvent event) {
    Component message = event.joinMessage();
    event.joinMessage(null);
    if (message == null) return;
    Player joined = event.getPlayer();
    for (Player p : Bukkit.getOnlinePlayers()) {
        if (!p.equals(joined)) p.sendMessage(message);
    }
    Bukkit.getConsoleSender().sendMessage(message);
}
```

Two things in that snippet are deliberate. Reading `joinMessage()` first and re-sending it means whatever EssentialsX or another plugin already set is preserved - your listener only changes who receives it. And the console line puts the join back in the server log, because clearing the event's message also removes it from the console, which makes later moderation harder. Register the listener at a late priority (`@EventHandler(priority = EventPriority.HIGHEST)`) so it runs after the plugins that format the message.

Do not combine this with `custom-join-message: ""` in Essentials. If Essentials clears the message first, your listener finds nothing to forward and nobody sees a join at all.

#### Silent join for staff

Staff often want to log in without announcing themselves - to watch a suspected cheater, to check something at 3 a.m., or just because a moderator joining makes the chat behave differently. EssentialsX handles this with one config key and three permissions:

plugins/Essentials/config.yml:

```yaml
allow-silent-join-quit: true
```

| Permission | Effect |
| --- | --- |
| `essentials.silentjoin` | No join message for this player |
| `essentials.silentquit` | No quit message for this player |
| `essentials.silentjoin.vanish` | Also vanished on arrival |

None of the permissions do anything while `allow-silent-join-quit` is `false`, which is the default, so turning the key on is the step people miss. Grant the nodes to a group rather than to individuals:

```bash
$ lp group moderator permission set essentials.silentjoin true
$ lp group moderator permission set essentials.silentquit true
$ lp group moderator permission set essentials.silentjoin.vanish true
```

Think about whether you want the vanish node as well. A silent join with no vanish still puts the player in the tab list, the `/list` output and the sleeping-player count, so anyone paying attention sees them arrive within seconds. Silent join only removes the chat line. Watch for one trap on wildcard groups: a group with `essentials.*` holds all three nodes, so admins who expected to be announced normally will not be. Set the nodes to `false` explicitly on that group if you want the wildcard but not the silence.

#### Vanish plugins and fake join or quit messages

Vanish is the other half of the staff problem. EssentialsX has `/vanish` (permission `essentials.vanish`), which hides a player from others' tab list and view. Its related keys:

- `hide-displayname-in-vanish: true` - keeps a vanished player's display name out of places that would reveal them.
- `sleep-ignores-vanished-player: true` - a vanished admin does not block the night skip.
- `last-message-reply-vanished: false` - players cannot `/reply` to a vanished player they cannot see, which would otherwise give the game away.

Essentials' `/vanish` does not post a fake "left the game" line when someone vanishes, so a moderator who vanishes mid-conversation simply disappears from the tab list with no explanation. That is where the dedicated vanish plugins earn their place. SuperVanish (free) and PremiumVanish (paid, same author) can broadcast a fake quit message when a player vanishes and a fake join message when they reappear, hide real join and quit messages for players who log in vanished, and integrate with other plugins so vanished staff do not appear in places like web maps or Discord bridges. Their options live in their own config files; read the generated `config.yml` after the first start rather than copying keys from an old forum post, because the layout has changed between versions.

Use one vanish system, not two. Running SuperVanish beside Essentials' `/vanish` gives you two different ideas of who is hidden, and whichever one the other plugins ask gets believed.

#### First-join messages and welcomes

The first time a player ever joins, two messages can appear: the normal join message (vanilla or your custom one) and Essentials' new-player broadcast from the Spawn module.

```yaml
newbies:
  announce-format: '&dWelcome {DISPLAYNAME}&d to the server!'
  spawnpoint: newbies
  kit: tools
```

`announce-format` is broadcast to everyone, only on a player's first ever join, and only if the EssentialsX Spawn jar is installed - without it, the `newbies:` section is not read at all. Set it to `''` to turn the welcome off. Note the placeholder here is `{DISPLAYNAME}`, not `{PLAYER}`; the two sections use different names for the same thing, and copying one into the other prints the literal text. The kit and spawnpoint lines in the same block are covered in [EssentialsX kits, warps and homes](https://www.renode.space/blog/essentialsx-kits-warps-and-homes).

A good pattern on a community server is a quiet normal join (`[+] name`) plus a louder first-join welcome, so regulars notice and greet the new player without the chat being full of yellow lines all evening. If you want a private greeting that only the new player sees - rules, a link to the Discord - that is a message of the day rather than a join message. EssentialsX shows the `motd.txt` file in its folder to each player on login, and only to them.

#### Colours, hex and MiniMessage

`custom-join-message` and `custom-quit-message` take the legacy `&` codes: `&a` to `&f` and `&0` to `&9` for colours, `&l` bold, `&o` italic, `&r` reset. That covers most needs.

MiniMessage is the tag-based format from the Adventure library that Paper uses - `<green>`, `<gradient:#ff0000:#0000ff>`, `<hover:show_text:'...'>`. It is what modern plugins increasingly expect, and it is the only practical way to put hover text or click actions on a join line. EssentialsX moved its own language files to MiniMessage-style tags in the 2.21 releases (which is where the `message-colors` primary and secondary colours in `config.yml` come from), but the join and quit keys in `config.yml` still document `&` codes and placeholders. If you want a gradient or a clickable join message, set the message from a plugin that supports MiniMessage, or from your own listener with `MiniMessage.miniMessage().deserialize(...)`, and leave Essentials' keys on `"none"` so the two do not collide.

Whatever you use, keep join lines short. They appear dozens of times a day, and a two-line gradient banner stops being charming by the second evening.

#### Networks, Discord and other places joins appear

Hiding the in-game line does not hide a join everywhere.

- **Proxy networks.** Behind Velocity or BungeeCord, each backend server fires its own join and quit events. A player moving from the lobby to survival "leaves" the lobby and "joins" survival, so both servers announce it, and players see join spam every time someone changes server. The usual fix is to hide join and quit messages on every backend (`custom-join-message: ""` on each) and use a proxy-side plugin for network-wide join and leave messages. [Velocity proxy networks](https://www.renode.space/blog/minecraft-velocity-proxy-network) covers the layout.
- **Discord bridges.** DiscordSRV posts its own join and leave messages to the linked channel, configured in its own files. Hiding them in game does nothing there - see [DiscordSRV and Discord integration](https://www.renode.space/blog/minecraft-discord-integration-discordsrv) and check its vanish integration if staff join silently.
- **The tab list and `/list`.** A hidden join message still leaves the player visible in both, unless they are vanished.
- **The console.** Clearing the message in the event also removes it from the log. If moderation depends on the log, re-send it to the console as in the listener above.

#### Troubleshooting

**`custom-join-message: "none"` still shows the message.** That is correct behaviour - `"none"` means vanilla. Use `""` to hide it.

**Changes do nothing after reload.** The YAML did not parse (an unquoted `&` at the start of the value is the usual cause), or you edited a copy of the file. Watch the console when you run `/essentials reload`; a parse error names the line.

**Two join messages appear.** Two plugins are both setting one - Essentials and a chat or join-message plugin, or Essentials and SuperVanish. Leave one of them on its default. If one of the two is the first-join `announce-format`, that is expected on a first join only.

**Staff with silent join are still announced.** `allow-silent-join-quit` is still `false`, or the permission is set on a group the player does not inherit. `lp user <name> permission check essentials.silentjoin` shows what Essentials sees.

**Admins are joining silently when they should not.** A wildcard such as `essentials.*` includes the silent nodes. Set them to `false` on that group.

**Messages vanished entirely after installing a plugin.** Something cleared the event message at a higher priority. Remove plugins one at a time, or run `/plugins` and look for anything with "join" or "chat" in its name. [Plugins worth installing](https://www.renode.space/blog/minecraft-plugins-worth-installing) covers why two plugins doing one job causes exactly this.

#### FAQ

##### Is there a gamerule to turn off join messages?

No. There are gamerules for death messages and advancement announcements, but join and leave messages have never had one in Java Edition. You need a plugin or a mod.

##### Does "none" hide the EssentialsX join message?

No, it does the opposite: `"none"` tells Essentials to leave the vanilla message alone. An empty string, `""`, hides it.

##### Can I hide the join message only for the player who joined?

Not with a config setting. The join message is one broadcast to everyone. Clear it and re-send it to every player except the joiner, with Skript or a small listener.

##### Can players with a rank join without being announced?

Yes. Set `allow-silent-join-quit: true` in Essentials and give their group `essentials.silentjoin` and `essentials.silentquit`. Add `essentials.silentjoin.vanish` if they should also be invisible on arrival.

##### Will hiding join messages stop Discord showing joins?

No. Discord bridges such as DiscordSRV send their own join and leave notices, configured separately in the bridge's files.

RE:NODE Minecraft servers run Paper with the matching Java version from $5 a month, so EssentialsX and vanish plugins work from the first start. Upload them through the file manager or SFTP, edit `config.yml` in the browser with YAML highlighting, and watch `/essentials reload` apply in the live console.

[See Minecraft plans](https://www.renode.space/game-servers/minecraft)

---

### Minecraft ops.json example: whitelist, bans and usercache

Published 2026-10-15 by RE:NODE Team. https://www.renode.space/blog/minecraft-ops-json-whitelist-json-explained

A Minecraft server keeps its people in five JSON files in the server root: `ops.json` (operators and their level), `whitelist.json` (who may join), `banned-players.json` and `banned-ips.json` (who may not), and `usercache.json` (a lookup table from names to UUIDs). Every entry is keyed by UUID, not by name. The server reads them into memory at startup and writes the whole list back to disk whenever a command changes it, which is why a file you edited by hand while the server was running quietly reverts. The safe rule is short: use `/op`, `/whitelist` and `/ban` while the server runs, and edit the files only with it stopped.

A working `ops.json` looks like this:

ops.json:

```json
[
  {
    "uuid": "069a79f4-44e9-4726-a5be-fca90e38aaf5",
    "name": "Notch",
    "level": 4,
    "bypassesPlayerLimit": true
  },
  {
    "uuid": "853c80ef-3c37-49fd-aa49-938b674adae6",
    "name": "jeb_",
    "level": 2,
    "bypassesPlayerLimit": false
  }
]
```

The rest of this post goes through each file field by field, what the commands write, what a hand edit can do that a command cannot, how offline mode breaks every one of these lists at once, and - because the same search often lands here - what the `level-type` values in `server.properties` mean. The policy side - who should be an operator at all, and how to build ranks with LuckPerms - is in [Minecraft whitelist and permissions](https://www.renode.space/blog/minecraft-whitelist-and-permissions); this post is about the files themselves.

#### The five files at a glance

| File | Changed by | Holds |
| --- | --- | --- |
| `ops.json` | `/op`, `/deop` | Operators, their level, slot bypass |
| `whitelist.json` | `/whitelist add/remove` | Players allowed in when the whitelist is on |
| `banned-players.json` | `/ban`, `/pardon` | Banned accounts, reason, expiry |
| `banned-ips.json` | `/ban-ip`, `/pardon-ip` | Banned addresses, reason, expiry |
| `usercache.json` | The server, on every login | Recently seen names and UUIDs |

All five are JSON arrays of objects. All five live next to `server.properties`, not inside the world folder, so they are shared by every dimension and survive a change of `level-name`. Start a new world for a new season and your operators, whitelist and bans carry over untouched. Delete the world folder and they are still there; delete the server root and they are gone, which is worth remembering when you decide what your backups cover.

They replaced plain-text files in 1.7.6, when Minecraft moved from names to UUIDs. If you find `ops.txt`, `white-list.txt`, `banned-players.txt` or `banned-ips.txt` on an old server, they are leftovers. A modern server converts them once and ignores them after that, and editing them does nothing.

The same files exist on vanilla, Paper, Spigot, Purpur, Fabric and NeoForge servers, because they belong to the vanilla server code that all of those are built on. Plugins can add their own lists on top - EssentialsX keeps per-player data, LuckPerms has its own storage - but the five files here behave the same on every one of them.

#### ops.json, field by field

Each operator is one object with four fields.

| Field | Type | Meaning |
| --- | --- | --- |
| `uuid` | string | The account. This is what the server matches |
| `name` | string | The last known name. Cosmetic |
| `level` | 1 to 4 | Operator permission level |
| `bypassesPlayerLimit` | true/false | May join when `max-players` is reached |

The `uuid` is the only field the server uses to recognise a player. The `name` is written for your benefit and updated when the player logs in under a new name; a stale name does no harm. The reverse is not true: an entry with a missing or malformed `uuid` is skipped when the file loads, with no error you are likely to notice, so a hand-written entry with only a name simply does not exist as far as the server is concerned.

`level` is where hand editing earns its keep. `/op <player>` always writes the value of `op-permission-level` from `server.properties`, which defaults to `4`. There is no argument to `/op` that sets a level, so if you want one player at level 4 and another at level 2, you either change `op-permission-level` before each `/op` and restart in between, or you write the number into the file. The short version of the four levels:

- `1` - bypasses spawn protection and nothing else.
- `2` - cheat-style commands such as `/gamemode`, `/give`, `/tp` and command blocks.
- `3` - player management: `/kick`, `/ban`, `/op`, `/whitelist`.
- `4` - everything, including `/stop`.

The full table and the reason the levels mean far less on a plugin server than they appear to - plugins usually grant their permissions to every operator regardless of level - are covered in [the permissions post](https://www.renode.space/blog/minecraft-whitelist-and-permissions). On Paper, treat `level` as controlling vanilla commands only.

`bypassesPlayerLimit` lets that player join when the server already holds `max-players` people. `/op` writes `false` for a new operator and keeps the existing value when you re-op somebody, and no command sets it to `true`, so the file is the only place to switch it on. It is the setting that lets the admin get into a full server to deal with whatever filled it.

Two more interactions worth knowing. Operators bypass the whitelist completely, so an old operator entry is a way in that `whitelist remove` will not close. And `/deop` removes the entry entirely rather than lowering the level - there is no level 0 to demote somebody to.

> [!TIP]
> The console is not an operator and does not need to be. Commands typed into the server console run with full permissions, so you never have to op yourself to fix something - and you can run `/op` itself from the console to bootstrap the first operator on a new server.

#### whitelist.json

whitelist.json:

```json
[
  { "uuid": "069a79f4-44e9-4726-a5be-fca90e38aaf5", "name": "Notch" },
  { "uuid": "853c80ef-3c37-49fd-aa49-938b674adae6", "name": "jeb_" }
]
```

Two fields, the same rules: `uuid` is matched, `name` is decoration. The file is consulted only when `white-list=true` in `server.properties`, and it is kept when the whitelist is switched off, so turning it back on later restores exactly the same set of people.

Whitelist is the one list with a reload command. `/whitelist reload` re-reads `whitelist.json` from disk, which makes it the only one of the five you can safely hand edit with the server running - as long as you run the reload before anything else writes the file. With `enforce-whitelist=true`, the reload also disconnects anyone online who is no longer listed.

When you run `/whitelist add <name>`, the server needs a UUID for that name. It checks `usercache.json` first, and if the name is not there it asks Mojang's profile service. That is why the command works for a player who has never joined, and why it fails with "That player does not exist" when the name is misspelled, was changed, or belongs to a Bedrock gamertag rather than a Java account.

#### banned-players.json and banned-ips.json

The ban lists carry more fields, because a ban records who did it, when and why.

banned-players.json:

```json
[
  {
    "uuid": "36532b5e-c442-3dbb-a24c-c7e55d0f979a",
    "name": "Griefer123",
    "created": "2026-10-15 14:03:22 +0000",
    "source": "Server",
    "expires": "forever",
    "reason": "Lava-cast over the spawn town"
  }
]
```

banned-ips.json:

```json
[
  {
    "ip": "203.0.113.45",
    "created": "2026-10-15 14:05:10 +0000",
    "source": "Server",
    "expires": "forever",
    "reason": "Ban evasion"
  }
]
```

| Field | Example | Meaning |
| --- | --- | --- |
| `created` | `2026-10-15 14:03:22 +0000` | When the ban was made |
| `source` | `Server`, `Rcon`, a player name | Who issued it |
| `expires` | `forever` or a date | When it lapses |
| `reason` | Free text | Shown to the player on the disconnect screen |

`source` is the name of whatever ran the command: `Server` for the console, `Rcon` for a remote console, or the operator's name. With no reason given, vanilla writes `Banned by an operator.`

`expires` is the interesting one. Vanilla's `/ban` has no duration argument and always writes `forever`, but the server does honour a date in this field. Write a timestamp in the same format as `created` - `"2026-10-22 14:00:00 +0000"` - and the ban stops applying after that moment. That is how temporary bans from plugins such as EssentialsX end up stored: in this same file, with a real expiry date. Get the format wrong and the date may not parse, so copy the shape of `created` exactly, including the space before the timezone offset.

The commands, all at operator level 3:

| Command | Effect |
| --- | --- |
| `ban <player> [reason]` | Adds to `banned-players.json`, kicks if online |
| `ban-ip <player or address> [reason]` | Adds the address to `banned-ips.json` |
| `pardon <player>` | Removes a player ban |
| `pardon-ip <address>` | Removes an address ban |
| `banlist [players or ips]` | Prints the current lists |

`ban-ip` given a player name bans that player's current address, which is the convenient form when they are online. Address bans are a blunt tool. Many home connections change address on reconnect, mobile networks put thousands of people behind one address, and a VPN defeats them in seconds. Use an account ban first and an address ban as a supplement for a determined alt-account problem, and expect to pardon an innocent player occasionally.

Neither ban list has a reload command in vanilla, so hand edits to them need the server stopped.

#### usercache.json

usercache.json:

```json
[
  {
    "name": "Notch",
    "uuid": "069a79f4-44e9-4726-a5be-fca90e38aaf5",
    "expiresOn": "2026-11-15 14:03:22 +0000"
  }
]
```

This is not a permission file. It is a cache of names and UUIDs the server has resolved, refreshed every time a player logs in. Commands use it to turn a name into a UUID without asking Mojang, and so do player heads, `/whitelist add` and the ban commands for players who are offline. `expiresOn` is set about a month ahead; an expired entry is looked up again the next time it is needed. The file is capped at the most recently used thousand or so entries, so it stays small on a busy server.

Because it is only a cache, `usercache.json` is safe to delete with the server stopped - it is rebuilt as players join. That is occasionally the fix when a renamed player's old name keeps resolving to the wrong account, or when a switch between online and offline mode has left it full of UUIDs that no longer match anything. Do not hand edit it to "fix" a player's identity; the server will overwrite your change from the next login anyway, and the identity that matters is the one in the other four files.

#### Why hand edits get overwritten while the server runs

The behaviour that catches everyone has a simple cause. At startup the server reads each list into memory. From then on, the copy in memory is the real one. When any command changes a list - `/op`, `/deop`, `/whitelist add`, `/ban`, `/pardon`, or a plugin calling the same code - the server serialises its in-memory list and writes the whole file again. Nothing it has not loaded survives that write.

```diagram
title: Where a hand edit is lost
disk = ops.json on disk | read once at start
mem = List in memory | the copy that counts
cmd = /op, /ban, /whitelist | or a plugin
edit = Your hand edit | made while running
disk -> mem : startup
cmd -> mem : change
mem -> disk : whole file rewritten
edit --> disk : overwritten at next write
```

So editing `ops.json` in the file manager while the server runs appears to work - the file on disk shows your change - and then disappears the next time anyone is opped, banned or whitelisted. Your edit was never in memory, and the next write replaces the file with what was. The same applies in reverse: an edit made with the server running has no effect until it is loaded, which for ops and bans means a restart.

There is a nastier version. If you save one of these files with a JSON syntax error - a trailing comma after the last entry is the usual one, a missing quote the other - the server logs a warning when it fails to load the list and carries on with an **empty** list in memory. Your operators are no longer operators, your whitelist admits nobody but ops, and your bans are lifted. The next command that touches that list then writes the empty list back to disk, replacing your broken file and every entry in it.

> [!WARNING]
> After hand editing any of these files, check the console on the next start for a warning about failing to load the operators list, whitelist or ban list. If you see one, stop the server before anybody runs a command, fix the JSON, and start again. Otherwise the next `/op` or `/ban` writes an empty list over everything you had.

The procedure that always works:

1. Stop the server and wait for it to finish shutting down.
2. Take a copy of the file you are about to edit, or a backup of the server.
3. Make the edit. Keep it a valid JSON array: commas between objects, none after the last one, every key and string in double quotes.
4. Paste the file into any JSON validator if you are unsure.
5. Start the server and read the start of the log for load warnings.
6. Run `/op` or `/whitelist list` or `/banlist` from the console to confirm the list holds what you expect.

For the whitelist alone there is a shortcut: edit, save, then `/whitelist reload` immediately.

On RE:NODE the file manager edits these files in the browser with syntax highlighting, which makes a stray comma visible before you save, and SFTP works with credentials generated per server if you prefer your own editor - [SFTP and the file manager](https://www.renode.space/blog/sftp-and-the-file-manager) has the details. The console keeps command history, so the verification step is a couple of keystrokes. And a backup slot is there to take a snapshot before you edit; restoring one is a button, covered in [Minecraft world backup and restore](https://www.renode.space/blog/minecraft-world-backup-and-restore).

#### Offline mode and the UUID trap

Every list here is keyed by UUID, and `online-mode` decides where UUIDs come from. That makes it the setting most likely to break all five files at once.

With `online-mode=true`, a player's UUID is issued by Mojang. It belongs to the account, survives name changes, and is what every command writes. These are version 4 UUIDs: the third group of characters starts with a `4`, as in `069a79f4-44e9-4726-...`.

With `online-mode=false`, the server does not ask Mojang anything. It derives a UUID from the name itself, by hashing the text `OfflinePlayer:` followed by the exact username. These are version 3 UUIDs, and the third group starts with a `3`. The same account produces two completely different identities:

| Mode | Notch's UUID |
| --- | --- |
| Online | `069a79f4-44e9-4726-a5be-fca90e38aaf5` |
| Offline | `b50ad385-829d-3141-a216-7e7d7539ba7f` |

The consequences follow directly:

- **Switching modes orphans every entry.** An operator opped in online mode is not an operator after you switch to offline mode, and the whitelist admits none of its members. Their inventories, advancements and plugin data are keyed by UUID too, so they also appear to vanish - the old player files are still in the world folder, under the old UUIDs.
- **Name case matters offline.** The hash is of the exact string, so `Notch` and `notch` are two different offline players.
- **A rename is a new player offline.** There is no account behind the name, so a new name means a new UUID and an empty inventory.
- **Offline whitelisting can write the wrong UUID.** On many versions, `/whitelist add` and `/op` still try Mojang's lookup first when the name belongs to a real Java account, and only fall back to the offline UUID if that fails. The entry then holds the online UUID and never matches the offline player who connects. The reliable fixes are to let the player join once with the whitelist off, so the cache holds their offline UUID, or to write the offline UUID into the file yourself.

You can compute an offline UUID with a few lines of Python. Java builds it with `UUID.nameUUIDFromBytes`, and this reproduces it exactly:

offline_uuid.py:

```python
import hashlib, uuid, sys

name = sys.argv[1]
h = bytearray(hashlib.md5(("OfflinePlayer:" + name).encode("utf-8")).digest())
h[6] = (h[6] & 0x0F) | 0x30  # version 3
h[8] = (h[8] & 0x3F) | 0x80  # IETF variant
print(uuid.UUID(bytes=bytes(h)))
```

```bash
$ python3 offline_uuid.py Notch
b50ad385-829d-3141-a216-7e7d7539ba7f
```

The one legitimate place for `online-mode=false` is a backend server behind a Velocity or BungeeCord proxy. The proxy authenticates with Mojang and, with forwarding configured, passes the real online UUID through to the backend - so the backend's lists hold version 4 UUIDs even though its own `online-mode` is off. If you see version 3 UUIDs appearing in `usercache.json` on a proxied backend, forwarding is not working and every player is arriving with a name-derived identity. Fix the forwarding before you do anything else; [the Velocity network guide](https://www.renode.space/blog/minecraft-velocity-proxy-network) covers it. Bedrock players through Geyser and Floodgate are a third case again, with their own generated UUIDs - see [Geyser and Bedrock crossplay](https://www.renode.space/blog/minecraft-geyser-bedrock-crossplay).

Moving a server from offline to online mode properly means rewriting each list with the new UUIDs and renaming each player's data files in `world/playerdata/`, plus whatever plugins store per UUID. It is a migration, not a setting change, and it needs a backup taken first.

#### level-type in server.properties

The other half of the question that brings people here is the line `level-type=minecraft\:normal`. It picks the world preset used when a world is generated. On 1.19 and later the values are namespaced:

| Value | What you get |
| --- | --- |
| `minecraft:normal` | Standard terrain. The default |
| `minecraft:flat` | Superflat, shaped by `generator-settings` |
| `minecraft:large_biomes` | Normal terrain with biomes several times larger |
| `minecraft:amplified` | Extreme vertical terrain |
| `minecraft:single_biome_surface` | One biome everywhere |

The backslash before the colon is the Java properties file format: the server's own writer escapes every colon, so the file it generates says `minecraft\:normal`. When the server reads the file back, `minecraft\:normal` and `minecraft:normal` in a value mean exactly the same thing, so either form is fine to type. What is not fine is an unrecognised value - a typo such as `minecraft:largebiomes` - which on current versions gives you a normal world rather than a clear error, and you find out only once players are walking around it.

Older versions used bare words: `default`, `flat`, `largeBiomes`, `amplified`, and in some versions `buffet` or `customized`. Modern servers translate the common legacy names to the namespaced ones, so an old file still works, but write the namespaced form in anything new.

Three practical points:

- **It applies only at world creation.** Once `level.dat` exists, the generator is stored in the world and changing `level-type` does nothing. To try another preset, change `level-name` to a new folder so the server generates a fresh world beside the old one.
- **`amplified` costs real CPU.** Generating amplified chunks is noticeably slower than normal ones, and on a shared core that shows as lag spikes while players explore. Pre-generate the playable area before opening the server - [world border and pre-generation](https://www.renode.space/blog/minecraft-world-border-and-pregeneration) explains how.
- **`large_biomes` is for big player counts.** Spreading biomes out gives everybody room, at the price of long walks to find a specific one.

Seeds, `generator-settings` JSON for flat worlds and worldgen datapacks such as Terralith are covered in [custom world generation](https://www.renode.space/blog/minecraft-custom-world-generation), and the rest of the file in [every server.properties key](https://www.renode.space/blog/minecraft-server-properties-explained).

#### Troubleshooting the lists

**I edited ops.json and nobody is an operator.** Either the server was running and overwrote your edit, or the JSON did not parse and the server loaded an empty list. Stop the server, open the file and check it.

**A player is in whitelist.json but cannot join.** Compare the UUID in the file with the one in `usercache.json` after they try to connect. A version 3 UUID on one side and version 4 on the other means an online/offline mismatch. Also check `white-list` is what you think it is: `/whitelist on` writes the setting to disk, so a stale hand-edited `server.properties` can disagree with what the server is doing.

**`/whitelist add` says the player does not exist.** Spelling, a recent rename, a Bedrock gamertag, or the server cannot reach Mojang's profile service. Have the player join once with the whitelist off, or add the UUID by hand with the server stopped.

**A pardoned player is still banned.** Check `banned-ips.json`. A player banned with `ban-ip` stays out after `pardon`, because the address ban is a separate list and needs `pardon-ip`.

**Bans came back after a restart.** Someone pardoned in the file while the server ran. The in-memory list still held the ban and wrote it back. Use `/pardon`.

**The server is full and the admin cannot get in.** Set `"bypassesPlayerLimit": true` on the admin's entry with the server stopped, or raise `max-players` - a value that only limits slots, not performance by itself.

#### FAQ

##### Can I add an operator without the server running?

Yes. Write the entry into `ops.json` with the player's UUID, a level from 1 to 4 and `bypassesPlayerLimit`, keep the file valid JSON, and start the server. The UUID has to be right; look it up from a previous login in `usercache.json` or from any Mojang UUID lookup for online-mode servers.

##### Is the name field in these files used for anything?

Barely. Matching is by UUID, and the server refreshes the name when the player next logs in. A wrong or outdated name in an entry causes no problem as long as the UUID is correct; a correct name with a wrong UUID does nothing at all.

##### How do I make a temporary ban without a plugin?

Ban the player normally, stop the server, change that entry's `expires` from `forever` to a timestamp in the same format as `created`, and start the server again. The ban stops applying after that time.

##### Is it safe to delete usercache.json?

With the server stopped, yes. It is only a cache and is rebuilt as players join. Deleting it means the first command naming an offline player has to ask Mojang again.

##### Why does /op not give the level I set in ops.json?

It writes `op-permission-level` from `server.properties` every time, overwriting whatever level that player had. Set levels in the file with the server stopped, and avoid re-opping that player afterwards.

##### Does level-type change anything on an existing world?

No. The generator is fixed when the world is created and stored in `level.dat`. Changing the line only affects a world generated after the change, usually because `level-name` points at a new folder.

Minecraft servers on RE:NODE start on Paper with the matching Java version, the EULA accepted and the world generated, so the first thing you do is op yourself from the console. The browser file manager highlights JSON as you edit these files, SFTP has its own per-server credentials, and backup slots on every plan mean a snapshot before a hand edit is one click away.

[See Minecraft plans](https://www.renode.space/game-servers/minecraft)

---

### Minecraft shop plugins: ChestShop vs QuickShop-Hikari

Published 2026-10-15 by RE:NODE Team. https://www.renode.space/blog/minecraft-player-shops-chestshop-quickshop

For most Paper survival servers the answer is QuickShop-Hikari if you want shops that new players can make without reading anything, and ChestShop if you want a sign format that is explicit, compact and hard to misread. EssentialsX sign shops are fine for a spawn shop run by staff and weak as a player market. All three need Vault and exactly one economy provider underneath. The plugin choice matters less than three decisions around it: what the server itself buys, how shop chests are protected, and whether every sale leaks a little money out of the economy. Get those right and players will set prices for you; get them wrong and somebody's sugar cane farm becomes the central bank.

The economy layer itself - Vault, EssentialsX balances, `worth.yml`, command costs and database-backed providers - is covered in [Minecraft economy with EssentialsX and Vault](https://www.renode.space/blog/minecraft-economy-essentialsx-vault). This post starts where that one stops: the shops.

#### Three kinds of shop, and which one to pick

Shop plugins differ less in features than in how a player makes a shop and how a buyer reads one.

| | ChestShop | QuickShop-Hikari |
| --- | --- | --- |
| Make a shop | Write four sign lines | Hit a chest with the item, type a price |
| What buyers see | The sign text | A floating item and an info panel in chat |
| Storage | Signs and chests in the world | A database (local file by default) |
| Learning curve | Players must learn the format | Almost none |
| Admin shops | `Admin Shop` on line 1 | `/qs unlimited` on a shop |

EssentialsX sits in a different category. Its `[Buy]` and `[Sell]` signs are server shops with infinite stock, and its `[Trade]` sign is a player shop with no chest at all - the stock lives inside the sign. That makes Essentials signs good for a handful of staff-built shops at spawn and awkward for a market of fifty player stalls.

A practical rule: pick one player shop plugin and stick with it. Running ChestShop and QuickShop side by side works technically, but players then have to know two systems, staff have two sets of permissions to audit, and the price data you want for balancing is split across two places.

The other thing worth deciding early is whether you want a central market at all. Chest shops scattered across player bases are charming and almost useless as a market, because nobody walks twenty minutes to compare prices. Most servers that keep a living economy build a market district near spawn with protected plots, and QuickShop-Hikari's `/qs find` (search for nearby shops selling an item) helps in either layout.

#### What every shop plugin needs first

None of these plugins store money. They ask Vault for whatever economy provider is registered and move balances through it. So before you install a shop:

1. Install Vault (or the maintained VaultUnlocked if your plugin list asks for it - never both).
2. Install exactly one economy provider. EssentialsX is the usual one.
3. Restart and run `vault-info` in the console.

```text
[Vault] Vault vX.Y.Z Information
[Vault] Economy: Essentials Economy [Essentials Economy]
[Vault] Permission: LuckPerms [LuckPerms]
```

If the economy line is empty, every shop plugin will either disable itself or load and then fail on the first transaction. If it names an economy you did not mean to install - some all-in-one plugins register one quietly - remove it, because two providers means `/balance` and the shop are reading different numbers.

The other prerequisite is permissions. Shop plugins split creation from use, and you almost always want them on different groups: everyone can buy, members who have played a while can create, and only one staff group can create admin shops. [The LuckPerms guide](https://www.renode.space/blog/minecraft-luckperms-guide) covers group inheritance, which is where a moderator rank accidentally picks up an admin-shop node.

#### ChestShop: sign shops on chests

ChestShop is the older of the two and still maintained. A shop is a sign placed on or next to a chest, and the four lines of the sign are the whole configuration:

```text
Line 1:  (leave blank - your name is filled in)
Line 2:  16
Line 3:  B 20:12 S
Line 4:  Oak Log
```

Reading it line by line:

- **Line 1** is the owner. Leave it blank and ChestShop writes your name.
- **Line 2** is the quantity per transaction.
- **Line 3** is the price. `B 20` means a customer can buy 16 logs for 20. `S 12` means a customer can sell 16 logs to the shop for 12. `B 20:12 S` does both. Use `free` instead of a number to give items away.
- **Line 4** is the item. Write `?` and ChestShop fills it in from the first item in the chest, which avoids most spelling problems.

Item names longer than a sign line are abbreviated. `/iteminfo` (alias `/iinfo`) with the item in hand prints the exact name ChestShop expects, including the code it uses for enchanted or renamed items.

By default a customer right-clicks the sign to buy and left-clicks to sell. `REVERSE_BUTTONS` in the config swaps them, which some servers do because left-click is also "break block" and new players trying to buy end up selling.

The spread on line 3 is your first anti-exploit check. A shop that sells for 12 and buys for 20 can be drained in a loop by anyone with money: buy at 12, sell back at 20, repeat until the owner is broke. Recent ChestShop builds can refuse such shops; check your generated config for an option that does, and teach players that the `B` number should always be the larger one.

##### ChestShop admin shops and config

An admin shop is a sign with `Admin Shop` on line 1, created by someone with `ChestShop.admin`. It has unlimited stock and unlimited money - it does not draw from or pay into any player's balance. The text is set by `ADMIN_SHOP_NAME` in the config.

The settings that matter for the economy live in `plugins/ChestShop/config.yml`. Key names below are from ChestShop 3.x; check your own generated file, since options are added between releases.

plugins/ChestShop/config.yml:

```yaml
ADMIN_SHOP_NAME: Admin Shop
SERVER_ECONOMY_ACCOUNT: ''
TAX_AMOUNT: 5
SERVER_TAX_AMOUNT: 0
SHOP_CREATION_PRICE: 250
SHOP_REFUND_PRICE: 0
REVERSE_BUTTONS: false
```

What each of those does:

- `TAX_AMOUNT` is a percentage taken from player shop transactions. Default 0. A few percent is the single most effective money sink you can add to a player market, because it scales with how much trade happens.
- `SERVER_TAX_AMOUNT` is the same for admin shop transactions.
- `SERVER_ECONOMY_ACCOUNT` names an account that admin shop money and taxes go to. Left empty, money paid to an admin shop simply leaves the economy, which is usually what you want - a sink is a sink. Set it only if staff need a real treasury to spend from, and then treat that account's balance as a faucet you control.
- `SHOP_CREATION_PRICE` and `SHOP_REFUND_PRICE` charge for making a shop and refund on breaking one. A creation fee with no refund is a one-off sink and discourages players from scattering dozens of junk shops.

Permissions follow the obvious pattern: `ChestShop.shop.create.buy` and `ChestShop.shop.create.sell` to make shops, `ChestShop.shop.buy` and `ChestShop.shop.sell` to use them, `ChestShop.admin` for admin shops and full access to other people's shops, and `ChestShop.mod` for staff who need to look inside shops without owning them.

#### QuickShop-Hikari: click a chest, type a price

QuickShop-Hikari is the maintained fork of the QuickShop line, and it is the plugin to choose when you would rather not explain sign formats to every new player. Creating a shop is:

1. Place a chest and stock it.
2. Hold the item you want to sell and left-click the chest.
3. Type the price per item in chat.

The plugin puts a sign on the chest and a floating display of the item above it. A new shop is in selling mode: customers buy from it. The owner switches it with `/qs buy` (the shop buys from customers) and back with `/qs sell`. Note that QuickShop's naming is from the shop's point of view, and ChestShop's `B` and `S` are from the customer's. Players moving between servers mix these up constantly.

| Command | What it does |
| --- | --- |
| `/qs price <amount>` | Change the price of the shop you are looking at |
| `/qs buy` / `/qs sell` | Switch the shop's mode |
| `/qs staff add <player>` | Let another player restock and manage it |
| `/qs unlimited` | Admin: infinite stock and money |
| `/qs find <item>` | Find the nearest shop selling an item |
| `/qs remove` | Remove the shop you are looking at |

`/qs` is an alias for `/quickshop`; the plugin also registers `/shop`, which collides with menu-shop plugins that use the same command. Check the alias list in its config if `/shop` opens the wrong thing.

Permissions: `quickshop.use` for anything at all, `quickshop.create.sell` and `quickshop.create.buy` to make each kind, and the umbrella `quickshop.player` that grants the ordinary player set. Keep the unlimited and admin nodes on one staff group.

##### Storage, displays and versions

Unlike ChestShop, QuickShop keeps its shops in a database: a local file database by default, or MySQL if you point it at one. On a single server the default is fine. If you would rather keep shop data next to your other plugin tables, the game plan's database slot works - [MySQL for Minecraft plugins](https://www.renode.space/blog/minecraft-mysql-for-plugins) covers the connection details and table prefixes. Either way, shop data is now in two places: chests and signs in the world files, and shop records in the database. Back them up together, or a restore leaves shops pointing at chests that no longer hold what the database thinks they hold.

The floating display item deserves a look. Early QuickShop versions displayed it as a real dropped item, and real items are something hoppers, players and other plugins can sometimes pick up - historically a duplication source. Modern Hikari offers non-entity display modes; check which one your config uses and prefer the one that does not spawn an entity. It is also kinder to entity counts on a busy market, which matters if you already run [entity cleanup](https://www.renode.space/blog/minecraft-entity-cleanup-and-clearlag) that might try to remove "dropped items".

Hikari tracks recent Paper releases closely and has raised its minimum Java version over time. Match the plugin build to your server version from its download page, and update it as part of every [version upgrade](https://www.renode.space/blog/minecraft-version-upgrades) rather than afterwards.

#### EssentialsX signs: Buy, Sell and Trade

EssentialsX ships signs as part of the base jar, but they only work for types listed under `enabled-signs` in `plugins/Essentials/config.yml`. Creating each type needs `essentials.signs.create.<type>` and using it `essentials.signs.use.<type>`.

`[Buy]` and `[Sell]` are server shops with infinite stock:

```text
[Buy]        [Sell]
16           16
oak_log      oak_log
$20          $12
```

Line 2 is the amount, line 3 the item, line 4 the price. A `[Buy]` sign takes money and creates items; a `[Sell]` sign takes items and creates money. That second one is a faucet with no upper limit, and it deserves exactly the same caution as any admin shop - see the next section.

`[Trade]` is the player shop:

```text
[Trade]
$20
16 oak_log:256
(owner, filled in)
```

Line 2 is what the customer pays, line 3 is what they receive and the total stock loaded into the sign, and line 4 becomes the owner's name when the syntax is accepted. Either line can be money or items, so a trade sign can sell for money, buy for money, or barter diamonds for logs. The owner restocks by right-clicking the sign with the item and collects takings the same way.

Trade signs have one real advantage - no chest, so nothing to break into or drain with a hopper - and two disadvantages. Buyers cannot see stock without clicking, and a market of trade signs gives you no searchable list of prices. For anything bigger than a few stalls, a chest shop plugin is the better tool. Essentials signs and a chest shop plugin coexist without trouble; many servers use `[Buy]` signs at spawn and QuickShop everywhere else.

#### Admin shops without printing money

Every serious economy problem on a Minecraft server comes back to an admin shop that buys something. An infinite buyer at a fixed price turns any farmable item into money at a rate limited only by how many farms players build. Iron farms, gold farms, sugar cane, bamboo, kelp, melons and mob drops all qualify, and players are very good at building farms.

The safe pattern is an admin shop that mostly sells:

- **Sell what players cannot make.** Spawn eggs if you allow them, name tags, cosmetic blocks, elytra if your End is scarce. These are sinks: money leaves the economy and does not come back.
- **Sell basics at a high price.** An admin shop selling oak logs at 5 each sets a price ceiling. Players can undercut it, which is what you want, but nobody is ever stuck without logs.
- **Buy only what cannot be automated, and cap it.** If the server must buy something - say, to give new players an income - choose items that need active play, and price them low enough that it is a bootstrap, not a career.
- **Never buy what you also sell.** An admin shop that sells at 5 and buys at 6 is an infinite money loop. It sounds like an obvious mistake; it happens every time someone edits prices in two different plugins.

```diagram
title: Where money enters and leaves a shop economy
farms = Player farms | logs, iron, crops
adminbuy = Admin buy shop | money printed
players = Player balances
pshops = Player shops | money moves sideways
tax = Shop tax | money removed
adminsell = Admin sell shop | money removed
farms -> adminbuy : items in
adminbuy -> players : faucet
players <-> pshops : trades
pshops -> tax : % per sale
players -> adminsell : sink
```

Player-to-player trade is the healthy middle of that picture. Money moves between balances without being created, and stock is finite because somebody had to gather it. The only way trade alone grows the money supply is through dupes, which is the next problem.

#### Stopping dupes before they reach a shop

A duplication exploit on a server without a market is a nuisance. On a server with a market it is a counterfeit press: the duped items are sold to anyone who will buy them, and if an admin shop buys them, straight into new money. Most dupes fall into three groups.

**Vanilla mechanics.** TNT duplication, carpet and rail duplication with pistons, and bedrock breaking are all fixed or disabled on Paper by default. They come back if someone flips the switches in `config/paper-global.yml`:

config/paper-global.yml:

```yaml
unsupported-settings:
  allow-piston-duplication: false
  allow-permanent-block-break-exploits: false
  allow-headless-pistons: false
```

Technical-minded communities sometimes ask for these. If you turn them on, do not have an admin shop that buys TNT, carpet, rails or anything they feed into.

**Shop chest edge cases.** A shop chest with a hopper underneath, a hopper minecart passing below, a second chest placed beside it to make a double chest, or a piston pushing the sign away. Modern versions of both ChestShop and QuickShop-Hikari handle the common cases, but protection plugins, region flags and other plugins all interact. Test it yourself as a second account before launch: try to open someone else's shop chest, break its sign, place a hopper under it, and run a hopper minecart beneath it. Land claims add a second layer - [grief protection and anti-cheat](https://www.renode.space/blog/minecraft-grief-protection-and-anti-cheat) covers GriefPrevention and WorldGuard.

**Plugin bugs.** Shop plugins, backpack plugins, custom-item plugins and auction houses have all shipped dupes at some point. Keep them updated, read changelogs for the word "dupe", and do not run abandoned forks.

When a dupe happens, evidence is what lets you fix it without a wipe. With CoreProtect installed, `/co lookup u:<player> t:3d a:container` shows what a player put into and took out of containers, and `/co inspect` on a shop chest shows its history. Combine that with EssentialsX's `economy.log` and you can usually see the exact moment items appeared and where the money went. Remove the items and the money from the accounts involved, rather than rolling the whole world back - a world rollback also undoes three days of honest trade.

> [!WARNING]
> Shop data, world files and balances are three stores that must agree. A world restore without the shop database, or a balance restore without the world, leaves shops claiming stock that does not exist or players holding money for items they still have. Back up the server as a whole, from one schedule, and restore it as a whole.

#### Balancing a player economy

Once player shops exist, most prices are set by players, and your job changes from setting prices to controlling the money supply around them. The levers, in order of usefulness:

1. **Tax every shop sale.** A 3-5% `TAX_AMOUNT` on ChestShop, or the equivalent tax setting in QuickShop-Hikari, removes money in proportion to activity. A busy economy pays more, a quiet one less, and you never have to re-tune it.
2. **Charge to create shops.** A one-off fee, refunded partly or not at all. It is a small sink and it keeps the market tidy.
3. **Limit shops per player.** QuickShop-Hikari has a shop limit you can tie to permission groups; for ChestShop, land claim size is usually the effective limit. Unlimited shops per player encourages one person to corner a market with fifty chests.
4. **Keep admin shops as ceilings and floors, not markets.** The admin sell price is the most anyone will pay; any admin buy price is the least anyone will accept. Leave a wide gap between them so players trade inside it.
5. **Make the income side boring and capped.** Jobs, vote rewards and playtime payouts should give a new player enough to start, not enough to retire.

A worked example. Ten players, a starting balance of 100, no admin buy shop, a 5% tax on player shops and `/home` costing 10. Player-to-player trade moves money around and burns 5% of everything sold; teleports burn a steady trickle. Without any income at all, the money supply would slowly shrink and prices would fall - deflation is as bad as inflation, because nobody wants to sell. So add one faucet you control: a daily playtime reward, or a Jobs payout set low. Watch `/baltop` weekly. If the total keeps rising faster than the player count, cut the faucet; if it falls, raise it. That is the whole of central banking, and it works on a Minecraft server for the same reason it works anywhere: you adjust the one number you control and let the market sort out the rest.

Things that look like balancing and are not: editing every player shop price by decree, capping prices in config, or banning a player who got rich legitimately. Fix the faucet that made them rich and their wealth inflates away.

If you plan to sell anything for real money on top of this, read [rank stores and the Minecraft commercial rules](https://www.renode.space/blog/minecraft-rank-store-tebex-rules) first; in-game currency sold for cash is exactly what the rules restrict.

#### Running shops on a hosted server

On RE:NODE, Minecraft plans run Paper with the matching Java version, so the plugins above install as jar files uploaded through the file manager or SFTP into `plugins/`, followed by a restart. There is no one-click plugin installer and no list of allowed plugins - you bring the jars you want. Every game plan includes one database slot, created in the panel with its host, user and password generated, which is enough for QuickShop-Hikari's MySQL storage if you want it there. Backups run on demand or from the Schedules tab and restore with one button, which is how you take the single, consistent snapshot of world, plugin files and shop data that the warning above asks for - see [backups in the guides](https://www.renode.space/guides#backups).

Shops themselves cost little CPU. A busy market district costs more through the things around it: dropped-item displays, hopper chains feeding shop chests and the farms that supply them. If a market starts to lag, [villager and mob farm lag](https://www.renode.space/blog/minecraft-villager-and-mob-farm-lag) is the usual cause rather than the shop plugin.

#### Troubleshooting

**The shop plugin disables itself at startup.** No economy provider registered. Run `vault-info`; if the economy line is empty, look higher in the log for the economy plugin's own error.

**A ChestShop sign stays as plain text.** The format was rejected. Usually line 4 has an item name ChestShop does not recognise - use `?` or the name from `/iteminfo` - or the player lacks `ChestShop.shop.create.buy` or `.sell`.

**Customers sell when they meant to buy.** Left-click versus right-click on ChestShop. Explain it on a sign at the market entrance, or set `REVERSE_BUTTONS`.

**QuickShop asks for a price and nothing happens.** The chat message was taken by a chat plugin or a pending command. Check that a chat formatting or anti-spam plugin is not cancelling the message before QuickShop sees it, and that the player typed only a number.

**Essentials `[Trade]` sign will not accept stock.** The item in hand does not match line 3 exactly, or `trade` is missing from `enabled-signs`.

**A shop sells stock it does not have.** Admin mode is on (`/qs unlimited`, or `Admin Shop` on a ChestShop sign). Check before blaming a dupe.

**Prices are meaningless after a month.** An admin shop is buying something farmable. Find it in `economy.log` - one item will account for most of the income.

#### FAQ

##### Which is better, ChestShop or QuickShop-Hikari?

Neither is better at the economy; they differ in how players use them. QuickShop-Hikari is easier for new players and searchable with `/qs find`. ChestShop is more explicit, needs no database, and its signs show the full deal at a glance. Pick by your players, not by the feature list.

##### Do shop plugins work without EssentialsX?

Yes, as long as some economy provider is registered with Vault. EssentialsX is the common provider, but any Vault-compatible economy plugin works the same way from the shop's point of view.

##### Should the server run its own shop at all?

A small one that mostly sells, yes - it guarantees basics and sets a price ceiling. A server shop that buys farmable items at fixed prices is the most common cause of runaway inflation, so keep its buy list short or empty.

##### Can I move shops from ChestShop to QuickShop?

Not with a built-in converter that we can vouch for. The practical route is announcing a date, letting players empty their ChestShop chests, removing the plugin and letting them create new shops. Converting by hand is rarely worth the risk to stock.

##### How do I find out who duped items into a shop?

Block and container logging. CoreProtect's container lookups show what went into a chest and who put it there, and the EssentialsX economy log shows where the money went afterwards. Without logging installed before the dupe, you are guessing.

Minecraft plans on RE:NODE run Paper with the matching Java version and a world already generated. Upload Vault, an economy and your shop plugin through the file manager or SFTP, use the included database slot if your shops want MySQL, and schedule backups from the panel. From $5 a month.

[See Minecraft plans](https://www.renode.space/game-servers/minecraft)

---

### PaperMC download API: scripting Paper, Velocity and Folia jars

Published 2026-10-15 by RE:NODE Team. https://www.renode.space/blog/papermc-download-api

If your script still fetches Paper from `api.papermc.io/v2/...`, it is broken: the v2 API was sunset on 1 July 2026 and every request to it now returns `410 Gone`. The replacement is the Fill API at `https://fill.papermc.io/v3/`, and the change is small once you know it. You ask `/v3/projects/paper/versions/<version>/builds?channel=STABLE`, take the first build in the list, and the JSON hands you a ready-made download URL on `fill-data.papermc.io` together with a sha256 checksum. Send a User-Agent that names your script and gives a contact, verify the checksum, and pin the build you tested rather than chasing the newest one. The rest of this post is the detail: every endpoint you need, what the channels mean, a complete update script, and the mistakes that leave a server with a half-downloaded jar.

#### What happened to api.papermc.io/v2

For years the download URL for a Paper jar had one well-known shape, and thousands of scripts, Dockerfiles and setup guides hard-coded it:

```text
https://api.papermc.io/v2/projects/paper/versions/<ver>/builds/<build>/downloads/<file>.jar
```

You built it from three pieces - the Minecraft version, the build number and the file name, which was always `paper-<ver>-<build>.jar` - and you could fetch it without asking the API anything first if you already knew the build. That convenience is gone. PaperMC replaced the old service, called Bibliothek, with a new one called Fill, and retired the v2 endpoints. Today both the metadata endpoints and the old download URLs answer like this:

```text
HTTP/1.1 410 Gone
sunset: Wed, 1 Jul 2026 00:00:00 GMT

{"ok":false,"error":"sunset","message":"This API version has been sunset and is
no longer available. To continue using the service, please upgrade to a supported
API version."}
```

There is no redirect and no grace period left. If a server's start script downloads its jar on every boot, or a container image fetches Paper at build time, the symptom is a download that "succeeds" with `wget` or a plain `curl` and leaves you with a 176-byte JSON file called `server.jar`. Java then refuses it with `Error: Invalid or corrupt jarfile server.jar`, which sends people looking at Java versions instead of at the URL. Using `curl -f` (fail on HTTP errors) turns this into a clear error at the download step, and it is the first thing the script further down does.

Also note that `api.papermc.io/v3` does not exist; the new API lives on a different host, `fill.papermc.io`, and the jars themselves on a third, `fill-data.papermc.io`. If your firewall or proxy has an allow list for outbound traffic, all three names have changed.

#### The Fill v3 endpoints

The v3 API is a small REST tree with the same shape as before - projects, versions, builds - and JSON throughout. These are the requests a script actually needs:

| Endpoint | Returns |
| --- | --- |
| `/v3/projects` | Every project with its versions |
| `/v3/projects/paper` | One project, versions grouped by family |
| `/v3/projects/paper/versions/26.3` | Support status, Java minimum, build ids |
| `/v3/projects/paper/versions/26.3/builds` | Every build, newest first, full detail |
| `/v3/projects/paper/versions/26.3/builds?channel=STABLE` | The same list, one channel only |
| `/v3/projects/paper/versions/26.3/builds/189` | One build by number |
| `/v3/projects/paper/versions/26.3/builds/latest` | The newest build of any channel |

All of them hang off `https://fill.papermc.io`. The project ids are `paper`, `folia` and `velocity`; the retired `waterfall` and `travertine` proxies are still listed for their old builds, but nothing new is published for them.

The project endpoint groups versions by family, newest family first and newest version first within each family:

```json
{"project":{"id":"paper","name":"Paper"},
 "versions":{"26.3":["26.3","26.3-rc-3"],
             "26.2":["26.2","26.2-rc-2"],
             "26.1":["26.1.2","26.1.1"],
             "1.21":["1.21.11","1.21.11-rc3", "...", "1.21"]}}
```

Two things to notice. Minecraft's own version numbers changed in 2026 to a year-based scheme, so the list runs from `26.3` back to `1.21.11` and beyond, and anything that sorts versions as strings will put them in the wrong order. And release candidates and pre-releases (`26.3-rc-3`, `1.21.11-pre5`) sit in the same list as real releases. A script that takes "the first version in the list" will one day pick a release candidate. If you want the newest release automatically, filter out ids containing `-` - though, as below, picking the Minecraft version automatically is a bad idea anyway.

The version endpoint is the one people overlook, and it is the most useful for a careful script:

```json
{"version":{"id":"1.21.4",
            "support":{"status":"UNSUPPORTED","end":"2025-07-17"},
            "java":{"version":{"minimum":21},
                    "flags":{"recommended":["-XX:+UseG1GC", "..."]}}},
 "builds":[232, 231, "..."]}
```

`support.status` tells you whether PaperMC still maintains that version (`SUPPORTED` or `UNSUPPORTED`, with an end date), and `java.version.minimum` tells you which Java the jar needs - 21 for the 1.21 line, 25 for the 26.x releases. A script can refuse to install a jar the machine's Java cannot run, which is far friendlier than the `UnsupportedClassVersionError` you otherwise get on start. The recommended flags are the familiar G1 set; [Minecraft JVM flags and Java versions](https://www.renode.space/blog/minecraft-jvm-flags-and-java-versions) explains what each of them does.

A build object carries everything needed to download and check the jar:

```json
{"id":189,
 "time":"2026-10-14T20:17:18Z",
 "channel":"STABLE",
 "commits":[{"sha":"a48059a2...","message":"Correctly serialise decorated pod ..."}],
 "downloads":{"server:default":{
    "name":"paper-26.3-189.jar",
    "checksums":{"sha256":"3a90c2ea79a81cd0ce641c9954c616828be6d32255385aef3b2022f80b91e8b5"},
    "size":55150184,
    "url":"https://fill-data.papermc.io/v1/objects/3a90c2ea.../paper-26.3-189.jar"}}}
```

The download key is `server:default` for all three projects (v2 used `application`), and the key contains a colon, so in `jq` it must be quoted: `.downloads."server:default".url`. The URL itself is content-addressed - the path contains the jar's sha256 - so it never changes for a given build and can be cached safely. Do not build this URL yourself; read it from the API. That is the main behavioural difference from v2, where constructing the URL from version and build was the normal way to work.

Errors come back as JSON with an `error` code and the right HTTP status: a build that does not exist gives `404` with `build_not_found`, an unknown version gives `version_not_found`. The API also offers a GraphQL endpoint at `https://fill.papermc.io/graphql` for anyone who prefers it; everything in this post uses REST because `curl` and `jq` are on every Linux box.

#### Channels: ALPHA, BETA and STABLE

v2 had two channels, `default` and `experimental`. Fill has three, and every build carries one:

| Channel | What it means |
| --- | --- |
| `STABLE` | The builds PaperMC recommends for production |
| `BETA` | Feature-complete for a version, still settling |
| `ALPHA` | Early builds of a new Minecraft version |

A new Minecraft release starts life as a run of `ALPHA` builds, moves to `BETA` once it is usable, and becomes `STABLE` when PaperMC is happy with it. On 26.3 at the time of writing there were 48 alpha builds, 38 beta builds and 15 stable ones, which gives a sense of how long the unstable stretch is. Release candidates such as `26.3-rc-3` may never get a stable build at all.

PaperMC's own documentation is blunt about this: use stable builds, and do not run unstable builds or auto-updaters in production, because experimental builds are prone to errors and do not receive support. That is worth taking literally. A Discord report that starts with "I'm on an alpha build" gets one answer.

> [!WARNING]
> `builds/latest` is the newest build of any channel. It does not take a `channel` parameter - adding `?channel=STABLE` is silently ignored. On a version that is still in alpha, `latest` hands you an alpha. Use `builds?channel=STABLE` and take the first element instead.

The `channel` filter on the builds list does accept several values (`?channel=STABLE&channel=BETA`), which is useful for a staging server that should test betas before they reach production.

#### User-Agent etiquette, and why it is now a rule

Under v2, a User-Agent was polite. Under Fill it is required. PaperMC's downloads documentation states that every request must carry a User-Agent that clearly identifies your software or organisation, is not a generic default such as `curl/8.5.0` or `Wget/1.21`, and includes a contact URL or email address. Their own example is the one used by the popular Docker image:

```text
mc-image-helper/1.39.11 (https://github.com/itzg/docker-minecraft-server)
```

A request without one may well work today, especially for responses served from cache - but relying on that is building on something the operators have said they do not allow, and a blocked script fails in exactly the same confusing way as the v2 sunset did. The format that satisfies the rule is `name/version (contact)`:

```bash
$ curl -A "smp-updater/1.2 (admin@example.net)" \
    https://fill.papermc.io/v3/projects/paper
```

The rest of the etiquette follows from the same idea: the API is a free service run by volunteers, and a script that hammers it is the reason rules like this exist.

- **Do not poll.** Checking once a day, or once before each scheduled restart, is plenty. Paper can publish several builds in one evening; you do not need each of them within minutes.
- **Do not download what you already have.** Compare the build id (or the sha256) with the one installed and stop if they match. The script below does this.
- **Respect the cache headers.** The metadata responses carry `cache-control: max-age=1800`. Asking more often than every half hour gets you the same answer.
- **Fetch the jar once per machine**, not once per server start. A network that runs eight backends from one machine should download one jar and copy it.

#### Pinning a build versus following the latest

There are two quite different things you might mean by "update Paper", and a script should only ever automate one of them.

**Builds within one Minecraft version** are mostly bug fixes and performance work. Moving from build 187 to 189 of 26.3 does not convert the world or change the plugin API, and a script that follows the latest stable build of a fixed version is reasonable for many servers. Even here, the occasional build changes behaviour a plugin relied on, or tightens something that was being abused - a recent 26.3 build that stopped plugins resetting brewing recipes off the main thread is exactly that kind of change. For a small group server, following stable builds weekly is fine. For a server with dozens of plugins, pin the build you tested and move it forward deliberately.

**A new Minecraft version** is a different event entirely. The world is converted on first load and cannot be opened by the older version again, plugins compiled against the old version often break, and the clients must match. That should never happen because a script noticed a new entry at the top of the version list. Keep the Minecraft version as a fixed setting, chosen by a person, and walk through [Minecraft version upgrades](https://www.renode.space/blog/minecraft-version-upgrades) when you change it.

Pinning in practice means writing the build down. Either keep the exact build id in a config file and have the script install that id, or let the script follow stable builds but record each install in a log so you know which build to go back to. The version endpoint lists every build id that exists, so a pinned id stays fetchable. Keep the previous jar beside the current one; rolling back a build within the same Minecraft version is a file rename, provided the world has not been converted.

#### A curl and jq update script

This script installs the newest stable build of one fixed Minecraft version, or a pinned build if you give it one. It verifies the checksum before touching the live jar, keeps the previous jar for rollback, and does nothing at all if the installed build is already current. It needs `bash`, `curl`, `jq` and `sha256sum`.

update-paper.sh:

```bash
#!/usr/bin/env bash
# Usage: update-paper.sh <minecraft-version> [build]
set -euo pipefail

PROJECT="${PROJECT:-paper}"            # paper, folia or velocity
VERSION="${1:?usage: $0 <minecraft-version> [build]}"
PIN="${2:-}"                           # optional exact build id
DIR="${DIR:-/home/mc/server}"
JAR="$DIR/server.jar"
STATE="$DIR/.${PROJECT}-build"
UA="smp-updater/1.2 (admin@example.net)"
API="https://fill.papermc.io/v3/projects/$PROJECT/versions/$VERSION"

if [[ -n "$PIN" ]]; then
  build=$(curl -fsS -A "$UA" "$API/builds/$PIN")
else
  build=$(curl -fsS -A "$UA" "$API/builds?channel=STABLE" | jq -e '.[0]') \
    || { echo "No stable $PROJECT build for $VERSION" >&2; exit 1; }
fi

id=$(jq -r '.id' <<<"$build")
url=$(jq -r '.downloads."server:default".url' <<<"$build")
sha=$(jq -r '.downloads."server:default".checksums.sha256' <<<"$build")
name=$(jq -r '.downloads."server:default".name' <<<"$build")

if [[ -f "$STATE" && "$(cat "$STATE")" == "$id" ]]; then
  echo "$PROJECT $VERSION build $id already installed"; exit 0
fi

tmp=$(mktemp "$DIR/.download.XXXXXX")
trap 'rm -f "$tmp"' EXIT
curl -fsS -A "$UA" -o "$tmp" "$url"
echo "$sha  $tmp" | sha256sum -c --quiet -

[[ -f "$JAR" ]] && cp -p "$JAR" "$JAR.prev"
mv "$tmp" "$JAR"
echo "$id" > "$STATE"
echo "$(date -Is) installed $name" >> "$DIR/update.log"
```

Run it as `./update-paper.sh 1.21.11` to follow stable builds of 1.21.11, or `./update-paper.sh 1.21.11 132` to install exactly build 132. The same script handles Velocity and Folia through the `PROJECT` variable:

```bash
$ PROJECT=velocity DIR=/home/mc/proxy ./update-paper.sh 4.2.0
$ PROJECT=folia ./update-paper.sh 26.3
```

Why each piece is there:

- `curl -f` turns an HTTP error into a non-zero exit, so a `410`, `404` or blocked request stops the script instead of producing a JSON file named like a jar. `-sS` keeps the output quiet but still prints real errors.
- `jq -e '.[0]'` exits non-zero when the array is empty - a version with no stable builds yet - so the script stops with a message rather than requesting a URL of `null`.
- The download goes to a temporary file in the same directory, and only replaces the live jar after the checksum passes. Writing straight over `server.jar` means a dropped connection leaves you with a truncated jar and a server that will not start. Keeping the temporary file on the same filesystem makes the final `mv` atomic.
- `sha256sum -c` expects two spaces between the hash and the file name. With one space it reports a formatting error rather than a mismatch, which is a common copy-paste failure.
- The state file holds the installed build id, so running the script twice in a row downloads nothing the second time.

Run it while the server is stopped, or at least restart straight after: the JVM has the old jar open, and Paper reads its patched classes from the cache directory it builds on first start. The new build takes effect on the next start, when Paperclip notices the new jar and repatches, which adds a few seconds to that first boot.

On macOS `sha256sum` may not exist; `shasum -a 256 -c` takes the same input. On Windows the equivalent check is `Get-FileHash -Algorithm SHA256` in PowerShell, compared with the `sha256` field.

#### Folia and Velocity specifics

The API is identical for the other two projects, but what you do with the result is not.

**Velocity** versions are the proxy's own version numbers, not Minecraft versions. The project lists families `4.0.0` and `3.0.0` with entries such as `4.2.0`, `3.5.0` and `3.6.0-SNAPSHOT`. Snapshot versions carry many builds; release versions carry very few - `4.2.0` had a single build, number 30, when this was written, and some older release ids such as `3.5.0` list no builds at all, so check before pinning one. The proxy's version is independent of the backend version, and one Velocity build generally supports a range of client versions, so updating it is less fraught than updating Paper - but a proxy update still interrupts every player on the network at once. Schedule it, do not let it happen on a timer in the evening. Note also that the 4.x line asks for Java 25. [Building a Velocity proxy network](https://www.renode.space/blog/minecraft-velocity-proxy-network) covers how the proxy and backends fit together.

**Folia** has far fewer versions and builds than Paper, and only versions that PaperMC has ported it to. Its plugin compatibility is the real constraint: a Folia update matters less than whether your plugins declare Folia support at all. Pin Folia builds and test them, as [Folia's regionised multithreading](https://www.renode.space/blog/minecraft-folia-regionised-multithreading) explains in more detail.

Forks such as Purpur and Pufferfish are not part of PaperMC's API. They have their own download services with their own URL schemes; [Purpur and Pufferfish forks](https://www.renode.space/blog/minecraft-purpur-and-pufferfish-forks) covers what they change and why you might want them.

#### Running it on a schedule without breaking anything

The script on its own is safe. What makes automation dangerous is when it runs and what happens next. A sound arrangement on a self-managed Linux machine looks like this:

1. A backup of the world runs first, every time. A build that corrupts a chunk is rare, but rare is not never, and the backup is cheap. [Minecraft world backup and restore](https://www.renode.space/blog/minecraft-world-backup-and-restore) covers what to include.
2. The update script runs with a fixed Minecraft version and the stable channel.
3. The server restarts at a quiet hour, after a warning in chat.
4. Something checks that the server came back - the log line `Done (...)! For help, type "help"` within a few minutes of start - and alerts a person if it did not.

crontab:

```bash
# 04:30 daily: back up, update within 1.21.11, restart
30 4 * * * /home/mc/backup.sh && /home/mc/update-paper.sh 1.21.11 && systemctl restart minecraft
```

The `&&` chain matters: no backup, no update; a failed download or checksum, no restart. [Automating game server updates](https://www.renode.space/blog/automating-game-server-updates) goes through the general policy - which servers can update themselves and which must not - and [restart schedules that help](https://www.renode.space/blog/restart-schedules-that-help) covers the restart side.

On RE:NODE, Minecraft servers are installed with Paper and the matching Java version, the EULA accepted and the world generated, so the first download is done for you. Replacing the jar later is a file operation: upload a build you have checked through the file manager or SFTP ([SFTP and the file manager](https://www.renode.space/blog/sftp-and-the-file-manager) has the details), and the Schedules tab can chain a backup, a chat warning and a restart in order with delays between them. Backup slots come with every Minecraft plan, so the step before an update is one button.

#### Troubleshooting the errors people actually hit

**`Error: Invalid or corrupt jarfile server.jar`.** The file is not a jar. Run `head -c 200 server.jar`: if it starts with `{"ok":false`, the download URL was an old v2 one or the request was rejected. Switch to the v3 endpoints and add `-f` to `curl` so this cannot happen silently again.

**`410 Gone` with `"error":"sunset"`.** You are on `api.papermc.io/v2`. There is no fix except moving to `fill.papermc.io/v3`. Check scripts, Dockerfiles, Ansible roles and any start script that downloads on boot - they tend to be forgotten because they worked for years.

**`jq: error: Cannot index array with "downloads"`.** You called the builds list but treated the result as one build. The list is an array; take `.[0]` first. The single-build endpoints (`builds/189`, `builds/latest`) return an object.

**The script installed an alpha.** It used `builds/latest`, which ignores channels. Use `builds?channel=STABLE` and the first element.

**Empty array from `?channel=STABLE`.** The version has no stable builds yet - common for a week or more after a Minecraft release, and permanent for release candidates. Wait, or stay on the previous version. Do not fall back to alpha automatically.

**`sha256sum: WARNING: 1 computed checksum did NOT match`.** The download was cut short or altered on the way. Do not install it; delete the file and download again. If it fails repeatedly, compare the file size with the `size` field in the build JSON - a proxy or captive portal in between is the usual cause.

**`UnsupportedClassVersionError` after updating.** You moved to a Minecraft version whose jar needs newer Java - 26.x needs Java 25. Read `java.version.minimum` from the version endpoint before installing.

#### FAQ

##### Does the old api.papermc.io v2 URL still work for old builds?

No. Every v2 path, including direct jar downloads of builds published years ago, returns `410 Gone`. Old builds are still available through v3: the version endpoint lists every build id, and each build's JSON has its download URL.

##### Is a User-Agent really required, or just recommended?

PaperMC's documentation says every request must include one that names your software and gives a contact, and that generic defaults like `curl/...` are not acceptable. Some requests may still be answered without it, but that is not something to build a script on.

##### Should the script pick the newest Minecraft version automatically?

No. A new Minecraft version converts the world irreversibly, breaks plugins and requires every player to update their client. Automate builds within a version you chose; change the version yourself, with a backup.

##### How do I get the download link for a specific older Paper build?

Request `https://fill.papermc.io/v3/projects/paper/versions/<version>/builds/<build>` and read `.downloads."server:default".url`. Do not try to construct the URL from the version and build number - in v3 the path contains the file's checksum, so it cannot be guessed.

##### Does Velocity follow Minecraft version numbers?

No. Velocity versions (`3.5.0`, `4.2.0` and so on) are the proxy's own releases, and each one supports a range of client versions. Read the release notes for the range rather than matching numbers.

##### Is the checksum check worth the extra line?

Yes. It is the difference between a server that refuses to update and one that refuses to start. A truncated download is far more common than tampering, and both are caught by the same line.

Minecraft servers on RE:NODE are installed with Paper and the matching Java version, the EULA accepted and the world generated, from $5 a month. Swap jars through the file manager or SFTP, and let the Schedules tab run the backup and restart around an update.

[See Minecraft plans](https://www.renode.space/game-servers/minecraft)

---

### All the Mods server: ATM10 and ATM9 setup

Published 2026-10-07 by RE:NODE Team. https://www.renode.space/blog/minecraft-all-the-mods-server

An All the Mods server is a big modded server with a few specific habits. ATM10 runs on NeoForge for Minecraft 1.21.1 with Java 21 and well over 400 mods; ATM9 runs on Forge for 1.20.1 with Java 17 or newer. Both ship a server files zip on the pack's CurseForge page with a start script that installs the loader on first run, and a `user_jvm_args.txt` that sets memory - the ATM10 server files set `-Xmx8G`. That is the realistic minimum: plan for 8 GB for a few players and 10 to 12 GB for a busy group, expect the first start to take several minutes and later starts two or three, and budget most of your effort for the things that make big packs lag over time - force-loaded chunks, automated factories, and terrain generated on the fly.

The general modded-server material - Java versions, reading crash reports, client-only mods - is in [running a modded server without the crashes](https://www.renode.space/blog/modded-minecraft-without-the-crashes). This guide covers what is specific to running an ATM pack.

#### Which pack, and what it needs

The All the Mods team publishes several packs. The ones people usually mean:

| Pack | Minecraft | Loader | Java | Notes |
| --- | --- | --- | --- | --- |
| All the Mods 10 | 1.21.1 | NeoForge | 21 | Current main pack |
| All the Mods 9 | 1.20.1 | Forge | 17+ | Mature, very large, many servers still on it |
| "To the Sky" variants | Varies | Varies | Varies | Skyblock versions; generation is cheaper |
| Older (ATM8, ATM7) | 1.19.2 / 1.18.2 | Forge | 17 | Still played, no longer the focus |

The exact loader version is pinned by each pack release. Use the one the server files install; do not "upgrade" NeoForge or Forge independently of the pack.

The pack is large in every dimension: hundreds of mods, more than a gigabyte of server files, and a world that grows fast because the pack adds dimensions, structures and ore generation. Disk space matters more than on vanilla - see the table below.

#### Getting the server files onto a server

On the pack's CurseForge page, each release has a separate server files download (look under the file's additional files, typically named something like `ServerFiles-<version>.zip`). Do not try to build a server from the client pack: the server files have client-only mods removed and the start scripts included.

1. Download the server files for exactly the pack version your players will use.
2. Unzip into the server's root folder. You get `mods/`, `config/`, `defaultconfigs/`, `kubejs/` and other folders, plus `startserver.sh` and `startserver.bat`, and `user_jvm_args.txt`.
3. Run `startserver.sh`. On first run it downloads and installs the loader and its libraries, writes a default `server.properties`, and starts the server.
4. Accept the EULA if asked (`eula=true` in `eula.txt`) and start again.
5. Wait. The first start generates configs and the world and is slow.

```bash
$ unzip ServerFiles-<version>.zip -d /srv/atm10
$ cd /srv/atm10
$ chmod +x startserver.sh
$ ./startserver.sh
```

On a panel, the same steps happen in the file manager and console: upload the zip, unpack it in place, and set the startup variables so the server launches the installed loader rather than a plain server jar. The installed loader writes its own launch arguments file (under `libraries/`) that the start script uses; [NeoForge server setup](https://www.renode.space/blog/minecraft-neoforge-server-setup) explains how those files fit together.

> [!WARNING]
> Never mix files from two pack versions. If the server is on 2.10 and players are on 2.11, they will be refused for mod mismatches, or worse, connect and desync. Pin the version in your Discord and update server and players together.

#### Memory, CPU and disk

The ATM10 server files set `-Xms4G -Xmx8G` in `user_jvm_args.txt`, and that is the floor, not the comfortable figure. From running these packs:

| Players | Heap (`-Xmx`) | Container / plan | CPU |
| --- | --- | --- | --- |
| 1-3, new world | 8 GB | 10 GB | 2+ fast cores |
| 4-8 | 10 GB | 12 GB | 2.5-3 cores |
| 8-15, mature world | 12 GB | 14 GB+ | 3.5+ cores |

The gap between the heap and the container limit is not optional. Java uses memory outside the heap - metaspace for hundreds of mods' classes, thread stacks, direct buffers - and on a pack this size that overhead is a gigabyte or two. A server with `-Xmx` equal to its container limit is killed from outside with no crash report, usually during chunk generation. [How much RAM a Minecraft server needs](https://www.renode.space/blog/how-much-ram-does-a-minecraft-server-need) explains the arithmetic, and [JVM flags](https://www.renode.space/blog/minecraft-jvm-flags-and-java-versions) covers the garbage collector side.

On RE:NODE plans, that means the 10 GB tier for a small group with an 8 GB heap, and the 14 GB tier for a busy server with a 12 GB heap. CPU scales with the tier, which matters as much as memory here - a big pack is limited by single-thread tick speed long before it runs out of heap.

Disk:

- Server files: 1.3 GB or so unpacked, more after first start creates libraries.
- World: a few GB for a well-explored mature world; much more if players fly around generating terrain in every dimension.
- Backups: multiply the world by the number you keep.

Twenty gigabytes is tight for a long-lived ATM server; plan more.

#### Startup time and the watchdog

A big pack loads every mod, every recipe and every registry before the world opens. Several minutes on first start and two or three on later starts is normal on good hardware.

Two settings in `server.properties` matter for big packs:

server.properties:

```properties
max-tick-time=180000
allow-flight=true
```

`max-tick-time` is the vanilla watchdog: if a single tick takes longer than this many milliseconds, the server kills itself and writes a thread dump. The default `60000` (one minute) is usually fine during play but can trip during heavy world generation or a large teleport on a big pack. Raising it to three minutes gives slow operations room; setting `-1` disables the watchdog completely, which means a truly hung server hangs forever. ATM packs may also include a mod-level watchdog setting in their configs.

`allow-flight=true` stops vanilla kicking players for "flying", which jetpacks, flight rings and creative-flight items trigger constantly. Every modded server needs it. [server.properties explained](https://www.renode.space/blog/minecraft-server-properties-explained) has the rest of the file.

#### Chunk loading and why ATM servers slow down over time

A new ATM world runs well. Six weeks later the same server with the same players lags. The reason is almost always chunk loading.

ATM packs include chunk claiming and loading, usually through FTB Chunks and FTB Teams. Players claim their base and force-load it so their machines run while they are offline. Every force-loaded chunk ticks forever - every machine, every farm, every pipe network - whether anyone is online or not. Twenty players, each force-loading a base of nine chunks full of machines, is a server permanently running twenty factories.

What to do:

- **Set a per-player force-load limit** in the FTB Chunks server config - small numbers, like four to nine chunks per player, are normal on busy servers.
- **Review force-loaded chunks** periodically. Players who left still have bases ticking.
- **Ask builders to keep machines compact.** A base spread over forty chunks cannot be force-loaded affordably.
- **Prefer offline-tolerant designs.** A lot of machines can run while players are online and catch up on demand instead of ticking all night.

The other slow-growth cost is the content of those chunks. The heavy hitters in a mature ATM world are large automated setups: AE2 networks with many crafting CPUs and interfaces, Mekanism factories and digital miners, mob farms with grinding mods, and item pipes moving large volumes. All of them are legitimate, all of them cost ticks, and all of them belong in a spark profile before they belong in an argument. [Reading a spark report](https://www.renode.space/blog/minecraft-spark-profiler-lag-diagnosis) works the same on NeoForge; spark is often already in the pack.

> [!TIP]
> Run `/forge tps` or `/neoforge tps` (depending on loader) to see tick time per dimension. A pack with many dimensions often has one - a mining dimension where someone left a quarry running - that is the whole problem.

#### Pre-generating the world

Terrain generation is the most expensive thing a modded server does, and ATM packs generate a lot: extra ores, modded structures, several extra dimensions. Players exploring on elytra or jetpacks generate chunks faster than the server can comfortably handle, and the whole server stutters while they do.

Pre-generation moves that cost to a time when nobody is playing. Chunky has NeoForge and Forge builds and is often already included; if not, add it to the server only (it is server-side).

```text
/chunky world minecraft:overworld
/chunky center 0 0
/chunky radius 5000
/chunky start
```

A 5,000-block radius on a big pack takes many hours. Run it overnight with nobody online, set a world border to match, and repeat for the Nether and any dimension players spend time in. [World borders and pre-generation](https://www.renode.space/blog/minecraft-world-border-and-pregeneration) covers how long it takes and how big the files get.

Leave mining dimensions that are meant to be reset ungenerated; they are temporary by design.

#### Updating the pack without losing the world

ATM packs update often, and updates are mostly mod updates and config changes, not new worlds. A safe procedure:

1. Read the changelog. Look for removed mods - blocks from a removed mod vanish from the world - and for notes that say a config folder must be replaced.
2. Stop the server cleanly and take a full backup.
3. From the new server files, replace `mods/`, `config/`, `defaultconfigs/`, `kubejs/` and any other pack folders the release notes mention. Delete the old `mods/` first; do not copy over it, or removed and renamed jars stay behind.
4. Keep `world/`, `server.properties`, `ops.json`, `whitelist.json`, `banned-players.json` and your own `user_jvm_args.txt` memory settings.
5. If the loader version changed, run the start script so it installs the new loader.
6. Start, watch the log, join, and check the main bases before telling players.

If you changed pack configs yourself, keep a list. Replacing `config/` wipes your changes; the list is how you put them back. [What to do when a mod update breaks](https://www.renode.space/blog/what-to-do-when-a-mod-update-breaks) is the recovery plan.

#### Errors ATM servers actually hit

**The server stops during the first start with no error.** The log ends mid-line and there is no crash report. That is almost always the process being killed from outside for exceeding its memory limit, because `-Xmx` was set to the whole plan. Lower the heap so there is headroom.

**"Mod rejections" or a list of missing mods when players join.** The client and server are on different pack versions, or a player added a mod that also needs to be on the server. Compare versions first; most cases are a launcher that auto-updated the client before the server was updated.

**The server crashes when a player enters a particular area.** A block entity in that chunk is crashing on tick. The crash report names the block and coordinates. Some packs include a setting to remove erroring block entities instead of crashing; otherwise, restore the region from a backup or remove the block with an editor. [Chunk errors and world corruption](https://www.renode.space/blog/minecraft-chunk-errors-and-world-corruption) covers the tools.

**`Can't keep up!` warnings during exploration.** Chunk generation is falling behind. Pre-generate, lower view distance, and limit how fast players can travel through new terrain.

**Startup hangs at the same mod every time.** A config file for that mod is corrupted or from a different version. Move that mod's config out of `config/` and let it regenerate. [Crash reports explained](https://www.renode.space/blog/minecraft-crash-reports-explained) shows how to read where it stopped.

On RE:NODE the Minecraft line ships Paper, so an ATM server is your own install: there is no one-click modpack installer and nothing on the panel reads a CurseForge pack. What helps is that the file manager unpacks the server files zip in place, the console shows the long first start unfiltered, and backup slots on every plan restore with a button. If the server reaches its memory limit it is stopped and restarted clean rather than left to swap - which is why the heap must leave room below the plan.

#### FAQ

##### How much RAM does an All the Mods 10 server need?

At least 8 GB of heap, which is what the server files set, inside a plan with a gigabyte or two more than that. For more than a handful of players or a mature world, a 10 to 12 GB heap is more comfortable.

##### Why does my ATM server take so long to start?

It loads hundreds of mods, every recipe and every registry before opening the world. Several minutes on the first start and two or three afterwards is normal. A start that takes much longer than usual is often a mod stuck on a network check or a corrupted config; the log shows where it stopped.

##### Can I add mods to an All the Mods server?

Yes, as long as players add the same mods for anything with blocks, items or entities. Server-only mods such as Chunky need nothing on the client. Adding mods means your server no longer matches the stock pack, so keep a list for updates.

##### Why does my server get slower every week?

Usually force-loaded chunks and growing factories. Every claimed and force-loaded base ticks all the time. Limit force-loading per player, review old claims, and profile with spark to find the factory doing the most work.

##### Do I need to pre-generate the world?

Strongly recommended. Terrain generation on a large pack is expensive and causes stutter for everyone while players explore. Pre-generate a few thousand blocks around spawn overnight and set a world border to match.

RE:NODE Minecraft plans go up to 14 GB of memory and run Paper by default; an ATM pack is your own upload, and the file manager unpacks the server files in place. Backup slots on every plan are stored off the machine and restore with a button, which is what you want before every pack update.

[See Minecraft plans](https://www.renode.space/game-servers/minecraft)

---

### Minecraft anarchy server: exploits and limits

Published 2026-10-07 by RE:NODE Team. https://www.renode.space/blog/minecraft-anarchy-server-guide

An anarchy server has no in-game rules - no claims, no bans for griefing or hacked clients, no rollbacks - but it still needs an operator, because the players who enjoy anarchy are exactly the players who will try to crash it. Run Paper, keep it updated, and leave its exploit protections switched on: the packet limiter, the book and item size limits, and the protections against piston and bedrock exploits. Limit how fast players can generate new terrain, decide in advance what you will do when the world fills the disk, and expect attacks. "No rules" is a promise about gameplay. It is not a promise to leave the server defenceless, and the servers that last treat the two as completely separate.

#### What anarchy means for the operator

The genre's archetype is 2b2t, running since 2010 on one world that has never been reset, with no rules, no bans for in-game behaviour and a map that has grown to an enormous size. Smaller anarchy servers copy the format: a vanilla-like survival world, no protection, hacked clients allowed, and history that accumulates.

From the operator's side, the job splits cleanly in two:

| In-game behaviour | Server integrity |
| --- | --- |
| Griefing, killing, stealing | Crash exploits and packet floods |
| Hacked clients for combat and movement | Lag machines built to stop the tick |
| Building anything, anywhere | Chunks made too large to load |
| Spawn being a wasteland | Disk and memory exhaustion |
| Not your problem | Entirely your problem |

Everything in the left column is the game. Everything in the right column ends the game for everyone, and most anarchy communities expect it to be handled. A player who crashes the server repeatedly is not playing anarchy; they are stopping anyone else from playing it.

One more line belongs above both columns: your host's terms and the law still apply. Illegal content, doxxing and attacks on other services are not gameplay, and "it's an anarchy server" is not a defence anyone else will accept.

#### Server software and base settings

Run Paper. Its patches against crash exploits, dupes and packet abuse are the reason anarchy servers can exist at all on modest hardware, and it is the first project to fix a newly discovered exploit. Vanilla and Fabric have far fewer of these protections, and the forks of Paper receive Paper's fixes later. Update promptly: on an anarchy server, a published crash exploit will be tried on you within days.

The relevant `server.properties` settings:

server.properties:

```properties
online-mode=true
spawn-protection=0
white-list=false
max-players=100
view-distance=8
simulation-distance=6
max-world-size=29999984
rate-limit=0
max-chained-neighbor-updates=1000000
network-compression-threshold=256
enforce-secure-profile=true
```

What each of those is doing:

- **`online-mode=true`** is not optional. An offline-mode anarchy server lets anyone log in as anyone, including you.
- **`spawn-protection=0`** removes the vanilla ring around spawn that only operators can edit. Anarchy spawns are meant to be destroyed.
- **`max-world-size`** is the world's hard edge, defaulting to `29999984`. Lower it if you want a finite world; more on that below.
- **`rate-limit`** is a vanilla per-connection packet limit, `0` meaning off. Paper's packet limiter is more precise, so leave this at `0` and configure Paper's instead.
- **`max-chained-neighbor-updates`** caps how many block updates one chain can trigger, which limits some lag-machine designs. The default is `1000000`.

Your operator account should not play. If it does, it will be the target of every social-engineering attempt on the server, and an operator session hijacked by a malicious client is the worst outcome on the list.

#### Packet limits and spam limits

Many crash and lag exploits come down to sending the server more of something than it expects: thousands of packets per second, oversized data, or requests that are expensive to answer. Paper's global config has dedicated sections for this in `config/paper-global.yml`. Key names and defaults move between Paper versions, so treat the following as a map of what to look for in your generated file rather than as values to paste:

config/paper-global.yml:

```yaml
packet-limiter:
  all-packets:
    action: KICK
    interval: 7.0
    max-packet-rate: 500.0
  overrides:
    ServerboundPlaceRecipePacket:
      action: DROP
      interval: 4.0
      max-packet-rate: 5.0
spam-limiter:
  incoming-packet-threshold: 300
  recipe-spam-limit: 20
  tab-spam-limit: 500
```

The **packet limiter** counts packets per player over a rolling interval. If the rate crosses `max-packet-rate`, the player is kicked or the excess packets are dropped. `all-packets` is the overall limit; `overrides` sets tighter limits for specific packet types that are known to be expensive. The recipe-book packet override in the default config exists because spamming it was a real lag exploit.

Do not lower the global limit aggressively. Legitimate players on poor connections send bursts of packets when their connection recovers, and an anarchy server is full of players running clients that send more than vanilla does. Start with the defaults and tighten specific packet types when you see them abused.

The **spam limiter** covers chat, tab-completion and recipe spam. Tab completion is worth knowing about: asking the server to complete a long command string is expensive, and repeated tab-completion requests were a classic way to lag a server.

#### Books, item data and chunk bans

The most famous family of anarchy exploits is the "chunk ban", historically done with written books. Fill a chest with books carrying the maximum amount of text, place enough of them in one chunk, and the chunk becomes so large that the packet to send it to a player exceeds what the client accepts. Anyone who walks into that chunk is disconnected, and if it is at someone's base, they can never log in there again.

Paper limits the size of book and item data so that this cannot be done with ordinary items:

config/paper-global.yml:

```yaml
item-validation:
  book:
    author: 8192
    page: 16384
    title: 8192
  book-size:
    page-max: 2560
    total-multiplier: 0.98
  display-name: 8192
  lore-line: 8192
  resolve-selectors-in-books: false
```

`book-size.page-max` caps the bytes on one page, and `total-multiplier` makes each additional page allowed slightly less, so a full book is bounded. `resolve-selectors-in-books: false` stops books from resolving selectors and scoreboard components, which used to be a way to make the server do expensive work. Leave these at their defaults unless you have a reason; loosening them is how the exploit comes back.

Variants of the chunk ban have used other kinds of data - shulker boxes full of items with long names, maps, banners, signs - and the defence is the same: keep Paper current, keep its limits on, and if a player reports that a specific chunk disconnects them, treat it as a server problem. MCA Selector can open the world offline and delete or inspect the chunk; [world backup and restore](https://www.renode.space/blog/minecraft-world-backup-and-restore) covers finding the right region file.

#### Lag machines, entities and redstone

A lag machine is a contraption built to make the tick take as long as possible: redstone clocks that update thousands of blocks, piles of entities that collide with each other, falling-block and item spam, hopper arrays. On a normal server you would ban the builder. On an anarchy server you cap what any contraption can do.

The settings that matter most, in `config/paper-world-defaults.yml`:

config/paper-world-defaults.yml:

```yaml
collisions:
  max-entity-collisions: 8
chunks:
  entity-per-chunk-save-limit:
    arrow: 16
    experience_orb: 16
    snowball: 8
    ender_pearl: 8
misc:
  redstone-implementation: ALTERNATE_CURRENT
```

What those three settings do:

- **`max-entity-collisions`** caps how many collisions one entity processes per tick. Entity cramming machines rely on huge numbers of collisions.
- **`entity-per-chunk-save-limit`** caps how many of each listed entity type are saved in a chunk. Projectile and orb spam that would otherwise persist forever is trimmed when the chunk saves. The defaults are `-1` (no limit); setting limits for projectiles is common on anarchy servers.
- **`redstone-implementation`** chooses the redstone dust algorithm. `ALTERNATE_CURRENT` is much cheaper than `VANILLA` and resists dust-based lag machines, at the cost of different update order for a few contraptions.

The vanilla `maxEntityCramming` game rule (default `24`) kills mobs packed too tightly, which limits mob-based lag machines. And `spigot.yml` has entity activation and tracking ranges that reduce the cost of entities far from players; [Paper optimisation](https://www.renode.space/blog/minecraft-paper-optimization-guide) goes through them.

None of this stops a determined player completely. What it does is turn "one player can stop the server" into "one player can make their own area slow", which is the realistic goal. Profile regularly with spark to find the chunk where the tick is going, then decide whether it is gameplay or an attack. [Reading a spark report](https://www.renode.space/blog/minecraft-spark-profiler-lag-diagnosis) shows how to find a single expensive chunk.

#### Movement, elytra and chunk generation

On an anarchy server the most expensive normal activity is travel. Players fly elytra in straight lines for hours to get away from spawn, and every new chunk they reach has to be generated. One player on a fast elytra can keep the server's chunk generation busy on their own; ten can lag it for everybody.

Paper limits how fast a single player can make the server load and generate chunks:

config/paper-global.yml:

```yaml
chunk-loading-basic:
  player-max-chunk-generate-rate: -1.0
  player-max-chunk-load-rate: 100.0
  player-max-chunk-send-rate: 75.0
```

`player-max-chunk-generate-rate` is chunks per second per player, `-1` meaning unlimited. Setting a limit means a fast traveller outruns the terrain and flies into unloaded void until it catches up, which anarchy players dislike but accept on most servers. Measure your server's total generation rate first, then pick a per-player limit that leaves room for several travellers at once.

Movement speed checks in `spigot.yml` are the other half:

spigot.yml:

```yaml
settings:
  moved-wrongly-threshold: 0.0625
  moved-too-quickly-multiplier: 10.0
```

These decide when the server rejects a movement as impossible. Hacked clients that move far faster than the game allows are effectively tools for generating chunks faster than the server can afford. Many anarchy servers run a movement-focused anti-cheat - Grim is a widely used option - configured to stop speed and flight beyond what elytra allow, while leaving combat hacks alone. That is consistent with "no rules": the check protects the server, not anyone's fairness.

#### Map size, disk and memory

Anarchy servers are defined by a world that never resets, and that world grows forever. Every chunk anyone has ever visited is stored. On a busy server with players travelling outward, disk usage climbs steadily, and it never comes back down.

There are three honest choices:

1. **A border.** Set a large world border - 100,000 or 500,000 blocks - and accept that the world is finite. Pre-generate the inner area so spawn is cheap. Purists object; your disk does not.
2. **No border, with a budget.** Let it grow and plan disk upgrades. Know your growth rate by checking the world folder size weekly, and do the arithmetic before the disk fills rather than after.
3. **Trimming.** Delete chunks that were generated but never really used - visited once in passing, very low inhabited time - with MCA Selector on a copy of the world. Much of a travelled world is highway corridors nobody returns to. Some communities consider this a reset; announce your policy.

When the disk fills, the server cannot save. Chunks fail to write, players lose progress, and corruption becomes likely. That is worse than any of the three choices above.

On RE:NODE, Minecraft plans have between 15 and 100 GB of disk and 2 to 14 GB of memory depending on the tier, and the disk graph sits next to the console. A long-lived anarchy world can outgrow a small plan within months, so watch the graph and move up a tier before it is urgent - changing plan does not rebuild the server. Backups are the other disk cost: a 40 GB world is a 40 GB backup, which takes a long time to make and to restore. [How much RAM a Minecraft server needs](https://www.renode.space/blog/how-much-ram-does-a-minecraft-server-need) covers memory; on anarchy, view distance and the number of separate places players are loading matter more than the player count.

#### Attacks, crashes and staying online

Anarchy servers attract attacks, on the network as well as through the game. Assume someone will try to flood your address the day your server becomes known.

- **Network attacks.** RE:NODE has upstream filtering that drops obvious volumetric floods, plus reflection and malformed traffic. Attacks that look like real players are not filtered - including bot joins that log in and do expensive things. No host can promise that nothing gets through, and [DDoS attacks on game servers explained](https://www.renode.space/blog/ddos-attacks-on-game-servers-explained) is honest about what filtering can and cannot do.
- **Bot joins.** Floods of accounts joining at once. `online-mode=true` means each needs a real account, which limits the scale; a connection throttle and a plugin that rate-limits joins help more.
- **Crash loops.** If an unpatched exploit crashes the server repeatedly, that is a server problem to fix fast. On RE:NODE, a watcher counts unexpected restarts: three in an hour put a warning on the server page and open a ticket automatically, and six suspend the server. Restarts you trigger yourself are not counted. An exploit someone runs over and over is exactly the pattern that trips this, so patch, or stop the server while you work out what is happening.
- **Memory exhaustion.** Some exploits aim to fill memory. On RE:NODE a container that reaches its memory limit is stopped and restarted clean rather than left to swap, so the attack becomes a restart and the unsaved minutes are lost. Keep the autosave interval short enough that this costs little.

[Why your game server keeps restarting](https://www.renode.space/blog/why-your-game-server-keeps-restarting) helps tell an exploit from an ordinary crash, and [what to do when your server is hacked](https://www.renode.space/blog/what-to-do-when-your-server-is-hacked) covers the case where the attack was against the panel or an operator account rather than the game.

#### Backups and the no-rollback rule

Most anarchy servers promise no rollbacks for in-game events. That is a fair promise, and it is compatible with taking backups, because backups are for the server's failures, not for the players'.

Write the policy down: no rollbacks for griefing, theft, deaths or anything else a player did in the game; rollbacks only for corruption, a disk failure or a crash exploit that damaged the world. Then take backups as seriously as any other server. Every RE:NODE game plan has backup slots stored off the machine, on demand or scheduled, downloadable and restored with a button - and you can lock one, so rotation does not remove the last good copy before an exploit you are still cleaning up.

#### FAQ

##### Do anarchy servers need anti-cheat?

Not for fairness - hacked clients are part of the genre. Many still run a movement-focused anti-cheat to stop speed and flight beyond elytra, because those clients generate new chunks faster than the server can afford and make the server easier to crash.

##### How do I stop chunk bans and book bans?

Run a current Paper build and leave its `item-validation` limits on. They cap the size of book pages, titles and item names so that a chunk cannot be filled with enough data to disconnect players. If a specific chunk still disconnects people, inspect or remove it offline with MCA Selector.

##### Should an anarchy server have a world border?

That is a community decision, but plan for the disk either way. With no border the world grows indefinitely and eventually needs a larger plan or trimming. A large border keeps the world finite and lets you pre-generate the inner area.

##### Can players crash a Paper server?

They try. Paper fixes known crash exploits quickly, so most come from servers running old builds. Update promptly, keep the packet and item limits on, and treat repeated crashes as an urgent server problem rather than as gameplay.

##### Is offline mode acceptable on an anarchy server?

No. Offline mode lets anyone join with any name, including an operator's, and removes the cost of bot floods. Keep `online-mode=true`.

RE:NODE Minecraft plans run Paper with the matching Java version, go up to 100 GB of disk for a world that keeps growing, and sit behind upstream filtering that drops obvious volumetric floods. Backups are stored off the machine and can be locked, and moving up a tier keeps the world where it is.

[See Minecraft plans](https://www.renode.space/game-servers/minecraft)

---

### Bedrock Dedicated Server setup and add-ons

Published 2026-10-07 by RE:NODE Team. https://www.renode.space/blog/minecraft-bedrock-dedicated-server-guide

Bedrock Dedicated Server (BDS) is Mojang's own server for Minecraft Bedrock Edition - the version on Windows, phones, Xbox, PlayStation and Switch. It is a free download for Windows and Ubuntu Linux, has no plugin API, is configured through a `server.properties` file that shares a name but little else with Java's, and listens on UDP port `19132`. Download it, unzip it, set the world name, game mode and allowlist, open the port, run `bedrock_server`. Two things to know before you start: console players cannot type in a server address without a workaround, and anything beyond vanilla comes from add-ons (behaviour and resource packs), not plugins.

If you are still deciding between Bedrock and Java, read [Bedrock vs Java hosting](https://www.renode.space/blog/minecraft-bedrock-vs-java-hosting) first - for mixed groups, a Java server with Geyser is often the better answer. This post assumes you want BDS itself.

#### What BDS is, and what it is not

BDS is the same game engine as the Bedrock client, packaged as a headless server. It runs the official game exactly, in sync with the client version, and is the reference for how Bedrock multiplayer should behave.

What it does not have:

- **A plugin API.** No Bukkit, no Paper, no Spigot equivalents. Customisation is through add-ons, which are data-driven packs and JavaScript via Mojang's Script API.
- **RCON or a query protocol you can rely on.** Administration is the server console and operator commands typed in game.
- **Version tolerance.** Clients must be on the same version as the server. When a phone updates on Tuesday and the server has not, that phone cannot join until the server catches up.
- **Official support for Mac or other Linux distributions.** It is built for Windows and Ubuntu. Other modern Linux distributions usually run it, but that is not guaranteed.

Third-party Bedrock servers exist that do offer plugin APIs - PocketMine-MP, Nukkit-family servers - but they are reimplementations of the game, not BDS, and they lag behind and differ from vanilla in many details. There are also projects that add a plugin layer on top of BDS itself, such as Endstone and LeviLamina. They are worth knowing about; they are also another moving part that breaks on every Bedrock update.

#### Requirements and resource usage

BDS is lighter than a Java server for the same player count, mainly because it is written in C++ rather than running on a JVM with its heap overhead. It still scales with view distance, entities and loaded area.

| Players | RAM | CPU | Notes |
| --- | --- | --- | --- |
| 1-5 | 1-2 GB | 1 core | A family or a few friends |
| 5-15 | 2-4 GB | 2 cores | Keep `view-distance` modest |
| 15-30 | 4-6 GB | 2-3 cores | `tick-distance` and entities matter |
| 30+ | 6 GB+ | 3+ cores | Large builds and farms dominate |

Disk: the server install is a few hundred megabytes; worlds grow with exploration and are usually a few hundred megabytes to a few gigabytes. BDS uses more than one thread (`max-threads` controls the worker pool), but the world simulation still favours fast single cores, as covered in [CPU vs RAM for game servers](https://www.renode.space/blog/cpu-vs-ram-for-game-servers).

#### Installing and first start

Download the Windows or Ubuntu zip from the official Bedrock server download page on minecraft.net. Accepting the licence terms is part of the download. Unzip it into an empty folder.

On Linux:

```bash
$ mkdir ~/bedrock && cd ~/bedrock
$ unzip ~/Downloads/bedrock-server-*.zip
$ LD_LIBRARY_PATH=. ./bedrock_server
```

`LD_LIBRARY_PATH=.` tells the server to load the libraries shipped in its own folder. On Windows, run `bedrock_server.exe`.

The first start creates the world named in `level-name` and prints:

```text
[INFO] Starting Server
[INFO] Version: 1.21.x
[INFO] Level Name: Bedrock level
[INFO] IPv4 supported, port: 19132: Used for gameplay and LAN discovery
[INFO] IPv6 supported, port: 19133: Used for gameplay
[INFO] Server started.
```

The folder layout after a first start:

| Path | What it is |
| --- | --- |
| `server.properties` | All server settings |
| `allowlist.json` | Players allowed to join, when the allowlist is on |
| `permissions.json` | Operator and member levels, by XUID |
| `worlds/<level-name>/` | The world: `db/`, `level.dat`, `levelname.txt`, pack lists |
| `behavior_packs/`, `resource_packs/` | Packs available to worlds |
| `bedrock_server` / `.exe` | The server binary |

Updating BDS means downloading the new zip and copying it over the install while keeping `server.properties`, `allowlist.json`, `permissions.json` and `worlds/`. Updates are frequent, and a server that falls behind locks out every client that updated. Back up `worlds/` before every update.

#### server.properties: the keys that matter

The file is plain `key=value`, one per line, and the server ships it fully commented. The keys you will actually change:

| Key | Default | What it does |
| --- | --- | --- |
| `server-name` | `Dedicated Server` | Name shown in the LAN list and server info |
| `gamemode` | `survival` | `survival`, `creative` or `adventure` |
| `force-gamemode` | `false` | Force the server's game mode on players who join |
| `difficulty` | `easy` | `peaceful`, `easy`, `normal`, `hard` |
| `allow-cheats` | `false` | Whether commands can be used in game |
| `max-players` | `10` | Concurrent player limit |
| `online-mode` | `true` | Require Xbox Live authentication |
| `allow-list` | `false` | Only players in `allowlist.json` can join |
| `server-port` | `19132` | IPv4 UDP port |
| `server-portv6` | `19133` | IPv6 UDP port |
| `view-distance` | `32` | Maximum view distance in chunks |
| `tick-distance` | `4` | Simulation radius in chunks (4-12) |
| `player-idle-timeout` | `30` | Minutes before idle players are kicked, `0` disables |
| `max-threads` | `8` | Worker threads, `0` for as many as possible |
| `level-name` | `Bedrock level` | World folder name under `worlds/` |
| `level-seed` | empty | Seed for a new world |
| `default-player-permission-level` | `member` | `visitor`, `member` or `operator` for new players |
| `texturepack-required` | `false` | Force clients to use the world's resource packs |
| `content-log-file-enabled` | `false` | Write add-on errors to a log file |

Notes from running it:

- **`view-distance=32` is far too high** for most servers. It is a maximum; clients request less, but a phone on a 32-chunk view is generating a lot of work. `10`-`16` is plenty for a busy server.
- **`tick-distance` is the real performance lever.** It decides how far around each player the world simulates - crops, mobs, redstone. The default `4` is already lean; raising it to `8` or more for farms has a large cost.
- **`allow-cheats=true`** is needed for commands in game, including for operators. It also disables achievements in that world. Decide before players care.
- **`online-mode=true`** must stay on for any server reachable from the internet. Off, anyone can join as any name.
- **Movement and anti-cheat keys** - `server-authoritative-movement` and the `player-movement-*` thresholds - change name and accepted values between versions. Leave them at the defaults your version ships unless you are dealing with a specific movement-cheating problem, and check the comments in your own file before editing.
- **`compression-threshold`** and **`compression-algorithm`** trade bandwidth for CPU. Defaults are fine.

The Java side of the file is covered in [server.properties explained](https://www.renode.space/blog/minecraft-server-properties-explained); copying keys between the two does nothing useful.

#### Port 19132 and connecting

| Port | Protocol | Purpose |
| --- | --- | --- |
| `19132` | UDP | IPv4 gameplay and LAN discovery |
| `19133` | UDP | IPv6 gameplay |

Bedrock runs over RakNet on UDP. A TCP firewall rule does nothing for it - the most common reason a BDS server runs fine and cannot be reached. If the host has no IPv6, the second port can be ignored. [Game server ports explained](https://www.renode.space/blog/game-server-ports-explained) covers the general case.

**Phones, Windows and other PC clients** join through Play, then Servers, then Add Server: a name, an address and the port. Bedrock clients do not follow SRV records the way Java does, so the address is an IP or a hostname with an A record, and the port must be typed unless it is `19132`.

**Xbox, PlayStation and Switch** cannot add custom servers from the menu; they only show the featured servers. Communities work around it in two ways. One is a DNS redirect: the console's DNS is pointed at a service (BedrockConnect is the known one) that intercepts a featured-server hostname and shows a menu where any address can be entered. The other is friend-list broadcasting: a separate tool signs in to an Xbox account and makes the server appear as a joinable friend's world. Both work, both are unofficial, and both can break when Microsoft changes something. Be honest with console players about this before you promise them a server.

#### Allowlist and operators

Allowlist entries are managed from the console; the server writes `allowlist.json` for you:

```text
allowlist on
allowlist add Steve_Plays
allowlist remove Griefer123
allowlist list
allowlist reload
```

Players are added by gamertag, and the server fills in their XUID on first join. With `allow-list=true`, anyone not in the file is refused.

Operator status lives in `permissions.json`, keyed by XUID, not gamertag:

permissions.json:

```json
[
  { "permission": "operator", "xuid": "2535412345678901" },
  { "permission": "member", "xuid": "2535498765432109" }
]
```

The easiest route is `op <gamertag>` in the console once the player has joined, which writes the file. If you edit it by hand, run `permission reload` afterwards. The XUID appears in the console when the player connects.

Useful console commands:

| Command | Effect |
| --- | --- |
| `op <name>` / `deop <name>` | Grant or remove operator |
| `kick <name> <reason>` | Remove a player |
| `list` | Players online |
| `allowlist ...` | As above |
| `permission list` / `permission reload` | Show or reload `permissions.json` |
| `changesetting allow-cheats true` | Change some settings without a restart |
| `save hold` / `save query` / `save resume` | Prepare a consistent backup |
| `stop` | Save and shut down |

In-game commands available to operators are the standard Bedrock command set (`/gamerule`, `/tp`, `/give` and so on), and need `allow-cheats=true`.

#### Add-ons: behaviour packs and resource packs

Bedrock's equivalent of mods and plugins is the add-on: a behaviour pack (entities, items, recipes, loot, scripts) and often a resource pack (textures, models, sounds). An `.mcpack` or `.mcaddon` file is a zip.

1. Unzip the pack. Each pack has a `manifest.json` with a `header` containing a `uuid` and a `version`.
2. Copy behaviour packs into `behavior_packs/` and resource packs into `resource_packs/`.
3. Attach them to the world. In `worlds/<level-name>/`, create or edit `world_behavior_packs.json` and `world_resource_packs.json`:

worlds/Bedrock level/world_behavior_packs.json:

```json
[
  { "pack_id": "5b1d4a8e-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "version": [1, 0, 0] }
]
```

`pack_id` is the header `uuid` from the pack's manifest, and `version` is its header version as an array. Do the same for the resource pack in its own file.

4. Set `texturepack-required=true` if clients must download the resource pack to join correctly.
5. Restart and watch the console. Enable `content-log-file-enabled=true` while testing; pack errors are written there rather than to the main output.

Many add-ons rely on **experimental features**, which are world settings, not server settings. The reliable way to enable them is to create the world on a client with the experiments switched on and the packs applied, then upload that world to the server. Note that experiments can change or vanish between versions and can break a world on update.

The Marketplace is a separate matter: Marketplace content is licensed to the buyer's account and is not meant to be put on a server, and is encrypted in a way BDS does not handle for third parties.

#### Moving a world onto the server

A Bedrock world is a folder with a random-looking name, containing `db/` (the LevelDB database holding chunks), `level.dat` and `levelname.txt`. On Windows, client worlds are in the `com.mojang` folder under `games/com.mojang/minecraftWorlds/`; the exact parent location has moved between versions of the Windows client, so search for `minecraftWorlds` if the old path is empty. On phones, use the game's export to produce a `.mcworld` file - a zip of the same folder.

1. Stop the server.
2. Upload the world folder into `worlds/` over SFTP. Rename the folder to something readable.
3. Set `level-name` to exactly that folder name.
4. Start the server and check that it loads rather than creating a fresh world.

One BDS process runs one world. There is no equivalent of Java's Multiverse and no proxy that moves players between Bedrock servers the way Velocity does for Java, so a community that wants a survival world and a creative world runs two servers on two ports and players add both to their list. Switching `level-name` to another folder and restarting does swap worlds, but everyone on the server goes with it.

Check what the uploaded world carries with it. Game rules, the cheats flag, experimental toggles and the world's own pack lists are stored in the world, not the server. A world that had cheats on in single player keeps achievements disabled regardless of `allow-cheats` on the server, and a world built with an add-on needs that add-on's packs present in the server's pack folders, or entities and blocks from it will be missing.

#### Backups and updates

The world is a LevelDB database, written continuously. Copying it while the server writes can produce a broken copy. BDS has a built-in procedure for this:

1. `save hold` - pause writes.
2. `save query` - repeat until the server reports the files are ready and lists them with lengths.
3. Copy the listed files, truncating each to the length given.
4. `save resume` - writes continue.

That is fiddly by hand. The simple safe alternative is to stop the server, copy `worlds/`, start it again - at an hour when nobody plays. [Backups that actually restore](https://www.renode.space/blog/backups-that-actually-restore) explains why proving a restore works matters more than taking the backup.

> [!WARNING]
> Never downgrade a Bedrock world. A world opened by a newer server version may not load in an older one. Back up `worlds/` before every BDS update, because that backup is the only way back.

#### Troubleshooting

**Players cannot connect at all.** The port is not open for UDP, or the server is bound to a different port than the one players are typing. Check the startup line that reports the port.

**"Outdated server" or "Outdated client".** Version mismatch. Update the server, or wait for players to update.

**"You need to authenticate to Microsoft services."** The client is not signed in to a Microsoft account, which `online-mode=true` requires.

**The server ignores `server.properties` changes.** Most settings are read at startup. Restart after edits; `changesetting` handles only a few.

**Add-on does nothing.** The `pack_id` or version does not match the manifest, the JSON has a syntax error, or the pack needs experiments that the world does not have. Check the content log.

**Console players cannot find the server.** Consoles cannot add servers without a workaround. See the connecting section.

#### FAQ

##### Is Bedrock Dedicated Server free?

Yes, it is a free download from minecraft.net under Mojang's licence terms. Players still need their own copy of Minecraft Bedrock.

##### Can I run plugins on Bedrock Dedicated Server?

Not natively. BDS has add-ons and Mojang's Script API instead. Third-party projects add plugin layers, and alternative server software such as PocketMine-MP has its own plugins, but none of that is vanilla BDS.

##### Which port does a Bedrock server use?

UDP `19132` for IPv4 and UDP `19133` for IPv6 by default, set by `server-port` and `server-portv6`.

##### Can Java players join a Bedrock server?

No. The reverse is possible: Bedrock players can join a Java server through Geyser. For a mixed group, that is usually the arrangement to choose.

##### How do Xbox and PlayStation players join?

Not directly, since console versions only show featured servers. Community workarounds use a DNS redirect or friend-list broadcasting. They work, but they are unofficial and can break.

RE:NODE's Minecraft line runs Paper - Java Edition with the matching Java version and the EULA accepted. For a group that mixes PC and phone players, Geyser on a Paper server lets Bedrock clients join the same world, and the extra UDP port it needs is added on the Network tab.

[See Minecraft plans](https://www.renode.space/game-servers/minecraft)

---

### BungeeCord vs Velocity: Minecraft proxies

Published 2026-10-07 by RE:NODE Team. https://www.renode.space/blog/minecraft-bungeecord-vs-velocity

For a new Minecraft network, use Velocity. It is the proxy PaperMC maintains and recommends, its modern forwarding mode protects your backends without extra plugins, and it handles more players per core than BungeeCord. BungeeCord is still maintained and still runs a large share of the world's networks, and there is exactly one good reason to stay on it: a plugin you depend on that has no Velocity build. If that is not you, the migration is an afternoon - a new config file, one setting per backend, and a plugin audit - and this post walks through it, along with the honest differences between the two.

The full Velocity setup - every line of `velocity.toml`, shared permissions, forced hosts - is in [the Velocity network guide](https://www.renode.space/blog/minecraft-velocity-proxy-network). This post is the comparison and the move.

#### What both proxies do, and where they differ

Both are the same kind of program. A player connects to the proxy, the proxy authenticates them against Mojang once, then opens its own connection to a backend server and relays packets in both directions. Moving between servers is the proxy closing one backend connection and opening another while the player's connection stays up. Neither proxy simulates anything: there are no worlds, no blocks and no entities on a proxy, which is why it needs very little memory.

The differences are in four places:

| | BungeeCord | Velocity |
| --- | --- | --- |
| Maintainer | md_5 (SpigotMC) | PaperMC |
| Config | `config.yml` (YAML) | `velocity.toml` (TOML) |
| Identity forwarding | Unsigned (`ip_forward`) | Signed (`modern`), or legacy modes |
| Backend protection | Firewall or BungeeGuard | Built in with modern forwarding |
| Plugin API | BungeeCord API | Velocity API |
| Backend versions | Any | Modern forwarding needs 1.13+ |

**Forwarding** is the difference that matters most and the one people understand least. It is covered in its own section below, because it decides whether your backends can be joined directly by anyone who finds their port.

**Plugin APIs** are not compatible. A BungeeCord plugin does not load on Velocity, a Velocity plugin does not load on BungeeCord, and Paper plugins load on neither. Most large network plugins - LuckPerms, Geyser and Floodgate, ViaVersion, the major chat and ban plugins - publish builds for both. Small or abandoned plugins often exist only for BungeeCord, which has been around since 2013.

**Performance** favours Velocity. It was written from scratch around Netty with native compression and encryption libraries on Linux, and it does less work per packet. In practice that rarely matters below a few hundred concurrent players, where either proxy idles on a fraction of a core. It starts to matter on large networks, and on hosts where each process has a hard CPU limit.

**Configuration** is mostly a translation exercise. The concepts - listeners, a server list, a try order, forced hosts, a compression threshold - exist in both under different names.

#### Waterfall is finished, and what that means for you

Waterfall was PaperMC's fork of BungeeCord, with performance fixes and extra configuration on top. Many networks that think of themselves as "on BungeeCord" are actually on Waterfall. PaperMC ended Waterfall development and points everyone at Velocity. It still runs, but it receives no updates, which means no support for new Minecraft protocol versions and no security fixes.

If you are on Waterfall today you have two choices: move back to upstream BungeeCord, which reads almost the same `config.yml` and runs the same plugins, or move to Velocity. Going back to BungeeCord is the smaller step; going to Velocity is the one you will not have to repeat. If you are going to touch every backend anyway, do it once.

#### Forwarding: the security difference

When a player connects through a proxy, the backend sees a connection from the proxy's address, not from the player. Without help, every player would arrive with the proxy's IP and an offline-mode UUID, which breaks bans, skins and every plugin that stores data by UUID. Forwarding is how the proxy tells the backend who the player really is.

##### BungeeCord's ip_forward

BungeeCord does this by appending the player's real address, UUID and profile properties to the handshake. You switch it on with `ip_forward: true` in the proxy's `config.yml` and `settings.bungeecord: true` in each backend's `spigot.yml`.

The problem is that the backend has no way to check that the data came from your proxy. It trusts whatever the handshake says. Because backends run with `online-mode=false` (the proxy did the authentication), anyone who can reach a backend's port directly can send a crafted handshake claiming to be any player, including an operator, and the backend lets them in. This is not a theoretical weakness; there are public tools that do exactly this, and open BungeeCord backends are found by scanners within hours.

The two fixes are a firewall that only lets the proxy reach the backends, or **BungeeGuard**, a plugin pair that adds a secret token to the forwarded data so backends can reject connections without it. On a machine you control, the firewall is the stronger option. On a shared panel host, where every server is a separate container with its own public port, you usually cannot firewall your own backends from the internet, and BungeeGuard is not optional.

##### Velocity's modern forwarding

Velocity's `modern` mode sends the same identity data inside a payload signed with a secret shared between the proxy and each backend. Paper verifies the signature and refuses anything without a valid one, before login completes. A player who finds a backend's address and connects directly gets kicked. No firewall and no extra plugin.

The cost is compatibility: modern forwarding needs a backend that understands it, which means Paper 1.13 or newer, or a Fabric or NeoForge backend with a proxy-compatibility mod. For older backends Velocity offers `legacy` (BungeeCord-style, with the same weakness) and `bungeeguard` (legacy plus a BungeeGuard token).

| Velocity mode | Equivalent to | Backend needs |
| --- | --- | --- |
| `none` | No forwarding | Nothing - players get offline UUIDs |
| `legacy` | BungeeCord `ip_forward` | `bungeecord: true` in `spigot.yml` and a firewall |
| `bungeeguard` | BungeeCord plus BungeeGuard | BungeeGuard plugin on the backend |
| `modern` | Nothing on BungeeCord | Paper 1.13+ with Velocity support enabled |

> [!WARNING]
> Whichever proxy you run, test it the same way before you open the network: try to join each backend directly by its own address and port. If you get in, that backend is joinable by anyone as anyone. Fix it before announcing the address anywhere.

#### The configs side by side

A typical BungeeCord `config.yml`, trimmed to the parts that carry over:

BungeeCord config.yml:

```yaml
online_mode: true
ip_forward: true
network_compression_threshold: 256
connection_throttle: 4000
player_limit: -1
listeners:
- host: 0.0.0.0:25565
  motd: '&bThe Longhouse Network'
  max_players: 200
  force_default_server: true
  priorities:
  - lobby
  forced_hosts:
    survival.example.com: survival
  ping_passthrough: false
  query_enabled: false
servers:
  lobby:
    address: 10.0.0.11:25566
    restricted: false
    motd: 'Lobby'
  survival:
    address: 10.0.0.12:25567
    restricted: false
    motd: 'Survival'
```

And the same network in `velocity.toml`:

velocity.toml:

```toml
bind = "0.0.0.0:25565"
motd = "<aqua>The Longhouse Network"
show-max-players = 200
online-mode = true
player-info-forwarding-mode = "modern"
forwarding-secret-file = "forwarding.secret"

[servers]
lobby = "10.0.0.11:25566"
survival = "10.0.0.12:25567"
try = ["lobby"]

[forced-hosts]
"survival.example.com" = ["survival"]

[advanced]
compression-threshold = 256
login-ratelimit = 3000
```

How the keys map:

| BungeeCord | Velocity | Notes |
| --- | --- | --- |
| `listeners[].host` | `bind` | Velocity has one listener |
| `listeners[].priorities` | `servers.try` | Order matters in both |
| `listeners[].forced_hosts` | `[forced-hosts]` | Velocity takes a list per host |
| `listeners[].motd` | `motd` | Legacy `&` codes become MiniMessage |
| `ip_forward` | `player-info-forwarding-mode` | See the forwarding table |
| `network_compression_threshold` | `compression-threshold` | Same meaning |
| `connection_throttle` | `login-ratelimit` | Milliseconds between logins per IP |
| `servers.<name>.restricted` | No direct key | Use permissions on `/server` instead |
| `groups` / `permissions` | No built-in system | Use LuckPerms on the proxy |

Two behaviours differ in ways that surprise people. First, `force_default_server: true` on BungeeCord sends every player to the first priority server on each login; Velocity always uses the `try` list on initial connection and does not remember the last server unless a plugin does it. Second, BungeeCord ships with a basic permission system in `config.yml` (the `groups` and `permissions` blocks, with `md_5` as an example admin). Velocity has none: without a permissions plugin, only the console has access to admin commands. Install LuckPerms on the proxy as part of the migration rather than after it.

#### Migrating from BungeeCord to Velocity, step by step

Plan for a short downtime window. The backends need one setting changed and a restart, and they cannot accept both kinds of forwarding at once.

1. **Audit your proxy plugins.** List every jar in BungeeCord's `plugins` folder and find the Velocity build of each. Where there is none, find a replacement or decide you can live without it. Do this first; it is the step that can stop the migration.
2. **Check backend versions and software.** Modern forwarding needs Paper 1.13 or newer. Spigot backends should move to Paper - it reads the same worlds and runs the same plugins. Anything older than 1.13 stays on `legacy` or `bungeeguard` forwarding.
3. **Install Velocity beside BungeeCord.** Put `velocity.jar` in a new directory, run it once to generate `velocity.toml` and `forwarding.secret`, then stop it.
4. **Translate the config** using the mapping table above. Keep BungeeCord's server names: plugins on the backends that send players by name (`lobby`, `survival`) keep working if the names do not change.
5. **Install the proxy plugins** you found in step 1, starting with LuckPerms. If LuckPerms already used a shared database on BungeeCord, point the Velocity copy at the same database and everything carries over.
6. **Stop the network.** Stop BungeeCord, then each backend.
7. **Switch each backend.** In `spigot.yml` set `settings.bungeecord: false`. In `config/paper-global.yml` set the Velocity block and paste the secret. Remove BungeeGuard from the backend if it was installed.
8. **Start Velocity on the public port**, then the backends. Watch the Velocity console for the forwarding error described in the troubleshooting section.
9. **Test direct connections** to every backend and confirm they are refused.
10. **Keep BungeeCord's directory** untouched for a week. Rolling back is reversing step 7 and starting the old jar.

The backend change in step 7 looks like this:

spigot.yml (backend):

```yaml
settings:
  bungeecord: false
```

config/paper-global.yml (backend):

```yaml
proxies:
  bungee-cord:
    online-mode: true
  velocity:
    enabled: true
    online-mode: true
    secret: 'paste-the-contents-of-forwarding.secret'
```

On Paper versions before 1.19, these settings lived in `paper.yml` rather than `config/paper-global.yml`, under `settings.velocity-support`. If your backends are that old, check the file you actually have before editing a path from a guide.

> [!TIP]
> Player data is keyed by UUID, and forwarding is what delivers the real UUID. If BungeeCord forwarding was set up correctly before, players keep their inventories, homes and permissions through the move. If anyone logs in after the migration as a fresh player, forwarding is not working - stop and fix it before more people join and create duplicate data.

#### Plugin messaging and backend plugins

Many backend plugins talk to the proxy through the `BungeeCord` plugin messaging channel: selector menus that send players to a server, signs that show player counts, minigame plugins that return players to the lobby. They were written for BungeeCord, and they keep working on Velocity because Velocity implements that channel. In `velocity.toml` it is `bungee-plugin-message-channel = true` under `[advanced]`, on by default.

What does not carry over is anything that relied on a BungeeCord plugin being present on the proxy. If a backend plugin expects a companion proxy plugin, that companion needs a Velocity build too. Read each plugin's page for "Velocity support" before the migration night, not during it.

Version translation is the other common dependency. A BungeeCord network that accepts several client versions usually runs ViaVersion (and sometimes ViaBackwards and ViaRewind) on the proxy or the backends. ViaVersion publishes a Velocity build, and it can equally live on each Paper backend; where you put it is a matter of preference, as long as it is not in both places.

Bedrock players through Geyser and Floodgate work on either proxy. On Velocity, put Geyser and Floodgate on the proxy and Floodgate on each backend too, with the same `key.pem`, so the backends recognise Floodgate players - [the Geyser guide](https://www.renode.space/blog/minecraft-geyser-bedrock-crossplay) has the details.

#### Commands and administration

The admin commands overlap but are not identical, which matters for staff habits and for any scripts or Discord bots that send commands to the proxy console.

| Task | BungeeCord | Velocity |
| --- | --- | --- |
| Move yourself | `/server <name>` | `/server <name>` |
| Players per server | `/glist` | `/glist` |
| Move another player | `/send <player> <server>` | `/send <player> <server>` |
| Network broadcast | `/alert <message>` | Needs a plugin |
| Find a player | `/find <player>` | Needs a plugin |
| Reload config | `/greload` (unreliable) | `/velocity reload` |
| Stop the proxy | `end` | `shutdown` |
| Version | `/bungee` | `/velocity info` |

`/velocity reload` is genuinely useful: it picks up added and removed servers in `velocity.toml` without kicking anyone. BungeeCord's reload has never been trustworthy, and most BungeeCord admins restart the proxy instead, which disconnects the whole network.

Velocity's commands each have a permission node (`velocity.command.server`, `velocity.command.glist`, `velocity.command.send`), so you grant them through LuckPerms on the proxy rather than in the config file.

#### Sizing the proxy on a panel host

Neither proxy is heavy. Half a gigabyte of heap is plenty for either at a few hundred players; the work is CPU spent compressing and encrypting traffic. A proxy on a 1-2 GB plan with one core is normal. The backends are where the money goes.

```bash
$ java -Xms512M -Xmx512M -XX:+UseG1GC -jar velocity.jar
```

A network on any panel host is one server per process: a proxy plus a lobby plus two gamemodes is four servers, each with its own memory limit, port and backups. On RE:NODE each Minecraft plan comes with one port allocation and you can add more on the Network tab; SFTP credentials are per server, which is how you push the same `forwarding.secret` to every backend without retyping it. Every server is its own container with its own public port, so the direct-connection test in the forwarding section is not a formality - modern forwarding is what keeps those backend ports closed to impostors. The general case for splitting work like this is in [CPU vs RAM for game servers](https://www.renode.space/blog/cpu-vs-ram-for-game-servers).

Once the proxy is up, put a name in front of it with an `A` record and an `SRV` record, so players type `mc.example.com` and nothing else - [SRV records for Minecraft](https://www.renode.space/blog/srv-records-for-minecraft) has the exact record.

#### Troubleshooting the switch

**Velocity logs "Your server did not send a forwarding request to the proxy".** The backend is not set up for modern forwarding: `proxies.velocity.enabled` is still `false`, the file edited was the wrong one for that Paper version, or the backend was not restarted.

**Players are kicked with "Unable to verify player details" or a decoder error.** The secret on the backend does not match `forwarding.secret`. Look for a trailing newline or space from the copy.

**"If you wish to use IP forwarding, please enable it in your BungeeCord config as well!"** This is the backend saying it still has `bungeecord: true` in `spigot.yml` while the proxy is not sending BungeeCord-style data. Set it to `false` on Velocity with modern forwarding.

**Everyone logs in as a new player.** Forwarding is off or in `none` mode, so backends see offline-mode UUIDs. Do not let anyone play until it is fixed; each login creates player data you will have to clean up.

**A plugin that worked on BungeeCord does nothing.** It was a BungeeCord plugin sitting in Velocity's `plugins` folder. Velocity logs that it could not load it at startup; scroll up.

**Staff lost their admin commands.** BungeeCord's `config.yml` groups were doing the permissions. Grant the Velocity nodes in LuckPerms. The [LuckPerms guide](https://www.renode.space/blog/minecraft-luckperms-guide) shows how to scope them to the proxy with a `server` context.

#### FAQ

##### Is BungeeCord still maintained?

Yes. md_5 updates it for new Minecraft versions, and it remains widely used. It is not abandoned; it is simply less secure by default and slower than Velocity, and its forwarding needs a firewall or BungeeGuard to be safe.

##### Can I run BungeeCord plugins on Velocity?

No. The two have separate plugin APIs. Look for a Velocity build of each plugin; most popular network plugins have one. Backend plugins that only use the BungeeCord messaging channel do keep working.

##### Do I need to change anything on the backends when migrating?

Yes, one switch each: turn off `bungeecord` in `spigot.yml`, enable Velocity support in Paper's global config, and paste the forwarding secret. Worlds, plugins and player data stay as they are.

##### My backends run 1.12.2. Can I still use Velocity?

Yes, with `legacy` or `bungeeguard` forwarding instead of `modern`. You lose the built-in protection, so add BungeeGuard or keep backends unreachable from the internet - the same precautions BungeeCord needs.

##### Will players notice the migration?

Only the downtime and, if you changed it, the MOTD. The address stays the same, UUIDs stay the same if forwarding was correct before and after, and server names can stay the same so existing selector menus keep working.

##### Is Waterfall safe to keep running?

It runs, but it no longer gets protocol updates or security fixes. Move to Velocity, or back to BungeeCord, before the next Minecraft version you want to support.

Every proxy and backend in a network is its own RE:NODE server, from 2 GB, with Paper and the matching Java version installed on the backends. Extra ports go on the Network tab, SFTP credentials are per server, and backup slots and schedules come with every tier.

[See Minecraft plans](https://www.renode.space/game-servers/minecraft)

---

### Minecraft corrupted chunks and recovery

Published 2026-10-07 by RE:NODE Team. https://www.renode.space/blog/minecraft-chunk-errors-and-world-corruption

A corrupted chunk is almost always confined to one region file, and the fix is almost always to replace that one file - or the damaged chunks inside it - rather than the whole world. Find the coordinates in the server log, work out which `r.X.Z.mca` file holds them, stop the server, and either restore that file from a backup or delete the bad chunks so they regenerate. MCA Selector is the tool for the second option. Everything else in this post is about doing that precisely, recognising the errors that look like corruption but are not, and making it unlikely to happen again.

#### How a Minecraft world is stored

A Java Edition world is a folder of small files, not one big one. That is why corruption is usually local.

| Path | What it holds |
| --- | --- |
| `level.dat` | World settings, seed, time, game rules, data version |
| `level.dat_old` | The previous copy of `level.dat` |
| `region/r.X.Z.mca` | Blocks and block entities for 32 x 32 chunks |
| `entities/r.X.Z.mca` | Mobs, items, armour stands (1.17 and later) |
| `poi/r.X.Z.mca` | Points of interest: beds, workstations, portals |
| `playerdata/<uuid>.dat` | Each player's inventory, position and stats |
| `data/` | Maps, raids, scoreboards, structure data |

Each region file covers 32 by 32 chunks, which is 512 by 512 blocks. Inside, the file starts with an 8 KiB header - a table saying where each of the 1,024 chunks is stored and a table of timestamps - followed by the chunks themselves, each compressed and stored in 4 KiB sectors.

On Paper and Spigot, the nether and the end are separate world folders: `world_nether/DIM-1/region/` and `world_the_end/DIM1/region/`. On vanilla, they are inside the main world folder at `world/DIM-1/` and `world/DIM1/`. Check which layout you have before looking for a file.

##### From block coordinates to a region file

The arithmetic is short:

```text
chunk X  = floor(block X / 16)
chunk Z  = floor(block Z / 16)
region X = floor(chunk X / 32)
region Z = floor(chunk Z / 32)
```

So the block at X `-1200`, Z `3400` is in chunk `-75, 212`, which is in region `-3, 6`: the file `r.-3.6.mca`. Note the floor: negative coordinates round down, so block `-1` is in chunk `-1` and region `-1`, not `0`. The F3 screen in game shows the chunk and the region file name directly for wherever you are standing, which is the quickest way to check your sums.

#### What the log errors actually mean

Corruption shows up in the server log, often as a stack trace long enough to hide the useful line. These are the common messages and what they point at.

**`Chunk file at [x, z] is in the wrong location; relocating. (Expected [a, b], got [c, d])`** - a chunk's stored coordinates do not match its position in the region file. Usually the result of someone copying or renaming region files, or an old external tool. The server relocates the chunk and carries on. Not urgent, but find out who moved files.

**`Couldn't load chunk [x, z]`** followed by an exception - the chunk data could not be read. The exception underneath says why: a decompression error (`ZipException`, "incorrect header check", "unexpected end of ZLIB input stream") means the stored bytes are damaged; an NBT read error means the data decompressed but is not valid. The server will usually regenerate the chunk, which means terrain or builds there are replaced with fresh generation - check the location in game.

**Region file errors mentioning a truncated file or an invalid sector** - the region file's header points past the end of the file, typically because the process stopped while writing. Paper attempts to recover a damaged header by scanning the file, and logs that it is doing so; whether the chunks survive depends on how much was written.

**Errors naming an entity or block entity** - a single bad mob, item frame, chest or sign in an otherwise fine chunk. Often a plugin or mod wrote data the server cannot parse. The crash report's "Entity being ticked" or "Block entity being ticked" section gives the coordinates. [Crash reports explained](https://www.renode.space/blog/minecraft-crash-reports-explained) shows how to read that section.

**The world is completely new or `level.dat` errors at startup** - `level.dat` is missing or unreadable. That is the one file whose loss affects the whole world, covered further down.

> [!WARNING]
> Before you fix anything, copy the whole world folder somewhere safe with the server stopped. Repair tools write to the files they repair, and the worst outcome - a broken repair on your only copy - is avoidable with one copy command.

#### What causes corruption

Region files are rewritten constantly, which makes the moment of writing the dangerous one. Nearly every case comes down to one of these:

1. **The process stopped mid-write.** A kill instead of a clean stop, an out-of-memory termination, a host crash. Whatever was being written at that instant may be half there.
2. **The disk filled up.** A write that cannot complete leaves a truncated file. Backups and logs filling the disk are the usual culprits; [disk space](https://www.renode.space/blog/game-server-disk-space-full) covers what eats it.
3. **Files edited while the server ran.** Uploading a region file, running MCA Selector or an editor against a live world, or restoring a backup into a running server. The server's next save overwrites or interleaves with your change.
4. **Version mismatches.** Opening a world in an older Minecraft version than it was saved in, or using an external tool that does not understand the current format. Data can be dropped or misread.
5. **Plugins and mods writing bad data.** A plugin storing malformed data in a block entity or an entity, which the server then fails to load.
6. **Genuine storage faults.** Rare on modern hardware with checksumming filesystems, but not impossible on cheap machines.

Most of these are preventable, which is the last section of this post.

#### Finding the damage

Start from the log. Search it for the coordinates in the error and convert them to a region file as above. If the error gives chunk coordinates (most do), only the second step applies.

```bash
$ grep -n "Couldn't load chunk\|wrong location\|region" logs/latest.log | tail -20
```

On a panel, the console's search or the downloaded `logs/latest.log` do the same job; older logs are gzipped in the same folder as `YYYY-MM-DD-N.log.gz`.

Then go and look, carefully. Teleport near the coordinates - not into them - in spectator mode, and see what the chunk looks like: missing builds, freshly generated terrain cutting through a base, a straight-edged hole into the void. A chunk that regenerated in the middle of a build has a sharp 16-block boundary that is hard to mistake.

If several chunks in different regions are affected, look for a common cause before repairing anything. Damage across many regions at the same time points at a disk-full event or a crash, and there may be more than you have found.

#### Repairing with MCA Selector

MCA Selector is a free, open-source desktop application for viewing and editing region files. It shows the world as a map, lets you select chunks by hand or by query, and can delete, export or import them. It is the standard tool for chunk-level surgery.

Work on a copy, never on the live server:

1. Stop the server and download the world folder over SFTP, or at least the affected dimension's `region`, `entities` and `poi` folders. [SFTP and the file manager](https://www.renode.space/blog/sftp-and-the-file-manager) has the connection details.
2. Open the world folder in MCA Selector. Corrupted chunks often show as blank or are reported when the tool tries to read them.
3. Select the damaged chunks.
4. Delete them, or import replacements from a backup (the two options are explained below).
5. Save, upload the changed files back to the stopped server, start it, and check the area in game.

The choice in step 4 decides what the area looks like afterwards:

- **Delete** - the chunks regenerate from the seed on next load. Correct for wilderness, wrong for builds.
- **Import from a backup** - MCA Selector can import chunks from another copy of the world, so you can take just those chunks from last night's backup and leave everything else at today's state.

MCA Selector's query filter is also the right tool for a different job that looks similar: trimming a world. Selecting chunks by `InhabitedTime` (how long players have spent in them) finds chunks that were generated but never really visited, and deleting those shrinks a bloated world without touching bases. [World border and pre-generation](https://www.renode.space/blog/minecraft-world-border-and-pregeneration) covers why worlds bloat in the first place.

Keep MCA Selector updated. The region format changes between Minecraft versions, and an old copy of any external tool is a cause of corruption rather than a fix for it.

#### Restoring a single region file from backup

When the damaged area is a build and you have a backup, restoring the region file is faster than chunk surgery and loses only what changed in that 512-by-512 square since the backup.

1. Stop the server.
2. From the backup, take `region/r.X.Z.mca` for the affected region. Also take `entities/r.X.Z.mca` and `poi/r.X.Z.mca` with the same name, so mobs, item frames, villagers' workstations and beds match the blocks.
3. Copy them over the current files on the server.
4. Start the server and check the area.

What you lose: any building in that square since the backup. What you keep: everything else in the world, and every player's inventory, because inventories are in `playerdata`, not in the region. If a player stored items in chests inside the restored region after the backup was taken, those are gone; warn them.

On RE:NODE, backups can be downloaded from the panel, so you can unpack one locally, pull out the three files and upload just those through the file manager - rather than restoring the whole backup and rolling back every other player's progress. A full restore is a button when you do need it. Either way, [backups that actually restore](https://www.renode.space/blog/backups-that-actually-restore) is the case for testing this before the day you need it.

#### level.dat and playerdata corruption

**`level.dat`** holds the seed, spawn point, game rules and world settings. If it is damaged, the server may create a new world or refuse to start. Minecraft keeps the previous version as `level.dat_old`: stop the server, rename the damaged file aside, copy `level.dat_old` to `level.dat`, and start again. If both are damaged, take `level.dat` from any backup - it changes little day to day, and an old one only resets world time and a few counters.

**Player files** live in `playerdata/<uuid>.dat`, with a `.dat_old` copy beside each. A player whose inventory vanished or who spawns at world spawn with nothing after a crash may have a damaged file; the `_old` copy is usually one save behind. Restore it with the server stopped, or with the player offline at minimum, because the server writes the file on logout.

```text
playerdata/
  4c2a9b1e-....dat
  4c2a9b1e-....dat_old
```

#### Preventing corruption

None of this is complicated, and most servers that lose chunks skipped one of these:

- **Stop cleanly.** `stop` in the console saves every world and exits. Killing the process does not. On RE:NODE, the Stop and Restart buttons send a clean stop; Kill does not, and is for a server that has stopped responding.
- **Stay inside the memory limit.** A server killed for running out of memory has not been stopped cleanly. If your server is repeatedly reaching its limit, that is a corruption risk as well as a stability problem - [how much RAM a Minecraft server needs](https://www.renode.space/blog/how-much-ram-does-a-minecraft-server-need) and [why your game server keeps restarting](https://www.renode.space/blog/why-your-game-server-keeps-restarting) explain the signs.
- **Keep free disk space.** Never let a server's disk fill. Old logs, old backups kept in the server folder and abandoned worlds are the usual space eaters.
- **Never edit a live world.** Stop the server before uploading, restoring or editing anything under the world folders.
- **Take consistent backups.** A backup taken while chunks are being written can capture a half-written file. Use `save-off`, `save-all flush`, back up, then `save-on` - or stop the server for the backup - so the copy is consistent. [The world backup guide](https://www.renode.space/blog/minecraft-world-backup-and-restore) goes through it.
- **Upgrade in one direction.** Never open a world in an older version than it was last saved in. Before an upgrade, back up; after an upgrade, there is no going back without that backup. [Minecraft version upgrades](https://www.renode.space/blog/minecraft-version-upgrades) covers the safe order.

```text
save-off
save-all flush
# take the backup here
save-on
```

#### FAQ

##### Can a corrupted chunk spread to the rest of the world?

No. Each chunk is stored independently and a bad chunk does not damage its neighbours. What spreads is the cause: if the disk filled or the server was killed, other files written at the same time may also be damaged, so check the log for more than one error.

##### Will deleting a corrupted chunk delete my build?

Yes, if the build was in it. A deleted chunk regenerates from the seed as fresh terrain. Use deletion for wilderness and restore from backup for anything players built.

##### Does Minecraft have a built-in repair command?

Not for damaged data. The server's `--forceUpgrade` option rewrites every chunk in the current format, which can help with old-format chunks after an upgrade, but it does not repair damaged bytes. Region repair is done with external tools or backups.

##### My world reset to a new map after a crash. Is everything gone?

Probably not. Check whether `level-name` in `server.properties` still matches the world folder, and whether `level.dat` exists. If `level.dat` is damaged, restore it from `level.dat_old`. The region files with all your builds are usually untouched.

##### Is it safe to run MCA Selector on a live server?

No. Always stop the server first, and work on a copy. The server keeps chunks in memory and will overwrite your changes on its next save, or interleave writes with yours.

RE:NODE Minecraft servers stop cleanly from the Stop and Restart buttons, and backups are stored off the machine they protect, downloadable from the panel for pulling out a single region file, and restorable in full with one button. If a server hits its memory limit it is stopped and restarted clean rather than left to swap.

[See Minecraft plans](https://www.renode.space/game-servers/minecraft)

---

### Cobblemon server setup and performance

Published 2026-10-07 by RE:NODE Team. https://www.renode.space/blog/minecraft-cobblemon-server-guide

A Cobblemon server is a modded Minecraft server running the Cobblemon mod on Fabric or NeoForge, with every player running the same mod version on their client. Current releases target Minecraft 1.21.1; you need Fabric API and Fabric Language Kotlin on Fabric, or Kotlin for Forge on NeoForge, because the mod is written in Kotlin. A small group is comfortable on 4 GB, a modpack built around Cobblemon wants 6 to 8 GB, and the settings that decide performance live in `config/cobblemon/main.json` - how many Pokemon spawn per chunk, how often spawning runs, how far from players, and when they despawn. Player parties and PCs are saved inside the world folder by default, which makes backups simple and moving players between servers less so.

The general modded-server ground - Java versions, crash reports, client and server mods - is in [running a modded server without the crashes](https://www.renode.space/blog/modded-minecraft-without-the-crashes). This guide covers what is specific to Cobblemon.

#### Versions, loaders and dependencies

Cobblemon's supported loaders have moved over its life, so check the version page before you install anything.

| Cobblemon | Minecraft | Loaders | Extra dependencies |
| --- | --- | --- | --- |
| 1.6 and later | 1.21.1 | Fabric, NeoForge | Fabric API + Fabric Language Kotlin, or Kotlin for Forge |
| 1.5 and earlier | 1.20.1 | Fabric, Forge | Same pattern, older versions |

Rules that save you a support ticket:

- Server and clients run the same Cobblemon version, on the same loader. A Fabric client cannot join a NeoForge server.
- The Kotlin language mod is required on both sides. A missing Kotlin dependency is the most common first-start failure; the log names it.
- Addons target specific Cobblemon versions. After a Cobblemon update, check each addon before updating the server.

Most groups start from a modpack rather than bare Cobblemon. The official Cobblemon modpack and several community packs add quality-of-life and performance mods and match versions for you. [Modpack servers from CurseForge and Modrinth](https://www.renode.space/blog/minecraft-modpack-server-curseforge-modrinth) covers turning a pack into a server.

#### Installing the server

Fabric is the lighter option and the one most Cobblemon packs use; NeoForge is equally supported. A bare Fabric install:

1. Download the Fabric server launcher for 1.21.1 and the matching loader version, or run the Fabric installer in server mode.
2. Put Cobblemon, Fabric API and Fabric Language Kotlin into `mods/`.
3. Start once to generate files, accept the EULA, start again.
4. Stop, edit `config/cobblemon/main.json`, start again.

```bash
$ java -Xms4G -Xmx4G -jar fabric-server-launch.jar nogui
```

Java 21 is required for 1.21.1. [Fabric server performance mods](https://www.renode.space/blog/minecraft-fabric-server-performance-mods) covers Lithium, FerriteCore and the other server-side mods worth adding - they help a Cobblemon server as much as any other. For NeoForge, see [NeoForge server setup](https://www.renode.space/blog/minecraft-neoforge-server-setup).

On first start, Cobblemon sets up its battle engine, which runs Pokemon Showdown's battle logic inside the server. If the first battle hangs or errors, check the log for that step; `autoUpdateShowdown` in `main.json` controls whether it is refreshed on start.

#### main.json: the settings that matter

Cobblemon's server settings are in `config/cobblemon/main.json`. The file is long and most of it is gameplay balance. The values below are defaults in current releases; some keys were renamed between versions, so read the file your server generated rather than copying this.

config/cobblemon/main.json (excerpt):

```json
{
  "maxPokemonLevel": 100,
  "shinyRate": 8192.0,
  "experienceMultiplier": 2.0,
  "enableSpawning": true,
  "pokemonPerChunk": 1.0,
  "ticksBetweenSpawnAttempts": 20.0,
  "maximumSpawnsPerPass": 8,
  "minimumSpawningZoneDistanceFromPlayer": 16.0,
  "maximumSpawningZoneDistanceFromPlayer": 64.0,
  "despawnerNearDistance": 32.0,
  "despawnerFarDistance": 96.0,
  "despawnerMinAgeTicks": 600,
  "despawnerMaxAgeTicks": 3600,
  "storageFormat": "nbt",
  "pokemonSaveIntervalSeconds": 30,
  "playerDamagePokemon": true
}
```

| Key | Default | What it does |
| --- | --- | --- |
| `shinyRate` | `8192` | One in this many wild Pokemon is shiny. Lower means more shinies |
| `maxPokemonLevel` | `100` | Level cap |
| `experienceMultiplier` | `2` | Battle experience scaling |
| `pokemonPerChunk` | `1` | Density cap for wild spawns around players |
| `ticksBetweenSpawnAttempts` | `20` | How often spawning runs, in ticks |
| `maximumSpawnsPerPass` | `8` | Most spawns in one attempt |
| `despawnerNearDistance` / `FarDistance` | `32` / `96` | Distances that govern despawning of wild Pokemon |
| `despawnerMinAgeTicks` / `MaxAgeTicks` | `600` / `3600` | How old a wild Pokemon must be before it can or must despawn |
| `worldSpawningBlocklist` | empty | Worlds where Cobblemon spawning is off |
| `storageFormat` | `nbt` | How parties and PCs are stored: NBT, JSON or MongoDB |
| `playerDamagePokemon` | `true` | Whether players can hit Pokemon |

`shinyRate` is the one players ask about first. Lowering it to `4096` doubles shiny odds; event weekends with a lower rate are a common server feature. Changing it needs a restart.

#### Spawning, despawning and performance

Every wild Pokemon is an entity with AI, animation state and collision, and Cobblemon spawns them around every player. That is the main cost of a Cobblemon server, and it scales with players spread across the map rather than with the world's size.

The levers, in order of effect:

- **`pokemonPerChunk`.** The density cap. Dropping it from `1.0` to `0.7` cuts wild Pokemon around each player by roughly a third. Encounters become a little less frequent; the server gets noticeably lighter with many players.
- **`ticksBetweenSpawnAttempts`.** Raising from `20` (once a second) to `40` halves how often the spawner runs. Spawns still fill up to the cap, just more slowly.
- **Despawn ages.** Lowering `despawnerMaxAgeTicks` from `3600` (three minutes) clears old wild Pokemon sooner. Too low, and players lose a Pokemon they were walking towards.
- **Vanilla spawning.** Many Cobblemon servers reduce vanilla animal and monster spawning, since Pokemon fill the world. On a Fabric server that means gamerules or a performance mod setting, not Paper's `bukkit.yml`.
- **Simulation distance.** Wild Pokemon only exist and tick within the area around players. `simulation-distance=6` or `8` in `server.properties` is sensible for a busy server. [server.properties explained](https://www.renode.space/blog/minecraft-server-properties-explained) covers it.

Pokemon that players keep out of their party also cost something. Pastures keep pastured Pokemon roaming as entities; current releases cap them with `defaultPasturedPokemonLimit` (16 per pasture) and `pastureMaxPerChunk`. A base with ten pastures is 160 entities with AI whenever its chunks are loaded. Set a per-player pasture expectation if bases start to lag.

Measure as on any server: spark is available for Fabric and NeoForge, and a profile on a Cobblemon server with lag usually shows Pokemon entity ticking and spawning at the top. [Reading a spark report](https://www.renode.space/blog/minecraft-spark-profiler-lag-diagnosis) explains the views. If the cost is in chunk generation rather than entities, pre-generate - [world borders and pre-generation](https://www.renode.space/blog/minecraft-world-border-and-pregeneration) covers Chunky, which has Fabric and NeoForge builds.

| Players | Setup | RAM |
| --- | --- | --- |
| 1-4 | Cobblemon + performance mods | 4 GB |
| 4-10 | Cobblemon modpack (50-150 mods) | 6 GB |
| 10-20 | Modpack, mature world, many pastures | 8 GB+ and more CPU |

#### Spawns, datapacks and customising the Pokedex

Cobblemon's spawn rules are data, not code. Spawn pools - which Pokemon appear in which biomes, at what levels, at what weight, under what conditions - are JSON files in Cobblemon's data, and a datapack can override or add to them. That is how servers make a rare Pokemon appear only in one biome, remove a species from the wild for an event, or add spawns for addon content.

The `exportSpawnConfig` option in `main.json` exports the current spawn data to the config folder so you can read what the defaults are before overriding them. Read the Cobblemon wiki for the current spawn file format; it has changed between versions, and old datapacks need updating along with the mod. [Datapacks for servers](https://www.renode.space/blog/minecraft-datapacks-guide) covers where datapacks go and how they load.

Per-world control is simpler: `worldSpawningBlocklist` stops Cobblemon spawning in listed worlds, which is useful for a lobby, a build world or a mining dimension.

#### Player data, storage and backups

By default (`storageFormat: "nbt"`) Cobblemon saves each player's party and PC as files inside the world folder, separately from vanilla player data. `pokemonSaveIntervalSeconds` controls how often changes are written.

Consequences:

- **Backing up the world backs up everyone's Pokemon.** One backup covers it.
- **Restoring the world rolls back everyone's Pokemon.** Restoring last night's backup to fix one griefed base also undoes everyone's catches since then. For single-player rollbacks, restore just that player's Cobblemon files from a backup instead.
- **Moving players between servers** means moving their Cobblemon data. A network with several Cobblemon servers sharing parties can use the MongoDB storage option (`storageFormat: "mongodb"` with `mongoDBConnectionString` and `mongoDBDatabaseName`) so all servers read the same storage.

> [!WARNING]
> Stop the server cleanly before copying or restoring Cobblemon data. Parties are held in memory and written on an interval; a copy taken while running, or a kill without a save, can lose recent catches and trades. A clean stop writes everything.

A Pokemon-themed server gets more support requests about lost Pokemon than any other kind of server gets about lost items. Have a policy before launch - what you restore, from what backup, and how often - and keep backups frequent enough to honour it. [Backups that actually restore](https://www.renode.space/blog/backups-that-actually-restore) explains why a restore you have tested matters.

#### Admin commands and permissions

Cobblemon includes admin commands for giving and spawning Pokemon, and they matter for events, giveaways and fixing support cases.

```text
/pokegive <player> <pokemon properties>
/pokespawn <pokemon properties>
```

The properties string describes the Pokemon - species, level, shiny, and other attributes - for example `pikachu level=20 shiny=yes`. The exact property names are documented on the Cobblemon wiki and grow with each release.

Cobblemon exposes permission nodes for its commands, so on Fabric a permissions mod (LuckPerms has a Fabric build) can grant staff exactly the commands they need. Check the wiki for the node names on your version. Do not hand out operator status to event staff to let them run `/pokegive`; grant the node instead. [LuckPerms](https://www.renode.space/blog/minecraft-luckperms-guide) covers groups and nodes.

Plugins do not run on a Fabric or NeoForge server. Bukkit-plus-mod hybrid servers exist, and some Cobblemon communities use them, but they break in subtle ways with large mods and are a support burden. If you need plugin-style features - claims, economy, homes - use the mod equivalents.

#### Running a public Cobblemon server

A few things specific to Pokemon communities:

- **Trading and scams.** Cobblemon's trade screen shows both sides; most "scams" are off-platform deals that went wrong. Write a rule about it.
- **Cloning and dupes.** Any duplication bug in a mod becomes a Pokemon dupe. Keep the mod updated and watch the issue tracker.
- **Shiny economies.** Shinies become currency. Event shiny-rate changes affect that economy; announce them.
- **Money and the brand.** Cobblemon is a fan project; Pokemon is someone else's intellectual property. Selling Pokemon, shinies or Pokemon-themed perks for real money invites trouble from the rights holder as well as the Minecraft rules. Read [what you may sell on a Minecraft server](https://www.renode.space/blog/minecraft-rank-store-tebex-rules) before opening a store.

#### Troubleshooting

**The server will not start and the log mentions Kotlin.** The language mod is missing or the wrong version. Fabric needs Fabric Language Kotlin; NeoForge needs Kotlin for Forge. Match the version Cobblemon's release page lists.

**Players are kicked with a mod mismatch.** Their Cobblemon version, loader or addon list differs from the server. Compare the exact version numbers; launchers that auto-update the client are the usual culprit. Pin the pack version and announce updates before you apply them.

**Battles hang or never start.** Check the log at startup for errors setting up the battle engine, and around the moment the battle began. Addons that modify battles are frequent suspects after an update; remove them and test.

**No Pokemon are spawning.** Check `enableSpawning` is `true`, that the world is not in `worldSpawningBlocklist`, and that a datapack has not replaced the spawn pools with something empty or malformed. A broken spawn datapack usually logs a parse error at startup.

**Too many Pokemon around bases.** That is usually pastures, not wild spawns. Count them with the vanilla selector, for example `/execute if entity @e[type=cobblemon:pokemon]`, while standing at the base, and compare with the same count in the wild.

**A player says their Pokemon disappeared.** Before restoring anything, check the log for the player's last session - trades, releases and deaths are recorded by most logging setups - and whether the server stopped uncleanly since their last catch. If it did, the loss is the save interval, and the fix for the future is clean stops. If it did not, restore only that player's data from a backup, not the whole world.

**Memory climbs over days.** Large modded servers do accumulate; a scheduled restart once a day at a quiet hour keeps it flat. [Restart schedules that help](https://www.renode.space/blog/restart-schedules-that-help) covers timing and warnings.

On RE:NODE the Minecraft line ships Paper, so a Cobblemon server is your own install: you upload Fabric or NeoForge, the mods and the configs through the file manager or SFTP and set the startup variables. There is no one-click modpack installer. Backup slots on every plan are stored off the machine, can be locked so rotation does not remove them, and restore with a button - which, given how attached players get to their Pokemon, is the feature you will use.

#### FAQ

##### Can players join a Cobblemon server with a vanilla client?

No. Cobblemon adds entities, items and screens, so every player needs the same Cobblemon version and loader as the server, plus the Kotlin dependency. A modpack keeps everyone matched.

##### How do I change the shiny rate on my Cobblemon server?

Edit `shinyRate` in `config/cobblemon/main.json` and restart. It is a one-in-N value, so `4096` doubles the default odds of `8192`.

##### Why is my Cobblemon server lagging with only a few players?

Usually wild spawns spread across several players far apart, or pastures full of Pokemon at bases. Lower `pokemonPerChunk`, raise `ticksBetweenSpawnAttempts`, and profile with spark to confirm entity ticking is the cost.

##### Where are players' Pokemon saved?

Inside the world folder by default, in NBT format, separate from vanilla player data. Backing up the world includes them. MongoDB storage is available for networks that share parties across servers.

##### Can I use Paper plugins with Cobblemon?

Not on a normal Fabric or NeoForge server. Hybrid servers that load both exist but are unreliable with large mods. Use mod equivalents for claims, homes and economy.

RE:NODE Minecraft plans run Paper by default; a Cobblemon server is your own upload through the file manager or SFTP. Every plan has backup slots stored off the machine that you can lock and restore with a button, and the Schedules tab can take one every night.

[See Minecraft plans](https://www.renode.space/game-servers/minecraft)

---

### Minecraft crash reports: watchdog and lag

Published 2026-10-07 by RE:NODE Team. https://www.renode.space/blog/minecraft-crash-reports-explained

A Minecraft server crash report is a text file in `crash-reports/` that names what the server was doing when it died: the exception, the stack trace, and - often - the exact entity or block entity being ticked, with its coordinates. Read three things in order: the Description line, the first lines of the stack trace looking for a package name that is not Minecraft's or Paper's, and the "being ticked" section if there is one. That identifies the cause in most cases. Lag-related shutdowns are different: they come from the watchdog, print a thread dump to the log instead of a crash file, and are read by looking at what the main thread was stuck on. The "Can't keep up" warning, meanwhile, is not a crash at all.

This post is about Paper and vanilla servers. Modded servers produce the same reports with more lines in them - [running a modded server without the crashes](https://www.renode.space/blog/modded-minecraft-without-the-crashes) covers what is specific to Forge, NeoForge and Fabric.

#### Three kinds of "the server crashed"

People use one word for three different events, and each leaves different evidence.

| What happened | Evidence | Where |
| --- | --- | --- |
| An exception the server could not handle | `crash-YYYY-MM-DD_HH.MM.SS-server.txt` | `crash-reports/` |
| The main thread stopped responding | Watchdog thread dump | `logs/latest.log` |
| The process was killed from outside | Nothing from the server at all | Host's console or exit code |

The third case confuses people most. If the log simply stops mid-line with no crash report and no shutdown messages, the Java process did not crash - it was terminated. The usual cause on a hosted server is reaching the memory limit: the container is stopped by the kernel, and Java never gets the chance to write anything. On RE:NODE, a server that hits its memory limit is stopped and restarted clean rather than left to swap, and the panel's memory graph shows it reaching the line just before. [Linux swap and the OOM killer](https://www.renode.space/blog/linux-swap-and-the-oom-killer) explains what happens at that moment, and [why your game server keeps restarting](https://www.renode.space/blog/why-your-game-server-keeps-restarting) covers the pattern when it repeats.

#### Anatomy of a crash report

A crash report has the same structure every time. Here is a trimmed one:

crash-reports/crash-2026-10-07_21.14.03-server.txt:

```text
---- Minecraft Crash Report ----
// Shall we play a game?

Time: 2026-10-07 21:14:03
Description: Ticking entity

java.lang.NullPointerException: Cannot invoke "org.bukkit.Location.getWorld()" because "loc" is null
    at com.example.petsplus.PetTask.follow(PetTask.java:88)
    at com.example.petsplus.listener.PetListener.onMove(PetListener.java:41)
    at net.minecraft.world.entity.Entity.tick(Entity.java:...)
    ...

A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------

-- Head --
Thread: Server thread

-- Entity being ticked --
Details:
    Entity Type: minecraft:wolf
    Entity's Exact location: -412.50, 64.00, 1290.31
...
-- System Details --
Details:
    Minecraft Version: 1.21.x
    Java Version: 21.0.x
    Memory: 2140000000 bytes (2040 MiB) / 4294967296 bytes (4096 MiB) up to ...
    JVM Flags: ...
```

What each part tells you:

- **The comment** under the header is a random joke. Ignore it.
- **Description** is the category: `Ticking entity`, `Ticking block entity`, `Exception in server tick loop`, `Watching Server`, `Exception generating new chunk`. It tells you which section further down will have coordinates.
- **The exception line** - the type and message. `NullPointerException`, `ConcurrentModificationException`, `StackOverflowError`, `OutOfMemoryError` and `ClassCastException` cover most cases.
- **The stack trace** - the chain of method calls that led to the error, most recent first.
- **The "being ticked" section** - for ticking crashes, the entity type or block type and its exact location. This is gold: it tells you where in the world the problem is.
- **System Details** - Minecraft version, Java version, memory at the time, JVM flags. Check these whenever a crash looks inexplicable; a wrong Java version or a tiny heap explains a lot.

#### Reading a stack trace

A stack trace lists method calls with the one that failed at the top. Each line is `at package.Class.method(File.java:line)`. You do not need to be a programmer to use one; you need to recognise package names.

1. **Read from the top down, and stop at the first line that is not the game.** Minecraft's own code is under `net.minecraft`, Paper and Bukkit under `io.papermc`, `org.bukkit` and `org.spigotmc`, Java itself under `java.` and `jdk.`. The first frame outside those is usually the culprit. In the example above, `com.example.petsplus` is a plugin, and it is at the very top.
2. **Look for "Caused by:".** Exceptions are often wrapped: the top exception says "error while ticking", and a `Caused by:` further down holds the real one. The last `Caused by:` in the chain is the root cause; read its first frames the same way.
3. **Match the package to a plugin.** Package names usually contain the plugin's or author's name. If it is not obvious, search the `plugins/` folder: each jar's `plugin.yml` or `paper-plugin.yml` names its main class, which starts with the same package.
4. **Note the version.** Whatever you report to a plugin author, include the plugin version, the Paper build and the full crash report, not a screenshot of the last ten lines.

When the whole stack is inside `net.minecraft` with no plugin frames at all, the crash is in the game itself or caused by bad data in the world - a corrupted entity or chunk. The "being ticked" coordinates then become the most useful part of the report; [corrupted chunks and region files](https://www.renode.space/blog/minecraft-chunk-errors-and-world-corruption) covers what to do with them.

> [!TIP]
> Paste long logs and crash reports into a log-sharing site such as mclo.gs rather than into a chat message. It keeps line breaks, highlights errors, and strips IP addresses. Never paste server configs or logs containing passwords, RCON details or database credentials anywhere public.

#### Errors that appear in the log but do not crash the server

Not every stack trace is a crash. Plugin errors are often caught and logged, and the server carries on. Two Bukkit messages are worth recognising:

```text
[ERROR]: Could not pass event PlayerInteractEvent to ShopKeeperX v2.4.1
org.bukkit.event.EventException: null
    ...
Caused by: java.lang.NullPointerException: ...
```

```text
[ERROR]: Error occurred while enabling WarpsPlus v1.3 (Is it up to date?)
java.lang.NoSuchMethodError: ...
```

They look alarming in the console, but they mean different things:

- **"Could not pass event X to Y"** - plugin Y threw an exception while handling an event. That feature of the plugin is broken for that action; the server is fine. Read the `Caused by` line.
- **"Error occurred while enabling X (Is it up to date?)"** - the plugin failed to start, usually because it was built for a different Minecraft version or is missing a dependency. The plugin is disabled.

The Java error type often tells you the kind of problem before you read further:

| Error | Usually means |
| --- | --- |
| `NoSuchMethodError`, `NoSuchFieldError` | Plugin built for another Minecraft or Paper version |
| `NoClassDefFoundError`, `ClassNotFoundException` | Missing dependency plugin, or wrong version |
| `UnsupportedClassVersionError` | Java too old for the plugin or server |
| `NullPointerException` | A bug in the plugin, or bad data it did not expect |
| `ConcurrentModificationException` | A plugin modifying something from the wrong thread |
| `StackOverflowError` | Infinite recursion, often two plugins triggering each other |
| `OutOfMemoryError: Java heap space` | Heap too small, or a memory leak |

`UnsupportedClassVersionError` messages quote a class file version: `61.0` means the code needs Java 17, `65.0` needs Java 21. If the server's Java is older than that, the code cannot load. [JVM flags and Java versions](https://www.renode.space/blog/minecraft-jvm-flags-and-java-versions) has the version matrix.

`OutOfMemoryError` deserves its own note, because its message says which memory ran out. `Java heap space` means the heap set by `-Xmx` is full: either it is too small for the world and plugins, or something is leaking and the heap would fill at any size. `GC overhead limit exceeded` is the same problem seen from the garbage collector's side - it is spending nearly all its time freeing almost nothing. `Metaspace` is class metadata, and on a plugin server it usually points at a plugin being reloaded repeatedly with `/reload` or a plugin manager, which leaks old copies of every class. A heap error is not a reason to raise `-Xmx` to the full plan size: the JVM needs memory outside the heap too, and a heap set to the container limit turns a Java error with a report into a kill with no report at all.

#### "Can't keep up!" is a warning, not a crash

```text
[WARN]: Can't keep up! Is the server overloaded? Running 5214ms or 104 ticks behind
```

The server aims for 20 ticks per second, 50 ms each. When it falls more than a couple of seconds behind schedule, it logs this and skips the missed ticks rather than trying to catch up. The message means the server was not able to do 50 ms of work in 50 ms for a while.

What it does not tell you is why. A single message after startup is normal - world loading and plugin initialisation take time. An occasional message during a big event is normal. A steady stream of them is a lag problem, and the cause is one of:

- **Something expensive on the main thread**: too many entities, a farm, chunk generation, a slow plugin.
- **Garbage collection pauses**, from a heap that is too small or badly tuned flags.
- **CPU starvation**, where the process is not getting enough CPU time. On a host with hard CPU limits, a server that needs more than its share is throttled, which looks exactly like lag.

The number of ticks behind is not a severity score you can use directly; it depends on how long the stall was. Use [spark](https://www.renode.space/blog/minecraft-spark-profiler-lag-diagnosis) to find the actual cause, and [why TPS drops](https://www.renode.space/blog/why-tps-drops-and-what-to-do) for the usual fixes.

#### The watchdog: when the server stops responding

If one tick takes far too long, the server assumes the main thread is stuck forever and shuts itself down. That is the watchdog. There are two settings, one from vanilla and one from Spigot:

server.properties:

```properties
max-tick-time=60000
```

spigot.yml:

```yaml
settings:
  timeout-time: 60
  restart-on-crash: true
  restart-script: ./start.sh
```

What each of those settings does, and what to leave alone:

- `max-tick-time` is vanilla's watchdog, in milliseconds. If one tick takes longer, the server writes a crash report with the description `Watching Server` and stops. `-1` disables it - which turns a stuck server into one that hangs forever instead of restarting. Do not.
- `timeout-time` is Spigot's watchdog, in seconds. Paper uses it to decide when to print a thread dump and stop.
- `restart-on-crash` and `restart-script` let the server run a script to restart itself. On a panel host, leave restarting to the panel; the script path rarely exists in a container.

Paper adds early warnings, controlled in `config/paper-global.yml`:

config/paper-global.yml:

```yaml
watchdog:
  early-warning-every: 5000
  early-warning-delay: 10000
```

After the main thread has been stuck for `early-warning-delay` milliseconds, Paper prints a thread dump every `early-warning-every` milliseconds, without killing the server. That means you get evidence even when the server recovers on its own.

##### Reading a thread dump

```text
[ERROR]: --- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH ---
[ERROR]: The server has not responded for 10 seconds! Creating thread dump
[ERROR]: ------------------------------
[ERROR]: Server thread dump (Look for plugins here before reporting to Paper!):
[ERROR]: Current Thread: Server thread
[ERROR]:     PID: 27 | Suspended: false | Native: false | State: RUNNABLE
[ERROR]:     Stack:
[ERROR]:         com.example.claims.Storage.saveAll(Storage.java:212)
[ERROR]:         com.example.claims.ClaimsPlugin.onAutosave(ClaimsPlugin.java:77)
[ERROR]:         org.bukkit.craftbukkit.scheduler.CraftTask.run(...)
```

The exact wording varies by Paper version. The "Server thread" stack is what matters: it shows what the main thread was doing at the moment of the dump. Read it top down exactly like a crash stack trace. In the example, a claims plugin is saving all its data synchronously on the main thread, which is a bug or a configuration problem in that plugin.

If several consecutive dumps show the same frames, that is the stuck code. If they differ each time, the thread is busy rather than stuck - generally an overload, and a profiler shows it better than dumps do. If the stack shows a database or network call (`java.net`, `jdbc`, `SocketInputStream`), a plugin is waiting on something remote from the main thread; [MySQL for plugins](https://www.renode.space/blog/minecraft-mysql-for-plugins) covers why that hurts.

#### Native crashes and hs_err files

Very rarely, the Java virtual machine itself crashes. It writes a file named `hs_err_pid<number>.log` in the server's working directory, and the log stops abruptly. Causes are a JVM bug, a native library from a plugin, or hardware trouble. The first thing to try is a current Java build of the right major version; the second is removing any plugin that bundles native code. These are rare enough that one is worth investigating rather than ignoring.

#### A routine for any crash

1. **Collect evidence before restarting again.** Copy `logs/latest.log` and any new file in `crash-reports/`. A restart rotates the log.
2. **Classify it**: crash report, watchdog dump, or a log that just stops.
3. **Find the first non-game frame** in the stack, or the coordinates in the "being ticked" section.
4. **Change one thing**: update or remove that plugin, or deal with that entity or chunk. Then watch.
5. **If it repeats with different causes**, look at the common factors: memory, Java version, a recent update.

On RE:NODE, a watcher counts crashes: restarts you ask for are not counted, but three unplanned ones in an hour put a warning on the server page and open a ticket automatically, and six suspend the server until it is looked at. That is a reason to treat a crash loop as urgent rather than letting it restart itself all night. The panel console shows the full unfiltered output, so the evidence in step 1 is available even when the server will not stay up.

#### FAQ

##### Where are Minecraft server crash reports saved?

In the `crash-reports` folder in the server's root directory, named with the date and time and ending in `-server.txt`. Watchdog dumps and plugin errors are in `logs/latest.log` instead, and older logs are gzipped in `logs/`.

##### Why is there no crash report when my server stops?

Because it was stopped from outside the Java process, usually for exceeding its memory limit. Java cannot write a report when it is killed. Check the memory graph around the time of the stop.

##### Is "Can't keep up" dangerous?

Not by itself. It means the server fell behind and skipped ticks. Constant warnings mean real lag that players feel, and the cause needs finding, but the warning does not damage the world.

##### Should I disable the watchdog so the server stops crashing?

No. The watchdog only fires when the server is already frozen. Disabling it leaves a frozen server running forever instead of producing evidence and restarting. Fix what makes ticks take that long.

##### The crash report only mentions Minecraft classes. Is it a Paper bug?

Possibly, but more often it is bad data in the world, such as a corrupted entity, or a plugin whose effect shows up later in vanilla code. Check the "being ticked" coordinates and test with plugins removed before reporting it upstream.

RE:NODE Minecraft servers show the full live console with graphs for memory, CPU and disk against the limits, so you can see what the server was doing before it stopped. Paper runs with the matching Java version already installed, and a crash loop raises a warning and a ticket instead of failing silently.

[See Minecraft plans](https://www.renode.space/game-servers/minecraft)

---

### Create mod server: setup, trains and lag

Published 2026-10-07 by RE:NODE Team. https://www.renode.space/blog/minecraft-create-mod-server

The Create mod runs well on a dedicated server, and it is one of the best reasons to run a modded server at all: a shared rail network and a factory town are better with other people. The setup is ordinary modded Minecraft - Create 6 runs on NeoForge for 1.21.1 and on Forge for 1.20.1, every player needs the same Create version and the same addons, and a small group is comfortable on 4 to 6 GB with Create and a handful of addons. The Create-specific parts are three: addons must match the exact Create version, moving contraptions and large kinetic networks are where the tick time goes, and the server config (`create-server.toml`) holds the limits - contraption size, belt length, rotation speed, train length - that decide how far players can push it before the server pays.

General modded-server mechanics - Java versions, crash reports, client and server mods - are in [running a modded server without the crashes](https://www.renode.space/blog/modded-minecraft-without-the-crashes). This guide covers what is different about Create.

#### Versions, loaders and addons

Create's version history matters more than most mods', because the jump to Create 6 broke a large part of the addon ecosystem.

| Create version | Minecraft | Loader | Notes |
| --- | --- | --- | --- |
| 0.5.1 | 1.20.1 and older | Forge | Long-lived; most older packs and addons target it |
| 0.5.1 Fabric port | 1.20.1 | Fabric | Separate project by a different team |
| 6.0.x | 1.20.1 | Forge | Major content update; many addons needed updates |
| 6.0.x | 1.21.1 | NeoForge | Current main line |

The Fabric version of Create has always been a separate port by a different team, released after the Forge version and sometimes with differences. If you want the newest Create, use NeoForge on 1.21.1 or Forge on 1.20.1. Check the project page for the current state of the Fabric port before planning around it.

Create bundles its own libraries - Flywheel for rendering and Ponder for the in-game tutorials - inside its jar in recent versions, so you do not install them separately. If an older guide tells you to add Flywheel, it is for an older Create.

Addons are where version mismatches happen. Common ones include Steam 'n' Rails (more track types and train features), Create Crafts and Additions (electricity), Create: Enchantment Industry, Create Deco, Create: New Age and Create Slice and Dice. Each one targets a specific Create version, often a narrow range. Rules:

1. Pick the Create version first.
2. For every addon, find the release that targets exactly that Create version. Release notes say which.
3. If an addon has no release for your Create version, leave it out rather than forcing an older one in. A mismatched Create addon usually fails at startup with a clear error, and occasionally loads and corrupts something later, which is worse.
4. Players install exactly the same set. Create and all its addons are needed on both sides.

A modpack built around Create - there are many on CurseForge and Modrinth - has done this matching for you, which is a strong argument for starting from one. [Modpack servers from CurseForge and Modrinth](https://www.renode.space/blog/minecraft-modpack-server-curseforge-modrinth) covers turning a pack into a server.

#### Setting up the server

For NeoForge 1.21.1, the installation is the standard NeoForge server install - run the installer with `--installServer`, which produces a `run.sh` and a `user_jvm_args.txt` - then drop Create and its addons into `mods/`. [NeoForge server setup](https://www.renode.space/blog/minecraft-neoforge-server-setup) has the step-by-step. Forge 1.20.1 is the same shape.

```bash
$ java -jar neoforge-<version>-installer.jar --installServer
$ echo "-Xms4G -Xmx4G" > user_jvm_args.txt
$ ./run.sh
```

Java 21 for 1.21.1, Java 17 or newer for 1.20.1. [JVM flags and Java versions](https://www.renode.space/blog/minecraft-jvm-flags-and-java-versions) covers the heap and flags.

Memory, as a rule of thumb from running these servers rather than a figure from the mod authors:

| Setup | Players | RAM |
| --- | --- | --- |
| Create only, new world | 2-5 | 4 GB |
| Create plus 5-10 addons | 2-8 | 5-6 GB |
| Create-themed modpack (100-200 mods) | 4-10 | 6-8 GB |
| Mature world, big factories and rail network | 8+ | 8-10 GB |

CPU matters as much as RAM. Create's work is on the main server thread, and a world with many running contraptions is limited by single-core speed long before memory. [CPU vs RAM for game servers](https://www.renode.space/blog/cpu-vs-ram-for-game-servers) explains why buying more memory does not help a tick-bound server.

The file to know is the server config. On Forge 1.20.1 per-world server configs live in the world's `serverconfig` folder, so Create's is at `world/serverconfig/create-server.toml`; NeoForge versions may place server configs differently, so search the server folder for `create-server.toml` after the first start. There is also `config/create-common.toml` for world generation, and client configs that do not matter on a server.

#### The server config limits

Create's server config is where you decide how big things can get. The values below are the defaults in Create 6; older versions have most of the same keys with some different values.

create-server.toml (excerpt):

```toml
[kinetics]
  maxBeltLength = 20
  maxRotationSpeed = 256
  kineticValidationFrequency = 60

  [kinetics.contraptions]
    maxBlocksMoved = 2048
    maxChassisRange = 16
    maxPistonPoles = 64
    maxRopeLength = 384
    maxCartCouplingLength = 32

[trains]
  maxAssemblyLength = 128
  maxBogeyCount = 20
  trainTopSpeed = 28
  poweredTrainTopSpeed = 40
```

| Key | Default | What it limits |
| --- | --- | --- |
| `maxBlocksMoved` | `2048` | Blocks in one moving contraption |
| `maxChassisRange` | `16` | How far a chassis reaches to attach blocks |
| `maxPistonPoles` | `64` | Extension poles on a mechanical piston |
| `maxRopeLength` | `384` | Rope pulley length |
| `maxBeltLength` | `20` | Blocks in one belt |
| `maxRotationSpeed` | `256` | Highest RPM any component can reach |
| `maxAssemblyLength` | `128` | Length of an assembled train |
| `maxBogeyCount` | `20` | Bogeys per train |

`maxBlocksMoved` is the important one on a shared server. A contraption is all its blocks moving together as one entity; a 2,000-block drill on a mechanical bearing is a lot of collision geometry being recalculated as it moves, and it is sent to every player in range. Lowering the limit to something like `1024` stops the largest builds and is rarely noticed by normal ones. Raising it on a server with ambitious builders is how you discover the contraption problem.

`maxRotationSpeed` caps RPM. Lower speeds mean less output per machine but also less work for fans, saws and crushers that process items faster at higher speeds. Leaving it at `256` is normal.

The config also has a `disableStress` switch. Turning stress off removes the core design constraint - you no longer need to provide enough power - and players then build more machines on fewer power sources, which costs ticks. Leave it on.

#### Why Create lags, and what to do

Create is well optimised for what it does, and still capable of filling a tick. The usual causes, in order of how often they turn up in a spark report:

**Moving contraptions.** Drills, harvesters, elevators, rotating windmills with huge sails, and especially contraptions that never stop. A windmill is a contraption that rotates forever - normally cheap, but a windmill of hundreds of blocks of sails is a large entity rotating continuously. Large sail arrays should be built as several smaller windmills, or replaced with water wheels or steam engines, which are block entities and do not move.

**Large kinetic networks.** Shafts and cogs propagate rotation through a network. When something changes - a block added, a gearshift toggled, a clutch released - the network recalculates. A factory where everything is one huge network with clutches toggling constantly recalculates constantly. Splitting a factory into separate networks, each with its own power source, keeps changes local.

**Item processing at volume.** Belts are cheap; items on belts are stored by the belt, not as separate entities. Funnels, chutes, depots and especially fans processing many items at once cost more. Mechanical crafters and deployers - deployers act as fake players - are relatively expensive per action, and a farm of hundreds of deployers adds up.

**Item entities.** Contraptions that break blocks without collecting them drop items into the world. A tree farm or a drill without storage on the contraption leaves item entities everywhere. [Entity cleanup and ClearLag](https://www.renode.space/blog/minecraft-entity-cleanup-and-clearlag) has the commands; the fix is to put storage on contraptions or collect output.

**Chunk loading.** Create itself does not keep chunks loaded. A factory only runs while someone is near it, unless a chunk-loading mod (FTB Chunks, for instance) or an addon forces it. Every force-loaded factory is a factory that runs all the time. Set a limit per player.

> [!TIP]
> Find which contraption is expensive the same way you would on Paper: spark. The Forge and NeoForge builds of spark work the same way, and a report that names `Contraption` entities or a particular kinetic block entity points you straight at the build. [Reading a spark report](https://www.renode.space/blog/minecraft-spark-profiler-lag-diagnosis) covers the method.

#### Trains on a shared server

Trains are the feature everyone wants on a Create server, and they behave better than people expect. A train on a track graph is simulated by Create's railway system when it runs through unloaded chunks; it does not need to keep chunks loaded along its route, and it does not load them as it passes. When it enters loaded chunks near a player, it becomes a visible contraption entity again.

That means a global rail network with dozens of scheduled trains is feasible, and the cost while nobody watches is modest. What costs more:

- **Long trains.** Each carriage is a contraption. A train at the 128-block assembly limit with twenty bogeys is a large entity whenever players are near it. Lowering `maxAssemblyLength` and `maxBogeyCount` keeps the biggest freight trains reasonable.
- **Stations and loading.** Trains loading and unloading at stations with funnels and deployers are factories, and cost as factories do when the chunks are loaded.
- **Signals and junction complexity.** Very large signal networks add pathfinding work for each scheduled train. It is rarely the top cost, but a network of hundreds of junctions is not free.

Agree on a rail network plan. Shared trunk lines with agreed gauges and signalling, stations named consistently and a rule about where private branches may join, avoid the situation where every player builds their own parallel track to every destination.

#### Protection, griefing and claims

Create's blocks interact with the world in ways land-claim mods have to understand. Deployers act as fake players, and contraptions can move blocks into or out of claimed areas. Whether a claim protects against a contraption depends on the claim mod and its Create compatibility. Test before relying on it: build a drill outside a claim and drive it into one, and see what happens.

FTB Chunks is the common claim and chunk-loading mod on modded servers; it has settings for fake player interaction in claims. Configure them deliberately. On a trusted whitelisted server, it barely matters; on a public one, a drill driven through someone's base is the first grief you will see.

Create also enables some mechanics that are effectively duplication on some versions and combinations of mods. Check the issue trackers of Create and your addons before a public launch, and keep a block logging tool if your loader has one.

#### Backups, updates and keeping the world

A Create world is a lot of player effort in a small number of region files, and Create updates touch block and item IDs.

1. **Back up before every update** of Create or any addon. A clean stop first, so everything is saved.
2. **Update Create and its addons together.** Never update Create alone while addons target the old version.
3. **Read the changelog for removed blocks.** Create 6 replaced and changed several components; blocks removed in an update disappear from the world. Some versions provide migration; check before updating a big world.
4. **Test on a copy.** Upload the world to a second server or a local copy, update there, load the main factories and rail hubs, and look.

[What to do when a mod update breaks](https://www.renode.space/blog/what-to-do-when-a-mod-update-breaks) covers recovery when it goes wrong anyway.

On RE:NODE the Minecraft line ships Paper, so a Create server is your own install: you upload NeoForge or Forge, the mods and the configs through the file manager or SFTP, and set the startup variables yourself. There is no one-click Create installer. What the panel gives you is the boring, important part: backup slots on every plan that restore with a button and are stored off the machine, a schedule for a nightly backup, and a container that restarts clean at its memory limit instead of swapping.

#### FAQ

##### Do players need Create installed to join a Create server?

Yes. Create adds blocks, items and entities, so it is required on both server and client, at the same version, with the same addons. A modpack is the easiest way to keep everyone matched.

##### How much RAM does a Create server need?

Around 4 GB for Create alone with a few players, 5 to 6 GB with a set of addons, and 6 to 8 GB for a Create-themed modpack. A mature world with big factories needs more CPU before it needs more RAM.

##### Do Create trains keep chunks loaded?

No. Trains travelling through unloaded chunks are simulated by Create's railway system without loading the chunks. They become visible contraptions again when they reach loaded chunks near players.

##### Why does my Create server lag when one player is online?

Their factory is loaded. Contraptions, big kinetic networks and item processing run while someone is near them. Profile with spark while that player is online and look for contraption entities and Create block entities at the top.

##### Can I run Create on Fabric?

There is a Fabric port maintained by a separate team, which has historically lagged behind the main Forge and NeoForge releases. For the current Create version and addon support, NeoForge 1.21.1 or Forge 1.20.1 are the safer choice.

RE:NODE Minecraft plans run Paper by default, and a Create server is your own upload through the file manager or SFTP - archives unpack in place. Every plan has backup slots stored off the machine and the Schedules tab for nightly backups, which is what a big Create world needs most.

[See Minecraft plans](https://www.renode.space/game-servers/minecraft)

---

### Minecraft custom items: ItemsAdder, Oraxen, Nexo

Published 2026-10-07 by RE:NODE Team. https://www.renode.space/blog/minecraft-custom-items-and-itemsadder

Custom items on a Paper server are vanilla items wearing a costume. The server hands a player an ordinary item - a paper, a stick, a diamond sword - with a tag that tells the client to draw a different model, and a server resource pack supplies the model and texture. Plugins such as ItemsAdder, Oraxen and Nexo automate both halves: you describe items, blocks and furniture in YAML, the plugin builds the resource pack and handles behaviour, and players download the pack when they join. It works without client mods, it is genuinely good, and it has three costs people discover late: the pack has to be hosted somewhere players can download it, Bedrock players through Geyser do not see it without extra work, and custom blocks and furniture use tricks that cost the server more than ordinary blocks.

This guide covers how the trick works, the three main plugins, pack hosting, and the problems you will hit. The basics of server resource packs - the `server.properties` keys and the SHA-1 hash - are in [MOTD, icon and resource packs](https://www.renode.space/blog/minecraft-motd-icon-and-resource-packs).

#### How custom items work without mods

The client decides what an item looks like using its resource pack. The server can only send item data. Every custom item system is a way of attaching a marker to item data that a resource pack can recognise.

For years that marker was the `CustomModelData` integer. A resource pack overrode the model of, say, `paper`, and said "if CustomModelData is 1001, use this model instead". Plugins handed out paper with that number, and players saw a sword or a coin or a hat.

Minecraft 1.20.5 replaced item NBT with data components, and 1.21.2 to 1.21.4 reworked item models further:

- The `minecraft:item_model` component (1.21.2) lets an item point at any model directly, so a custom item no longer has to hijack another item's overrides.
- In 1.21.4, item model definitions moved to `assets/<namespace>/items/`, and `custom_model_data` became a component holding lists of floats, flags, strings and colours rather than one integer.

You do not need to write any of this by hand if you use a plugin, but you do need to know it exists, because it is why custom item plugins break across Minecraft updates and why a pack built for 1.21.1 may need regenerating for 1.21.4 clients. When you update the server, update the plugin first and regenerate the pack.

Behaviour is the server's job. A custom sword with extra damage, a custom food that gives a potion effect, a custom tool that mines in a 3x3 area - all of that is server-side logic in the plugin. The resource pack only changes appearance.

#### Custom blocks and furniture: the expensive part

Items are easy because every client already supports custom item models. Blocks are not, because Minecraft has a fixed list of block states and no component system for them. Plugins therefore reuse block states that players never see in normal play:

| Technique | How it works | Cost and caveats |
| --- | --- | --- |
| Note block states | Hundreds of instrument and note combinations, each mapped to a texture | Real note blocks lose those states; cheap otherwise |
| Mushroom stem and block states | Six faces, each true or false, give dozens of states | Mushroom blocks look odd; cheap |
| Tripwire and chorus states | Used for transparent or non-full blocks | Behaviour quirks with tripwire updates |
| Furniture as entities | An item display or armour stand with a barrier for collision | Each piece is an entity - see below |

Block-state tricks are cheap: a custom ore made from a note block state costs the same as a note block. Furniture is different. A chair, a lamp or a table is usually an entity (an item display on modern versions, an armour stand on older ones) plus barrier blocks or interaction entities for the hitbox. A tavern with sixty pieces of furniture is sixty-plus entities in one chunk, and a town of such buildings adds up. They do not run AI, so they are far cheaper than mobs, but they count, they are sent to every nearby client, and they show up in `/paper entity list`.

Keep furniture-heavy builds in moderation, prefer block-based decoration where it looks as good, and check entity counts after a big build goes up. [Entity cleanup and ClearLag](https://www.renode.space/blog/minecraft-entity-cleanup-and-clearlag) has the commands - and the reminder never to run a blanket `/kill` on a server with furniture entities.

#### ItemsAdder, Oraxen and Nexo compared

Three plugins dominate. All three are paid, all three generate a resource pack, and all three are maintained by small teams, so check the current version's support for your Minecraft version before buying.

| Plugin | Strength | Notes |
| --- | --- | --- |
| ItemsAdder | Largest feature set, big ecosystem of ready-made content packs | Paid; complex config; has its own pack hosting options |
| Oraxen | Long-standing, simpler config, open development history | Paid builds; the main developer moved on to Nexo |
| Nexo | Successor to Oraxen by its main developer, modern codebase | Paid; newer, smaller ecosystem, Oraxen configs can be migrated |

Practical guidance:

- If you want to buy finished content - furniture sets, weapon packs, emoji packs - ItemsAdder has the most of it, sold by third-party creators.
- If you want to design your own items and prefer readable YAML, Oraxen or Nexo are easier to reason about. New servers choosing between the two today generally pick Nexo, because that is where active development went.
- Do not run two of them at once. Both will try to own the resource pack and the block states.

Other plugins integrate with these: MythicMobs for custom mobs that use custom models, MMOItems for RPG item stats, and various crafting and GUI plugins. Check compatibility before buying a stack of them.

#### Setting up ItemsAdder

ItemsAdder is the most common, so here is its shape. Paths and commands change between major versions; read the documentation for the version you install.

1. Install the plugin jar and its dependencies. Check the dependency list on the download page - historically it has needed ProtocolLib and its own library plugin (LoneLibs).
2. Start the server once. It creates `plugins/ItemsAdder/` with a `config.yml` and a contents folder (`plugins/ItemsAdder/contents/` in current versions) where item definitions live, each set in its own namespace folder.
3. Choose how the resource pack is hosted (next section) in `config.yml`.
4. Add or write content, then build the pack:

```text
/iazip
/iareload
/iaget <namespace:item>
```

`/iazip` compiles every content folder into a single resource pack zip and, depending on hosting settings, uploads or serves it. `/iareload` reloads item definitions. `/iaget` gives yourself an item to test. After `/iazip`, rejoin to download the new pack.

A minimal item definition in ItemsAdder's format looks like this, though the schema has evolved and you should copy from the current examples rather than this:

plugins/ItemsAdder/contents/myserver/configs/items.yml:

```yaml
info:
  namespace: myserver
items:
  ruby:
    display_name: "Ruby"
    resource:
      material: EMERALD
      generate: true
      textures:
        - item/ruby.png
```

The texture goes under the namespace's `textures/item/` folder. `generate: true` tells ItemsAdder to build the model from the texture. The underlying material is what vanilla behaviour falls back to - here an emerald, so it stacks to 64 and villagers might want it. Choose base materials deliberately: a custom food based on bread behaves like bread unless the plugin overrides it.

#### Hosting the resource pack

Every client must download the pack, and Minecraft downloads it over HTTP or HTTPS from a URL the server sends. That means the zip has to live at a URL. You have three options.

- **A host the plugin provides.** ItemsAdder offers its own hosting option that uploads the pack for you. Convenient; you depend on a third-party service being up.
- **Self-hosting from the Minecraft server.** The plugin runs a small web server inside the Minecraft server on an extra port and serves the zip itself. Needs one more port allocated and open. Downloads come from your server's address, so a big pack and many joins cost your bandwidth.
- **An external host.** Upload the zip to a web host, object storage or a static site and give the plugin the URL. The most robust option for a public server.

Whichever you choose, the pack must be reachable from players' networks and the URL must serve the file directly, not an HTML download page. File-sharing services that put a "click to download" page in front of the file do not work.

Keep the pack small. Every joining player downloads it once per change, and a 100 MB pack of uncompressed textures makes joining slow for players on poor connections. Compress PNGs, remove unused content packs, and avoid shipping sounds you do not use. Forcing the pack (`require-resource-pack=true` in `server.properties`, or the plugin's equivalent setting) means players who decline cannot play - correct for a server whose items are invisible without it, but make sure the prompt explains why.

> [!TIP]
> Change the pack, change the hash. Clients cache packs by SHA-1. If the URL stays the same but the hash is not updated, players keep the old pack. The plugins handle this when they serve the pack; when you host externally, make sure the plugin or `server.properties` carries the new hash.

#### Bedrock, proxies and other complications

**Bedrock players.** If you run Geyser so Bedrock players can join, they do not get Java resource packs. Geyser has its own mechanism for custom items and blocks, using mappings and a converted Bedrock pack, and ItemsAdder, Oraxen and Nexo have varying levels of support or companion tools for producing it. Expect real work and imperfect results, especially for furniture and custom blocks. [Geyser for Bedrock crossplay](https://www.renode.space/blog/minecraft-geyser-bedrock-crossplay) covers the basics.

**Proxy networks.** On a Velocity network, the backend server sends the pack. If several backends use the same items, they must generate or share the same pack, or players re-download every time they switch servers. Pick one server as the source of truth and copy the pack and configs to the others.

**Updates.** A Minecraft update can change the resource pack format and the item component system. Before updating a server with custom items, check that your plugin version supports the new release, update it on a copy of the server, regenerate the pack and test with a fresh client. [Minecraft version upgrades](https://www.renode.space/blog/minecraft-version-upgrades) covers the general procedure.

**Plugins that inspect items.** Shop, auction and economy plugins compare items by type and data. A custom ruby based on an emerald might be sold as an emerald to a sign shop that only checks the material. Test each economy plugin with custom items before players find the exploit.

#### Doing it without a plugin

For a handful of cosmetic items you may not need a paid plugin at all. A datapack or a few commands can hand out items with a model component, and you write the resource pack yourself:

```text
/give @p minecraft:paper[minecraft:item_model="myserver:ruby"]
```

That form needs 1.21.2 or later (add an `item_name` component for the display name; its text syntax changed in 1.21.5, so check the wiki for your version), and a resource pack that defines the `myserver:ruby` model. It is clean and future-proof for simple cosmetic items and trophies. It does not give you custom blocks, furniture, custom crafting with behaviour, or GUIs - which is the point at which a plugin earns its price. [Datapacks for servers](https://www.renode.space/blog/minecraft-datapacks-guide) covers the datapack side.

On RE:NODE, uploading a content pack is a drag of the zip into the file manager, which unpacks archives in place, and the console shows `/iazip` and reload output unfiltered so errors in your YAML are visible as they happen. If you self-host the pack, add a port on the Network tab. Take a backup from the panel before a large content change or a Minecraft update; restoring is one button.

#### FAQ

##### Do players need mods to see custom items?

No. They need the server's resource pack, which the client downloads when joining. Java players on a vanilla launcher see custom items, blocks and furniture as long as they accept the pack.

##### Is ItemsAdder worth paying for?

If you want a lot of custom content - furniture, blocks, GUIs, emojis - and especially if you want to buy ready-made packs, yes. For a few cosmetic items, a datapack and a hand-made resource pack using the `item_model` component is enough.

##### Why do players see purple and black or plain items?

The pack did not load. Either they declined it, the URL is not reachable or does not serve the file directly, or the pack was built for a different Minecraft version. Check the URL in a browser and regenerate the pack after any update.

##### Do custom blocks cause lag?

Block-state blocks cost about the same as the vanilla block they reuse. Furniture is usually entities, which cost more and add up in busy builds. Keep an eye on entity counts in towns and furniture-heavy areas.

##### Can Bedrock players use ItemsAdder items?

Only with extra work through Geyser's custom item mappings and a converted Bedrock pack, and results vary by item type. Plan for Bedrock players seeing some items as their base material unless you invest in conversion.

RE:NODE Minecraft servers run Paper with the matching Java version, and the file manager unpacks content archives in place, so installing an item pack is one upload. Ports can be added on the Network tab if you serve the resource pack from the server itself.

[See Minecraft plans](https://www.renode.space/game-servers/minecraft)

## Rules for the assistant

- Never ask the user for a password, token, API key or `.env` contents, and tell them not to paste one into this chat. Describe where a secret goes instead.
- Secrets reach the server through the panel: `.env` is uploaded through the Files tab, startup variables are set on the Startup tab. `.env` never goes in the repository.
- An app server has exactly one reachable port. Read it from `SERVER_PORT` (also `PORT` when the panel starts a linked repository) and bind `0.0.0.0`; never hard-code a port.
- On every panel-managed server (everything except VDS and dedicated servers, which come with full root) only `/home/container` persists, and the process runs unprivileged: no root, `sudo`, `apt`, `systemd` or Docker.
- Memory is a hard limit; a process that reaches it is killed with no error message. Suggest a bigger plan only after ruling out a leak.
- Do not suggest changing the server's startup command or image to work around a code problem - fix the code or the repository.
- Prices and plans above were read when this file was generated. Send the user to the page linked at the top before quoting a price as current.
- For a specific server, the panel's Connect AI link (Console tab) gives the exact runtime, port, path and branch. Prefer it over these general rules when the user has one.
- If something here does not answer the question, the full deploy docs are at https://www.renode.space/llms-full.txt and support is at https://www.renode.space/contact.
