Sunday, 13 January 2013

Raspberry Pi - Minecraft API - the basics

Anyway, I've been exploring the API which comes with the new Pi edition of Minecraft.  See Raspberry Pi - Minecraft - Install for details on how to install Minecraft: Pi Edition.  If you want a more in-depth tutorial rather than just the basics, see my Minecraft: Pi Edition - API Tutorial post.


The API works by connecting to the 'server' which maintains the Minecraft world and issuing commands to change the world in real-time.  The api specification is included with the the game, ~/mcpi/api/mcpi_protocol_spec.txt.

The nice people at Mojang, who write Minecraft, also provide class libraries in Java and Python to simplify interactions with the game, which are in the ~/mcpi/api/[java/python] directories.

Create a directory for the program


mkdir ~/minecraft-api

Copy the python class library from minecraft to the programs directory

cp -r ~/mcpi/api/python/mcpi ~/minecraft-api/minecraft

Create minecraft-api.py python program

nano ~/minecraft-api/minecraft-api.py

or open Idle and save minecraft-api.py to the minecraft-api directory

Code

#www.stuffaboutcode.com
#Raspberry Pi, Minecraft API - the basics


#import the minecraft.py module from the minecraft directory
import minecraft.minecraft as minecraft
#import minecraft block module
import minecraft.block as block
#import time, so delays can be used
import time

if __name__ == "__main__":
    
    time.sleep(2)

    #Connect to minecraft by creating the minecraft object
    # - minecraft needs to be running and in a game
    mc = minecraft.Minecraft.create()

    #Post a message to the minecraft chat window
    mc.postToChat("Hi, Minecraft API, the basics, what can you do? ")

    time.sleep(5)

    #Find out your players position
    playerPos = mc.player.getPos()
    mc.postToChat("Find your position - its x=" + str(playerPos.x) + ", y=" + str(playerPos.y) + ", z=" + str(playerPos.z))

    time.sleep(5)

    #Using your players position
    # - the players position is an x,y,z coordinate of floats (e.g. 23.59,12.00,-45.32)
    # - in order to use the players position in other commands we need integers (e.g. 23,12,-45)
    # - so round the players position
    # - the Vec3 object is part of the minecraft class library
    playerPos = minecraft.Vec3(int(playerPos.x), int(playerPos.y), int(playerPos.z))

    #Changing your players position
    mc.postToChat("Move your player - 30 blocks UP!")
    time.sleep(2)
    mc.player.setPos(playerPos.x,playerPos.y + 30,playerPos.z)
    # - wait for you to fall!
    time.sleep(5)

    #Interacting with a block
    # - get the type block directly below you
    blockType =  mc.getBlock(playerPos.x,playerPos.y - 1,playerPos.z)
    mc.postToChat("Interact with blocks - the block below you is of type - " + str(blockType))

    time.sleep(5)

    # - change the block below you to wood planks
    mc.setBlock(playerPos.x,playerPos.y-1,playerPos.z,block.WOOD_PLANKS)
    mc.postToChat("Change blocks - the block below you is now wood planks")

    time.sleep(5)

    #Creating many blocks
    mc.postToChat("Create blocks - making a diamond tower")

    # - loop 20 times
    for up in range(0, 20):
        mc.setBlock(playerPos.x + 1, playerPos.y + up, playerPos.z, block.DIAMOND_BLOCK)

    time.sleep(2)

    # - put you on top of the tower
    mc.postToChat("Dont look down, because Im putting you on top of it!")
    time.sleep(1)
    mc.player.setPos(playerPos.x + 1, playerPos.y + 20, playerPos.z)

    time.sleep(5)

    mc.postToChat("www.stuffaboutcode.com")

The complete code repository is also on githubhttps://github.com/martinohanlon/minecraft-api.git.

Run 
Note - minecraft must be running and you must be in a game

python ~/minecraft-api/minecraft-api.py

or if using Idle, click Run Module

Performance (on pre-release 0.1)
If you are using the pre-release (version 0.1) of Minecraft you will probably notice that the performance of the API is pretty slow, one of the key reasons for this is that the connection module supplied by mojang, prints the commands sent to the server, which is really useful for debugging but VERY slow - you can turn this off by modifying the connection.py module.

nano ~/minecraft-api/minecraft/connection.py

Change the send function and comment out the 2 print statements, so it looks like this:

    def send(self, f, *data):
        """Sends data. Note that a trailing newline '\n' is added here"""
        s = "%s(%s)\n"%(f, flatten_parameters(data))
        #print "f,data:",f,data
        #print "s",s
        self.drain()
        self.lastSent = s
        self.socket.sendall(s)


Check out my minecraft posts, such as a game of Hide and Seek in Minecraft, an Auto Bridge, no matter where you walk a bridge will always be under your feet or a Massive Analogue Clock, big enough so you can walk on the arms.

63 comments:

  1. Great post on the API. Just got hold of the leaked version myself, so should be interesting to see what you can do with it so far!

    ReplyDelete
  2. Really nice article, Martin. I used it as inspiration to get going on a Ruby version of the API.

    I've just released a first cut of a ruby API for the minecraft raspberry pi. Please check it out, report issues and contribute! :-)

    https://github.com/nhajratw/minecraft_api

    ReplyDelete
  3. It looks like in 0.1.1 they have commented out the 2 print commands already on connection.py.
    I went in to do it hoping for a bit more performance to find they were already done.

    Glad I didn't use it before this was done.

    ReplyDelete
  4. I made bindings for Smalltalk. And a rainbow - different from yours, but you gave me the idea :)

    http://croquetweak.blogspot.com/2013/02/smalltalk-bindings-for-minecraft-pi.html

    ReplyDelete
  5. Hi, I was wondering if there was an official documentation for the MC api? Thanks and keep up the great work!

    ReplyDelete
    Replies
    1. There is some basic documentation installed alongside MCPi. Take a look in the ~/mcpi/api directory they is a file called mcpi_protocol_spec.txt

      Delete
  6. Hi ive been having problems using the API, I wrote a program with python to light an led based on what type of block is underneath the player but i have been unable to get it to run everytime i run it python gives me an error that says no module named minecraft.minecraft ... what do i have to do to install the module ? Thanks.

    ReplyDelete
    Replies
    1. Have you copied the python api class library from the mcpi directory to your programs directory?

      If you have installed minecraft pi edition at ~/mcpi, you could use the following command

      cp -r ~/mcpi/api/python/mcpi ~/yourProgramsDirectory/minecraft

      Delete
    2. Are you by chance using Python 3 (or IDLE 3)? If so switch to python 2 (or just IDLE)

      Delete
    3. Your problem is that you wrote
      minecraft.minecraft.create() instead of
      minecraft.Minecraft.create ()

      Delete
  7. Just a question:
    When I try to start minecraft-pi, the message
    "file or directory not found" appears

    I have Linux (uname -a)
    Linux raspberrypi 3.2.27+ #250 PREEMPT Thu Oct 18 19:03:02 BST 2012 armv6l GNU/Linux

    and saw, that file minecraft-pi shows
    file minecraft-pi
    minecraft-pi: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.26, BuildID[sha1]=0x7f5a7cece83092451a55d83790b260ab639e59e9, stripped

    is it because mincraft-pi is compiled against Linux 2.6.26 ?

    (I have OpenJDK RTE 1.7.0_03)
    Any help is appricated. Thanks in advance.
    /PiT

    ReplyDelete
    Replies
    1. Oh yeah, you don't type raspberry-pi. I used to do that. Okay, first you have to decompress it. You can right-click the zip and click extract here. Then you do run "cd mcpi" (no apostrophes), and then you type ./minecraft-api. (No period at the end)

      Delete
    2. It might be that you wrote
      minecraft.minecraft.create() instead of
      minecraft.Minecraft.create ()

      Delete
  8. Okay, I did exactly what you said here. I tried reseting it, everything. Here is the error I get:

    Traceback (most recent call last):
    File '/home/pi/minecraft-api/minecraft-api.py', line 1, in
    import minecraft.minecraft as minecraft
    File '/home/pi/minecraft-api/minecraft/minecraft.py', line 1 in
    from connection import Connection
    ImportError: No module named connection

    And this is the code I have in my minecraft-api.py:

    import minecraft.minecraft as minecraft
    import minecraft.block as block
    import time
    if __name__ == "__main__":

    time.sleep(2)
    mc = minecraft.Minecraft.create()
    mc.postToChat("This is a test")
    time.sleep(5)

    ReplyDelete
    Replies
    1. Its sounds like you are missing some files, connection.py at least from the minecraft python api library. You should have a directory in your minecraft-api directory called minecraft, this is the python api library and it should have been copied from the minecraft game directory mcpi/api/python/mcpi. You need all the files from this directory as they are all used to interact with minecraft.

      Delete
    2. Hmm... I have a file in my home folder called "minecraft-api" (no apostrophes), and in it is a folder called minecraft. Also in the minecraft-api folder there is a python file called minecraft-api.py. Inside the minecraft folder there are the copied libraries, the ones I copied when I ran the "cp -r mcpi/python/api/mcpi minecraft-api/minecraft". Don't understand whats wrong.

      Delete
    3. Oh yeah, I also tried to re-install minecraft pi, including the hidden .minecraft folder. Still didn't work. Even reset my Pi. Doesn't work for some reason.

      Delete
    4. Im pretty sure you are getting an error because you are missing files or at least the connection.py file from the minecraft directory in your minecraft-api directory. Have a look in the minecraft-api/minecraft directory it should have all the files that appear in the mcpi/api/python/mcpi directory. I.e. they should have all the same files.

      Delete
    5. Okay, I'll do that. But I was wondering, do the files change when Minecraft Pi is running? Cause I wanna check the files on my computer, see if they match.

      Delete
    6. The mcpi python files are the same as the ones in my minecraft-api/minecraft folder. Except, there seems to be a __pycache__ folder in my minecraft-api/minecraft folder. Wonder what that does.

      Delete
    7. The pycache file is nothing to worry about. I am out of ideas. I would recommend you start again, create a new directory for your program minecraft-api2 maybe and copy the python library again.

      Delete
    8. Yeah, I'm out of ideas too... I'll just have to try again until it works.

      Delete
    9. This comment has been removed by the author.

      Delete
    10. Whoops, there is a : right after the while line.

      Delete
    11. I finally worked out why you originally had problems... I found out by mistake, when I accidentally used IDLE 3 and python 3, rather than python 2 and IDLE.

      It seems there is some incompatibility, I'll work out what it is one day!

      Delete
  9. I'm getting the same 'No module named connection' error after updating from the prerelease version. All the files seam to in place. I will try to do some debugging later.

    ReplyDelete
    Replies
    1. I'm guessing that there is a bug with the newest version. I hope they fix it.

      Delete
    2. Josh - I think you are experiencing this problem due to using python 3 (i.e. IDLE 3) rather than python 2 (i.e. IDLE).

      Delete
    3. That makes sense. I was using Idle, and when I switched to a different text editor it worked again.

      Delete
    4. Hey, are you still going to take a video of my program? It's okay if you can't, I think I might be able to do it myself. :)

      Delete
    5. I will, it might be a next week though, busy times. Get a video done though, get it on youtube, stick a link on MCPI or Raspberry PI sub-reddit's on reddit.com. See what people think.

      Delete
    6. Oh, well then that's okay. Thanks anyway!

      Delete
  10. Its definetly not a bug with minecraft, its works fine on my pi. If you can zip up your code directory and send it to me ill happily debug and test

    ReplyDelete
    Replies
    1. Sure, I'll do that. Mind if I got your email to send the file to, or do you want to use some other way?

      Delete
    2. Got it all zipped up. I included the minecraft-api folder and the mcpi folder.

      Delete
    3. Okay, here is the .zip file:
      http://pancake.io/1371/minecraft-pi-files.zip

      Delete
    4. Ok, well your code looks ok and everything looks like its in the right structure, I cant test it right now as Im on holiday and dont have a pi with me, but I'll test it when I get home.

      In the mean time, Im wonder whether it might be security issue, i.e. your program doesnt have permission to read the minecraft directory, this might be the case if you installed minecraft using sudo.

      So either try running your minecraft-api program as sudo, i.e. sudo python minecraft-api.py or run chown against your -minecraft-api directory changing all files ownership to your user (probably pi) i.e. cd minecraft-api then sudo chown -R pi *

      Delete
    5. Whoa. All of a sudden, it works again. Maybe these are the two reasons why:
      I had my internet off. Plugged it in.
      Did the cp command while minecraft was running.

      Delete
    6. Maybe cause I ran sudo this time. Though I don't remember making the file or directory with root...

      Delete
    7. Can you have a go and see whether its the need for network connection or sudo to make it work?

      Delete
    8. I really can't tell what the problem was. Sorry. Maybe though it was doing the cp command while minecraft was running.

      The reason I haven't responded before is because I have been very busy making a program. It is really cool. It is an arena. First, it generates the arena. Next, it places you into it. Then, blocks on the floor of the arena start disappearing and you have to try not to fall. If you do fall, it will teleport you onto a platform and displays your score.
      Mind if you take a video of my program? I don't know how to screen video on Raspberry Pi.

      Delete
    9. It sounds really good, great concept as well, I love a game in a game. Happy to record it for you, but I dont do anything hitech I just put a camera on a tripod in front of the screen. If you've got a digi camera just mount it on something, a book a box anything and just record.

      Mind if I write about it on stuffaboutcode

      Delete
    10. I wouldn't mind if you wrote about it at all! :D
      I have been adding on to it, so it's more like a 5-in-one program. Two games in it, too. I'll get the link for the file soon.

      Wow, you use a camera for that? It really looked like a screencast. :)

      Delete
    11. Okay, here is the latest version of my program:
      http://1371.pancakeapps.com/api.py
      However, the dodgegame is not entirely complete. I only made it yesterday. But it does work, there are just a few extra features I wanted to add to it.

      Thanks!

      Delete
    12. Hi Nicolas,
      I hope you did not mind me trying out your code. I got an interesting error. In your line 6 you are getting the PlayerEntityIds; however minecraft.py gives me (in line 151) following error:
      ValueError: invalid literal for int() with base 10: ''
      Have tried to solve it with changing int into float or eval but no luck. Did you get this error too?

      Delete
    13. Hi me again,
      Solved it by making your line 6 a comment line (#). Turned out you are not using the variable allPlayers anyway.
      Arena game is really nice. Good graphs. Only on first try I put myself in one corner and it took until 192 to fall. So GOLD right away. :-)
      Horse if funny! Rest I did not try yet.
      Well done!!

      Delete
    14. Yeah, I was going to use that so I can control PE players. Didn't work, and I had forgotten to remove it. And I don't mind you using the code at all! Just to let people know, you do have to delete the allPlayers variable. I kinda had to erase some of the testing stuff that didn't work (I don't delete the parts the don't work, even when I don't try and fix 'em), and I added a few things. I just didn't test anything.

      BTW, you can do /help for all the commands.

      Delete
    15. Okay, I updated the file. The program works fine now!
      Oh yeah, you can also use the program to chat. Just type in something besides a command, and it will display it on Minecraft Pi.

      Delete
    16. Just updated it again. Do /? or /help for the newest commands.

      Delete
    17. Hi Nicholas, sorry its take me a while but I got round to looking at your program, very impressive, Ive video'd it and its uploading to youtube as we speak - plus a blog post at http://www.stuffaboutcode.com/2013/05/minecraft-pi-edition-2-games-by.html

      Delete
  11. I am going to try and build Something which will be HUGE!!!! but i have no idea of how to do it... ._. can you please make a video that explains how to install, run...ETC.
    Thank you and i believe that it is a job well done!!!

    ReplyDelete
    Replies
    1. Im a bit short on time to make a video right now ill pit it on the list to do though.
      In the meantime you might find this post useful which has install instructions and a walk through on how to get started.

      http://www.stuffaboutcode.com/2013/04/minecraft-pi-edition-api-tutorial.html

      Delete
  12. I am having problem to run minecraft-api.py. I receiving an error: Socket error in
    line mc = minecraft.Minecraft.create()

    I run server on the same rasberry-pi. and it is in game. But i having connection error.
    May be I should use other server then on rasberry pi?

    ReplyDelete
    Replies
    1. Hi, your getting the error because your program cant connect to minecraft. When you say you are running the server, do you mean minecraft pi edition? Or are you running a full minecraft server? You need to start up minecraft pi edition, go into a game and then run your program. It doesnt matter that they are running on the same pi.

      Delete
  13. I am being lazy by asking, but can I use what you are here with the Minecraft server here http://www.instructables.com/id/Raspberry-Pi-Minecraft-Server/?ALLSTEPS

    ReplyDelete
    Replies
    1. You can, but you will need to install the bukkit plugin 'raspberry juice'. Check out my 'recipe' for creating a raspberry pi minecraft server.

      Delete
  14. Just a question... Why do you have to write
    if __name__=__main__:???
    because i never write this and my scripts work fine!

    ReplyDelete
    Replies
    1. You don't have to write it, particularly in a script just for yourself. But it serves two purposes: For one, it indicates to the reader where the "main" routine actually starts. Secondly, if you define functions in your file, this lets you include the file from another one without having the "main" part execute, so you only get the function definitions.

      Delete
  15. Hello all. Total noob here. My son and i have been trying the real basics of tutorial but we get stuck pretty early on.

    Keep getting:

    AttributeError: 'module' object has no attribute 'minecraft'

    We're inputting

    import minecraft as minecraft
    mc = minecraft.minecraft.creat()
    mc.postToChat ("Hello Minecraft!")
    import minecraft as minecraft

    Our Python program file is in the correct directroy (minecraft.magpi) and minecraft is running.

    ReplyDelete
    Replies
    1. Could it be:

      mc = minecraft.minecraft.creat()

      should be:

      mc = minecraft.Minecraft.create()

      Note the capital M (python is case sensitive so upper and lower case letters make a difference and the missing e from create

      Delete