ios

Operation: Eradicate Post Mortem

For four or the five months, I have been working on Operation: Eradicate, an iOS turn based strategy game. With my graphics designer, we at Skejo Studios have revisited the last few months, and wanted to write about the highs and lows, and lessons learned for next time.

First I wanted to start with our initial hoped for timeline:

Initial Timeline

* Sept 2011 - Start
* Oct 2011 - Code fleshed out and Art assets started, first round done
* Nov 2011 - Dev and art near finish, start beta testing
* Dec 2011 - Wrap up loose ends, ship by Christmas

What really happened

* Oct 2011 - Started full-time on the first project with part time UI graphics guy, and contract artist
* Late Oct - Basic gameplay with dev art done, still hoping for Xmas release. Yeah right!
* Late Oct - First hard-drawn art assets issued
* Early Nov - Save/resume games implemented, iOS 5 turn based games (a selling point, to Apple more than anyone).
* Late Nov - Wife got a new job, moved new city little dev done. Art still slowly making progress.
* Early Dec - Final non-colorized artwork done. We were advised the game needed a full event driven tutorial to on-ramp players to game. Ugh! - Moved goal for launch to end of Jan.
* Late Dec - All game mechanics done, first beta test sent out to 5 players.
* Mid Jan - Many UI redesigns occur, plus tons of polishing adjustments.
* Late Jan - Finalized, full color artwork delivered. Pushed launch to Feb. Another round of play testing, polishing, tweaking.
* Early Feb more weeks of polishing.
* Submitted to Apple, Tuesday Feb 14.
* Approved by Apple, Mon Feb 20 (on my birthday)!!! Massive Marketing push ensues.
* Released set for Sunday Feb 26 (to get in front of GDC)

I will also be writing a Marketing Post Mortem to trace and dissect the good, bad and lessons learned from the launch.

The first lessons we learned is to be flexible with due dates, but still have them in place. As I was the only full time person, I was pushing hard because I could, but it is difficult to push part time contractors to speed up. I now will factor in slips in the timeline for artists. But even missed deadlines serve the function of putting a mark on the calendar and pushing for it. Motivation sometimes can be lacking, and that date keep things in focus. Just don't use missed deadlines as a source of depression, just learn to estimate better. Deadlines also help you look back and realize how much you did get done before that date passed.

Deadline Tip we learned

One way to help contractors (of any stripe, not just artists) create deadlines they will really try to hit, is to incentivize the deadline. Maybe add a 5% bonus for each delivery deadline hit, or maybe a lump bonus if 75% of delivery deadlines were hit. This will help them suggest dates they can hit, and gives them reason to hit them more accurately.

What Went Wrong

As already mentioned, this was my first time working so closely with artists directly, and a few false starts, and all deadlines missed made me realize I was working with people different that me (an analytical engineering type). We are all different minds, and that is all good. For me, I felt the artist delivered more than I asked for, but took longer than I wanted. But how do you direct them to do less to hit the deadline, when they are working on hand drawn artwork. Especially when the artist insists that he won't charge. Again, this is where the incentivized deadlines can come in handy

The other deadline item is setting realistic timelines for part time contributors. Rarely did their contributions come in smooth, predictable chucks. More likely they came in spurts, sometimes unpredictable. We will keep that in mind on our next projects, and as we develop updates for this game.

The last huge mistake is that we didn't add a zoom to the playing map for iPhones and iPod Touches. During one UI redesign, we took it out, and none of our play testers complained so we thought we were good. Except all of our play testers were experienced gamers, and had used the controls so much they didn't notice (or didn't report) issues with the map on smaller devices.

But we were nailed in the reviews w/ numerous 1 star reviews, and many emails asking for a zoom to be added. Thankfully we already had the code generally working, so it only took a couple hours to get an update to our testers, and wrapped up a submission to Apple in two days (numerous other typos, small fixes and enlargement of other buttons included).

Two things we learned from this issue is to specifically ask the impressions of a change you make if you are using the same testes. Them not reporting that the disliked a change, doesn't mean they liked it, just that they didn't report it. Second, use more new testers each time you have a test release. Otherwise they might be too familiar with the and attuned to the rough spot, thus not reporting them.

What we did right

We allowed enough time for UI rework. We didn't kid ourselves into thinking that we were going to get it all right the first time. I worked on a first pass developer UI just to get the game to a playable state. This I pushed to the UI designer while I worked on other behind the scene stuff like turn based games, Game Center integrations and other items. Then I implemented his design and we through it to some testers. Their feedback, and more time to imagine gave the designer more inspiration, which eventually lead to a good interface.

You can see the map and UI progressions here: http://www.tech-wanderings.com/eradicate-week-16-game-mapui-progression

Some Quick Lessons Learned

* Send stuff to publishers. They may reject you, say mean things about your progress, but they might also give you hints on how to improve. They did for us.
* Fix bugs/broken stuff when you see it, don't add toa todo list. Fix it NOW!
* Biting off too much is very easy to do!

Don't Listen to these Fears

Fear 1: What will other people think of it? Maybe I will wait until I get more done.

No, the earlier you get feedback the better. Test users and honest feedback gets you off wrong paths and deadens, and spot glaring issues sooner. Polish added to a feature you remove later is a waste of time. Don't polish anything until you know you have nothing more to cut out.

Fear 2: We are done, but I don't want to send the game to reviewers because they might be critical.

If you think your game doesn't blow away the competition, or that the reviewers will hate it, then why did you make the game? If you aren't proud of it, send it back for more polish or rework. If you are proud of it, send it out, get as much talk about your game. Anything is better than silence. This last point is more for a marketing post-mortem, but it felt like it fit here.

Quick Facts

  • Web site: http://www.skejo.com/eradicate
  • Release date: February 26th, 2012 (iPad and iPhone/iPod touch)
  • Development time: 4 months
  • Team size: 1 full time, 1 part time, 1 contractor part time
  • Development cost: Cost of living for 4 months + about $2500 (art, marketing, resources)
  • Open source code: Cocos2d, Box2d
  • Primary tools: Xcode, git, SpriteHelper
  • Raw asset size: 391 MB
  • Total app size: 13.9 MB
  • Coffee Consumed: 500+ shots of espresso

Finally, we do have the first week's worth of sales data, and we must have done a few things right. We landed in the #4 iPad Strategy spot and the #5 iPad Board game spot at launch. We didn't write down targets for launch, but this would have exceed anything we would have written.

  

What is coming next for Skejo Studios?

Vertical Scrolling story telling platformer, to be official announced shortly.
With a side scrolling indirect platformer using same artwork/world/back story.
Very high concept resource management, mini-game, character advancement game.

Operation: Eradicate on iTunes.

Comment below, or with Twitter,

SLIDES:

iOS Game Center Achievement Display

In one of my projects, while I waited for some art work, I wanted to get ahead with my Game Center integration. This tutorial is about how to get Achievements to be displayed in the Game when the achievement is sent to Game Center. I will further explore how to get the achievement images also included. A few simple frameworks will be used.

Also, I am taking it for granted that Game Center is up and running on your app. I was able to get it up and running in a few hours using the methods found in Learning Cocos2D or in numerous tutorials around, here or here.

Once you have a user authenticating, and you have setup a few iTunes Connect achievements, you might want to display an 'Achievement Attained' message when a new achievement has been accomplished. Again, this is different than just showing the Achievements window, that shows all the achievements a player has completed. We want a little notification message displayed.

In iOS 5, Apple finally gave us a prepackaged API call that will show an achievement banner when an achievement is complete (per your code giving a 100.0% to an achievement). Here is the simplest way:

- (void)sendAchievement:(GKAchievement *)achievement {

    achievement.percentComplete = 100.0;   //Indicates the achievement is done
    achievement.showsCompletionBanner = YES;    //Indicate that a banner should be shown
    [achievement reportAchievementWithCompletionHandler:
     ^(NSError *error) {
         dispatch_async(dispatch_get_main_queue(), ^(void)
                        {
                            if (error == NULL) {
                                NSLog(@"Successfully sent archievement!");               
                            } else {
                                NSLog(@"Achievement failed to send... will try again \
                                      later.  Reason: %@", error.localizedDescription);                
                            }
                        });
     }];
}

This code creates the achievement object according to your identifier (whatever you setup in iTunes), you set the completion to 100%, set the 'showsCompletionBanner' property to YES, and shoot it off to Apple. The new iOS property is 'showsCompletionBanner' which defaults to NO, but if updated to YES, will display a cute little banner with the title and description of the achievement, as shown below (yes I am using the http://www.neuroshimahex.com/ game as inspiration, so placed as my dev background. Check it out, very fun strategy game).

But this approach has a few limitations. First off, it uses the generic Game Center icon, instead of the image that I uploaded for my game achievement. Worst off, if the player earns two achievements at the same time, only one of them will be displayed, which I think is a bummer. And lastly, this is an iOS 5 only API calls, so will crash any device not running iOS5, oops!

So to repair all of these issues, we will not be using the 'showsCompletionBanner' property, but will be implementing our own notification, or more correctly using and modifying some code of people who have gone before us.

To get started, I used the great code that Type One Error demonstrated in http://www.typeoneerror.com/articles/post/game-center-achievement-notifi.... Read that article for some background if you want, and then grab the code at https://github.com/typeoneerror/GKAchievementNotification and install into your project. We will be using the GKAchievementNotification and GKAchievementHandler classes, with some updates and modifications. First off, if you are using ARC for your game, do a quick scan of the code and remove the few release, retain and autoreleases you find in that code. If you don't want to scan, just try to build after you place the files in your project and fix wherever the compiler squawks at.

The Type One Error classes will display a notification that is similar to the one that the iOS 5 call gives, but your code needs to know what the achievement title and description is. To do this you need to populated a'GKAchievementDescription' object.

One great thing about GKAchievementDescription objects is that they are already localized according to the language setting of the user (if you support that language) and thus don't have to worry about any localization issue if you use this method.

The bummer is that you can't load just one Achievement description, you have to load them all. I believe the best time to do this is when a user has authenticated Game Center on your app, you should do an async call to get them. Galdly Apple does give an API call for this, which I place in the CompletionHandler of the user authentication call.

If you are using the code by Ray Wenderlich, then you have a method like this, which I add one line to, and a new method. Also add an NSMutableDictionary * self.achievementsDescDictionary to whatever class is processing your Game Center code, which will store the achievement data for the rest of the active session.

- (void)authenticateLocalUser { 
    
    if (!gameCenterAvailable) return;

    NSLog(@"Authenticating local user...");
    if ([GKLocalPlayer localPlayer].authenticated == NO) {     
        [[GKLocalPlayer localPlayer] 
         authenticateWithCompletionHandler:^(NSError *error) {
             if([GKLocalPlayer localPlayer].isAuthenticated){
                 [self retrieveAchievmentMetadata];         //Here is the new code
             }
         }];        
    }
}


//Here is the new method.
- (void) retrieveAchievmentMetadata
{
    self.achievementsDescDictionary = [[NSMutableDictionary alloc] initWithCapacity:2];
    
    [GKAchievementDescription loadAchievementDescriptionsWithCompletionHandler:
     ^(NSArray *descriptions, NSError *error) {
         if (error != nil) {
             NSLog(@"Error %@", error);
             
         } else {        
             if (descriptions != nil){
                 for (GKAchievementDescription* a in descriptions) {
                     [achievementsDescDictionary setObject: a forKey: a.identifier];
                 }
             }
         }
     }];
}

The 'retrieveAchievmentMetadata' method initializes the dictionary then calls to get all the Achievement descriptions for your game, and cycles through and adds them to the dictionary. This is an async call, so it shouldn't slow down the start of your game or project.

Now that we have all the titles and descriptions for all your achievements, we can modify our original code to create an iOS 4/5 friendly notification, that will also show all achievements in succession using the Type One Error code, again inside of Ray Wenderlich's code (resource links at the top and bottom of this post).

- (void)reportAchievement:(NSString *)identifier 
          percentComplete:(double)percentComplete {    
        
    GKAchievement* achievement = [[GKAchievement alloc] 
                                   initWithIdentifier:identifier];
    achievement.percentComplete = percentComplete; 
    
    if (percentComplete == 100.0) {
        //Show banners manually
        GKAchievementDescription *desc = [achievementsDescDictionary objectForKey:identifier]; //Update pull achievement description for dictionary
        
         [[GKAchievementHandler defaultHandler] notifyAchievement:desc];  //Display to user


    }
    [achievementsToReport addObject:achievement];    //Queue up the achievement to be sent
    [self save]; 
    
    if (!gameCenterAvailable || !userAuthenticated) return;
    [self sendAchievement:achievement];   //Try to send achievement 
}


- (void)sendAchievement:(GKAchievement *)achievement {
    [achievement reportAchievementWithCompletionHandler:
     ^(NSError *error) {
         dispatch_async(dispatch_get_main_queue(), ^(void)
                        {
                            if (error == NULL) {
                                NSLog(@"Successfully sent archievement!");
                                [achievementsToReport removeObject:achievement];   //Remove Achievement from queue.             
                            } else {
                                NSLog(@"Achievement failed to send... will try again \
                                      later.  Reason: %@", error.localizedDescription);                
                            }
                        });
     }];
}

The additional checks to see if the achievement is 100% complete, and if so, grabs the correct achievement description object and displays it to the user. Then it continues on with telling Apple about the new achievement, and if you have a landscape game, it will look something like this.

But, I think it would be even better to also have the achievement image displayed, instead of the default image. So to do that, update the code with the notification part to this:


    if (percentComplete == 100.0) {
        //Show banners manually
        GKAchievementDescription *desc = [achievementsDescDictionary objectForKey:identifier];

        [desc loadImageWithCompletionHandler:^(UIImage *image, NSError *error) {
            if (error == nil)
            {
                [[GKAchievementHandler defaultHandler] setImage:desc.image];   //If image found, updates the image to the achievement image.
            } 
            [[GKAchievementHandler defaultHandler] notifyAchievement:desc];
        }];

    }

Since that code is inside a completion handler block, it will only execute once the handler returns. If it returns an image, then the notification is updated with that image, and then it displays to the user.

Yeah, yeah, I have temporary art in there. I told you the art was falling behind. Anyway, using this method out of the box you will notice that if you have a landscape game, that the notifications are off to the side and sideways (the Type One Error guys made it for portrait only). To fix this for landscape you need to do two things, adjust the frame and the rotation.

Find the 'notifyAchievement' method in the GKAchievementHandler class and update to:

- (void)notifyAchievement:(GKAchievementDescription *)achievement
{

    GKAchievementNotification *notification = [[GKAchievementNotification alloc] initWithAchievementDescription:achievement];
    notification.frame = kGKAchievementFrameStart;
    notification.handlerDelegate = self;
    
    //Adjusting rotation.
    
    if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft) {
        notification.transform = CGAffineTransformRotate(notification.transform, degreesToRadian(-90));
    } else {
        notification.transform = CGAffineTransformRotate(notification.transform, degreesToRadian(90));
    }
    
    notification.frame = kGKAchievementFrameStartLandscape;  //Update the frame, you need to create this definition.
    
    [_queue addObject:notification];
    if ([_queue count] == 1)
    {
        [self displayNotification:notification];
    }
}

Also adjust the 'animateIn' and 'animateOut' frames as needed. I found these frames to be useful:

#define kGKAchievementFrameStartLandscape    CGRectMake(-53.0f, 350.0f, 104.0f, 284.0f);
#define kGKAchievementFrameEndLandscape      CGRectMake(20.0f, 350.0f, 104.0f, 284.0f);

So, by using the Game Center code from Ray Wenderlich's
tutorial as a starting point, along with the Type One Error notification code, we then added adjustments so our final solution does the following:

1) Display one or more achievement notifications (the Type One Error code queues the display of many notifications)
2) Displays the notifications with images and full title and descriptions.
3) In a manner that is iOS version independent.

You determine a player had completed an achievement, sprinkle in:

[GCHelper sharedInstance] reportAchievement:identifier 
          percentComplete:percentComplete];  

Or whatever way you access your Game Center achievements

Lastly, if you believe pulling all the achievement data early in the authentication call is a performance or data issue, you can wait and place the 'retrieveAchievmentMetadata' call until the player earns an achievement, and place in its completion handler, add the code to display the achievement notification. But there is a little extra legwork needed to save the achievement until you have retrieved all the description data. I leave it to the reader to finish off that particular use case.

Resources:
http://developer.apple.com/library/ios/#documentation/NetworkingInternet...
http://www.typeoneerror.com/articles/post/game-center-achievement-notifi...
https://github.com/typeoneerror/GKAchievementNotification
http://www.raywenderlich.com/3276/how-to-make-a-simple-multiplayer-game-...

Comment below, or with Twitter,

Cocos2d Menus and arguments

I was toying with the idea of writing a post about why I went independent, but I figure that wasn't appropriate for the wider audience of iDevBlogADay.com. Check my blog for those posts. So I decided to post a more technical piece regarding cocos2d menus and how to pass arguments through the Cocos2d menu system. But I was facing two issues. One I hated rewriting similar code over and over again. Second to make menu items more reusable, I needed to be able to pass arguments to the selector of the menu, which wasn't readily apparent how to do this. Also, checking the cocos2d forums and other places I saw that many others have had this issue.

So my goal is to create a reusable button factory which allows for the passing of arguments to the selector (read check this tutorial to get the basics for Button and Text Menu Items in Cocos2d).

For starters, here is a very typical pattern for adding a text menu item:

-(void) addMenu {
    //Create the label for the menu
    CCLabelTTF *label = [CCLabelTTF labelWithString:@"Button Text fontName:@"Arial" fontSize:12];

    //Add label to a menu item.
    CCMenuItemLabel *menuItem = [CCMenuItemLabel itemWithLabel:label target:self 
                                                      selector:(menuItemPressed:)]; 
    //Add menu item to a menu.   
    CCMenu *menu = [CCMenu menuWithItems:menuItem, nil];
    menu.position = ccp(0,0);

    //Add menu to a layer.
    [self addChild:menu];
}

//Method to receive button pressed action
-(void) menuItemPressed: (id)sender {
    [self doSomething];
}

As you might have noticed, the argument for the menu select is automatically supplied as a CCMenuItem of some sort or another, but generically it is just an id object. The question is how do you forward some information to the menuItemPressed method, from the menu item you created, and to no have to go through the effort of creating this sequence of code over and over again.

Example, this is ugly.

//Method to receive button1 pressed action
-(void) menuItemPressed1: (id)sender {
    [self doSomething: 1];
}
//Method to receive button2 pressed action
-(void) menuItemPressed2: (id)sender {
    [self doSomething: 2];
}
//Method to receive button3 pressed action
-(void) menuItemPressed3: (id)sender {
    [self doSomething: 3];
}

I wanted something like this.

-(void) menuItemPressed: (id)sender {
    [self doSomething: sender.passedVariable];
}

Gladly, all the CCMenuItem classes and subclasses all have a userData property that you can use to assign data to like this:

menuItem.userData = someObj;

To use the userData, and to make sure there weren't warnings or error in XCode, I explicitly cast the object to what is should, and assign it to a temp variable.

Update the code a bit and it becomes:

-(void) addMenu {
    //Create the label for the menu
    CCLabelTTF *label = [CCLabelTTF labelWithString:@"Button Text fontName:@"Arial" fontSize:12];

    //Add label to a menu item.
    CCMenuItemLabel *menuItem = [CCMenuItemLabel itemWithLabel:label target:self 
                                                      selector:(menuItemPressed:)]; 
    //Add menu item to a menu.   
    CCMenu *menu = [CCMenu menuWithItems:menuItem, nil];
    menuItem.userData = someObj;  //Of type SomeObj.
    menu.position = ccp(0,0);

    //Add menu to a layer.
    [self addChild:menu];
}

//Method to receive button pressed action
-(void) menuItemPressed: (id)sender {
    (SomeObj*) tempObj = (SomeObj*) sender.userData; 
    [self doSomething: sender.userData];
}

So now, we have a passed variable being used in a receiver of a pressed menu item. Great. Now write this code over and over again. OR, create a button factory that does the heavy lifting for you. Since I wanted to pass the position, and have a general layer to use, this method returns a CCLayer, but you could just return a CCMenu instead.

Here is my final button factory code, and an example usage (subject to improvements in the future, I will try to keep this article up to date).

-(CCLayer*) actionTrayButtonFactory: (NSString*) text withPosition: (CGPoint) pos withUserData: (id) userData selector: (SEL) selector {
    
    CCLayer *layer = [CCLayer node];
    
    CCLabelTTF *label = [CCLabelTTF labelWithString:text fontName:@"Arial" fontSize:13];
    label.color = ccc3(255, 255, 255); //Set your own color.
    
    CCMenuItemLabel *menuItem = [CCMenuItemLabel itemWithLabel:label target:self 
                                                      selector:selector];
    menuItem.userData = [userData retain];
    
    CCMenu *menu = [CCMenu menuWithItems:menuItem, nil];
    menu.position = pos;

    [layer addChild:menu];
    
    return layer;
}

Usage:

        CCLayer *layer = [self actionTrayButtonFactory: @"Button Name" withPosition:ccp(100, 200) withUserData:[NSNumber numberWithInt:1] selector:@selector(menuItemPressed:)];
        [self addChild: layer];

I would use this inside a loop where I am incrementing the button name, position height and the userData passed in.

Next, I will be making a similar button factory that takes in images and will create CCMenuItemImages instead. The same format will work. Also, a further extension would be to add in another argument for button type incase you wanted to adjust the size/shape/color of the manufactured menu item.

Also, if you are making a localized app, the button factory method can update the 'labelWithString:text' portion to 'labelWithString:NSLocalizedString(text, nil)', which is what I am doing in my game.

I am not sure if I needed to use objects in the userData property, instead of just integers or floats, but that is what was need when I got it to start working. I also at times needed to place a 'retain' on the object to maintain the data. Not exactly sure why. Any help from my readers on why that is the case will help clean up this code long term.

This code will show up in the Skejo Studios Outbreak project. Check out the game development diaries. This post is a part of the iDevBlogADay series. Check out some other recent posts including Who is an Indie Dev and What's my motivation.

Who is an indie developer?

I recently resigned from my startup engineering roles to start my own thing at mentioned here. I wanted to pursue my own projects and goal, work on stuff I was really excited about, learn a few new things and I currently have the financial safety to just go for it.

I started reading www.idevblogaday.com, and followed one of the authors to their blog and came across the Indie Budget, by Doug Davies. Since I haven't produced an indie game yet (but a few New and Noteworthy Travel apps) I won't comment on budgeting, but I think I can give a few opinions regarding his opening on who an indie dev is. I will return to Doug's definition in a moment, but I wanted to visit a few others first.

Eradicate Week 2: Panning, Pinch Zoom, Stock Images and Stubbed Layers

I wish I could say I spent the whole week working on this project, but past contact was extended, and I worked on my other non-game project, the Dog Park Finder. We are updating the logo branding and adding thousands more dog friendly locations with new filters and map icons. But this is a dev diary about our Outbreak project (view all posts here). Also visit Skejo Studios to see all we are doing.

For this update, instead of working on a ton of under the hood methods, I hours I did spend on I used on some UI elements. Or more precisely, stubbing out the UI.

Below is one of out UI sketches we made. Partially we were just brainstorming on what a player would need to, prioritizing frequent interaction and highlighting them above less frequent actions. Though we in no way consider the sketch as perfect, we wanted to get something on paper, and then get it in rough for into the game. This way we are getting closer to a fully playable demo, as well as interactive with device and testing user and action flow.

Book Review: Learning Cocos2D

When I was making the transition into iOS development from Internet engineering, I grabbed two 500 page iPhone app development books, read and worked the examples over a Christmas vacation, coded nights and weekends for three months and produced an app that Apple highlighted as New and Noteworthy, the Dog Park Finder. So, now when I decided to make the leap from iOS development to iOS game development 18 months later, I wanted to grab a great intro book and go from there.

First I had to determine the tools I would use, and landed upon Cocos2D (this isn't a game platform review, so I am not going into the pros/cons of Cocos2D or other platforms, that is a different post). Following that decision, I grabbed Learning Cocos2D by Rod Strougo and Ray Wenderlich. The other obvious choice was Learn iPhone and iPad Cocos2D Game Development. Honestly, I came across Learning Cocos2D first, which is why I bought it.

Learning Cocos2D is a great book to use as an on-ramp to the Cocos2D platform, as well a giving good best practice insight into general game development, and design pattern to follow. If are a long term game developer, well versed in texture map optimization, OpenGL programming or physics modeling, then you probably should just read the Cocos2D API documentation. But if not, Learning Cocos2D is a hands on book for getting up to speed quickly (if you are altogether new to Objective-C and iOS development, the a read through an basic iPhone programming book before working through this book).

The book uses working example of building a Space Viking game (free at the app store). Through the examples you will be shown how to make a splash screen, menu pages (including credits and options pages), how to move and animate sprites, spawn enemies, scroll the landscape, create gravity puzzles and joy ride in a mine cart across an alien landscape. Among other things. All the while, Rod and Ray skillful introduce support tools and mix in programming best practices for optimizing memory and speed up the game.

Like many of books of this nature, all the sample code viewed in the book, is also available for download. It is a great help see and interact with an entire XCode project when a concept is eluding you. Also, the authors have given full permission to use the code in any manner to help accelerate your projects.

The book's 17 chapters are broken into five sections. Instead of highlights and review each chapter's content, I will do so at the section level.

The four chapters in the 'Getting Started' section give a steps the reader from a installing Cocos2D into XCode, to simple 'Hello World' program, to making your first game scene with a hero, a villain, some animations and basic collision detection. These chapters define the basic Cocos2D vocabulary of scenes, layers and sprites, along with batching sprites for performance, definition animation sequences in plists instead of in the code, and spells out some of the workflow and time saving API calls for handling sprite movements and scene updates.

The next short section involves chapters 5 and 6 where some decent amount of computer science concepts of class hierarchy, interfaces and other concepts are written along side instructions about sprite and layer affects, generating text labels, and other font usage. The authors also help guide you to a quick debugging layer for better testing of your games.

'From Level to Game', is the third section of the book. Chapter 7 deals with Cocos2D's menu items, which can be used to create dynamic menus, directing to new scenes for viewing credits, as well as creating options for defining game settings. Chapter 8 is dedicated to all things audio. Including different tools for importing sound and asynchronous loading of sound/music for a better user experience. Lastly Chapter 9 deals with larger levels than one screen can hold. Both scrolling, and parallax scrolling are covered as well as the efficient way to create and reuse time maps.

The most cerebral of sections, is 'Physics Engines' sections. I spent a little less time working the examples of the Physics chapters 10 through 13, but Rod and Ray extensively introduce both the Box2D and Chipmunk Physics engines. Starting a bit easy with gravity, mass and simple collisions to setting up a fully actuated Viking to throw and rag-doll around, these chapters lay a solid foundations for you to explore physics in the Cocos2D world on your own.

Lastly, a ragtag section is used to wrap up the basic particle system in Cocos, while giving pointers for toll in creating your own particle effects. A chapter is also dedicated to Game Center integration, including login/sign up, creating leader boards, setting achievements, and how to save updates when an Internet connection is not available. Besides the conclusion, the last chapter deals with general performance tips, debugging and profiling guides and some quick tips to loading your sprites faster.

Too sum up, Learning Cocos2D is not just a book on how to use Cocos2D, but really a how-to guide to making your first iOS Cocos2D game with good technical architecture, with many best practices and how-to's thrown in. At over 500 pages, it isn't a quick read, but I would recommend it to anyone looking for good book for iOS Cocos2D development

Before signing off, I thought I should also introduce myself, as this is my first post for iDevBlogADay.com. My name is Greg Holsclaw, and I am the founder of Skejo Studios, a new iOS shop. We have already produced two apps for ourselves (one is the Dog Park Finderwith over 200K downloads), and two more for clients. Since completing a BS in computational mathematics, I have been creating websites and backend engineering for 7 years, and creating iOS apps for the last two years.

My hobbies sites and weekend work has blossomed enough that I recently was able to resign my engineering lead role at a successful internet startup to create Skejo Studios, and there is no looking back. Look for more posts at www.tech-wanderings.com concerning the intersection of Drupal (a web CMS) and iOS apps, as well as development diaries for the games we are developing. Until next time. -Greg

Eradicate Week 1: Starting the Project

Today, I am kicking off the development diary for the project that inspired Skejo Studios to get started. We may have a second project in parallel (to fill any down time this project might have), but most of our energy will spent on this project.

I plan on making weekly project updates, at least on any week that I spend work on a particular project. This first update reflects about two weeks of elapsed time, but less than a week's worth of dedicated time. To set expectations, some updates will be technical in nature, where others might focus more on the design, UI or business side of things.

Currently, the in-house name is Outbreak, but that is of course subject to change at any point right up to launch. We are aiming to create an iPad evolution of a table top strategy game concept. A co-operative type game where there are two to four players who are trying to beat back four regional outbreaks. Most likely we will play a zombie theme for these outbreaks, but for now we are just working on the game mechanics. This project is being built on the Cocos2d game platform.

Leverage Existing Tools

From my years in industry, I know that re-inventing the wheel, just so I can say it is my wheel is a huge form of waste.

Going iOS native, Skejo Studios coming

With Drupal being my main technology for the last 5 years, I have been working on numerous iPhone projects for 18 months. During the last 4 months, I have been contemplating a career move. T2Media has been a great company for me, as well as giving me some financial options I didn't have a few years ago.

So I decided to resign my position a lead architect (yeah, crazy given the current economic climate) and start up my own iOS studio. I have enough internal projects lined up to keep me busy for a while, with design and artistic freelancers helping me out as needed.

I imagine that I will be making many more entries now that a steady paycheck isn't in the mix. I will still be making Drupal post now and again, but I will also start writing posts concerning my iOS development, mostly around some game ideas I have been popping around in my head.

Check back for more posts coming soon. Mostly on Cocos2d for iOS, http://www.cocos2d-iphone.org, as that is the framework I will be using going forward.

Syndicate content