Solved Block removal without blocking main thread.

Discussion in 'Plugin Development' started by mine-care, Feb 20, 2016.

Thread Status:
Not open for further replies.
  1. Offline

    mine-care

    Hello bukkit comunity.

    For a block party minigame im making i need to remove a large area of blocks (45*1*40) without blocking the main thread.
    The reason is that this operation takes a few seconds to complete and in the mean time other arenas are in progress so people on them will freeze everytime the floor changes for an arena.

    Ofcourse i cannot do that asynchronously because an exception will be thrown (Although i can bypass the check i dont want to for obvious reasons).

    So how can i stop the lag produced by the removal and addition of blocks?

    Note:
    I have tried using a synchronous task instead of a loop but it is much much slower and although it makes a difference, it isnt much.

    Thank you!
     
  2. Offline

    Konato_K

    That area doesn't seem like a lot of blocks, are you sure it's hanging the server for a moment? Maybe the clients are just freezing because all the block updates (so updating all blocks without causing updates might help with that)


    @mine-care
     
  3. Offline

    mine-care

    @Konato_K
    Hello,
    Unfortunately yes, it is blocking the main thread and that is noticable once you try to invoke a console command at the same time the block removal is going on.
    What i havent mentioned (my bad.. sorry) is that it is not simply removing them but also checking if each block is of a specific color because it has to leave this color behind. I have done all i could to make it as efficient as possible, but still i need to get the color of the block, and compare it with a DyeColor i have defined outside the loop.
    The loop looks like this so far:
    Code:
    for (int x = Math.min(fromx, tox); x <= Math.max(fromx, tox); x++) {
                for (int z = zmin; z <= zmax; z++) {
                    Block b = w.getBlockAt(new Location(w, x, y, z));
                    if (DyeColor.getByData(b.getData()) != color)
                        b.setType(Material.AIR);
                }
            }
    Also, since i suck at blocks, i may be using something wrong from the API, if you spot anything alike, please let me know.

    Cheers.
     
  4. Offline

    WolfMage1

    Use this.

    Code:
    //loc1's block x is less than loc2's blockx return loc2's block x else loc1's block x
    int topBlockX = l1.getBlockX() < l2.getBlockX() ? l2.getBlockX() : l1.getBlockX();
    int bottomBlockX = l1.getBlockX() > l2.getBlockX() ? l2.getBlockX() : l1.getBlockX();
    
    int topBlockY = l1.getBlockY() < l2.getBlockY() ? l2.getBlockY() : l1.getBlockY();
    int bottomBlockY = l1.getBlockY() > l2.getBlockY() ? l2.getBlockY() : l1.getBlockY();
    
    int topBlockZ = l1.getBlockZ() < l2.getBlockZ() ? l2.getBlockZ() : l1.getBlockZ();
    int bottomBlockZ = l1.getBlockZ() > l2.getBlockZ() ? l2.getBlockZ() : l1.getBlockZ();
    
    for(int x = bottomBlockX; x <= topBlockX; x++) {
        for(int y = bottomBlockY; y <= topBlockY; y++) {
            for(int z = bottomBlockZ; z <= topBlockZ; z++) {
                    //What you want to do.
            }
        }
    }
    this doesn't lag me but your method did
     
    Last edited: Feb 20, 2016
  5. Offline

    mine-care

    That looks prety much like what i already have, except you are also looping through the Y axis which is not needed in my case since it is a single layer of blocks.

    Also about the maths to calculate max and min, it is exactly what im doing here:
    and outside the nested loop, using the methods comming from the Math class of Java instead of building my own comparasons.

    My method 'laged' you because it gets a block within the loop, and compares the colors and everything...

    Also, is this code made by you? or did you find it somewhere?
    Getting blocks between 2 positions
    I was sure i have seen it somewhere...
     
  6. Offline

    WolfMage1

    In my case (believe me or not) I actually did write it.

    And I don't like using things like Math.min or .max (idk why I just dont)
     
  7. Offline

    mine-care

    @WolfMage1 Alright, i dont have a reason not to belive you.
    Also why not?
    Code:
    public static int min(int a, int b) {
             return (a <= b) ? a : b;
    }
    That is the code it is running which is more or less the same as yourse :p it just wraps it up a bit.

    Going back to the lag issue, the two pieces of code are almost identical so i dont think it has to do with that at all..
    What i suspect is the issue is the block lookup on the world but i dont know any alternative...
     
  8. Offline

    teej107

    Remove as much blocks as you can in X milliseconds. If you are not done removing blocks, repeat process.
     
  9. Offline

    mine-care

    @teej107 Hey Teej :D
    Erhm, well i tried this with a bukkit runnable and although there was an improvment, it wasnt much.
     
  10. Offline

    Xerox262

    @mine-care Have you tried using World#getBlockAt(int, int, int); instead of creating a new location (therefore loading all it's data) each time?
     
    mine-care likes this.
  11. Offline

    teej107

    Improvement in lag or the speed of the operation?
     
  12. Offline

    mine-care

    @Xerox262 Oh wow... You are absolutely right! I removed it and indeed it increased the execution speed significantly! But the problem remains. it still lags a bit...

    @teej107 Improvment in terms of lag.
     
  13. Offline

    Xerox262

    @mine-care Merge with the bukkit runnable and have it remove some blocks over time
     
  14. Offline

    teej107

    @mine-care Nothing you can do about it in terms of client lag. WorldEdit does have a "fast edit" mode (something like that) but I think it goes into NMS and it doesn't update blocks or something that can make it glitchy.
    If this is server lag, then you need to reduce the amount of time for each operation.
     
    mine-care likes this.
  15. Offline

    mine-care

    @Xerox262 Alright ill try :- )

    @teej107 I know, i read wiki but it is unstable and may cause chunk corruption that is defenately something i want to avoid. Anyways thanks a lot!
     
Thread Status:
Not open for further replies.

Share This Page