Most Significant Digit

Sunday, March 07, 2010

This blog has moved

Blogger is stopping its FTP publishing option, and it was time for a new website anyway. I've merged this blog with my portfolio. It's all at http://selenetan.com. This blogspot URL will stay up, but I won't be updating it anymore.

My NaNoWriMo blogs have also moved over to Blogspot:

Wednesday, February 17, 2010

Simple Sudoku and Modes of Thinking

A while back, I found Simple Sudoku, a freeware Sudoku puzzle maker/solver. It generates puzzles for you to solve, and also has a lot of features to make it easier to solve them. After playing way too much Sudoku in it, I realized why it makes things so much easier. On the surface, Sudoku is all about logical deduction--the 9 in this square means you can eliminate 9's elsewhere in the row and column, and so on. However, at higher levels, Sudoku is actually about pattern recognition, and that is what Simple Sudoku reveals.

One feature of Simple Sudoku is that it automatically shows the candidates for a square. This takes away the tedium of having to manually eliminate the obvious candidates, like 9's in a row that already has a 9. Still, the candidates sometimes look like a mess.
Simple Sudoku solves this with a feature called candidate filtering. What it does is highlight all squares that might be a particular number, e.g. all possible 9's. This makes it easy to see, for example, when there's only one possible 9 left in a column.
A screenshot of Simple Sudoku that shows candidate filtering on 6's. A now-obvious lone 6 in the rightmost column has been circled.
A screenshot of Simple Sudoku that shows candidate filtering on 6's. A now-obvious lone 6 in the rightmost column has been circled.

Candidate filtering is good for slightly more advanced deductions, as well. Let's say you have one 3x3 cell where all the possible 6's are in the same row. You can eliminate 6 as a candidate from the rest of the row. Or, visually, you can do this:

The same screenshot of Simple Sudoku with filtering on 6's. In the upper-right 3x3 cell, an arrow is drawn from the row of 6's across the row, showing that you can eliminate the other 6's.
The same screenshot of Simple Sudoku with filtering on 6's. In the upper-right 3x3 cell, an arrow is drawn from the row of 6's across the row, showing that you can eliminate the other 6's.

There is an advanced Sudoku technique called coloring or linked candidates. It involves forming a chain of candidate squares where you know that some of the squares contain the candidate, and the rest do not. However, which set of squares contains the candidate is unknown at the start. The technique involves "coloring in" the candidate squares in an alternating pattern, e.g. with blue and pink. If any pink square contains the number, then all pink squares will contain the same number, and all blue squares will not. The reverse is true as well.

The technique can be difficult to understand from a description, but in Simple Sudoku, it's really easy to do. Filter candidates so that, say, all 5's are shown. Find a place where there are only two 5 candidates in a row, column, or large cell. Color one of the squares pink, and one blue. Then continue the chain as long as you can find links where there are only two 5's. If you see two pink neighboring each other, then the pinks don't have 5's and the blues are the ones with 5's.

A screenshot showing two neighboring pink squares. Click to view an animation of the process.

Coloring turns a painstaking deduction problem into a simple pattern-recognition problem. Going through the chain of logic step-by-step takes a while and can be prone to error, but marking squares as colors is easy. And on the computer, it's easily reversible. I'll often start coloring squares even when "simpler" deductions can be made because in Simple Sudoku, coloring is a simple deduction.

In general, as you get better at a type of logic puzzle, you start recognizing common sequences of deductions. Internally, you formulate a series of rules: "If this, then do that." What Simple Sudoku and other good puzzle interfaces do is 1) Make it easier to notice common deductions, and 2) Make it easier to spot the "If this" part of your rules.

Labels: ,

Sunday, February 14, 2010

Prototype: Sideliner

One thing I noticed about the Ludum Dare Flash entries was that most of them were done with flixel. For the competition, I decided not to use it because I didn't want to learn a new library in the same 48 hours I had to make a game.

Anyway, I've finally gotten around to trying flixel out. I cast around a bit for a game idea that I thought would suit flixel's strengths. It's a game with 3 tracks where rocks come at you and you have to switch tracks to dodge them.

Play the Sideliner prototype

Unfortunately, it's not really fun. The graphics were also a pain. Rocks I can do; the drill took me at least twice as long.

Sunday, January 31, 2010

SEEK*TOR update

SEEK*TOR, my Ludum Dare 16 entry, now has a proper page on my website. I also took the opportunity to add a few niceties: a preloader, an instructions screen in the game, and the mute button reads "MUTE" and "UNMUTE" as appropriate.

Saturday, December 19, 2009

Fixed bugs in SEEK*TOR

I finally tracked down the bug in SEEK*TOR that sometimes makes the red enemy square (and some of the ally turrets) unclickable. While I was at it, I squashed a few more bugs I found along the way.


Play SEEK*TOR v 1.2

Changes in this version:
  1. Fixes bug where the upper-left turret is unclickable
  2. Fixes bug where sometimes the red enemy square is unclickable
  3. Fixes bug where on very high levels, the level never starts
  4. Turns off debug flag so turret layouts are randomized between 4 choices instead of just one
  5. Background music now loops
So what caused the unclickable-things bug, and how did I track it down?

With the help of debug output, I discovered that when a turret or enemy was unclickable, it was because something else on the screen "stole" the click event. In the unclickable upper-left turret bug, the click event was going to the flare display in the upper-left. In the unclickable enemy square bug, the click event was going to an object with a name like SpriteXXX. XXX was a number that was larger the later in the game the bug appeared.

The object name was my biggest clue. The number meant that it was a sprite that was created every level. The turrets are created anew every level, but they show up as TurretXXX. So I combed through the code until I found a sprite that was being created every level.

The sprite I found was the little explosion graphic that shows when you click on the enemy turret. In my competition-driven haste, I'd written code that created a new sprite every time the explosion went off, and didn't bother to make it unclickable, or remove it from the stage afterward.  To fix the bug, I modified the code so that it created the explosion sprite only once and reused it every level, and I made sure the sprite was unclickable. That fixed the bug.

Labels: ,

Monday, December 14, 2009

Post-Mortem: SEEK*TOR

 So this was my first Ludum Dare. I did the Global Game Jam back in February, so I had some idea of what to expect, although the GGJ was teams rather than solo. One thing I do regret is not interacting more with the community–IRC, Twitter, etc. I could have used more feedback than I got, instead of relying almost entirely on my husband’s comments.
Friday night I spent brainstorming ideas and thinking over mechanics. Saturday morning I started coding. By late afternoon / early evening, I had the major mechanics implemented, but it wasn’t fun. At that point the turrets were just yellow diamonds (and they were warp portals which your cyan circle teleported between), and the hint circle always disappeared before you could fire again.

Screenshot of older version of SEEK*TOR
Screenshot of older version of SEEK*TOR

The best thing that happened for the game occurred when I sent my Saturday prototype to a friend for feedback. He told me two very important things:
  1. He had the most fun figuring out where the hint circles intersected
  2. He wanted to know why you had to aim and fire to reveal the map instead of just placing light bulbs around the “platforms” (yellow diamonds)
So I made the hints persist but fade over time. That means you can see the hint circle intersections, but the screen doesn’t become overly-cluttered with old hint circles. It also means the aiming mechanic is important, since if you take too long, the previous hint will have faded away. I also changed the theming of the game so that the portals became turrets and you selected a turret to fire from, rather than teleporting between them.
Sunday was mostly a day of polish. The big feature changes were implementing multiple levels, scoring, and flare limits. I also added the start, game over, and between-level screens, made the graphics, (such as they are–hooray for GlowFilter!) composed a background track, and created the sound effects.
In the end, I was successful in terms of having a pretty-much finished game at the end. On the other hand, seeing some of the other entries, I kind of wish I’d done something a little more ambitious…
Things that worked out:
  1. Using abstract glow-y vector graphics instead of trying to draw. (I spent about 20 minutes attempting to draw a single turret before deciding my time was better spent elsewhere.)
  2. The game selects from 4 (hand-crafted) turret layouts and randomizes the enemy and player locations. That turned out to be enough randomization that I didn’t need to make a turret layout generator. In fact, I only just realized that I left the game in debug mode where it always chooses the same turret layout.
Things that didn’t work out:
  1. When I started, I implemented everything in one file just to see if the core mechanic would work. I made such a mess of my code that I spent hours late Saturday night moving code around so I could add levels. Spending hours working on code without actually adding new functionality–even regressing at times–was very hard on my morale.
  2. I spent too long trying to make my git history tidy. I’d keep forgetting to add a file to the commit or not commit for a while and wind up with a gigantic commit that involved 3 features and all the source files. Then I’d try to figure out how to break up or revise the commits. (And how to use vim, since that’s the default git editor…) Given that I never had to revert to a previous version, it was kind of silly of me.
Tools and Libraries Used:
  1. FlashDevelop
  2. TweenLite
  3. git
  4. ACID Music Studio
  5. Free VSTi soft synths: Crystal, LazySnake, and ErsDrums
  6. Audacity
  7. sfxr
(cross-posted from Ludum Dare)

Labels: , , , ,

Sunday, December 13, 2009

Finished my first Ludum Dare!

Sweet, I managed to complete my first Ludum Dare! I was thinking of learning Push Button Engine for it, but after going through a couple of tutorials I decided I’d go for straight-up Actionscript instead. PBE has some neat features, but I need more time to get my head around its component-based programming model.
Anyway, SEEK*TOR is a game where you’re trying to locate the enemy by firing search flares from turrets. You have limited flares, and turrets have a limited range, so you need to carefully choose where you aim. It’s in Flash.

SEEK*TOR Voting page

Incidentally, I’m annoyed with Audacity because it added an initial silence to all the mp3 files I encoded with it. So all the sounds come in late. :( Also, I just realized that I forgot to have the background music loop…

(Cross-posted from Ludum Dare)

Labels: , ,