.. _conversion: ==================== Conversion from mcpi ==================== If you have existing scripts that use the reference implementation (minecraft-pi aka mcpi), and you wish to convert them to using the picraft library, this section contains details and examples covering equivalent functionality between the libraries. Minecraft.create ================ Equivalent: :class:`~picraft.world.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) Minecraft.getBlock ================== See :ref:`Minecraft.getBlockWithData` below. .. _Minecraft.getBlockWithData: Minecraft.getBlockWithData ========================== Equivalent: :attr:`~picraft.world.World.blocks` Accessing the id of a block is rather different. 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 :class:`~picraft.vector.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)] The id and data can be extracted from the :class:`~picraft.block.Block` tuple that is returned:: >>> w.blocks[Vector(0, -1, 0)].id 2 >>> w.blocks[Vector(0, -1, 0)].data 0 Minecraft.setBlock ================== Equivalent: :attr:`~picraft.world.World.blocks` Setting the id (and optionally data) of a block is also rather different. In picraft the same attribute is used as for accessing block ids; just *assign* a :class:`~picraft.block.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)] >>> w.blocks[Vector(0, -1, 0)] = Block(1, 0) Minecraft.setBlocks =================== Equivalent: :attr:`~picraft.world.World.blocks` Again, the same attribute as for ``setBlock`` is used for ``setBlocks``; just pass a slice of :class:`vectors ` instead of a single vector (the example below shows an easy method of generating such a slice by adding two vectors together 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() >>> v = Vector(0, -1, 0) >>> w.blocks[v] >>> w.blocks[v:v + Vector(1, 7, 1)] = Block(1, 0) Minecraft.getHeight =================== Equivalent: :attr:`~picraft.world.World.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) Minecraft.getPlayerEntityIds ============================ Equivalent: :attr:`~picraft.world.World.players` The connected player's entity ids can be retrieved by iterating over the :attr:`~picraft.world.World.players` attribute which acts as a mapping from player id to :class:`~picraft.player.Player` instances:: >>> import mcpi.minecraft as minecraft >>> mc = minecraft.Minecraft.create() >>> mc.getPlayerEntityIds() [1] >>> from picraft import World >>> w = World() >>> list(w.players) [1] Minecraft.saveCheckpoint ======================== Equivalent: :meth:`~picraft.world.Checkpoint.save` Checkpoints can be saved in a couple of ways with picraft. Either you can explicitly call the :meth:`~picraft.world.Checkpoint.save` method, or you can use the :attr:`~picraft.world.World.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') Minecraft.restoreCheckpoint =========================== Equivalent: :meth:`~picraft.world.Checkpoint.restore` As with saving a checkpoint, either you can call :meth:`~picraft.world.Checkpoint.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') Minecraft.postToChat ==================== Equivalent: :meth:`~picraft.world.World.say` The ``postToChat`` method is simply replaced with the :meth:`~picraft.world.World.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!') Minecraft.setting ================= Equivalent: :attr:`~picraft.world.World.immutable` and :attr:`~picraft.world.World.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 .. _Minecraft.player.getPos: Minecraft.player.getPos ======================= Equivalent: :attr:`~picraft.player.HostPlayer.pos` The ``player.getPos`` and ``player.setPos`` methods are replaced with the :attr:`~picraft.player.HostPlayer.pos` attribute which returns a :class:`~picraft.vector.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 relatively to their current one becomes simple:: >>> w.player.pos += Vector(y=20) Minecraft.player.setPos ======================= See :ref:`Minecraft.player.getPos` above. .. _Minecraft.player.getTilePos: Minecraft.player.getTilePos =========================== Equivalent: :attr:`~picraft.player.HostPlayer.tile_pos` The ``player.getTilePos`` and ``player.setTilePos`` methods are replaced with the :attr:`~picraft.player.HostPlayer.tile_pos` attribute which returns a :class:`~picraft.vector.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) Minecraft.player.setTilePos =========================== See :ref:`Minecraft.player.getTilePos` above. Minecraft.player.setting ======================== Equivalent: :attr:`~picraft.player.HostPlayer.autojump` The ``player.setting`` method is replaced with the write-only :attr:`~picraft.player.HostPlayer.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 Minecraft.player.getRotation ============================ Equivalent: :attr:`~picraft.player.HostPlayer.heading` The ``player.getRotation`` method is replaced with the read-only :attr:`~picraft.player.HostPlayer.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 Minecraft.player.getPitch ========================= Equivalent: :attr:`~picraft.player.HostPlayer.pitch` The ``player.getPitch`` method is replaced with the read-only :attr:`~picraft.player.HostPlayer.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 Minecraft.player.getDirection ============================= Equivalent: :attr:`~picraft.player.HostPlayer.direction` The ``player.getDuration`` method is replaced with the read-only :attr:`~picraft.player.HostPlayer.duration` 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) .. _Minecraft.entity.getPos: Minecraft.entity.getPos ======================= Equivalent: :attr:`~picraft.player.Player.pos` The ``entity.getPos`` and ``entity.setPos`` methods are replaced with the :attr:`~picraft.player.Player.pos` attribute. Access the relevant :class:`~picraft.player.Player` instance by indexing the :attr:`~picraft.world.World.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) Minecraft.entity.setPos ======================= See :ref:`Minecraft.entity.getPos` above. .. _Minecraft.entity.getTilePos: Minecraft.entity.getTilePos =========================== Equivalent: :attr:`~picraft.player.Player.tile_pos` The ``entity.getTilePos`` and ``entity.setTilePos`` methods are replaced with the :attr:`~picraft.player.Player.tile_pos` attribute. Access the relevant :class:`~picraft.player.Player` instance by indexing the :attr:`~picraft.world.World.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) Minecraft.entity.setTilePos =========================== See :ref:`Minecraft.entity.getTilePos` above. Minecraft.entity.getRotation ============================ Equivalent: :attr:`~picraft.player.Player.heading` The ``entity.getRotation`` method is replaced with the read-only :attr:`~picraft.player.Player.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 Minecraft.entity.getPitch ========================= Equivalent: :attr:`~picraft.player.Player.pitch` The ``entity.getPitch`` method is replaced with the read-only :attr:`~picraft.player.Player.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 Minecraft.entity.getDirection ============================= Equivalent: :attr:`~picraft.player.Player.direction` The ``entity.getDuration`` method is replaced with the read-only :attr:`~picraft.player.Player.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) Minecraft.camera.setNormal ========================== Equivalent: :meth:`~picraft.world.Camera.first_person` The :attr:`~picraft.world.World.camera` attribute in picraft holds a :class:`~picraft.world.Camera` instance which controls the camera in the Minecraft world. The :meth:`~picraft.world.Camera.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 :attr:`~picraft.world.World.player` attribute, or as a player retrieved from the :attr:`~picraft.world.World.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]) Minecraft.camera.setFollow ========================== Equivalent: :meth:`~picraft.world.Camera.third_person` The :attr:`~picraft.world.World.camera` attribute in picraft holds a :class:`~picraft.world.Camera` instance which controls the camera in the Minecraft world. The :meth:`~picraft.world.Camera.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 :attr:`~picraft.world.World.player` attribute, or as a player retrieved from the :attr:`~picraft.world.World.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]) .. _Minecraft.camera.setFixed: Minecraft.camera.setFixed ========================= Equivalent: :attr:`~picraft.world.Camera.pos` The :attr:`~picraft.world.Camera.pos` attribute can be passed a :class:`~picraft.vector.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) Minecraft.camera.setPos ======================= See :ref:`Minecraft.camera.setFixed` above. Minecraft.block.Block ===================== Equivalent: :class:`~picraft.block.Block` The :class:`~picraft.block.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 :class:`~picraft.block.Block` class also provides several means of construction, and additional properties:: >>> from picraft import Block >>> Block(1, 0) >>> Block(35, 1) >>> Block.from_name('wool', data=1).description u'Orange Wool' >>> Block.from_color('#ffffff').description u'White Wool'