1.14.4 Chunk Save Error

Discussion in 'Spigot Plugin Development' started by OkDexter12, Jan 17, 2020.

  1. I have this method to generate a radius of chunks around the spawnpoint of my world:

    Code (Text):
    public static void generateChunksFully(int radius, Location center) {
            for(int xPos = 0; xPos < radius; xPos++) {
                for(int yPos = 0; yPos < radius; yPos++) {
                    Location chunkIndex = center.clone().add((xPos*16), 50, (yPos*16));
                    main.console.sendMessage("Beginning generation of region : " + xPos + " , " + yPos + " - Chunk numbers : " + chunkIndex.getChunk().getX() + " , " + chunkIndex.getChunk().getZ());
                    chunkIndex.getChunk().load(true);
                }
            }
            main.console.sendMessage("Chunk Generation Finished !");
            main.console.sendMessage("Beginning creation of core regions in 10 seconds.");
            return;
        }
    However, when I run the code, the server starts giving these errors for all the chunks generated:
    Code (Text):
    Failed to save chunk 7,24
    java.util.ConcurrentModificationException: null
            at java.util.TreeMap$PrivateEntryIterator.nextEntry(Unknown Source) ~[?:1.8.0_191]
            at java.util.TreeMap$KeyIterator.next(Unknown Source) ~[?:1.8.0_191]
            at net.minecraft.server.v1_14_R1.TickListServer.a(TickListServer.java:140) ~[spigot-1.14.3-R0.1-SNAPSHOT.jar:git-Spigot-d05d3c1-7ffb2a2]
            at net.minecraft.server.v1_14_R1.TickListServer.a(TickListServer.java:121) ~[spigot-1.14.3-R0.1-SNAPSHOT.jar:git-Spigot-d05d3c1-7ffb2a2]
            at net.minecraft.server.v1_14_R1.TickListServer.a(TickListServer.java:117) ~[spigot-1.14.3-R0.1-SNAPSHOT.jar:git-Spigot-d05d3c1-7ffb2a2]
            at net.minecraft.server.v1_14_R1.TickListServer.a(TickListServer.java:177) ~[spigot-1.14.3-R0.1-SNAPSHOT.jar:git-Spigot-d05d3c1-7ffb2a2]
            at net.minecraft.server.v1_14_R1.ChunkRegionLoader.saveChunk(ChunkRegionLoader.java:365) ~[spigot-1.14.3-R0.1-SNAPSHOT.jar:git-Spigot-d05d3c1-7ffb2a2]
            at net.minecraft.server.v1_14_R1.PlayerChunkMap.saveChunk(PlayerChunkMap.java:667) ~[spigot-1.14.3-R0.1-SNAPSHOT.jar:git-Spigot-d05d3c1-7ffb2a2]
            at java.util.stream.ReferencePipeline$2$1.accept(Unknown Source) [?:1.8.0_191]
            at java.util.stream.ReferencePipeline$2$1.accept(Unknown Source) [?:1.8.0_191]
            at java.util.stream.ReferencePipeline$3$1.accept(Unknown Source) [?:1.8.0_191]
            at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Unknown Source) [?:1.8.0_191]
            at java.util.stream.AbstractPipeline.copyInto(Unknown Source) [?:1.8.0_191]
            at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source) [?:1.8.0_191]
            at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source) [?:1.8.0_191]
            at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source) [?:1.8.0_191]
            at java.util.stream.AbstractPipeline.evaluate(Unknown Source) [?:1.8.0_191]
            at java.util.stream.ReferencePipeline.forEach(Unknown Source) [?:1.8.0_191]
            at net.minecraft.server.v1_14_R1.PlayerChunkMap.save(PlayerChunkMap.java:280) [spigot-1.14.3-R0.1-SNAPSHOT.jar:git-Spigot-d05d3c1-7ffb2a2]
            at net.minecraft.server.v1_14_R1.ChunkProviderServer.save(ChunkProviderServer.java:252) [spigot-1.14.3-R0.1-SNAPSHOT.jar:git-Spigot-d05d3c1-7ffb2a2]
            at net.minecraft.server.v1_14_R1.ChunkProviderServer.close(ChunkProviderServer.java:257) [spigot-1.14.3-R0.1-SNAPSHOT.jar:git-Spigot-d05d3c1-7ffb2a2]
            at net.minecraft.server.v1_14_R1.World.close(World.java:1032) [spigot-1.14.3-R0.1-SNAPSHOT.jar:git-Spigot-d05d3c1-7ffb2a2]
            at net.minecraft.server.v1_14_R1.MinecraftServer.stop(MinecraftServer.java:712) [spigot-1.14.3-R0.1-SNAPSHOT.jar:git-Spigot-d05d3c1-7ffb2a2]
            at net.minecraft.server.v1_14_R1.DedicatedServer.stop(DedicatedServer.java:681) [spigot-1.14.3-R0.1-SNAPSHOT.jar:git-Spigot-d05d3c1-7ffb2a2]
            at net.minecraft.server.v1_14_R1.MinecraftServer.close(MinecraftServer.java:656) [spigot-1.14.3-R0.1-SNAPSHOT.jar:git-Spigot-d05d3c1-7ffb2a2]
            at org.spigotmc.RestartCommand.restart(RestartCommand.java:119) [spigot-1.14.3-R0.1-SNAPSHOT.jar:git-Spigot-d05d3c1-7ffb2a2]
            at org.spigotmc.RestartCommand.restart(RestartCommand.java:40) [spigot-1.14.3-R0.1-SNAPSHOT.jar:git-Spigot-d05d3c1-7ffb2a2]
            at org.spigotmc.WatchdogThread.run(WatchdogThread.java:95) [spigot-1.14.3-R0.1-SNAPSHOT.jar:git-Spigot-d05d3c1-7ffb2a2]

    Does anyone know why or how I can fix this?
     
  2. md_5

    Administrator Developer

    You can't just generate them all at once or the watchdog will think your server is lagging so hard it crashed.

    Also your stack trace is from 1.14.3 but you put 1.15.1 in the title
     
  3. Ah crap, I forgot I switched back to 1.14.3 my bad. So the best thing to do would be to add a wait time between loading the chunks? Like waiting 5 seconds or something?
     
  4. md_5

    Administrator Developer

    Yes but not that drastic.

    The better question is why aren't you just using WorldBorder?
     
  5. Drastic as in more seconds or I should do less seconds?

    I would use worldborder but I want to know when the chunks are finished loading as I have another method that modifies the chunks after they are all loaded. Also because I like to keep everything in one plugin.
     
  6. #6 7smile7, Jan 17, 2020
    Last edited: Jan 17, 2020
  7. md_5

    Administrator Developer

    Less seconds, like 1 chunk every 5 seconds would be very slow
     
  8. Okay, I made this but i'm not sure if it's too sketchy to use this many bukkit runnables:

    Code (Text):
    public static void iterateXLocations(int radius, int xPos, int yPos, Location center) {
            Bukkit.getScheduler().runTaskLater(main, () -> iterateYLocations(radius, (xPos + 1), 0, 20, center), ((radius/20)*2)*20);
        }
       
        public static void extendYLooping(int radius, int xPos, int yPosEnd, Location center) {
            Bukkit.getScheduler().runTaskLater(main, () -> iterateYLocations(radius, xPos, yPosEnd, (yPosEnd + 20), center), (radius/50)*20);
        }
       
        public static void iterateYLocations(int radius, int xPos, int yPosStart, int yPosEnd, Location center) {
            if(yPosStart >= radius) {
                if(xPos >= radius) {
                    main.console.sendMessage("Chunk Generation Finished !");
                    main.console.sendMessage("Beginning creation of core regions in 10 seconds.");
                    return;
                }
                else {
                    iterateXLocations(radius, xPos, 0, center);
                    return;
                }
            }
            for(int yPos = yPosStart; yPos < yPosEnd; yPos++) {
                if((yPos + 1) % 20 == 0) {
                    extendYLooping(radius, xPos, yPosEnd, center);
                    return;
                }
                else {
                    //do chunk stuff
                    Location chunkIndex = center.clone().add((xPos*16), 50, (yPos*16));
                    main.console.sendMessage("Beginning generation of region : " + xPos + " , " + yPos + " - Chunk numbers : " + chunkIndex.getChunk().getX() + " , " + chunkIndex.getChunk().getZ());
                    chunkIndex.getChunk().load(true);
                }
            }
        }

    Oh dang, that seems pretty useful. Would you call addRequests(int x, int z, UUID) for every chunk you would want to load?
     
  9. Yes you just call addRequests(int x, int z, UUID) where x is the chunk coordinate x, y is the chunk coordinate y and UUID is the worlds UUID.

    PS no idea if this works but should be fine. If you still experience issues just change the scheduled time to 2 or more ticks. Also if the chunks dont generate try
    loadChunk()
    unloadChunk()
    instead of
    getChunkAt()