Monthly Archives: July 2014

Indra’s Net and Theming

(Indra’s Net is available on both the app store and google play.)

Okay, if you’ve played Indra’s Net or seen screenshots you’ll know that it hardly “themed”. They’re squares, they change colors. There aren’t any cute animals or sugary confections to grab the semantic part of your brain, but there is theming nevertheless!

After establishing the core mechanic I wanted a little something extra to make the game more meaningful. Since in the first formulation the player had to turn all of the tiles white in order to progress, I thought that emptiness might be a neat theme, so the game was called Sunyata and featured the text of the Heart Sutra parsed into 14 sections (hence the current 14-level structure). Each time through the sutra would repeat, and the game became a meditation on emptiness for me. I enjoyed this quite a bit but there was something lacking since the relationships of the squares was never addressed.

With Ben’s suggestion I began looking into Cause and Effect as a potential theme and shortly came upon dependent origination, which coincidentally enough is considered complementary to sunyata in Buddhist philosophy. Having found the two ends of what I wanted, I searched further to discover Indra’s Net, which “is a metaphor used to illustrate the concepts of emptiness, dependent origination, and interpenetration in Buddhist philosophy.” The shoe fit.

The heart sutra, however, did not fit anymore. The new metaphor of Indra’s Net was more playful than the austere Sunyata, and after having played the game for a while I discovered that it put me in a playful mood of discovery and wonder. With that feeling in mind I decided to write a brief story about Cause and Effect which Sarah and I rewrote shortly after. The basic premise, if you haven’t played yet, is that Cause and Effect become separated and go about their own journeys to be finally reunited in the end, where they arrive in a different place (and the next season), for the story to repeat as the board grows bigger/features more colors.

This was the story of how from a purely abstract logic puzzle, a game embracing confusion and addressing separation was created. The theme and story help lower the stakes, make it playful, and allow people to get lost without worry. When we’re lost and without assumptions we can finally start to learn brand new things.

Pro-social Game Design

Today I published an article I’ve been working on about pro-social game design, making things that are good for people. It takes as inspiration games which I very much respect and distills some of the lessons from them. Here’s an abridged version:

There’s an analogy between fast food/slow food and types of games in that the former are easy, low cost upfront, high cost later and the latter are higher cost up front, more challenging, but ultimately better for you.

Three ways to go about making a game that is good for people:

  • let people sit, give them space
  • encourage growth
  • reward the player

If we make enough pro-social games then people’s standards will raise and they will realize that they didn’t really want the cheap stuff to begin with. That’s the job of the indie game designer.

Developing Secant

Secant, our latest release, is a minimalist geometric puzzle game (see the trailer below). Today I’d like to share a bit about what it was like to develop it, from inspiration to design to implementation, along with some road bumps and their solutions.

Backstory + inspiration: In machine learning and statistics one type of problem is classification, which is basically what it sounds like. This can be tricky, because data can be noisy or arranged in some strange shape. A particular type of classifier called a support vector machine (SVM) tries to classify data by cutting it up with planes (or, in the 2D case, with straight lines), so that each region has only a single class. We might say the SVM uses hyperplanes as its basis functions, and because of this support vector machines are inherently limited. So the question emerges: what if you allow other shapes? Secant is just that, played in two dimensions only, where you get circles and lines as your basis functions and your job is to separate data points into regions based on their class (color). Or at least, that’s how I originally thought about it.

Crux problem: With SVMs, all you ever have to worry about for each point is whether it is ‘above’ or ‘below’ each plane (or line). Since planes carve up the plane very nicely (notably, into convex regions) you can simply look at two points, P and Q and ask are they above or below each plane. If they match up on all counts, then they must be in the same region. Now, this is still true with circles and lines, but what doesn’t hold is that is that if they do not match up then they must be in different regions. Evie (aka Evdog) came up with the following situation during her first play through the game:


Notice that the green and yellow are in different geometric regions (clearly!) yet they are both inside the big circle, outside the small one, and above the line. Since the game doesn’t see this as a win, it doesn’t allow the player to progress (how sad) until they find a solution that doesn’t use such geometric tricks. Since disallowing geometric tricks would surely make for a worse game, I realised that what Evie had done was most assuredly a valid solution. But the question remained: how to correct it?

Two approaches and a decision: There were two ways to go about it. One was to use a flood fill algorithm (think paint bucket in photoshop) which checks if you paint-bucket from each point you don’t get regions with multiple colors painted on them. This was pretty clear to be a solution, but I thought running it on device was going to be a nightmare (it would involve iterating through all of the pixels onscreen and I didn’t even have access to the pixels and would have to redraw it from scratch). So I kept thinking about it, and came up with an alternate solution based on the original logic of being inside or outside each closed region: compute all intersections as vertices, link them up in a graph (where edges are adjacencies between intersections on a shape), find the cycles, and then check the winding number of each data point with respect to each cycle. This would give all the funky weird regions as loops, and then verify that these loops either did/did not go around each point. The main problem with this: it was going to be even worse than flood fill because, while computationally far simpler (with not too many shapes on the board, mind) it would involve finding all cycles and then computing the winding numbers (which would involve making polygonal proxy shapes for the circles or casting a ray from the data point in question and ‘walking’ the circuit to find a minimal enclosing region). In short: this was not going to be any better than flood fill if I could get flood fill to perform reasonably on device.

Solution -> Aesthetic: I tested out the performance of flood fill which was disheartening at first, read up about coroutines in Lua, and ultimately used a grid that was a quarter of the size in each direction (resulting in a ~16x speedup) which, while a bit crude and not so pure, worked in practice. And a magical thing that popped out of this cruder grid? When you beat a level, it fills it in (at half of that resolution, every 8 pixels, for performance reasons with the display–this ain’t being done with shaders y’all) with circles of the appropriate color to show you the regions that you carved the space into. A nice reward for finishing a level (and something a few people asked about only to discover that it had already been implemented)!


If you like these sorts of things, you might enjoy hearing about new releases by joining the google group.

Block Party Kickstarter Recap

This post is well overdo and I’ve been away from the blog for a while. Better late than never.

The Kickstarter was a wild ride. We raised over $22,000 in 40 days and almost 500 people backed the project, most of whom we didn’t know! While I could go into what we did for publicity (cross-campaign promotion is great), the practices we learned (more frequent updates are apparently expected, though I usually think an email more than once a week is spam), or what we could have been doing more of (it worked really well in a classroom setting), I’m instead going to talk a bit about the emotional aspect of running a Kickstarter, at least for us.

Anyone who has done or is planning to do a Kickstarter has likely heard about the slow middle. In short, expect the middle section of your campaign to be crawling, where you have to actively be shouting about what you’re doing for anyone to hear or care. Well, we got into the beginning of our second week, experienced some cross-promotion (thanks, Primo aka Prime Climb!) and had our second biggest day of funding to that point after the launch day (several thousand in a day). Slow middle? Yeah right! We were rocking it!

And this is how the rollercoaster goes. After that wave of hype fizzled, we¬† were dead in the water. A couple backers a day, a few days we might have had nothing, and after that insane day it felt awful. My guess? Expectation. Watching the money just pour in the door is one of the most surreal feelings I’ve had. Replying to backers with thank-yous as they came in amidst fits of smiling and wide-eyed surprise/lack of ability to respond emotionally to what was happening, that really big and successful day was pretty draining (read: I was not prepared for it). It was also insanely gratifying and uplifting and validating. But three days later I had come down from the high, was experiencing the tiniest amount of traffic, and wondering if we’d fund at all (of course, as the money rolled in we were jumping up and down talking about how we’d fund next week).

Ours was only a moderate case. We did not get millions of viewers (or even tens of thousands) but I can only imagine what that must be like.

The lesson learned? Take each day as it comes, try not to set expectations except when they’re useful for making decisions, and don’t get too attached to what’s happening today because it most likely won’t last. Keep to the work and make better things because you love doing it.