Barcamp Montréal 2 Wrap-up

May 2nd, 2007

Barcamp went well. Somehow I wound up being the first presenter, but that was fine. I was able to get a network cable for my laptop, so the demo from my side went smoothly. However, there was something funny about the wireless at the SAT, so I don’t think anyone else was able to get Mujax to work quite right. That was unfortunate. Also strange was that there weren’t many questions. Evan asked all of the questions and had a good suggestion about how I might be able to easily get a lot of content into the system, but everyone else just stared blankly. Perhaps this had something to do with the fact that no one had had their coffee yet. Or maybe Mujax isn’t very interesting to people who are primarily concerned with making a living working on the web.

The rest of the day was pretty good. There were some very engaging speakers and some real snorers (I think I may have been one of the snorers, actually). I’ve decided that it’s really important for PowerPoint slides to be somewhat entertaining and it’s really boring when people put too much info on their slides and then just basically read back that information, embellishing only slightly.

I made picture notes again, but rather than post them all here I’ve created a set on Flickr. If you want to see actual photographs of the event you can look at the barcampmontreal2 tag page.

IGDA GameCafé Report

April 26th, 2007

Last night I attended the second GameCafé held by the Montréal chapter of the IGDA. Due to the fact that people who ordered food received it a little bit later than anticipated, discussions started an hour late, which meant I spent most of that hour listening to Phil and Antoine trade quotes from Anchorman.

Jason Della Rocca, the IGDA’s executive director, preambled the discussions by relating a recent exchange he had with Jack Thompson, an infamous anti-games attorney, who called him an idiot and a jackass on MSNBC. This was apparently in response to Jason calling him out as a massacre chaser. Anyway, you should check out Jason’s post about his e-mail exchanges with Thompson, for the full story.

Industry discussion notes.The discussions I took part part in were decent, for the most part. Digital Distribution was once again lauded as the exciting new business model that will enable indie developers to carve out a niche in the marketplace, but that super publishers like EA will continue to dominate in the retail sector. *yawn*

Micropayments were mentioned and someone pointed out that Asia is way ahead of the West in this regard. Apparently they have made it exceedingly easy to pay with plastic over there, even going so far as to build card readers directly into laptops. This is pretty interesting to me and I wonder when/if it’ll catch on in the West.

Studio discussion notes. At the table about Studio level Future of Work, there was discussion about whether teams that are geographically separated and communicate only over the internet will become more common in game development. The consensus seemed to be that it could work, but meeting in person at least once goes a long way towards creating team cohesion.

I’m a big fan of long-distance collaborating. I’ve made songs with people I’ve never even met in person. However, I think that with music the medium itself is a kind of communication. It is, in fact, easier to understand what someone is going for if they just record a bit of music than if they try to describe it in words. I think this falls apart a bit when dealing with a game because it is audio/visual/interactive; there is no single medium that can act as an intention carrier. For this reason, it seems to me there will always be the need for teams to work in the same physical space. I find that when I’m trying to figure out a programming problem, it really helps to talk it through with someone in person.

Career discussion notes. At the Career discussion table I felt like there was a bit too much focus on working in a studio. But good things were said about how people tend to be happier when they are busy, even if they are not super thrilled about the game they are working on. On the other hand, if it is clear to everyone that their game sucks, it can be really demoralizing. I floated the idea that studios ought to work it out so that when people finish a project, they just get a week or two of paid time off so that they can recover and be ready for the next project. The way it is right now, people are typically pushed onto a new team immediately after finishing a project, even if the new team doesn’t need them right away. Much twiddling of thumbs follows and people get bored and restless. The only difference from paid time off is that they are required to come in to work and occupy a chair. It was mentioned that at least one game developer in Montréal is trying to implement some training programs, so that people can work on improving their skills during downtime, which sounds like an excellent idea to me, but that it’s not very organized yet.

There were many comparisons to the movie industry made during table discussions and also in the final roomwide discussion at the end. This seems to happen every time developers get together to talk about making games. It’s usually mentioned that the game industry is young and is similar to the movie industry of the early 20th century, mimicing the studio model. This comparison is then used to speculate about the future of how work will be parceled out (i.e. outsourcing) and whether that will be good for the industry. People will point to the movie industry and hold up independent film as proof that a change in the distribution of work can only be good, but I’m not so sure I buy that.

Making games is complicated. Possibly more complicated than making a feature film. Part of that is due to the lack of really good high-level tools for making games, but I think part of it is also inherent to the medium. One can view film production as a series of discrete processes: write the script, shoot the footage, edit the film, apply special effects, record the score and foley. Each of these activities can happen pretty much independently of the others. Also, there is usually no going backward. People don’t often decide to shoot more footage once they are in the editing process. Games don’t really work this way. You can’t really decide if your gameplay is any good until you actually implement it and play the game a bit. So you can’t really separate the design of the gameplay (i.e. scriptwriting) from the implementation of the gameplay (i.e. editing?). You see how my analogy is already falling apart? I think developers would do well to stop thinking about how they need to catch up with the film world in terms of work flow and process and what have you, and start focusing on what is good for the medium of games, specifically. No one knows better how games are made than the people who are making them.

Paradigm Shift?

April 25th, 2007

Ever since reading this post about moving the Start menu to the top of the screen, I’ve occassionally considered it. I’ve also often found myself wishing that the Quick Launch toolbar in Windows behaved a bit better so that I could actually have it set on auto-hide and not have it jump out every time I try to use the scroll bar on a full screen program. In fact, I found myself wishing it would behave more like the Dock on a Mac. Well, recently I came across a program called RocketDock that emulates the Dock on a Mac and also is as customizable as the Quick Launch toolbar (moreso, actually).


My new desktop configuration.

It hasn’t broken my computer yet, so I feel pretty good about recommending it to people who maybe wish their PC was more like a Mac. One nice feature is that you can set it so that when you minimize something it becomes an icon in the dock and disappears from the Start bar. This helps keep the Start bar uncluttered when there are a lot of programs open but many of them are minimized. One down side to this is that when an icon does the little bounce thing to get your attention, it doesn’t bounce onto the screen. This means you have to periodically check the dock to see if any of your minimized windows are trying to get your attention, like an IM window or something.

Since I now I have Dock-like shortcut bar, I thought I’d just go whole hog and move the Start bar up to the top of the screen. It’s a little strange, but not so bad. I’ve locked it so it doesn’t have the funky looking beveled edge that it does when it’s resizable. The other thing I’m trying to retrain myself on is using the button on the side of my mouse to bring up an the application switcher instead of mousing up to the top of the screen and clicking on the program tab, or worse, mousing over to make the dock appear so I can click on a minimized window. If I’m switching back and forth between two programs, which is often the case when I’m working on the port or the unit test suite for the port, all it takes is two clicks of the mouse button to switch to the window I want.

I’m not entirely sure what it means to be rocking such a faux-Mac desktop. Maybe it just means that OSX has a better UI. In any event, it’s a nice change of scene and will hopefully reduce some unecessary mousing around and clicking.

Barcamp Montréal 2

April 24th, 2007

I will be giving a 15 minute presentation about Mujax at Barcamp Montréal 2 this Saturday, April 28th. It takes place at the SAT and starts at 9:30 am. Other topics range from “taking photographs with cheap drugstore cameras”, presented by Simon Law, to “everything you wanted to know about the sex trade in Thailand but were afraid to ask”, an already controversial presentation by Madame Woo.

Barcamp is an unconference where all of the attendees are also participants. If you attend Barcamp you must either give a presentation or contribute to the event in some other way (like helping to set up).

The Dreaded Double Diamond

April 19th, 2007

So I’m porting the graph packages from Ptolemy II to C++ and I’ve finally gotten to the point where I can unit test some of it. I was going to start writing tests for the Graph class but when I ran the suite I got errors about some missing implementation in the graph library. A couple of those were methods I did actually miss, but one of them turns out to be the result of multiple inheritance. When you read about multiple inheritance there’s always mention of the dreaded diamond. Well, after sketching out the inheritance tree I’ve discovered I have a case of the dreaded double diamond!

The Dreaded Double Diamond!

This is what the Java inheritance tree looks like. However, it should be noted that all of the Analyzer classes are Java interfaces, which means it makes perfect sense in Java. However, porting this over to C++ is a bit stickier. My initial response to it was “this is silly”, so I broke the Analyzer-Strategy connection and the CachedStrategy-GraphAnalyzer connection. This prettied things up quite a bit. However, now it’s come back to bite me in the ass!

Analyzer defines a pure virtual toString() method. CachedStrategy implements a virtual toSting() method but it is not overriding Analyzer’s because it is no longer deriving from Analyzer. SelfLoopStrategy also implements a virtual toString() method and I thought that this would work not only as an overriding method for the implementation in CachedStrategy, but also as the implementation required by Analyzer. But this is not the case. As it happens, elsewhere in the code, toString() is invoked on a GraphAnalyzer and it doesn’t know where to find the implementation. This makes sense after reading about the subtleties of multiple inheritance. The question I am faced with now is whether I want put the double diamond inheritance scheme back into the C++ code. It makes me a little uneasy is all, there’s this little voice in my head saying, “there’s got to be a better way!”

If I was to use the double diamond, I’m pretty sure the way to handle it would be for Strategy and GraphAnalyzer to inherit Analyzer virtually and then for CachedStrategy and SelfLoopAnalyzer to inherit from GraphAnalyzer virtually. This would give SelfLoopStrategy the responsibility of calling the constructors for GraphAnalyzer and Analyzer. Oh multiple inheritance gurus, have I got that right? Is there a better way?

Live Code v01

April 19th, 2007

Last night I was thinking about live coding and also about how Java has reflection built into it. So, even though there is a forum topic about live coding with Processing, I decided to code up a simple sketch that evaluates a single line of Processing code and continually draws the result. There are drawbacks, of course, namely that you can’t specify fills or stroke colors and you can’t change the background color. However, in the next iteration I plan to ditch the textfield being used and instead use a textbox that will be evaluated in draw without the user having to press the enter key. Probably I should check out the tools talked about in the forum topic, but I like the idea of having a sketch that is itself an interpreter, rather than using a more generic tool for evaluating Java. Then again, I may discover that building something even marginally useful is more complicated than I care to implement, at which point I will probably turn to an existing tool. In the meantime, please enjoy:

Live Code v01

Code Highlighting Is Go!

April 2nd, 2007

It’s really great when you discover that people have already done exactly the thing you wanted to do. I went from thinking I needed to write my own code highlighting plugin for Wordpress to not only finding out that someone has already written one, but that it is also built on a generic code hightlighting engine that is easy to add new languages to. Then I figured I’d need to add Processing as a language to GeSHi, or at least add to the Java file. But someone already did that, too! So now I have lovely, simple code highlighting that is the same as the code highlighting in the PDE.

Sweet.

Minim: An Audio Library for Processing

March 27th, 2007

It’s here, the first release of my audio library for Processing: Minim.

Here are some of the cool features:

  • Released under the GPL, source is included in the full distribution.
  • AudioFileIn: Mono and Stereo playback of WAV, AIFF, AU, SND, and MP3 files.
  • AudioFileOut: Mono and Stereo audio recording either buffered or direct to disk.
  • AudioInput: Mono and Stereo input monitoring.
  • AudioOutput: Mono and Stereo sound synthesis.
  • AudioSignal: A simple interface for writing your own sound synthesis classes.
  • Comes with all the standard waveforms, a pink noise generator and a white noise generator. Additionally, you can extend the Oscillator class for easy implementation of your own periodic waveform.
  • AudioEffect: A simple interface for writing your own audio effects.
  • Comes with low pass, high pass, band pass, and notch filters. Additionally, you can extend the IIRFilter class for easy implementation of your own IIR filters.
  • Easy to attach signals and effects to AudioInputs and AudioOutputs. All the mixing and processing is taken care of for you.
  • Provides an FFT class for doing spectrum analysis.
  • Provides a BeatDetect class for doing beat detection.

Visit the download page, then take a look at the Quickstart Guide or dive right into the Javadocs.

Why Make Video Games?

March 27th, 2007

I’m pretty new to this whole video game programming thing and because of that I’ve been asked in a couple of interviews why I want to make games. I think it’s an important enough point to address here.

Large Problem Space

Writing video games means knowing at least a little bit about a whole lot of stuff: graphics, sound, physics, collision detection and response, decision-trees, state machines, animation, UI, character control, camera control, etc. If you are making a game that focuses on a unique mechanic or some kind of real-world modeling you might have to learn a bit about something that isn’t normally included in a game.

For example, when Heather and Phil wrote the design for Glee, they initially decided that they wanted actors in the game to respond to individual instruments in the music. That would have meant diving into the complicated field of music information retrieval. I told them tracking individual instruments would be way too hard but that we could probably track beats. So, we went with that and I spent about a month reading up on beat detection and implementing an algorithm in Processing (which has since been improved upon and incoporated into my audio library for Processing, Minim).

Getting to learn about all these different problem domains and implementing workable solutions (even if they are simplistic, like using only circles for collision detection) is a lot of fun. I love learning about new things and I love it even more when I feel like I have a strong enough grasp on the subject to use it in some meaningful way. Since the problem space will likely change from game to game, it means that there will always be something new to sink my teeth into or an opportunity to revisit a problem that I haven’t thought about for a while.

Pretty Pictures

Games never use the standard Windows GUI. That’s cool. It’s nice to work on something that doesn’t look like every other desktop application. It’s nice to work in 3D where I feel like there’s something to explore out there. It’s nice to just be able to rotate around 3D models, even. Making a game feels so much different than writing a web app or other standard GUI based app. It really changes my relationship to the software.

Interactivity

Games are interactive, but more than that, games are usually highly reactive. A game responds to user input in more ways, and in more unpredictable ways, than a spreadsheet or a word processor or an audio editor. Not only is it a lot of fun to program that reactivity, but it is also a lot of fun to test it, to find the quirks in it, to iron those out, to be surprised by something you’d never imagined happening. It’s a huge payoff to design a procedural animation or actor state system with lots of different behaviors and transition cases and then to see it actually working the way I planned. I mean, it’s way cooler than seeing the chunk of HTML I requested from a web server show up in the place on the page where I wanted it to appear, even if I’m using the AJAX technique to make it happen.

Fun

Games are fun (if they’re good, anyway). I like making something that is fun to use. I like watching other people play the game I’ve made, with a smile on their face. This was really brought home to me at GAMMA 01. I got to see the game I’d programmed up on a big projection screen, vector graphics smiley faces pulsing to the music, being played by all sorts of people. Every time I went by the computer, someone was playing the game and enjoying it. That’s awesome! When I get to work on a game that is commercially released and hopefully get to see people enjoying it in their own homes, investing time in it like I’ve invested time in great games like Katamari Damacy, Guitar Hero, Elebits, and Okami, that’s going to be even more awesome.

FFT Averages

March 21st, 2007

This post assumes you already know what an FFT is, so if you don’t, I suggest reading Chapter 8 and Chapter 12 of The Scientist and Engineer’s Guide to Digital Signal Processing. What I’m going to discuss is two different ways of averaging contiguous bands of an FFT. Before I do that, I’d like to review exactly what the frequency bands of an FFT represent.

What’s In An FFT?

Let’s say you have a sample buffer that has 1024 samples in it. If you run this through an FFT you will get a frequency domain described by two arrays that are each 1024 values long. However, typically the values in these arrays are not used directly. Instead, each pair of values (real[0] and imag[0], real[1] and imag[1], etc) is used to calculate the amplitude of each point in the FFT and that value is then used as the value of the spectrum at that point. Even more confusing to those new to the FFT is that the spectrum of 1024 samples is only 513 values long (the array runs from 0 to 512). The reason for this is because the values above spectrum[512] are, in practice, meaningless because they represent frequencies above the Nyquist frequency (one-half the sampling rate). So now we’ve simplified our two 1024 value arrays down to one array that is 513 values long. What do these 513 values represent, exactly?

Each point of the FFT describes the spectral density of a frequency band centered on a frequency that is a fraction of the sampling rate. Spectral density describes how much signal (amplitude) is present per unit of bandwidth. In other words, each point of an FFT is not describing a single frequency, but a frequency band whose size is proportional to the number of points in the FFT. The bandwidth of each band is 2/N, expressed as a fraction of the total bandwidth (i.e. N/2, which corresponds to the point at one-half the sampling rate), where N is the length of the time domain signal (1024 in our example). The exceptions to this are the first and last bands (spectrum[0] and spectrum[512]), whose bandwidth is 1/N. This makes more sense when talking about actual frequencies, so:

Given a sample buffer of 1024 samples that were sampled at 44100 Hz, a 1024 point FFT will give us a frequency spectrum of 513 points, with a total bandwidth of 22050 Hz. Each point i in the FFT represents a frequency band centered on the frequency i/1024 * 44100 whose bandwidth is 2/1024 * 22050 = 43.0664062 Hz, with the exception of spectrum[0] and spectrum[512], whose bandwidth is 1/1024 * 22050 = 21.5332031 Hz. Knowing this, we can get on to the business of averaging contiguous bands.

Linear Averages

We’ve got an FFT with 513 spectrum values, but we want to represent the spectrum as 32 bands, so we’ve decided to simply group together frequency bands by averaging their spectrum values. The obvious way to do this is to simply break the 513 values into 32 chunks of (nearly) equal size:

int avgWidth = (int)513/32;
for (int i = 0; i < 32; i++)
{
  float avg = 0;
  int j;
  for (j = 0; j < avgWidth; j++)
  {
    int offset = j + i*avgWidth;
    if ( offset < 513 )
    {
      avg += spectrum[offset];
    }
    else break;
  }
  avg /= j;
  averages[i] = avg;
}

The problem with this method is that most of the useful information in the spectrum is all below 15000 Hz. By creating average bands in a linear fashion, important detail is lost in the lower frequencies. Consider just the first average band in this example: it corresponds roughly to the frequency range of 0 to 689 Hz, that’s more than half of the keyboard of a piano!

Logarithmic Averages

A better way to group the spectrum would be in a logarithmic fashion. A natural way to do this is for each average to span an octave. Starting from the top of the spectrum, we could group frequencies like so (this assumes a sampling rate of 44100 Hz):

11025 to 22050 Hz
5512 to 11025 Hz
2756 to 5512 Hz
1378 to 2756 Hz
689 to 1378 Hz
344 to 689 Hz
172 to 344 Hz
86 to 172 Hz
43 to 86 Hz
22 to 43 Hz
11 to 22 Hz
0 to 11 Hz

This gives us only 12 bands, but already it is more useful than the 32 linear bands. We could now easily track a kick drum and snare drum, for example. If we want more than 12 bands, we could split each octave in two, or three, or whatever, the fineness would be limited only by the size of the FFT.

Knowing what frequency each point in the FFT corresponds to, and also how wide the frequency band for that point is, allows us to compute the logarithmically spaced averages. First we need to be able to map a frequency to the FFT spectrum. These functions will accomplish that (timeSize is N):

public float getBandWidth()
{
  return (2f/(float)timeSize) * (sampleRate / 2f);
}
 
public int freqToIndex(int freq)
{
  // special case: freq is lower than the bandwidth of spectrum[0]
  if ( freq < getBandWidth()/2 ) return 0;
  // special case: freq is within the bandwidth of spectrum[512]
  if ( freq > sampleRate/2 - getBandWidth()/2 ) return 512;
  // all other cases
  float fraction = (float)freq/(float) sampleRate;
  int i = Math.round(timeSize * fraction);
  return i;
}

This may not seem clear at first, but it is simply the inverse of mapping an index to a frequency, which was mentioned above: Freq(i) = (i/timeSize) * sampleRate. Here’s how we’d use these functions to compute the logarithmic averages listed above:

for (int i = 0; i < 12; i++)
{
  float avg = 0;
  int lowFreq;
  if ( i == 0 ) 
    lowFreq = 0;
  else
    lowFreq = (int)((sampleRate/2) / (float)Math.pow(2, 12 - i));
  int hiFreq = (int)((sampleRate/2) / (float)Math.pow(2, 11 - i));
  int lowBound = freqToIndex(lowFreq);
  int hiBound = freqToIndex(hiFreq);
  for (int j = lowBound; j <= hiBound; j++)
  {
    avg += spectrum[j];
  }
  // line has been changed since discussion in the comments
  // avg /= (hiBound - lowBound);
  avg /= (hiBound - lowBound + 1);
  averages[i] = avg;
}

This is hard coded to compute only 12 averages, which is not ideal, but it would be easy enough to determine the number of octaves based on the sample rate and the smallest bandwidth desired for a single octave.

LinLogAverages is an applet demonstrating the difference between linear averages and logarithmic averages.