ARC Memory Management in iOS 5 and Cocos2d-iPhone 2.0

My rewrite of Dungeonators is crawling along at a glacial pace. Mostly because I can only work a couple of hours a week on the project. But the iOS 5 way to manage memory with ARC (automated reference counting) is making the process far less painful than it was the first time I wrote my game. ARC uses annotations and some new key words to manage memory on your behalf. It works very well if you’re doing simple client-side game development and don’t have to worry about backward compatibility with iOS 4.

Here is an example of how ARC changes your life for the better…

In the old days you would declare out your ivars, declare your properties, then synthesize and map them together, and release them in a dealloc method. This little design pattern required 4 repetitive lines of code for every ivar (instance variable) and engendered flamewars about  coding style and where underscore should go (if you thought it was necessary to distinguish an ivar name from a property name).

Pre-ARC Entity.h

#import "cocos2d.h"
@interface Entity : CCSprite {
BOOL isActive_;
NSString * name_;
}
@property (nonatomic) BOOL isActive;
@property (nonatomic, copy) NSString * name;
@end

Pre-ARC Entity.m

#import "Entity.h"
@implementation Entity
@synthesize isActive = isActive_;
@synthesize name = name_;
- (id) init {
  self = [super init];
  if (self) {
    isActive_ = YES;
    name_ = @"Fang";
  }
  return self;
}
- (void) dealloc {
  [name_ release];
  name_ = nil;
  [super dealloc];
}

In this new modern era of automated reference counting I just declare properties, I don’t worry about accessing the ivars directly, and I don’t write my own dealloc. It’s a lot less code in a complex game where characters and objects have dozens of properties.

Post-ARC Entity.h

#import "cocos2d.h"
@interface Entity : CCSprite
@property (nonatomic) BOOL isActive;
@property (nonatomic, strong) NSString * name;
@end

Post-ARC Entity.m

#import "Entity.h"
@implementation Entity
@synthesize isActive;
@synthesize name;
- (id) init {
  self = [super init];
  if (self) {
    isActive = YES;
    name = @"Fang";
  }
  return self;
}

To get Cocos2d-iPhone to work with ARC was really easy: I just replace the NSAutoreleasePool object in main.m with the new ARC friendly @autoreleasepool annotation. (I might not have had to do this but it’s supposedly more efficient.)

int main(int argc, char *argv[]) {
//    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
//    int retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate");
//    [pool release];
//    return retVal;
  int retVal;
  @autoreleasepool {
    retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate");
  }
  return retVal;
}

The downside, as I stated above, is that your app will only run on iPhones, iPads, and iPods running iOS 5 and you need to use Cocos2d-iPhone 2.0. But I think that’s a fair tradeoff. Backward compatibility is a killer of the artistic soul and should be avoided where possible. To Err is human, but to upgrade is divine 🙂

Check out Ray Wenderlich’s excellent ARC tutorial for all the gritty details!

Personal Music Discoveries for 2011 (Thanks Spotify!)

One of the best parts about working at Spotify is being paid to listen to music. After all some has to do the quality assurance! Actually, our QA guys and gals do a great job… but I can’t help myself 🙂

This year I’ve spent a lot of time with my old favorites, recapitulating my youth and young adulthood into playlists. You can find all my playlists here: JPavley’s Spotify profile.

But the known is not the topic of this blog post: Today, one of the final days of 2011, I want to tell you about unknown music.

Spotify has over 15 million tracks available in the US and I doubt that I’ve listened to more than 3000 different songs in my entire lifetime. It’s hard to guess but generally as we age our tastes settle and we stick to what we know. As much as I love the familiar I love the thrill of discovery even more! It’s painful for me to think about music that I may never hear yet that I would love if I had the chance to heard it.

Here are my top 10 personal music discoveries for 2011*:

10. Wire – Red Barked Trees Tension and power slowly build up “to find the healing red barked trees”.

9. Harald Grosskopf – VIVACISSIMO CON MOTO – Album Mix Like a mini sci-fi epic Grosskopf’s a great sound track for living in the future.

8. Röyksopp – Keyboard Milk Scary but mentally danceable.

7. Zomby – Witch Hunt Another scary, haunting song with a fast tempo and bonus gun shots.

6. The Cinematic Orchestra – Evolution – versao portuense Slow and relentless and dreamy.

5. Digitalism – Miami Showdown I grok the repeating patterns that ebb and flow around a central beat.

4. 8 Bit Weapon – 64 Gigabit Mario Epic Like something out of a electronic Miyazaki movie.

3. Wye Oak – Two Small Deaths Could be electronic-pattern-based but actually made by Indy humans.

2. Lullatone – My Second Favorite Song In The World I could live inside this song for ever.

1. John Fahey – Sligo Mud Starts out like a blue standard and moves into abstract and concrete bliss.

Each of these artists is new to me. Hearing each track for the first time was more like remembering something that was missing than finding something new.

Here’s the complete playlist: Personal Discoveries 2011

* This is new-to-me not necessarily new-to-the-world. There is a lot of back catalog that I’ve missed over the years!

Dungeonators Battle UI Redesign


There is nothing quite like real user feedback. The Dungeonators game that I started coding about a year ago has been through several design iterations. Before I wrote a line of code I mocked up the whole UI and tested that on my friends and kids (paper prototype, an honorable UI design tradition). And with each development build I tested everything again and even enlisted strangers. I must have played though the final release candidate a 100 times. (It was then that I realized that game programmers must get sick of their games if they properly test them!)

When I uploaded Dungeonators to the App Store on 14 October 2011 I was pretty confident about the game play and the user interface. Famous last words as they say 🙂

After an initial healthily growth curve Dungeonators installs tanked:


The message I get from this user adoption curve was simple: Dunegonators stinks!

So I went back to the drawing board to search for the stinky bits. After much reflection I realized three things:

  1. Dungeonators is too hard for casual users and too easy/dumb for hardcore gamers. People who play MMORPGs like World of Warcraft punch through my game. People who play Angry Birds get stuck around level 1.6. (Which is as far as you can go if you don’t know what you’re doing.)
  2. People don’t know what to touch. They want to touch the avatars and not the raid and spell frames. If you don’t know what raid frames and spell frames are then you are not going to get my game.
  3. I was going to have to fix this. I could fix this problem with a lengthy tutorial or FAQs. But Dungeonators is causal game not productivity software. I never read manuals and skip tutorials. I expect my audience to have the same level of self respect!
So here is the new battle UI that tries to clean this mess up:
  • The good guy raid frames (on the left) are no longer touchable: They just display status. I couldn’t find a casual user who knew what a raid frame was so I got rid of raid frames.
  • Good guy spell frames are no longer associated with good guy raid frames: Spell frames are now modeless and never hidden. Each good guy has two spells available 24/7. As the game progress the spell are automatically upgraded. I’ll have to rewrite the game mechanics to handle the fact that the total number of available spells has gone from 4 x 6 (which I understand is 24) to a mere 8. But that actually makes Dungeonators a heck of lot simpler to program and to play.
  • The bad guy raid frames are still touchable and still enable the player to switch targets. But in the original UI you could have separate bad guy targets for every good guy. In the revised UI all the Dungeonators are synchronized. It’s a gross simplification that is all for the best.
  • Touching the center of the screen, where the avatars live, is still not part of the game play but if you do, the game will pause and bring up the main menu. I was able to kill two birds with one stone: No main menu button and a valid response to a user touch. Feedback is everything thing: In the original design touching the center of the screen was ignored and could have been interpreted as the game freezing up.
In general I learned what I thought I always knew: iPhone games have to be simple and causal gamers don’t have the time or energy for complex mechanics. But in practice I learned a lesson that every battled hardened game developer must know after their first game is released: There is no better test case than the real world!

Sprite Playground

I wrote a little Cocos2d-iPhone test app and committed the project to GitHub. (Like every dutiful hacker should.) You’re welcome to download the project and fool around with the code.

My goal was to figure out how to create a composite sprite, make sure it could respond to touches, and rotate and move it round the screen. With a little trial and error I got it working. Here’s how I did the hard parts:

I created a sprite from an PNG file and got it’s dimensions:

CCSprite * cocos2dGuy = [CCSprite spriteWithFile:@"avatar_n1_tang.png"];
CGSize spriteSize = cocos2dGuy.textureRect.size;

Then I created a CCNode to be the parent of my sprite sandwich. (I originally tried to use my cocos2dGuy CCSprite as the parent but Cocos2d stacks added on top of partent nodes and I wanted the particle effect under the cocos2dGuy not on top of him.) I set the size of the CCNode to the dimensions of the cocos2dGuy so that when you touch the CCNode it responds as if you’re touching the image. Then I add the CCNode to the layer. It’s also important to set the CCNode’s anchorPoint to the center (0.5, 0.5) as it’s default is bottom-left. CCSprite default to center anchorPoints and I want my CCNode to act like a proper sprite.

CCNode * composite = [CCNode node];
composite.anchorPoint = ccp(0.5,0.5);
composite.contentSize = spriteSize;
composite.position = centerPt;
[self addChild:composite z:0 tag:kCompositeTag];

Next I added the cocos2dGuy sprite to the center of the composite CCNode. These two entities are now both the same size and stacked on top of each other. (It’s probably not necessary for me to set the cocos2dGuy’s anchorPoint and so I’ll remove that line of code down the road.)

cocos2dGuy.anchorPoint = ccp(0.5, 0.5);
CGSize compositeSize = composite.contentSize;
CGPoint compositeCenterPt = ccp(compositeSize.width/2,compositeSize.height/2);
cocos2dGuy.position = compositeCenterPt;
[composite addChild:cocos2dGuy z:1 tag:1];

Finally I created the custom CCParticleSystem from a Particle Designer file and added it to the composite CCNode but at a lower Z value show it shows up under the cocos2dGuy sprite. See how I had to set the position and the anchorPoint to ensure everything lined up.

CCParticleSystem * fx = [ARCH_OPTIMAL_PARTICLE_SYSTEM particleWithFile:@"fireball_small_fast_green.plist"];
fx.anchorPoint = ccp(0.5, 0.5);
fx.position = compositeCenterPt;
fx.duration = kCCParticleDurationInfinity;
fx.scale = 2.0f;
fx.autoRemoveOnFinish = YES;
[composite addChild:fx z:0 tag:1];

Movement and animation are easy in the world of Cocos2d. I really like the visual effect of CCEaseExponentialInOut. It has a nice punch.

Handling touches are bit harder. I had to remember to set self.isTouchEnabled = YES in my init method and override both registerWithTouchDispatcher and ccTouchBegan. The key bit of code for responding to a touch is isTouchForMe:

bool hit = false;
for(CCNode * node in [self children]) {
    if(node.tag == kCompositeTag) {
         hit = CGRectContainsPoint([node boundingBox], touchLocation);
         if (hit) {
             [self hiliteSprite:(CCSprite *)node];
         } else {
             [self turnSprite:(CCSprite *)node andAttackPoint:touchLocation];
         }
    }
}

The main thing here is to give each touchable node a unique tag and test each node in the layer for that tag. If you touch the sprite he inflates for a moment. If you touch an empty part of the screen the sprite turns and launches himself at your finger. Ouch!

Cocos2d-iPhone Sprite Rotation to an Arbitrary Point

I had some time during the Thanksgiving weekend to work on Dungeonators. I’m hoping to get an upgrade out to the App Store soon. One thing I needed //TODO: is refactor my rather poor implementation of rotating a sprite to face another sprite. My original code worked ok, in a roundabout way, but was ugly and mysterious.

(My iPhone game is full of ugly mysterious code: As I implement my ideas in code I first focus on getting it to work. Then, if I have time I go back and fix it to work cleanly. Generally cleanly means boiling the code down to the fewest number of lines possible, making it as functional as possible, and using functions from the operating system or open source code libraries as much as possible.)

I won’t show you my original sprite rotation implementation. Some things are too gross even for the Internet. Let’s just say it was written as if I was trying to remember high school trigonometry by trial and error.

Instead below is the final implementation, useful to any Cocos2d-iPhone programmer who wants a sprite to rotate to face an opponent at any point on the screen:

- (void) rotateSourceSprite:(CCSprite *)sourceSprite toFaceTargetSprite:(CCSprite *)targetSprite {

    // Calculation
    CGPoint difference = ccpSub(sourceSprite.position, targetSprite.position);
    CGFloat rotationRadians = ccpToAngle(difference);
    CGFloat rotationDegrees = -CC_RADIANS_TO_DEGREES(rotationRadians);
    rotationDegrees += 90.0f;
    CGFloat rotateByDegrees = rotationDegrees - sourceSprite.rotation;

    // animation
    CCRotateBy * turnBy = [CCRotateBy actionWithDuration:0.5f angle:rotateByDegrees];
    CCEaseIn * ease = [CCEaseIn actionWithAction:turnBy rate:4];
    [sourceSprite runAction:ease];
}

And here’s how it works, just incase you’re curious…

  • The method takes a source sprite and as target sprite as parameters. After it runs it will rotate the source to face the target.
  • The calculation part uses Cocos2d helper functions and macros (ccpSub, ccpToAngle, and CC_RADIANS_DEGREES) to figure the maths. In my original implementation I had written my own versions. Using the Cocos2d API makes my code easier to read and perhaps faster.
  • The maths work like this: Create a vector out of the distance between to points. Convert the vector to an angle. Convert the angle from radians to degrees and negate it*. Add 90 degrees to the angle to get the proper orientation. (The +=90.0f value is game specific: My sprites are rotated 90 degrees to start with.) Subtract the penultimate result of the calculation from the current rotation property (angle) of the source sprite to get the final result (the amount to rotate by).
  • The animation, which could easily be factored out into a method of its own, uses Cocos2d’s CCRotateBy and CCEaseIn to turn the source sprite to face the target in half a second. This part didn’t change from the original code. I didn’t factor it out because in my game I always use these two pieces together. I don’t like to do too much work in the abstract because I usually end up making my code too complex.

* The need to negate the value produced by CC_RADIANS_DEGREES is a bit of a mystery to me. If I don’t do it my sprite ends up facing in the opposite direction.

When Dogfooding Fails

For over 20 years we’ve been eating our own dog food in the software industry and it’s not working. For the uninitiated dogfooding means to actually use the product you’re developing. It started out as a radical idea at Microsoft and spread as a way to get developers to experience their customer’s pain. On the surface it was a very good idea–especially for an aging corporate culture divorced from its users. When I interviewed with Microsoft in 1995 I was told that all their engineers we’re given low-end 386 PCs. These PCs ran Windows 95 so slowly that the MS developers were incentivized to improve Windows’ performance to ease their own suffering. I don’t know about you, but I find that Windows is still pretty slow even in 2011 running on a really fast multicore PC. Clearly all this dogfooding is not helping.

So I’d like to frame an argument against dogfooding and in favor of something else: Plagiarism.

My argument goes like this:

  1. Dogfooding doesn’t work, or at least it’s not sufficient, because it’s not a good predictor of software success. Some software that is dogfooded is very successful. Most software that is dogfooded fails. (Most software fails and most software is dogfooded therefore dogfooding fails.)
  2. Dogfooding is really bad because it give you a false sense of doing something to improve your product: “It’s OK, I know our software is terrible but we’re forcing our employees to dogfood it and out of shear frustration they will make things better! Everyone go back to sleep…”
  3. Dogfooding reinforces bad product design. Human beings are highly adaptable (and last time I looked software devs are still considered human). We get used to things, especially in a culture where company pride and team spirit are valued (e.g. groupthink). Over time poor performance becomes typical performance. It starts to feel natural. Thus slow loading Windows operating systems become the gold standard for thousands of loyal Microsoft employees and customers. Instead of fixing the software we are fixed by it.

I believe that the urge to Dogfood is an emergent strategy of mature tech companies that want to rejuvenate their software development process. Management starts talking about Dogfooding when they realize the spark of creativity has gone out and they want to reignite it.

One of the reasons Dogfooding fails is that you never eat your own dog food in the beginning: The dog food didn’t exist yet. You had to get your inspiration from outside the company. Microsoft Windows was not the first OS with a graphical mouse-driven shell. At some point the Windows devs must have looked at the Apple Lisa and Macintosh computers for inspiration. And the Apple devs looked at the Xerox Star. And the Xerox devs drew their inspiration from the physical world: The first GUI desktop was modeled on an actual physical desktop. No dog food there.

So rather than dogfooding we should talking about plagiarism. If you want to make a great software product eat another a great software product and make it taste better–don’t eat yucky dog food.

Microsoft should force their devs to use the fastest computers running the best operating systems with really cool applications. I think they must have bought some MacBook Airs, installed Ubuntu and Spotify because Windows 8 looks pretty awesome 🙂

Dungeonators iPhone Game Released in the App Store!

Writing a real game, from scratch, in Objective-C, with original Art and sound effects, took a heck of a lot longer than I imagined. Even with the help of the Cocos2d-iPhone framework!

You can find it here: http://bit.ly/rkZvCJ

Here’s what the sprite atlas looks like (formatted by Zwoptex) …

And here are some stats:

Now you know all my secrets!

 

 

Invalid Code Signing Entitlements

Finally after 11 months I submitted my iPhone game, Dungeonators, to iTunes Connect for inclusion in the Apple App Store. I’m planning on giving it away so the “warcraft meets angry birds” funs is accessible to everyone! I hope it passes Apple’s review process 🙂

It took several attempts for me to get to “waiting for review status”. Here are the step I went through in hope that if you, in the near future, need to submit an app for the first time, you can succeed on your first attempt.

At this point set a cold beer within easy reach…

  1. Most of the info from Apple and the books on iPhone development is based on the old Xcode 3-based application submission process. Google Xcode 4 iTunes connect for the most recent tips. I’m not even going to include a link because the info goes stale fast. Just google it.
  2. Set your app’s pricing and metadata in iTunes connect. You’ll need a 512 x 512 icon too.
  3. Follow all the directions about distribution certificates and distribution provisioning profiles. Like a double-linked list your distro cert should point to your provisioning prof and vice versa.
  4. First create the distro cert via keychain access app on your map. Make sure there is key associated with your distro cert after you install it in your key chain.
  5. Second create your distro provisioning prof and install it in Xcode 4. Make sure your target’s code signing entitlements point to your distro provisioning profile for the release build.
  6. Clean and Archive your app with the Product menu in Xcode 4. The Archive scheme should be set to your release configuration.
  7. In the Organizer window validate and submit your app. You’ll need your iTunes Connect password.
  8. If you get the dreaded “invalid coding signing entitlements” don’t panic. It could mean a lot of different things. But if your iOS app is simple then it’s most likely  the iCloud entitlement. (Google it for more info.)
  9. Go to App IDs in the provisioning portal. Scroll to the bottom. Click configure on the row that represents your app’s ID. Uncheck Enable for iCloud. Click Done. Create a new distro provisioning prof and reinstall it into Xcode 4. Go to iTunes Connect and reject your binary. Go back to Xcode’s Organizer window and do Validate and Submit again.
  10. If you get an invalid binary. Drink a beer and try again! (do while beer != empty)
See, that was easy!

Why Engineers Should Win

If you accept my argument that engineers generally don’t win arguments because they tend to rely on reason instead of rhetoric (even if you don’t accept my example that spam is preferable to junk mail) then you’ll be glad to know I have  a prescription for engineers that will help them win arguments.

But before I get to that prescription I’d like to point out two important premises. First, winning arguments is desirable; Second, winning arguments via rhetoric isn’t really winning.

I have some friends in the hacker/engineering community who are simply disgusted and ready to drop out of mainstream society. In many ways they already have. They have their own culture, their own activities, and their own vernacular.

Q: Why did the hacker surrender his spoon but not his fork?

A: Because spooning is privilege but forking is a right.

If you get this joke you’re an engineer (of the hacker persuasion). Don’t ask me to explain it to you 🙂

“Why bother with the muggles if they’re just going to abuse us with their outmoded ideas about sexuality, gender, religion, intellectual property, and what constitutes an worthwhile activity?”

But there are several good reasons for dealing with the main stream, and helping it become more efficient, effective, and generally more happy. The muggles are our parents, brothers, sisters, and children and we owe them something. They are suffering needlessly. If you can help someone but stay your hand that’s just as bad as doing direct harm. These are all excellent but tired arguments. The best reason for engineers to engage society-at-large and start winning arguments is that we don’t have our own private planet. A couple of more Chernobyls, a few more degrees of global warming, a few more years of developing world famine, and it’s game over for all of us.

“Kk” you say, “I grok it. Let’s all go learn rhetoric and NLP and beat the muggles at their own game!”

Unfortunately that happens all the time. I know lots of people who started out as engineers and ended up as salesmen, managers*, and investors. Once you change your thinking patterns to base arguments on rhetorical techniques (winning on style, winning at any cost, winning as an end in itself) you lose the the ability to figure out the reasonable thing to do. Like Stockholm Syndrome once you take up the sword of your enemy you become your enemy.

If we really want to win arguments, we can’t win on mainstream terms, because then we lose. We have to win arguments on our own terms. See if you can guess how before I write  my next post…

* Mea culpa.

Why Engineers Never Win

Our world is full of bad decisions based on convoluted logic in service of irrational preferences. A great example is people who drive into NYC every morning to get to work. Why people sit in bumper-to-bumper traffic for hours polluting the air, wasting fossil fuel, and developing hypertension inducing road rage is beyond me. Another good example is junk mail. I just can’t phantom why the we tolerate a process where perfectly good trees are transformed into trash, and delivered to my mailbox in brightly colored envelops. Every day I simply throw this junk mail away. At least with spam no trees are sacrificed and I can automate filtering it out.

I like to think that if engineers ruled the world driving into NYC and junk mail would be optimized away like inefficient algorithms and duplicated code.

Apparently engineers don’t rule the world. They rule the internet and the desktop–all the virtual worlds–just not the real one.

So why is that? Why do lawyers and managers (like me) and lawmen get elected and listened too? Why do A students work for C students?

It’s a problem of tools. Engineers are taught logic. Lawyers, managers, and lawmen are taught rhetoric. Thus the engineer makes a well reasoned argument based on data and sound scientific principles and gets blown away by a non-engineer making an emotional appeal in the court of public opinion. If engineers used rhetoric to communicate their ideas instead of reason we would not have half as many problems. We would figure out where to store nuclear waste, how to feed more people, provide more health care, and jump start the economy. As a manager I don’t have the answers to these problem but I know several engineers who do.

If we let the engineers win life would not be perfect but it would actually get better via iterative processes, refactoring, and bug fixing. Instead our life degrades. This makes me sad and hopeful too because there is an obvious solution: Engineers of the world: Stop arguing so rationally.

My favorite Monty Python skit is the one about the Argument Clinic:

Python 1: Ah, is this the right room for an argument?

Python 2: I told you once

Python 1: No you haven’t.

Python 2: Yes I have.

Python 1: When?

Python 2: Just now.

This skit is brillant on so many levels. Every engineer should study it to help him or her learn rhetoric. Python 1 is obviously a typical rational engineer. He asks a perfectly good and honest question. Python 2 is obviously a manager. Python 2 answers Python 1’s question with a statement designed to inflame his passions and cloud his senses. By the end of the skit Python 1 has had his argument but feels cheated out of it at the same time. Like asking for technical debt to be addressed and leaving the meeting wondering how you got talked into creating more technical debt to remove the old technical debt.