I’ve always felt that structures have never really been taken full advantage of, especially as the format and official support makes it a better alternative to WorldEdit/MCEdit schematics. It isn’t in the Bukkit API yet, either, despite the fact that it would make perfect sense to access from a Spigot plugin. At the moment, you can use structures using DefinedStructure/DefinedStructureManager available in the Minecraft NMS source. Obviously this isn’t ideal, especially as it’s constantly changing.
The fact that the implementation is there, though, makes it an easy candidate for adding to Spigot. It’s easy to just add a wrapper to DefinedStructure and to replace the DefinedStructureManager with a Bukkit version, but I wanted to give more control than that. Mainly, I wanted the ability to manipulate structures while they’re still in memory. For example, filling chests in a structure with loot before being pasted into the world.
At the moment, the syntax looks like this:
That example loads a structure from file called house.structure in the plugin folder. The Structure object holds all the blocks and other info in the structure. The next line gets a Structure.
Block instance, which gets a block at a location in the structure. This block is at coordinates 0, 0, 0. Notice I also check if the block is null – this is because it’s possible for a block at a location to be empty. That’s not to be confused with Minecraft’s air.
The difference is that when the structure is placed in the world, air blocks will replace whatever is in the way, where empty blocks will not modify the world at that block position. In vanilla, there’s a block called structure void which can be placed around to mark areas that should not be saved to file (empty blocks). They aren’t saved in NBT anywhere.After making sure the block isn’t empty, I check if the block type is a chest.
If it is, it’s safe to assume that the BlockState is a Chest as well. In Bukkit, BlockStates are not directly tied to the World, though they do have a location. That means all data in the BlockState does not update with the world, nor do modifications made to the BlockState change the block until you call the update function. It makes the perfect class to use for structures as well.
Additionally, all tile entities (blocks that hold data, like chests) extend that class.Next I declare a variable with the Chest BlockState, casting from Structure.Block#getState(). I clear the inventory, and set it to a double chest expanding left.
Just like BlockStates in a Bukkit world, it needs to be updated to take effect in the structure.Finally, I call the paste function, giving the spawn location of “world” as the paste location. I’ll add more arguments later, like rotating it or whether or not to include entities.