PHP, Arduino And… Minecraft? Combining Minecraft with PHP!

Share this article

PHP, Arduino And… Minecraft? Combining Minecraft with PHP!
IoTWeek_Gray
It’s IoT Week at SitePoint! All week we’re publishing articles focused on the intersection of the internet and the physical world, so keep checking the IoT tag for the latest updates. Some of the most interesting programming I’ve done has been in Minecraft. It’s an open-world, sandbox game developed by Mojang, (recently acquired by Microsoft). Minecraft began as a canvas for creative expression, and while I do very different things in it these days, it still is that for me. I’m going to take you on a journey, as we build a Minecraft mansion, and then secure it with a real-world alarm system. There’s quite a bit of ground to cover, and though I plan for this to be a two-part series, I’m going to have to leave some of the tangential details for you to discover! You can find the code for this tutorial at https://github.com/sitepoint-editors/tutorial-php-arduino-and-minecraft

Crash Course in Minecraft Programming

Minecraft began as the combination of two simple ideas. The first is that players can harvest resources from the map in which they find themselves. Some of these resources, like food and wood, are common above ground. Others, like gold and stone, require a bit of virtual elbow-grease. This is where the “mine” (in Minecraft) comes from. One of these resources is called Redstone. It’s found deep underground, and it’s a conductor of sorts. When harvested and placed on the ground, it resembles the silvery lines on the flip side of circuit boards. There are also power emitters, similar to batteries or mains power, which take many forms in the game. In-game screenshot of Redstone Using these harvested resources, players can build dwellings, cook food and even wire up virtual circuitry. This is where the “craft” comes from. I talk about all of this, as well as basic circuitry and programming, in my conference talk Zombies and Binary. I presented it most recently at php[tek] 2016, but the recording was lost. Here’s a JavaScript-themed version, from FluentConf 2016: https://youtu.be/APJRBZUxADQ. Imagine we’ve created a sprawling Minecraft mansion… In-game screenshot of mansion Now, imagine we want to secure the front door of said mansion…We need a way to check whether the front-door has been opened. To do this, we need to use Redstone, something called a Comparator, and another thing called a Command block: In-game screenshot of testing for block You may notice the switch I’ve connected to the Command block. Switches are one kind of power source, and this one will provide some power to the Command block so that it can perform the open door check. We’ll automate this power source in a bit… Command blocks are placeholders which can contain a single server command. Server commands are anything you as a player can do (provided you are a server admin or in single-player mode). They’re like Amazon Dash buttons, in that they can be given a single command to run, at the push of a button. We’re going to make the Command block test for an open door. Minecraft maps are coordinate-based, which means the test needs to include coordinates for where the door will be placed. For argument’s sake, let’s say the door is at 191 67 -194. The command for the test (of an open wooden door) will then be:
/testforblock 191 67 -194 wooden_door 3
You can find your current map coordinates with fn + alt + F3 (for Mac) and F3 (for Windows). Walk to the block where you’ll place the door, and enter those coordinates in the command. Different Minecraft blocks (whether crafted or naturally occurring) have unique block names. wooden_door is the unique block name for an Oak door. 3
is a reference to the orientation of the door, so it might be different in your maps if you place your door in a different orientation. If so, try 0 through 3 until you get the desired result. We’ll make the second Command block whisper a message back to us to indicate when the test has found a matching block. When we flick the switch, and the door is still closed, we should see nothing. But when we open the door (and the test matches the open door’s orientation), we should see confirmation of this! In-game moving image of testing for a block Now we have a way to check for an open door. We don’t want to be standing around, to manually run this check though. Let’s set up the programming equivalent of an infinite loop, or the electronic equivalent of a crystal clock. For this we need two Command blocks, arranged like this: In-game screenshot of clock Notice I’ve attached a button to each Command block, so that I can run their commands. These buttons also act as a power source, giving a brief power spike to the blocks they’re connected to. Map coordinates can also be relatively defined. That is, if you need to reference coordinates nearby the Command block, you can use ~-1 ~ ~+1 to mean the Command block’s x coordinate minus 1, the same y coordinate, and it’s z coordinate plus 1. In this arrangement, we want the top Command block to place a Redstone block just below it:
/setblock ~ ~-1 ~ redstone_block
…And we want the bottom Command block to place a block of air above it:
/setblock ~ ~+1 ~ air
Redstone blocks also act as a power source. This arrangement has an interesting side-effect. When the top block places a Redstone block below itself, the Redstone block gives power first to the bottom Command block. It then gives power to the top Command block. In the meantime the bottom Command block has removed the Redstone block. Since the top Command block got a new power signal (from the Redstone block it placed) and the block was then removed by the bottom Command block, it starts the cycle over again. This leads to the infinite loop I spoke about. The loop will persist through server restarts, and if you’re in creative mode you’ll be able to break the Redstone block and see new ones created instantly. In-game animated image of working clock By default, these Command block actions will be logged and will trigger messages on the server. You can disable these with a couple commands (which you only have to enter once per map): /gamerule logAdminCommands false and /gamerule commandBlockOutput false. If we take power from the clock, and direct it into the testing Command block, the test will run many times a second, giving immediate feedback when the door is opened! Newer versions of Minecraft allow Command blocks to power themselves and even repeat themselves. With that, it’s possible for the door check to repeat without the clock. If you’re using an older version of Minecraft, especially when using mod packs, you may still need to make the clock yourself… In-game animation of working door, opening and closing It’s also useful to know when the door has been closed, so we can turn the real-world alarm off. For that we can use an inverter (think of it as turning the closed door (false value) to a true value, in much the same way as we would in programming: while (true) if (!$doorOpen) print.... In-game screenshot of inverter

Watching Log Files with PHP

All of this is pretty and useless without the ability to see these changes in PHP. We need a way to “hear” when the door has been opened, and react in PHP. Fortunately, the whispered messages are all logged. If we can figure out how to watch and interpret the log files, we should have all the information we need… A quick Packagist search provides a file watcher library
which looks like it’s up to the task. We can install it with:
composer require yosymfony/resource-watcher
After that’s done, let’s make a script to watch the log files. We begin by creating a Symfony Finder instance, and pointing it at the directory in which the Minecraft logs are stored:
require __DIR__ . "/vendor/autoload.php";

use Symfony\Component\Finder\Finder;

$path = "/path/to/Application Support/minecraft/logs";

$finder = new Finder();

$finder->files()
    ->name("*.log")
    ->depth(0)
    ->in($path);
The path to Application Support will be different for you – it’s usually in the Library folder associated with your account. You could also be using a portable version of Minecraft, so you’ll just have to search around a bit, until you find the logs folder. This Finder instance narrows the file watch list to *.log files in the same directory as the one we’ve specified. The methods are clearly named, so you can expand the criteria for other applications. Next we need to define a cache file, and a watcher instance:
use Yosymfony\ResourceWatcher\ResourceCacheFile;
use Yosymfony\ResourceWatcher\ResourceWatcher;

$cache = new ResourceCacheFile(__DIR__ . "/cache.php");

$watcher = new ResourceWatcher($cache);
$watcher->setFinder($finder);

while(true) {
    sleep(1);

    $watcher->findChanges();

    // ...respond to changes
}
This script acts as a long-running process. That is, we want to watch for changes to files, for an indeterminate amount of time. So we create an infinite loop, and use it to constantly probe for file changes. You can sleep for more or less time. I found 1 second was good enough for me… The watcher library provides methods for three kinds of file changes: creation, deletion and updates. We only care about the updates:
while(true) {
    sleep(1);

    $watcher->findChanges();

    // ...respond to changes
    $changes = $watcher->getUpdatedResources();

    if (count($changes) > 0) {
        $first = $changes[0];

        $lines = file($first);

        for ($i = count($lines) - 1; $i > -1; $i--) {
            if (stristr($lines[$i], "CHAT")) {
                if (stristr($lines[$i], "closed")) {
                    print "closed!";
                }

                if (stristr($lines[$i], "open")) {
                    print "open!";
                }

                break;
            }
        }
    }
}
New chat messages are appended to the bottom of the log file, so we need to check if any log files have been modified (we expect only one log file), split the log file into lines and check each line from the bottom of the file to the top. If we see a log line containing CHAT, we can assume it is a chat message. If it also contains open or closed, we can assume it is caused by the circuit we created. Animated image of PHP and Minecraft working together You’re welcome to use more “unique” message formats for open/close events. The approach I’ve chosen is simple but open to abuse and ambiguity (like if someone else whispers “open” to me). The underlying principles are the same though. This is only half of the experiment. In the followup post we’ll look at how to build an Arduino-based alarm circuit, and connect it to this script. The end result will be an automated, real-world alarm for our Minecraft mansion. If you’ve enjoyed this and/or have questions, please let us know in the comments!

Frequently Asked Questions about Combining Minecraft with PHP and Arduino

How can I use PHP to interact with a Minecraft server?

PHP can be used to interact with a Minecraft server through the use of RCON and Query protocols. These protocols allow you to send commands and retrieve information from the server. You can use PHP libraries such as PHP-Minecraft-Query and PHP-Minecraft-Rcon to facilitate this interaction. These libraries provide functions to connect to the server, send commands, and retrieve responses.

Can I host a Minecraft server on Arduino?

Arduino, due to its limited processing power and memory, is not suitable for hosting a Minecraft server. Minecraft servers require a lot of resources, which Arduino boards typically do not have. However, you can use Arduino to interact with a Minecraft server hosted on a more powerful machine.

How can I use Arduino to interact with a Minecraft server?

Arduino can interact with a Minecraft server through the use of serial communication. You can write a script in a language such as Python or PHP that communicates with the Minecraft server and sends/receives data to/from the Arduino board over a serial connection.

What is the title command in Minecraft and how can I use it with PHP?

The title command in Minecraft is used to display custom text on the screen of players. You can use PHP to send this command to a Minecraft server. This can be done by establishing a connection to the server using RCON and then sending the title command with the desired text.

How can I use PHP to query a Minecraft server?

You can use PHP to query a Minecraft server to retrieve information such as the number of players online, the server’s version, and the list of player names. This can be done using the Query protocol and a PHP library such as PHP-Minecraft-Query. The library provides functions to send a query to the server and parse the response.

Can I use PHP to control a Minecraft game?

Yes, you can use PHP to control a Minecraft game by sending commands to the server. This can be done using the RCON protocol and a PHP library such as PHP-Minecraft-Rcon. The library provides functions to connect to the server, authenticate, and send commands.

What is RCON and how does it work with Minecraft?

RCON (Remote Console) is a protocol that allows remote execution of commands on a server. In the context of Minecraft, it can be used to send commands to the server from a remote machine. This can be done using a PHP script and a library such as PHP-Minecraft-Rcon.

How can I use PHP to send commands to a Minecraft server?

You can use PHP to send commands to a Minecraft server using the RCON protocol. This can be done using a PHP library such as PHP-Minecraft-Rcon. The library provides functions to connect to the server, authenticate, and send commands.

Can I use Arduino to control a Minecraft game?

While Arduino cannot directly control a Minecraft game, it can be used to interact with the game through a script written in a language such as Python or PHP. The script can communicate with the Minecraft server and send/receive data to/from the Arduino board over a serial connection.

How can I use Arduino and PHP together with Minecraft?

You can use Arduino and PHP together with Minecraft by writing a PHP script that communicates with both the Minecraft server and the Arduino board. The script can send commands to the server and receive responses, and it can also send/receive data to/from the Arduino board over a serial connection.

Christopher PittChristopher Pitt
View Author

Christopher is a writer and coder, working at Over. He usually works on application architecture, though sometimes you'll find him building compilers or robots.

alarmarduinoBrunoSelectronicsiotMinecraftoddballOOPHPPHP
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week