To explore the tech world, though mostly focusing on iOS, Django, and Drupal development Sometimes it isn’t the perfect that gets in the way of the good, but the revolutionary gets in the way of the evolutionary.

Should indie game devs do it all?

Running in the game dev circles for the last three months has exposed me to a ton of one or two man shops that undertake the entire development and production of a game on their own. Some are doing well, but others are struggling.

It almost seems like some developers purposely handicap themselves by 'doing it all' just so they can claim the elusive 'indie developer' mantel. I don't want to touch the What is an indie game developer? topic again, but I do want to target the thinking behind doing it all yourself.

Is going it alone wise, productive, or profitable?

Coming from the startup world of Silicon Valley, it is regularly frowned upon to hear about a startup with only one founder (#1 mistake startups make). The reasons are broad, but generally distill down to three core issues:

1) If nobody has partnered with you, you might be a pain to work with.
2) If nobody has partnered with you, your idea probably isn't very good.
3) One person just can't do it all.

I don't really want to touch the first issue as it is a personal issue. I want to assume that all indie developers and designers aren't doing the indie scene because they have been fired from every job they have ever held, but instead choose this path for themselves.

Moving to the second point, I think it is valid to ask a solo dev if they have really tried to flesh out their game idea, bouncing it off their circle of friends and family. If none of them wanted to join, or at least refer a co-developer/co-artist to help the game idea along, maybe the idea doesn't have legs. Listen to this signal. Refine your concepts and ideas until people start biting, and offering to help you. Remember, most likely, your idea sucks anyway.

Is it Productive?

But, assuming your idea is awesome, which will result in the next Zynga or Rovio, why would you still want to do it alone?

Will you, as the one man show be able to produce that quality game that you see in your mind?

Or will have to settle when you hit the roadblocks of your weaknesses?

Art is hard for analytical coders. Game design and balancing is hard for the more artistic among us. Pulling together all the aspects of a game is not a skill everyone has.

Stop thinking that your awesome strengths are going to mask the other weaknesses in your game development process. It won't. Don't be surprised that your product is judged against its weakest aspect, the stuff you aren't good at, not its strengths.

Pull together a team, use your strengths to compliment the rest of your team's strengths.

Is it Profitable?

Finally, assuming you have the best idea, should you keep it to yourself, doing all the work? Will the payout be bigger by keeping the whole pie for yourself?

A widely noted survey also backs up the team theory, versus one man show. Scroll to around Figure 7, which show more returns for more developers working together. / Owen Goss, the author's take:

"The conclusion that I draw from this is that, in general, larger groups of developers are able to create games that earn more money. Wagering a guess, this is perhaps because they are able to create games that are larger in scope, more technically interesting, and more polished, because they have more people to work on the game and provide input into its improvement."

General experience shows that partnerships of 2-5 definitely outperforms solo developers in most situations. As Owen notes, along with many startup founders and investors, a team compensates for the weak links of the individuals. In the same way, a game development team should have a higher standard of quality, polish and completeness when compared to an otherwise average game.

If you don't want to partner with someone, at least use contractors to fill your holes. If you, yourself are not willing to invest $500-$1000 for decent graphics and music/sounds, is your idea really that awesome? Or, if you can't convince your closest family and friends that your game idea really is the next best thing, to help by filling art needs when you are mediocre artist or worse, or at least by buying decent art, should you spend all your time to craft top notch code and crown it with so-so artwork?

If you really are the rock star artist/game designer/developer, I will cheer you on to success. But if you are like me, great a few things, good at some other and down right horrible at many thing, surround yourself with folks whose strengths amplify your own. Stop trying to it all yourself.

The composition of a team is a different articles, so I won't even touch that, and there a few articles already written:
http://www.gamasutra.com/blogs/AlistairDoulin/20100107/4040/Building_A_S...
http://www.lorekings.com/blogs/2011/oct/3rd/ig_building/team-pg1.html
http://www.indiezen.org/index.php?option=com_content&view=article&id=119...

Are there are great examples for one man shows that have succeeded in the long term (I have a few in mind)? Are they the exception to the rule? Any brave souls wanting to describe examples of one man shows that resulted in burn out or unpolished games?

Comment below, or with Twitter,

Eradicate Week 7: Turn Based Gaming

This week I want to talk about how two issues converged: saving game state and turn based match play. Saving the state of a strategy game is an obvious feature. If every time you turn off the game you have to restart the game, people stop playing.

As a selling point, we are also going to implement Turn Based Matches (Apple API not quite updated, check this tutorial to get started), which is also a prefect fit for turn based strategy games.

The reason these two issues converge is because the current packet size limit for the turn based game, see http://www.idownloadblog.com/2011/08/19/new-in-beta-6/, check the Game Kit section. Hopefully Apple increases the limit later, but until then, I had to work with the 4KB limitations.

Eradicate Week 6: Quick Update

We have had a super busy week, working on art, and documentation and other stuff, but I don't have any really cool stuff to talk about in detail. So I will just post a couple more pieces of artwork, and list some features that we nailed down.

FEATURES:
Save/Resume game - data stored when game pause by iOS as well
Turn Based Matches - groundwork set play a game with the new iOS 5 turn based matches system
Completed more animations backend code for city markers

Eradicate Week 5: Planning for marketing

Coming off last week where I hit a road block concerning art assets, I haven't been able to make much progress on the actual game. It feels like I haven't coded for the game in almost two weeks. I say that I am dedicated as a full time dev on this project, but various legacy contracts keep needed attention. Brings in a bit of cash, but that isn't really a need right now.

But, it has allowed me to rethink the priority and project list for this Eradicate project. We are also bringing in a new creative art guy, an old friend, to the mix at Skejo Studios. We are doing a trial run with this game to see if we have a good long term fit for the studio. Below is one sketch portrait of a key character. Four more to come.

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,

Eradicate Week 5: Art Assets

It has been a week and half since the last update. Trying not to fall behind on the development updates, but the time can really fly with so many projects up in the air.

This week I have really been hitting the wall when it comes to creativity, or my lack there of. I think of myself as a creative problem solver and a good coder. But I have no sense when it comes to both music and graphic art. Thus far I have been stubbing out the layout of controls, and what the animations might need to be. But as my development task list keeps shrinking, the list of art and music assets needed keeps growing.

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.

Eradicate Week 3: Playtesting Demos

Should I get this playtest?

That is a question I have heard from people before, and I even ask myself often. At times I constantly have a list of new tasks, features, or controls that need to be completed. Might as well keep my head down w/o rolling a build and actually playing the game. Also my vanity doesn't want to show to anyone an unpolished app or game.

But let's all agree. Don't do this!

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.

How I am Motivated

So on iDevBlogADay.com, I came across a few posts stating the lack of motivation, or taking a few weeks off because they just didn't feel like working on their iOS project. Being only six weeks into the full time indie dev situation, I guess I haven't hit that wall yet. Or since I am not doing this nights and weekends, but full time I have a bigger downside if I lose focus since I don't have a regular salary backing me up.

I choose to go full time, leaving behind a pretty good salary. I did this so I would have the freedom and time to pursue some personal and profession goals I want. But I also have to make money long term, so this isn't just a hobby excursion.

My goals as an independent developer, and founder of new iOS studio, Skejo Studios, are two-fold: create a lasting iOS company; work on games and projects that will use myself.

Syndicate content