Hacking Minecraft on the Raspberry Pi
The Raspberry Pi 2 is a surprisingly capable device, considering its sub-£30 price. It comes with a version of Minecraft preinstalled, along with an API that lets you write code to be run in the virtual world. You do this in Python, which is simple to learn. The combination of the Pi, Python and Minecraft provides a great opportunity to start exploring the possibilities of programming. And the thrill of seeing a house build itself on a virtual landscape isn’t just for kids, either.
Scripting in Minecraft
Minecraft is an open sandbox game that doesn’t have a plot line to follow. It’s sometimes described as “virtual Lego”, as the player can build any kind of structure using the blocks at their disposal. The version bundled with the Raspberry Pi has a limited feature set suited to its educational role – so you don’t need to worry about being chased by zombies, for example. Interacting with this world requires no special setup, only a recent build of the Raspbian OS plus a programming environment. I’d opt for Geany, which you can install by opening up LXTerminal and typing:
sudo apt-get install geany
Let’s start by creating a script for building a house in front of the player – but rather than just slapping one into place, we’re going to animate it. We’re also going to build in various configurable settings, which will allow the player to experiment with different dimensions and materials. This will also make the program modular, so it can be used as the basis for creating more sophisticated wellings.
To make the code work, load it into Geany then start Minecraft and create a new world. Press the Tab key to release the cursor from the Minecraft window and click the cog icon in Geany (or press F5) to launch the script. You should see a house magically assemble itself. If you don’t, try turning around – it might be behind you! You can see the script in action here. So how does the script work? Well, first it opens a link to Minecraft:
import mcpi.minecraft as minecraft, time mc=minecraft.Minecraft.create()
In Python, it’s important to pay attention to indentation, since that’s how code is divided into blocks. In this case, both lines are flush with the left-hand margin: the first line imports the Minecraft and Time libraries and the second creates a Minecraft object for us to use throughout. The next 25 lines set a few variables for the blocks we’re going to use so we can refer to them as, say, wood_planks rather than by their block ID (5, in this case). We then indicate which of these blocks will be used for the walls, which for the roof and so on. We can easily change the construction of the house completely by swapping brick walls for cobblestone, for example. Finally, we set the width, length and height of our desired dwelling.
We now call the Minecraft function mc.player.getTilePos() to locate the player in the landscape, and the values that come back are then used to create two variables, left and bottom, to describe where the first corner of the dwelling will be.
Thereafter, the structure of the script matches the Minecraft process of “manually” building a house. We begin by clearing a space so that if the player chooses to build the house inside, say, a mountain, the living area won’t be solid stone. Here’s the block of code – the function in Python – that does this:
When we call clear_house, we pass in the parameter nuclear. It has the value True or False. You can try calling it with True to clear a larger volume around the target area, or call it with False to confine clearance to the internal dimensions of the house. In Minecraft, the mc.setBlocks function is used to create a cube of blocks by passing it the co-ordinates, in three dimensions, of opposite corners followed by the block type you wish to use. In this instance we’re clearing a space, so we use air.
Once we’ve cleared the space it’s time to move on to construction. Each of these construction stages takes place in its own function. At the end of the script, you’ll see a function called main(), which controls the program flow by calling each phase of construction in turn. By naming our functions sensibly and calling them from main(), it’s easy to understand what the program is doing:
The next function called in main() builds the floor – this uses mc. setBlocks again to carve out a foundation (for artistic effect) and then add a cube of floor tiles with a depth of one block to create a solid floor in our house.
Building the walls
The build_walls function is the heart of the program. The most efficient way to create the shell of a house would be to slap down a solid cube of bricks and then use clear_house to carve out the interior. However, we want the house to appear to construct itself, so we need to place blocks individually, one after the other. Here’s a simplified version of the wall-building code:
def build_course(start_pos, direction,
if direction==”up” or
blocks=blocks+1 # move onto the next block
We begin by storing the starting position – this will be the position of the last block laid from the previous course of blocks. We then specify how many blocks to lay, depending on whether we’re going along the length of the building or its width.
The building phase is contained within the while block – this continues to run until we have laid all the blocks. mc.setBlock places a single block at the co-ordinates shown, then increments one of those co-ordinates depending on the direction in which we’re laying. The effect is that blocks are laid along a wall before turning a corner and continuing in a rectangle until the course is completed.
The final version of the code is a little more involved, adding windows to each wall. The windows are dynamically sized so that they’re half the length of the wall and centred. It also records the position for the door; it’s added once the walls are built. Courses are controlled from the build_walls function, which repeats the build_course function for each course of blocks until it reaches the final height.
You could even try building your house in the ocean or in the air – do this by double-pressing the spacebar to fly, then press again to raise yourself before running the script. Alter the wall_block and roof_block variables to see what happens if you create the walls or roof out of gold or, indeed, lava. You can add your own blocks by consulting the full list here, and adding the associated variable to the script. More challenging modifications might include adding multiple storeys to the structure if the height variable is set to a large enough value. Work out how to add turrets, for example, and you have the makings of a Minecraft castle.
These tweaks might sound trivial, but I’ve been programming professionally for more than 20 years and I still get a thrill when a snippet of code works as intended. If you’ve never programmed before, I hope you’ll give it a go – and if you have a Minecraft fan in the household, I suggest letting them loose on the code and seeing where it takes them. You’ll find links to Minecraft Pi resources at kevpartner.co.uk/programming.