terrain Package

terrain Package

Terrain-related NBTParse modules.

This package consists of modules relating to Minecraft terrain. The basic unit of terrain manipulation is voxel.VoxelBuffer, which is used to store blocks of terrain and tile entity data compactly.

dimension Module

class nbtparse.minecraft.terrain.dimension.Dimension(regions: nbtparse.minecraft.terrain.dimension.RegionManager, *, fill_value: nbtparse.minecraft.terrain._voxel.Block=None, namespace=<Namespace (entity_ids): 58 entries>)[source]

Bases: object

A dimension, in Minecraft terms.

A collection of (usually) contiguous regions.

May be indexed and sliced using block coordinates. Indexing is similar to that of voxel.VoxelBuffer, except that X and Z coordinates are absolute, and X and Z slices must have both a start and an end.

Dimensions may also be used as a context manager, to automatically call close():

with dimension.open('foo/bar') as baz:
    # Do things

Dimensions are not thread-safe.

close()[source]

Close this dimension.

Once closed, a dimension is no longer usable. Closing multiple times is legal and has no effect.

Some region managers, such as FileRegionManager, require closing the dimension to ensure all data is saved properly.

Warning

Dimensions do not automatically close themselves when garbage collected. You must close them explicitly.

entities

Sliceable collection of entities.

Provides a similar slicing API to the dimension itself, except that extended slicing and ordinary indexing are unsupported. Slicing the object returns a set of entities. Slices may also be assigned to and deleted. As with dimensions, all slices must be fully-qualified, except for Y-dimension slices. Unlike with dimensions, slice indices may be fractional.

Other collection-related operations are not currently supported.

Note

The slices are sets, not lists. Duplicate entities with the same UUID and type are not supported and will be silently coalesced.

class nbtparse.minecraft.terrain.dimension.FileRegionManager(path: str, max_cache: int, namespace=<Namespace (entity_ids): 58 entries>)[source]

Bases: nbtparse.minecraft.terrain.dimension.RegionManager

RegionManager backed by the filesystem.

Regions are stored and retrieved from disk in the specified path. A cache of regions is also maintained, and can be manipulated with these methods.

The files get names like those in a typical Minecraft world.

atomic

Make the following operations atomic.

Either every change made within the block will be saved to disk, or none of those changes are saved to disk. This should not be confused with the other three ACID guarantees (particularly isolation). The transaction is aborted if and only if an exception is raised (but see below).

Can be used as a context manager or decorator:

@dim.regions.atomic
def atomic_function():
    # Things in here will happen atomically.

with dim.regions.atomic:
    # Things in here will happen atomically

In some circumstances, you may need to call recover_atomic(). This is generally only necessary if the system crashed or lost power while actually saving regions to disk. The method may roll back a partially-committed transaction to ensure atomicity, or it may complete the transaction.

It is legal to call save_all() while in this context. Doing so creates a sort of “checkpoint”; if an exception is raised, the context rolls back to the last checkpoint. There is an implicit checkpoint at the beginning of the context.

Nested invocations are legal but have no effect.

This consumes memory more aggressively than normal operations. It ignores the max_cache attribute for the sake of correctness.

Warning

This is not the same as thread safety. If you require thread safety, use explicit locking. Multiple threads attempting to enter or exit the atomic context at the same time can cause data corruption, and the rest of the class is similarly unsafe for concurrent access.

Note

Atomicity is only guaranteed on systems where os.replace() is atomic and os.fsync() can be used on a directory. Most POSIX-compliant systems should satisfy these requirements. Windows most likely fails the second and perhaps the first as well. The Python implementation of pathlib.Path.touch() may also require a working O_EXCL flag, which is known to be broken under some versions of NFS. More generally, working on a network drive of any kind is questionable.

cache_size

Number of regions currently cached.

Should be <= max_cache immediately after a call to release(), except inside an atomic invocation.

close()[source]

Empty the cache and set max_cache to zero.

flush_cache(*, save=True)[source]

Trim the cache to at most max_cache items.

If save is True, any regions discarded from the cache will be saved to disk (instead of just dropping them).

get_region(r_x: int, r_z: int, require_exist: bool=True) → nbtparse.minecraft.terrain.region.Region[source]

Return the requested region.

Looks for a file with a name like r.1.2.mca in path, and loads it using region.Region.load(). If the region is cached, the cached copy is returned directly.

max_cache

The number of regions to keep cached.

An unlimited number of regions can be cached temporarily, but when release() is called, only this many regions will be kept.

If set to None or we are inside an atomic block, the release() method does nothing, and the cache may grow arbitrarily large.

Note

Setting this attribute does not automatically call release(), which is usually necessary if you want to ensure that cache_size is at most max_cache.

recover_atomic() → bool[source]

Recover from a failure during atomic or save_all().

Call this method if a system crash or other severe problem occurs while exiting an atomic block. It is not necessary to call this method if the crash occurred while control was still inside the block. The method should also be called if save_all() raised an exception, even if it did so inside an atomic block.

Return True if the changes were saved, False if the changes were rolled back. Also return True if the Dimension is already in a “clean” state and recovery is unnecessary.

Warning

Do not call this method while a save is in progress. Doing so will likely cause severe data corruption. This rule applies regardless of which process is performing the save. save_all() raises a ConcurrentError to indicate that it believes a save cannot be safely made at the current time. Calling this method will override that safety check.

release()[source]

Equivalent to flush_cache() with save=True.

save_all()[source]

Save every region currently cached.

Regions which are no longer cached have already been saved.

Prefer correctness over speed; provide the same guarantees as FileRegionManager.atomic.

A ConcurrentError is raised if another save appears to have been in progress when this method was called. Under no circumstances are two or more save_all() calls allowed to run concurrently on the same directory; all but one will always fail with an exception.

If an exception is raised under other circumstances, it is recommended to call recover_atomic().

save_fast()[source]

Save every region currently cached (like save_all()).

Prefer speed over correctness; do not provide any guarantees beyond those of the basic region caching system.

class nbtparse.minecraft.terrain.dimension.RegionManager[source]

Bases: object

Abstract class for managing region objects.

Implementations are responsible for creating and caching region objects, or objects which are duck-type compatible with regions. In PEP 484 notation, the required duck type is as follows:

typing.MutableMapping[typing.Tuple[int, int], chunk.Chunk]

The primary consumer of this interface is Dimension. Other classes may use it, but for simplicity, this documentation refers to the API consumer as a “dimension.”

Note

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT” “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.

close()[source]

Hook method called when the Dimension is closed.

Implementations MAY save regions to disk or other persistence mechanisms at this time. Implementations which consume a lot of memory or other resources SHOULD make reasonable efforts to minimize their resource consumption after this method returns.

The default implementation does nothing, since some implementations might not need to take any action in this case.

The dimension SHALL NOT call any method other than close() after the first call to close(). Subsequent calls SHALL succeed and do nothing. Implementations MAY fail fast if the dimension violates this contract.

get_region(r_x: int, r_z: int, require_exist: bool=True)[source]

Return the region at the given coordinates.

An implementation MUST satisfy these invariants:

  • The dimension MAY mutate the return value of this method in-place. Any changes made SHALL be preserved in future calls to this method.
  • The dimension SHOULD periodically call release(). After it does so, the dimension SHALL NOT modify any regions without first reacquiring them from this method.
  • If require_exist is True and a region does not exist, an IndexError SHALL be raised. Existence is implementation-defined, but SHALL be internally consistent.
  • If require_exist is False, an IndexError SHALL NOT be raised; if the region does not exist, an empty region SHALL be returned.
  • Regions SHALL NOT be created except at the request of the dimension, but implementations MAY prune empty regions (regions which contain no chunks). Said pruning SHALL only take place when release() is called.

Note

Coordinates are region coordinates, not block or chunk coordinates. Floor-divide chunk coordinates by 32 to get region coordinates.

release()[source]

Hook method called when regions are no longer needed.

Affects the semantics of get_region(). Briefly, once this is called, the implementation is no longer required to persist changes made to regions in-place. Implementations which engage in caching of region objects MAY flush or evict them here. Other implementations MAY take housekeeping actions appropriate to their specific needs.

The default implementation does nothing, since some implementations might not need to take any action in this case.

nbtparse.minecraft.terrain.dimension.open(path: str, *, max_cache: int=5, fill_value: nbtparse.minecraft.terrain._voxel.Block=None, namespace=<Namespace (entity_ids): 58 entries>) → nbtparse.minecraft.terrain.dimension.Dimension[source]

Create a new Dimension object.

Return value is backed by a FileRegionManager. All arguments passed to this function are forwarded to the appropriate constructors.

region Module

class nbtparse.minecraft.terrain.region.Region(region_x: int, region_z: int, namespace=<Namespace (entity_ids): 58 entries>)[source]

Bases: collections.abc.MutableMapping

A Minecraft region file.

region_x and region_z should be the region coordinates (as they appear in the filename). Standard constructor creates an empty region. load() loads a region from a file.

For both loading and saving, files generally need to be seekable. This may pose a problem if you want to send a region over the network or through a pipe. Depending on your memory and disk resources, you may be able to use io.BytesIO or tempfile as temporary buffers.

Contains individual chunks. Access chunk (1, 2), in chunk coordinates, as follows:

r = Region.load(...)
chunk = r[1, 2]

No slicing. A KeyError is raised if the chunk does not exist. You may use absolute or relative coordinates as you please; they will be translated into positive relative coordinates via modulus. You may also replace one chunk with another.

clear()[source]

Mark this region as empty.

Equivalent to deleting every chunk from the region, but quite a bit faster.

classmethod load(region_x: int, region_z: int, src: _io.BufferedReader, namespace=<Namespace (entity_ids): 58 entries>)[source]

Load a region from disk (or another I/O-like object).

src must support seeking in both directions.

save(dest: _io.BufferedWriter)[source]

Save the state of this region.

dest must support seeking in both directions.

chunk Module

class nbtparse.minecraft.terrain.chunk.Chunk(*args, namespace=<Namespace (entity_ids): 58 entries>, **kwargs)[source]

Bases: nbtparse.semantics.nbtobject.NBTObject

entities = <SingleField: nbt_name='Entities', default=None>
classmethod from_bytes(raw: bytes, namespace=<Namespace (entity_ids): 58 entries>)[source]
height_map = HeightMapField('HeightMap', default=None)
static prepare_load(nbt: nbtparse.syntax.tags.CompoundTag) → nbtparse.syntax.tags.CompoundTag[source]

Unwrap nbt from a singleton CompoundTag.

static prepare_save(nbt: nbtparse.syntax.tags.CompoundTag) → nbtparse.syntax.tags.CompoundTag[source]

Wrap nbt in a singleton CompoundTag.

sections = SectionDictField('Sections', default=None)
tiles = <SingleField: nbt_name='TileEntities', default=None>
class nbtparse.minecraft.terrain.chunk.HeightMap(intlist: [<class 'int'>])[source]

Bases: collections.abc.MutableMapping

The height map of a chunk.

Maps coordinates to heights:

hm[3, 4] = 5

Keys may not be inserted or deleted, and must be pairs of integers. Intlist should be the raw list of integers as saved by Minecraft.

to_raw() → [<class 'int'>][source]

Returns the raw list used by Minecraft.

class nbtparse.minecraft.terrain.chunk.HeightMapField(nbt_name: str, *, default: nbtparse.minecraft.terrain.chunk.HeightMap=None)[source]

Bases: nbtparse.semantics.fields.MutableField, nbtparse.semantics.fields.SingleField

Field for HeightMap.

static from_python(value: nbtparse.minecraft.terrain.chunk.HeightMap) → nbtparse.syntax.tags.IntArrayTag[source]
static to_python(tag: nbtparse.syntax.tags.IntArrayTag) → nbtparse.minecraft.terrain.chunk.HeightMap[source]
class nbtparse.minecraft.terrain.chunk.Section(*args, **kwargs)[source]

Bases: nbtparse.semantics.nbtobject.NBTObject

blocks = _BlockField('Blocks', 'Add', 'Data', length=16, height=16, width=16, default=None)
y_index = ByteField('Y', default=0)
class nbtparse.minecraft.terrain.chunk.SectionDictField(nbt_name: str, *, default: dict=None)[source]

Bases: nbtparse.semantics.fields.MutableField, nbtparse.semantics.fields.SingleField

Field for the sections of a chunk.

Keys are y_index, values are sections.

static from_python(sec_dict: dict) → nbtparse.syntax.tags.ListTag[source]
set_default(obj: nbtparse.semantics.nbtobject.NBTObject, field_name: str)[source]
static to_python(sec_list: nbtparse.syntax.tags.ListTag) → dict[source]

voxel Module

Terrain editing at the level of individual blocks.

Note

This is the pure Python version of the module. Pass --cythonize to setup.py to build the Cython version. Once it’s built, setup.py will install it automatically.

class nbtparse.minecraft.terrain.voxel.Block(id: int, data: int=0)[source]

Bases: object

A basic block, not including tile entity data.

Blocks are not NBTObjects because Minecraft does not store them that way. They cannot be serialized directly to NBT. Instead, Minecraft stores blocks in groups called chunks.

id is the block id, a nonnegative integer. data is the damage value, also a nonnegative integer.

Blocks compare equal if they have the same id and data. Blocks are immutable and hashable.

data

The block damage value.

id

The block ID.

class nbtparse.minecraft.terrain.voxel.VoxelBuffer(length: int, height: int, width: int)[source]

Bases: object

A 3D buffer of blocks.

Stores block IDs and damage values in much the same way as Minecraft: a “packed” format involving 8-bit strings (i.e. bytearray).

Basic constructor will create a buffer full of air (block ID 0).

Blocks may be retrieved or changed with standard subscription. Slicing is also acceptable, and assigning a block to a slice is interpreted as filling the slice with the block. However, it is not possible to resize a buffer once created. Replacing a single block with subscription will erase the accompanying tile entity. Slicing is a shallow copy, and will only duplicate references to tile entities.

Slicing a VoxelBuffer is a potentially expensive operation. It is linear in the total volume sliced, which sounds fine until we realize that the volume of a cube is (logically enough) cubic in the edge length. Slices covering an entire VoxelBuffer are very fast, as they are optimized into a single memory copy. This currently does not apply to any other slices. Manipulating individual blocks is relatively fast, however.

VoxelBuffers can be iterated. This is done in the rather esoteric YZX order rather than the conventional XYZ order because the former is more natural in practice. The VoxelBuffer.enumerate() method may be used to prepend (x, y, z) coordinates in much the same way as the builtin enumerate() does. Standard iteration is marginally faster than the following code, because it skips some unnecessary sanity checks:

for y in range(vb.height):
    for z in range(vb.width):
        for x in range(vb.length):
            yield vb[x, y, z]

If you want to iterate in the XYZ ordering instead, use xyz().

Note

Do not write this, as it does not work:

vb = VoxelBuffer(length, height, width)
block = vb[x][y][z]

Instead, write this:

vb = VoxelBuffer(length, height, width)
block = vb[x, y, z]
empty() → bool[source]

Return True if every block is equal to Block(0, 0).

enumerate()[source]

Iterate over the blocks in the buffer, with coordinates.

Produces the (x, y, z) coordinates of each block in addition to the block itself:

for (x, y, z), block in vb.enumerate():
    # block is equivalent to vb[x, y, z]
classmethod from_raw(ids: bytes, addids: bytes, damages: bytes, length: int, height: int, width: int)[source]

Create a new VoxelBuffer from the provided buffers.

These buffers should be bytes objects (or acceptable to bytes()). Each byte or nybble should correspond to a block, in the same format as minecraft stores terrain data.

No tile entities will be attached to the terrain. You must do this manually.

Do not use this to duplicate a VoxelBuffer. Instead, take a slice of the entire buffer.

height

The height (Y-axis) of the buffer.

length

The length (X-axis) of the buffer.

Note

This should not be confused with the len() of the buffer, which is the product of the length, width, and height (i.e. the volume), for consistency with iteration.

tilemap

Mutable mapping from coordinates to tile entities.

Overwriting a single block with subscription will delete the corresponding entry from this mapping, even if the block is otherwise unchanged. Overwriting a slice of blocks will replace the entries with the equivalent entries from the other buffer.

Example code:

vb.tilemap[(x, y, z)] = tile.TileEntity(...)

The following is exactly equivalent and, in the opinion of the author, more readable:

vb.tilemap[x, y, z] = tile.TileEntity(...)

Note

This is a mapping, not a 3D array or similar. It cannot be sliced and negative indices will not be converted into positive indices.

Note

Coordinates are always relative to the origin of the VoxelBuffer, as with subscription. This means they do not correspond to the TileEntity.coords attribute. Furthermore, said attribute will be ignored and overwritten with the coordinates provided to this mapping when the chunk is placed into a region.

to_raw() -> (<class 'bytes'>, <class 'bytes'>, <class 'bytes'>)[source]

Return the raw buffers as used by Minecraft.

unwatch(observer: <built-in function callable>)[source]

Unregister a previously-registered observer.

Undoes a previous call to watch(). KeyError is raised if the observer was never registered.

Observers are not automatically unregistered, so it is important to call this method manually if you intend the VoxelBuffer to outlive the observers.

watch(observer: <built-in function callable>)[source]

Register an observer.

The observer will be called with three arguments every time the buffer is modified. The arguments will be one of the following:

  • The (x, y, z) coordinates of the single block which has changed.
  • Three range objects, describing the set of blocks which have changed (the range of X coordinates, Y coordinates, and Z coordinates).

The observer must be hashable. If this is a problem, wrap it in a lambda expression.

Changes to tilemap will not trigger notifications.

width

The width (Z-axis) of the buffer.

xyz()[source]

Iterate over the blocks in the buffer, in XYZ order.

Produces coordinates, just like VoxelBuffer.enumerate().

Performance of the voxel module

The voxel module is implemented both in pure Python and in Cython. When you import it, you will receive the most performant version available.

When running setup.py on a system with a compatible version of Cython, pass the --cythonize flag to request compilation of the Cython version into C, or --pure-python to request the total exclusion of the Cython version. If neither flag is passed, the script assumes the Cython-to-C conversion has already happened and goes looking for a C version. Note that the tarball provided on PyPI has the C source code included, so --cythonize is not normally necessary unless building directly from version control.

The Cython version is, generally speaking, far more performant than the Python version, unless you happen to be a PyPy user. Both versions are optimized under the assumption that tile entities are relatively rare and most blocks are ordinary blocks. This assumption allows the Cython version to release the GIL when copying memory. It should be possible, in principle, to realize considerable gains from parallelism here. However, the current implementation does not do so.

The Cython version of the module implements the buffer protocol, as described in PEP 3118. This allows C code fast access to the underlying memory backing a VoxelBuffer. VoxelBuffers provide buffers compatible with the flag value PyBUF_RECORDS. Each element is an unsigned short with native byte order (i.e. the format string is H). The block ID is stored in the 12 least significant bits, and the data value is stored in the next 4 bits. On those arcane architectures where unsigned short is not 16 bits, the remaining high bits are ignored.

Both the pure Python and the Cython versions of VoxelBuffer are acceptable arguments to numpy.asarray() and some other NumPy functions. The memory layout is substantially identical to that described above. This is generally a fast operation with no significant memory copying, even if you are using the pure Python version. Keep in mind that the elements of the array will be numbers (as described above) and not Block objects.

Note

As an implementation detail, buffers are contiguous in the YZX order (that is, with the second index changing least often and the first index changing most often). This behavior is not contractual, but it may help you maximize CPU cache hits.

Warning

Modifications made through the buffer protocol or NumPy will not trigger notifications to any observers which may be registered.

filters Module

class nbtparse.minecraft.terrain.filters.Filter(vb: nbtparse.minecraft.terrain._voxel.VoxelBuffer)[source]

Bases: collections.abc.Mapping

Filter for rapidly finding all blocks of a given type.

Keys are Block objects or integers. Values are sets of (x, y, z) 3-tuples. Filters maintain the following invariants:

vb = VoxelBuffer(...)  # with arbitrary contents
block = Block(number, data)
filter = Filter(vb)
((x, y, z) in filter[block]) == (vb[x, y, z] == block)
((x, y, z) in filter[number]) == (vb[x, y, z].id == number)

The filter updates automatically when the VoxelBuffer changes.

Initially constructing a filter is expensive, but keeping it up-to-date is relatively cheap. You may realize performance gains by constructing a single filter and reusing it many times.

Integer keys will not appear in iteration, because the same information is already available via block keys.

close()[source]

Close this filter so it can no longer be used.

Filters slow down the VoxelBuffers they are attached to. Closing them is good practice. Using a filter as a context manager will close it automatically when the context is exited:

with Filter(vb) as filt:
    pass

Closing a filter twice is legal and has no effect. Doing anything else with a closed filter will raise a RuntimeError.

Unclosed filters issue a warning when they are garbage collected. In some unusual circumstances, it may not be possible to issue a warning while the interpreter is shutting down. Since VoxelBuffers form reference cycles with their attached filters, a filter which is attached to a live VoxelBuffer cannot be collected.

copy_vb() → nbtparse.minecraft.terrain._voxel.VoxelBuffer[source]

Return a copy of the VoxelBuffer and attach to it.

This will detach the filter from the original VoxelBuffer, so it will track the copy instead.

This is equivalent to the following code, but significantly faster:

filter.close()
copy = vb[...]
filter = Filter(copy)

tile Module

class nbtparse.minecraft.terrain.tile.AbstractDispenser(*args, **kwargs)[source]

Bases: nbtparse.minecraft.terrain.tile.Container

A dropper or dispenser.

items = ObjectListField('Items', Item, default=())
class nbtparse.minecraft.terrain.tile.Beacon(*args, **kwargs)[source]

Bases: nbtparse.minecraft.terrain.tile.TileEntity

A beacon.

id = UnicodeField('id', default='minecraft:Beacon')
levels = IntField('Levels', default=0)
primary = IntField('Primary', default=0)
secondary = IntField('Secondary', default=0)
class nbtparse.minecraft.terrain.tile.Cauldron(*args, **kwargs)[source]

Bases: nbtparse.minecraft.terrain.tile.Container

A brewing stand (not actually a cauldron).

brew_time = IntField('BrewTime', default=0)
id = UnicodeField('id', default='minecraft:Cauldron')
items = ObjectListField('Items', Item, default=())
class nbtparse.minecraft.terrain.tile.Chest(*args, **kwargs)[source]

Bases: nbtparse.minecraft.terrain.tile.Container

A single chest. Double chests are two of these next to each other.

id = UnicodeField('id', default='minecraft:Chest')
items = ObjectListField('Items', Item, default=())
class nbtparse.minecraft.terrain.tile.Comparator(*args, **kwargs)[source]

Bases: nbtparse.minecraft.terrain.tile.TileEntity

A comparator.

id = UnicodeField('id', default='minecraft:Comparator')
output = IntField('OutputSignal', default=0)
class nbtparse.minecraft.terrain.tile.Container(*args, **kwargs)[source]

Bases: nbtparse.minecraft.terrain.tile.TileEntity

One of several different kinds of containers.

Consult the id to determine which kind.

custom_name = UnicodeField('CustomName', default='')
lock = UnicodeField('Lock', default='')
class nbtparse.minecraft.terrain.tile.Control(*args, **kwargs)[source]

Bases: nbtparse.minecraft.terrain.tile.Container

A control block.

command = UnicodeField('Command', default='')
id = UnicodeField('id', default='minecraft:Control')
last_output = UnicodeField('LastOutput', default='')
success_count = IntField('SuccessCount', default=0)
track_output = BooleanField('TrackOutput', default=False)
class nbtparse.minecraft.terrain.tile.DaylightSensor(*args, **kwargs)[source]

Bases: nbtparse.minecraft.terrain.tile.TileEntity

A daylight sensor.

id = UnicodeField('id', default='minecraft:DLDetector')
class nbtparse.minecraft.terrain.tile.Dispenser(*args, **kwargs)[source]

Bases: nbtparse.minecraft.terrain.tile.AbstractDispenser

A dispenser.

id = UnicodeField('id', default='minecraft:Trap')
class nbtparse.minecraft.terrain.tile.Dropper(*args, **kwargs)[source]

Bases: nbtparse.minecraft.terrain.tile.AbstractDispenser

A dropper.

id = UnicodeField('id', default='minecraft:Dropper')
class nbtparse.minecraft.terrain.tile.EndPortal(*args, **kwargs)[source]

Bases: nbtparse.minecraft.terrain.tile.TileEntity

An end portal.

id = UnicodeField('id', default='minecraft:Airportal')
class nbtparse.minecraft.terrain.tile.FlowerPot(*args, **kwargs)[source]

Bases: nbtparse.minecraft.terrain.tile.TileEntity

A flower pot.

flower_type = IntField('Data', default=0)
id = UnicodeField('id', default='minecraft:FlowerPot')
item = IntField('Item', default=0)
class nbtparse.minecraft.terrain.tile.Furnace(*args, **kwargs)[source]

Bases: nbtparse.minecraft.terrain.tile.Container

A furnace.

burn_time = ShortField('BurnTime', default=0)
cook_time = ShortField('CookTime', default=0)
id = UnicodeField('id', default='minecraft:Furnace')
items = ObjectListField('Items', Item, default=())
class nbtparse.minecraft.terrain.tile.Hopper(*args, **kwargs)[source]

Bases: nbtparse.minecraft.terrain.tile.Container

A hopper.

cooldown = IntField('TransferCooldown', default=0)
id = UnicodeField('id', default='minecraft:Hopper')
items = ObjectListField('Items', Item, default=())
class nbtparse.minecraft.terrain.tile.Music(*args, **kwargs)[source]

Bases: nbtparse.minecraft.terrain.tile.TileEntity

A music block.

id = UnicodeField('id', default='minecraft:Music')
note = ByteField('note', default=0)
class nbtparse.minecraft.terrain.tile.Piston(*args, **kwargs)[source]

Bases: nbtparse.minecraft.terrain.tile.TileEntity

A piston.

block_data = IntField('blockData', default=0)
block_id = IntField('blockId', default=0)
extending = BooleanField('extending', default=False)
facing = IntField('facing', default=0)
id = UnicodeField('id', default='minecraft:Piston')
progress = FloatField('progress', default=0.0)
class nbtparse.minecraft.terrain.tile.RecordPlayer(*args, **kwargs)[source]

Bases: nbtparse.minecraft.terrain.tile.TileEntity

A jukebox.

id = UnicodeField('id', default='minecraft:RecordPlayer')
record_id = IntField('Record', default=0)
record_item = NBTObjectField('RecordItem', Item, default=None)
class nbtparse.minecraft.terrain.tile.Sign(*args, **kwargs)[source]

Bases: nbtparse.minecraft.terrain.tile.TileEntity

A sign.

id = UnicodeField('id', default='minecraft:Sign')
line1 = UnicodeField('Text1', default='')
line2 = UnicodeField('Text2', default='')
line3 = UnicodeField('Text3', default='')
line4 = UnicodeField('Text4', default='')
class nbtparse.minecraft.terrain.tile.Skull(*args, **kwargs)[source]

Bases: nbtparse.minecraft.terrain.tile.TileEntity

A skull on the ground.

id = UnicodeField('id', default='minecraft:Skull')
rotation = ByteField('Rot', default=0)
skull_id = ByteField('SkullType', default=0)
skull_name = UnicodeField('ExtraType', default='')
class nbtparse.minecraft.terrain.tile.SpawnPotential(*args, **kwargs)[source]

Bases: nbtparse.semantics.nbtobject.NBTObject

One possible spawn from a spawner.

properties = NBTObjectField('Properties', NBTObject, default=None)
type = UnicodeField('Type', default='')
weight = IntField('Weight', default=0)
class nbtparse.minecraft.terrain.tile.Spawner(*args, **kwargs)[source]

Bases: nbtparse.minecraft.terrain.tile.TileEntity

A mob spawner.

delay = ShortField('Delay', default=-1)
entity_id = UnicodeField('EntityId', default='')
id = UnicodeField('id', default='minecraft:MobSpawner')
max_delay = ShortField('MaxSpawnDelay', default=1)
max_entities = ShortField('MaxNearbyEntities', default=0)
min_delay = ShortField('MinSpawnDelay', default=0)
player_range = ShortField('RequiredPlayerRange', default=0)
spawn_count = ShortField('SpawnCount', default=0)
spawn_data = NBTObjectField('SpawnData', NBTObject, default=None)
spawn_potentials = ObjectListField('SpawnPotentials', SpawnPotential, default=())
spawn_range = ShortField('SpawnRange', default=0)
class nbtparse.minecraft.terrain.tile.TileEntity(*args, **kwargs)[source]

Bases: nbtparse.semantics.nbtobject.NBTObject

A tile entity. Stores additional data about a block.

coords = <TupleMultiField: nbt_names=('x', 'y', 'z'), default=(None, None, None)>
id = UnicodeField('id', default='')