Over the past few weeks I’ve been building HuffPost Swing Vote for iOS Messages, and I’d like to share one of the challenges I faced.
Perhaps my all-time favorite technical book is called “Programming Pearls”. For a book about coding, it’s remarkably short and readable. It’s a collection of war-stories drawn from the trenches of early computer science, and I love it because the anecdotes themselves tend to conjure a pretty romantic notion of how sweet life used to be: Imagine being the first programmer tasked to write a sorting routine of TWA’s route fares in the 70s. Reading through the solution, I can almost smell the stale coffee and tobacco stained aircraft cabins of the era.
Backdrop aside, the book is powerful because it teaches a point that’s salient to programmers of any generation : The solution is almost always in how you look at the problem. Something that appears overly complex or time-consuming can so often be looked at differently, and then hopefully, solved more easily.
Swing Vote for iOS is progressive in that games have never lived in the Messages app before, but the game itself isn’t technically unique. In source, we take various objects supplied by design (states, candidates), attribute various properties of physics to them, and then dictate what’s to happen when, say, a state that’s been cut from it’s suspending rope collides with the bucket of the character Donald Trump.
This type of game interaction isn’t novel or groundbreaking, and despite my lack of previous experience with them, Apple’s tools for producing this type of thing are adept.
With the tools in place and assets delivered, this challenge amounted to churning out the necessary quantity and quality of assets to yield something that feels fun to play.
If you play the game, you’ll notice that the majority of interaction extends to cutting ropes. The ropes are anchored to the canvas of game play, and then pinned to each of the swing states. When a rope is cut, the jointed state swings freely. When the remaining ropes are sequentially cut with care, the state (hopefully) falls toward the desired target to “score” for the desired candidate. Each state is suspended by a handful of ropes, and as I developed the game, it occurred to me that representing these ropes may compose a significant part of development.
Each rope had to be defined in relative terms as to where it was attached to the canvas, where it attached to the connected state, how long the rope was, and where the state it was attached to was positioned. I knew a simple data structure could easily represent each coordinate, but as a programmer, my first inclination when I want something to appear on screen “just so” is to type it into my code.
I wrote up a few structures to represent ropes on the first state, Utah, and ran the app. Utah appeared on screen, suspended by the ropes I’d defined. The ropes, unfortunately, were oddly placed and the lengths were way off, making for a rather stuttered rope-cutting experience. I rinsed and repeated the process a handful of times, quickly arriving at the conclusion that to position each rope and state coordinates to satisfaction in code would take the better part of a week.
Still, we needed ropes, positions, and states. The astute may already have realized the solution, and it’s one that comes back, quite literally in this case, to how I thought to look at the problem. Looking at it from the code, the numbers have to be considered, input, observed, and then adjusted.
The perspective that proved most useful was to express the ropes, anchors, and their positions just as the user would see them: On the screen.
Guided by this realization, within a couple hours, I’d introduced an “input” mode to the game. Using a simple set of controls, the positions of various taps would be recorded in a structured text file for each state. One tap would position the state on the screen. Another tape defined where a rope began, and yet another where it should pin to the state. A button advanced input to the next state. Back in code, we use Pythagorean theorem to calculate the length of the rope, and introduce a simple multiplier sway the “bounciness” of the rope.
What initially seemed to be a tremendously tedious task, that of of typing dozens of coordinates into code, was reduced to a few minutes of tapping on the screen.
Certainly not every problem can be solved this way: Just try mixing Swift 2.3 and Swift 3.0 code in your next iOS project. Any way you look at that one, it won’t compile.