Modifying a world asynchronously

Discussion in 'Plugin Development' started by Shadow_tingBRO, Mar 25, 2020.

Thread Status:
Not open for further replies.
  1. So I have made a minigame and its all working successfully, however it has to randomly generate blocks around a about 100x100 area and this takes a lot of CPU time (aprox 5 seconds) and I would like to do this in a separate thread im just wondering how I would do this as bukkit is not synchronized and i know you should only access bukkit methods from the main thread. Ive read posts on this but I dont think any of them has been solved yet.
    Is there a way to do this?

    Current Code:
    Code:
    Random m = new Random(game.hashCode());
    Bukkit.getScheduler().runTask(thepluginclasshere,()->{//would like to use runTaskAsynchronously
                for(double x = game.arena().getMinX(); x<game.arena().getMaxX(); x++) {
                    for(double z = game.arena().getMinZ(); z<game.arena().getMaxZ(); z++) {
                        if(game.lobby().contains(x, game.lobby().getCenterY(), z))continue;//if the coords are in the lobby region
                        if(m.nextInt(RARITY_INDEX)!=4)continue;
                        world.getBlockAt((int)x,world.getIfLoaded().getHighestBlockYAt((int)x, (int)z), (int)z).
                        setType(random(m).material());//random is a method which gets a random material out of about 10
                    }
                }
            });
    
     
  2. Online

    timtower Administrator Administrator Moderator

    @Shadow_tingBRO If you know the area then you can handle ... amount of blocks per tick, sync.
     
  3. @timtower Im confused, what do you mean if i know the area then i can handle?
     
  4. Online

    timtower Administrator Administrator Moderator

    @Shadow_tingBRO Now you do everything in 1 go, can you split that into parts?
     
  5. @timtower Im confused do you mean everything in 1 go in the code or question?
     
  6. Online

    timtower Administrator Administrator Moderator

    @Shadow_tingBRO
    Code:
    BukkitRunnable runnable = new BukkitRunnable(){
       double x = game.arena().getMinX();
       double z = game.arena().getMinZ();
       
       @Override
       public void run(){
         for(int i = 0;i<100;++i){
           if(game.lobby().contains(x, game.lobby().getCenterY(), z))continue;//if the coords are in the lobby region
           if(m.nextInt(RARITY_INDEX)!=4)continue;
           world.getBlockAt((int)x,world.getIfLoaded().getHighestBlockYAt((int)x, (int)z), (int)z).
           setType(random(m).material());//random is a method which gets a random material out of about 10
           z+=1;
           if(z>=game.arena().getMaxZ()){
             z = game.arena().getMinZ();
             x+=1;
           }
           if(x>=game.arena().getMaxX()){
             this.cancel();
             return;
           }
         }
       }
    }
    runnable.runTaskTimer(plugin, 1);
    
    Something like that.
    Will handle the code in chunks of 100 blocks.
    Written without IDE so can contain mistakes.
     
Thread Status:
Not open for further replies.

Share This Page