mciwb.builders#
Higher level building blocks: roofs, arches, columns, stairways, roads, foundations that follow the terrain, and Sponge schematic files.
They all build with the RCON client of the current thread (get_client),
take Vec3 positions and blocks as Item, block state strings or
BlockState, and return the bounding box (a Volume) of the blocks they
placed, ready to grab, save or clear. A server error (e.g. an unknown block,
or a position in an unloaded chunk) raises BuildError.
Coordinates follow Minecraft: Y is up, north is -z, east is +x.
Members
A block id, its block state properties and optionally its block entity data (the contents of a chest, the text of a sign ...). |
|
The server rejected a building command, e.g. an unknown block or a position that is not loaded. |
|
The Minecraft heightmaps: what counts as the ground. |
|
One block along the middle of a path |
|
Place blocks with the RCON client of the current thread, recording the bounding box of every block placed. |
|
A box of blocks with their block states, e.g. to save to, or load from, a Sponge schematic |
|
An arch standing in a vertical wall plane. |
|
The blocks of an arch, as (u, v) cells where u counts across the span from 0 to |
|
A square column standing on base. |
|
The block state name of a |
|
A flat roof: one layer of block, optionally with a parapet around its edge. |
|
A foundation that follows the terrain: fill each column of a rectangular footprint from the ground up to |
|
The full block made of the same material as a stairs block, e.g. |
|
A gable (pitched) roof: two slopes of stairs meeting at a ridge. |
|
The y of the top ground block at |
|
The y of the top ground block of each of a set of columns. |
|
A hip roof: four slopes of stairs, one from each side of the footprint, with outer corner stairs where they meet. |
|
A road along a path that follows the terrain: each block of the road replaces the top ground block of its column. |
|
The slab made of the same material as a stairs block, e.g. |
|
Work out the |
|
A stairway along a path, climbing (or descending) between the heights of its points. |
|
The blocks along the middle of a path through points, with the heights of the blocks spread evenly between the heights of the points. |
- class mciwb.builders.BlockState(name: str, props: Mapping[str, str]=<factory>, nbt: str = '')[source]#
A block id, its block state properties and optionally its block entity data (the contents of a chest, the text of a sign …).
str(state)gives the form thatsetblockandfillaccept, and that Sponge schematic palettes use:>>> state = BlockState.of(Item.OAK_STAIRS, facing="east", half="bottom") >>> str(state) 'minecraft:oak_stairs[facing=east,half=bottom]' >>> str(state.rotate(1)) 'minecraft:oak_stairs[facing=south,half=bottom]' >>> BlockState.parse("stone").name 'minecraft:stone' >>> sign = BlockState.parse("oak_sign[rotation=4]{front_text:{}}") >>> sign.nbt '{front_text:{}}'
- Variables:
name – the namespaced block id, e.g.
minecraft:oak_stairsprops – the block state properties, e.g.
{"facing": "east"}. Properties that are not given take the block’s default value.nbt – the block entity data as SNBT text, including its braces, e.g.
{Items:[{Slot:0b,id:"minecraft:apple",count:3}]}, or""for none.setblockandfillgive it to every block they place. It is compared as text, so states that differ only in the spacing or order of their NBT are not equal.
- classmethod parse(block: Item | str | BlockState) BlockState[source]#
Make a BlockState from an
Item, a block state string or a BlockState. A string may end with block entity data in SNBT, assetblocktakes it, e.g.chest[facing=west]{Items:[...]}.- Raises:
ValueError – if the string is not a valid block state
- classmethod of(block: Item | str | BlockState, **props: str | bool | int | Vec3) BlockState[source]#
Make a BlockState from a block and extra properties, e.g.
BlockState.of(Item.OAK_STAIRS, facing=Direction.EAST). A Direction is converted to its name, a bool totrue/falseand an int to its digits, e.g.BlockState.of(Item.SNOW, layers=3). The new properties replace any that the block already has, and any block entity data is kept.
- with_props(**props: str | bool | int | Vec3) BlockState[source]#
A copy of this state with some properties added or replaced, e.g.
.with_props(half="top", waterlogged=True, rotation=4)
- with_nbt(nbt: str | None) BlockState[source]#
A copy of this state with its block entity data replaced, e.g.
.with_nbt('{Items:[{Slot:0b,id:"minecraft:apple",count:3}]}').Noneor""removes it.- Raises:
ValueError – if nbt is not one SNBT compound
{...}
- property item: Item#
The
Itemfor this block, without its properties- Raises:
ValueError – if the block is not in
Iteme.g. a modded block
- rotate(steps: int = 1) BlockState[source]#
Rotate the block about the Y axis by steps quarter turns clockwise, viewed from above (north becomes east). Updates
facing,axis,rotation(signs, banners, heads), direction named connections (fences, walls, panes, redstone) and railshape. Block entity data is kept unchanged.
- mirror(axis: str) BlockState[source]#
Mirror the block along the
"x"axis (east and west swap) or the"z"axis (north and south swap). Also swaps left and right, e.g. the stairs shapeouter_leftbecomesouter_right.
- exception mciwb.builders.BuildError[source]#
The server rejected a building command, e.g. an unknown block or a position that is not loaded
- class mciwb.builders.Heightmap(value)[source]#
The Minecraft heightmaps: what counts as the ground.
- WORLD_SURFACE = 'world_surface'#
the highest block that is not air (includes plants, snow layers …)
- MOTION_BLOCKING = 'motion_blocking'#
the highest block that blocks movement, or holds water or lava
- MOTION_BLOCKING_NO_LEAVES = 'motion_blocking_no_leaves'#
as MOTION_BLOCKING, but ignoring leaves
- OCEAN_FLOOR = 'ocean_floor'#
the highest block that blocks movement, e.g. the bed of a lake or the sea
- class mciwb.builders.PathStep(pos: Vec3, direction: Vec3)[source]#
One block along the middle of a path
- pos: Vec3#
the position of the block
- direction: Vec3#
the horizontal direction of travel into this block (out of it, for the first block)
- class mciwb.builders.Placer(client: Client | None = None)[source]#
Place blocks with the RCON client of the current thread, recording the bounding box of every block placed.
- Parameters:
client – the client to use, defaults to
get_client
- property volume: Volume#
The bounding box of every block placed so far
- Raises:
ValueError – if nothing has been placed
- include(start: Vec3, end: Vec3 | None = None) None[source]#
Extend the bounding box to include a block, or a box of blocks
- setblock(pos: Vec3, block: Item | str | BlockState) str[source]#
Set one block, e.g.
placer.setblock(pos, "oak_stairs[half=top]"). The block may carry block entity data, e.g. a sign’s text:text = '''{front_text:{messages:['"Hi"','""','""','""']}}''' placer.setblock(pos, "oak_sign[rotation=4]" + text)
- fill(start: Vec3, end: Vec3, block: Item | str | BlockState, mode: FillMode | None = None, filter: str | None = None) str[source]#
Fill the box between two opposite corners, inclusive. Block entity data in block (
chest{Items:[...]}) is given to every block.- Parameters:
mode – e.g.
FillMode.KEEPto only replace airfilter – only replace these blocks, e.g.
"minecraft:stone"or a tag like"#minecraft:logs". ImpliesFillMode.REPLACE
- Raises:
ValueError – if a filter is given with a mode other than REPLACE
- class mciwb.builders.Schematic(blocks: ndarray, *, block_entities: list[dict[str, Any]] | None = None, offset: Vec3 = (0, 0, 0), metadata: dict[str, Any] | None = None, data_version: int = 5023)[source]#
A box of blocks with their block states, e.g. to save to, or load from, a Sponge schematic
.schemfile.For example, copy a building with its stairs and slabs facing the right way, turned a quarter turn clockwise:
house = Schematic.from_world(Volume.from_corners(corner1, corner2)) house.save("house.schem") Schematic.load("house.schem").rotate(1).paste(Vec3(100, 64, 0))
- Variables:
blocks – a 3D numpy array of
BlockState, indexed[x][y][z]block_entities – the block entities (chests, signs …) from a file, as Sponge BlockEntity compounds (
Pos,Id,Data). These are kept when saving, but not pasted into the worldoffset – the Sponge
Offsetof the file, kept when saving, but not used when pastingmetadata – the Sponge
Metadatacompound (Name,Author…)data_version – the Minecraft data version that the blocks are from
- property size: Vec3#
The size of the schematic, as (width x, height y, length z)
- property palette: list[BlockState]#
The different block states in the schematic
- classmethod from_cuboid(cuboid: Sequence[Any] | ndarray) Schematic[source]#
Make a schematic from a 3D list (or numpy array) of blocks indexed
[x][y][z], e.g. fromgraborload_items. The blocks may beItem, block state strings orBlockState.
- to_cuboid() list[source]#
The blocks as a 3D list of
Itemindexed[x][y][z], for use withBlocksorsave_items. This loses the block states.- Raises:
ValueError – if a block is not in
Iteme.g. a modded block
- classmethod from_world(volume: Volume, states: bool = True) Schematic[source]#
Read the blocks in a Volume of the world.
Reading is slow: one RCON command for each block, and when states is True a few more for each stairs, slab and log-like block, to find its
facing,half,shape,typeoraxis. Other block states (e.g. the facing of a door or a furnace) can not be read back, and those blocks take their default state. Block entity data (e.g. chest contents) is not read either. Some blocks read back as a related block, e.g. a wall torch as a torch, seeget_block.- Parameters:
volume – the box of the world to read
states – read the block states of stairs, slabs and logs
- paste(position: Vec3, air: bool = False) Volume[source]#
Place the blocks in the world, with the schematic’s bottom north west corner (
blocks[0][0][0]) at position. Uses onefillfor each rectangle of the same block state in each layer, bottom layer first.- Parameters:
position – where to put the bottom north west corner
air – if True, also place the air blocks, clearing whatever is in the box. If False, leave the world unchanged where the schematic has air
- Returns:
the box that the schematic covers in the world
- rotate(steps: int = 1) Schematic[source]#
A copy of the schematic turned about the Y axis by steps quarter turns clockwise, viewed from above (so a stairs block facing north faces east after one step). See
BlockState.rotatefor the block states that turn with it.
- mirror(axis: str) Schematic[source]#
A mirror image copy of the schematic:
"x"swaps east and west,"z"swaps north and south. SeeBlockState.mirror.
- mciwb.builders.arch(start: Vec3, end: Vec3, block: Item | str | BlockState = Item.STONE_BRICKS, *, style: str = 'round', thickness: int = 1, depth: int = 1, clear: bool = False) Volume[source]#
An arch standing in a vertical wall plane.
start and end are the two outermost blocks at the foot of the arch, on the same y and in a line along x or along z. The arch rises from there: a 7 block span with the default thickness of 1 looks like this (
#is the arch,.the opening):### y = start.y + 3 ###.### #.....# #.....# y = start.y: start and end are the # at each end
Its legs are short: build walls or a
columnunder it for a taller opening (or start it higher up).arch_profilegives the shape of any arch without building it.- Parameters:
start – the block at one foot of the arch
end – the block at the other foot, in line with start along x or z
block – the block to build the arch from
style –
"round"(semicircular) or"pointed"(gothic)thickness – the thickness of the ring of the arch, in blocks
depth – how many blocks thick the arch is through the wall. The extra blocks go south (for an arch along x) or east (along z)
clear – also set the opening under the arch to air, e.g. to cut an arched doorway through an existing wall
- Returns:
the bounding box of the arch, and the opening if cleared
- mciwb.builders.arch_profile(span: int, thickness: int = 1, style: str = 'round') tuple[set[tuple[int, int]], set[tuple[int, int]]][source]#
The blocks of an arch, as (u, v) cells where u counts across the span from 0 to
span - 1and v counts up from the springing line (v = 0).- Parameters:
span – the outside width of the arch, in blocks
thickness – the thickness of the ring of the arch, in blocks
style –
"round"(a semicircle) or"pointed"(a gothic, equilateral arch: two arcs whose radius is the width of the opening)
- Returns:
(ring, opening): the cells of the ring of the arch, and the cells of the opening under it
- mciwb.builders.column(base: Vec3, height: int, block: Item | str | BlockState = Item.QUARTZ_PILLAR, *, width: int = 1, plinth: Item | str | BlockState | None = None, capital: Item | str | BlockState | None = None) Volume[source]#
A square column standing on base.
- Parameters:
base – the bottom block in the middle of the column
height – the total height of the column, including any plinth and capital
block – the block for the shaft
width – the width of the shaft. Odd widths are centred on base, even widths have the extra block to the east and south
plinth – if given, the bottom layer is this block, one block wider than the shaft on every side
capital – if given, the top layer is this block, one block wider than the shaft on every side
- Returns:
the bounding box of the column
- mciwb.builders.facing_name(direction: Vec3) str[source]#
The block state name of a
Direction, e.g."east"forDirection.EAST- Raises:
ValueError – if direction is not one of the six Directions
- mciwb.builders.flat_roof(start: Vec3, end: Vec3, block: Item | str | BlockState = Item.SMOOTH_STONE, *, parapet: Item | str | BlockState | None = None, parapet_height: int = 1, overhang: int = 0) Volume[source]#
A flat roof: one layer of block, optionally with a parapet around its edge.
- Parameters:
start – a corner of the footprint, e.g. the top of a corner of the walls; the roof is at
start.y + 1end – the opposite corner of the footprint (only x and z are used)
block – the roof block, e.g. a full block or a slab
parapet – if given, build a low wall of this block around the edge of the roof, on top of it. Walls, fences and panes join up automatically
parapet_height – the height of the parapet
overhang – extend the roof this many blocks past the footprint on every side
- Returns:
the bounding box of the roof and parapet
- mciwb.builders.foundation(start: Vec3, end: Vec3, block: Item | str | BlockState = Item.COBBLESTONE, *, heightmap: Heightmap | str = Heightmap.OCEAN_FLOOR, max_depth: int = 64) Volume[source]#
A foundation that follows the terrain: fill each column of a rectangular footprint from the ground up to
start.y, giving a level platform atstart.yto build on (atstart.y + 1).Build the foundation before anything above it: the ground height is the top of the highest block in each column, so a building already standing there would count as the ground. Columns where the ground is higher than
start.yjust get the top layer (replacing the ground there).- Parameters:
start – a corner of the footprint, at the height of the top of the foundation
end – the opposite corner of the footprint (only x and z are used)
block – the block to build the foundation from
heightmap – what counts as the ground. The default ignores water, so the foundation goes down to the bed of a lake or the sea
max_depth – the deepest any column may go, in blocks below
start.y(a guard against building down into a ravine or the void). 0 gives just the top layer
- Returns:
the bounding box of the foundation
- mciwb.builders.full_block_of(stairs: Item | str | BlockState) Item[source]#
The full block made of the same material as a stairs block, e.g.
Item.OAK_PLANKSforItem.OAK_STAIRS,Item.STONE_BRICKSforItem.STONE_BRICK_STAIRS- Raises:
ValueError – if there is no matching block
- mciwb.builders.gable_roof(start: Vec3, end: Vec3, stairs: Item | str | BlockState = Item.OAK_STAIRS, *, ridge: Item | str | BlockState | None = None, gable: Item | str | BlockState | None = None, axis: str | None = None, overhang: int = 0) Volume[source]#
A gable (pitched) roof: two slopes of stairs meeting at a ridge.
For a footprint 7 wide across the ridge, seen from the gable end (
#is the gable, if one is given):▄ <- ridge slab, y = start.y + 4 ◢ # ◣ ◢ # # # ◣ ◢ # # # # # ◣ <- stairs, y = start.y + 1 W . . . . . W <- walls, top at start.y- Parameters:
start – a corner of the footprint, e.g. the top of a corner of the walls; the roof starts at
start.y + 1end – the opposite corner of the footprint (only x and z are used)
stairs – the stairs to build the slopes from
ridge – the block along the ridge when the footprint is an odd number of blocks across. Defaults to the slab matching stairs, placed as a bottom slab. The gap under it, between the stairs of the course below, is filled with the same block as a double slab (or with ridge itself if it is not a slab)
gable – if given, fill the triangular gable ends under the roof with this block, above the footprint’s end walls
axis –
"x"or"z", the direction that the ridge runs. Defaults to the longer side of the footprintoverhang – extend the roof this many blocks past the footprint on every side (the slopes stay at the same height, so the eaves overhang the walls)
- Returns:
the bounding box of the roof (and gables)
- mciwb.builders.ground_height(x: float, z: float, heightmap: Heightmap | str = Heightmap.MOTION_BLOCKING_NO_LEAVES) int[source]#
The y of the top ground block at
(x, z), seeground_heights.
- mciwb.builders.ground_heights(columns: Iterable[tuple[float, float]], heightmap: Heightmap | str = Heightmap.MOTION_BLOCKING_NO_LEAVES) dict[tuple[int, int], int][source]#
The y of the top ground block of each of a set of columns.
Teleports a temporary marker entity to the top of each column, which costs one RCON command per column (plus two to make and remove the marker).
- Parameters:
columns –
(x, z)pairsheightmap – what counts as the ground, see
Heightmap
- Returns:
the y of the top ground block, keyed by
(x, z). In a column with no ground at all (e.g. the void in the End) this is one below the bottom of the world- Raises:
BuildError – if a column is not in a loaded chunk
- mciwb.builders.hip_roof(start: Vec3, end: Vec3, stairs: Item | str | BlockState = Item.OAK_STAIRS, *, ridge: Item | str | BlockState | None = None, overhang: int = 0) Volume[source]#
A hip roof: four slopes of stairs, one from each side of the footprint, with outer corner stairs where they meet. Each course is a ring of stairs one block in and one block up from the course below. Where the slopes meet along a line one block wide (the ridge) the roof is finished with ridge blocks, on a line of full blocks (the ridge slab doubled) that fills the middle of the course below.
- Parameters:
start – a corner of the footprint, e.g. the top of a corner of the walls; the roof starts at
start.y + 1end – the opposite corner of the footprint (only x and z are used)
stairs – the stairs to build the slopes from
ridge – the block for a ridge one block wide, defaults to the slab matching stairs, placed as a bottom slab. The middle of the course below it is filled with the same block as a double slab (or with ridge itself if it is not a slab)
overhang – extend the roof this many blocks past the footprint on every side
- Returns:
the bounding box of the roof
- mciwb.builders.road(points: Sequence[Vec3], block: Item | str | BlockState = Item.DIRT_PATH, *, width: int = 3, border: Item | str | BlockState | None = None, clearance: int = 2, heightmap: Heightmap | str = Heightmap.MOTION_BLOCKING_NO_LEAVES) Volume[source]#
A road along a path that follows the terrain: each block of the road replaces the top ground block of its column. The y of points is ignored.
The road does not smooth the terrain, it steps up and down with it. Use
stairwayfor a path at fixed heights.- Parameters:
points – the start, each corner and the end of the road
block – the road surface
width – the width of the road
border – if given, the blocks along both edges of the road
clearance – set this many blocks above the road to air, clearing grass, flowers and snow
heightmap – what counts as the ground, see
Heightmap. The default ignores leaves, but the road goes over the top of water
- Returns:
the bounding box of the road
- mciwb.builders.slab_of(stairs: Item | str | BlockState) Item[source]#
The slab made of the same material as a stairs block, e.g.
Item.OAK_SLABforItem.OAK_STAIRS- Raises:
ValueError – if there is no matching slab
- mciwb.builders.stair_shapes(stairs: Mapping[tuple[int, int], str]) dict[tuple[int, int], str][source]#
Work out the
shapeof each stairs block in one horizontal layer of stairs of the samehalf, as Minecraft does when the blocks are placed.- Parameters:
stairs – the
facingof each stairs block, keyed by(x, z)- Returns:
the
shapeof each stairs block, keyed by(x, z)
A stairs block’s
facingis the side of its full height step, so people walking up it travel in that direction. A corner forms when the stairs in front of (or behind) it face across it:outer_lefthas its high corner on thefacingside and the side counterclockwise from it,outer_righton the clockwise side. This followsStairBlock.getStairsShapein Minecraft.
- mciwb.builders.stairway(points: Sequence[Vec3], stairs: Item | str | BlockState = Item.STONE_BRICK_STAIRS, *, landing: Item | str | BlockState | None = None, width: int = 1, support: Item | str | BlockState | None = None, clearance: int = 0) Volume[source]#
A stairway along a path, climbing (or descending) between the heights of its points.
Each point is a block of the walkway, the block that people stand on, so the walkway’s surface is one block above it. Each section between two points climbs at most one block for each block along it. Where a block is higher than the one before it there is a stairs block (facing the way up), elsewhere a level landing block. So
pointsat the same height give a level path.The path may pass over itself, as in a spiral staircase round a tower or a switchback: each pass gets its own blocks. Choose the points so that there is headroom between one pass and the next one above it.
For example, from (0, 64, 0) east to (4, 66, 0):
◢ # y = 66: stairs, then a landing at the end ◢ # y = 65: stairs, landing # y = 64: a landing at the start
- Parameters:
points – the walkway blocks at the start, each corner and the end
stairs – the stairs to climb with
landing – the block for the level parts, defaults to the full block matching stairs e.g.
Item.STONE_BRICKSwidth – the width of the stairway
support – if given, fill the space under the stairway with this block, down to the height of its lowest block (only replacing air). Where the stairway passes over itself, the support stops above the headroom of the pass below
clearance – set this many blocks above the walkway to air, to make headroom through the terrain
- Returns:
the bounding box of the stairway
- mciwb.builders.trace_path(points: Sequence[Vec3]) list[PathStep][source]#
The blocks along the middle of a path through points, with the heights of the blocks spread evenly between the heights of the points.
In a section that climbs (or descends) by less than its length, the last block before each point (the first block after it, when descending) stays level, so that a corner is a landing.
- Raises:
ValueError – if a section is diagonal, or climbs more than one block for each block along