Showing posts with label objective-c. Show all posts
Showing posts with label objective-c. Show all posts

Wednesday, October 29, 2014

Space Bot Alpha

For the past six months I've been working on a touch device game called Space Bot Alpha.  Here's a video.

Late on Wednesday evening I pushed the final release candidate binary to Apple's App Store review pipeline.  If you want to check out the game I'm expecting it will go live around November 5th.  Doing a review, article or LetsPlay?  Ping me on Twitter and I can get you a access.

Whoa. What a totally weird feeling.

After 2013 and working really hard on Ethex2080 only to realise that I'd need a team of 2-3 people as well as me, and another 12 months to get it done, this year has been all about getting my feet on the ground and shipping a video game.

Now, I proved to myself I could do it, and even if your tastes in games are not aligned to space ships and strategy/puzzlers I hope you'll agree with me that the level of polish and completeness is pretty good for a solo indie developer's first published game.  I'm reaching around and patting myself on my back right now.  But its also weird after pushing so hard for so long to break thru and ship this thing.

Yes, I'm really pretty happy with how Space Bot Alpha has turned out, and although its the end of this stage of the Space Bot Alpha story, as the plucky little guy still has lots of work yet to go with Android releases, level packs and other stuff.  So no relaxing just yet.

But I have to say I'm really excited about what this uncorks for me going forward.  Pushing a build isn't everything: I know that.  If no-one likes the game, and no-one plays it then I am going to have to seriously rethink what I'm doing.  But I did a lot of testing and I've seen people have fun with it.  I've even had some fun with it myself which is pretty amazing considering the times I wanted to just throw my dev tablet across the room in frustration at some stupid bug.  I think this, right now, will be the moment I look back on as when my game development career kicked in to high gear.

In December I'm heading to the UK for a holiday and that'll give me a chance to reset my head.  In 2015 I'm planning to make a new game.  In October 2015 at PAX and GCAP I'm going to turn up there and belong; I'm going to have 2 published games under my belt.

Wanna know more about that new game?  Subscribe here and I'll dump some concepts in coming weeks and months.

In the mean time thanks to everyone that was so supportive and appeared just when I was on the ragged edge to say some nice things and keep me going.  I want to give a particular shout-out to my friends at Disparity Games, Nic and Jason and the rest of the Stark clan; and also +Cameron Owen and +James Bowling of AttractMode Games for making me feel like a real game developer.

And, hey - what are you doing just sitting there!  Go check out Space Bot Alpha!

Wednesday, July 17, 2013

CocosBuilder and CGPaths for non-rect Tap Detection

This is just a short post to frame a video how-to on detecting taps for selection on touchscreen devices, using CGPaths - and how to create those CGPaths using CocosBuilder.



What this essentially does is makes CocosBuilder into a tool that you can use to create non-rectangular bounding paths for tap detection.  As a bonus, I show how you can use the CGPath information to create a blue selection sprite image to signify the active selection in the UI.


I reference Bob Ueland's excellent CGPath tutorial, and that does include some code that you can use for the actual hit test.


For the extraction of the CGPath data from the CocosBuilder file I am not posting my code for cutting-and-pasting but if you've followed my earlier tutorials and are building your own game in Cocos2D you should have enough knowledge to follow what I have done.  It is just simply a case of traversing the nodes and using the standard method to build up a path from the CGPoint information stored in the CCNodes.

My technique for creating a selection sprite from the CGPath data is also not tricky - just check the documentation.  Give it a try and if you get really stuck feel free to ask a question here or on G+.

Hope it helps, and enjoy selecting stuff!

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!

Wednesday, December 19, 2012

Primal Scream

Right now I'm bogged down trying to get some infrastructure stuff done for my game and its very frustrating.

Later in January my time will be mine to schedule as it suits, but right now I'm still working days and coding on my game at nights.  It means I'm tired and not as on top of my game as I should be.

Things that seem conceptually simple and had looked like being fun to do, turned out to be a real pain in the neck.

And literally, as my home work setup is not ergonomically great.  Now I'm walking round like Quasimodo.

Its discouraging.  Why with all these amazing productivity tools can the simplest things be so painful to achieve?

I have a bunch of stuff hard-coded in the game and I'm trying to make it data driven.  The theory is I change a few values in a file, and hey presto the game springs to life with a whole new scene.  Minimal coding, just drop in the artwork and away we go.

Nuh.  Not so much.

To sum it up I've crossed a watershed in Objective-C where I know enough to start coding up things beyond the bounds of the tutorials and example code - and I absolutely have to do that because none of the things I want to do fit neatly into those examples.  So I can see what I need to do, but don't know it well enough to quickly write and debug the code to achieve it.

Things that ought to be simple - wiring up a few data structures to some UI elements - are painful beyond belief.  CoreData's magic binding stuff is not doing what I want, and even where I thought I had it nailed its not working how I thought.

There are a few API's and languages I know really well - those I am used to being able to express myself in quickly.  I can get stuff done fast.

And I will get to that point sometime with Objective-C but right now.... I want to throw the whole thing at the wall!  Grrrr!!!

Oh well.  Hopefully by the next blog things will be better!

Monday, December 10, 2012

Customizing the core data store.

CoreData is a pretty awesome way to manage and persist your game objects, especially for a game with complex inter-related items, such as an adventure game.

Trouble is there is a helluva learning curve getting going with CoreData.  I just solved one little thing that was driving me crazy and wanted to share: how do you customize aspects of the CoreData store?

Image of apple core courtesy of http://www.wpclipart.com/


In my game I have two project targets: one is the game itself written in Cocos2D, and the other target is a game data editor written in Objective-C & Cocoa for the Mac.  They share a lot of classes, and the idea is that I can edit the games data, save it out as a SQLite file (which is one of CoreData's persistence formats) and then when someone goes to play the game for the first time they get a fresh instance of that data as the initial game state.

Trouble is, how do I tell the Mac Cocoa gui, to create my custom instance of an SQLite database, instead of popping up a dialog - which is the default thing you get using XCode's CoreData enabled app wizard?

And for that matter how do I get my database of game objects into my Cocos2D app?

If you're a CoreData beginner like me I suggest:
  • The answer begins with having to understand the bare essentials of CoreData.  For that I recommend Bob Uelands video tutorials.  He has a patient and careful manner that is a bit frustrating but his clarity is hard to beat.  If you've some familiarity with CoreData you can probably fast forward or even skip his stuff.
  • You could try Ray Wenderlich's tutorials - but I find they're a bit too specific and don't always give me the "why am I doing this" answers I want so I can build my own stuff.  But have a look and they may just have exactly what you need.
  • Go and run through Apple's CoreData command line tutorial.  It builds a CoreData app up from first principles all inside main.m.  If its all gobble-de-gook to you, then maybe skipping patient Bob's tutorials was a bit hasty...
What is great about the Apple CoreData tutorial is that the final result - a CoreData app that does not start with any of AppKit or UIKit, or any XCode scaffolding - is exactly what you need for dropping CoreData into a Cocos2D app.  If you have the time and want a good understanding work through the tutorial building up the code in the order given, and resist the temptation to just past the whole source.

Seriously - if you're used to skipping the boring documentation in the Apple developer site you're missing a buried gem with this tutorial.  They give the steps to building a whole data persistence stack.

I found working through these gave me the answers I needed.  So for example to solve my problem with customising the data store, I took the code from Apple's CoreData tutorial managedObjectContext() function and overrode the managedObjectContext function in the NSPersistentDocument sub-class I was using in my Mac OSX game editor GUI.

Edit:  OK, this looked like it was working but wasn't - my apologies.  Basically you can use this code, but you need to create your own window controller and UI class, not use the NSPersistentDocument - which is built to handle arbitrary "documents", not one well-known path for a database.  Sigh.

That let me specify the details of my store:

- (NSManagedObjectContext*)managedObjectContext
{
    static NSManagedObjectContext *moc = nil;
    if (moc != nil) {
        return moc;
    }
    
    NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc]
                                                 initWithManagedObjectModel:[self managedObjectModel]];
    
    NSString *STORE_TYPE = NSSQLiteStoreType;
    NSString *STORE_FILENAME = @"GameData.sqlite";
    
    NSError *error;
    NSString *path = [[PreferenceValues sharedPreferenceValues] saveGamePath];
    NSURL *url = [NSURL fileURLWithPath:path isDirectory:YES];
    url = [url URLByAppendingPathComponent:STORE_FILENAME];
    
    NSLog(@"Setting up the store with type %@ - at %@", STORE_TYPE, [url path]);
    
    NSPersistentStore *newStore = [coordinator addPersistentStoreWithType:STORE_TYPE
                                                            configuration:nil
                                                                      URL:url
                                                                  options:nil
                                                                    error:&error];
    
    if (newStore == nil)
    {
        NSLog(@"Store Configuration Failure\n%@",
              ([error localizedDescription] != nil) ?
              [error localizedDescription] : @"Unknown Error");
    }
    
    moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    [moc setPersistentStoreCoordinator:coordinator];
    
    return moc;
}

Wait, what is that PreferenceValues thing doing in there? That is my own NSUserDefaults front-end. More on that in another post.

How do I get my data into Cocos2D?  I'll show you how I did it, but that's for another blog post.  Subscribe - give me feedback and I will post more!  Thanks for reading!