Paper
Paper copied to clipboard
Settings worlds to not auto-save still makes them save
Expected behavior
Worlds should not auto-save after doing world#setAutoSave(false);
Observed/Actual behavior
Worlds auto-save (very visible on timings)
Paper timings: https://timings.aikar.co/dev/?id=22031926125f4a879eeffb5636e58c76#timings Spigot timings for the exact same server/setup: https://timings.spigotmc.org/?url=uqiqowular
I am not 100% sure about how the Spigot timings work, whether they would show individual world saving per world or would group them up, but if it is individual this would indicate that my problem is specific to Paper.
Steps/models to reproduce
I am using this class to initialize my temporary worlds
public class WorldLoader {
/**
* Generates a world which does not save, does not keep spawn loaded and is a void world
*
* @param worldName
* @param environment
* @return
*/
public static World loadVoidTemporaryWorld(String worldName, World.Environment environment) {
//Case where the world is already loaded
if (Bukkit.getWorld(worldName) != null) return Bukkit.getWorld(worldName);
File folder = new File(Bukkit.getWorldContainer().getAbsolutePath());
if (!Files.exists(Paths.get(folder.getAbsolutePath() + File.separatorChar + worldName))) {
Logger.warn("File " + folder.getAbsolutePath() + File.separatorChar + worldName + " does not exist!");
return null;
}
Logger.info("Loading world " + worldName + " !");
Filter filter = newFilter -> false;
Filter previousFilter = Bukkit.getLogger().getFilter();
Bukkit.getLogger().setFilter(filter);
try {
WorldCreator worldCreator = new WorldCreator(worldName);
worldCreator.environment(environment);
worldCreator.keepSpawnInMemory(false);
worldCreator.generator(new VoidGenerator());
World world = Bukkit.createWorld(worldCreator);
if (world != null) world.setKeepSpawnInMemory(false);
world.setDifficulty(Difficulty.HARD);
world.setAutoSave(false);
Bukkit.getLogger().setFilter(previousFilter);
return world;
} catch (Exception exception) {
Bukkit.getLogger().setFilter(previousFilter);
Logger.warn("Failed to load world " + worldName + " !");
exception.printStackTrace();
}
return null;
}
private static class VoidGenerator extends ChunkGenerator {
@Override
public void generateSurface(WorldInfo info, Random random, int x, int z, ChunkData data) {}
@Override
public boolean shouldGenerateNoise() {
return false;
}
@Override
public boolean shouldGenerateBedrock() {
return false;
}
@Override
public boolean shouldGenerateCaves() {
return false;
}
}
}
As you can see, pretty simple. You can use it on any non-default world to load it from the worlds folder. I have verified that the loggers messages do, in fact, run, so this is indeed how the world is being loaded, and no other plugin on my server can/would load these. Plus, the void world generator code is working perfectly fine, a big indicator that this is otherwise functional.
Plugin and Datapack List
Essentials, FreeMinecraftModels, ProtocolLib, packetevents, LibsDisguises, EliteMobs, ResourcePackManager
Paper version
Version | 1.21-97-e71c1df (MC: 1.21) (as you can see in the timings report)
Other
electroniccat told me to report it.
Let me know if there's anything I can do to speed this ticket up short of submitting a fix, this has been a persistent issue for people using my plugins.
I've had this issue before, and forgot to report it.
Looking thru the code, I think I see the issue,
In MinecraftServer#stopServer:
It appears CraftWorld uses the vanilla logic for no-auto-saving.
Minecraft appears to just overrides and forcefully decides to save against your wishes when the server stops.
I'm assuming Mojang did this on purpose, using the no-save option to just stop auto-saving every 5 minutes, but still continuing to save when the server stops.
I guess in a sense the World.setAutoSave is kinda of correct, as it's not AUTO saving (every 5 min), but maybe another method should be added to prevent saving altogether.
autosaving is not full saving, the entire point of that mechanism is to disable the periodic saving in order to allow an external program to backup the world, it prevents various things like chunks from being able to unload, and doesn't even prevent everything from saving.
The big issue with this sorta thing is that the entire data system is leaky as there was never any real considerations of mojang to having separate levels being as separate as CB and people like to think they are, but, also, there's the entire headaches over what disabling saving should and should not affect (and the fact that this is an entire set of discussions and work for such a niche usecase in which we don't have any form of mechanism for assuring that these kind of things would keep working to the degree that people would expect for read-only worlds, etc, etc)
Yeah that makes sense. As I read the code I understand its just to prevent the 5 min auto save. The docs for this should maybe be detailed a smidge more explaining that?!?! I for one definitely had the wrong impression when reading it, until now.
Since this is a very common misconception I'd suggest changing the JD to clarify this behavior