First Time Linux

Playing with Minecraft

You've probably already heard of Minecraft, a hugely popular pixellated world-building game available on many platforms. It's a creative game, either single-player or multi-player, where you can place blocks in a virtual world and roam around to explore what you and others have built.

With the Raspberry Pi version of this game, there are a few twists. On the positive side, it doesn't cost any money, and it's a simple install from the Raspbian repositories. On the negative side, it's a reduced version which can't do as much as the full-price versions. But on the other positive side, it comes with a way to programmatically interact with the world using a Python API, which allows you to do super-cool things from the command line.

Our starting point is the excellent set of instructions called "Getting Started with Minecraft Pi". For those who find a pdf easier to read than a javascript-intensive click-through, there's another version at setbc.org.

There's not much to explain about installing minecraft, you just get it from the repositories with sudo aptitude install minecraft-pi and that's it. And it can be launched, unsurprisingly, from the "Games" menu, bringing the entry menu shown in this screenshot.

The window which Minecraft appears in is an odd beast - the title bar and controls are offset and partially hidden (making it rather difficult to reposition the window) and making screenshots with scrot just gives black rectangles.

It's possible to maximize the window by clicking the control near the top right of the window, but this isn't without its issues - exploring and viewing works ok with the mouse but for example you can't select any items on the right side of the inventory screen when the window is maximized, it seems the coordinate bounding rectangle is wrong.

OK, but we didn't want to run Minecraft on the pi just so that we could run around and look in different directions, right? We came here to play with python, right? So then you've got a couple of choices - either run a python console on the pi, on the same screen as the Minecraft window, or run it on a separate computer connected via ssh. The guide above recommends side-by-side windows on the pi, but I found having a python console on the netbook far preferable - then one person can explore the world with keyboard and mouse on the pi, and another person can try things in the python shell.

After connecting via ssh, we launch python3 on the pi, and then in the interactive shell we can do things like:

from mcpi.minecraft import Minecraft
mc = Minecraft.create()
mc.postToChat("Hello, minecraft!")

x,y,z = mc.player.getPos()
from mcpi import block
mc.setBlock(x+1, y-1, z, block.GOLD_ORE.id)

This object mc is the object we use to interact with the running Minecraft world. As well as posting a message on the screen to test that it works, we can get the player position in (x,y,z) coordinates, and we can place a block of GOLD_ORE next to the player's feet. Note that x and z are horizontal directions, and y is the vertical, so "y-1" places the new block below the player, and "x+1" brings it to one side. This doesn't mean to the player's left or right though, the positive x and z directions are fixed in the world no matter in which direction the player is facing.

Creating terrain programmatically

As well as the setBlock method to set a single block, there is also a setBlocks method to set a cuboid range of blocks, and this is explained in the guide above. One of the block types is TNT, and with an extra "data" value of 1, this becomes explosive. I'd really recommend only trying out single blocks of TNT though, as detonating multiple of blocks of TNT can really cause damage, both to the surrounding constructions and to the responsiveness of the pi as it tries to figure out all the exploding, flying and spinning bits of debris.

Another problem with explosions is that it's all too easy to blow holes through the lowest layers of the world, and stepping into these leads to you falling through empty space. And filling in these holes again can be rather tedious, unless you use another setBlocks to make a new floor.

Now it would be nice to go beyond single method calls, and build some more impressive terrain. One possible starting point would be building pyramids with a loop, making the square levels of the pyramid one by one. If we make this into a function, we can call it several times with different materials, for example:

def makePyramid(size, blockId):
    x,y,z = mc.player.getPos()
    for d in range(size):
        mc.setBlocks(x+11-d, y-6-d, z-d, x+11+d, y-6-d, z+d, blockId)

This uses the player's current position, and goes 11 spaces in the positive x direction and 6 spaces vertically down to position the tip of the pyramid. Then it uses the size parameter to define the number of levels, and the blockId parameter to define the block type. Then you can jump to a suitable position in the air, and call the function like this:

makePyramid(6, block.GOLD_ORE.id)

Re-creating terrain

Another idea to try is to recreate real-world terrain in the pixellated Minecraft world. I took a grid of real altitude data from a nearby mountain range (using NASA's SRTM dataset) and converted it to a csv file of pixel coordinates. Then I read in this file with python and used the setBlocks method to create the landscape with grass-covered blocks.

This needs a fair bit of experimentation with the scaling to give a reasonable (horizontal and vertical) size to the features. But the results didn't end up as recognisable as I'd hoped, mainly due to the limited visibility in the Minecraft world.

It would certainly help to use different block types such as water, stone and brick to note features like lakes, cliffs and buildings, but extracting these features programmatically is a bit more difficult.

Lava & water

The guide also suggests pouring lava from the sky onto terrain, and then pouring water on top. It's fun to experiment with, for sure, but I'm still not sure what happens to all the water!

Further ideas

There was an advent calendar advertised recently which explored precisely this subject, with a different task to try out each day. The physical things included in the calendar weren't particularly special, mostly just LEDs, resistors and connecting wires, but the ideas were interesting. They extend the suggestions in the "Getting Started" guide by connecting the Minecraft world to the real world:

There's clearly a whole load of experimentation possible with the interaction of python and Minecraft, programmind and exploring, the real world and the virtual world. There may be some issues with the pi edition of Minecraft but as long as you don't expect it to have the same features (or performance!) as the other versions, then there's plenty to do and try out and explore.

I would also hope that for kids who are already enthusiastic about Minecraft, this extra dimension of programming might open their eyes to how useful being able to code might be. This applicability and relevance may just be the spark which triggers an interest in programming, who knows.