I Saw a Dinosaur, or How I Built a Real-Life Version of Chrome T-Rex Game

Using Front-End Engineering to Have Fun Hacking Hardware!

Uri Shaked
12 min readNov 22, 2017

It all started at Geekcon

Geekcon is a weekend-long hackathon where the purpose is to build useless but cool stuff. It’s one of my favorite kinds of events, because I love seeing all the cool and fun things people come up with. It was extra fun because this time around I had a special co-hacker: my girlfriend Ariella!

This year, they really pulled out all the stops: there was real-life pac man, a laser pointer-chasing robotic cat, a mopey robot, and much more!

So what did we build?

As I’ve mentioned previously, I’ve been pretty into the Chrome T-Rex game, and so of course my project was going to have something to do with that:

A T-Rex runner in real life? Why not?!

With a little help from the hackathoners, Ariella and I were able to get a prototype working while at Geekcon. You can check out a video about it here (with an appropriate soundtrack included ;-):

What was also nice to see is that people of all ages seemed to enjoy playing the game:

Since people seemed to like it so much, and since the Chrome Developer Summit was coming up, and I was already going to be there… I thought I would contact the organizing team and asked if they would like to display the game in the exhibition area.

Turns out, they were really excited about it!

Of course, I now realized that it was time to get down to the real work: I had less than a month to take the real-life T-Rex game from a prototype to a reliable, good-looking, and above all, functional product.

Build Challenges and Techniques

Both in building the original prototype and in making the improved version, there were a number of challenges I knew I had to overcome to make the game:

  • Making the cacti loop so that the game is totally automatic. I also wanted to introduce some kind of randomness, so that the timing of the cacti’s approach is not always the same to make the game more challenging.
  • Making the dinosaur jump reliably.
  • Making sure there is not too much noise coming from the build.
  • Making sure I could travel with it! This meant that I had to make sure the weight of the finished product would be reasonable to take on a plane, and also that the game would be easy to disassemble at home and reassemble at the event.

Part of the fun of taking on this project was that I knew I was going to have to level up a lot of the “maker” skills I’ve acquired over the last few years (see links below), as well as learn some new ones. Aside from writing the code for the game (more on that in a moment), I was able to deploy the following skills/techniques during the project:

You can find a complete list of the parts I used for the project here.

Coding the Game: JavaScript All the Way!

Since I was planning on presenting this demo at the Chrome Dev Summit, it was important for me to have it powered by Web Technologies. To that end, the entire game is written in JavaScript, with the physical-game code running in Espruino, an embedded JavaScript interpreter that can run on constrained hardware. To add some extra fun, I also made sure that the game would be programmable over the air with Bluetooth, so I used a Web-Bluetooth IDE to tinker and upload the JavaScript code to the chip.

As the code grew larger, I decided to break it up into different modules. I used rollup.js, a module bundler that can also detect and eliminate unused code as well as combine functions from different modules efficiently.

It was so much fun to use the same tooling as I use for Front-End Development to build hardware games! If you want to jump right in, you can find the complete source code for the game here:

Designing the Cacti Loop

Making the cacti loop around was the biggest challenge in the project. Again, I was lucky to have Ariella there helping me out!

The original plan was to have the cacti ride on timing belts, with one timing belt in the front of the project, and a second one at the back, going the opposite direction, with some mechanism to move the cacti between these belts.

This turned out to be quite complicated, so for the initial prototype we just skipped that part and only had one timing belt going forward — but this meant that you had to manually move the cacti to the beginning of the track, which wasn’t really playable, but was still very fun for the purposes of the “useless stuff” hackathon :-)

After some experimentation, we found that if we made a loop between two motorized tracks, the cacti would actually push each other around the loop until they got back to the to the other motorized track.

A diagram of the cacti’s movement
Cacti queueing up along the 3d-printed loop

We first tried 3d-printing this loop. It worked quite well, but as the loop surface was not very smooth, sometimes the cacti got stuck in the middle due to friction. This did, however, allow us to figure out a radius for the loop that worked best.

Once we had a better idea of what we were doing, we laser-cut the loops, which made them smoother (and also better looking!).

This worked very well for the small cacti, but the bigger ones (with three instead of two plans) would almost always flip over. The reason was obvious: the cacti weighted about 6 grams, while the base part that carried them was only about 1.5 grams. They were top-heavy, to say the least.

An early fix idea: add weight with nuts. Not quite right.

In order to fix that, we had to add some weight to the cactus carriers. To make it extra special, we decided to manufacture some of our own — but this time out of a heavier material than 3D-printer plastic.

After some online research about densities of different materials, it seemed like the only feasible material for the job was Tin — it combines high density, 7.3g/cm with low enough melting point (230C) that I could easily melt it at home. Tin is also very easy to get a hold of.

Casting tin into the homemade silicone mold

My sister (who is an awesome designer, and who drew the cover art for some of my other posts) helped me create a silicone mold using a 3D-printed template, and then we used this mold for the actual casting process. Adding this extra weight to the cacti carriers tremendously helped, by bumping their weight to 5–6 grams, which made them much more stable and less likely to flip over:

Cacti stands with their specially molded weights!

At that point, we had the cacti running around the track, and after some fine tuning of the loop height and angle, and if we didn’t go to fast, the largest cactus would easily made it around without flipping over. Great success!

Detecting the Cacti

In order to score the game, I needed to work out a way to detect when the cacti were passing by the dinosaur. I achieved this by attaching a small magnet to each one of the cactus carriers, then using a KY-024 magnetic sensor.

The idea is that every time a cactus is detected, you check the position of the dinosaur. If the dino is jumping, you get a +1, and if the dino is still on the ground, that means your T-Rex has run into the cactus and the game ends.

Working with the sensor proved to be quite easy — it was very accurate, provided no false positives, and with some fine tuning of the timing in code, it counted the number of cacti that passed by very accurately.

(That red light there below the T-Rex is the sensor.)

Jump, Dino, Jump!

Making the Dino jump turned out to be pretty easy — we nailed it in the first few hours of Geekcon, and it worked pretty well.

An early success!

Even though it worked well at Geekcon, I decided to re-build the jump mechanism, as the original mechanism we came up with was pretty clumsy, did not jump high enough, and also made the entire game tremble when the Dino hit the ground. It was also pretty heavy, as we used two steel rods as the track for guiding the jump. These steel rods were also just a bit too high, showing above the background pane of the game, and since I don’t know how to cut steel… it was time for a change.

I decided to try using a stepper motor with a timing belt, a mechanism similar to the one we used for the cacti track. I replaced the steel rods with carbon fiber tubes, which, in addition to being a better size so far as the game’s background was concerned, cut almost 200 grams off the game.

A few 3D-printed parts to mount the motor, a simple shaft with a pulley and bearing at the top, a few hours of hard work, and we had it working!

Go jumping dinosaur!

…or at least the physical part of it.

Controlling the stepper motor from JavaScript proved to be quite challenging. Generating an accurate number of steps at high frequencies was not possible, because in some cases other tasks (such as the magnetic detector listener) were interfering with the timing, causing the motor to overshoot and go beyond the end of the jump slot and make unpleasant grinding sound.

Luckily, Gordon Williams, the creator of Espruino, was able to give me some pointers how to set up the nRF52 hardware to generate a given amount of steps in a given frequency, using an hardware interface called PPI, which bypasses the CPU. That was the only piece of code I had to write in C for the project.

With the new code inspired by Gordon’s help, our Dino jump was working well! I ran a stress test, where I had the T-rex jumping every 2 seconds for half an hour, and it still worked pretty well.

Improving Game Design with a Wireless Control Button

Initially, when I asked my sister to help with the design of the project, one of her first feedback points was that the button should be wireless, so that we wouldn’t have any unseemly wires running from the controller to the game, as well as giving us the flexibility to place the actual controller wherever.

I though this would take some time to implement, and that there might be reliability or latency issues, but within just a few minutes I got it working very reliably and without any noticeable latency. It continued to work reliably on the same CR2032 battery during the entire duration of the conference.

Basically, I added another small nRF52-based board, called BLE Nano 2 (the same one I used for my Purple Eye bot, which is also powered by JavaScript running on Espruino), into the controller setup.

Yum… Blueooth!

The code to make this work is quite simple: it essentially involves listening for button presses and transferring that information over Bluetooth. You can find the button’s firmware here, and the button driver code (the part where the game connect with the button) here.

Final Touches: Displaying Players’ Scores

To display the score, I decided to use an E-Paper display. These are the displays that you can find in e-book readers such as the kindle, and they have several interesting properties.

The most interesting one for me was the colors: very high contrast black ink on white background, which perfectly fits the original colors of the game. In addition to that, the display retains its content even when it’s unpowered.

Funny story about that last piece: when I initially got the display in the mail, I tried to remove the manufacturer’s logo sticker from the display, only to discover that it was not a sticker at all, but the last thing that was presented on the display before it shipped out from the factory!

It wasn’t a sticker…

Working with this display proved to be quite challenging. The display takes about 0.3 seconds to update, and though it does support partial updates (meaning I could update just one part of the screen without affecting the others), it has two memory buffers that it switches between, making the coding a bit more complicated.

So if I wanted to draw something, then display it to the screen, the next thing I would draw goes to the second buffer, so when I display it, the first thing will disappear, since the first buffer is overridden by the second (though the original drawing will still be in the first buffer and be displayed again in the next update).

The display control code turned out complicated enough that I decided to write some unit tests for it so I could iterate faster.

Furthermore, storing the bitmaps for all the game assets (digits, texts, and t-rex icon) in memory was taking most of the free RAM that I had, so eventually I had to store them directly in the Flash memory of the chip.

But after all that, finally it worked!

You can find all the assets bitmap, in a nice text format, here. And I did make one nice discovery while editing them:

Tracking the High Score

This was a feature I added at the last moment (literally finishing the code the morning of the first day of the summit), and it also provided some challenges.

The high score had to be stored in the Flash memory of the chip (so it would not wiped out when power goes off), but Flash memories are weird creatures: when you write to them, you can only turn bits from 1 to 0, but not the other way around.

The only way around this is to erase a whole section of the flash memory, which resets it to 1s, but not only does it wear out the flash, it is also a relatively slow operation. You can find out how I eventually ended up storing the high score by looking at the source code and the unit tests I wrote, if you’re curious.

The Big Event: Dinos at the Chrome Dev Summit

When I flew in for the Chrome Dev Summit, the game was almost working — just jumping didn’t work very well (see above where I explain about the timings issue that I had with JavaScript):

However, I managed to hack the solution a day before the summit, and the game was ready in time (well, except for displaying the high score, but we already went over that).

Me and the Dino at the Dev Summit

It was much fun seeing people play and enjoy the game so much. I managed to catch some of this on camera, so you can also enjoy it:

Overall, the game was played nearly a thousand of times by different people throughout the summit, and someone even scored 129 points (she was really determined to break the high score)!

Overall, I acquired many new skills while working on this project: working with Stepper motors, casting tin, driving e-paper displays, connecting 3D-printed parts using nuts and bolts, designing laser-cut parts, using pulleys and timing belts, and writing unit tests for firmware code (just to name a few).

I had a lot of fun seeing the final result working and people enjoying it so much, and I look forward to seeing what inspiration strikes for the next year!

I’d like to thank to Lars Knudsen, Kenneth Christiansen, Sander Elias, Alyssa Nicoll, and Mike Hartington who were of invaluable help setting up, running this demo, and running the other demo that I presented during the summit.

Yet again it proves what a great “family” the Google Developer Expert community is, and how much we help each other out.

I would also like to thank my girlfriend Ariella, who helped me build the project in the first place :)

And finally, as an aside, I got asked several times if I am the creator of the original game (which I am not!). This prompted me to do a little googling… and it turns out there are lots of creators! I also dug up this neat interview with one of the game’s designers.

--

--

Uri Shaked

Google Developer Expert for Web Technologies, Maker and Public Speaker