In high school I loved playing a little Flash game called Planarity. I've absolutely no idea how I stumbled upon it, but I played it most days in the library before classes if I got to school early. In the intervening years between then and now it would occasionally cross my mind as a fun memory. In the years since I learned to code it's also occasionally crossed my mind, but with a more concrete notion: it would be fun to build an implementation of the game.

Last week it crossed my mind again, and this time I had an idea of how to actually build the game. I was wrong.

The algorithm behind Planarity is both quite simple, but also more involved than I'd thought, as a player of the game. The creator of the game, John Tantalo, was gracious enough to publish the algorithm in the public domain. The game isn't just a series of random vertices and lines, but rather built on an underlying assortment of intersecting lines, which in turn create the puzzle to solve.

I was able to reuse a lot of my work from SwiftGraphics which has most the basic geometry code needed for doing line intersections and such. The hardest part was figuring out how to build the actual graph from the original intersection points. I'm not sure if my implementation is the most efficient, but it does seem to work.

The entire app is built in SwiftUI, including the actual graph. It does take some work to convince SwiftUI to do absolute positioning the correct way1, but it provides some really nice options for higher level things like styling and interaction. Planarity is perfectly suited to being played on the iPad, especially with an Pencil.

There are still things to polish and features to add. For instance, I'd like to add a more comprehensive records section, keeping track of puzzle history like the fewest moves in a level to solve the graph and the total number of moves. It would also be fun to export an animation of the puzzle being solved2.

I would like to release the game when it's ready, even if no one else is interested in it. The app needs a little more polish, and a more original name. In the meantime I have graphs to untangle.

Update: I've done the polishing and the game is now available to beta test on TestFlight.


  1. .frame().position(). not .position().frame()

  2. Perfect for all of that social media clout.