aternosorg / thanos

PHP library to automatically detect and remove unused chunks from Minecraft worlds.
https://packagist.org/packages/aternos/thanos
MIT License
222 stars 20 forks source link

Many incompatibilities with data packs #7

Closed GrantGryczan closed 3 years ago

GrantGryczan commented 3 years ago

Background Information

Hello, I am a data pack developer at Vanilla Tweaks. I'm assuming you know what a data pack is, but the gist is that their logic runs almost entirely on vanilla commands. We can't run Java or access files or chunk NBT or anything. Just vanilla commands, for the most part. And vanilla commands don't have the ability to change a chunk's InhabitedTime value.

Many data packs use a method where chunks really far from spawn are kept loaded via the /forceload command. Data packs use these loaded chunks to optimize certain methods of in-world processing, store information in those chunks, and also perform certain operations which are necessary to perform in-world rather than in data. You can run /forceload add ~ ~, and the chunk which the command was ran from will be kept loaded indefinitely. You can get a complete list of all the force-loaded chunks in a dimension using /forceload query, and you can remove a chunk from being force-loaded using /forceload remove ~ ~.

The Issue

The reason data pack developers choose to force-load locations so far from spawn is intended specifically to prevent players from entering them and interfering with the data packs. This means the InhabitedTime of these chunks never increases, causing an incompatibility with Aternos's "Optimize" setting, which to my understanding is what this repository is for. That setting deletes these force-loaded chunks, since they almost always have no InhabitedTime, causing any data packs which depend on persisting information in those chunks to stop working properly. The only current workaround we can give to our users is to disable Aternos's "Optimize" setting entirely.

Proposed Solution

My suggestion, which would fix these incompatibilities with many data packs, is to also not discard any chunks which are force-loaded. Chunks can only be force-loaded via the /forceload command (unless a mod or plugin does it by other means), so this can't have any side effects that would result in unintended/unnecessary chunks being kept.

Useful Details for Implementation

Each dimension's force-loaded chunks are stored in its data folder, in chunks.dat. In that file's NBT, data.Forced is an array of longs which contains information about which chunks are force-loaded in that dimension. Unfortunately I couldn't find any documentation on it beyond that, so you'd have to figure out the exact format of the chunk coordinates within those longs, but I don't think it should be too complicated. It seems each long in the array somehow represents the coordinates of one force-loaded chunk.

KurtThiemann commented 3 years ago

Thanks for reporting this! Chunks that are listed in the dimension's chunks.dat file should now always be kept, independently of their InhabitedTime value.

It might take a few hours until the change applies to Aternos servers.