DonaldSays: React Native & Augmented Reality

Oscar Lafarga
4 min readOct 8, 2016

--

Hello world!

This is my first ever written piece on anything remotely related to software, or any topic really, save for the occasional Facebook rant/sermon after I see one too many ridiculous comment threads on an even more ridiculous news feed article… However, instead of boring you all with my hopes and dreams, I’d rather take the opportunity to gauge my written communication skills and share how I built my latest mobile game/app.

You’re fired!

DonaldSays is a “augmented reality” style (think Pokemon Go) parody game with some mild political humor that I threw together after becoming deeply interested in VR/AR development. Since I’m quite familiar with Android Studio, I enthusiastically hacked out the Android version (https://play.google.com/store/apps/details?id=com.setdev.donaldsay) without too much trouble. I showed a handful of people, got some great laughs, followed by a few desperate pleas to get the iPhone version out. My iOS skills are pretty decent, but I had recently got out of a really bad relationship with Storyboard & Interface Builder and was still a little emotional, so I forked off an existing project my startup is currently working on and took a stab at what may be one of the first augmented reality style games built in React Native.

Let’s get into it!…

Tools & Key Packages

I also want to take a second and acknowledge React Redux as the single most beautifully architected framework I’ve ever developed with. After my friend Quinn had set it up in the dev environment and all the core concepts finally clicked, I was amazed at how quickly and easily I was able to manage my application state with tight, elegant, and readable code structures. The paradigm shift in thinking required to implement and understand why it works the way it does leaves me in absolute awe of the developer(s) who built it. Bravo.

Going into the React Native port, I figured motion sensing, cameras, animations, video/sound effects, etc would definitely call for some ‘NativeModules’ support to tweak or rewrite some React components in Objective C, but fortunately everything out there was relatively well put together, and I also had a nice clean wall to bang my head against when the going got tough.

With predictable state structures helping me maintain a clean codebase, I was free to focus on the tasks at hand:

  • Bring up the camera and overlay some UI components on top
  • Build a clean, responsive 3D laser animation complete with delightful sound effects
  • Manage game timers/countdowns using a one-way data flow (really interesting, this one)
  • Map the device’s gyroscope sensors to the application state
  • Simulate the “AR” feel by running the gyroscope readings through arbitrary mathematical formulas affecting the position of the targets on screen
  • Test & tweak various timeout constants affecting the pace and difficulty of the game

The interesting part about building this first in native Java and then porting it to React Native was that implementing some of these functions required completely different approaches. I had to go back and find the “greatest common denominator” for the different pieces of state in my components so they could all listen in on the right pieces of that single one-way state channel. For me, this really reinforced the same mindset shift between React’s state management flow and jQuery’s “on click, do this, but only if that’s selected, and if those aren’t visible, cancel everything and use all of these values, which changes this click to a hover…”

If you’re looking to build something like this in React Native, I can tell you right now one of your biggest challenges will be maintaining 60 FPS. We’re running Javascript remember? You can’t just be lazy and spin up multiple threads just because you don’t want to simplify redundant logic… You win this time Java, but I did end up gaining a deeper understanding of React’s component lifecycle since reducing the number of renders with shouldComponentUpdate was critical in keeping up with real-time game animations.

Pro tip: Using Dimensions for your styles makes it much easier to stay responsive across iPhone screens.

What I’ll probably do next is try deploying the React Native build to Android to get a feel for how much of the codebase can actually be shared cross-platform. Then I’ll run some performance tests and maybe compare some of the compiled code with the native Java app to see what’s going on under the hood. Hope to get back to you all with some findings!

Download it free, live now!

iPhone: https://itunes.apple.com/us/app/donaldsays/id1160429309?mt=8
Android: https://play.google.com/store/apps/details?id=com.setdev.donaldsays

Source code:

iOS (React Native): https://github.com/otech47/react-native-donaldsays
Android (Java): https://github.com/otech47/donaldsays

--

--