Image Editor Seashore 0.1.6 Released

Seashore is an open source image editor for Cocoa. It features gradients, textures and anti-aliasing for both text and brush strokes. It supports multiple layers and alpha channel editing. It is based around the GIMP’s technology and uses the same native file format.

What’s new in this version:

  • Adds support for JPEG 2000 image format (Mac OS 10.4 or later only)
  • Adds Posterize plug-in
  • Adds Threshold plug-in
  • Adds rulers
  • Adds the ability to reapply the last effect
  • Adds tool tips
  • Adds the ability to disable multithreaded brush strokes
  • Adds a menu item for layer rotation
  • Fixes problems with the centering view in Mac OS 10.4
  • Fixes problems with the canvas not being refreshed when zoomed out in Mac OS 10.4
  • Fixes a number of rotation bugs
  • Fixes PDF importing
  • Fixes a bug when condensing to content
  • Fixes a bug when zooming in or out on content
  • Fixes a bug when printing at resolutions other than 72 dpi
  • Improves usability

SourceForge: Seashore

http://seashore.sourceforge.net/——-

image,editor,seashore,016,released

Nanocrisis Postmortem

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:

Interview with AdiumX Team’s Programmer

Not entirely game related, DrunkenBlog.com is featuring an exhaustive interview with Evan Schoenberg of the AdiumX team, describing the team’s experience with Cocoa, reverse engineering, protocols, and modding, among other very interesting stuff. This is not a quick read, but it’s sure to provide you with a snapshot of the backstage of developing an open-source project with Cocoa in a team of 12.

Related links:

interview,adiumx,programmer

Adventures on Pirate Isle

Another interesting thing to note is that my target audience for Pirate Isle was much younger than those I normally develop for. One goal for Pirate Isle was that it would be fun and appropriate for gamers of all ages, and this resulted in a number of technical and game design considerations. I tried to keep the number of individual controls down to a minimum (the gamer only has four buttons to control Slash fully: left, right, jump, action) and the default configuration is set up so that two children can control Slash at once.

Not only did I choose a different target audience and genre of game to make, I also decided to explore different technologies with which to make the game. The entirety of Adventures on Pirate Isle is defined in a number of XML files which are then interpreted by the executable to display the game, much like how your web browser interpreted the HTML of this document in order to render this web page. The engine I created for Pirate Isle utilizes XML to provide structure and easy parsing of the game objects, but without some kind of scripting language it is nothing more than a file format to store definitions. For the brains behind the brawn, Pirate Isle uses Lua.

Yo ho ho, and a bottle of rum!

pirate_isle_2.jpg

Slash against the octopus

I found Lua to be simple to incorporate, easy to learn, and quite powerful in its own right. I had no experience with scripting languages before writing Pirate Isle, so the first thing I did was research the various languages. As normally happens, this particular topic of discussion had already been flushed out on the iDevGames forum. What excited me about Lua as opposed to the other scripting languages is its small footprint. Incorporating Lua into my project was a snap, and it handled running on Mac OS 9, Mac OS X, and Windows beautifully. Lua is also a simple, easy to read language, perfect for allowing interested parties to modify the game to their liking.

Even though Lua is as cool as it is, it is still an interpreted language. This means it lacks what games need most often, performance. My initial tests with Lua showed that it was too slow and cumbersome to have it handle every aspect of the game (such as storing and rendering the sprites). After some more tweaking and brainstorming, I ended up with what is best compared to a car and its driver. The car in this case is an OpenGL engine written in C—clean, fast, quick to respond and handles all the brunt work of going from here to there. Lua then fulfilled the role of the driver. Lua tells the car where and when to go, but leaves the specifics of how the car travels along the road and bounces against the rocks to the car. This approach improved performance dramatically.

That’s great, but now that Lua has been “demoted” to just being the driver I ran into another problem. How should all these scripts be structured, and what API needed to be developed in order to place the least amount of burden on the scripting language?

Hello XML

Using XML allowed me to define separate sprite objects, each with its own initialization, update, and event Lua scripts for unlimited customization. Once this was in place, I had a quick and easy framework for adding new, unique sprites to the game. This was also extremely useful for quick prototyping of new sprite animations, as well as doing quick fixes since modifications to the script did not require a recompile, and in many instances didn’t even require the game to be reloaded!

Avast ye ZBrushers!

pirate_isle_zbrush.jpg

ZBrush in action

I found out quite quickly that making a platformer is hard. I enjoy switching between genres when choosing games to make, and I must admit that the amount of work it takes to make a decent platformer is far beyond what I originally anticipated. If the sheer number of assets were not daunting enough, the intricacies of level design and the pressure to balance it just right are enormous. When I first developed the idea for Pirate Isle, my thoughts were to use pixel art in order to recapture some of the “retro” gaming experience. An example of this can be seen in the first color version of Slash in the image at the top of this postmortem. However, after about two weeks of some serious sprite creation and animation framing, I realized that at my current rate of graphic creation I would never make the deadline in time. Also, my pixel renditions of Slash didn’t have the “cute and cuddly” feeling that I was going for (as my lovely wife so pragmatically put it the pixel version looks like a “drowned rat”).

It was too late in the contest by this time to redo many of the hand-crafted game items I had already made, and Steve was already working on some hand-drawn enemy sprites, so I was forced to make some tough decisions. I settled on using the hand drawn objects I had already created (for instance, the fruit power ups, the tombstones, etc) and the hand drawn sprites Steve was making, and I would use a rendering package to create the backgrounds. In steps ZBrush!

ZBrush has got to be the finest character creation tool I’ve used yet (beating out such packages as Carrara Studio, for example). My good luck in the 2002 uDevGames Contest nabbed me a copy of ZBrush, and utilizing it for Pirate Isle helped give the game some character. I used ZBrush when creating the “tiki” statues, the jackal statue at the end of each level, and the “big-boss” octopus at the end of the sixth level. Using ZBrush for this purpose was incredibly simple and an enormous time saver. ZBrush allows you to start with a simple geometric object (I used a sphere when creating the octopus and a cylinder when creating the tiki statues) or you can use their unique modeling technique known as ZSpheres (ZSpheres are the 3D modeler’s equivalent of the little 2D mannequin most artists use to get proportions and posture right. I used ZSpheres when creating the jackal statue). Once you have your basic object, you can then mold and sculpt that object in a very intuitive manner, allowing for the creation of eyes, nose, mouth, and other facial characteristics in a matter of minutes.

In the end, the mixed-and-matched nature of Pirate Isles graphics hurt it more than helped. Poor planning in the beginning and my underestimation of the amount of art work required to make a good platformer caused Pirate Isle to suffer more than it should have. The experience was not a waste however, since I had a blast learning how to create “pixel art,” as well as spending more time with ZBrush.

Clear sailing ahead!

pirate_isle_3.jpg

Game Map Screen

Building upon past experience

Although the uDevGames Contests are only three short months long, I always try hard to make sure I code with an eye for the future. In some cases this “future planning” results in some wasted time, but in all too many cases it results in saving even more time. Adventures on Pirate Isle uses the same engine code that I wrote for The Belt last year, and it is even an evolution of the base code I wrote for Imp Fodder in the very first uDevGames Contest. Reusing this code allowed me not to worry about the average stuff such as how to open a window, or take over the fullscreen properly, or develop an architecture for my animation…you get the picture.

Utilizing a Scripting Language

We’ll be revisiting scripting languages in the “What went wrong” stuff below, but using a scripting language had many advantages. It allowed for quick bug changes, provided for much more stable code (when there is a problem with a script it simply displays an error and doesn’t crash the entire program), and it allows for artists and gamers to easily modify the game to their liking. All in all using Lua saved me both time and effort.

Non-tile Based, Polygonal Collision Detection

Although this may be a little noticed feature, Pirate Isle was not based on tile like most traditional platformers. All of the objects in Pirate Isle could be an arbitrary size, and all of them could have an arbitrary polygon as their collision boundary. This allowed for Pirate Isle to develop a non-tiled, more natural look, although the added complexity in the collision detection routines required some last minute fine-tuning for it to work on older computers.

An Enthusiastic Musician

Dori Eggan is the wife of a relatively new friend of mine, Nate. Dori and Nate both came from my home state of Ohio, and Dori happens to have started a career as an educator in music. I approached her to see if she would be interested in experimenting in the world of game music, and I found she was quite enthusiastic about creating some original content for Pirate Isle. This panned out well, considering this was her first foray into the digital music realm and Pirate Isle scored sixth in the Sound and Music category. I sure next year she’ll be bursting with ideas and pent up talent, so watch out!

A Cool Artist

While I did 95% of the artwork for Pirate Isle, all of the creative genius which provided for the enemy sprites came from Steven. For his day job Steve does the cool art for many of Freeverse’s titles, but sometimes drawing monkeys for a living can get repetitive. When Steve let me know he’d be interested in redrawing a few sprites for Pirate Isle I was ecstatic, and would have been a fool to say no to such a talented artist. The various enemies Slash encounters are one of my favorite parts of the game, and thanks to Steve they didn’t disappoint!

Good Vocal Talent

Finding vocal talent for a game is challenging, especially for a freeware title being developed in under three months! So when the time came to create voice-overs for Slash my wife and I both sat down and recorded our voices. Needless to say her voice-overs were an order of magnitude better than mine, and thanks to her Slash has a voice instead of just little text bubbles. Some extra work could have gone into the sound processing of the vocals (to help reduce some of the static and such), but all in all I was pleased with the results.

Anyone want a peanut?

pirate_isle_4.jpg

Battleboard Screen

Interpreted Languages are Slow

Here is where we admit that scripting languages have their faults. First and foremost is performance. Lua is also deficient in that it does not have a C API for separate compilation and later loading of these pre-compiled chunks. Now, before I get a ton of emails saying that luac can input a Lua script and output the compiled version, note that this is not what is needed in this instance. The whole point of XML encapsulated Lua code is that it becomes simple for gamers to modify the game. This means that pre-compilation or running the scripts through a conversion tool is not ideal. What I really needed was a lua_compilestring() and lua_runcompiledstring(), but even after digging into the Lua library code myself I was unable figure out a good way of doing this. In the end, I was able to simulate pre-compilation by having my C code encapsulate all of the scripts in their own unique function. This reduced my script compilations from 60-200 lines of code to a single line of code. This managed to get the game to run well on 400MHz machines.

Lack of Audio Input

When my powerbook died late last year, I was forced to upgrade to a “Windtunnel” G4. This was nice development-wise, but one small speed-bump is that regular old microphones don’t work with this computer. I’m no audiophile, but apparently you need a special kind of microphone that I didn’t have the money for in order to use the audio input jack. I ended up borrowing my mother’s DV camera and recorded sounds and voice that way, but this turned out to be incredibly cumbersome. My disappointment in spending a little over $2,000 for a new computer and not being able to use a regular old microphone was profound.

HID Manager Woes

HID manager is actually a simple API to use. In a few days I developed a nice wrapper for it, had it integrated into my game, and was running Slash around with my little Gravis Gamepad. Unfortunately, it was something as simple as keyboard input that seemed to give HID manager all kinds of trouble. Yes, I understand all keyboards are evil since keyboard rollover is in their hardware, but for some odd reason HID manager itself was missing some key combinations which regular Carbon events were getting fine. My particular example is with the arrow keys. When I was gathering events with Carbon events, using the left, right, and up arrow keys in conjunction with the space bar worked flawlessly. When I switched to HID manager only, this key combination no longer worked. So although keyboard rollover still effects the Carbon events code, there must be some other bug in HID manager which caused that oddity in behavior. In the end I used a hybrid system of Carbon events for keyboard and HID manager for other input, and that seemed to work best.

Limited by the Design

As I mentioned earlier, I underestimated the amount of work that a platformer needs. My original plan for Pirate Isle was to release the uDevGames version with three separate worlds having different scenery and enemies, and each world with 5-7 individual levels. As you can see, I only got one world with six levels completed, and by then there was not enough time left to consider making an entire new world.

Hoist Anchor!

This year for uDevGames I wanted to explore new areas of game development, experiment with different art techniques, and ultimately just have a fun time creating a game that children of all ages could play with their parents. It is doubly satisfying hearing from others that “the sugar glider hero is very cool” or that “Slash is so cute,” because coming up with a good hero character and portraying that character well to the audience is probably the hardest thing to do in any medium, be it movies, literature, or games. Although my willingness to explore new areas resulted in somewhat of a “melting pot” of graphical styles, I had fun doing it and feel that I’ve gained much from the experience.

  • Genre: Platformer
  • Developer: Rocco Bowling
  • Url: http://homepage.mac.com/felinegames/
  • Team size: 1
  • Released date: June 20, 2003
  • Project length: 3 months
  • Development hardware: “Wind Tunnel” PowerMac G4

GL Golf Postmortem

What Went Right

NeHe and Cocoa

Learning OpenGL and Cocoa in three months is no easy task! The first step was reading my uDevGames 2002 prize, ‘Building Cocoa Applications.’ This is a great book; after reading about 200 pages and building the project with the book, I had a solid understanding of what Objective-C was, and the incredible powers of object oriented programming.
Read the rest of this entry »

Gaichu Postmortem

What Went Right

Early Planning, or “The List”

By choosing an update to a classic game, a lot of the hardest work was already done. Since Ladybug was a maze game, I had a genre that was proven to work. In addition, I had already worked on an unreleased maze game, so I knew most of the programming challenges that would confront me. With that in mind I grabbed a fresh yellow legal pad and started planning. I wrote down every game play feature I thought I would need. I planned out the interface. I wrote out several classes and how they would work. Whenever I would think of something new, I would add it to the to-do list. If I knew I wouldn’t have time to do the programming or art for a feature (such as terrain multi-texturing, or multiple level designs), then it didn’t even get written down.

As the three months went on, the list grew and shrank, but it always remained a roadmap for what I had done and what I still had to do. I could see which features would need to be implemented next, and which could wait until the end in case they needed to be cut. It wasn’t a strict schedule or design document, but it did its job. I was kept sane as the list kept the project organized. My brain could focus on the task at hand instead of the overall picture. In the end the vast majority of features made it into the final game, leaving a few to serve as the basis for a post-uDevGames update.

Cocoa or OpenGL

Apple has done their homework — ;Mac OS X is a dream to use and to program for. I knew before I even started work on Gaichu that I would be using Cocoa and OpenGL to realize it. OpenGL was a no-brainer, as there is no other alternative on Mac OS X for 3D. However, I had never done anything more than a few simple tests with it. Cocoa worried me as well. I had programmed several full projects using Carbon for both classic Mac OS as well as Mac OS X, but my only Cocoa programs had been those same OpenGL tests.

After the three months I can say that I shouldn’t have been worried at all. Obj-C is a beautiful language and Cocoa is a beautiful API. The Cocoa development docs are a great resource, and what can’t be found there can easily be found on-line (CocoaDev is a favorite). OpenGL is very easy to use and puts the old QuickDraw API to shame. And needless to say, the on-line resources for OpenGL are vast. Anybody who still isn’t using Cocoa or OpenGL needs to get with the times and discover the greatness of these two APIs.

Listening to Early Feedback

I knew from the beginning that since I was working alone I was going to need feedback from as many outside sources as possible. I tried hanging out in the iDevGames chat room as often as I could, and I had a Gaichu feedback thread in the forum within the first three weeks of the contest.

The early feedback was invaluable as my “testers” caught several bugs that I wouldn’t have caught otherwise. I thought that my first attempt at player movement code was more than adequate, but because of feedback I ended up re-writing that piece of code more than three times. And I must conclude that player movement in the final version is vastly superior to the earlier versions.

Listen to your testers. When you’re playing your game four hours a day, every day for months, you start to lose perspective. Just because you think a certain feature is adequate, or that the difficulty is right on, that doesn’t mean that the rest of the gaming public will as well.

What Went Wrong

Inconsistent Art Focus

If there’s one thing that I hate more than anything else in shareware games it’s amateurish artwork. I used to believe that artwork wasn’t what made a game great, but it’s hard to have fun playing a game when the artwork makes your eyes bleed. In the not-making-your-eyes-bleed category, I think Gaichu does pretty well, however I still wasn’t satisfied with its artwork.

Gaichu lacks a consistent art focus. Since I was doing all the artwork myself, I thought that I wouldn’t need to do extensive sketches and tests for each piece of art. I thought that I could just make each piece as necessary and in the end it would work out since they would all be made by the same person. It didn’t turn out that way. Most of the artwork was redone not once, but multiple times. Some pieces like the title-screen were slapped together at the last minute.

Gaichu badly needed an art director with a unified vision for what the game should have looked like. Gaichu’s final artwork isn’t bad. In fact, there’s a lot I like about it. However, it’s not as good as it could have been, and that’s something I will be striving to fix in the near future.

The One-Man-Band

When you’re making a game by yourself, you have to wear a lot of hats. Sometimes you’re the producer, sometimes you’re the programmer, sometimes you’re the sound guy. Unfortunately, at times certain hats get more of a preference than others. For Gaichu it was definitely the programmer hat that took up most of the time. When presented with both a programming and an art task, the programming often took precedence. Art and sound assets took a back seat and didn’t receive as much attention as they deserved.

Regrettably, there’s not much that can be done to remedy this. There are really only three possibilities. You can extend the deadline to give you more time, you can hire one or more persons to assist you, or you can overextend yourself and work even harder for longer hours. For the uDevGames Contest, number two is the only real choice; unfortunately I have a phobia of letting other people help me on projects such as this. A partner or two on a later project might be something I want to explore.

Not Enough Early Feedback

Above I said that early feedback was one of the things that went right, however it’s also something that went wrong. Browsing the forums shows that a few of the games seemed to monopolize most of the forum members’ time. Some games reached multi-page threads almost immediately, while others died out without constant developer bumping. When you’re a developer starved for feedback, you start begging for comments and suggestions.

As the voting was winding down I received several comments that the game was too hard, that the enemies were too fast. That’s a great comment that can be used to improve the game, but it came too late in the contest to work on it. Next year I’m going to lock several testers in my basement and force them to give comments and suggestions.

Conclusion

In the end, Gaichu did pretty well; 5th place in Polish, and 10th Overall, is nothing to sneeze at in a competition involving 43 games. Of course, the best prize is that after years of programming and attempting to make games, I’ve actually made one. When someone asks me what I do and I respond, “I make games,” I no longer secretly think, “Liar!” In that regard, uDevGames 2003 was huge success.

Project Details

  • Number of Developers: 1
  • Length of Development: 3 months
  • Development Hardware: 867MHz G4 (1.1GB RAM/GeForce2MX 32MB), 350MHz G3 (448MB RAM/Rage128 16MB)
  • Critical Applications: ProjectBuilder, InterfaceBuilder, Photoshop, Hash Animation Master, UVMapper, Peak DV, Melody Assistant, OpenGL Profiler, Shark
  • Project Size: 48 code files, 9,833 lines of code, 100MB of art and sound assets

Chopper Postmortem

When I tried to think of a game I could make that fitted that restraint, something based on an old memory of a 2D scrolling helicopter game came to mind. I later found out that this game was the Apple II classic “Choplifter.” My Dad told me that I played it a lot when I was three or four years old, and it had obviously left a mark in my mind.

With the idea starting to form, I began work. The first step was to make an OpenGL view in a window, and add player control. I used Cocoa and Project Builder, as I was already familiar with them, and within a day or two I had a simple Chopper sprite and basic (but very buggy) player controls, in a spunky metal window.

Then I decided that for this type of game I would need a level editor, so I started working on that. The level editor evolved alongside the game, and was hugely useful in the process.

Continued Development

From there on in, it was a matter of refining and adding to what I had. I started adding collision detection, tanks, and eventually gunfire and explosions. Chopper evolved into something that I had never thought was possible when I had begun.

Graphics were slowly updated as I went. Usually I would put in placeholder graphics for a start, and change them when they annoyed me enough. Most graphics were overhauled at least a couple of times, if not more. Some graphics, such as the Chopper graphic, and the sky and ground, were updated or replaced at least half a dozen times.

An interesting decision I made about a month into development was to give the 3D effect. Chopper has a 2D engine. It’s all done with an orthographic projection so there is no z coordinate. As a graphical enhancement I decided to make it pseudo 3D. I added side walls to buildings, and depth to the grass. This made some of my earlier work redundant, such as angled tiles, and also made some things far more difficult for me later on. It may also have limited some gameplay elements, as it took a lot of my time to make things move properly. I believe it was worth it, though, as it added to the realism element of the graphics, and taught me a great deal.

While making Chopper I used “to-do” lists extensively. I would make a build, play it for a while, and write down any problems I found. I found this to be very useful in many ways. It was a good tool for finding what the player might see as a problem; it ironed out bugs, and there was a great feeling when I had an extensive list with all items crossed off. I also wrote down anything I thought might be added as an improvement to the game. Whenever I completed one task, I would build and run again, and write down anything I found wrong.

This part of the development process was always done on paper, as was any math that I had to do. I think a pencil and paper are invaluable.

What Went Right

I believe the most significant thing that went right was that I was a self-employed artist for the period, and as such was able to spend roughly 10 hours a day for the whole three months working on Chopper. Also, my girlfriend was overseas for six weeks of that time, and I probably worked about 15 hours a day over that period. Time was one of the constraints of the competition, and I had it in my favour.

METAL or other such options.

Despite the fact that I will probably never develop on such a limited machine again, I am glad that I used a G3 350MHz iMac to develop on. There were a few entries in uDevGames that as a result of being developed on higher-end machines run very poorly on low-end Macs, and could have been easily optimized to run much better. I was forced to optimize a lot throughout the process, just so I could continue to test it. This brings two benefits: one, I have learnt ways to optimize code, and two, Chopper can run reasonably well on a G3. I think a good way to develop games would be to code and build on a fast machine (aka G5), and test on the lower spec machine you are aiming for. I hope to do this in the future.

The iDevGames community and the uDevGames Contest were a tremendous help along the way. The combination of motivational and technical support has been amazing.

Another thing that went really right is that I got a great job as a result of developing Chopper. The experience and knowledge that I have gained have proved to be invaluable.

What I Would Do Differently Next Time

Instead of writing what went wrong, I thought it would be easier and more beneficial to say what I would do differently.

Number one on the list would have to be that I would do it all in 3D right from the start. As I mentioned earlier, pretend 3d in orthographic projection is a lot of work, and limits what you can do. This is going to mean that if I were to do Chopper 2 it would have to be a re-write.

I would plan more. When I started Chopper I had no idea what it was going to be like, only a very vague memory of Choplifter. If I had thought a little further ahead I could have structured better and saved myself a lot of headaches. Now that I have learnt more about my own capabilities and limitations I will be planning my next project a lot more carefully from the start.

Related to this, I would also refactor more. The code got very messy about halfway through when I changed the way map tiles were saved and loaded, and found I had to optimize. Instead of spending the day or three cleaning it all up and making it nicely structured, I just left it in a mess. The code turns into a dodgy DIY add-on spaghetti pile and it then takes a lot longer to add new features. Functions should also be shorter than I have made them, if anything just so it is easier to navigate through the code. The classes work well, but the functions within them need to be broken up into much smaller tasks.

I would write my own music and spend more time on sound effects. I spent about three days searching the net on a 56k modem for suitable music. It was a very frustrating process, and in the end the best I could find was less than satisfactory. A hired musician or music creating software is a must for decent music, and next time I will hopefully have the latter.

I would post less betas. I probably uploaded about 30 beta versions over the three month period, and although I received great support from people, many seemed to tire of it at the end. Fair enough too! Three or four betas would probably be a much better way to find out what needs fixing that I hadn’t already noticed while play-testing.

Conclusion

Chopper has been great fun to make. Most of all, it has been a great learning experience. If I had sat down before I began Chopper, and thought about what the best Choplifter clone I could make would be, I would not have imagined anything near the standard that Chopper turned out to be. I now feel I can do anything, and can’t wait to prove it!

Project Details

  • Genre: Arcade
  • Developer: Magic Jungle Software
  • Url: http://majicjungle.com/
  • Team size: 1
  • Released date:
  • Project length:
  • Development hardware:
  • Critical applications:

WildLands Hockey Postmortem

Win-Win Game Development

Experience is the difference between a project taking months or days. With the first version of the engine finished, it was time to make a game with real gameplay. I had spent years learning the mechanics of game architecture without going past a simple game like Pong. At around the same time I had created the Java game engine I was working part-time in television production. One of the projects was a hockey related mascot animation. This project fell through and went very wrong. It was one of those things that seem right at the time but was not meant to be.

With a significant number of the 3D models already created and some of the animation already done, it made sense to salvage this project and turn it into a game. Using animals eliminates the sexism and racial problems that often occur in modern games so this was a win-win situation for me. The animation was improved and set outdoors and a polar bear was made to accompany the elk. The intro was animated and rendered. At this point it was around summer 2003, and I had created the basic treatment for the game that would become WildLands Hockey. Things were stating to take shape: all the final goals were planned and documented. Gameplay was fleshed out along with look and feel.

Gameplay Design

The second version of my engine, which now included network support, was completed a month before the uDevGames Contest deadline, along with a simple Pong game. Thus, the final stage of game design and development for WildLands Hockey began. Game character graphics were created with animated cycles for the skating elk and head turns for the bear. The idea was to keep this game small as my web space was rapidly being used up.

Some size experimentation was done with the characters and puck to see what looked and felt right. The character graphics were rendered in Lightwave 3D with a sprite plug-in. The time clock and game timer were first, then the goalies were added and their motion created, which would simulate inertia and momentum. They only move on one axis and their motion was the basis for all the other character motion. The goalie motion was later changed to be based on the player motion. This simplified things and allowed for less data to be transmitted in a network game. With the goalie done it was on to the puck. At this point I decided to start with the in-game sound design as I would be in those locations of the code. So, puck related sounds were edited and prepped. Various sample rates were used to get the best sound and size ratio; as most of the sounds were low quality it was somewhat of a challenge to get them to sound halfway decent.

If you do not know much about the importance of sound then take a tip from those in film. Sound is essential — people tolerate bad picture but not bad sound. Do the best with what you have but never skimp on sound. The great sound on the C64 and Amiga is part of what makes these systems so legendary. The sound systems in my first and second engines were also spatial and velocity based. This further enhances player experience by simulating the audio environment. Fast actions trigger louder sounds, and sounds play through stereo speakers on the side of the screen where they occur.

The puck actions were mapped temporarily to the keyboard to create and fine tune its motion boundaries and reaction in the game. Interactions with the boards, goalie, and net were finished along with most of the gameplay states. This made sense here as the puck is the focal point of the game. Its actions drive the states.

With the puck completed, the players were last. I approached this with multi-player in mind initially, as I wanted to triage the seemingly more complex parts first so that the 2004 contest would not be missed. Player motion was designed and implemented first, then player interaction with the boards and other places on the rink. Puck and player interaction was done, then stick and puck interaction. I spent a good portion of time making all these simple details work the way I felt they should. I wanted it to feel right. These simple little details combine into the complex gameplay that can either be fun and interesting or tedious and boring. Later beta testing with complete strangers would determine if I had something worth playing. Shooting was then added, and lastly player-to-player collision.

With the multi-player game completed, the client server network game state system from version two of the engine was updated, adjusted, and tested to work with WildLands Hockey. The nice part about code reuse is that not only do you avoid the tedium of doing something over but you know that it will work. The network gameplay required some minor adjustment and went quite smoothly. It is not perfect but some things were just beyond my capabilities.

What Went Right

Text communication

Given the need to communicate with text and numbers, fonts and localization can be an issue when your game is meant for worldwide distribution. A system was required to handle generating and displaying text in the game. In keeping with the sports theme a matrix system was designed. This allowed me to program text and numerals on the fly and display them without having to worry about fonts, cross-platform text or other languages. The matrix system is based on the kind you see at a hockey arena (or used to). I had spent two years in TV working at hockey games so I had more than enough time to study this and create my own version. I even put in crawls and scrolls like you see in the credits screen.

Intro animation

Experimentations began as to what codec would provide the best quality and least amount of size with full screen playback ability on most systems. Animation can really suffer from the wrong kind of compression — all of the beautiful time-consuming details can be wiped out or blurred beyond comprehension with the wrong compressor or settings. After much experimentation QuickTime H261 (similar to MPEG1) was used, as it was the best for all requirements.

Beta testing and adjustments

I called on friends, family and whoever to get the network and other alpha testing done. Some minor tweaks and bug fixes later, I submitted it to the REALbasic games list for beta testing. The general consensus was that the game was way too hard to play. One of the developers on the list informed me that developers usually find their own games too easy to play. He said you should make the game far too easy for yourself to make it accessible for your perspective players. I took this advice and made the AI easier but also adjustable to keep it harder for advanced players. I also made the players skate faster and their sticks bigger to make getting the puck easier. With some other issues fixed and time running out things were not perfect but I was pleased with them. There comes a point when you need to just release your art, as it is never really done. Also, while the input of beta testers is invaluable you probably will not be able to get all the requests in. The best is to compromise on those large changes that may not be feasible.

What Went Wrong

Major architecture change required

Before starting the original development, I went out for lunch with a friend and former coworker who is also a programmer. His background is in networks and security, mostly on Unix. When I told him about the game I going to do he asked if I was going to have a network multi-player mode. Up to this point I never even thought about something like that. I had never done network programming before, even though I was a network admin in my time in the IT work force, and knew what it was all about. Out of ignorance I said I would make things multi-player over the network — how hard could it be right?! With his network programming background and some of his help I could get up to speed and do what needed to be done fairly quickly. This was early Fall 2003, when it became apparent that a version two of the engine would need to be created for full network game play. The game would not be completed for the uDevGames 2003 Contest. I had more than enough experience as a programmer working on large projects to know this. I had not entered yet so it was not a problem; things could wait until next year.

Impossible architecture

The sprite surface control in REALbasic was not designed for network multi play. In fact some said that creating a real-time 2D network game like this just could not be done. I was already too far into it to listen to that — it had to work. I came up with a multi-threaded model that would work around this. However, in order for things to work across all platforms I needed to use an experimental version of REALbasic. At this time Real Software was redoing the whole thread model across REALbasic. This, along with some other issues and projects that needed to be finished, placed my second version of the engine and WildLands Hockey on the back burner for some months, until the newer version allowed me to finish it.

Lack of resources for network multiplayer design

If game programming is a black art then network game development is a 33rd degree black art shrouded in the deepest of mysteries. Finding information on it proved to be very hard. Most books simply show you how to set up a socket and send packets back and forth. Network game development is so much more than that. I got help from Aaron on the network communication system, which is an extended UDP socket that would fulfill all the communication requirements for a game. The work developing an interface menu and internal game system to connect two hosts was also a big job. There was much to think about. My solution was to look at other games and pick what I liked and what was also simple and feasible for a person with small resources. At this time my head was really starting to hurt with all the intricacies of network game design; single local game design really looked very simple now in comparison.

In late summer of 2004 everything was ready with the new version of REALbasic and so was I. It was back to version two of the engine to create at least a basic working network engine for 2D games. The latest version of REALbasic also had the bonus of a remote debugger, making things much easier. I looked at all the resources I could on network game design and what I could not find was done by trial and error. By the end of September 2004 I had a working network game that was like Pong running in version two of the engine. Network connection, sync, packet loss, lag, prediction and all the other network related issues I had faced were mostly solved. I placed this engine on the web with its complete docs and a basic network game programming theory paper I wrote, in the hopes that it may be useful to someone else facing the huge proposition of creating a network real-time game. In retrospect if I had known the work involved I may have never tried this. Ignorance is probably responsible for more things out there that we could imagine.

Audio

The sound designer dropped out with no work completed. This is to be expected when your project does not pay and paying work comes in. I decided to do the sound design myself. This is why there are no sound design credits and some gaps where the sound designer credits were to be. I spent a great deal of time scouring the web and elsewhere for free and royalty-free sound effects. I managed to get an adequate selection of lower to medium quality sound effects that would suffice for the game and intro.

Player pixel level collision

Pixel level collision was too sensitive for player-to-player collision and felt wrong. I came up with a distance-based system that makes the game player interaction less touchy and more real.

AI and game play design

The AI for single player mode was the last thing to be created. AI is not my cup of tea and some design flaws reared their ugly heads. I had spent so much time on the multi-player mode that not much forethought went in to the single player mode. I was able to crank something out with a few kludges that was actually better than I had expected it to be but far from perfect.

Late feature additions and polish issues.

With the audio designer dropping out my work load became much greater than I had planned. Thus some of the polish suffered. I was not able to get an in-game user controls section and it was a late add in the start up screen. As well I never had the time to make a better user guide in the game, or at least an HTML file, as opposed to just text.

Reflecting on Game and Contest

The WildLands Hockey project was a big learning experience that put all my skills and years of experience to the test. I wanted to finish a commercial grade game (circa 1990) before I hit 30. I didn’t quite make it, though I was close. Many of the game’s features and design were made for me. I wanted to make things the way I would like them to be. There are such things as cool features not getting in the way of the game. So many games are created with glitz first, but to me the worst of all is making it so real it gets in the way of the gameplay. Some examples of this are the game intro. Sure I worked really hard on this, but it will only play the first time the game is played; after that you must select it from the menu. An intro is cool the first few times, but after fifty it can get irritating when you just want to play. Mine also has a click to allow you to exit it. This common courtesy I feel goes a long way to providing an environment that a player will want to return to.

WildLands Hockey is client server based; each frame in the gameplay is stored in a state that can be transmitted in a packet for network play. This same design can allow for replays very easily. While this is a cool real feature I felt it just hinders gameplay. I worked for two years in TV for a local hockey team and most of that time I ran VTR and did replays so I am sympathetic to this cause. However, while real players and officials need that time, computers and computer players do not, so it can appear to just get in the way especially when the game is only three minutes stop time. You don’t want to spend more time on extras than on gameplay. If people want reality then they can get their skates on instead of playing my game. I feel game developers need to offer their players more fun than reality.

I hope the simplicity of this game will appeal to people even where hockey is not played — this is one chance you take when your game may have a more regional appeal. I certainly learned a lot about myself and game development on this project. Somewhere along the way this project did become work. It is something I am proud of and something bigger than myself that I can leave behind for others. Who knows, maybe this game will some day end up in a Mac or PC emulator similar to the C64 collection I have that reminds me of the many of hours of entertainment I had back in the 80’s and provides inspiration for today.

Conclusion

After being around since the VIC-20 and working in IT, including networks, database admin, and as a member of a few large and small development teams, I have seen a lot over the past many years. I’m beginning to feel like a dinosaur. I’m losing interest in much of modern computing as I look back on the golden age with increasing fondness. This was probably obvious as my game was not much different than what you would have found in an arcade many years ago. In all this time I have never even tried any 3D programming due to a lack of interest, but as that is where it all seems to be going I’ll either have to get with it or do something else. I may eventually do more games and maybe salvage my Java engine to the mobile world, but who knows what the future holds. For years I have wanted to finish a larger game project and now that it is completed it is a bittersweet accomplishment. Some of the magic is lost once the mystery is gone.

  • Developer: Kevin Dromereski
  • Genre: Arcade
  • Team Members: 1
  • Development Tools: REALbasic, MBS plug-in
  • Animation & Graphics: Lightwave 3D 7.5, Photoshop
  • Video & Sound: Sony Vegas, Digital Media Workshop, SoundEdit
  • Hardware: 12” iBook G3 800MHz, Custom-built Dual 1.8GHz PC (Windows XP)

BitRacer

Nevertheless, I did succeed in making a fun racing game. Hopefully this postmortem will shed some light on the development process, what went right and what went wrong.

Tools

I used many tools to create BitRacer. For programming I used Xcode to program Objective-C, C++ and Python, making use of FTGL, FreeType, ODE, and OpenAL. To create the user interface I used Interface Builder. To create the 3D graphics I used Blender and Wings3D. To create the 2D graphics I used my own drawing program, as yet unnamed. To edit sounds I used Cacophony by Richard Bannister.

What Went Right

Polish

One of my aims was to make BitRacer immediately and easily playable, and I think I achieved what I set out to do. I used most of the last week of development time during uDevGames to work on the polish of my game. That is, the menus, options, help files and all that is peripheral to the gameplay. Spending this time on polish was a good decision, for polishing a game takes longer than you think. Now, having done so, I can really appreciate the difference it makes.

You never fully realize how important polish is until it is done. Often it seems inefficient to waste time on menus or help files, when you could spend valuable time on gameplay. Especially when you realize that polish takes far longer and it is not so fun. Yet when people play your game, few bother to read the read-me, or check the help, they just play it. If it doesn’t work or is unintuitive, they don’t have time.

An unpolished game will, simply by virtue of being unpolished, score lower when users rate it in all the other categories, and visa-versa. The link is stark when you look at the uDevGames 2003 results; the top three best overall games are identical to the top three games for polish. In identical order! Possibly it is the way in which people rate games in terms of irritation instead of enjoyment.

UI and IB

A more technical aspect of polish: Apple has a superb Interface Builder (IB) that is very easy to use. Every Cocoa programmer will use it for almost all aspects of their interfaces. But it is limited to the rather un-gamelike blue of Aqua.

One of the best technical ideas in BitRacer was the use of IB to create my interface using OpenGL. In Quartz Apple has a superbly powerful compositing engine, and it allows a developer to simply interweave OpenGL contexts, pictures and standard user interface controls. I used this to allow me to graphically put together my interfaces whilst also using OpenGL to provide a classier look and feel.

SCREENSHOT HERE

In the screen-shot above you can see how I used graphics and text as standard Cocoa objects, while at the same time using my own OpenGL menu items. I used the tool-tip field in Interface Builder to create text, buttons, checkboxes and radio buttons.

Retro Graphics

Or just half-baked graphics? Indeed, I was both criticized and applauded for my graphics. Unfortunately, I could not avoid the use of cuboids due to the physics, and so I spent many hours racking my brain, asking myself “How can you make a bunch of plain cubes look good?” I did not initially want to use retro graphics, however they were a good solution. Looking back, I now like them much more, the solid color against the dark background is a striking and different look. I like the way it gives BitRacer a distinguishable look, and their Tron-eqsue feel.

The Blender Track Editor

Initially I created levels that hard-coded into the code, but after that became implausible I used a text data file. However, neither of these methods came close to providing the ability to create decent 3D tracks. Again I was constrained by the physics. Instead of being able to use a 3D program to create sweeping curves, banks and rolls, I had to use imagination to create fun levels out of cuboids. No 3D program was going to let me export a list of cubes, who wants to model with cubes, right?

Fortunately I knew about Blender, a powerful free 3D program. One of Blender’s many attributes is its use of Python to allow scripts to access and alter its scenes and objects. I could use a script to output my cuboid information based on the objects in Blender. After hacking around I was able to use Blender to create 3D tracks out of cubes. I could now create and edit tracks in 3D, and using more of Blender’s abilities, I was able to position a tree of waypoints and checkpoints for the AI to race around.

What Went Wrong

ODE (Open Dynamics Engine)

Physics is extremely hard to get right. I have written my own physics engines, notably the one behind SillyBalls. For BitRacer I decided it would be better to use a “real” physics engine, for which the only genuine option for free use on the Mac is ODE.

Using ODE and creating physics took up a vast amount of time whist working on BitRacer. The myriad of interdependent variables and options are extremely confusing. For example, I would change the geometry slightly and the steering would also change!

That aside, ODE worked great, except that it provides few robust collision primitives. This meant that although I could construct objects from arbitrary meshes, the collisions with the meshes were very temperamental. Cuboids were the sole useful collision primitive that I could successfully get to work, the result of which is my use of only cuboids. I did not foresee this constraint—initially putting together ODE was deceptively easy.

Unfortunately this constraint molded almost every aspect of the game. It forced me to think of alternative solutions, like using Blender for generating tracks or a Tron like look. While these solutions weren’t necessarily bad they were very time consuming.

The racer is a good example of the problems I had from using ODE. Many people complained that it stuck on walls or bounced oddly. Above you can see what the racer really looks like for collisions.

Bug Testing

I own a dual PowerMac G4 450MHz computer, and had assumed this would be a good baseline; “If it works well for me then it should work well for everyone else,” was what I thought. Of course my clever use of multithreading and buffered physics worked beautifully, for me.

It wasn’t until I tested it on the last day of the competition that I realized my folly. Single processor machines had thread timing issues—BitRacer would run like treacle because the physics thread was starved of CPU processing. I then scrambled for the next three days into the voting period to make it playable even on a single PowerMac G5 2GHz. Oh foolish me, to ever underestimate the need for testing.

Distractions

Ah yes. The weeks off doing this or that, having to spend most of my time at work. Oh the wasted time, I should have spent every waking moment working on BitRacer!

Conclusion

There are many things done and many more things remaining. After the intensity of uDevGames, like most entrants, it is time for a break. I am very happy with how BitRacer turned out; leaving it as a learning resource makes it worthwhile as is.

However, excluding the ever-present possibility of BitRacer 2, I am planning to make at least a multiplayer update to BitRacer, with hopefully LAN play. I realize, yet again, that these are big goals, but it would be fun.

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

Bio

Will Thimbleby has been writing Mac games since Tracktor Beam. Since then he was a runner up in uDevGames 2001 with SillyBalls. In real life he is a PhD student working on fancy calculators, and programs MacSword, a bible study program, in his spare time.

Druid

Drunk with this new-found power, I made the rather sudden (even, perhaps, presumptuous) move to enter uDevGames 2003. Excitedly I began to think up ideas, draw graphics, and make music simultaneously, and with no real order or plan. This was probably my first mistake. In the grand scheme of things, I hoped to create a platform game I had an idea for a while ago.

Because I had no real experience or reference to anything at all, I was just making things up and improving as I went along. If you have the patience, then this kind of self-taught approach to learning how to make games is probably the best path for a beginner. The way I see it, if you base everything you do on your own first impulses and ideas, you are virtually guaranteed to have a somewhat original game. And then you can go back and improve upon bits and pieces that need tidying up. That was my basic philosophy for making Druid. Too bad I never got around to the tidying up part. :)

Music Creation

Oddly enough, Druid’s music was not only the first thing I started doing, and the thing I ended up most happy with, but also the only thing I used a PC for; the music was done completely with FruityLoops on Windows 98. (Lucky me, I get the music producer with a professional recording studio in his backyard for a dad. Boy did I take advantage of that!)

I had a reasonable amount of experience with music-making already, and I put it to use. I really tried to give each music track a distinct “feel,” so that you could recognize which tile set it belonged to automatically. You can make a catchy tune, but if it doesn’t have instruments and a melody to fit the environment of the game, it’s wasted in my opinion.

So, I tried to pick instruments and sound effects which suited each environment. For the Forest music track, I used a sample of a female singer, slowed it down, and voilà , instant Druidical hum. I used a lot of tribal-sounding drums and other instruments, and tried to keep it reasonably simple. I think the end result for that piece was quite good; it had a nice feel to it while remaining not too overpowering or attention-grabbing (it is, after all, background music). I followed a similar pattern for the other two sound tracks, using quasi-environmental instruments, and using excessive Fruity filters to get that echo-y, cave-like sound for the Cave track (which I believe only appears on one level).

The music creation wasn’t really coordinated with the rest of the project. I basically just worked on it when coding and drawing graphics was getting boring. Even so, I think it suits the style of the individual levels quite well and did a lot to help the overall feel of the game.

Graphic Creation

All the level graphics and sprites were done with AppleWorks 6, which I find invaluable for such hand-drawn pixel graphics. For the characters I did on the main menu (which aren’t really that good, I just needed something to put in the menu background) I used Flash 5, then did finishing touches (fire on the arrow of the red Druid, etc.) with Photoshop 6.

Like my code, my graphics drawing was really a learn-as-I-go experience. It took me ages to start off—I tried to draw a decent-looking rock about 20 times before it looked okay. I drew a lot of inspiration for my graphics by playing some good old Atari ST platform games, with cute-looking, excessively colorful graphics. After some experimentation, I was onto the right train of thought, which was basically drawing the outlines of objects, filling them in with a solid color, then subtly shading around the edges. I think it gave the game a cute, quasi-cartoony appearance, which was what I was after.

Animation I find to be the trickiest part of drawing graphics. After a lot of experimentation, I ended up drawing the animation of the Druid running in Flash 5, by overlaying each image as semitransparent layer, then using that as a guide for drawing each individual frame in AppleWorks. I’m not sure if this is the best method, though. I would really like to learn a bit more about animation.

Of course, drawing decent graphics by hand took me a long time, and I was quickly running out of time and patience. So, unfortunately, I began to get lazy, and ended up merely changing the color of the sky and tinting in order to create differing tile sets, and I only ended up making one Druid sprite.

Coding

I of course began Druid with very little knowledge of programming, and because of this the basis for my game was highly unstructured. Druid was built on this rather unstable foundation, and suffered greatly in terms of speed and stability. It also made it very difficult to expand and customize, so in a way it also slowed down the project and damaged polish.

Now that I have proper knowledge of how programming operates and how a game should be written, I will not make the same mistakes again when I re-write Druid from scratch, nor if I make another game.

Ideally, for next year’s competition I’d like to team up with someone who knows a good deal about programming with something like Cocoa, and then just make game assets (graphics and music). There is only so much that you can physically do in the time limit. I really doubt I could develop a good code in something other than TNT Basic and still make quality graphics and sound within those time restrictions.

What Went Right

Music & Graphics

I’m really happy with the music I made for the game. I think that it gave Druid a really good environmental feel. However, it did considerably add to the file size (about 6MB).

Likewise, I think I did quite well in terms of graphics for a first shot. Several people have commented that they like the colorful world and cute Druids.

Weather Effects

Weather Effects gave my game a much-needed depth and feel for environment. Although I desperately wanted to make animated levels and parallax scrolling, this was not possible at a decent speed with TNT Basic. Without the weather effects, the levels would have simply been a completely flat plain.

TNT Basic

TNT Basic allowed me to create a reasonable game with virtually no experience, in two months! This is something I don’t think many other (if any) game-building apps for Mac can do, at least not with that level of ease.

What Went Wrong

Speed

The speed of Druid is really terrible. It usually only goes at about 10-15 FPS on my Power Mac G4 (it does run a bit faster in Mac OS 9 and with weather effects off). This is largely due to my poorly-structured, inefficient code, but it also has to do with TNT Basic’s restrictions in terms of the number of sprites on-screen.

Polish

Druid didn’t turn out particularly polished at all. I’m embarrassed at my horrid, pointless renditions of Druidical characters on the main menu, people have complained that the menu system is awful (and it is), and the randomly-flashing text impossible to see. This is largely due to the fact that Druid was only half-finished when the due date arrived for uDevGames 2003. When I re-write it, I vow to keep polish and overall interface smoothness firmly in mind.

TNT Basic

TNT Basic, while being remarkably powerful considering its ease of use, does have its restrictions. I’m particularly disappointed at being unable to do parallax scrolling or animated levels, as I mentioned earlier.

Conclusion

Overall, I’m very pleased with my first attempt at serious game-making, especially the game assets (graphics and music).

Participating in uDevGames couldn’t have been a more interesting and rewarding experience. It gave me an incentive to learn programming and graphics very quickly, which I did. And I even ended up coming in 4th for originality, and winning prizes!

Working with TNT Basic was also a good move. It introduced me to programming very quickly and easily, and let me program a basic game quickly enough for me to still have time to make graphics and music.

I’m very much looking forward to uDevGames 2004. I intend to use proper art tools and techniques to hopefully produce a more visually stunning title next year. And with my experience in programming, I won’t make the same coding mistakes again, for a faster, more stable game, with more polish. It will also leave more time for improving the game and assets, instead of spending most of my time learning what to do by trial-and-error.

I’m going to continue working on Druid, of course. I’ll finally finish the game I originally intended it to be…

  • Developer: Miles de la Hunty
  • Genre: Platform
  • Site:
  • Team Size: 1
  • Project Length: 4.5 months
  • Development Hardware: Power Mac G4, Windows 98 PC
  • Critical Applications: TNT Basic, AppleWorks 6, FruityLoops 4 (PC)

iDevGames Forum

iDevApps Forum