1. icon for News
  2. icon for TCHOW


Thursday, January 10, 2013

Rainbow - Post-Mortem (Part 3)

These posts tell the story of rainbow, my LD25 entry. In part 1 and part 2, I talked about ideation and the initial push to a working prototype. In this part I will talk about the refinements and polish I added to reach the finished version.

Sunday Morning: Sound

My Saturday prototype didn't have any sound, so I started out Sunday fooling around in Reason.

I decided to make the background music from a pair of loops (a dull "background" loop and a sparkly "rainbow" loop), which would be mixed according to level state. This seemed like a good option for getting some variability out of the music without having large downloads or making long tracks.

I additionally built some chords for when peons are enlightened, and a little arpeggio for when the rainbow starts.

Note: I took this screenshot on my mac laptop; however, I actually did the music stuff under Windows. This also meant that I had the chance to find a few OS-dependent bugs (most of the dev work was done under Linux).

To get the sounds into the game, I exported various tracks from Reason (selectively muting), then loaded them into Audacity where I trimmed and exported to ogg.

This is much the same workflow as I use for sound in rktcr. It's not very automated, which I think is something of a problem; but it certainly isn't one that I was going to solve during a time-limited game compo.

By noon, I'd added the last (crucial!) sound feature, muting:

I could have just turned off my speakers, but that would have interfered with listening to spotify in the background.

Sunday Afternoon: Polish

Going into the afternoon, I knew I had something that resembled a game, but there were many things that could be improved. I was pretty sure I wouldn't get to all of them, so I made a list and prioritized.

The first thing I added were peon textures. These tied the in-game experience to the intro and outro screens:

As you may notice, my first pass didn't actually change the peons' expressions, just their color. The fading turned out to be easy to add (~10 minutes more work), so I got that in next.

From there, I turned to the rainbow ends. I knew there needed to be some way to tell apart "live" rainbow (that could grow further) and "dead" rainbow (that had -- say -- enlightened a peon). My first attempt was to add fade-outs:

These turned out to be a bit too subtle, as you can see.

So I added sparkles:

I like these because they are higher-contrast than the fade-outs, they clearly indicate where the end of the bow is, and their motion makes them very easy to spot.

At this point, it was around 13:40 in the afternoon. There was a potluck I wanted to go to which started at 5pm; and I was treating this as my unofficial (early) deadline. So I didn't want to start any big changes on the game.

Unfortunately, I still wasn't quite satisfied with the way small rainbows controlled, and this was going to require a rather large chunk of refactoring to fix. Fortunately, the refactoring went better than I'd hoped and I had smoother small-bow control by 15:00.

As a bonus, the refactored control made it easy to draw sparkles that actually showed were controlled rainbows would be going:

This brought me to around 15:20, with the main game basically finished. Since I still had a chunk of time before the potluck, I added some animation (jumping/tipping peons) to the intro and outro screens, and drew additional title cards for these scenes.

At 16:30, I noticed things were no longer working in Firefox and had a 15-minute bug-hunt-scramble. I got the code up on my web page, figured out how to submit, and made it to the potluck by 17:30 or so. (Other times in these posts came from commit messages, the potluck arrival I just have to guess at.)

Final Thoughts

I think I did a good job on this project of picking something with a small scope, and getting it into a working state quickly. I also think I made the right choice by avoiding javascript frameworks and instead working directly with the default HTML5 APIs. This probably cost me some cross-browser compatibility, but it also saved a lot of reading documentation and fixing other people's bugs.

There were some ideas -- e.g. an overworld map to show level progress, color filters, mirrors -- that I could have added given more time. Specifically, the lack of an overworld makes it hard to know how long the game is, which is the biggest problem with the final version. There are also smaller things -- like optimizing the rainbow drawing -- which I would like to have done for perfectionism's sake, but weren't really required to make things work.

During development, I worried that the game was too easy. I had one of my neighbors play the first prototype, and they confirmed my suspicions. The player can see exactly where the rainbow will go, and there is no time pressure in planning its path. I wanted to fix this by having the rainbow constantly grow, but never got around to it. I guess I'm sort of glad that I didn't, as many of the comments on the contest page for the game talk about how hard it is.

Of course, these comments are wrong.

As a procedural note, I'm glad I sat down and rated a bunch of games (my brother helped by sitting with me and offering second opinions). Not only were there some real gems in there, it also meant that rainbow got rated a bunch of times. It's great to get feedback from so many people, and I'm flattered that folks found the game innovative.

Moving Forward

I find that I like this mechanic, and would enjoy producing an extended version of the game. However, my priority at the moment is rktcr.

Wednesday, January 9, 2013

Rainbow - Post-Mortem (Part 2)

In this series of posts, I talk about the process behind Rainbow, my LD25 game.

In part one, I described my failure to come up with a good idea while feeling sad. I resume the story on...

Saturday Morning: An idea

I woke up Satuday morning (probably around 10am -- lots of sleep is important for creativity) and decided that being sad was hard to do and wasn't getting me anywhere. So I sat down to do some more sketches.

I started with the anti-thief idea from Friday, which got me thinking about visibility rays. In turn, this led to thinking about light versus shadow, and I drew some pictures of houses with light streaming in through the windows. Of course, light that goes straight didn't seem to have much play-ability, so I started thinking about steerable light.

Which led me to the idea of steerable rainbows. This struck me as a good concept because rainbows aren't sad, and because thinner rainbows might steer differently than thicker ones. I also had some ideas for different mechanics like splitting rainbows, color filters, and color-limited targets.

Saturday Afternoon: Coding

With my idea in hand, I set out to build it in HTML5 using the canvas' 2D drawing API. My only previous experience in HTML5 was the tchow solstice card, and a few hacks for a (not yet published) study. (I generally work in C++ / OpenGL.)

Anyway, I sat down with an empty .js file and a pile of tutorials and started hacking together something I thought might work. By about 13:40 I had a really basic prototype in place, which was able to draw a level and a bit of rainbow that followed the mouse cursor's horizontal position:

This was good as far as showing that I was going to be able to work in HTML5, but it didn't get at the core of the game (steering the rainbow). By around 15:00 I had added steering behavior, though hadn't done collision yet:

I kept working on the steering mechanic, trying to get the rainbow to feel stately enough without being trivial. By 15:40 I had collisions and rainbow splitting:

It was becoming obvious, though, that the way the rainbow was being drawn (as one path for each color) wasn't correct -- it meant that certain colors were always on top, rather than fresher parts of the rainbow being on top. This wasn't going to cut it, graphically, so I started the process of going from 2D canvas drawing primitives to WebGL triangle drawing.

By 20:20 I had this working:

The jaggies are present because I turned off antialiasing to make it easier to spot bugs in the drawing. I ended up having to write my own thick-line-drawing because glLineWidth didn't do nice joins at corners.

With the evening growing late, I decided to push a bit more and wrap the game up in an intro and outro to explain the plot, and make levels winnable.

After toiling in inkscape to produce some pictures, and then figuring out how texture loading works in HTML5 (neat hack: if you don't want to deal with local file access permissions stuff, you can just base64-encode your textures into data urls), I had something looking relatively finished:

You'll notice that the peons have not yet been skinned (texture loading was used only for the intro and outro screens at this point). Also, at some point in this work, I added feature which allowed me to jump to any level by putting its index in the query string. This was useful for testing (and remains in the final version of the game).

At this point I had something that was winnable and had a beginning and end; and it was getting late (1:40), so I headed to bed.

However, the game was far from complete. The steering of thin rainbows was a bit glitchy, I hadn't worked on sound at all, and there was no indicator for which rainbow would grow next (or where it would grow to). Also, more levels were needed.

Of course, this is a story for the next post.

Tuesday, January 8, 2013

Rainbow - Post-Mortem (Part 1)

Well, that went well! Rainbow placed first in Innovation (and tenth overall) in Ludum Dare 25. (See also: results page, Ludum Dare page for Rainbow)

I've been meaning to write a post about how I ended up making Rainbow, and I guess that I might as well do it now, while the potential audience is larger than the usual set of {me, myself, I}.

Friday: Brainstorming, Sadness

Late on Thursday, I asked the coolest girl I know out. On Friday, she rejected me. This is relevant, because I was feeling rather melancholic; and I thought that perhaps I'd hold on to this feeling and use it to power a really emotionally charged game.

I went out to dinner with a group of friends who were all planning on making games for Ludum Dare. After the theme was announced, we threw ideas around. I found that -- being sad -- all my ideas were rather mealy and depressing.

One was to make a game where everything you do fails and you end up scapegoated and alone, despite your most nefarious (or beneficent) intentions. This sounded like a terrible idea; I imagine it would be like playing an angsty teen-age livejournal post. Also, it was really heavy on graphics and story assets, and I wanted to write some code, darn it.

A theme of the ideas folks were coming up with at dinner was reversing the hero/villain roles in an established game. Some nifty games came out of this (e.g. Tom7's Age of Umpires, David's Robot Revolution Dance).

Thus inspired, I did make some sketches about inverse sneaking games -- say, where you are a wealthy baron and want to populate the world with guards. This, I reckoned, might involve solving things like the castle and the princess puzzle. But I also figured that the level design was going to be hard-bordering-on-impossible. And I felt sad.

So I went home after dinner with a heart full of unproductive melancholy, and a head full of ideas that didn't really seem very good. Not a productive first night.

(Continued in part 2. Spoiler: I'm not very good at being sad.)