Your Brain: The Ultimate Game Controller
Controlling the Chrome Offline T-Rex game with your Eyes
We all love (and hate) the T-Rex that appears in our Chrome browser when the Internet connection’s down. And I’m sure many of you also know that the T-Rex is actually a game — if you click it (or press space), the game begins and you’re running around trying to avoid the cacti and pterodactyl.
Lately, I’ve become very interested in EEG, a technology that reads electrical activity in the brain. I managed to connect an EEG device called Muse to the web browser using Web Bluetooth, which you can read about it in my previous blog post: Reactive Brain Waves.
This time, I decided to “level up” and apply EEG/Web Bluetooth to the T-Rex game. The idea was that, if you have to be offline, you could at least have some fun and play the game hands free, just by blinking!
Before we start: I found a sweet shortcut to get into the game, in case you want to play it without having to switch to airplane mode:
So, let’s get down to business!
The Game and Your Brain
Originally, I wanted to come up with some cool code snippet that you could just paste into the browser console and play the game using the EEG headset, but this turned out to be impossible given the limitations of Web Bluetooth: you can only use Web Bluetooth on secure sites whose URL starts with https://
, and apparently chrome://dino
doesn’t.
So, I tried the next best thing — I googled and found that somebody had already extracted the game from chrome into a standalone HTML page — hooray! Now I just needed to paste the code from my previous blog post, connect the dots, and it will work (or so I thought).
In order to make the game work with the EEG headset, we need to set up a few things so we can load the muse-js and rxjs libraries into the browser.
Setting up the environment
First, let’s clone the extracted game’s repository:
git clone https://github.com/arnellebalane/trex-runner
Then, we’ll go into trex-runner
directory to initialize a new NPM project:
npm init -y
After which we can install muse-js:
npm install --save muse-js
We are going use SystemJS, a configurable module loader, and set it up to load the muse-js library and rxjs, its dependency. You can learn more about SystemJS in “Setting Up Angular from Scratch,” where we also use it. We will start by installing SystemJS:
npm install --save systemjs
and then add the following code to index.html
:
The first line loads SystemJS, and then the subsequent lines define where to find the muse-js
and rxjs
modules (inside node_modules, obviously), and also the name of the entry point file for muse-js
. This is all we need to setup.
Finally, the last code line (number 18) instructs SystemJS to load a file called brain.js
, where we will include the logic around the new controls for the game.
We could have chosen to use a different solution for handling modules, such as WebPack, Browserify or fuse-box, but SystemJS seemed to require the least amount of configuration and changes to the existing setup, so I went with it.
A Brain-Based Controller
So… with that, let’s implement the brain.js
file! We will build on top of the blink detection code from the Reactive Brain Waves post:
Lines 7–9 set up and initialize the muse client. Lines 11–15 take care of filtering the blinks detected for the left eye (see the previous blog post for a walk-through), and then on line 17, we call to subscribe
to start listening for the blink events.
Finally, we expose our function on the global window
object, as we will invoke it directly from the click event listener of a button in just a moment. We need to explicitly expose it as a global because we are running in a SystemJS environment that provides encapsulation, so by default, all the variables and functions we define only exist in the context of the current module.
Note that you may have to tinker with the threshold on line 15. I found out that in some cases, lower values such as 150–200 work best, and in more noisy environments, 400–500 works better.
Next — let’s add the connect button to our index.html. I added mine at the bottom of the page, but you can get creative with it:
And now, for the final piece of the puzzle. Our JavaScript code currently only prints “Blink!” whenever you blink, so we need to connect it with the game.
We could read the source code of the game (recommended, as you will find some hidden gems inside), but there is actually a simpler method. You use the spacebar to jump in the game, so we can simply simulate a DOM keydown
event, and the game will interpret it as if the user actually hit space.
All it takes is 3 lines of code, which you add to inside the blinks
subscription callback:
So all told, in about 25 lines of code (+ some System JS configuration), we can play the game with our Muse EEG headset. Not bad, huh? You can see the full repo below:
Gameplay
In order to run the game, you will need a web server to serve the HTML page. I usually use live-server for quickly running local web server for development, but there are lots of options out there.
When I showed this on stage for the first time, I got some very excited feedback from the audience:
The volunteer from the audience was quite nervous, and it also takes some training to properly play the game this way. Here is another demo taken with Asim Hussain, Simona Cotin and Vitaliy Zasadnyy in a more relaxed setting, during the DevFest Nantes 2017 conference:
Final Thoughts
So as I think you can see above, this turned out to be a fairly simple but extremely rewarding and fun little project. If you’ve ever read any of my other posts, you know how I love to mix Web Bluetooth with all sorts of different applications, but also, importantly — I like to mix it with fun!
I think there is certainly much more we can do with EEG and Web Bluetooth, and I’ve already had people coming up to me after I demonstrate the technology pair with all sorts of really neat ideas that range from the supremely silly to applications that could have immense impact on improving the quality of peoples’ lives.
While my own EEG/Web Bluetooth journey is still just beginning, I’m very excited about where it seems to be heading, and I’ll be sure to continue sharing what I learn as it comes!