BlockStorage

Welcome to the circus!

BlockStorage maintains persistent storage for blocks. Why is this necessary? Due to limitations of Paper/Minecraft, we cannot associate arbitrary data with blocks like we can with entities.

BlockStorage guarantees that a chunk's blocks will never be loaded if the chunk is not loaded.

We store blocks by chunk, in each chunk's persistent data containers.

This works based on chunks rather than individual blocks. When a chunk is loaded, the associated data for all the Pylon blocks in that chunk is loaded. And conversely, when a chunk is unloaded, all the data for that chunk is saved. Additionally, there are autosaves so chunks that are not ever unloaded are still saved occasionally.

When saving, we can simply ask the block to write its state to a PDC, then we write that PDC to the chunk. And when loading, we go through each block PDC stored in the chunk, and figure out which block type it is, and then create a new block of that type, using the container to restore the state it had when it was saved.

Read AND write access to the loaded block data must be synchronized, as there are multiple fields for loaded blocks. If access is not synchronized, situations may occur where these fields are briefly out of sync. For example, if we unload a chunk, there will be a short delay between deleting the chunk from blocksByChunk, and deleting all of its blocks from blocks.

See also

Properties

Functions

Link copied to clipboard
fun breakBlock(block: PylonBlock, context: BlockBreakContext = BlockBreakContext.PluginBreak(block.block)): List<ItemStack>?
fun breakBlock(blockPosition: BlockPosition, context: BlockBreakContext = BlockBreakContext.PluginBreak(blockPosition.block)): List<ItemStack>?
fun breakBlock(location: Location, context: BlockBreakContext = BlockBreakContext.PluginBreak(location.block)): List<ItemStack>?
fun breakBlock(block: Block, context: BlockBreakContext = BlockBreakContext.PluginBreak(block)): List<ItemStack>?

Removes a Pylon block and breaks the physical block in the world. Does nothing if the block is not a Pylon block. Only call on the main thread.

Link copied to clipboard
fun get(blockPosition: BlockPosition): PylonBlock?

Returns the Pylon block at the given blockPosition, or null if the block does not exist

fun get(location: Location): PylonBlock?

Returns the Pylon block at the given location, or null if the block does not exist.

Returns the Pylon block at the given block, or null if the block does not exist.

Link copied to clipboard
inline fun <T> getAs(blockPosition: BlockPosition): T?

Gets the Pylon block (of type T) at the given blockPosition.

inline fun <T> getAs(location: Location): T?

Returns the Pylon block (of type T) at the given location.

inline fun <T> getAs(block: Block): T?

Returns the Pylon block (of type T) at the given block.

fun <T> getAs(clazz: Class<T>, blockPosition: BlockPosition): T?

Returns the Pylon block (of type T) at the given blockPosition, or null if the block does not exist or is not of the expected class.

fun <T> getAs(clazz: Class<T>, location: Location): T?

Returns the Pylon block (of type T) at the given location, or null if the block does not exist or is not of the expected class.

fun <T> getAs(clazz: Class<T>, block: Block): T?

Returns the Pylon block (of type T) at the given block, or null if the block does not exist or is not of the expected class.

Link copied to clipboard

Returns all the Plyon blocks in the chunk at chunkPosition.

Link copied to clipboard

Returns all the Plyon blocks with type key.

Link copied to clipboard

Returns whether the block at blockPosition is a Pylon block, or null if the chunk at blockPosition is not loaded

Returns whether the block at block is a Pylon block, or null if the chunk at block is not loaded

Link copied to clipboard
fun placeBlock(blockPosition: BlockPosition, key: NamespacedKey, context: BlockCreateContext = BlockCreateContext.Default(blockPosition.block)): PylonBlock?
fun placeBlock(location: Location, key: NamespacedKey, context: BlockCreateContext = BlockCreateContext.Default(location.block)): PylonBlock?
fun placeBlock(block: Block, key: NamespacedKey, context: BlockCreateContext = BlockCreateContext.Default(block)): PylonBlock?

Creates a new Pylon block. Only call on the main thread.