Lang: English | 简体中文
A simple tool to remove unused chunks from Minecraft worlds(Java Edition), freeing disk space.
-
Maybe a Java implementation of Thanos.
-
Currently only supports the Anvil file format (since Minecraft JE 1.2.1).
-
In some cases, disk space occupied by the worlds can be reduced by over 50%.
-
Supports configuring protected chunks for each world using chunk coordinates and chunk coordinate ranges (wildcard
*
supported), preventing certain chunks from being removed.
Chunks are stored within the Anvil file, and Minecraft Java Edition stores a field InhabitedTime
for each chunk, which records the cumulative time ticks that players have spent within that chunk.
This tool finds out chunks where players have barely stayed by examining the InhabitedTime
value, and then removes them. It can be used on both local game worlds and server worlds.
The
InhabitedTime
of a chunk increases as long as a player is within the "mob spawn distance"Doc of that chunk. Therefore, theInhabitedTime
of chunks around the player's current chunk often increases as well.
-
If you are using a Paper server or a server based on Paper (such as Purpur), DO NOT set the
fixed-chunk-inhabited-time
Doc key in the Paper World Configuration file to a value$\ge 0$ , as this will fix theInhabitedTime
of the chunks, thereby affecting the functionality of the tool. -
If your world is created or edited by mods / external softwares rather than manual construction by players, the
InhabitedTime
values of the chunks may be unpredictable, and it's not recommended to use this tool in such cases.Of course, you can configure protected chunks to prevent certain chunks from being removed.
-
This tool performs in-place operations on the region Anvil files, the changes will firstly be written to a temporary file and then replace the original file. It is still advisable to occasionally make backups.
- You should have already installed the corresponding version of JRE (Java Runtime Environment). For details, refer to this document.
- Download the
PotatoPeeler*.jar
from Releases according to your Java version, and place it in a suitable location (such as the root directory of your Minecraft Server).
You can run this tool from the command line:
java [jvmOptions...] -jar PotatoPeeler*.jar
[--world-dirs <worldPath1>,<worldPath2>,...]
[--server-jar <serverJarPath>]
[--min-inhabited <ticks>]
[--help]
[--cool-down <minutes>]
[--threads-num <number>]
[--verbose]
[--skip-peeler]
[additionalOptions...]
Flag | Description |
---|---|
--help |
Displays help information |
--verbose |
Outputs detailed information to the log |
--skip-peeler |
Skips chunk processing, no chunks will be removed. If the --server-jar parameter is specified, it will directly launch the Minecraft server |
Parameter | Default Value | Description |
---|---|---|
--world-dirs |
Comma-separated paths to Minecraft Worlds. * For example, /opt/server/world,world_nether specifies two world directories, one with an absolute path and the other with a relative path. The program will process these worlds one by one. |
|
--min-inhabited |
0 |
The InhabitedTime threshold for chunks (in ticks, 20 ticks = 1 second).* A chunk with an InhabitedTime less than or equal to this value, and not protectedSee below, will be removed. * For example, if you want to remove chunks where players have stayed for 100 . * It is not recommended to set this value to be * The default value of 0 is already useful in most cases. |
--cool-down |
0 |
The amount of time that must wait for since the last chunk processing before this tool can be used again (in minutes). * Note that the timer starts after the last chunk processing for all specified worlds has been completed. For example, if the --skip-peeler flag is used to skip chunk processing, it will not count toward this cooldown. |
--threads-num |
10 |
The number of threads to use for concurrent (and possibly parallel) processing of Anvil files in a world. |
--server-jar |
The path to the Minecraft server jar file. * If a valid jar file is specified, this tool will run the jar file in the current JVM after chunk processing, starting the server. |
|
jvmOptions | JVM options. * If --server-jar is specified, these JVM options will be inherited by the server. |
|
additionalOptions | Remaining parameters. * If --server-jar is specified, these parameters will be passed to the server. |
-
Note 1: For the vanilla level format, you can specify the world dimensions like this:
--world-dirs world,world/DIM1,world/DIM-1
.In fact, this tool will search for the
region
directory using a breadth-first approach. -
Note 2: If you prefer not to write parameters in the command line, you can create a file named
potatopeeler.args
in the working directory ofPotatoPeeler*.jar
and write all the command line parameters into this file (excluding JVM parameters).This tool will only read the
potatopeeler.args
file when no parameters are specified in the command line (excluding JVM parameters).
Protected chunks will not be removed and can be categorized into three types:
- Force-loaded chunks in the world (/forceload).
- Custom protected chunks.
- Chunks with excessive data.
You can create a text file named chunks.protected
in the dimension root directory (the same level as region
) to specify chunks that you want to protect in this world.
Click to see an example of the file's location
world
├── DIM-1
│ ├── data
│ │ └── raids_end.dat
│ └── region
│ └── ...
├── DIM1
│ ├── data
│ │ └── raids_end.dat
│ ├── region
│ └── chunks.protected # Protected chunks in the End dimension
├── data
│ └── raids.dat
├── datapacks
├── entities
│ ├── r.-1.-1.mca
│ └── ...
│
├── level.dat
├── level.dat_old
├── chunks.protected # Protected chunks in the Overworld dimension
├── playerdata
├── region
│ ├── r.-1.-1.mca
│ ├── r.-1.0.mca
│ ├── r.0.-1.mca
│ └── r.0.0.mca
└── session.lock
Note: Non-vanilla servers may save dimensions like DIM-1
, DIM1
in separate directories, commonly as world_nether/DIM-1
, world_the_end/DIM1
.
- Each line specifies a rule, which can be a single chunk coordinate like
x,z
, or a rectangular area likex1~x2,z1~z2
. - Wildcard
*
is supported. (For example,*~5,6
protects chunks in the area$x \in [-2^{31},5], z = 6$ .) - Starting with
#
, single-line and inline comments are both supported.
The coordinates mentioned above are chunk coordinates, which can be seen in the game by pressing F3:
Click to see an example of the file content
# Protect all chunks, the tool will remove no chunks in this world dimension.
*,*
*~*,* # The same as above.
*,*~*
# Protect a long strip area where x ranges from -5 to 5 and z = 6.
-5~5,6
# Protect a rectangular area where x ranges from -54 to 14 and z ranges from 7 to 77.
-54 ~ 14 , 7 ~ 77 # Loose spacing is OK
# It doesn't matter if the num on the left is bigger or smaller than the num on the right.
1~4, 18~9 # Protect a rectangular area where x ranges from 1 to 4 and z ranges from 9 to 18.
# Protect a single chunk.
12 , 450
All logs output to the console will also be saved in the peeler_logs
subdirectory of the tool's working directory.
# Remove chunks with a total player stay time <= 5 seconds from the specified three worlds
java -jar PotatoPeeler*.jar --min-inhabited 100 --world-dirs world,world_nether,/opt/server/world_the_end
# Or it can be simpler, just specify the world paths. By default, only chunks with a total player stay time = 0 seconds will be removed
java -jar PotatoPeeler*.jar --world-dirs world,world_nether,/opt/server/world_the_end
# Remove chunks with a total player stay time <= 5 seconds from the specified two worlds
# After removal, purpur.jar will be started in the current JVM
# JVM options -Xms1G -Xmx4G will be inherited
# Additional parameters/flags --nogui --forceUpgrade will be passed to purpur.jar
java -Xms1G -Xmx4G -jar PotatoPeeler*.jar --min-inhabited 100 --world-dirs world,world_nether --server-jar purpur.jar --nogui --forceUpgrade
You can set up a scheduled restart task for your server. For example, if you restart your server every day at 4 AM and you want to clean up unused chunks every 4 days, you can write a server startup script like this:
#!/bin/bash
# Use the --cool-down parameter to configure a cooldown period of 5760 minutes after each cleanup, which means cleaning unused chunks every 4 days
java -Xms1G -Xmx4G -jar PotatoPeeler*.jar --cool-down 5760 --world-dirs world,world_nether --server-jar purpur.jar --nogui
java -jar PotatoPeeler*.jar --world-dirs 'C:\Users\Administrator\AppData\Roaming\.minecraft\saves\MyWorld'
For each world dimension, if there is a chunks.protected
configuration file, the program will print to the console:
Protected chunks from <path of chunks.protected> have been read.
If the
chunks.protected
file has a format error and cannot be read, the program will print the erroneous line number and part of the content.
If there are force-loaded chunks in this world, it will print:
Force-loaded chunks read.
Click to see this example
When no command line parameters are specified, the program will attempt to read parameters from the potatopeeler.args
file.
You can write all command line parameters (excluding JVM parameters) into the potatopeeler.args
file in the working directory of PotatoPeeler*.jar
.
An example of the potatopeeler.args
file is as follows:
--min-inhabited 100 --world-dirs world,world_nether,world_the_end --server-jar purpur.jar
Typically, we will place the potatopeeler.args
and PotatoPeeler*.jar
files in the same directory:
Server Root
├── PotatoPeeler-1.0.0.jar # PotatoPeeler
├── bukkit.yml
├── config
├── plugins
├── potatopeeler.args # Command line parameters
├── server.properties
├── spigot.yml
├── purpur.jar
├── whitelist.json
├── world
├── world_nether
└── world_the_end
Then simply execute java -jar PotatoPeeler*.jar
, and the command line parameters will be automatically read from the potatopeeler.args
file.
Thanks to the hard work of open source developers!
- 区域文件格式 - Minecraft Wiki
- 强制加载区块存储格式 - Minecraft Wiki
- Java版存档格式 - Minecraft Wiki
- 区块存储格式 - Minecraft Wiki
- NBT 二进制格式 - Minecraft Wiki
This project is licensed under the MIT License.
Thanks for using it! o(* ̄▽ ̄*)o