NBTBlockEntity¶
abstract class NBTBlockEntity(
type: BlockEntityType<*>,
pos: BlockPos,
blockState: BlockState
) : BlockEntity, NBTHolder
A BlockEntity base class that automatically persists fields declared with NBTHolder delegates to and from the block entity's CompoundTag.
Subclass this and declare fields using the NBTHolder delegation API:
class MyBlockEntity(pos: BlockPos, state: BlockState)
: NBTBlockEntity(MY_TYPE, pos, state) {
var energy by nbt.intField()
var label by nbt.stringField { "default" }
val items by nbt.itemField(9)
}
Saving and loading are handled automatically via saveAdditional and loadAdditional. Call BlockEntity.setChanged to push the block entity state to tracking clients.
Constructors¶
NBTBlockEntity¶
constructor(
type: BlockEntityType<*>,
pos: BlockPos,
blockState: BlockState
)
Properties¶
blockPos¶
open val blockPos: BlockPos?
blockState¶
open var blockState: BlockState?
isRemoved¶
level¶
@get:
Nullable
open var level: Level?
modelData¶
open val modelData: ModelData?
persistentData¶
open val persistentData: CompoundTag?
type¶
open val type: BlockEntityType<*>?
updatePacket¶
open override val updatePacket: Packet<ClientGamePacketListener>?
Functions¶
applyComponents¶
fun applyComponents(components: DataComponentMap?, patch: DataComponentPatch?)
applyComponentsFromItemStack¶
fun applyComponentsFromItemStack(stack: ItemStack?)
booleanField¶
open override fun booleanField(default: () -> Boolean): PropertyDelegateProvider<Any?, ReadWriteProperty<Any?, Boolean>>
byteField¶
open override fun byteField(default: () -> Byte): PropertyDelegateProvider<Any?, ReadWriteProperty<Any?, Byte>>
clearRemoved¶
open fun clearRemoved()
collectComponents¶
fun collectComponents(): DataComponentMap?
components¶
open fun components(): DataComponentMap?
doubleField¶
open override fun doubleField(default: () -> Double): PropertyDelegateProvider<Any?, ReadWriteProperty<Any?, Double>>
energyField¶
open override fun energyField(capacity: Long, onUpdate: () -> Unit?): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, ArchieEnergyStorage>>
Declares an ArchieEnergyStorage field capped at capacity, keyed by the delegated property's name. See itemField for onUpdate's semantics.
energyListField¶
open override fun energyListField(capacity: Long, onUpdate: () -> Unit?): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, ArchieStorageList<ArchieEnergyStorage>>>
Declares an ArchieStorageList of ArchieEnergyStorages, each capped at capacity, keyed by the delegated property's name. See itemMapField for onUpdate's semantics.
energyMapField¶
open override fun energyMapField(capacity: Long, onUpdate: () -> Unit?): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, ArchieStorageMap<ArchieEnergyStorage>>>
Declares an ArchieStorageMap of ArchieEnergyStorages, each capped at capacity, keyed by the delegated property's name. See itemMapField for onUpdate's semantics.
field¶
open override fun <T> field(serializer: KSerializer<T>, default: () -> T): PropertyDelegateProvider<Any?, ReadWriteProperty<Any?, T>>
Declares a read-write field backed by serializer, keyed by the delegated property's name. default supplies the value used before the field has been loaded/set.
field¶
inline fun <T> NBTHolder.field(noinline default: () -> T): PropertyDelegateProvider<Any?, ReadWriteProperty<Any?, T>>
Reified variant of NBTHolder.field that resolves the KSerializer for T automatically.
fillCrashReportCategory¶
open fun fillCrashReportCategory(reportCategory: CrashReportCategory?)
floatField¶
open override fun floatField(default: () -> Float): PropertyDelegateProvider<Any?, ReadWriteProperty<Any?, Float>>
fluidField¶
open override fun fluidField(
limit: Long,
size: Int,
filter: Predicate<FluidResource>,
onUpdate: () -> Unit?
): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, ArchieFluidStorage>>
Declares an ArchieFluidStorage field with size tank slots each capped at limit, keyed by the delegated property's name. See itemField for onUpdate's semantics.
fluidListField¶
open override fun fluidListField(
limit: Long,
size: Int,
filter: Predicate<FluidResource>,
onUpdate: () -> Unit?
): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, ArchieStorageList<ArchieFluidStorage>>>
Declares an ArchieStorageList of ArchieFluidStorages, each with size tank slots capped at limit, keyed by the delegated property's name. See itemMapField for onUpdate's semantics.
fluidMapField¶
open override fun fluidMapField(
limit: Long,
size: Int,
filter: Predicate<FluidResource>,
onUpdate: () -> Unit?
): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, ArchieStorageMap<ArchieFluidStorage>>>
Declares an ArchieStorageMap of ArchieFluidStorages, each with size tank slots capped at limit, keyed by the delegated property's name. See itemMapField for onUpdate's semantics.
getData¶
getExistingData¶
open fun <T : Any?> getExistingData(type: AttachmentType<T?>?): Optional<T?>?
getStateContainer¶
fun BlockEntity.getStateContainer(): BlockEntityStateContainer
Convenience extension to get or create a state container for a block entity.
getSyncTag¶
open override fun getSyncTag(): CompoundTag
Builds a CompoundTag suitable for sending to the client to sync current field values.
getUpdatePacket¶
open override fun getUpdatePacket(): Packet<ClientGamePacketListener>?
Builds the block entity update packet carrying getUpdateTag's data.
getUpdateTag¶
open override fun getUpdateTag(provider: HolderLookup.Provider): CompoundTag
Returns the NBTHolder sync tag sent to tracking clients; see NBTHolder.getSyncTag.
handleUpdateTag¶
open fun handleUpdateTag(tag: CompoundTag?, lookupProvider: HolderLookup.Provider?)
hasAttachments¶
fun hasAttachments(): Boolean
hasCustomOutlineRendering¶
open fun hasCustomOutlineRendering(player: Player?): Boolean
hasData¶
hasLevel¶
intField¶
open override fun intField(default: () -> Int): PropertyDelegateProvider<Any?, ReadWriteProperty<Any?, Int>>
invalidateCapabilities¶
@ApiStatus.NonExtendable
open fun invalidateCapabilities()
isValidBlockState¶
open fun isValidBlockState(arg: BlockState?): Boolean
itemField¶
open override fun itemField(
size: Int,
filter: Predicate<ItemResource>,
onUpdate: () -> Unit?
): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, ArchieItemStorage>>
Declares an ArchieItemStorage field with size slots, keyed by the delegated property's name. onUpdate, if given, runs in addition to (not instead of) this holder's own internal bookkeeping (persistence, @Sync propagation, BlockEntity.setChanged, ...) every time ArchieItemStorage.update fires for this specific field - a caller-supplied "something in this inventory changed" hook, without needing to poll it or re-derive the same notification some other way.
itemListField¶
open override fun itemListField(
size: Int,
filter: Predicate<ItemResource>,
onUpdate: () -> Unit?
): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, ArchieStorageList<ArchieItemStorage>>>
Declares an ArchieStorageList of ArchieItemStorages, each with size slots, keyed by the delegated property's name. See itemMapField for onUpdate's semantics.
itemMapField¶
open override fun itemMapField(
size: Int,
filter: Predicate<ItemResource>,
onUpdate: () -> Unit?
): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, ArchieStorageMap<ArchieItemStorage>>>
Declares an ArchieStorageMap of ArchieItemStorages, each with size slots, keyed by the delegated property's name. onUpdate, if given, runs whenever the map's own structure changes (an entry added/removed/cleared) or any individual entry's own contents change - every entry the map creates is wired with the map's own persistence trigger as well, so a mutation deep inside one entry is never silently unpersisted.
listField¶
open override fun <T> listField(serializer: KSerializer<T>, default: () -> List<T>): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, ObservableList<T>>>
Declares a mutable-list field backed by serializer, keyed by the delegated property's name.
listField¶
inline fun <T> NBTHolder.listField(noinline default: () -> List<T>): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, MutableList<T>>>
Reified variant of NBTHolder.listField that resolves the KSerializer for T automatically.
loadCustomOnly¶
fun loadCustomOnly(tag: CompoundTag?, registries: HolderLookup.Provider?)
loadFromTag¶
open override fun loadFromTag(compoundTag: CompoundTag)
Loads every declared field's value from compoundTag, overwriting current values.
loadWithComponents¶
fun loadWithComponents(tag: CompoundTag?, registries: HolderLookup.Provider?)
longField¶
open override fun longField(default: () -> Long): PropertyDelegateProvider<Any?, ReadWriteProperty<Any?, Long>>
mapField¶
open override fun <T> mapField(serializer: KSerializer<T>, default: () -> Map<String, T>): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, MutableMap<String, T>>>
Declares a mutable-map (keyed by String) field backed by serializer, keyed by the delegated property's name.
mapField¶
inline fun <T> NBTHolder.mapField(noinline default: () -> Map<String, T>): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, MutableMap<String, T>>>
Reified variant of NBTHolder.mapField that resolves the KSerializer for T automatically.
nestedField¶
open override fun <T : NBTHolder> nestedField(factory: (CompoundTag) -> T?): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, NestedNBTHolder<T>>>
Declares a single nested NBTHolder field, keyed by the delegated property's name and built once via factory - the scalar counterpart to nestedMapField/nestedListField. Unlike those, there's exactly one fixed-type entry, so no per-entry type discrimination is needed: factory takes no tag to inspect.
nestedListField¶
open override fun <T : NBTHolder> nestedListField(factory: (CompoundTag) -> T?): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, NestedNBTHolderList<T>>>
Declares a NestedNBTHolderList field, keyed by the delegated property's name - the index-ordered counterpart to nestedMapField; see its KDoc for factory's role and T's.
nestedMapField¶
open override fun <T : NBTHolder> nestedMapField(factory: (CompoundTag) -> T?): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, NestedNBTHolderMap<T>>>
Declares a NestedNBTHolderMap field, keyed by the delegated property's name. Unlike mapField, entries aren't one fixed kotlinx.serialization-compatible value type - each is its own self-contained NBTHolder, built fresh via factory either when first inserted (NestedNBTHolderMap.getOrPut) or, when loading a previously-saved entry back, from that entry's own raw sub-CompoundTag (so factory can inspect it - e.g. a stored "kind" field - to decide which concrete nested holder type to reconstruct). T is factory's return type - the common upper bound every entry shares, letting a caller declare e.g. NestedNBTHolderMap<HookHolderState> instead of always getting back the base NBTHolder type and having to cast every entry manually.
onChunkUnloaded¶
open fun onChunkUnloaded()
onDataPacket¶
open fun onDataPacket(
net: Connection?,
pkt: ClientboundBlockEntityDataPacket?,
lookupProvider: HolderLookup.Provider?
)
onLoad¶
open fun onLoad()
onlyOpCanSetNbt¶
open fun onlyOpCanSetNbt(): Boolean
removeComponentsFromTag¶
open fun removeComponentsFromTag(tag: CompoundTag?)
removeData¶
@Nullable
fun <T : Any?> removeData(type: AttachmentType<T?>?): T?
requestModelDataUpdate¶
open fun requestModelDataUpdate()
saveCustomAndMetadata¶
fun saveCustomAndMetadata(registries: HolderLookup.Provider?): CompoundTag?
saveCustomOnly¶
fun saveCustomOnly(registries: HolderLookup.Provider?): CompoundTag?
saveToItem¶
open fun saveToItem(stack: ItemStack?, registries: HolderLookup.Provider?)
saveToTag¶
open override fun saveToTag(compoundTag: CompoundTag)
Writes every declared field's current value into compoundTag.
saveWithFullMetadata¶
fun saveWithFullMetadata(registries: HolderLookup.Provider?): CompoundTag?
saveWithId¶
fun saveWithId(registries: HolderLookup.Provider?): CompoundTag?
saveWithoutMetadata¶
fun saveWithoutMetadata(registries: HolderLookup.Provider?): CompoundTag?
serializeAttachments¶
@Nullable
fun serializeAttachments(provider: HolderLookup.Provider?): @Nullable
CompoundTag?
setChanged¶
open fun setChanged()
setComponents¶
open fun setComponents(components: DataComponentMap?)
setData¶
setRemoved¶
open fun setRemoved()
shortField¶
open override fun shortField(default: () -> Short): PropertyDelegateProvider<Any?, ReadWriteProperty<Any?, Short>>
stringField¶
open override fun stringField(default: () -> String): PropertyDelegateProvider<Any?, ReadWriteProperty<Any?, String>>
triggerEvent¶
open fun triggerEvent(id: Int, type: Int): Boolean
ubyteField¶
open override fun ubyteField(default: () -> UByte): PropertyDelegateProvider<Any?, ReadWriteProperty<Any?, UByte>>
uintField¶
open override fun uintField(default: () -> UInt): PropertyDelegateProvider<Any?, ReadWriteProperty<Any?, UInt>>
ulongField¶
open override fun ulongField(default: () -> ULong): PropertyDelegateProvider<Any?, ReadWriteProperty<Any?, ULong>>
updateProperty¶
open override fun <T> updateProperty(
propertyName: String,
serializer: KSerializer<T>,
value: T
)
Updates a single field, identified by propertyName, from a client sync payload.
ushortField¶
open override fun ushortField(default: () -> UShort): PropertyDelegateProvider<Any?, ReadWriteProperty<Any?, UShort>>