Friday, April 26, 2013

Nice iOS Snippet for sayin' "Hi Mom!"

Just a quick one from the forge: when debugging my iOS code for my game I like to use the "Hi Mom!" method.

Image of elderly lady in a hat - original source seems to be Huff Post (after some Google Image searching)
Hi Mom!  (Photo credit: Huffington Post)
What's that you say?  "Hi Mom"....?

This is when you have lots of places where your code prints out something - Hi Mom is fine, tho' you often want something more informative - but the key is it prints out on the console, and you can trace its execution by checking these points, and the data output at those times.  It's the best debugging technique I know.

It's the traditional "printf" style of debugging as some call it.  An elite coder friend who coined the term did it I think because "Hi Mom" is really quick and memorable - it highlights the fact that when you're doing this kind of debugging you want a quick edit-compile-run loop so lots of typing is a pain.  And "Hi Mom" is short.  It's just flagging that you reached that point.

It seems pretty obvious perhaps, but in these days of high-powered IDE's (like XCode) and symbolic debuggers that lead you by the nose through your code as it runs, it might seem that Hi Mom is a bit past it and long in the tooth.  Far from the truth!

It might also seem like hard work - writing more code to debug the code I've already got?  Wrong again!

Symbolic debuggers are a pain sometimes - they don't always work especially if your bug has messed up the stack.  Getting a breakpoint just where and when you need it is not always straight forward.  Getting information about the variables you want to see in the right format doesn't always come easy either.  When code is multi-threaded or backgrounding, or you have to interact with the UI using the debugger is not always convenient.

So Hi Mom has some mileage here, even in these days of magic IDE's.

What about all that work typing tho' - especially when Objective-C does not give you a nice __FILE__ or __LINE__ macro to use like C++ does?

Here's a nice snippet I came up with that I'm using a lot - its a macro which uses a bit of token pasting:

#define MARK(object) NSLog(@"%@::%@ MARK - %s: %@", \
        NSStringFromClass([self class]), \
        NSStringFromSelector(_cmd), #object, object)

It gives me output that looks like this:
2013-04-26 22:21:31.994 Ethex2080[24072:c07]\
 UIStateManager::graphSearchFromNode:toNode: MARK - nodeStart: Location #501

Breaking this down:

  • The time stamp and binary name come from NSLog
  • the class name and method name come from the two "NSStringFrom..." functions
  • MARK (my version of "Hi Mom!") tells me its from a "MARK" macro call 
    • so I can see from the console what it is, if I have forgotten to remove one
  • The string nodeStart: is the name of the variable 
    • (from a c-pre-processor token paste, the #object) and 
  • then the results of calling the -(NSString *)description function on that variable.

In fact I put it in my global project declarations file which is one of the headers which gets included in my precompiled header.  That way its always available in any code I write in the project, without having to go hunting for the include or import:

//
// Prefix.pch

#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>

#import "cocos2d.h"

#import "Ethex2080Utils.h"
#endif

Now in my code that I'm debugging I can quickly drop in a statement like this:

- (void)doSomethingWeird:(NSArray *)someStuff
{
    MARK(someStuff);

    // rest of stuff
}

This gives me a nice debug line with
  • the name of the class
  • the name of the function that is running
  • the name of a key variable I'm dumping
  • the description (dump) of that variable
Benefits are:
  • ultra quick to type - no need to type the name of the variable even
  • easy to find and remove before I do my git commit
  • being a macro it can capture the name of the function (a debug function could not)
Feel free to use this if it helps (I hereby place this snippet in the public domain) and good luck as you "Hi Mom" your way to bug-free code!

Saturday, April 20, 2013

What does your game dev back-up strategy look like?

It's an important question to ask.  Sorry for asking it, as I am totally sure you're all over it - but just in case some of you aren't - ahem: backups?  Offsite?  Versioned?  Tested?  :-)



So this post is just a helpful reminder - no need to teach anyone how to suck eggs as we all know the sorts of things that work:

  • source control with remote repositories
  • cloud storage (especially if its versioned)
  • offsite backups
  • multi-site replication
Mine is drop-dead simple.  Basically I use DropBox (with the pro/paid for account you get versioning) for all my directories that are full of binary stuff, like artwork, animations and so on.  And for my code I put it all under source control and push every commit to GitHub.



Obviously GitHub or DropBox could die horribly, get compromised or whatever - just as long as that does not happen on the same day that my house burns down then I'm golden.

Whatever you do choose it has to be simple, and it has to work.  If its a pain to use, and not automatic enough, then you'll forget or overlook using it.

Here's my rule: every time I do a commit to GitHub, I option drag the root folder of my artwork into a folder in my DropBox.

I also have my lap top backed up by TimeMachine to a big hard drive on my home network.  If the house does burn down then obviously both of those things are lost, but the TimeMachine is more about catching my own screw-ups where I delete a file or a folder full of stuff by mistake.

The safety net for catastrophic events is the DropBox and GitHub combo.

It's far from perfect, but I find I can work with it.

I have used both systems to restore files as well - not because I was being thorough and testing my backups like  you're supposed to - but because I'd screwed up and needed to recover stuff.

It was a good feeling knowing it works!  If by some crazy chance you're flying without backups, try making some - its a good feeling, and I'd love to hear your stories.

Thursday, April 18, 2013

CocosBuilder Revolution

A couple of months ago now I threw away all my code and started again.

Was that a bad thing?  Well, it was bad in the sense that I wish I had known back before I started writing all that code that there was a better way to do it, a way that was going to be so much more productive that even throwing away months of work was going to be sort of OK.

So what is that better way?  Using CocosBuilder.

Cocos2D is a powerful API for building your games on iOS, but it is just code, and when I started out on my game I quickly found it impossible to organise all the resources I needed and to size and position all the elements on the game screen.  As I mention in the video I had seen CocosBuilder last year but it seemed flakey and not up to doing enough of what I needed.

But the new 3.0 version is much improved and there are a number of tricks with CocosBuilder that allow you to do a lot more with it than appears at first blush.  It turns out to be well-suited to creating an adventure game like mine, if you can figure out how to game it to your ends.

To try to help anyone who is contemplating going down the path I went down, or anyone who needs a powerful game interface creation tool but is too afraid to ask, here is a video tutorial I put together looking at how to get started with CocosBuilder for iOS.  The tutorial also includes a bit of my thinking around the game editor journey for me.

The tutorial comes in 4 parts, each of around 10 minutes (due to YouTube constraints) and I have tried to make the divisions not too arbitrary.  I'd encourage watching the whole thing, but if you just want to dip into the bits you need I hope the text below will help choose the right parts to watch.

As well as watching my tutorial please also check out two other great tutorials (not videos but very good nonetheless) which I used myself during my CocosBuilder learning process:
http://code.zynga.com/2012/10/creating-a-game-with-cocosbuilder/
http://www.raywenderlich.com/23996/introduction-to-cocosbuilder

Here are download links to the software I used:




Part 1 - Installation and Setup of a Tutorial project for Cocos2D-iOS & CocosBuilder


Part 2 - CocosBuilder resources and first Run of content


Part 3 - Creating a HUD layer CCB



Part 4 - Animating the HUD & making the buttons work

Things I had to leave out

The tutorial was already up to 40 minutes so I had to leave some things out.  Maybe I need to learn how to talk faster.  :-)

Using the UI elements: I imported some UI elements in a plist file in part 1, but never got time to use them.  But if you experiment you should have no trouble in seeing how to use these.  It's pretty much a case of drag and drop.  In some cases you need to use the "Sprite frame" selector in the properties panel on the right-hand-side of CocosBuilder.

Making a layer use the targeted touch handler: I recorded some footage on this, but had to remove it to get the tut down to a reasonable size.  The trick here is that most tutorials and references tell you to implement registerWithTouchHandler in your CCLayer subclass in order to get the kCCTouchesOneAtATime behaviour.

With that behaviour you can use

- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
    CCLOG(@"%@::%@ - %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), touch);
    CGPoint location = [touch locationInView: [touch view]];
    location = [[CCDirector sharedDirector] convertToGL:location];
    
    BOOL isHandled = NO;
    if (CGRectContainsPoint([self boundingBox], location))
    {
        isHandled = YES;
        // do stuff
    }
    return isHandled;
}

Now it turns out that you can get that by setting the following in CocosBuilder for your CCLayer subclass:


...and since these are set in didLoadFromCCB before the onEnter handler sets up the registration, this will cause the CCLayer's implementation of registerWithTouchHandler to set up your instance for one-at-a-time touches.  Now you can implement your touch handler (as above) and off you go.

Thanks for watching videos - I hope they're useful.  Please - if you spot any mistakes let me know so I can address them.

Happy Cocos building!

Wednesday, April 10, 2013

Resting and Seeing

No posts for a week or so because I've been having a nice restful holiday to New Zealand.  It was a chance to rest my brain, and allow myself to really see stuff again.  To see stuff, I draw - photographing stuff is good, but you don't see what is there or get your mind working on it until you draw it.

When you make a game you need a premise.  OK - we're shooting a bunch of bad guys - and why are they bad again?  They're evil zombies from a scientific experiment gone wrong?  OK - that is a premise, and without one even the most obvious game idea won't work.

My game concepts are all driven by fairly rich premises and I need something to work from to build those.  Bad guys need a back story, and good guys need one too - if players are to care at all about your game characters they need some dimensions.

Sitting in a cafe is great - I find I can easily make up stories about the folks having a coffee two tables over.  But travelling to another country, sitting in airports and travelling on ships and helicopters: hell, it doesn't get any better than that for topping up my creative reserves.

Here's some images from my trip and a few words about each - maybe it will give you some insight into how my imagination sees the world and creates a story out of it.

I flew into Wellington, NZ and started there with a trip to Weta Digitals "Weta Cave" for their "Window into Workshop" tour.  This was an absolutely amazing insight into the creative people behind movies like "Lord of the Rings" and "District 9", and I have only my memories of it as we were not allowed to take pictures.  As it was a guided tour doing drawings was not possible either, not that Weta would have been all that keen on my "taking notes" of what they were working on.  

I went to the Southward car museum and managed to strike up a conversation with the curator there.  The Corvette Stingray and Jaguar E-type next to it were pretty nice too.
Clearly you need to lend me this De Lorean so I can save the universe from evil

I went up on the Wellington Cable Car to a great vantage point and checked the harbour views.  In this picture I'm in front of an older cable car in their cable car museum.

From Wellington I went across to the South Island on the Interislander: a large roll-on, roll-off ferry.  It was a few hours so I got to relax and sketch.  My favourite activity is ninja sketching random people and making up stories about them.  I hold my sketchpad down out of sight and draw them quickly hoping I won't get sprung.
Guy on the Ferry

Guy on the Ferry: he was sitting a few seats over and had a very game-worthy face.  Strong potato of a chin and kind of a solid demeanour.  He could be like some kind of SAS guy, trying to get away from the memories of his last tour in Afghanistan.  He actually smiled a lot, but when his friends pointed at something out the Ferry window he kind of got the "thousand yard stare".
These guys were clearly spies travelling to complete an assignment.  I'm not convinced they really were human.  Maybe SAS guy was going to take them out.

As the Ferry neared the South Island there were some lovely views of the peaks of the fjords reaching up out of the water, and a few tiny yachts gliding across the water.
View out Ferry porthole
There was something about the way portholes framed the views that made them more poignant, more dramatic.
Queen Charlotte Sound
I think it is the way whoever is watching the view becomes part of the frame itself, their black silhouette and that of the ships window being a surround for the scene sliding past.  Ninjas and assassins are like that - you don't see them because they become part of the darkened frame.

Coming into Picton
The ferry itself was pretty enormous - and as it approached the South Island terminus of Picton the buildings seemed tiny compared to it.  One of its sister ships was tied up at the wharf.

We spent a few days in Picton doing the wine district and driving around the Nelson & Marlborough area, then headed down to Franz Josef Glacier.

 Our cabins in Franz Josef were right next to a miniature horse place and one of the cute little guys stuck his head all the way through the wire fence to where I was set up on a chair with my sketch pad.

The goal of Franz Josef was to get up on the glacier itself which was acheived by helicopter.  I would love to own one of these things.  Lots of game memes here.  :-)


Landing up on the glacier we met up with our guide who took us through the ice caves and crevasses.  Glaciers are very very big.  And powerful.  This is a shot of me carefully listening to the safety briefing - "Don't fall into the ice caves as we won't be able to get you out".

The ice caves can go all the way down through the glacier to its bed, but they quickly get too small for us crazy humans.  Here's me doing my best Bear Grylls/Crocodile Dundee impression as I head down into one of the crevasses.

The mountains of the Southern Alps - which featured prominently in the Weta Digital enabled "Lord of the Rings" - were pretty spectacularly beautiful too, swathed in dense green from sea-level and soaring up to snow capped peaks.

From Franz Josef it was back via the scenic Arthur's Pass national park to Christchurch.  This city of 300,000 people has been plagued by earthquakes for the past few years.  Locals have responded by deploying shipping containers as makeshift barriers to prevent rocks from nearby mountains plunging through their houses.

Post apocalyptic doesn't get any better than this.
The city itself is amazing too - shop owners have moved their businesses into shipping containers and a new cafe district is thriving in the container mall called "Re:START" in the city center.

Here a once proud landmark of Cave Rock is fenced off due to earthquake damage and this rather inexplicable steam-punk pumping device is playing some role in that.
After a couple of nights in Christchurch at a rather Agatha Christie style guest house called "The Grange" it was time to head back to Australia.