Twofold Secret

Archive for the ‘Uncategorized’ Category

Goodnight, Nintendo Power

Tuesday, January 8th, 2013

The wellspring of nostalgia that rose inside me when I read that Nintendo Power was ceasing publication was inevitable. NP was the herald of a new age of video games: my era, not my father’s. He had bought an Atari 2600 when I was in elementary school and we played together a lot. Nearly all the games we were had were not very interesting played alone. Outlaw, Canyon Bombers, Ice Hockey — they were more like sports or board games than worlds to explore. Naturally, my father always held the upper hand when we played together. He had better reflexes than me, could anticipate things better, and could recognize patterns in a way I couldn’t as a kid. It didn’t hurt my feelings. It was just the natural order of things, and even so, I won some of the time too.

For those few 2600 games that really shone in single player, I was my father’s eager co-pilot. I remember him reaching the final level of Escape from the MindMaster, where the game took away the minimap you had relied on all game long and put you in a maze of tiny rooms, all alike. He opened the top drawer of his dresser — we played on the TV in my parents’ bedroom — and unfolded a map he had drawn on a sheet of notebook paper. It was inexplicable to me, that map. At that age, I couldn’t understand how you would even start to make a map like that. The game world was totally opaque to me. I could barely finish the first level of MindMaster on my own. I had to stick with the simplest variation of Adventure.

The NES changed the order of things between my father and I. He decided the console was not for him, period — one button was all he needed to play a game, he contended. And a few months after my parents gave me a NES for my birthday (with Contra and Zelda II — thank you, anonymous shop clerk who made those recommendations), they gave me a subscription to Nintendo Power. I didn’t know how good I had it.

The NES era fully ushered in video game lore into my consciousness. Before, being good at video games was mostly a matter of reflexes and improvisational tactics. It was in the NES era that I had to learn a video-game world — where all the secret powerups were, how to navigate the world, what order to do things in. I think it was first Metroid that I encountered an enemy that was completely immune to the weapon I had.

And I think it was in this aspect that Nintendo Power really made its mark. The blatant self-promotion inside its pages is tacky in retrospect, but what remains fascinating to me are the guides that were produced as part of the magazine, in particular the in-depth ones. When I first read them, they were kindling to my imagination– I would actually imagine playing the games in the magazines. But now, the maps in Nintendo Power look eerily similar to the kind of documents someone would draw up while designing a game — or maybe I should write, they look eerily similar to the documents I draw up when I design games now. Nintendo Power might be the first game design teacher I ever had, though I didn’t know it.

Of course things have changed considerably since 1988, when it was first published. The Web has in large part replaced the need for printed guides, of course. (Is GameFAQs still the leading source for that kind of thing? The site looks so dated now.) But more importantly, game design is a topic of lively discourse, not just something that accidentally is packaged up in a two-page spread on how to beat level 3. Most excitingly, it’s a discourse that game designers are taking a much more active part in, not just game players. I find every postmortem on Gamasutra a fascinating read, even when I haven’t even played the game the article describes.

So thank you, Nintendo Power. I treasure you in the oddest way.

Adventures in Shading

Friday, August 24th, 2012

When LÖVE 0.8 was released in April, there were two main changes that drew my eye. First, it did away with Power of Two Syndrome, to which my reaction was: oh thank you. At that point, we were embarking on testing Sought and while we hadn’t yet run into someone whose drivers had this issue, it had all the makings of a nasty bug that would take some care to work around. The second change was the addition of pixel effects. To quote the breathless wiki entry:

Potential uses for pixel effects include HDR/bloom, motion blur, grayscale/invert/sepia/any kind of color effect, reflection/refraction, distortions, and much more!

To which I thought: cool. As I’m sure you’re aware, our games invoke a low-fi, retro aesthetic. As an emulation junkie ever since I found out I could play Atari 2600 games on my Power Macintosh 5400 (rest in peace, emulation.net), I knew people had written code to simulate the artifacts of an old television set or arcade monitor, and I knew that these effects could add a lot to the atmosphere of our games.

I don’t think either Joel or I have been very concerned about the authenticity of our games — e.g. whether or not Where We Remain could have been a NES game (which it couldn’t, not with our color palette and screen resolution). But I do agree with Jason Rohrer’s argument that the retro aesthetic goes beyond flat, sharp blocks of color. I think there’s something interesting in the analog artifacts of actual, not-yet-perfected hardware married to the idealized and brutal digital.

First Time Out

So I tried my hand at a pixel effect, just to get a sense of how hard it would be. I failed miserably. Pixel effects are written in a language called GLSL — not to be confused with HLSL, which is the DirectX take on the concept — which is essentially a stripped-down C dialect with a stock of vector- and matrix-related functions. Well, not exactly. They’re actually written in a LÖVE-specific thin layer of syntactic icing on top of GLSL. For example, the type sampler2D is #defined to Texture, which makes it a bit clearer as to its meaning, I suppose. LÖVE also takes care of the boilerplate of setting up a GLSL fragment shader, which incidentally is just the tip of the iceberg of 3D graphics jargon you encounter when you start working with this stuff.

(In plain English, a fragment shader computes the color for a single pixel of a 3D polygon, given a texture and pixel position. Its counterpart is the vertex shader, which manipulates the vertices of a polygon. As far as I can tell, shaders don’t have anything to do with color per se; the term seems to refer more to the idea of shading in a rough sketch.)

Anyway, I don’t think this icing is all that helpful. Right now there is very little documentation out there on how to write a LÖVE pixel effect (guess why I’m writing this blog entry?), though there are a bunch of examples on the forums. On the other hand, there are oodles of material on the web that explain GLSL, and similarly large amounts of sample code. If you can’t translate between GLSL and LÖVE’s dialect, they won’t do you any good, so you end up learning GLSL anyhow. It’s sort of a moot point, as it’s perfectly fine to use the GLSL types instead of LÖVE’s, and if you really, really want to, you can disable the sugar entirely.

That was my next stop. I tried plugging in a shader I found on the web — I forget which one, but it crashed and burned with a cryptic syntax error. In retrospect, I’m not sure if I just copied and pasted incorrectly or the shader expected a different version of GLSL. It’s hard to interpret error messages when you have no idea what you’re doing.

So to sum up, pixel effects are not something you can create without knowing at least a little bit about 3D graphics, nor can you plug in existing GLSL fragment shaders on the web as-is and expect things to work magically.

And Now The Learning Can Begin

I finally had some time in the last two weeks to dive into learning PixelEffects. Here’s a link-primer for those, like me, who are coming to the subject with nearly nil pre-existing knowledge:

  1. What-When-How’s introduction to GLSL shaders, parts 1 and 2. This doesn’t even talk about writing shaders per se, just the language itself. I actually read these twice: when I was first starting out, then after I had written a few effects. The second read settled things in my mind. After I finished, I finally felt competent.
  2. Gaussian Blur Filter Shader. Don’t worry about the math used to compute the blur too much — this is just a super-short example of a shader that is reasonably easy to understand.
  3. The GIMP documentation on image convolution. Image convolution is a simple but powerful technique that maps well to a pixel effect. It boils down to taking the average of pixels surrounding a single one, but how you weight that average dramatically changes the end result. You can blur, sharpen, and detect edges with the same algorithm. This documentation page is super light on the math, and has some nice examples.
  4. OpenGL GLSL Manual Pages. Your basic function reference.

There are a few things I know now that I wish I had known back when I first started out. First, texture coordinates have nothing to do with pixels. They instead range from 0 (top or left corner of the texture) to 1 (bottom or right corner). To translate these to pixels — e.g. to find a pixel adjacent to the current one — you need to know the size of the texture and multiply accordingly. The accepted practice seems to be for external code to tell the shader this through a uniform (or extern in LÖVE land) variable.

Which brings up the point that if you want to do post-processing effects in your game, you need to use a LÖVE canvas to do so. A pixel effect normally acts on each image or shape you draw individually, but this causes problems if you need the pixels of separate images to interact with each other– when blurring, for example. Instead, you need to draw the entire screen in an offscreen canvas, then draw the contents of the canvas onscreen using your pixel effect.

The problem with this is that not all graphics drivers support canvases. But in my limited testing, those drivers that aren’t canvas-capable aren’t capable of pixel effects, either. So that moral of the story is that if you want to embrace all possible users, you can’t depend on a pixel effect to convey something essential to the player.

Finally, for loops are ridiculously slow. Really! I tried using a set of nested for loops to implement a 3×3 convolution matrix and it was astounding how slower it was than an unrolled loop. Because I am just a mortal, I am willing to accept it as just one of life’s little WTFs and work around it.

Going Back To Last Century

Once I had a handle on GLSL, My first thought was to try porting an existing retro effect to LÖVE. The most common monitor effect in emulators is Blargg’s NTSC filter, which actually goes to the trouble of converting the pixels into an analog signal, then simulating a television poorly interpreting that signal. It looks really good… but it’s licensed under the LGPL. Porting it to GLSL would count as a derivative work, which would introduce a slew of license considerations. I was hoping to include the shader with Zoetrope, which is zlib/pnglib licensed.

I think the LGPL is completely right for this kind of work, and obviously it’s Blargg’s moral right to decide how his or her work is licensed anyhow. So it was time to dive in for real.

I knew that writing something that literally simulated an analog signal would take a lot of effort, so I did some research and it seemed that simulating an old monitor had these effects:

  • Scanlines. People who use MAME sometimes try to emulate the aperture grill on arcade monitors, but when I tried it, it obliterated the image unless it was at 3x or 4x normal size.
  • Screen curvature.
  • Color smearing and fringing. (You can see it in closeups of old television screens and monitors, but boy is it difficult to quantify exactly what this is.)
  • General blurriness and/or bloom as lighter phosphors bleed into darker ones.

Once you give up the idea of actually simulating analog signals and rabbit-ear televisions, there are no hard and fast rules to creating an effect. There are many possible takes on the concept and none can really be considered definitive; it’s all up to taste. And besides– after playing some old games with a critical eye to the NTSC filter, it really does reduce the original pixels into a muddy mess. There had to be a decent middle ground.

I tried a lot of different approaches. Some did well with dark scenes but not well with bright ones. Some worked better with text than others. After a couple days of experimentation, my eyes started to hurt in that peculiar way they do when I’ve spent a lot of time designing color schemes for web sites.

It led to some interesting, bizarre effects.

At one point I had turned my shader into an illegible, blurry, washed-out mess. I put it aside and wondered if I just didn’t have the chops for it after all, or that I would have to learn the ins and outs of NTSC in order to get something that actually looked good. But mostly I thought instead of coding. I think you have to give up on big problems for a little in order to solve them.

Inspiration returned a day or two later, when I decided to start playing with the different filters on the emulators I had on my computer. Kega Fusion displays a screenful of static when you first boot it up; a nod to the old days of channel 3. But, as crazy as it sounds, the static looked perfect. I couldn’t distinguish it from a TV screen. I tried Ecco, my favorite Genesis game, and the effect wasn’t perfect but still compelling.

Kega’s menus make it manifestly clear the post-processing effects it uses: it does a bilinear filter on the image to blur it, applies scanlines at the intensity you select, and allows you to adjust the brightness of the image to compensate. All of these things are easy enough to code, and when I finished, the results looked good to me.

For fun I added a noise filter to it, which — to bring us full circle — is not particularly authentic, but I think it’s atmospheric. Here’s the source code.

In Closing

I’m hoping to roll pixel effect support into the next release of Zoetrope. I was hoping to offer people a way to use them without having to roll up their sleeves and understand their inner workings, but it doesn’t seem possible for now. There are just too many details that need understanding.

But more than that, I’ve enjoyed dipping my toes into the world of graphics. It’s a complicated, weird world full of words that seem to carry one meaning at first glance (shader, convolve) but hold another when you really understand them. It’s fascinating that way.

The Buddy System

Friday, March 2nd, 2012

We’ve been experimenting a lot with our creative process. For a few months after we released Alight, Joel and I both worked on separate projects in some sort of creative version of communism. From each according to their ability, to each according to their need, right? Joel would do graphics for both projects, I’d write code for both, but we’d work separately on the design and story of each one. It was an interesting experiment but not a successful one. We divided our talents more than we combined them and neither of us was that in love with the other’s idea, so instead of working hard on one project, we half-heartedly worked on two.

Now we’re working on a single concept, but we’re still tweaking our workflow. Although Joel and I live only about 25 minutes apart from each other, in the past we mainly worked together via IM. It was one of the laziest possible ways to collaborate, and though it worked fine for our previous projects, it seemed silly to use long-distance collaborative methods when we had a simple, powerful one easily available: just hang out.

We’ve had a standing weekly game-making date night since the new year, and I can say that it’s been an unqualified success for me. I’m having more fun working on this game, it’s inspired me to work harder in general, and I’ve got more structure when I code on my own. On random weekday nights, instead of throwing random features in based on what I think is needed or (more realistically) what’s interesting to code, I’m thinking about what I can work on that will make our in-person sessions productive. When we’re together, it feels like we’re playing creative leapfrog. I’ll add a feature, Joel fleshes it out with graphics and sounds. Joel builds out a level and needs a locked door, so I add that in. Synergy has become a buzzword but it’s the best word I can think for it.

(Joel, I am also finding out, mixes a mean gin and tonic.)

I’ve also been thinking a lot about how to structure our code. Lua imposes a lot less structure on your code than the Java-inspired ActionScript ever did. At first this is scary, as it’s easy to shoot yourself in the foot. My constant, annoying refrain when we’ve been working together has been you forgot a comma. But once you realize it’s not so bad — at least, no worse than JavaScript — there are some interesting possibilities.

I’ve been thinking about ways I can make Joel more productive as a designer, e.g. how to make it easier for an idea in his head to become an actual thing he can test out. I think the most succinct way to explain how I’ve been doing it is, I’ve been separating configuration from mechanism.

To give you an example, we have bullets in our game. (Quelle surprise, right?) Joel as a designer isn’t particularly concerned with how a bullet aimed at a particular position onscreen decides how to set its velocity components. He is, however, very interested in the sprite each type of bullet uses, and how much damage it does to something it strikes. I’ve split up the definition of our Bullet class into two files. One is the traditional class definition with methods that handle aiming, playing the appropriate sound when it hits a wall, and so on. The second is full of statements like:

Weapons.basicBlaster.bullet = { width = 16, height = 16, damage = 10, speed = 800 }

It’s code, but only just barely. It’s closer to shudder XML in that it describes data only. So what? you may ask. This could easily be done with constants inside the class definition. But there are two advantages here:

  • All of the data that we could consider user-accessible sits in a separate file — there’s no way to mess up the core behavior of the class by accident, nor does Joel have to understand a line of my code.
  • More importantly, it’s considerably easier to add new content. Imagine we have a Turret sprite set up in DAME that has a property named bulletType. To make a turret shoot a wholly new type of bullet, all Joel has to do is change the bulletType to a new name, then add a corresponding entry in the configuration file. I don’t have to write any code myself to make it happen.

We’ve never separated mechanism and configuration this much previously; each time we needed to load some data from text file, I had to write a custom importer. It’s not difficult, but it is relatively time-consuming, especially because the easiest format to parse is CSV, but CSVs are brittle. Imagine that you decide a CSV list of enemies should have its lines formatted in this order:

  1. X position
  2. Y position
  3. Enemy type

It’s fine until you realize you need to add a z-index so that bird enemies appear above snails. Either you append the new bit of data at the end of the line, which gets awkward as you keep amending the format, or you rewrite the importer to do the right thing. Either way, you’re spending time working on things that are not actively making your game better.

I realize this approach is adding complexity. It’s dangerous to spread the definition of a class out among several files, since you don’t want to play hide-and-seek in your code. But I think putting require 'settings.weapons' at the bottom of a source file is clear enough. The closest analogue I can think for this separation is the classic .c/.h division the C language makes.

It remains to be seen how effective this will turn out to be. We only started doing this last week, but it feels intuitively to me that we are going in the right direction. Ironically, the more independent we can make ourselves, the more productive I think we’ll be.