Pac-Man

I've published my Pac-Man clone! It's not 100% complete, but this was just a learning exercise, and I think I've gotten enough out of it.

The bits that I didn't do:

  • Music: I wanted to record some simple background music in a particular key, and record the sound effects in the same key. They would combine produce a randomly generated soundtrack. I recently attended a talk at Freeplay by a guy called Stephan Schütze, who had lots of interesting things to say about procedural music generation. I may revisit this idea in a future project.
  • Artwork: There are some elements that I didn't bother doing (mainly the bonus symbols, which are represented as plain white squares). The ghost artwork is pretty inconsistent, too - ghosts look totally different when frightened. I would probably have fixed this, but my trial Photoshop license expired. (Do you know how much that thing costs nowadays?)
  • I skipped some behavioural details, like the way ghosts jostle around in the house when they're waiting to be released.

Other than those, it's a pretty faithful implementation of the game.

There are some technical decisions that I would make differently in retrospect. The following (non-exhaustive!) list outlines some choices that might have overcomplicated things:

  • Code structure: Programmers have a tendency to look for patterns and generalisations in code that can be re-used. In my case, I wanted to keep the engine code as simple as possible, and pushed all the behavioural bits and pieces (particularly the ghost releasing and mode switching behaviour) down into objects (i.e. DotCounter, ElroyCounter, ModeSwitcher and ReleaseTimer). I don't think I hit a particularly sweet spot of abstraction by doing that – it would probably have been nicer to keep it all nearer the surface.
  • Movement: I got overly concerned about actors moving in sub-pixel increments. That is, the ghosts and Pac-Man can have speeds of e.g. 1.2 pixels/frame, but you can't draw inbetween pixels on the screen. I came up with some rather complicated code to accumulate fractional pixel amounts between frames, but it would've been much easier to store the raw values and round to the nearest pixel when drawing. Check out Actor to see what I mean.

There are plenty of other warts in the code, but it works OK.

The playable version is at http://www.harto.org/wheel/pacman. It works in recent versions of Firefox, Chrome and Safari (without sound). The source is at https://github.com/harto/pacman.

Let me know what you think!

Simple JavaScript dependency analysis

One of the most glorious forms of procrastination for a programmer is developing tools that automate menial and repetitive tasks. I've wasted lots of time on little Python scripts that generate Java classes, remove unused rules from CSS stylesheets, and all kinds of other unnecessary stuff.

My latest invention is a program that does a simple analysis of JavaScript files to determines the order in which they should be concatenated.

Concatenating multiple JS files is a simple optimisation that reduces the number of HTTP requests between a browser and a server. However, they need to be concatenated in the right order so that objects and functions are defined before they are referenced.

The program works by scanning JSLint /*global ...*/ declarations to determine the JavaScript variables referenced by each script. It then looks in all other scripts to figure out which one defines each variable. This results in a dependency graph that maps each file to each of its dependencies.

Once the dependencies are known, the program determines the concatenation order by inserting files into a list, one at a time. Each file is inserted after all its dependencies. If any of the previously inserted files references the newly inserted file, they are removed and reinserted in the same way.

The insertion algorithm seems very inefficient, and possibly isn't even correct! (I don't remember anything about graph theory.) But it seems to work for my Pac-Man project, which is split into 32 interdependent files.

Here's the program, and a Makefile that shows how it's used:

State of play

So much for my regular blogging habit.

Since my last post, I've been continuing my self-education in games development. I'm going to write about the state of my current project, which is a Pac-Man clone.

But first, briefly, some exciting personal news!

In March, 7 years after we starting going out, I proposed to my partner Lucy. And she said yes! We're getting married in October here in Melbourne.

We also went to Europe for a short holiday - one week in the UK catching up with relatives, then two weeks in a Parisian apartment. It was an amazing time - what an incredible city!

So, as is often the way with Life, I haven't been able to spend as much time as I expected on Pac-Man. Aside from the aforementioned events, it's still taken longer than expected.

There are a few reasons for this:

  • As my understanding of the game evolved, I would think of different ways of doing things. This resulted in me reworking large chunks of code. This is really the whole point of the exercise: an opportunity to learn how a program like this hangs together.
  • While fleshing out "secondary" parts of the game, I would realise that some earlier assumption I had made was no longer valid, and would have to do some rework. For example, when Pac-Man eats a ghost, everything pauses for about half a second. This meant implementing a global wait function. I could've glossed over these kinds of details, but I learned more by just spending the time and doing it.
  • I decided to implement some rudimentary graphics and sound effects. This has been a lot of fun so far, and is a big part of why I'm excited by games development - lots of different creative techniques involved.
  • The game logic is more complicated than I realised. Luckily, I could refer to The Pac-Man Dossier whenever I needed help - an excellent resource.

I'm not going to implement every last feature of the game, but I do still want to implement a couple more things. I think it's only the following:

  • Background music. (In the original Pac-Man, this is a weird wobbling sound that speeds up towards the end of each level.)
  • Artwork for the bonus symbols (cherry, key, etc).
  • "Cruise Elroy" mode (see Pac-Man Dossier)
  • Maze flashing on level-up

The code will be available on my GitHub account shortly. Once I publish it, I'll write a follow-up post detailing some of the interesting technicalities of my implementation.

Blinky

Reinventing the wheel

To get really skilful at something, you got to do it a lot. An obvious way to learn games development is by building clones of existing games.

My brother showed me an article that prescribes a list of arcade classics to be developed by the aspiring programmer. Once you remake each of these games, you'll theoretically know all the fundamentals of game development. (This would also be a really good way to learn a new programming language.)

I started on a Tetris clone a long time back then forgot about it. But I recently remembered that I kind of, you know, need to learn how to make games. It's implemented in JavaScript and basically works, although the rotation algorithm is a bit smelly (i.e. wrong). I've pushed it to Github and you can find the source here.

Feel free to use the code in whatever way you like. It's obviously not perfect. I publish it to shame myself into improving it. Hopefully I'll find the time to do so.

Other people's software seems simple until you discover all the little details that accumulate over the life of the program. I won't aim for 100% of the functionality, since it's only a learning exercise. But I will endeavour to add a bit more here and there, possibly in parallel with the next game in the list - Breakout.

Small games

I'll be working on games with my brother once he moves to Melbourne in the next couple months. Until he arrives, I'm coming up with as many concepts as I can. We'll then pare down that list and prototype the most promising ideas.

The size of our team, and our relative lack of experience, limits the types of games we can realistically implement. (We can't all be Derek Smart.) My plan is to start small - real small - and make a few simple things before tackling something a bit grander. So, I got to thinking a bit about the sorts of games that a couple knuckleheads could make in a reasonable timeframe. Small games. The sorts of games that would work well on small devices.

First, I'm gonna go ahead and completely discount 3D games. I haven't done any 3D programming since university in 2002, and making games in 2D is already hard enough. I happen to have a soft spot for hand-drawn graphics though, so it's no problem. I always loved the visual style of those Sierra and LucasArts adventure games. You could also find some amazing animation in the so-called "cinematic platformers" like Heart of Darkness. It looks so much better than Flash-style tweening.

Performance is not normally a huge problem with 2D games, which (hopefully) means I can avoid low-level languages. In fact, I'm hoping to write games in JavaScript, which is good enough for 2D games, but probably not efficient enough for 3D - yet. (Interpreters are becoming increasingly performant, so this will change very soon.) I'd love to write a game in a dynamic language like JavaScript. The beauty of JS in particular is that it runs on just about every platform I can think of. It would be excellent to have the same code on desktops and mobile devices.

The main user interface for mobile devices - the touch screen - is perhaps the most significant factor in terms of game design (ignoring the accelerometer, as there's no way of emulating that on the desktop.) You gotta work with the medium. The touch interface lends itself to slightly slow-paced stuff: adventure games, RTS, puzzles, etc. I'm not so interested in making pure puzzle games like Tetris, but maybe a puzzle hybrid might work: something like Lemmings. Or something simpler: Flight Control is a stripped-back game that suits the medium perfectly. The interface is totally transparent.

There's multiplayer to consider, too. That might come later. Something like Worms might be fun - it has that physics aspect. I think a guy made some 3D clone of Scorched Earth during the original iPhone gold rush. Physics games are good multiplayer games, I reckon. Men can compete to be the best at calculating angles, which is a thing they love to do.

I'm not worried about coming up with a great idea, because my first idea will be terrible. It's OK, I expect it. You got to get that first bad idea out of the way. It's more about the process and learning than the actual product.

Hi ho!

init

Welcome!

I've re-purposed this blog. It was previously a small collection of odds and ends: pictures, soundbites and programming hints, read by about 4 people worldwide. I'm now going to use it for discussing independent games development.

Allow me to explain.

As of today, I remove one leg from the trousers of full-time work. I continue to spend 3 days a week at my day job, but the rest of my time will be spent working on games. My interest is in small games and the development of games as an art form.

I don't have any commercial experience making games. There will obviously be much to learn along the way. I want to document my progress and explain things as I go in order to test my own understanding. It might be nice for posterity, and it might also help others in some small way.

I also hope to connect with like-minded developers both abroad and here in Melbourne. Hopefully this blog will faciliate that in some way. Feel free to get in touch!