Programming Minecraft Pi edition using the Python API

This post will give a very quick introduction to programming the special edition of Minecraft for the Raspberry Pi using the Python API. It will be a very short post, covering the very basics, since the topic has been covered well elsewhere.

First, you need a Raspberry Pi running Minecraft Pi Edition. Follow the instructions on that site to get the game itself up and running. The game itself is rather unremarkable – it is a cut down version of the pocket edition. What makes it interesting is the fact that it has an API, and this API can be a good way to illustrate some basic programming concepts to kids. My kids are now quite interested in writing games in Scratch, I think because you can do interesting stuff on screen with very little code. But I’ve struggled to get them excited about Python, and other “real” programming languages, I think because the start-up costs are much higher. The Minecraft Pi API also allows you to build stuff on screen with very little Python code, so I’m hoping that this will turn out to be a good way to get kids interesting in real programming languages.

Once the game is running, hit Escape to get your mouse pointer back and run a terminal. If you’ve just unpacked the game in your home directory, the Python API won’t be in the system Python path, so you’ll need to add it using a command like:

export PYTHONPATH=/home/pi/mcpi/api/python/mcpi

though this may need editing depending on the location of your copy of minecraft. You may want to add this to your .profile or .bashrc so that you don’t have to re-enter it. Once the path is set correctly, just run python from the command prompt, and start interacting. The following session should get you started:

import minecraft
import block
import math

mc=minecraft.Minecraft.create()

mc.postToChat("Hello")
mc.setBlock(10,10,10,block.STONE)

Then fly to (10,10,10) to check to see if there’s a stone block there.

Once that’s all working, there’s loads of stuff on-line that I don’t want to repeat here – start with Minecraft API basics, or dive in at MCPIPY.

I’ll just record here a few functions I’ve found useful for building stuff. First, drawing a circle. When I first learned to program as a kid, I did this by drawing a regular n-sided polygon for large n. However, that’s fairly unsatisfactory for various reasons. It occurs to me that it makes more sense to trace out the first one eighth of a circle pixel by pixel using Pythagoras, and then fill in the other 7 eighths via symmetry. I guess this is Computer Graphics 101, but I’ve never studied graphics… Anyway, a function that seems to work OK is below:

def circle(cx,cy,cz,r,b):
  x=r
  y=0
  while (x>=y):
    mc.setBlock(cx+x,cy,cz+y,b)
    mc.setBlock(cx+x,cy,cz-y,b)
    mc.setBlock(cx-x,cy,cz+y,b)
    mc.setBlock(cx-x,cy,cz-y,b)
    mc.setBlock(cx+y,cy,cz+x,b)
    mc.setBlock(cx+y,cy,cz-x,b)
    mc.setBlock(cx-y,cy,cz+x,b)
    mc.setBlock(cx-y,cy,cz-x,b)
    y=y+1
    x=int(round(math.sqrt(r*r-y*y)))

Once you have a way of drawing circles, cylinders are easy:

def cylinder(cx,cy,cz,r,h,b):
  if (h>0):
    circle(cx,cy,cz,r,b)
    cylinder(cx,cy+1,cz,r,h-1,b)

Note that I’ve expressed this recursively rather than as an iteration, just because. It turns out that cylinders are useful for building castle turrets… Speaking of recursion, a straightforward function to draw a Menger sponge is:

def menger(x,y,z,l):
  if (l==0):
    mc.setBlock(x,y,z,block.STONE)
  else:
    s=3**(l-1)
    menger(x+0*s,y+0*s,z+0*s,l-1)
    menger(x+0*s,y+0*s,z+1*s,l-1)
    menger(x+0*s,y+0*s,z+2*s,l-1)
    menger(x+0*s,y+1*s,z+0*s,l-1)
    #menger(x+0*s,y+1*s,z+1*s,l-1)
    menger(x+0*s,y+1*s,z+2*s,l-1)
    menger(x+0*s,y+2*s,z+0*s,l-1)
    menger(x+0*s,y+2*s,z+1*s,l-1)
    menger(x+0*s,y+2*s,z+2*s,l-1)
    menger(x+1*s,y+0*s,z+0*s,l-1)
    #menger(x+1*s,y+0*s,z+1*s,l-1)
    menger(x+1*s,y+0*s,z+2*s,l-1)
    #menger(x+1*s,y+1*s,z+0*s,l-1)
    #menger(x+1*s,y+1*s,z+1*s,l-1)
    #menger(x+1*s,y+1*s,z+2*s,l-1)
    menger(x+1*s,y+2*s,z+0*s,l-1)
    #menger(x+1*s,y+2*s,z+1*s,l-1)
    menger(x+1*s,y+2*s,z+2*s,l-1)
    menger(x+2*s,y+0*s,z+0*s,l-1)
    menger(x+2*s,y+0*s,z+1*s,l-1)
    menger(x+2*s,y+0*s,z+2*s,l-1)
    menger(x+2*s,y+1*s,z+0*s,l-1)
    #menger(x+2*s,y+1*s,z+1*s,l-1)
    menger(x+2*s,y+1*s,z+2*s,l-1)
    menger(x+2*s,y+2*s,z+0*s,l-1)
    menger(x+2*s,y+2*s,z+1*s,l-1)
    menger(x+2*s,y+2*s,z+2*s,l-1)

So drawing M3 at (10,10,10) can be done with:

menger(10,10,10,3)

I know that other people wrote code for this as soon as the API was released, but I haven’t looked to see how their code compares to mine. In any case, this isn’t code golf – I could have written the function much more succinctly – I was trying to write it in a simple pedagogic style here, explicitly enumerating the 20 component blocks and commenting out the 7 “missing” blocks… Note that M3 is 27x27x27 blocks, which is a good size for Minecraft on the Pi. Generating M4 actually runs OK, though it takes a while. But this is 81x81x81, which is a struggle for Minecraft Pi to render satisfactorily.

Advertisements

Published by

darrenjw

I am Professor of Stochastic Modelling within the School of Mathematics & Statistics at Newcastle University, UK. I am also a computational systems biologist.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s