0

So I've been trying to create a simple minigame engine. Within my Arena Manager class I create the arena's based on the config file information. I then make it so these worlds have autosave set to false. That way when I unload and reload the world in the reset() method of my Arena class the map/arena should be as good as new. However, that is not the case. If someone could please tell me what I am doing wrong or some good alternate methods that would be greatly appreciated! Game class is where reset() is called Relevant Classes Arena ClassArena Class Arena Manager ClassArena Manager Game ClassGame Class Config text Tried setting autosave in the bukkit.yml to be -1 to see if that was overriding my plugin settings. Expected it to ensure unloading the world didn't have any changes left. Instead didn't work. For more clarification the world isn't being unloaded so changes made to the arena map carry over into the next game.

Code For Creating Minigame Arena

for (String str: config.getConfigurationSection("arenas.").getKeys(false)){
        // Returns a set of strings
        World world = Bukkit.createWorld(new WorldCreator(config.getString("arenas."+str+".world")));
        world.save();
        world.setAutoSave(false); // Setting World 1's Autosave to false

        arenas.add(new Arena(minigame,Integer.parseInt(str),new Location(
                Bukkit.getWorld(config.getString("arenas."+str+".world")),
                config.getDouble("arenas."+str+".x"),
                config.getDouble("arenas."+str+".y"),
                config.getDouble("arenas."+str+".z"),
                (float) config.getDouble("arenas."+str+".yaw"),
                (float) config.getDouble("arenas."+str+".pitch"))));
    }

Code For Resetting Arena:

public void reset(){
    System.out.println("Method fired!");
    if (state == GameState.LIVE) {
        this.canJoin = false;
        // Adding check to see if GameState is Live which indicates we need to reset a map and kick players,
        // However, in other cases we don't need to bother with kicking players
        Location lobbySpawn = ConfigManager.getLobbySpawn();
        for (UUID uuid : playersinArena) {
            Bukkit.getPlayer(uuid).teleport(lobbySpawn);
        }
        playersinArena.clear();

        String worldname = spawn.getWorld().getName();
        System.out.println("World Name:"+worldname);
        Bukkit.unloadWorld(spawn.getWorld(), false);
        World world = Bukkit.createWorld(new WorldCreator(worldname));
        world.setAutoSave(false); // Setting World 1's Auto-save to false
    }
  • 1
    Welcome on StackOverflow ! Can you make a [mre] instead of giving your full plugin with paste. With this, you could focus on only part of code and include in your post – Elikill58 Jul 31 '23 at 14:17
  • Here I added the methods that are giving me trouble. Also I'm not getting an error so I can not do the minimal reproducible example. The code is simply not doing what it is supposed to which is unloading the world. I have verified that world name and spawn variable are both correct worlds. @Elikill58 – Slackingslack Aug 01 '23 at 00:08
  • You may receive better help on the [SpigotMC forums](https://www.spigotmc.org/forums/spigot-plugin-development.52/), as the issues you describe are a bit inherent to the underlying system for what you're doing (there are several hurdles to dynamic world handling, one of which can be memory leaking, another is misconceptions of what the methods do). One idea in the short term to make the issue rear its head: set the world folders to read-only (e.g. `chmod -R 600 world1/`). Anything trying to write to them then will fail and throw a stack trace. – Rogue Aug 02 '23 at 14:24
  • [SpigotMC](https://spigotmc.org) is def the place to go for anything Minecraft Java Edition related! For [my network](https://sandbattle.com) I always post there first before coming to the [StackOverflow](https://stackoverflow.com). It helps because people are use to Plugin development **almost entirely**. – Nathanna Aug 24 '23 at 06:21

1 Answers1

0

Setting setAutoSave to false doesn't guarantee that the world won't be saved; it only prevents the auto-save feature from executing. Other triggers cause a world save, such as chunks unloading or players leaving (player data is stored as part of the world data).

The normal way to achieve what you're after is to keep a clean copy of your arena world on disk. Then, when you want to reset the arena, you delete the current world and copy over the clean version to the server.

For example:

private World arenaWorld;
private Arena arena;
...
private void resetArena() {
    // Call logic to remove players from the world
    this.arena.teleportPlayersToHoldingWorld();
    // Unload the world, and don't save it
    Bukkit.unloadWorld(this.arenaWorld, false);
    // Delete the old world
    FileUtility.delete(this.arenaWorld.getWorldFolder());
    // Copy over the clean arena
    FileUtility.copyFolder(this.arena.getArenaFiles(), Bukkit.getWorldContainer());
    // Load the world using `WorldCreator`, with a void terrain generator
    this.arena.createArena(this.arenaWorld.getName(), TerrainGenerator.VOID);
}

This is pseudo-code; you would need to create FileUtility and Arena classes yourself, but plenty of resources are out there to get you started.

Lucan
  • 2,907
  • 2
  • 16
  • 30