6. Conversion from mcpi

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.

6.1. Minecraft.create

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)

6.2. Minecraft.getBlock

See Minecraft.getBlockWithData below.

6.3. Minecraft.getBlocks

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.

Warning

There is currently no equivalent to getBlockWithData that operates over multiple blocks, so blocks returned by querying in this manner only have a valid id field; the data attribute is always 0.

6.4. Minecraft.getBlockWithData

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

6.5. Minecraft.setBlock

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)

6.6. Minecraft.setBlocks

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)

6.7. Minecraft.getHeight

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)

6.8. Minecraft.getPlayerEntityIds

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]

6.9. Minecraft.saveCheckpoint

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')

6.10. Minecraft.restoreCheckpoint

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')

6.11. Minecraft.postToChat

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!')

6.12. Minecraft.setting

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

6.13. Minecraft.player.getPos

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)

6.14. Minecraft.player.setPos

See Minecraft.player.getPos above.

6.15. Minecraft.player.getTilePos

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)

6.16. Minecraft.player.setTilePos

See Minecraft.player.getTilePos above.

6.17. Minecraft.player.setting

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

6.18. Minecraft.player.getRotation

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

6.19. Minecraft.player.getPitch

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

6.20. Minecraft.player.getDirection

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)

6.21. Minecraft.entity.getPos

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)

6.22. Minecraft.entity.setPos

See Minecraft.entity.getPos above.

6.23. Minecraft.entity.getTilePos

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)

6.24. Minecraft.entity.setTilePos

See Minecraft.entity.getTilePos above.

6.25. Minecraft.entity.getRotation

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

6.26. Minecraft.entity.getPitch

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

6.27. Minecraft.entity.getDirection

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)

6.28. Minecraft.camera.setNormal

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])

6.29. Minecraft.camera.setFollow

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])

6.30. Minecraft.camera.setFixed

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)

6.31. Minecraft.camera.setPos

See Minecraft.camera.setFixed above.

6.32. Minecraft.block.Block

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>