See you at WWDC 2008

Every year around this time a mass migration occurs around the world. Large numbers of Mac developers make the long arduous journey to San Francisco to gather, learn, network, and socialize.

This year I make my own way to join this strange ritual for the first time.

It’s time for Apple’s World Wide Developers Conference (WWDC). A solid week of full emersion in all things Mac and iPhone.

I’m looking forward to finally meeting many people I’ve previously only known through following their Twitter feeds, reading their blogs, using their software, or chatting with them in IRC. It’s a strange business we’re in where most of our contacts are strictly via electronic means.

With MacBook Pro, iPhone, and code in hand; I’m off.

Resolution Independent Buttons

Sean Patrick O’Brien shares his approach and sample code for creating attractive resolution independent controls in Cocoa.

I, like most developers, love shiny new user interfaces. Rounded corners, gradients, drop shadows, custom drawing — all of these things make me smile.

Sean takes us through his steps for prototyping his controls in Photoshop to get the look just right. Then he walks us through his code step by step. Complete sample Xcode project included.

Core Animation Podcast

In my previous post, Mac and iPhone Programming Books, I briefly mentioned the eBook Core Animation for OS X.

Today, the publisher, The Pragmatic Programmers announced a new podcast interview with the book’s author, Bill Dudney.

The podcast is obviously pushing his new book. But, if you have any interest in Core Animation or iPhone development it does have some interesting information and it’s worth listening too.

UPDATE: The Mac Developer Network is also featuring Bill Dudney in their latest Late Night Cocoa Podcast episode, Introduction to Core Animation.

Mac and iPhone Programming Books

The introduction of Apple’s iPhone Software Development Kit has lead several friends to ask me for book recommendations to help them get started developing for the iPhone and Mac.

While the selection is not huge at the moment, the few books that do exist are actually quite good.

There are two primary technologies used to develop iphone and Mac software. Objective-C is the programming language and Cocoa is the framework that provides the building blocks for building applications.

Cocoa Programming for Mac OS X (3rd Edition), by Aaron Hilegass, is probably the most recommended Mac programming book published. The current edition is outdated, but serves as a very good teaching aid for the beginning Cocoa programmer. But, if you can wait until this summer, the 3rd edition of this book will cover the additions and improvements to the Cocoa framework that Apple has added in Tiger and Leopard.

Cocoa uses the Objective-C language and
Programming in Objective-C, by Stephen Kochan, teaches the fundamentals you’ll need to get your work done.

Alternatively, you may want to look into the eBook Learn Objective-C on the Macintosh, By Mark Dalrymple and Scott Knaster. I haven’t read this one, but have heard good things.

One of the cool things about Objective-C is that it’s basically an extension of the C programming language. While programming in straight C is not usually required, it does come up from time to time and it can be very helpful to know what you are doing. If you don’t know C, you many want to check out the eBook Learn C on the Macintosh, By Dave Mark.

The books listed above will get you started programming for the Mac and iPhone, but if you are interested in advanced topics or event Apple Script, the following books might be helpful.

I’ve read most of these books, but the few that I haven’t were recommended to me and have very good reputations.

Development Automation

The second beta of LicenseKeeper 1.3 was just released to testers this morning.

Running a beta test cycle at the end of the year is a bit rough. People aren’t at their computers. Instead, they are spending time with friends and family. Luckily, a few people have been running the beta and reporting issues. But, I can always use more testers.

If you would like to help out with testing and get an early look at what’s in the next version of LicenseKeeper, sign up on the LicenseKeeper Beta Mailing List

Automating the Development Process

For those of you that are developers or are interested in the inner workings of the development process, I’m trying something new with this release.

Since the start of LicenseKeeper development I’ve been meaning to automate the process of testing and packaging releases. But, I was focused on development and just brute forced my way through these things. As expected, I stumbled a few times which resulted in some embarrassing moments.

Automated Builds and Packaging

With the extended beta cycle due to the holidays, I took the time to get these items implemented into my process. This beta release is the first LicenseKeeper release to have been built and packaged through an automated process.

While the script that automated this work is relatively simple, it ensures that everything that needs to take place does so. Manually building and packaging software can be time consuming and error prone due to all the steps involved. Now, I just kick off one shell script and everything gets done in the correct order.

Automated Testing

Additionally, LicenseKeeper now has a full suite of unit tests for the serial number scanning. This part of LicenseKeeper began as a pretty simple chunk of code. As people reported email formats that the scanner could not read or parse, the code was updated. Over time this code has become quite complex and hard to test manually.

So, I added a suite of unit tests that run through a large set of test emails in various formats to ensure that they are all scanned correctly. Now when a change is made, I can run the tests and instantly see if any of the known email formats break.

If someone reports an email format that doesn’t work, I simply create a new test and adjust the code. This serves as a great way to ensure I don’t break anything going forward and provides a simple method for documenting what email formats the scanner supports.

ZIPs vs DMGs

Also new with this release is a move away from the traditional Disk Image or DMG distribution package. While I haven’t had the DMG related support issues that many other developers have suffered through, they are a pain to deal with on the creation side.

Yes, there are several products and methods for dealing with the creation of DMGs and I did try to incorporate several into my automated build process. But while trying to crowbar this into my build script, I took a step back and asked myself what benefit the DMG was providing over a simple ZIP file. I couldn’t come up with any reasons to keep using the DMG.

Mac OS X automatically uncompresses ZIPs when downloaded and cleans them up for you. There is no need to copy the application out of them in order to get work done or eject them to clean up your desktop. Plus, I don’t have to spend time and resources on trying to get my DMG background images to reliably look good under Tiger and Leopard.

Decision made. Starting with version 1.3, LicenseKeeper will be distributed using the ZIP format.

New Podcast: The Business of Mac Software

A few days ago I mentioned The Mac Developer Network and their great lineup of podcasts.

Well, Steve Scott (Scotty) has added yet another podcast to the mix: MacSB: The Business of Mac Software.

The MacSB podcast focuses on the business issues of developing Mac software.

The show takes an interview format where the host interviews Mac Developers with solid experience of running a Mac Software Business.

Episode 1, Getting started as a Mac Indie Developer features two established Mac developers, Gus Mueller of Flying Meat (Voodoo Pad, Acorn) and Marcus Zarra of Zarra Studios (seSales, iWeb Buddy).

The Mac Developer Network

From the creator of the Late Night Cocoa podcast comes The Mac Developer Netowrk (MacDevNet.com) and the new Mac Developer Roundtable podcast.

The Mac Developer Network (MDN) is hoping to become your first port of call for all things to do with Mac Development.

Scotty has done a wonderful job with Late Night Cocoa over the past year and that makes me think the Mac Dev Net is going to be a great resource as its content and podcast episodes build up.

With the recent increase in Mac users and developers, it’s surprising there aren’t more programming resources outside of The Apple Developer Connection. It’s a great community booster to have Cocoa developer resources like Mac Dev Net, CocoaDev.com, and Cocoa Dev Central.

Bullfrog Game Design: Dynamic Bugs

Developing software is an interesting process. There are times where I work very hard with little to show for it for several days. Then there are those days where I can knock out a ton of tasks on my “To Do” list with little effort. Usually, one state directly follows the other.

I recently spent several days working on the mechanism that Bullfrog 2 will use to load level and bug definitions. There was much reworking and testing involved. Now that the work is complete, designing new levels and bugs should take little time and effort.

Hardcoded Bugs

In the original Bullfrog, the player was tasked with munching bugs as fast as possible. Bugs were randomly spawned on the screen based on a simple algorithm. This algorithm would generate a certain number of bugs depending on what round the player had reached. For example the gnat was generated using the following calculation.

int numberOfGnats = roundIndex * GNAT_SPAWN_RATE;
listing 1

Each bug type had it’s own spawn formula and custom class. Each bug class would then be allocated and tracked in a NSMutableArray during the round.

NSPoint origin = GetRandomGamePoint(gameRect);
unsigned int direction = GetRandomAngle();
switch([bugDef bugType])
{
   case GnatType:
      bug = [[Gnat alloc] initAtPosition:origin
                           withDirection:direction];
      break;					
//   ...
}
listing 2

This approach worked fairly well for a simple game using random spawn points on a simple game board. There were no level design elements to worry about. A bug was either alive and on the screen, or it had been eaten.

Dynamic Bugs

For Bullfrog 2, we really wanted to move away from randomly generated rounds and bugs to designed levels. We plan to have multiple levels with unique artwork and challenges. But how do we define bugs and have them spawn based on a definition file?

We could read in the definition and run through a big switch statement with a case block for each bug type similar to the code above (listing 2) used in the first Bullfrog. But, this gets nasty pretty quick.

We’re also adding new game elements to Bullfrog 2. Players will have obstacles such as rocks and water to deal with while hunting down bugs. These elements also need to be defined and tracked inside the game.

With a bit of imagination, rocks and bugs are basically the same thing except for a few different attributes. Bugs can move, rocks can’t. A mosquito can damage the player, but a rock can block the player’s movement.

This lead us to a base class we’re calling Actor. Each actor can be completely defined with a set of attributes which denote size, animation, and other things.

We still have the problem of needing unique AI (artificial intelligence) for the different bugs. Using just the Actor class won’t provide us with customized code to define personality attributes such as chase and escape behaviors.

So we defined a set of Actor subclasses that provide the custom behaviors of the various bugs and other objects populating the Bullfrog world. But, with each new game object, our switch case grows in complexity.

Objective-C to the Rescue

This is where our decision to use Objective-C pays off. By using the dynamic nature of the Objective-C we can allocate and initialize our actors at runtime without using a huge switch statement.

Given the following Actor definitions (listing 3) we can dynamically generate the level’s actors with a simple loop (listing 4).


   
      class
      BFRock
      blocksMovement
      1
   
   
      class
      BFGnat
      blocksMovement
      0
      moveSpeed
      0.005
      turnFrequency
      5
      turnSpeed
      20
   

listing 3
- (void)loadActorsDefinition:(NSArray *)actorsDefinition 
                   intoLayer:(NSMutableArray *)layer
{
   id actor;
   NSDictionary *actorDef;
   for(actorDef in actorsDefinition) {
      NSString *actorClass = [actorDef valueForKey:@"class"];
      actor = [[NSClassFromString(actorClass) alloc] init];
      if (![actor isKindOfClass:[OLActor class]]) continue;
      [actor loadDefinition:actorDef];
      [layer addObject:actor];
   }
}
listing 4

The key piece here is the function: NSClassFromString(NSString *str). This Foundation function returns a Class object that can then be used just like your hardcoded class definition for allocating a new instance.

In the above function (listing 4) we get the “class” attribute from the XML and feed that into the NSClassFromString function to get our Class. Then pass in the XML for this particular Actor into the instance method -loadDefinition: on the Actor class. Some more Objective-C runtime magic reads in the defined attributes and stores them in the Actor instance properties using key-value coding (listing 5).

NSString *key;
for (key in [definition allKeys]) {
   [self setValue:[definition valueForKey:key] forKey:key];
}
listing 5

Now all actors for each defined level are easily loaded and we don’t have to constantly rewrite or modify our code each time we add a new type of bug or game object.

The difference in complexity and number of lines of code in Bullfrog 2 is greatly reduced because of the magic that Objective-C provides. Dynamic class loading is very powerful and provides us with great flexibility moving forward.