Skip to content

Instantly share code, notes, and snippets.

@switzersc
Last active January 14, 2020 23:28
Show Gist options
  • Save switzersc/60eab75a45022c801200 to your computer and use it in GitHub Desktop.
Save switzersc/60eab75a45022c801200 to your computer and use it in GitHub Desktop.
Connecting Minecraft Pi to the World

Intro

We (some engineers at Notion) recently led a kids activity at a Google Developer event, and we wanted to connect IoT devices (specifically Notion sensors) to a Minecraft server running on a Raspberry Pi, so that events detected by the sensors would trigger events in our Minecraft world. We used webhooks from the Notion API to POST to a locally running Python HTTP server (accessible from the web via an ngrok tunnel), which then triggered events in the Minecraft world using the awesome Python API for Minecraft Pi. For example, kids would wet a sensor with a cup of water, which would then cause huge blocks of water to appear in their Minecraft world -- or raining dandelions, or blocks of TNT, or whatever the kids programmed to happen. This gist shows how we did it.

Prerequisites

  • a Raspberry Pi
  • Minecraft Pi - This is a version of Minecraft built to run on the Raspbery Pi. It comes preinstalled with the latest version of Raspbian, so if you have a Raspbery Pi and just install the lastest Raspbian on it, you're ready to go with Minecraft Pi. You can find a great tutorial on getting started here.
  • Internet access
  • Some way to send web requests (cURL, Postman, webhooks, etc)

Steps

  1. Open the terminal on your Raspberry Pi. Type nano server.py and copy the contents of this gist's server.py to that file. Save and close (keystrokes: CTR + X, Y, Enter). This is the HTTP server that waits for web requests and then runs a script to interact with your Minecraft server when it receives a POST request.
  2. Now make a new file for the script you would like to run for your Minecraft event. Type nano craft.py and copy the contents of this gist's craft.py. Save and close.
  3. Start your HTTP server by running python server.py in the terminal.
  4. Open a second terminal tab (or window) and start your Minecraft Pi server by running minecraft-pi. This will open the Minecraft GUI. Start a new game.
  5. Now your Minecraft server and HTTP sevrers are running, but because the HTTP server is local, a web request from another computer will not be able to reach your local server. Let's change that by installing ngrok to open a tunnel to your local server. Go to ngrok.com and follow the steps to download for Linux/ARM.
  6. Once ngrok is installed, get it running by opening a third tab in your Raspbery Pi's terminal and typing ./ngrok http 8000. This starts the ngrok tunnel and exposes port 8000, which is the port our python server is running on. You will see the new url in the terminal that you can use to send requests to - it will look something like "http://92832de0.ngrok.io" - and requests to this url will be forwarded to your local computer at port 8000.
  7. Now you can send HTTP POST requests to your ngrok URL and watch what happens in your Minecraft GUI! A cURL request you could run from a different computer could simply look like curl -X POST http://92832de0.ngrok.io -- just remember to use your own ngrok url.

Tips:

  • Your Minecraft Pi server, HTTP server, and Ngrok server must all be running at the same time, and you must have a Minecraft world open.
  • Flower blocks and other blocks with heavy animation are sometimes too much for the little Pi, so if you create lots of those blocks, it may freeze.
from mcpi.minecraft import Minecraft
def run():
mc = Minecraft.create()
# creates some text in a chat box
mc.postToChat("Hello World")
# Get your Minecraft player's position in the world.
x, y, z = mc.player.getPos()
# Generate a 10x10 block of water in front of your player. 8 is the number for water blocks, but you can find the full reference and other block numbers [here](http://www.stuffaboutcode.com/p/minecraft-api-reference.html).
blocks = 8
mc.setBlocks(x+1, y+1, z+1, x+11, y+11, z+11, blocks, 1)
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import SocketServer
import craft as Craft
PORT = 8000
class S(BaseHTTPRequestHandler):
def _set_headers(self):
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
# define the action to happen once a POST request is received
def do_POST(self):
self._set_headers()
# Run our script to create chat text and blocks in our Minecraft world (Note: The Minecraft Pi server MUST be running)
Craft.run()
# Respond to the POST request (not really necessary, but polite ^.^)
self.wfile.write("<html><body><h1>Thanks!</h1></body></html>")
def run(server_class=HTTPServer, handler_class=S, port=PORT):
server_address = ('', port)
httpd = server_class(server_address, handler_class)
print 'Starting httpd'
httpd.serve_forever()
# Start our server when this python file is run from terminal
run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment