mciwb#
Minecraft Interactive World Builder: build in a Minecraft world from Python.
The main entry point is Iwb, which connects to a Minecraft server. The
building blocks (Vec3, Item, Direction, Volume, polygon
etc.) come from the mcwb library. These and the classes below can all be
imported from mciwb.imports. mciwb.builders has higher level building
blocks: roofs, arches, stairways, foundations and schematic files.
Read and draw regions with scan and render from the mciwb.render
module (or mciwb.imports). They are not imported here, where a function
called render would hide the mciwb.render module.
- mciwb.__version__: str#
Version number as calculated by pypa/setuptools_scm
Submodules
Render a region of a Minecraft world to an image, so that you (or an AI agent) can see what a build looks like without joining the game. |
|
Higher level building blocks: roofs, arches, columns, stairways, roads, foundations that follow the terrain, and Sponge schematic files. |
Members
Interactive World Builder class. |
|
Return the current |
|
Represent a player in the world and provide functions for monitoring their position and direction they are facing. |
|
The player (or named entity) could not be found in the world. |
|
Provides an interactive way to use copy and paste commands within a Minecraft world. |
|
Monitor the world for signs placed by a player. |
|
Draw walls between pairs of points in the world. |
|
Build walls interactively with command signs. |
|
Defines a class for representing a lever, button or any other activator in the world. |
|
A class to provide threads for monitoring. |
|
An RCON client for Minecraft Java Edition that copes with the other RCON clients of the server. |
|
Retrieve the client for the current thread. |
|
Set the client for this thread. |
|
Create a thread with its own RCON Client connection stored in thread local storage. |
|
Naive deserialization of an SNBT string into a object graph of Python types. |
|
Backup and restore a Minecraft world folder. |
|
Create and monitor Minecraft servers on the local machine using Podman |
|
The blocks of a cuboid region of the world. |
|
The colours of blocks, see the module documentation for the rules. |
- class mciwb.Iwb(server: str = 'localhost', port: int = 20100, passwd: str = 'default_pass')[source]#
Interactive World Builder class. Provides a very simple interface for interactive functions for use in an IPython shell, or in scripts.
Connect to the server started by
mciwb startwith:world = Iwb()
Call
stopwhen finished to stop any background monitoring threads.- Variables:
player – The default
Playerobject.copier –
CopyPasteobject for the above player.signs – The
Signsobject for the above player.world_folder – The server’s world folder, if it is on this machine.
scanandrenderread blocks from its files, which is much faster than over RCON. Set for the server ofmciwb startwhen it uses the default--folder: for another folder, set it yourself, e.g.world.world_folder = Path("/my/server/world").
Initialise the world object.
- Parameters:
server – the server address, defaults to the local server started by
mciwb startport – the server’s RCON port
passwd – the server’s RCON password
- Raises:
SessionTimeout – if the connection to the server fails
- debug(enable: bool = True)[source]#
Enable/disable debug log. Enabling this will also enable full Traceback log.
- Parameters:
enable – True to enable debug log, False to disable
- backup(name: str | None = None) None[source]#
Backup the Minecraft world to a file. If no name is given then the backup will be named using the current date and time.
- Parameters:
name – the name of the backup file
- connect() Client[source]#
Makes a connection to the Minecraft Server. Can be called again if the connection is lost e.g. due to server reboot.
- get_player(name: str) Player[source]#
Get the player object for the given player name.
- Parameters:
name – the name of the player
- add_player(name: str, me: bool = True, setup: bool = True)[source]#
Add a player to the world object. This provides monitoring of the player’s position and handles the player’s placing of action signs. The player is also given a set of the action signs.
If me is True then the player will be set as the current default player. The default player is available using:
Iwb.the_world.player
All players are available using:
Iwb.the_world._players
- Parameters:
name – the name of the player
me – if True, set this player as the default player
setup – if True, make the player an operator in creative mode
- stop()[source]#
Stop all background monitoring threads. Call this when finished with the world, e.g. at the end of a script.
- set_block(pos: Vec3, block: Item, facing: Vec3 | None = None, nbt: list[str] | None = None) bool[source]#
Places a block in the world
- Parameters:
pos – the position to place the block
block – the type of block
facing – the direction the block should face (if applicable)
nbt – a list of block states to apply to the block
nbt examples:
Placing a top half of a door, open, with hinge on the left:
nbt=[“half=upper”, “hinge=left”, “open=true”]
- Returns:
True if the block is now in place. False if the server rejected the command (the server’s response is logged as an error)
- place_door(pos: Vec3, door_type: Item, facing: Vec3 = (0, 0, -1), open: bool = False, right_hinge: bool = False) None[source]#
Place a door in the world (doors are 2 blocks high)
- Parameters:
pos – the position of the bottom half of the door
door_type – the type of door to place e.g. Item.OAK_DOOR
facing – the direction the door should face
open – whether the door should be open or closed
right_hinge – True for a hinge on the right, False for the left
- get_block(pos: Vec3) Item[source]#
Gets a block in the world
- Parameters:
pos – the position to get the block from
- save(filename: str | Path, vol: Volume | None = None)[source]#
Save a Volume of blocks to a file. The volume can be specified in the vol parameter or alternatively defaults to the current copy buffer.
The file is saved in the mcwb format which is a JSON file containing a 3d array of Item objects. If the filename ends in
.schemit is saved as a Sponge schematic instead, with the block states of stairs, slabs and logs (seemciwb.builders.Schematic.from_world), which other Minecraft tools such as WorldEdit can load.The file can be loaded into a world using the
loadmethod.- Parameters:
filename – the name of the file to save to
vol – the volume to save
- Raises:
ValueError – if no vol is given and there is no copy buffer
- load(filename: str | Path, position: Vec3 | None = None, anchor: Anchor3 = Anchor3.BOTTOM_SW)[source]#
Load a saved set of blocks into a location. The location can be specified in argument position or alternatively defaults to the copy buffer start position.
The blocks are loaded from a file in the mcwb format which is a JSON file containing a 3d array of Item objects, or from a Sponge schematic if the filename ends in
.schem(seemciwb.builders.Schematic).The blocks are loaded into the world using the Blocks class.
- Parameters:
filename – the name of the file to load from
position – the position to load the blocks to
anchor – the anchor point for the blocks
- Raises:
ValueError – if no position is given and there is no copy buffer
- scan(start: Vec3, end: Vec3) BlockGrid[source]#
Read the blocks between two opposite corners of a region, from the world’s files if
world_folderis set, otherwise over RCON.- Parameters:
start – a corner of the region
end – the opposite corner of the region
- Returns:
the blocks, e.g.
world.scan(a, b).counts()counts them
- render(start: Vec3, end: Vec3, file: str | Path = 'render.png', views: Sequence[str] = ('top', 'iso'), scale: int | None = None, labels: bool = True) BlockGrid[source]#
Render the region between two opposite corners to a PNG image, to see what a build looks like. See Render a Build to an Image for the views.
- Parameters:
start – a corner of the region
end – the opposite corner of the region
file – the image file to write
views – the views to draw: top, iso, north, south, east, west, iso_ne, iso_nw or iso_sw; a list, or the name of one view
scale – pixels per block, chosen automatically by default
labels – add titles and world coordinate labels
- Returns:
the blocks that were rendered, see
scan
- cmd(cmd: str, expect: str | None = None) str[source]#
Run any arbitrary Minecraft console command on the server.
The server’s reply is returned as it is, including error messages such as
Incorrect argument for command...<--[HERE]. (On Minecraft 26.x, for example, game rules have snake case names, sogamerule doDaylightCycleis an error: usegamerule advance_time. Andtime query daytimeis an error too: usetime query dayfor the ticks into the current day, andtime query day repetitionfor the number of days.)Changed: before mciwb#166 the errors that mcipc recognises were raised as mcipc exceptions (e.g.
InvalidArgument); now they are returned as text like any other reply.Another RCON client of the server (e.g. a dashboard) can, rarely, garble the reply: empty it or add its own output to it. Pass expect to check the reply and send the command again if needed. Only do that for a command that is safe to send twice (e.g.
setblock,tpto a fixed place,gamerule ..., but notgiveorsummon).- Parameters:
cmd – the command to run, without the leading slash e.g. “time set day”
expect – a regular expression that the reply must contain, e.g.
r"Game rule \S+ is currently set to \S+"
- Returns:
the server’s response. With expect, just the part of it that matched, or the whole response if it never matched
- mciwb.get_world() Iwb[source]#
Return the current
Iwbworld object, i.e. the most recently created one.
- class mciwb.Player(name: str)[source]#
Represent a player in the world and provide functions for monitoring their position and direction they are facing.
Creating a Player only reads from the world. Call
setupto make the player an operator in creative mode (Iwb.add_playerdoes this).- Parameters:
name – the name of the player, or the CustomName of any other entity
- setup() None[source]#
Make the player an operator in creative mode, so that they can use command signs and build freely.
- property pos_f: Vec3#
Return the player’s precise position
- property pos: Vec3#
Return the player’s block position
- property facing: Vec3#
Return the player’s facing direction
- Returns:
a Vec3 representing the direction the player is facing NORTH = Vec3(0, 0, -1) SOUTH = Vec3(0, 0, 1) EAST = Vec3(1, 0, 0) WEST = Vec3(-1, 0, 0)
- exception mciwb.PlayerNotInWorldError[source]#
The player (or named entity) could not be found in the world.
- class mciwb.CopyPaste[source]#
Provides an interactive way to use copy and paste commands within a Minecraft world.
- apply_volume(vol: Volume)[source]#
Use a Volume to set the copy buffer location and dimensions. The paste point is set to the start of the Volume.
- get_commands()[source]#
return a list of command names and the callback functions they represent. For use in setting up a
Signsobject that can be used to interactively call the copy paste functions.
- select(pos: Vec3)[source]#
Select a new copy buffer start point in the world. The previous start point becomes the stop point (i.e. opposite corner of the paste buffer)
- paste_safe(pos: Vec3)[source]#
Paste the contents of the paste buffer to pos, but only if the paste buffer does not overlap with the target area
- fill(pos: Vec3 = (0, 0, 0), item: Item = Item.AIR)[source]#
fill the paste buffer offset by pos with Air or a specified block
- Parameters:
pos – offset from the paste buffer start point
item – block to fill with
- class mciwb.Signs(player: Player)[source]#
Monitor the world for signs placed by a player. Perform an action based on the text of the sign.
Each sign object can be used to monitor the placing of signs by a single player. The object can be hooked to functions that are to be called when a sign is placed by the player.
By default each Sign object is initialized with select/copy/paste functions. Additional signs with callback functions can be added.
For best results, use the bound methods of an object for the callback functions. That way the user code can manage state within the object providing those functions.
- poll()[source]#
check if a sign has been placed in front of the player 1 to 3 blocks away and take action based on sign text
- do_action(command: str, target: Vec3, block_pos: Vec3)[source]#
Perform an action based on the text of the sign. The action is to call the callback function that is configured for this sign text.
- Parameters:
command – the text of the sign
target – the target block that the sign indicates
block_pos – the position of the block that the sign is on - this is cleared if the sign is used
- add_sign(name: str, function: Callable[[Vec3], None])[source]#
Add a new sign type with its action callback function
- Parameters:
name – the text of the sign
function – the callback function to be called when the sign is placed
- remove_sign(name: str)[source]#
Stop monitoring for a sign with the given name
- Parameters:
name – the text of the sign
- classmethod sign_block(text: str) str[source]#
Return the block state and NBT for a standing oak sign with the given text. For use with setblock, e.g. to place a command sign from code.
- Parameters:
text – the text for the first line of the sign
- class mciwb.Wall(height: int | None = None, item: Item | str = Item.STONE, profile: list[Any] | None = None)[source]#
Draw walls between pairs of points in the world.
A wall is drawn column by column along the line from its start to its end. The profile describes the columns, and is repeated along the length of the wall:
the profile is a list of columns
each column is a list of blocks, from the top of the column down
each block is an
Item, or a list of Items to make the wall more than one block thick (extending to the right of the direction of drawing)
If the column is shorter than height it is repeated to fill the height.
For example, a castle wall with crenellations on top:
battlement = [Item.AIR, Item.STONE_BRICKS, Item.STONE_BRICKS] solid = [Item.STONE_BRICKS] * 3 wall = Wall(profile=[solid, battlement]) wall.set_start(Vec3(0, -60, 0)) wall.draw(Vec3(20, -60, 0))
- Parameters:
height – the height of the wall, defaults to the length of each column in the profile
item – the block to build a plain wall from, used when no profile is given
profile – the profile of the wall, a list of columns
- set_start(pos: Vec3)[source]#
Set the start point of the next wall. The wall is built on top of the block at pos.
- Parameters:
pos – the block that the wall starts on
- class mciwb.WallMaker(wall: Wall | None = None)[source]#
Build walls interactively with command signs. Gives the player a ‘start_wall’ sign and an ‘end_wall’ sign. Place ‘start_wall’ to set the start of a wall, then place ‘end_wall’ to draw the wall up to it. Keep placing ‘end_wall’ signs to draw a connected series of walls.
Requires a player added with
Iwb.add_player.- Parameters:
wall – the
Wallto draw, defaults to a plain stone wall 3 high
- class mciwb.Switch(position: Vec3, item: Item, callback: Callable[[Switch], None], name: str = '')[source]#
Defines a class for representing a lever, button or any other activator in the world. Implements monitoring of the switch’s state with callbacks.
- Parameters:
position – the position of the switch in the world
item – the item type of the switch (must be one of
item_types)callback – the callback to call when the switch’s state changes
name – the name of the switch (defaults to “switch” + id)
- Variables:
id – the id of the switch
name – the name of the switch
pos – the position of the switch in the world
powered – the current state of the switch (True if powered)
callback – the callback to call when the switch’s state changes
monitor – the
Monitorobject for the switchswitches – the list of all switches in the world
next_id – the next id to assign to a switch
on – the state to check for a powered switch
off – the state to check for an un-powered switch
- class mciwb.Monitor(func: Callable[[...], Any] | None = None, params: tuple[Any, ...] = (), once: bool = False, name: str | None = None, poll_rate: float = 0.2, start: bool = True)[source]#
A class to provide threads for monitoring. Each thread maintains a list of functions to call repeatedly.
Each thread has its own Client object for parallel execution of Minecraft server functions.
- Parameters:
func – a function to call in the Monitor thread
params – parameters to pass to the above function. Note that func and params can be None, () in which case you must use
add_poller_functo add functions to be called.once – if True, stop polling after first poll - use for a single background operation
name – name of the thread
poll_rate – rate at which to poll the functions
start – if True, start the thread immediately
- add_poller_func(func: Callable[[...], Any], params: tuple[Any, ...] = ())[source]#
Add a function to the pollers list
- Parameters:
func – function to add
params – parameters to pass to the function
- remove_poller_func(func: Callable[[...], Any])[source]#
Remove a function from the pollers list
- Parameters:
func – function to remove
- class mciwb.Client(*args, frag_threshold: int = 4096, **kwargs)[source]#
An RCON client for Minecraft Java Edition that copes with the other RCON clients of the server.
Each command waits for any command running on another connection of this process to complete, so that the server returns the output of this command only.
Other processes can still run commands at the same moment, which can empty our reply or add theirs to it (about 1 in 10000 commands while another client polls the server). So the replies of
setblockandfill(except indestroymode) andloot(as used bymcwb.get_block) are checked, the command is sent again if the reply is lost, and only the command’s own output is returned. Other commands, includingclone, are sent once: useretry_command, orIwb.cmd(..., expect=...), for those that are safe to send again.Set an optional fragmentation threshold and command in order to detect fragmented packets.
For details see: https://wiki.vg/RCON#Fragmentation
- mciwb.get_client() Client[source]#
Retrieve the client for the current thread.
Every thread needs its own RCON connection. Threads created with
new_thread(e.g. byMonitor) get one automatically.
- mciwb.set_client(client: Client) None[source]#
Set the client for this thread. Use this when the client object has been created outside of
new_thread.
- mciwb.new_thread(client: Client, target: Callable[[], None], name: str) Thread[source]#
Create a thread with its own RCON Client connection stored in thread local storage.
The thread is a daemon thread so that it can never keep the Python interpreter alive on exit. Use
Monitor.stop_allto stop threads cleanly.- Parameters:
client – the client whose connection details the new thread copies
target – the function to run in the new thread
name – the name of the new thread
- mciwb.parse_nbt(s_nbt_text: str) object[source]#
Naive deserialization of an SNBT string into a object graph of Python types.
Note that this is one way only since the following details are lost: - distinction between byte, short, int long, types (suffixes of b,s,none,l) - distinction between float, double types (suffixes of f,d) - distinction between SNBT and raw JSON (enclosed in single quotes)
- class mciwb.Backup(world_folder: Path = PosixPath('/home/runner/mciwb-server/world'), backup_folder: Path = PosixPath('/home/runner/mciwb-backups'))[source]#
Backup and restore a Minecraft world folder.
- Parameters:
world_folder – the world folder of the server (containing level.dat)
backup_folder – the folder to save backup zip files in
- backup(name: str | None = None, running: bool = True) Path[source]#
Backup the world folder to a zip file in the backup folder.
- Parameters:
name – the name of the backup file, defaults to the current date and time
running – True if the server is running. The server is then told to save everything to disk and pause saving during the backup. This needs an RCON client for the current thread (see
get_client)
- Returns:
the path of the backup file
- Raises:
ValueError – if the world folder is not a Minecraft world
- find(name: str | None = None) Path[source]#
Find a backup file
- Parameters:
name – the name of the backup file, defaults to the latest backup
- Returns:
the path of the backup file
- Raises:
ValueError – if the backup file does not exist
- restore(name: str | None = None, backup: bool = False) None[source]#
Restore the world folder from a backup. The server must be stopped.
The current world folder is replaced. It is kept as a sibling folder with the suffix ‘-old’ if backup is True, and deleted otherwise.
- Parameters:
name – the name of the backup file, defaults to the latest backup
backup – keep the current world folder as ‘<world>-old’
- Raises:
ValueError – if the backup file does not exist
- class mciwb.MinecraftServer(name: str, rcon: int, password: str, server_folder: Path, world_type: str, keep: bool = True, test: bool = False, version: str = '26.3')[source]#
Create and monitor Minecraft servers on the local machine using Podman
- Parameters:
name – the name of the server
rcon – the rcon port for the server
password – the rcon password for the server
server_folder – the folder to store the server files in
world_type – the type of world to create (a world preset such as “normal” or “flat”)
keep – keep the server running: the container has the “always” restart policy, so podman-restart.service restarts it after a reboot, and
removedoes nothing unless forcedtest – run the server in test mode (a flat world without structures or mobs, regenerated by each
create)version – the Minecraft Java Edition release to run. Note that an existing world is upgraded if it is opened with a newer release
Create a
MinecraftServerobject only. Usecreateto spin up the container.- wait_server()[source]#
Wait until the server is ready to accept rcon connections
- Raises:
RuntimeError – if the container stops, or the server does not accept connections within
start_timeoutseconds. The error includes the end of the server log.
- remove(force=False)[source]#
Remove a minecraft server container
- Parameters:
force – force the removal of the container
- create(force: bool = False) None[source]#
Spin up a minecraft server in a container, creating a new world if the server folder has none.
If the container already exists it is reused (and started if it is stopped) with the settings that it was created with. Use force, or
mciwb stop, to recreate it with new settings.- Parameters:
force – force the server to be removed if it already exists
- class mciwb.BlockGrid(origin: Vec3, ids: ndarray, names: list[str])[source]#
The blocks of a cuboid region of the world.
Each block is stored as an index into a list of block names, which keeps large regions small and makes per-block lookups (e.g. colours) cheap.
- Variables:
origin – the world position of the block at index [0, 0, 0], the lowest (north west bottom) corner of the region
ids – integer array of shape (size x, size y, size z), indexed
ids[x][y][z]like amcwb.Cuboidnames – the namespaced block id for each index in ids, e.g.
"minecraft:stone"
- classmethod from_blocks(blocks: Iterable, origin: Vec3) BlockGrid[source]#
Make a grid from a 3D array of block names or
mcwb.Item, indexed[x][y][z], such as themcwb.Cuboidreturned bygrab- Parameters:
blocks – a nested list or numpy array of blocks
origin – the world position of blocks[0][0][0]
- property size: Vec3#
the size of the region in blocks (x, y, z)
- property end: Vec3#
the world position of the highest (south east top) corner block
- property volume: Volume#
the region as a
mcwb.Volume
- class mciwb.Palette(colours: Mapping[str, tuple[int, int, int] | tuple[int, int, int, int]] | None = None)[source]#
The colours of blocks, see the module documentation for the rules.
- Parameters:
colours – colours that take precedence over the defaults, keyed by block name (with or without the
minecraft:namespace), as (r, g, b) or (r, g, b, a) with values 0-255