If you have existing scripts that use the mcpi implementation, and you wish to convert them to using the picraft library, this section contains details and examples covering equivalent functionality between the libraries.
Equivalent: World
To create a connection using default settings is similar in both libraries:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> from picraft import World
>>> w = World()
Creating a connection with an explicit hostname and port is also similar:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create('localhost', 4711)
>>> from picraft import World
>>> w = World('localhost', 4711)
See Minecraft.getBlockWithData below.
Equivalent: blocks
This method only works with the Raspberry Juice mod for the PC version of Minecraft. In picraft simply query the blocks attribute with a slice of vectors, just as with the equivalent to Minecraft.setBlocks below:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.getBlocks(0, -1, 0, 0, 5, 0)
[2, 2, 2, 2, 2, 2, 2]
>>> from picraft import World, Vector, Block
>>> w = World()
>>> v1 = Vector(0, -1, 0)
>>> v2 = Vector(0, 5, 0)
>>> w.blocks[v1:v2 + 1]
[<Block "grass" id=2 data=0>,<Block "grass" id=2 data=0>,<Block "grass" id=2 data=0>,
<Block "grass" id=2 data=0>,<Block "grass" id=2 data=0>,<Block "grass" id=2 data=0>,
<Block "grass" id=2 data=0>]
Note
In picraft, this method will work with both Raspberry Juice and Minecraft Pi Edition, but the efficient getBlocks call will only be used when picraft detects it is connected to a Raspberry Juice server.
Equivalent: blocks
There is no direct equivalent to getBlock, just getBlockWithData (as there’s no difference in operational cost so there’s little point in retrieving a block id without the data). In mcpi this is done by executing a method; in picraft this is done by querying an attribute with a Vector:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.getBlock(0, -1, 0)
2
>>> mc.getBlockWithData(0, -1, 0)
Block(2, 0)
>>> from picraft import World, Vector
>>> w = World()
>>> w.blocks[Vector(0, -1, 0)]
<Block "grass" id=2 data=0>
The id and data can be extracted from the Block tuple that is returned:
>>> b = w.blocks[Vector(0, -1, 0)]
>>> b.id
2
>>> b.data
0
Equivalent: blocks
In picraft the same attribute is used as for accessing block ids; just assign a Block instance to the attribute, instead of querying it:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.getBlock(0, -1, 0)
2
>>> mc.setBlock(0, -1, 0, 1, 0)
>>> from picraft import World, Vector, Block
>>> w = World()
>>> w.blocks[Vector(0, -1, 0)]
<Block "grass" id=2 data=0>
>>> w.blocks[Vector(0, -1, 0)] = Block(1, 0)
Equivalent: blocks
The same attribute as for setBlock is used for setBlocks; just pass a slice of vectors instead of a single vector (the example below shows an easy method of generating such a slice by adding 1 to a vector for the upper end of the slice):
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.getBlock(0, -1, 0)
2
>>> mc.setBlocks(0, -1, 0, 0, 5, 0, 1, 0)
>>> from picraft import World, Vector, Block
>>> w = World()
>>> v1 = Vector(0, -1, 0)
>>> v2 = Vector(0, 5, 0)
>>> w.blocks[v]
<Block "grass" id=2 data=0>
>>> w.blocks[v1:v2 + 1] = Block(1, 0)
Equivalent: height
Retrieving the height of the world in a specific location is done with an attribute (like retrieving the id and type of blocks). Unlike mcpi, you pass a full vector (of which the Y-coordinate is ignored), and the property returns a full vector with the same X- and Z-coordinates, but the Y-coordinate of the first non-air block from the top of the world:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.getHeight(0, 0)
0
>>> from picraft import World, Vector
>>> w = World()
>>> w.height[Vector(0, -10, 0)]
Vector(x=0, y=0, z=0)
Equivalent: players
The connected player’s entity ids can be retrieved by iterating over the players attribute which acts as a mapping from player id to Player instances:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.getPlayerEntityIds()
[1]
>>> from picraft import World
>>> w = World()
>>> list(w.players)
[1]
Equivalent: save()
Checkpoints can be saved in a couple of ways with picraft. Either you can explicitly call the save() method, or you can use the checkpoint attribute as a context manager:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.saveCheckpoint()
>>> from picraft import World
>>> w = World()
>>> w.checkpoint.save()
In the context manager case, the checkpoint will be saved upon entry to the context and will only be restored if an exception occurs within the context:
>>> from picraft import World, Vector, Block
>>> w = World()
>>> with w.checkpoint:
... # Do something with blocks...
... w.blocks[Vector()] = Block.from_name('stone')
Equivalent: restore()
As with saving a checkpoint, either you can call restore() directly:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.saveCheckpoint()
>>> mc.restoreCheckpoint()
>>> from picraft import World
>>> w = World()
>>> w.checkpoint.save()
>>> w.checkpoint.restore()
Or you can use the context manager to restore the checkpoint automatically in the case of an exception:
>>> from picraft import World, Vector, Block
>>> w = World()
>>> with w.checkpoint:
... # Do something with blocks
... w.blocks[Vector()] = Block.from_name('stone')
... # Raising an exception within the block will implicitly
... # cause the checkpoint to restore
... raise Exception('roll back to the checkpoint')
Equivalent: say()
The postToChat method is simply replaced with the say() method with the one exception that the latter correctly recognizes line breaks in the message:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.postToChat('Hello world!')
>>> from picraft import World
>>> w = World()
>>> w.say('Hello world!')
Equivalent: immutable and nametags_visible
The setting method is replaced with (write-only) properties with the equivalent names to the settings that can be used:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.setting('world_immutable', True)
>>> mc.setting('nametags_visible', True)
>>> from picraft import World
>>> w = World()
>>> w.immutable = True
>>> w.nametags_visible = True
Equivalent: pos
The player.getPos and player.setPos methods are replaced with the pos attribute which returns a Vector of floats and accepts the same to move the host player:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.player.getPos()
Vec3(12.7743,12.0,-8.39158)
>>> mc.player.setPos(12,12,-8)
>>> from picraft import World, Vector
>>> w = World()
>>> w.player.pos
Vector(x=12.7743, y=12.0, z=-8.39158)
>>> w.player.pos = Vector(12, 12, -8)
One advantage of this implementation is that adjusting the player’s position relative to their current one becomes simple:
>>> w.player.pos += Vector(y=20)
See Minecraft.player.getPos above.
Equivalent: tile_pos
The player.getTilePos and player.setTilePos methods are replaced with the tile_pos attribute which returns a Vector of ints, and accepts the same to move the host player:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.player.getTilePos()
Vec3(12,12,-9)
>>> mc.player.setTilePos(12, 12, -8)
>>> from picraft import World, Vector
>>> w = World()
>>> w.player.tile_pos
Vector(x=12, y=12, z=-9)
>>> w.player.tile_pos += Vector(y=20)
See Minecraft.player.getTilePos above.
Equivalent: autojump
The player.setting method is replaced with the write-only autojump attribute:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.player.setting('autojump', False)
>>> from picraft import World
>>> w = World()
>>> w.player.autojump = False
Equivalent: heading
The player.getRotation method is replaced with the read-only heading attribute:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.player.getRotation()
49.048615
>>> from picraft import World
>>> w = World()
>>> w.player.heading
49.048615
Equivalent: pitch
The player.getPitch method is replaced with the read-only pitch attribute:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.player.getPitch()
4.3500223
>>> from picraft import World
>>> w = World()
>>> w.player.pitch
4.3500223
Equivalent: direction
The player.getDirection method is replaced with the read-only direction attribute:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.player.getDirection()
Vec3(0.1429840348766887,-0.3263934845430674,0.934356922711132)
>>> from picraft import World
>>> w = World()
>>> w.player.direction
Vector(x=0.1429840348766887, y=-0.3263934845430674, z=0.934356922711132)
Equivalent: pos
The entity.getPos and entity.setPos methods are replaced with the pos attribute. Access the relevant Player instance by indexing the players attribute:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.entity.getPos(1)
Vec3(12.7743,12.0,-8.39158)
>>> mc.entity.setPos(1, 12, 12, -8)
>>> from picraft import World, Vector
>>> w = World()
>>> w.players[1].pos
Vector(x=12.7743, y=12.0, z=-8.39158)
>>> w.players[1].pos = Vector(12, 12, -8)
See Minecraft.entity.getPos above.
Equivalent: tile_pos
The entity.getTilePos and entity.setTilePos methods are replaced with the tile_pos attribute. Access the relevant Player instance by indexing the players attribute:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.entity.getTilePos(1)
Vec3(12,12,-9)
>>> mc.entity.setTilePos(1, 12, 12, -8)
>>> from picraft import World, Vector
>>> w = World()
>>> w.players[1].tile_pos
Vector(x=12, y=12, z=-9)
>>> w.players[1].tile_pos += Vector(y=20)
See Minecraft.entity.getTilePos above.
Equivalent: heading
The entity.getRotation method is replaced with the read-only heading attribute:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.entity.getRotation(213)
49.048615
>>> from picraft import World
>>> w = World()
>>> w.players[213].heading
49.048615
Equivalent: pitch
The entity.getPitch method is replaced with the read-only pitch attribute:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.entity.getPitch(213)
4.3500223
>>> from picraft import World
>>> w = World()
>>> w.players[213].pitch
4.3500223
Equivalent: direction
The entity.getDirection method is replaced with the read-only duration attribute:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.entity.getDirection(213)
Vec3(0.1429840348766887,-0.3263934845430674,0.934356922711132)
>>> from picraft import World
>>> w = World()
>>> w.players[213].direction
Vector(x=0.1429840348766887, y=-0.3263934845430674, z=0.934356922711132)
Equivalent: first_person()
The camera attribute in picraft holds a Camera instance which controls the camera in the Minecraft world. The first_person() method can be used to set the camera to view the world through the eyes of the specified player. The player is specified as the world’s player attribute, or as a player retrieved from the players attribute:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.camera.setNormal()
>>> mc.camera.setNormal(2)
>>> from picraft import World
>>> w = World()
>>> w.camera.first_person(w.player)
>>> w.camera.first_person(w.players[2])
Equivalent: third_person()
The camera attribute in picraft holds a Camera instance which controls the camera in the Minecraft world. The third_person() method can be used to set the camera to view the specified player from above. The player is specified as the world’s player attribute, or as a player retrieved from the players attribute:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.camera.setFollow()
>>> mc.camera.setNormal(1)
>>> from picraft import World
>>> w = World()
>>> w.camera.third_person(w.player)
>>> w.camera.third_person(w.players[1])
Equivalent: pos
The pos attribute can be passed a Vector instance to specify the absolute position of the camera. The camera will be pointing straight down (y=-1) from the given position and will not move to follow any entity:
>>> import mcpi.minecraft as minecraft
>>> mc = minecraft.Minecraft.create()
>>> mc.camera.setFixed()
>>> mc.camera.setPos(0,20,0)
>>> from picraft import World, Vector
>>> w = World()
>>> w.camera.pos = Vector(0, 20, 0)
See Minecraft.camera.setFixed above.
Equivalent: Block
The Block class in picraft is similar to the Block class in mcpi but with one major difference: in picraft a Block instance is a tuple descendent and therefore immutable (you cannot change the id or data attributes of a Block instance).
This may seem like an arbitrary barrier, but firstly its quite rare to adjust the the id or data attribute (it’s rather more common to just overwrite a block in the world with an entirely new type), and secondly this change permits blocks to be used as keys in a Python dictionary, or to be stored in a set.
The Block class also provides several means of construction, and additional properties:
>>> from picraft import Block
>>> Block(1, 0)
<Block "stone" id=1 data=0>
>>> Block(35, 1)
<Block "wool" id=35 data=1>
>>> Block.from_name('wool', data=1).description
u'Orange Wool'
>>> Block.from_color('#ffffff').description
u'White Wool'
Compatibility constants are also provided:
>>> from picraft import block
>>> block.DIAMOND_BLOCK
<Block "diamond_block" id=57 data=0>
>>> block.STONE
<Block "stone" id=1 data=0>