Wednesday, April 17, 2013

Symmetry in Games

As a part of the MochiPets project, I have been rapidly prototyping mini-games. This weeks game was Flip Puzzle, a game in which players flip a 3x3 area of tiles on a grid so that it will match the answer key. The core mechanic essentially being that the player needs to find the single (or multiple at higher levels) answer tile to flip that will cause the two grids to match.

I put together a couple different patters for grids spanning from 3x3 to 5x5, using the size of the grid and the number of clicks to determine difficulty. However, during play testing, I discovered something very interesting and unexpected. The symmetry of the puzzle was also a key factor in determining a puzzle's difficulty. Amongst the designed puzzles, there were puzzles with no symmetry, bilateral symmetry, and quadrilateral symmetry. Quadrilateral was least difficult, bilateral harder, and asymmetrical was the most difficult.

Once this realization came to light, it actually made a lot of sense. Our brains are designed to read patterns, and when something breaks that pattern a red flag goes off in our heads. By breaking the grids up into quadrants based on symmetry, we are easily able to distinguish which quadrant is the most problematic.

In the example above, you can clearly see that the bottom left quadrant is the most incorrect in comparison to the answer key. In fact, it is the exact inverse, so we can be reasonably sure that the tile we want to click is one of those four (it's the second column, third row ;) ). Because of this discovery, I divided the puzzles in each grid size into bins by symmetry and added this consideration to the puzzle generation algorithm.

This was a very useful discovery, especially for puzzle games! When making a game that involves patterns of any sort, whether it's pieces of a puzzle or ships flying at you, it's worth considering the symmetry of your design!

Thursday, April 4, 2013

RequestAnimationFrame in Processing.js

In the weeks since the Github Game Off, I have been working on making my game, PolyBranch, playable in mobile browsers. A huge part of this has been optimization. PolyBranch was written using slightly non-conventional, although hugely beneficial methods in that the core game was written in Processing (Java) and then exported to JavaScript via Processing.js from the Processing 2.0 IDE. This is the standard way of exporting your Processing sketches to the web, however, in addition to this I followed Pomax's guide to bind my Processing.js code and JavaScript code to each other, thus allowing myself to make calls to Processing with the site's JavaScript. This is how the majority of the event binding in the game was done, including the entire menu and any GUI elements. The big advantage of this is being able to write your GUI in straight HTML5. Being designed for making interfaces (websites), it is much easier to write your GUI this way than directly in Processing!

Now, back to my original point, what makes this so important is optimization. When developing HTML5 canvas for mobile, it has been widely accepted that JavaScripts requestAnimationFrame() function offers huge advantages over traditional JS timing functions like setInterval() or setTimeout (see Paul Irish's post for more info as well as the polyfill). Unfortunately, because rAF wasn't around when PJS was first written, it uses setInterval() instead. The good people on the PJS team are aware of this and hard at work on a fix, but just isn't there yet. So, because of this, I found a work around! Because I had already bound PJS and JS together so I could do the interface, I also handed control of the looping to JS entirely! This way, I was able to write a rAF loop which calls pjs.draw(), as I will demonstrate below:

First, binding JavaScript and Processing.js together (see Pomax's guide for more details)
I have had better luck with renaming my .pde file to a .pjs file at this point. This is a practice I have copied from examples around the web, although I do not know why it works. If anyone has an explanation, I would love to know! :)

Now that Processing and JavaScript can communicate with each other, we can use rAF to call Processing's draw function!

This is a very bare-bones demonstration of the draw loop. Be sure to check out Kushagra Agarwal's article on time based animations for best results!

As a disclaimer, I should note that I had moved over primarily to JavaScript development at this point in the process and was using this method so I could retain the logic I had written in Processing. I was no longer working within the Processing IDE! If you are using Processing.js as a JavaScript library, you can also check out this discussion from the PJS google group.