Game Center Achievement Notification

Game Center has a notification window that slides down and informs the GKLocalPlayer that they've been authenticated. There is no built-in way to display achievements that the user may have earned during use of your application. The GKAchievementNotification classes are a way to display achievements awarded to the player in the same manner as the authenticated message—similar to Xbox Live style achievement dialogs. The achievement dialogs are added to the UIWindow view of your application:


Achievement notifications in the upcoming Cee-lo 1.1 update.

Using It

You can grab the code from github. Add the folder (.h, .m, images) to your Xcode project. The GKAchievementHandler class handles the display of the notifications. You'll primarily use that (there'd usually be no reason to create a notification directly). When your player earns an achievement, you can notify them of this via GKAchievementHandler:

// grab an achievement description from where ever you saved them
GKAchievementDescription *achievement = [[GKAchievementDescription alloc] init];

// notify the user
[[GKAchievementHandler defaultHandler] notifyAchievement:achievement];

You can also use custom messages instead of a GKAchievementDescription object:

[[GKAchievementHandler defaultHandler] notifyAchievementTitle:@"High Roller" andMessage:@"Earned 100 points online."];

Customization

Apples Guidelines state that "it is up to you to do so in a way that fits the style of your game". and Allan Schaffer of Apple stated in the forums that "[the] best way to do that would be to present a custom dialog using the look and feel of your game" (emphasis, his). This to me means you may be rejected for using Apple's artwork in a custom application. If this worries you, use the setImage: methods to change the logo displayed in the dialog or change the gk-icon.png images in your images. You can also set the image to nil to not show any image:

[[GKAchievementHandler defaultHandler] setImage:nil];

You can also edit the gk-notification.png images to change the stretchable background.

October 1st, 2010 | Permalink

Street Ceelo: Fun Times with the iPhone SDK

Do you follow me on Twitter? You don't? Well you should! If you do though you know how much pain the iPhone SDK has brought me in the last three or four months. I'm very close to being done with a very cool app, but some Apple bugs are making it quite difficult to get it done. Care to read my story and learn about the iPhone application I'm making? Okay...

ceelo1 ceelo3

The Street Ceelo App

I'm working on a dice game – a street dice game called Ceelo. The application itself is essentially a 3D dice rolling simulation. You can play with one phone, passing it back and forth, or you can connect using iOS's GameKit over bluetooth or wi-fi and play with multiple "iDevices". It features custom UI design and elements, networking, peer to peer gameplay, animation, navigation and tab controllers...basically "the works" of the iOS kit. I used this application as a learning exercise and it's turned into an application I'm very proud of.

Pretty cool huh? Well, it was cool until iOS 4.0 came out. You see, 4.0 introduced some new classes called GameCenter that expand on GameKit. It also broke the hell out of the original GameKit classes. So my application runs "flawlessly" (it's essentially complete) on devices running the iOS versions 3.0–3.1.3, but on 4.0.X there are numerous issues with the GameKit in Apple's underlying SDK and in certain places it crashes. This is not acceptable to me so I am working to rewrite much of the code and some of the user experience itself to accommodate the issues.

The Broken

So, what broke when 4.0 was released? Here's an example. In Ceelo, there's a custom peer to peer table display. One player (server) says they are going to start a game and others (clients) join her. Now, if a client quits at any time, a "message" is send to their peers that they disconnected. No problem; we simply remove them from the list of players (if in the game lobby) or the game ends. This works fantastically in 3.x iOS. Now, in 4.0.x, instead of a quick notification, there's a lengthy delay when a player disconnects or cancels a connection request. When the message is finally "sent" (it isn't really), it crashes the server:

Thread 3 Crashed:
0   GameKitServices                 0x06352f90 gckSessionChangeStateCList + 411
1   GameKitServices                 0x0635b49c gckSessionRecvProc + 1474
2   libSystem.B.dylib               0x981c181d _pthread_start + 345
3   libSystem.B.dylib               0x981c16a2 thread_start + 34

For more information on this crash check out my StackOverflow question on the topic or poke into the developer forums. Radar IDs for these issues include 8095838 & 8203566, 8174249 & 8094858.

So I filed a bug with Apple and it's been confirmed as a "known issue". The great thing is that the recent betas of the SDK fix the crashing. Unfortunately the long delays remain. I'm continuing to file a bug with each release of the beta. I'm really shocked that this hasn't been addressed yet as the 4.1 release is supposed to be the GameCenter/GameKit release. Classic Apple though to release broken product to get it to market. It is what it is and I've learned to be patient with them in becoming an "Objective-C developer". Also, from what I understand, the 3.0 release was very much the same way.

The Fixes

At this point I'm changing some of the connection logic to remove some of the opportunities for players to quit the game. I've also changed the peer to peer game selection interface to just auto-accept incoming connection requests. This was thanks to a brilliant suggestion by Avi Itskovich who diagnosed a similar GameKit bug via my Stackoverflow post on the topic. It seems to work much better if you connect people up first.

If the game ever gets to the store, it'll be interesting to see how I'll word the required iOS version. You see, this game will work on *all* iDevices, even those without Bluetooth (I wrote it so there's wifi fallbacks). It works on iPhone, 3G, 3GS, Touches, etc. From iOS 3.0–3.1.3. It'll probably run very well on iPhone4 with 4.1 when that is released (already upscaled all the graphics for the retina display!). The only OS it won't run well on is 4.0. How should I word that? "We don't support 4.0 at all but everything else is grand". Just seems odd to have support for everything all the way back to 3.0, but here in the middle is this turd. Such is life.

That's Nice...

So what's the point of all this? Well, I'm worried that GameKit may be phased out. It doesn't seem like Apple is putting priority on fixing it and is focusing more on the Xbox Live-like GameCenter (which obviously is much more lucrative prospect than peer-to-peer gaming). So, I wanted to share my experience as an introduction to Typeoneerror Studios offering iOS development one of our new services. As frustrating as this has been, I absolutely love the Apple development kits, tools and the overall process.

Want to beta test at some point?

Send an email to ceelo at typeonerror with your device ID. How do you get that? Use this fantastic video that Sam Vermette hosts at http://whatsmyudid.com/.

August 24th, 2010 | Permalink

Custom Key Bindings in XCode for TextMate Users

I’ve recently been getting doing some development in XCode and Interface Builder (learning the iPhone SDK). I found XCode a real pleasure to work with (especially its unique form of “Code Sense”), but I did miss some of TextMate’s default text shortcuts, specifically “delete line” and “duplicate line.” There are some Key Binding options in the Preferences but nothing like those.

I asked a question on StackOverflow, a great new wiki/forum/help site for programmers and was pointed to the Cocoa docs and some useful posts where I figured out how to put together these simple key bindings. Results follow.

Create the file ~/Library/KeyBindings/PBKeyBinding.dict if it doesn’t exist and add the following to the file:

{
    "^$K" = (
        "selectLine:",
        "cut:"
    );
    "^$D" = (
        "selectLine:",
        "copy:",
        "moveToEndOfLine:",
        "insertNewline:",
        "paste:"
    );
}

The above snippet creates a key binding for “^$K” (Control-Shift-K – aka TextMate’s “delete line”) and “^$D” (Control-Shift-D – AKA TextMate’s “duplicate line”). You can see there’s loads of different macro’s you can add to this file to make unique key binding snippets. Note that they won’t take effect until you restart XCode.

January 1st, 2009 | Permalink