Playing Pokemon via SMS with Node.js and Twilio

August 19, 2019
Written by
Sam Agnew
Twilion

Copy of Generic Blog Header 3(2).png

Pokemon filled many childhoods with joy. For some of us as adults, Node.js does the same. What better way to spend a fun afternoon than combining the two?

Let’s walk through how to build your own version of Twitch Plays Pokemon powered by text messages using the Twilio API, Node.js and Lua scripting for the Visual Boy Advance emulator.

Getting Equipped

Before moving on, you'll need to set up your environment. First make sure you have Node.js and npm installed.

If you're not on Windows, install wine to be able to run the emulator we need, as only the Windows version has Lua scripting functionality.

If you’re on a Mac, you can install Wine using Homebrew with the following command:

brew install wine

You might have issues getting the emulator to run by default, so make sure you have a 32-bit prefix set by running the following commands in your terminal:

rm -rf ~/.wine
WINEARCH=win32 WINEPREFIX=~/.wine wine wineboot

Wine depends on XQuartz, so if that installation didn’t work you might also have to install XQuartz. You can do this with brew as well:

brew cask install Caskroom/cask/xquartz

You can download the Windows Visual Boy Advance emulator here. Any of those should have the Lua scripting functionality. If you end up having any trouble getting them to run on your machine, you can directly download the version I have been using.

Now we'll need to install the node modules for Express, the body-parser middleware, and the Twilio Node library. To install these npm modules, navigate to the directory where you want this code to live and run the following command in your terminal to create an npm package for this project:

npm init --yes

The --yes argument just runs through all of the prompts that you would otherwise have to fill out or skip. Now that we have a package.json for our app, let’s install the necessary libraries with the following shell commands:

npm install twilio@3.33.0 --save
npm install express@4.17.0 --save
npm install body-parser@1.17.0 --save

Writing emulator Lua scripts

Now that you have everything installed, run the VBA emulator with Wine. If you installed Wine with brew you can do this by running the terminal command wine followed by the filename of the VBA executable.

What’s cool about this version of VBA is that it has Lua scripting capabilities. You can write Lua code that will run in the environment of the emulator for a variety of things such as manipulating the game’s memory, creating save states, or programmatically controlling button input. We’ll be doing the latter.

To begin, create a file called pokemon.lua in the directory where you want your code to live, and add the following Lua code:

function read_file(filename)
    local f = io.open(filename, 'r')

    if f ~= nil then
        io.input(f)
        local content = io.read()
        io.close(f)

        return content
    end
end

function press(button)
    local input_table = {}
    input_table[button] = true
    joypad.set(1, input_table)
end

emu.message('Hello World!')

while true do
    local button = read_file('button.txt')

    if button ~= nil then
        press(button)
        emu.message('Pressing: ' .. button)
        os.remove('button.txt')
    end

    emu.frameadvance()
end

What we’re doing here is reading from a file called button.txt on every frame of the game. The while true do infinite loop will execute before each frame, allowing our JavaScript code to pipe button presses directly into the game’s input by writing to button.txt whenever a text message is received.
To run the Lua Script, do the following as shown in the GIF below:

  • Open VBA with Wine, and the ROM of the game you are using. I will be using Pokemon Red version. If you don’t have one, you can try grabbing a free ROM for a homebrew game like Tobu Tobu Girl.
  • Navigate to "Tools -> Lua Scripting -> New Lua Script Window"
  • Click “Browse” and navigate to where your script is
  • Click “Run”

You should see a “Hello World!” on the screen to let you know things are working.

LuaScript.gif

 

Setting up an Express app to receive incoming messages

Open a file called index.js in the same directory as your package.json and add the following code to it:

const fs = require('fs');
const express = require('express');
const bodyParser = require('body-parser');
const MessagingResponse = require('twilio').twiml.MessagingResponse;

const app = express();
const buttons = ['a', 'b', 'up', 'down', 'left', 'right', 'start', 'select'];

app.use(bodyParser.urlencoded({ extended: false }));

app.post('/sms', (req, res) => {
  const twiml = new MessagingResponse();
  let button = req.body.Body.toLowerCase();

  // Check to see if the user's input was a valid Gameboy button.
  if(buttons.includes(button)) {
    twiml.message('Thanks for playing Pokemon with me!');

    // The Lua Joypad API expects A and B buttons to be uppercase.
    if(['a', 'b'].includes(button)) {
      button = button.toUpperCase();
    }

    fs.writeFileSync('button.txt', button, 'utf8');
  } else {
    twiml.message('Please text a valid Gameboy button.');
  }

  res.writeHead(200, { 'Content-Type': 'text/xml' });
  res.end(twiml.toString());
});

app.listen(3000, console.log('Express app listening on port 3000.'));

This code sets up an Express app, defines a route on the app to handle incoming SMS messages, and then has it listen on port 3000 for incoming requests. In the /sms route, the body-parser middleware is used to access data in the request body in order to grab the text of the message, which is going to be the button the user wants us to press in the game.

This /sms route is going to handle requests representing text messages to our Twilio number, which will be controlling the game. If the user sends a message corresponding to a button on the Gameboy, we'll write it to the button.txt file for the Lua script to read and press in the game.

You can run this code with the following command:

node index.js

Setting up your Twilio account

Before being able to respond to messages, you’ll need a Twilio phone number. You can buy a phone number here (it’s free if you’re using the number to test your code during development).

Your Express app will need to be visible from the internet in order for Twilio to send requests to it. We will use ngrok for this, which you’ll need to install if you don’t have it. In your terminal run the following command:

ngrok http 3000

If you’ve just installed ngrok and that previous command didn’t work, you might have to run it like ./ngrok http 3000 from the directory that the ngrok executable is in.

This provides us with a publicly accessible URL to the Express app. Configure your phone number as seen in this image by adding your ngrok URL with "/sms" appended to it to the “Messaging” section:

You are now ready to receive a text message to your Twilio number.

Playing Pokemon with text messages

AttackMissed.gif

 

Now all of your friends can send text messages to your Twilio number to play Pokemon with you! This code should work with any other game as well. Try building off of this and messing around further with the Lua scripting functionality.

If you have any other cool ideas, feel free to reach out and let me know or ask any questions: