Pygame 1.8 Released!

Pygame is a set of Python modules designed for writing games. Pygame adds functionality on top of the excellent SDL library. This allows you to create fully featured games and multimedia programs in the python language. Pygame is highly portable and runs on nearly every platform and operating system. Pygame itself has been downloaded millions of times, and has had millions of visits to its website.

Nanocrisis

Game Design: Scale down!

My first step in creating the game was to figure out exactly how it would play. I decided on making a 3D-platform game because I had not previously tried making a game of this genre. My intention was to make a game that would at least be fun for me to play, so I added a lot of RPG features, such as the ability to upgrade your character as you moved through the game. The original design was more similar to Secret of Mana, and two-player support was planned. This turned out to be much too lofty of a goal, so the game was ultimately single-player, and not anywhere near as long as originally planned. Thus, the same lesson you hear a lot in the Indie game world persists here—scale down your plan! There’s no way to make a 3D game like the newer Zelda series or Mario64 within this short of a time period, and those are even single-player. Design a story with characters that stand out.

I wrote up an initial design document, and a friend filled in the story. The story was also scaled down a great deal, and what remains in the game are only some elements of the story that caught my eye. I don’t have a whole lot to say about the story, but I feel that making memorable characters in the game was very worthwhile—of course, you always have a main character or several who are memorable, but including a standout villain or a character who shows up frequently adds a lot more fun to a game. To appeal to casual players, keep it simple.

I am not really sure how successful the actual in-game design was, because a lot of people got stuck at the title screen (see uDevGames section below) and there really were not all that many comments about it. I think a lot of people were confused about this style of game, because the game didn’t really tell you what to do, you had to explore and try to find money and items to get further along. Those who got far into the game tended to like it, so there seems to be a certain hump to overcome, at which point you understand what the game is about and how it is to be played. Presumably a lot of people didn’t have time to try and mess around to get over this hump.

Game Engine: Never start from scratch!

Rule number one for actually making this sort of game is that you should never start from scratch, unless you have years to work on it, and an interest in how the guts of game engines work. With this in mind, I next picked out some libraries to start with, in particular the code of Devlib, which is an open-source, minimalist game engine. This was a great idea, as it gave me a notion of how to glue these separate open-source libraries together. Devlib by itself was not sufficient to do what I wanted, so I had to hack it like crazy—I would not recommend using it without modification. For making a 3D-platform game, I would actually recommend you start with a more high-level engine if possible, such as Torque. If you are very serious about making a 3D game, there are of course a lot of other great commercial engines as well, and again I would advise against starting from scratch unless you have lots of time and interest in low-level details.

Devlib incorporates SDL for setting up a drawing context. This is a great choice for the Mac OS X platform, and is becoming a lot more popular and stable. I would recommend it to anyone.

Drawing: DirectX and OpenGL

I chose OpenGL since I wanted to work well with the Mac OS X platform. Any cross-platform developer would want to do the same.

Image Loading: DevIL

The cross-platform image library DevIL worked great for what I wanted, and I recommend it. (Relevant to me was the JPG, PNG, and TGA support.) QuickTime is also popular for loading images, but I was interested in making the game as cross-platform as possible.

Font Drawing: FreeType for TrueType

This library is also fine, and by the way, there are plenty of free TrueType fonts you can find on the web, such at those at Tom7. I would not recommend using Devlib’s built-in font drawing support, which is quite inefficient and has a lot of overhead. Instead, OpenGL FreeType is a much better choice, tailored towards OpenGL rendering.

Physics: ODE

All in all, this library was acceptable for what I wanted to do, but it is somewhat quirky and difficult to get to work exactly the way you want it to. A game-specific physics library might be a better choice, but I haven’t played around too much with it. ODE definitely will get the job done, though, but it may cost you some time.

Scripting Language: Lua

This was the first time I wrote a game with scripting, and I was amazed by how much this helped to speed up game creation. Lua is one of the best choices you can use for a game scripting engine—so much that I have dedicated a section to it below.

Sound: SDL_mixer

FMOD is what Devlib used for sound, but I ended up using SDL_mixer, because I was trying to avoid the cost of licensing FMOD. FMOD itself is supposed to be fairly good if you actually do use it. However, using SDL_mixer turned out to be a poor choice. SDL_mixer is not as good about using audio hardware acceleration, and can sometimes introduce clicks and pops; also, it has limited features. I recommend using OpenAL instead.

Devlib also has several other components that I did not use, such as its mesh loading support, resource loading support, and font support. Devlib’s mesh support is not very flexible, so I wrote my own mesh/geometry code. This is a fairly simple linear-interpolation system; each mesh file is a group of keyframes, and each keyframe has all the vertex positions for a given pose of the model. Then, in animation files, keyframe weights are listed with time deltas. You can see this in the ‘ani’ files of the data folder. I created these models and animation files with my own modeler, OpenTeddy, which I describe a little further in the work flow section.

Resource Management: Caching is a powerful method for resources

Though I used Devlib’s resource support, I wrote my own resource management system. The system is simply a cache. Instead of having separate variables for each data pointer I want to store, I have a table for each type of data (e.g. sounds, images, keyframe data) and ask the system to give me a resource with a given name. The resource is loaded if it is not already in memory, and if not, it is loaded, but if it already is, a pointer to it is returned. To use this effectively, you need to pre-load a certain amount of resources to avoid delays when something new appears. For example, there is a noise for when the player swings a weapon; this sound is loaded when the game starts by requesting it instead of the first time the player actually swings, so there is no delay in case it takes a while to load the file.

Another consideration you might be worried about is taking up too much memory from loading all these data. Not to worry! In modern operating systems (Mac OS X, Windows NT or higher) when your program takes up too much memory, the operating system starts using the disk to store your excess memory that hasn’t been used in a while (this is called ‘virtual memory’) and it brings the memory back into your program when it is accessed. This is all done transparently, behind your back. So, you can load all you want, and if you load too much you should be fine, as long as you don’t work with a really big set of resources in a small time window. For those that use C++, here is a snippet of code from the system. PRall_lookup is a templated hash table, where you choose the type of the pointer to return. It also has a method find_or_load(), which returns a pointer to the loaded version of a data file you request. When g_all_music below is destroyed, its destructor from PRall_lookup will free all the loaded music files.

struct PRmusic : public PRcopystr {
public:
Mix_Music *music;
PRmusic(const char* i_filename) : PRcopystr(i_filename){
g_soundLoad();
music = Mix_LoadMUS(i_filename);
}
~PRmusic(){
Mix_FreeMusic(music);
}
};
PRall_lookup&ltPRmusic> g_all_music;
PRmusic* p = g_all_music.find_or_load("title.ogg");
PlayMusic(p);

Programming with Lua: Scripting helps speed up your development.

I should note that half of my code is Lua (in the data folder,

game.lua

,

title.lua

) and the other half is C++. Because I added scripting, I was able to add a lot of new behavior and features very quickly. By the way, make sure you are getting full output from your scripting interface. You need to know from which line and which file you are having a problem, and a full stack trace if possible.

Function Interface

What I found to be the easiest (though possibly not the most efficient) way to do the interface is have my Lua procedures each take in one argument, which is a table. This way I can quickly change my interface and allow default values. For example, I might have:

render_billboard( [x=50, y=20, texture="mytex.png"] )

Then if I decide to allow a color, I can make the default color white if it is unspecified and the user could also specify it:

render_billboard( [x=50, y=20, texture="mytex.png", color=[1.0,0.0,0.0] )

There is still some annoying manual labor you have to do to implement this. For each argument you obviously have to try to look up the string in the table, and if it’s there, use it instead of the default argument.

I would not use Luabind makes your compilation time incredibly slow, and if you start increasing the maximum number of arguments in your interface, it starts running into too-deep template errors. I tried it out and wasted a lot of time on it.

Vectors

I found it useful (though it’s somewhat slow) to represent vectors with tables. You can see in my previous code example how this works. The way to do this easily in Lua is to push a table, then push the number 1, push the first value, push the number 2, push the second value, then the third value. I use vectors of size 2 through 4. All my vector math is implemented in Lua. If this is too slow you can of course push it up into the engine layer, but again you still have this sort of overhead by converting to a table. However, I found it incredibly easy and flexible to do it in this way.

Handles

The way my system works is that when you ask for a new object, you get an integer handle to the object. You can then refer to it by the handle:

local ob = create_object( [model="test.model", loc=[0,1,0]) … set_object( [index=ob, loc = [1,1,1] )

In my system, objects are the only things with handles. You could do a lower-level version of things where textures have handles, models have handles, etc. I find, though, that you may just want to specify what you want each time and simply use a cache. So for example instead of passing a texture to a handle, then using that handle, you just mention the name of the texture every time, and the system is smart enough to internally cache that texture so that it doesn’t have to load it each time the draw texture is called. This is described in the above resource management section.

There are of course a lot of programs that use Lua, and I have actually not looked at any other ones (which is probably to my disadvantage, but my engine is working fine so far, except being somewhat slow on older systems.) I am aware of one recent game, Gia (from rpgdx.net) that uses Lua. I haven’t looked at how he does things, though.

Workflow: Start simple as possible, and slowly grow a full game

The first thing I did was try to make a simple program using Devlib. Once I got that to work, I made more and more complicated programs, that first loaded my meshes, animated them, added physics support, and then scripted them. This sort of continual evolution is a very good way to develop a program, because you know that what you currently have is working fine, so when you add something new, you know that’s probably the culprit. I used a memory checking system (called MMGR.h) and turned out checking all the time, so whenever a memory bug came up, I could fix it right away. Once I got scripting working, I made a simple demo where the character could walk around on another mesh. From here I tried to make sure I had all the features I wanted, by adding more and more interactions with other objects. At this point I started making the actual game levels. Use a professional tool chain.

Making character and monster models was done in OpenTeddy, which I developed myself earlier in the year. The reason was surprisingly not that I wanted more power from a modeler, but that I actually, despite being a computer graphics student, do not know how to use professional modeling packages, such as Maya, as I never learned them. I would recommend against making your own modeler. I had tons of trouble with my modeler, and it was really insufficient for making level (room) models. Instead, you should learn how to use Maya, for example, and you could write some plug-ins for it in order to do things specific to your game. This is certainly the best approach, but rather difficult if you don’t know too much about it. So start learning how to use a professional 3D package as early as possible.

A lot of the level data is in my scripts, which is also a fairly bad idea—it meant that I had to type in the location of exits and entrances, which was a huge nuisance. It would have made a lot more sense to store this data inside the level meshes, or make a special level format just for rooms.

I had a lot of fun making characters and monsters, however, which is a big part of what motivated me to keep going. This was the only advantage of my own tool, because OpenTeddy is specialized in making organic shapes. As an aside, OpenTeddy is based on the work of Takeo Igarashi. His team created an easy-to-use 3D modeling tool based on creating mesh blobs with 2D strokes. I extended the concept to include boolean operations, which made it a lot more usable, and allowed me to make (debatably) much more professional-looking models. I hear there is a Teddy plug-in in several professional 3D packages, and I would recommend using such a tool to save you time.

Music for the game was created with FruityLoops. I had a lot of fun with this, and would recommend it to anyone. It is, however, PC-only. I felt that the music added a lot of mood to the game, but from the uDevGames results, people either didn’t like the music that much, or didn’t like the sounds that much. It’s difficult to tell, because I didn’t receive many comments about it.

Audio was created by finding free sounds, and then modifying them with Audacity. This is fairly straightforward, so I won’t say much about it, but you should remember that OGG is a good sound format to use, though you will need to get the correct libraries for this.

uDevGames: Make sure your opening interface is simple and comprehensive

When I received my scores for uDevGames, I was disappointed, because I expected to do somewhat better. However, I did something really stupid. At the title screen, I opted for somewhat of a consistent keyboard interface, but this was a very bad idea, because people didn’t know to press a key since in most computer games you would click the mouse instead. I did not implement mouse support, and I really didn’t want to. I should have though, because it would probably have given me a good deal more votes. So the tip here is you should definitely make your out-of-game interface both mouse and keyboard—a standard interface is best. Instructions all along the way (even CLICK THE MOUSE TO CONTINUE at the beginning might help) are probably a great idea; in-game instructions are the best, and I think it was helpful for me to include them. If you’ve played the fairly recent “Prince of Persia: Sands of Time” game, it has fairly sufficient in-game instructions, which gives you an idea about that. Simpler games appeal to the public.

About gameplay, again I received very few comments, and what comments I did receive I fixed gameplay for, so it’s very difficult for me to gauge what people actually thought about it. My personal opinion is that I received a mediocre score because the game was too complicated—remember that for uDevGames you are being judged by the public, and a game that will be most successful with the most number of people is one with a simple interface, so nobody has trouble playing it. I should also note that historically, RPGs have not placed all that highly in uDevGames for what I feel is this same reason of complexity. I also encountered some game crashes despite testing with a reasonable number of people. Because again my game was somewhat complicated, it was almost impossible to anticipate these bugs coming up.

Try your sound on headphones, and on different systems

For audio, one comment I heard is to make sure things aren’t too loud or too soft—there should be an audio adjustment menu and you should test the game with headphones. I did neither of these things. Another problem I came across is that a few people felt the music was somewhat monotonous. However, I was only allotted 10MB of space for the whole game, so each song was only a minute and a half to two and a half minutes. It would have been a better idea to just make one or two pieces of longer music, and leave the other music out to decrease download size. Small downloads can lead to more votes, because non-broadband users probably will download smaller games first in the interest of time. The best-rated graphics are clean and consistent.

Finally, about graphics, I think I was judged somewhat harshly because I had a lot of repeating textures—since I didn’t have the time to make really detailed levels, I went for levels that were just comprehensible but not really detailed. This was probably not such a good idea, because I think it introduced the perception that I was just being sloppy. The fact that I had animated models did not seem to help me all that much, and you can probably get a lot of mileage out of 2D graphics that look good.

* Genre:
* Developer:
* Url:
* Team size: 1
* Released date:
* Project length:
* Development hardware:
* Critical applications:

SDL,OpenGL,DevIL,ODE,Lua

Feathered Soccer

Project Aims

To avoid comparison with the big Pro Evolution Soccer or FIFA series, I wanted my game to be strongly arcade. I also wanted to develop a game that both a child and an adult could find fun to play.

Design

At the beginning the design was very poor. Of course, I produced a lot of ideas for the game, but I knew that developing even a simple soccer game in three months would be very hard for me. Consequently, I decided to first develop a simple game and then add additional features as time permitted. So I simply designed an objects tree, thinking of the C++ classes I would have used and keeping the game concept in my mind.

What Went Right

Math

Coding a 3D game usually requires a lot of math, trigonometry and physics formulas, and Feathered Soccer made no exception. Moving the ball realistically, moving characters, and checking collisions are some examples of where math is essential in this project. However, I love this subject, and when I started coding I had just completed a first year Computer Science course at college that included one physics and two math exams, so producing the needed formulas wasn’t a big problem.

Happy Coding

Even if I had to fight against some bad technical bugs during this project, they didn’t take much time to discover and fix. Their presence was due mainly to the little time I had to complete the project. Because of this, and of course because of being a big (and bad) programmer sloth, my code isn’t very good in regards to maintenance. However I had the code clear in my mind at every stage of the project, so I could fix the bugs with little pain.

Using Strong Tools and APIs

It could seem an obvious thing, but it’s not: choosing strong and proven tools like Xcode and strong and proven APIs like OpenGL and SDL really helped my development. You can of course use and be fascinated by a new tool, however it’s not a good thing if, having only three months to develop a game, you also have to beta-test the tools you use.

What Went Wrong

Artificial Intelligence

Well, I’m coding a soccer game and everything’s going fine, so where is the tricky part? That part is Artificial Intelligence (AI). It took me a long time to produce a not-so-stupid AI and I found the teammates’ AI expecially difficult. When the player controls a character, all the other characters of his team should move in a meaningful way. The first experiment I made resulted in very unintelligent AI. It was clear to me that I had underestimated the problem. So I spent a lot of time on this, thinking of a better solution, playing other soccer games and, at coding time, using a try-and-fix approach. In the end it seems that because of a fear of making AI that was too easy, I made AI that, according to user feedback, is too difficult. So the moral of the story is “In medio stat virtus,” as the Romans used to say, which means, “Virtue stands in the middle.”

Sound

I added sound at the end of the project, which means I had very little time to find and implement it. I was in trouble trying to find some good royalty-free sound effects and background music so I decided to buy a copy of iLife ’04 and produce my own music with GarageBand. Then I found some nice effects and bought them. There were also some problems from a technical point of view. I tried to use _SDL_mixer_ to add sound, but for some reason, probably due mainly to me, I wasn’t successful in doing this in even a simple way. Because time was running out, I decided to go platform-specific for this contest and I encapsulated some Cocoa code into my C++. I found the Apple documentation on this topic very clear. Then I noticed that the game slowed down while playing a sound effect, so I modified my Cocoa code to be multithreaded. Finally everything worked and I am very proud of my encapsulated Cocoa code. I will, of course, have to change it if I decide to port the game to other platforms.

Fighting Against Time: Mid-Project Changes

One of the worst enemies in this project was time, so there are a lot of features I would like to add which are not present in the current (1.0) version of the game. Choosing what to implement and what leave for later versions was very hard. I tried to think of what is really necessary in an arcade 3D soccer game and what is not. I only wanted my game to be polished and fun to play, even if this would have meant the lack of some features. I list here some of the features I didn’t implement.

  • No bonuses — If you played the game, you may have noticed that tackles aren’t punished and that, even if the game has a strong arcade/cartoon inspiration, it hasn’t any kind of hyper-speed or other bonuses, which would have also changed the gameplay experience positively.
  • No two-player game
  • No configurable options
  • No replay
  • More teams and competitions

Of course this is only a small selection of the things I didn’t add because of time.

Risk Management

Choosing the API and the Game to Develop

Even though I had experience with 2D games, considering that I had never developed a 3D game before, choosing OpenGL as the main API was a brave decision and a big risk. However I really wanted to do something I would find fun and a 3D soccer game fit the bill. In real life, with a boss who wants a good game developed in three months, I would probably take another route.

Conclusion

One thing I learned from the development of this game is that I should pick a project that is possible for me to complete in the given time with less pain. However, it’s also important for a person to pick a project which he/she likes and enjoys developing. As a matter of fact, I also had a confirmation of human will power: I really wanted to have something playable for November 6th and I had it. If I could suggest something to a person who wants to conduct a big project I would say this: choose something you really like and trust yourself.

  • Critical applications: Xcode, GraphicConverter X, GarageBand, Cinema 4D CE, Art of Illusion, The Logo Creator 3
  • Development hardware: PowerBook G4 867MHz (384MB RAM)
  • Url: www.bluepixysw.com/
  • APIs: SDL 1.2.7, OpenGL, Cocoa (only for sound)
  • Project length: 3 months

Snowball

Snowball had a dual purpose. First, it was meant to be a successful entry in uDevGames 2004 in order to win recognition in a wider arena than just my peers. Second, it was meant as a proof of concept for an isometric engine for future game development. The intended customer for Snowball was the average voter attracted to uDevGames.

Details

Schedule

The scheduled development timeline included having a basic foundational engine in place by September 10th. This was to take advantage of a two-week break from my teaching job. After that I planned to begin beta testing and add features and stages weekly until November 6th. In reality, the basic engine wasn’t in place until October 19th, more than a month late.

Source Code

The source code consisted of 2,220 lines of code used from my previous projects and 10,138 new lines of code. In addition, the following libraries were utilized: SDL, SDL_mixer, OpenGL, libPNG, and zlib.

Compatibility

The finished application bundle is roughly 3.3MB in size and should be compatible with Apple computers running Mac OS X 10.0. It requires a video card with at least 8MB VRAM (like an ATI Rage 128) and a G3 500 MHz processor or better. The only known compatibility issues are with the Windows version of the game and have to do with resolution switching.

Tools

The primary development tool used was Apple’s Xcode 1.5. For the PC version, DevC++ 4.9.8 was used. Corel’s Painter 8.1 and Adobe’s Photoshop CS were used for creating content along with an Intuos 2 Wacom Tablet. Apple’s GarageBand was used for composing the music.

Credits

The writer of this postmortem, Aaron Sullivan, designed and programmed the game. Amy Sullivan, his wife, constructed the in-game stages and recorded sound effects. Sean Sullivan, his brother, composed the music.

Of note were contributions from outside this team including Eric Wing and Josh Abernathy, who helped test and fix an important bug in SDL involving mouse coordinates.

Carlos Camacho and the staff at iDevGames provided the contest under much duress and Snowball would not have been created without the motivation of this particular contest. Feedback from several members of iDevGames’ forum was also of great benefit as was feedback from family and friends and voters that took the time to reply by email.

What Went Right

Origin

Before uDevGames 2004, I contemplated creating a computer role-playing game (CRPG) and I decided on an isometric view in order to capitalize on having rich illustrated artwork rather than stale jaggy 3D models. As the beginning of the contest approached, I realized that a CRPG was a far too ambitious project to complete in three months, but I could develop a part of the larger CRPG game with a smaller entry. The isometric graphics engine now became the focus.

I had used OpenGL to develop two 2D games: an unfinished uDevGames 2004 entry, Bugganauts, and Space Barrage, my first finished game in decades. I had never used OpenGL for its more common purpose, a 3D game. I had a quick tech demonstration that I worked on as a proof of concept, but now I needed an idea for a small game using the isometric view.

The choice was between a 3D version of Bugganauts, involving lots of alien shooting and hostage rescuing, or a cutesy puzzle game like an old favorite of mine, Adventures of Lolo. Well, I was really leaning towards Bugganauts, until I thought that I could maybe make the small game into a part of the larger CRPG. The setting for the CRPG was to be a snow covered world. I thought about snowballs and a puzzle game and how you could use the ball rolling up snow and enlarging. I had never seen this in a game before and that spark of originality sold me on it.

Graphics

The basic premise for the game was simple, and I expected that most of the work would be in creating the graphics engine. This was okay, because that was one of the two primary goals. I despise aliasing (jagged edges rendered on the edges of objects, especially prevalent in 3D games) and after great success with using glAArg1 to polish Space Barrage, I became somewhat obsessed with removing as much aliasing as possible from this game. While this took time from other aspects of the game, I learned the most from this part of the development.

Spending so much time on the graphics delayed my beta testing by more than a month, however! I include this under “what went right” because I waited till very near the deadline (a day or two?) to reveal Space Barrage. Even a month late is a big improvement over my last attempt.

Workflow

I had a reasonably efficient workflow that included posting updates for whoever would read my blogs at uDevGames and visit my personal web site about progress on Snowball. I made an effort to keep these updates from becoming a distraction.

I kept the web page very simple with an easy process for adding screen shots. I had a couple of long winded blogs, but I used them as a way to process what was going right and wrong and to think through what the next goal needed to be. It kept me accountable to a public audience (even if it was just an illusionary one) that would know if I was sticking to the goals rather than going off on a time consuming tangent.

STL

I finally embraced the STL (C++‘s Standard Template Library.) I made it a point in Space Barrage to simply avoid dynamic memory all together in order to sidestep time consuming memory leaks, because I knew I could easily derail in such a short time span. In this project, I dug into the STL. One investment I made was buying the book ‘Accelerated C++’ by Koenig and Moo. I highly recommend it to beginning programmers and anyone who isn’t acquainted with using the STL and likes to use sample code and tutorials.

At first I found using some of the STL conventions cumbersome, feeling a bit like wading through Java-type convolutions to perform simple actions. After working with it a bit, I learned to really enjoy the peace of mind that comes from avoiding the responsibility of plugging memory leaks. I didn’t get in too deep, really, just some vectors, strings, and maps, but I’ll never look back.

Code Reuse

Reusing some code from Space Barrage and the unfinished Bugganauts gave me a boost at the start. I relied on SDL for window and graphics setup and a custom PNG texture loader that I think is mostly code by Keith Bauer (a.k.a. One Sad Cookie). I used code I had set up for music and sounds (though the sound effects never made it in) that relied on SDL_mixer.

Cross-platform

Using these cross-platform libraries made the port to Windows very easy. I’ve found that developing on two platforms really helps refine your code. One platform catches some errors that the other might not.

What Went Wrong

Time

The obvious and probably most common problem in software development is difficulty predicting the length of time parts of a project require. This is especially true for inexperienced programmers. When one has never programmed a 3D game, how is one to estimate the length of time it will take to complete a 3D game engine? One guesses.

Design Document

My work schedule was very full at the start of the contest, but I anticipated a two week break and worked on a design document and engine ideas in the spare moments in between teaching classes. I carried a growing stack of papers covered in cartoon sketches, schematics, and formulas. I never took the time to formally compile it into a design document and although you’d think that was a bad thing, it wasn’t that bad.

From working on Space Barrage for the 21 Day Later Contest I knew that a tight schedule meant I’d be keeping it mulling around in my brain at all times anyway. I did eventually keep a list of tasks to complete as I approached the end. So, for a longer term project, especially one with more than one programmer, I would say that not having a detailed design document was something that went very wrong. For this short term project, however, my stack of papers was enough for this single programmer to stay reasonably on track.

Schedule

That said, my schedule went way off track. I was determined to get a playable out to the public as soon as possible to avoid the problems I had with Space Barrage, but I released it a month late.

I had time to clearly identify the areas that needed to be improved in order for the game to do well in the contest, but I ran out of time to implement the changes. Some of the problems identified were:

  • The WASD keyboard controls were just right for some, but unnatural for others. Custom keyboard options were needed.
  • One unexpected discovery is that some players found the learning curve too easy and gave up before it became challenging.
  • Mouse control was something I didn’t plan until I realized there was a simple and effective way to implement it. The mouse control made it much easier for inexperienced gamers to play compared to the keyboard control, but led to some confusion as well.
  • People were much more inclined to play through if they knew the total number of stages but the game never gives them a hint.
  • Everyone wanted a way to continue if they stopped playing and came back to the game later.
  • Snowball’s music soothed some and got on the nerves of others as it constantly repeated for hours with no interruption, if you played that long.

Bugs

There was a serious bug discovered when running on Mac OS X 10.2 that inverted the mouse coordinates read by the game. It happened in the middle of the voting, so anyone with that OS version would not be able to play. As a quick remedy I forced the game to start in full screen mode where the bug did not appear. This bothers many in the Mac community, but my hope is that it enabled more people to play. Several days of correspondence led to fixing the bug in SDL that was causing the problem.

Windows PC

Because Sean, my music composer, had issues with getting his PC hardware/software working correctly I had to deal with the possibility that he’d be unable to provide a soundtrack. I spent time with Amy composing some music in GarageBand. It was temporary and would need much more refining before release. Fortunately, Sean agreed to work at our office and used GarageBand to create some excellent original compositions in a matter of three days near the deadline.

Time Again

Overall, I spent too much time making sure I fulfilled the one goal of creating a new graphics engine and too little time making sure I fulfilled the goal of doing well in the contest. If I had compromised on some graphics issues, I very well might have had time to add more game features, get more early feedback and fix many of the interface and user experience issues.

Mid-project Changes

In the last three weeks or so it became apparent that many of the planned obstacles and game mechanics couldn’t be added in time. This was disappointing, but focusing on the various techniques involving the ice blocks turned out to give enough game play variety to satisfy the expected length for a small contest game.

In fact, I was very pleased that just one element could be stretched so far and it helped me to accept that this project was worth continuing beyond the contest.

Conclusions

Fun

Overall, I’m satisfied with the state of the game that was completed during the voting period. Because I delegated stage design to my wife, there was plenty of content for players to explore even if the amount of variety was low. The team members had fun working on it and I know that many people had fun playing it.

Some things that I learned

  1. A game’s difficulty curve is one of the most important ways to keep a player playing. If the target audience has a wide range of skill levels, there had better be options that allow them to play how they want right away. I had comments that there was no challenge to the game or that there were far too many “easy” stages. In smoothing out the difficulty curve and forcing people to play through the “learning” stages I had turned off the less casual gamers.
  2. Players want to know how far away the conclusion (or the next goal) is. Players who did not know the number of stages either gave up, or lost interest early on. As soon as I told players the number of stages, they would play to the end.
  3. I can’t stand aliasing. Many casual gamers have not learned to ignore aliasing and I’ve even heard one person say, “Did you see all the rats?” referring to the crawling pixels on an aliased line. The amount of work and time I had to invest to help remove “the rats,” however, seemed to be worth it. I still get a big reaction from many players when they rotate the stage for the first time. Many simply expect it to stay flat because of the style of the imagery.
  1. Sound effects make a big difference with people’s response to the music and the game overall. There are sound effects recorded for Snowball but getting them in the game was one of those tasks that kept sliding off the priority list. The impact of the player’s actions and the level of immersion felt by the player is greatly reduced in this soundless game compared to, say, Space Barrage. Also, there are comments from players about loving the music, but many could not stand the unbroken repetition of the single track during game play, no matter how good the music might be.

Conclusion

Snowball was meant to be a contest winner and an engine test for another game. In part it has succeeded but I’ve really grown to believe that Rollo the Snowball has a much bigger exciting life ahead of him.

My plan is to bring this game to a commercial level of development. In the coming months, I’ll be using all the brilliant feedback from the participants in this contest and taking the time to add all the fun features that were so painful to cut from this abbreviated version. This time, the goal will be to finish a game worthy of a player’s hard earned cash.

1 Developed by arekkusu

  • Critical applications: XCode, Adobe Photoshop, Garageband

Rescue

My interest in space games dates back many years, when I played Elite for countless hours on a Sinclair Spectrum. In later years, I found myself enthralled by Frontier, the ‘sequel’ to Elite, and the vastly underrated plot-led combat sim Warhead. Both of those games more or less typify how I expect a space game to work: convincing physics, true 3D and immersive environments.

The thing that brought these old gaming memories back was a recent remake of Elite written by Giles Williams, the punningly-named Oolite. As much as I liked Giles’ game, I really wanted to see a space sim with more graphical realism and a sort of crude, industrial look. Also, where many space games revel in high-tech heads-up displays, I wanted to place the player directly in the cockpit, looking around at the clunky hardware as well as out at the stars.

I’m always reluctant to exactly copy existing games, so I began to think of ways to make my game stand out as I laid down the design for the gameplay. I decided that it would be most interesting to shy away from the usual ‘dogfights in space’ gameplay and go for something a little more unusual: a more passive kind of gameplay where you have to rescue asteroid miners from certain doom. No guns, no shields, just a chunky industrial space tug, a set of mining tools, and your flying skills to keep you alive. Having settled upon this cursory design, I began coding.

What Went Right

Starting from Scratch

One of the first decisions I made was to drop almost all the code I had ever written before. I had wanted to take this step for quite a while because I had become weary of working with the same rotten old code, which I first started writing several years ago. I used this code to make Super Phoenix and Yoink, and it works adequately as far as it goes, but it has deep seated design problems that I’ll probably never manage to eliminate. By starting afresh, I hoped that I would be able to create a clean, focused basis upon which to work, and that would help me to make a better game.

I also wanted to try several technologies which were new to me. My earlier games are still compatible with Mac OS 9, using the CFM runtime and the Carbon API. For Rescue, I thought I’d go a step further and build a Mac OS X only Mach-O game for the first time.

Using Standard Libraries

Having disposed of my own source code resources, I decided to replace it by utilising as much freely available, widely used source code as possible. I mainly wanted to avoid reinventing the wheel, but I also hoped to learn some new skills and techniques by delving into other people’s code.

I chose SDL as the foundation of my application. It has a good track record, it’s popular and as a bonus it’s abundantly cross platform. SDL also has an extensive selection of standard (and not-so-standard) additional libraries, and I picked two of the best respected-_SDL_image_ and _SDL_mixer_-to handle image file loading and sound, respectively.

For my math and physics code, I decided to try WildMagic, a huge and rather complex C++ library. WildMagic had a large number of features which I didn’t really want to use, such as a built-in scene graph and an application framework similar to GLUT, but I was able to use the functionality I wanted (vectors, quaternions, matrices, intersections and so on) without picking up too much unwanted overhead.

I needed a way of loading 3D models, something which I haven’t even thought about since the last time I used QuickDraw3D. Because I had no experience in writing my own model loader, I decided to use the OBJ format loader written by Karl Berg, another member of the iDevGames’ forum. I found his loader particularly interesting because the example program supplied with it showed a spaceship model with attractive specular highlights and an illumination map.

For other data files, I decided to use TinyXML, a simple but effective XML library written in C++. I used it in the creation of my uDevGames 2003 entry, Yoink, so I was already satisfied that it was the right tool for the job.

Optimization

I wanted to make an infinitely large, densely populated asteroid field with a large visibility range. This was going to cause obvious problems in terms of the frame rate, so I had to use some tricks to keep things moving quickly.

I used simple cubic space partitioning to control the culling of invisible objects. Partitions which are outside the camera frustum are not drawn. I had considered using octrees instead of plain partitions, but I decided that it would be too complicated and not necessarily much faster. However, I did go on to use an octree routine to lay out asteroids in space partitions in a way which prevented two rocks from overlapping.

In addition to this, I needed to cull objects by distance. I was only able to render about a hundred asteroids before things started to get too slow, but this meant that either my visual range was very short or the asteroid field had to be very sparse. I dealt with this by reducing distant rocks to a silhouetted polygon on a billboard, and using fog and careful scaling to make the level-of-detail pop less noticeable. It wasn’t clever, but it allowed me to display several hundred asteroids instead of just a few.

Elsewhere, I used very few optimizations. Apart from having to make some minor changes to WildMagic to get a big speed increase, I didn’t do anything much to make things efficient, so the game wasn’t very fast or smooth on slower computers. Machines with old graphics cards such as the ATI Rage 128 were almost bearable, but most people weren’t able to tolerate the game at such a low frame rate, so I necessarily cut a lot of users with lesser machines out of my potential audience.

Teamwork

When I embarked upon the development of Rescue, two weeks after the start of the contest, I was really only using the contest as a chance to experiment in a formal setting. I didn’t even sign up for a several weeks. However, out of the blue I was contacted by a freelance musician, Mikko Tarmia. He said that he had seen Rescue and wanted to write music for the game. I was flattered that he liked what I had done and I really liked the sample pieces of music he showed me, so I was very keen to ask him to contribute.

It then struck me that my little game experiment was now much more serious. It wasn’t just my effort and reputation on the line, but Mikko’s too, so I felt that there was no way I could afford to let him down by slacking on my part of the deal. From that point, no matter what happened, I was determined that I would do my best to reach the end of the contest without quitting.

Later in the contest, I realized that, while I had nice spaceship and asteroid models, as well as pretty star and nebula textures, I was going to have a hard time adding textures to the 3D models. My modelling software, form-Z, is rather good at low-poly modelling, but is lacking in features for manual UV mapping. I could also see that I was going to be pushed for time if I concentrated too much on making textures. Having already formed a small team, I was much less reluctant to ask for extra help than I had been on previous projects. With this in mind, I asked my old friend Brian Smith, a skilled graphic designer and 3D model maker, to join the team and work on the textures.

I had never developed a game as part of a team before so all of this was a whole new experience for me. I’m pleased to say that I found the whole collaborative working process very smooth and easy to deal with. My teammates were both very professional and delivered high quality work right on time, and they were thankfully tolerant of my requests for changes and criticism! Mikko and Brian wrote their own accounts of their parts in the project, which you can read below.

What Went Wrong

Too ambitious

As was the case with Yoink in uDevGames 2003, I found that the game I had designed was much more complex and time consuming than I had imagined. I still find it difficult to perceive how long things will take at early stages of the project.

My failure to devise a schedule and stick to it meant that many features had to be omitted from the game, so much so that the resulting gameplay was nothing like what I originally envisaged. I had planned to make Rescue a much more innovative game, in which stealth and lateral thinking were your only weapons against a much more powerful enemy. Among some of the features I had to omit:

  • Giant enemy battleships which would patrol the asteroids looking for mining installations to destroy. This would have been quite a significant part of the programming work, as it’s very difficult to make an effective AI which is fun to interact with. I expect that developing the AI would have required a lot of tweaking to get things just right.
  • Tools such as limpet mines which could be deployed from the player’s ship to distract or delay the enemy. Also, I wanted the player’s ship to be able to pick up objects with its robot arm and carry them around. I mainly omitted these features not because they were difficult, but because they would have served no purpose without an enemy to defend against.
  • A mothership which would drop the player off at the beginning of each stage and pick them up at the end. It would loiter in the background and act as a drop-off point for evacuated miners. I was very disappointed to have to leave the mothership out of the game, but Brian and myself agreed that there wasn’t enough time to build and texture another detailed spaceship model. In the end, I resorted to having the player accelerate into hyperspace instead, and this was at least an unusual approach to this particular sci-fi cliche.
  • The most ambitious thing I had to omit was the planned character interaction and plot. I wanted to have a co-pilot character sitting in the other seat of the cockpit, and this animated character would act as in-game help, telling the player what to do next and explaining how to perform certain tasks. Beyond that, I had imagined that I could have a storyline played out in animated 3D cutscenes, using the same characters. Unfortunately, all of this had to go because it was the lowest priority of all. However, I wish I had been able to add some kind of in-game help in the absence of the co-pilot, since many players clearly had difficulty understanding how to dock the ship and how to get into hyperspace.

Scheduling

Another problem in common with last year’s project was the proper scheduling of the development process. I don’t particularly like to work to a fixed timeline, so I spent my first two months producing code and game assets with no regard to the deadline.

Much of the work was comparatively easy and quick to produce, since I had already written similar code for my other games. For example the time-based animation system and simple scene graph were quite elementary and didn’t take long at all. On the other hand, several essential elements ballooned out of control and ate up significant chunks of the development time and my patience. The collision detection system was an especially major source of wasted time.

I also spent a whole week doing nothing but trying to redesign the cockpit model. I had an existing cockpit model which appeared in early versions of the game, but I wanted to replace it with one that was much more immersive and full of equipment. This became a huge source of stress and annoyance because I simply could not get the result I had in my mind. In the end I had to compromise and revert to the version of the model which was closest to my original intent.

Collision Detection was Problematic

I chose to write my own collision detection system from the ground up instead of using a library such as ODE. This seems odd with hindsight, as I was trying to utilize third party code as much as possible, but I suppose I was afraid of its complexity. I have since discovered more about ODE through the experience of other developers, and it seems that it is indeed fraught with tricky problems. Maybe I made the right decision for that moment in time.

I designed a rather complex but crude mechanism which utilised WildMagic’s intersection routines to handle interactions between primitive spheres and capsules, groups of primitives, and rays. It took about two or three weeks to write because I kept deciding that I had made design mistakes and refactoring it. Even after all that hard work it still didn’t work properly, and many of the features were never used in the finished game because they weren’t reliable.

As it stands, my collision detection system is still too crude for my liking, and this shows in various places. For example, the requirement that all objects must be capsules forced all of the asteroids and buildings to be roughly capsule shaped. Unfortunately, you can sometimes still see weaknesses in the system when you get close to irregular objects while looking at the external view. This code will all need replacing in some future version.

A Lack of Refinement

While I managed to make good headway into the technical issues of making the asteroid field limitless and the spaceship fly the way I wanted, I didn’t pay enough attention to the little niceties that gamers expect. The title, end of level and game over screens are extremely lightweight in their presentation. There’s no in-game menu; everything is just ‘press a key to continue’ (and it doesn’t even tell you to do that!). Also, there are no in-game preferences and there’s no way of redefining the controls. I did manage to have an editable XML preferences file, but that’s probably too technical for ordinary gamers.

As I expected, I’ve had quite a lot of feedback asking for redefinable controls, so I have put this on my to-do list. Of course, I don’t intend that the game will continue to have a horrible in-game GUI—I shall also deal with this in time.

I did have a little success with the manual I wrote. The final version of the manual was illustrated and had detailed instructions to help novice pilots figure out how to land and escape into hyperspace. I know that many people won’t read the manual, but I’ve had positive feedback from those that did, so I’m happy that it wasn’t a waste of time.

Working with the Limitation of Other People’s Code

There were several occasions when I was forced to deal with problems that were not of my own making, but which came instead from the way the various libraries and other incorporated code worked.

The first thing which hampered my progress was a strange bug in CodeWarrior 8.3 which prevented _SDL_image_ and _SDL_mixer_ from being linked to my application. A little research revealed that the problem was caused by the underscore in the libraries’ names. I dealt with this quite easily by making my own versions which were renamed to remove the underscore.

The only thing which concerned me about this modification was compliance with the license. Since the SDL libraries were released under the LGPL, I didn’t want to fall afoul of the license’s rather complex wording. My modifications were extremely minor, so I simply asked Sam Lantinga, the author of both libraries, for permission to make the changes without getting embroiled in the licensing concerns. Much to my relief he gave his permission!

WildMagic also needed modifications, although it was less worrying to me because its license permits almost any modifications. The problem was that the programmer had inexplicably decided to use the memcpy() function as a means of implementing copy constructors and assignment operators for almost every class. For frequently used types like vectors and quaternions, the overhead of calling memcpy() all the time was substantial and showed up as a large blip in Shark profiles. At the time, I felt that Rescue wasn’t running fast enough on slower computers, so I tackled this by simply commenting out several of the most commonly used constructors and assignment operators and rebuilding the library. This increased the speed of the game by no less than 30 percent, so in the long run this was a great benefit!

Karl Berg’s OBJ loader was the other component that I changed, and again it was helpful that his license amounted to the freedom to make any changes. In its original state it was only able to support BMP textures and didn’t look for texture and material files in sensible places. I addressed these issues by adding support for _SDL_image_ and adding a function to return the application bundle’s resources folder.

At some point I would like to make some more radical changes to Karl’s code. His coding style, essentially C with classes, doesn’t really marry well with my own, and there are some outstanding bugs I’d like to fix. I plan to strip down his code to the bare parsing routine and build it back up in a way which is more suitable for my purposes. I’d especially like to add features which allow code to examine the model geometry, as this would be useful for collision detection.

Last Minute Damage Control!

I saw this coming but I somehow didn’t manage to avoid it: I reached the uDevGames submission deadline and I still didn’t have any gameplay to speak of. You could fly the ship around, pick up miners and hyperspace to the next level, but there was no threat and nothing to force you to take any risks, so if you were a careful driver you’d be able to play the game forever.

About three hours before the deadline I took the drastic step of adding a simple time limit. This was something I really didn’t want to do because it made Rescue seem very similar to Asteroid Rally, Matt Diamond’s game from uDevGames 2003! At this late stage I saw it as the only way to turn my basic spaceship flight simulator into something like a proper game. Thankfully, it only took me a few minutes to implement the time limit itself and the ‘out of time’ game over screen. Once in place, the time limit did indeed have the desired effect, and it was now necessary for the player to rush from one mining installation to another to complete later levels in time, putting their ship at risk in the process. After a little tweaking of the difficulty level, I finally reached a stage where my game was fun and exciting for me to play, not just mildly interesting! Satisfied that the game was now just about acceptable, I packaged it up and submitted it just one hour before the deadline.

Tools

I used the Metrowerks CodeWarrior 8.3 IDE to write and build the game. However, in an attempt to make the source code more accessible to the community I’ve since made an Xcode project as well. This was a useful learning experience in itself!

The spaceship exterior and interior models, as well as the buildings and some of the asteroids, were built using form-Z, a highly accurate and complex modelling package I use for my commercial visualisation work.

Brian used Cinema 4D for UV mapping and texturing the models, as well as making some additional asteroids.

Carrara 3 was used to make the stars and sun. I had hoped to make better use of Carrara since it was one of the prizes I won in last year’s contest, but as it turned out I wasn’t able to learn its polygon modelling feature set in time to do something useful with it. I used Photoshop CS to make the font and various other graphics, while Brian used Photoshop 7 to work on the textures.

For audio, I used Reason, another prize won in uDevGames 2003, just once to make the first sound effect! Had Mikko not come on board to make the music and the rest of the sound effects I would have had an opportunity to put it to better use. Never mind, Yoink still needs music!

Summary

Now that that the contest is over, I can clearly see that I made many of the same mistakes as last year. I devised a game idea which appeared at first glance to be concise and manageable, but which with hindsight couldn’t possibly have fitted into the three month development period. Maybe if I had unlimited amounts of free time it might be possible, but when I have to fit all this hard work around a full time job and other obligations and interests, it’s can’t be done.

Still, even though the resultant game didn’t match my original vision, I’ve benefited in several ways. I’ve learnt a lot about several very interesting APIs. I’m now very interested in using the SDL libraries and WildMagic in future projects.

I’ve worked as part of a development team. I’m used to teamwork in my day job, but it’s a bit of a breakthrough for me to be able to share my personal creative work with other people. It has been enlightening to work with other people’s opinions and contributions in mind.

My objective of making a reasonably complete space game engine has finally been achieved. I (and others) can now build upon this project to make more sophisticated games. I now have another partly finished project to hang up on my web page!

Where shall I take Rescue now? I plan to add all of the features I was forced to omit before I go any further. Replacing my home-cooked physics with ODE, renovating the OBJ loader to suit my needs, building the enemy ship models, putting them into the game and giving them AI…all of those things are achievable now that the deadline has passed and I’m free to work at my own pace. It seems that Mikko and Brian are both interested in seeing the project completed, so it looks like I’ll be working hard on Rescue for the next few months.

Neil Carter

www.nether.org.uk

Making the Music and Sound

Mikko the Musician

I almost cancelled my intention to participate in this contest because I had a great deal of work with other projects going on. But then a big project was cancelled and I had some time again. I found Rescue, which is sort of a slow action game (I was actually looking for an action game), and contacted Neil.

After trying the early version of Rescue, I quickly had a vision of what the music would be like. Neil didn’t want it to be too modern in terms of its harmony, so I followed this rule. I’ve usually created this kind of stuff by using orchestral instruments only, but this time I wanted to add some electronic sounds to it. The ambient in-game track sounds electronic, but actually most of the sounds in it are “real” (low strings, choir). The main theme reappears in the action track too, to make the game audio more coherent.

I also promised to help Neil with sound effects, so I made them after the music was ready. I didn’t notice the rapid passage of time and was actually a bit rushed to finish them before the deadline!

I didn’t have any problems with this project. Communication was great and things worked out nicely. The only thing I got a little worried about was when Neil decided to change the purpose of certain music tracks to deal with changes in the gameplay. Fortunately the game developed in a way that meant we didn’t have to throw anything out. Just some of the sound effects I made have not been used in the game (yet).

Texturing the Models

Brian Creates the Eye Candy

I was happy to accept when Neil asked if I would like to produce textures for Rescue. Like Neil, I tend to start lots of projects but only finish a few and so the competition sounded like a good incentive.

The first step was to make sure we could transfer Neil’s models from form-Z to the 3D package I use, Cinema 4D, UV map them and then export the models as Wavefront .obj files which the object loader library could use. We soon discovered Cinema’s .obj file exporter reversed the surface normals. This was easily fixed by inverting the models’ normals before exporting. There also appeared to be a problem with the UV mapping in Rescue. By examining the UV data in Cinema 4D’s Structure Manager I discovered that the first UV coordinate was being zeroed when the models were opened by the object loader library. Neil and myself decided that this glitch should be worked around by editing the .obj model files (copying the first set of vt coordinates to the end of the UV list and then updating all references to it in the f polygon list) to save time hunting it down. Cinema 4D also didn’t export material files with the .obj model files and so manual file editing was required to construct them and link them to the model files.

The most time consuming part of my work was UV mapping the models. This was done in Cinema 4D with the freeware plug-in, UV Toolkit. The asteroids proved tricky to flatten as they had continuous surfaces. I decided to minimise variation in texture scale and shearing at the expense of creating seams. I also chose to stick to a single 512×512 texture for all the asteroids to save time and conserve VRAM. To change the texture scaling to fit the different sizes of asteroid I first mapped the larger asteroids to the full texture space and scaled down the smaller ones proportionately. However, this resulted in a very blurred texture on the large asteroids. I later realized that the object loader would tile the texture if the UV coordinates were outside the 0.0 to 1.0 range and so the smallest asteroids were assigned the full texture space with the larger ones scaled up, to a maximum of 4x for the biggest ones.

For the buildings and tug UV maps I found the best method was to break down the model’s surfaces based on the most suitable type of projection. For example, first I assigned UV coordinates to all the surfaces that could be mapped with flat projection, then all those that need cylindrical projection and so on. With all the elements mapped the largest surfaces were placed and scaled within the UV map. Finally the smaller elements were slotted into the remaining spaces. Much fine tuning of elements’ scales was required to optimize texture space usage. For most models the texture space assigned over its surface needed to remain constant. However the tug cockpit model was to be viewed from a fixed position so I skewed the scaling so that the surfaces nearer the viewer were allocated more texture space.

The textures themselves were based on reference images supplied by Neil (a photo of an asteroid, a shot of the Space Shuttle cockpit and so on) and discussions that occurred as the textures where developed. I took screen shots of the UV maps in Cinema 4D and opened them in Photoshop. All the textures were painted at twice their final target resolution. They were rendered using a mixture of filled and stroked selections and hand painting. Public domain photos from the web were overlaid on the painted texture to add detail to the metal, concrete and stone surfaces. I also placed blurred highlight lines along the model edges where I wanted emphasis.

Overall, given the limited time I had available to UV map and texture the models, I am pleased by the results. I would like to get involved in more game texturing in the future and am sure that what I have learned from this project will come in handy.

Brian Smith

www.steampunk.demon.co.uk

www.mikkotarmia.com

Industrial Revolution

The second option was rejected after a long debate in iDevGames’ forum about whether or not the modern game player was tough enough for the kind of gameplay we grew up with 20 years ago. Option three was the one that I finally went for.

I knew that my choice would not appeal to a very large section of the game playing community. Pandering to the 3D high frame rate obsessed voter would have been an easier path to score votes, but I wanted to make a game that I would like to play. I wanted to make a game that requires some thinking to play and not something that you can just pick up, press fire and play.

I also suspected that, as my game would not have a story line, I would not be able to score maximum points in the voting. This was confirmed once a large chunk of the contest had elapsed. I fully respect the various issues that caused delays behind the scenes of the uDevGames 2004 Contest, but it is a bit demoralizing for a developer to find the scope of the project, i.e. the rules, going against them when clarification had been requested long before the contest started. Luckily by that time I had decided I was in the contest for the fun of taking part and not out to win otherwise there would have been one less game to vote for.

When it comes to game development I’m more interested in the logic side of the game (my other projects such as FlipSquare, Chromacell and Metamorphosis point to this) and less interested in the look and feel. I guess this is why I can’t get very enthused over the graphics stuff in FPS games even if I try. Industrial Revolution is a game that contains a lot of behind the scenes game logic.

Why Cocoa and Objective-C?

I briefly toyed with the idea of using C++ and SDL and making this a cross-platform game, however I was already working on yet another evolution of my Metamorphosis game using C++ and SDL so I wanted to do something different.

Ever since I first started developing on the Mac I’ve liked Cocoa and Objective-C, so that is what I decided to go with. I know there are some people out there who would not approve of my choices, but it was my entry and not theirs.

Organization

A very important component of any successful project is organization. In order to keep track of what I was doing and what I still had to do in the project, I used my Project Tracker application. The uDevGames Contest was a perfect chance for me to put Project Tracker through a proper test in a realistic environment. The diary function proved very useful in allowing me to keep my development blog up to date on the uDevGames site. Recording every new idea, class and feature and noting every change to the design as I went provided an easy way of checking back on what I had done. It also provided a very useful document for writing this postmortem.

Just over half way through development (September 20th to be precise) I was introduced to OmniGraffle by a fellow Mac developer who unfortunately failed to last the course in uDevGames 2004. Using a trial version of OminGraffle Professional, I produced a set of class diagrams so that I could get an overview of how everything fitted together. My intention was to publish these diagrams as part of the development blog but time did not permit this. The diagrams will be included in the source code released as part of the contest, however.

Priorities

At the very start of the contest I made the decision that I would not let the game rule me. I would do the development when I had spare time, and if the game failed to be completed in the three month window it would not be the end of the world. Taking this non-pressured approach ended up being more productive than trying to cram coding into every waking moment. I feel that knowing you have to get something potentially complex finished by a fixed deadline can sometimes lead to the ‘headless chicken’ effect where you spend the whole time sitting there thinking ‘I’ve got to do this! I’ve got to do this!’ instead of thinking about the actual project.

Most of the initial development took place during my lunch breaks at work. This meant that for the first couple of weeks I spent no more than about eight hours on the project. The first real long sessions of coding came about due to being stuck for hours on trains going to and from meetings.

Another opportunity for putting in some serious development time arose when I was away on holiday for a week. However, I again decided that a life in the real world was more important than the contest.

Even right up to the close of the contest I did not end up doing any of those “lack of sleep” coding sessions. However I must admit to losing more than a couple of hours around midnight on several occasions just playing the game and trying to claw back the money I spent on my railway!

Development Phases

Before I began coding I had an idea in my head of the distinct phases of development I planned to do. The plan was as follows:

  • Get the basic Cocoa framework up and running (this used the initial steps I had previously written for the FlipSquare tutorial).
  • Office screen — Text based display of player assets (such things as factories and trains).
  • Map screen — Graphical display of player assets on a map (this would just use placeholder graphics and text labels).
  • End of game turn logic
  • Expanding transport network
  • Invention Tree
  • Inventors
  • Computer players
  • Final graphics
  • User guide

It’s Still in Development!

Whenever I’m developing a game, or any other application involving some kind of graphical display, I always use placeholder graphics right from the start. The final, or even appropriate but not final, graphics can be added once everything else is working. You can see that an alien is in the wrong place just as well if the alien is a green square.

This placeholder approach was what I used for my menuing/button system. In fact, the system has been designed to allow full functionality and a quick game to be developed without any graphical work at all.

However I must say that I was slightly disappointed to find out just how many people who visit a game development site do not seem to understand this approach. If I was to get a positive vote for every person who questioned the point of having a tool tip appear beside a button that contained the same text then I would have won the contest! Apart from this little rant though I must say that the quality of feedback and interest for Industrial Revolution throughout development was very good. It was the public who convinced me it was worth carrying on after the rules fiasco.

How it Evolved

During the progress of the contest Industrial Revolution evolved. Some things were dropped before they were even coded. Other things were coded and then removed when it became obvious that they just did not work well. A couple of ideas only made themselves apparent during development.

The following is a list of what was dropped from the contest entry:

  • Computer opponents
  • Inventors
  • Recruiting factory and construction workers
  • Extended Invention Tree
  • Additional transport upgrades
  • Different maps

The following is a list of what was written but then dropped:

Shop Screen

Originally new transport and other things were to have been purchased from a shop screen. This screen was similar to the shop system in my uDevGames 2003 entry Garden Pests and a lot of the code came from that game also.

Office screen as main screen.

During early development the Office screen was the main screen where are all the moving of transport and other housekeeping was carried out. The enhanced Map screen made a lot of this functionality redundant so it was removed.

The following is a list of what evolved during development:

The Icon Wheel

Originally everything was controlled via buttons but this was changed to use a circle of icons along the same lines as NeverWinter Nights.

Technology Points

Originally the plan was to have various technology categories that the player built up, and reaching various levels gave access to new inventions. This changed to a system where the technology points were researched from a research budget and then used to ‘buy’ inventions. Had time permitted Inventors would have been required to build up these points using their various skill categories.

Unexpected Music

Due to the fact that Industrial Revolution had no story line to it I knew from the start that I would not be able to win the overall contest. With this knowledge I decided not to bother worrying about music for the game. This was the case right up until the first day of voting, when I showed the game to my line manager at work. As it happens, he has a Mac and a collection of music hardware and software and so he offered to create some music for me. The original idea was to have four pieces of music: title screen music, in-game music, good end-of-turn music and bad end-of-turn music for when a disaster had occurred. However due to time and file size limits we just stuck with the one piece of music.

Knowledge Gained

One of the goals of the uDevGames Contest is for the developers to expand their knowledge. In my opinion it is always easier to learn something new when you have an actual use for it, and the development of Industrial Revolution was the perfect opportunity for me to try out some new things.

Scripts

I’ve heard a lot of people going on about how using scripts for various things in games makes life in development a whole lot easier by cutting down on compile times when making small game changes. Personally I was not convinced about the idea as I find it quicker to hard code things than adding layers of additional work to process files. However the phrase, “Don’t knock it until you’ve tried it,” comes to mind so I gave it a go.

The area of the game I actually tried it out on was the in-game training tasks. One path I did consider taking the game down was to add levels that each required certain tasks to be completed. My plan was to have a script that would easily allow training tasks, and the possible level tasks, to be set up and loaded into the game. In total I must have spent about seven hours getting this system working correctly. There was no way that recompiling every time after editing the in-code task entries would take as much time as that!

What finally convinced me that I’d really wasted too much time on the scripts was that in order for me to test some additional game features using their own tasks I would have had to create multiple script files and keep copying and renaming them compared to just commenting out a couple of lines of code.

The script episode had not been completely pointless though as it gave me a chance to discover and really come to grips with a lot of Cocoa’s string handling abilities. I have put this knowledge to good use in some other projects that I’m working on.

Selectors

I finally got a handle on selectors during this project. I started off using them for a couple of simple things, such as calling the relevant screen drawing routine dependent on the current game state.

Next, I totally rewrote my Button class to use selectors instead of large chunks of switch statements.

Selectors also played a part in the training tasks, the Icon Wheel and Inventions, and briefly in the shopping system before it was dropped.

This new understanding caused me to become distracted from the contest with rewrites of sections of my planned Cocoa Desktop Games book.

The Future

The first task ahead of me is to fully document and tidy up the existing source code.

After the source code has been dealt with I will look at putting in the functionality that I had to leave out, with the exception of the computer opponents. I intend to get the game to a stage where it is completely playable with no opponents. Only when it is working will I add in the computer opponents.

However, before I think about computer opponents I’m toying with the idea of adding in some timers and giving the player the option of real time as well as turn based play, and even the option of mixing the two should they wish.

My other big plan for the game is to use the basic engine and build a construction kit for making similar kinds of games.

I also plan to produce a more detailed write-up of the development of the game and revised construction engine to turn into a series of tutorials, or maybe include it in my still to be completed book. Another alternative is to maybe turn it into a course at the iDevGames university should it ever come into being.

  • Developer: Andrew Sage
  • Language: Objective-C
  • API: Cocoa
  • Lines of Code: 8,352
  • Critical applications: Xcode, Interface Builder, ClassBuilder (personal class building wizard app), OmniGraffle Pro (trial version), Adobe Photoshop, ProjectTracker, Microsoft Word
  • Development Hardware: iBook G4 933MHz 256MB
  • Test Hardware: iMac G4 800MHz 768MB

Kiki the Nanobot

What Went Right

The Idea

Three months is still a very short time, so I knew I had to come up with a very simple idea and stick to it in order to finish before the deadline. Sokoban came to my mind, which I really love. I decided to create a game with rules of similar simplicity but as many possibilities for complex and mind-challenging puzzles. Since it was clear from the beginning that the game would be 3-dimensional, the decision to implement a user interaction scheme similar to Kula-World was quite obvious.

kiki03.gif

When discussing this plan with my friend Rolf, we came up with several ideas for different game items and mechanics. Most of them were just copies or simple alterations of ideas we knew from other games. But there was one exception: the idea of an unusual physics with a subjective gravity, a gravity that has no fixed orientation in space, but one that is bound to the player and changes with its orientation. Letting the game take place in the nano world was a good solution for explaining the altered physics. But it could also be used as an excuse for simple graphics and other glitches that might appear. Altogether I was very happy that I quickly found a simple but appealing idea with some originality in it. Highly motivated, I began to evaluate which tools I would use.

The Tools

kiki04.gif

I knew I wanted to reuse some of the code I wrote for my previous project, mainly some basic vector, matrix, quaternion, and projection utilities. I also wanted to avoid long compile times and do some rapid prototyping in Python. After evaluating some systems to bridge between C++ and Python, I chose SWIG, which I can highly recommend. I’ve never written a program with sound output before, so I tried the _SDL_mixer_ library, because I already appreciated the well-done SDL framework. There was no need to look for other solutions, since the sound system I hacked together in a few hours worked perfectly for me and I felt no reason to touch it again, despite its probably quite naive implementation. Compliments and thanks to the author for this very nice library.

The shareware program Amadeus II was my choice for simple sound editing tasks. After trying some free modelers, I found that Wings3d is the best solution for me because of its stability and ease of use. I feel that the time I spent with these evaluations (approximately a week) was worth it, since I found a couple of free but very good libraries and tools that enabled me to be quite productive.

Planning

kiki05.gif

Since I was the only person on this project, I felt no need for a formalized design and project plan. Nevertheless, I knew I had to focus on a small set of predefined features and estimate the time needed for their implementation. The rough project plan I sketched has been a good approximation. Despite some unforeseeable problems, I managed to finish the game in time and without any stress. When looking back, I think that defining the scope and features of the game beforehand has been of even more importance. The first playable version of the game was finished quite fast and I have very often been tempted to add more features. With a few exceptions, the feature list prevented me from doing this and enabled me to concentrate on improvements instead.

Scripting

If somebody would ask me: “What is the one best thing you have learned by doing this project?” I would surely answer: “Discovering the power of scripting in general and the coupling of C++ and Python especially.” The time I saved by being able to test the various aspects of the program and change its parameters in real time, without having to recompile it, was simply invaluable. Thanks to SWIG, I could easily export almost all the C++ classes and methods to the python interpreter running inside the game. This not only eliminated the need for implementing a level editor, but also helped a lot in many different situations. The last time I programmed in Python was years ago. I am amazed at how mature this language and the accompanying libraries (modules) became in the meantime. Many compliments go to the people who developed it!

What Went Wrong

kiki06.gif

Design

The player movement turned out to be much more complicated than planned. But instead of redesigning the whole mechanism to fit the unforeseen needs in an early stage, I hacked around the initial structure and soon got quite a mess. This introduced some runtime bugs which were very hard to find (or still unsolved), mainly because I have problems understanding my own code now. But the worst thing is that the whole system virtually isn’t extensible anymore. If I had changed the design early enough, possible additions like moving sideways or jumping backwards would have been much easier to integrate. I honestly think this is the only thing that really went wrong. But let me try to summarize some things that have been ‘sub-optimal.’

Shadows

As mentioned above, I lost my focus sometimes and implemented features that hadn’t been planned. This wasn’t a problem as long as they improved the game, but on one occasion it was a real waste of time, since I didn’t use any of the code I created for days. This was when I tried to implement shadows. After I got the first version of the shadow system working, I realized that shadows were absolutely not fitting into the overall design of the game. Instead of adding some ‘realism’ to the world, they just made it look confusingly complex. Additionally, a proper implementation would have been very time consuming since I didn’t anticipate the clash with the quite heavily used transparency.

Lighting

kiki07.gif

When I compiled and ran the game the first time on Jaguar, the lighting was broken. This has been very annoying, since the optical appeal of the game completely depends on the lighting instead of texturing. After some days of debugging I came to the conclusion that there must be a bug in the OpenGL implementation of the new Jaguar release and asked for help in Apple’s OpenGL mailing list. After getting no immediate reply, I obsessively tried to find a workaround myself. Eventually I found one, but the frustrating process of finding it almost drained all my motivation. Looking back, I should have asked for help earlier while anticipating some time for its arrival, since a nice person sent me another workaround later.

Conclusion

I learned a lot while making this game. I surely will continue to use the C++/SWIG/Python combination in future projects but I will probably drop the inclusion of the frameworks inside the application bundle. I will also try to improve my design capabilities and refactor more mercilessly in the future. Asking for feedback in the iDevGames forum has been a good idea and I hope to exchange more experiences on the web and in mailing lists. I am planning to port the game to Linux and Windows with my friend Znek in the next months and I will certainly take part in the next competition, if I have time then. There is already an idea for the next game growing in my head. I had a lot of fun developing the game and taking part in the competition. I am quite proud of the work I have done and it makes me happy that some people like the game as well and provided me with valuable feedback. I would like to thank the organizers, participants, and sponsors of the uDevGames Contest, the people playing, voting and providing feedback for the games, and the many people programming, documenting and maintaining Open Source programs and libraries.

  • Genre: 3d puzzle
  • Developer: Thorsten Kohnhorst
  • Url: http://kiki.sourceforge.net/
  • Team size: 1
  • Released date: November 15, 2002
  • Project length: 3 months
  • Development hardware: Cube 450MHz G4 and iBook 500MHz G3
  • Critical applications: Apple’s Development Tools, Python, SDL, Wings3d, SWIG

Recent Forum Threads

About iDevGames

Since 1998, iDevGames has been educating, supporting and enhancing the community of game developers that produce video games for the Apple Mac and iPhone platforms. Get the latest game development news by subscribing to our news feed.