Solved What's the most efficient way of changing blocks?

Discussion in 'Plugin Development' started by daviga404, Nov 3, 2013.

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

    daviga404

    Usually, when changing the materials of multiple blocks, the ticks per second lowers from 20 to a staggeringly low amount (usually about 15.5TPS when restoring 150 blocks on a 64GB RAM dedicated server).

    The standard way of changing a block's material seems to be org.bukkit.block.Block#setType(org.bukkit.Material)

    I was wondering if there were more efficient shortcuts to reduce lag on a densely populated server when restoring blocks, such as a function in the org.bukkit.World. Does anybody know of any "shortcuts" like this, or good practice of restoring blocks in general?
     
  2. Offline

    CubieX

    If you use NMS calls, it's much faster than using Bukkit calls.
    However, using NMS (Native Minecraft Source) will mean, you ahve to update your plugin on almost every MC update.

    I can't tell you how this works exactly as I have never used NMS code for this.
    But WorldEdit for example uses NMS calls for changing blocks. So have a look at the source of WE to get the idea.
    Perharps someone who has used this already can help you more.
     
  3. Offline

    xTrollxDudex

    Or NMS - Net.Minecraft.Server
     
    CubieX likes this.
  4. Offline

    daviga404

    I did a bit of experimenting with the NMS classes and some reflection, it is actually possible to use methods in the NMS classes without the need to import them, or update your plugins.
    See this gist for an example of using simple reflection & regular expressions to change a block's type ID in a Bukkit plugin.
     
  5. Offline

    fromgate

    I think provided example is not faster than normal craftbukkit block.setType method.

    Here is example from the "NMS call":
    Code:
        // Mimics the original World#setTypeIdAndData method in the NMS class.
    private void setBlockNatively(org.bukkit.block.Block b, int typeId, int data) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    Object craftWorld = getHandle.invoke(CraftWorld.cast(b.getWorld()), new Object[]{});
    setTypeIdAndData.invoke(craftWorld, b.getX(), b.getY(), b.getZ(), typeId, data, 0);
    }
    and here is original code from craftbukkit 1.6.4:
    Code:
      public boolean setTypeId(int type) {
        return this.chunk.getHandle().world.setTypeIdAndData(this.x, this.y, this.z, type, getData(), 3);
      }
    You see that in both methods we use same method setTypeIdAndData, so... I did not sure that this class works faster. So there's no reason to use NMS to set block. If you learn WorldEdit code, you will find that it use standart setType methods too.

    But I have another question. Does really setting the 150 blocks affected to your TPS???? When I created plugin ScLoad during the test I loaded big schematic that contain thousands of blocks. And there's no problem to place about five thousand to block during one tick.

    If you changing type of large number of blocks I can recommend you to optimize this process: group blocks by chunk (first change blocks in one chunk, than in another one), check how much block can be changed during the tick and create a queue. Change 150 blocks (if it is your system limit), than other 150.....
     
    daviga404 likes this.
  6. Offline

    daviga404

    The example I provided was proof of concept that you could use NMS classes without needing to import the NMS classes, which contain the Bukkit version and thus would have to be updated on every Bukkit update.

    WorldEdit does use NMS to set blocks, but not regular blocks - it simply queues the blocks to set. I have not yet tested whether or not using NMS to set blocks actually makes a difference when changing large quantities of blocks, but when I do I shall update this post.

    This was an incorrect statement (sorry), I actually meant something along the lines of 150x150x60, which is quite a few blocks for the server to handle on top of about 30 players being teleported, which could actually be causing the TPS drop due to all of the triggered events from the moving.

    Thanks for the advice! I shall try to incorporate this into my plugin which will need to change quite a few blocks with quite a few people, hopefully it will make a difference.
     
    fromgate likes this.
Thread Status:
Not open for further replies.

Share This Page