Gibs!

Published on 21/09/2011

A good friend of mine recently tweeted that graphic artists often think that the only thing that needs to go into a game is good art. As someone who writes code for a living, it’s always interesting to see the disconnect between aesthetic and application. What people see versus what people fail to consider.

I’m in the process of writing a hobby game for the iPad that’s fairly far along in terms of development, but still an infant where aesthetics are concerned. It’s full of programmer art and debugging messages and generally things people don’t attribute to a polished product. So today I thought it would be interesting to document just how much work goes into a seemingly simple detail: handling player death and giving visual feedback.

In video games when players meet a grisly end their bodies are often gibbed. A gib, in this case, can be thought of as a chunk of meat or an appendage. In other words: generally stuff you want to keep about your person. Duke Nukem 3D was famous for its elaborate gib sprites (including everything from eyeballs to ribcages and, of course, the ultra-rare testicles).

Fortunately, the game I’m putting together isn’t 3D (or even faux-3D). In fact, it borrows more from the older generation of side-scrollers and platformers. So when it came to adding gibs to our game, I looked to more recent examples, such as the gore-heavy Super Meat Boy.

Jetpack Janitor (as I’ve affectionately nicknamed it) sees players navigating a variety of levels as a jetpack-clad janitor. You’ll move through various levels in a bid to return power to the ship you watch over, avoiding obstacles and hazards as well as solving various physics-based puzzles. Here’s a rough snapshot of a test level featuring a few keys, a closed airlock, and a wall of buzzsaws. You’ll have to excuse the programmer art.

When Stan (that’s our janitor) hits a buzzsaw, he is killed immediately. What we want to do today is not only kill Stan, but also have his body cut into ten or so meaty chunks and distributed about the level.

The Jetpack Janitor engine has been built from the ground up to integrate with the box2d physics engine. This means that every entity (object on screen) is represented by a physics-enabled object. The graphics you’re seeing, from the tilemap that makes up the level, to the player sprite and particle effects, are simple graphical representations that are updated by the physics simulation at regular intervals.

To get the ball rolling, I went ahead and created a Gib class. Because we wanted our gibs to roll around the ground after landing on a surface, I modelled each Gib instance as a circular dynamic body. By turning on debug rendering, you can see that now, when Stan explodes, his body is replaced by three Gib instances (shown here above the buzzsaws):

Unfortunately, while the Gib instances behaved as expected, something felt a little off. I spent a while tweaking their restitution and friction before reaching a point where things felt ‘right’. Finally, I increased the number of Gib instances spawned on death and made the radius of each Gib randomly decided upon instantiation.

With the Gib instances behaving nicely within the physics simulator it was time to up the gore level slightly by allowing each instance to create a finite number of decals. A decal is created each time a Gib collides with a static physical body (such as a wall). In this case, each decal represents a bloody stain that gets painted onto the level geometry.

The plan here was to use a single decal sprite which would then be rotated programatically to fit against the surface it had collided with. As you can see from my initial tests, the method I had hoped to use as a means of calculating decal rotation didn’t quite make the grade. You’ll notice some blood smears towards bottom of the screen are incorrectly rotated.

There are, of course, far more bullet-proof means of calculating the angle and position of such decals. But for our purposes, a simple check against the point of collision versus the relative position of our body seemed to suffice.

With decals working nicely, it was time to work on the actual Gib rendering code. This was a fairly simple case of scaling the meatwad graphic based on the randomly chosen Gib radius. Below I’ve included three screenshots of Stan meeting an untimely end:

So what’s next? Before this code can be considered final, it’s now time to hand it over to Glynn for an art and sound pass. As a result, the code I’ve written is likely to change to encompass the following requirements:

  • A random variety of splatter decals and gib sprites
  • Particle effects during the players initial ‘explosion’
  • Particle emitters tied to each Gib instance
  • And finally, the ability for Gib instances to generate squishy sound effects upon collision with other entities

Hopefully this post has given an interesting insight into the amount of work that goes into even a simple game element.

Now you see me…

Published on 7/08/2011

About a week ago I released a small Mac menubar application that’s designed to help you stay focused and keep your desktop clutter free. It’s called Houdini and it works by hiding applications which have been inactive for a certain amount of time. It was heavily inspired by Drikin’s Spirited Away but has some fundamental differences. For one, Spirited Away works for a fixed timeout for all applications, whereas Houdini will work on a per-application basis.

It was the first Mac application that I’ve realised in a personal capacity and it’s been very rewarding to hear that people are finding it useful. It’s been mentioned and reviewed in a couple of different places and seems to be doing pretty well for itself.

Really useful app! This is already improving my concentration and workflow. Very, very useful and well-done app. I’d pay for this on the MAS.

The app looks good and has a couple of nice settings. Despite the author claiming the app is ugly, it’s quite useful.

Optimizing CoreData full-text queries

Published on 20/07/2011

Given that the CoreData documentation describes a 10,000 object collection as a fairly small data set, I was surprised to find a simple NSFetchRequest being responsible for massive resource spikes in a recent Mac application I’ve been working on.

The NSFetchRequest in question uses an NSPredicate to fetch Files entities with a given path. As can be seen from the original query, I’m performing a case-insensitive comparison of each records path attribute with a receivedPath string.

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"path ==[c] %@", receivedPath];
 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Files" inManagedObjectContext:self.moc];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];

While I had indexed the path attribute and ensured that I was using an NSSQLiteStoreType backing store, I hadn’t considered exactly how CoreData would treat the case-insensitive modifier internally. By passing my debug build the -com.apple.CoreData.SQLDebug argument, I was able to ascertain that the comparison makes use of a custom CoreData SQLite function: NSCoreDataStringCompare.

Essentially this meant that SQLite was boiling the string comparison down to a fairly costly LIKE statement, meaning my index was being overlooked completely. To solve the issue I simply created a secondary attribute: lowercasePath, ensured it too was indexed, and used a direct string comparison, like so:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"path == %@", [receivedPath lowercaseString]];

The results were staggering. The function in question is no longer significant enough to even register during profiling runs.

Glyphs

Published on 11/07/2011

A lovely set of free social media glyphs by GSIX Corp, Inc. Left here more for my own record. But please feel free to check them out.

Via 9-Bits.

Episodes v1.1

Published on 27/02/2011

Part of the fun of releasing applications is pushing out new and exciting features. Unfortunately before you can do that you need to solve outstanding issues. Thankfully with two bugfix releases behind us (v1.0.1 and v1.0.2), Ben and I are now looking to improve the application in some exciting (and hopefully unexpected) ways.

Here’s a quick list of the changes we’re hoping to roll-out later this week:

  • Within your Watchlist, the Upcoming section will now show the next episode of a series that is due to air. We think this one will make a lot of people very happy.
  • We’re looking to introduce the ability to mark historic episodes as being seen/unseen. Making your way through an old Mad Men boxset? Not a problem. Tick episodes off as you watch them.
  • Finally, we’re making it possible for users to allow friends to see what’s on their watchlist. The service is totally free, and it’s opt-in. You can see an example of a public watchlist here (note: still very much a work in progress).
  • A number of UI tweaks and fixes to customise and polish certain native behaviours we weren’t very happy with.

Look out for Episodes v1.1 in the near future.

Working hard on Hardly Working

Published on 11/02/2011

Episodes has been doing fairly well on the App Store and I’m currently working towards a v1.1 release that should introduce a few UI/UX improvements as well as social integration. In the meantime, I wanted to take some time out to introduce my second iOS project: Hardly Working.

Hardly Working was initial conceived to answer the age old question: how much am I being paid to poop? More over, how much is Jay-Z being paid to poop? Suffice to say, we took the idea and ran with it. Hardly Working is where we ended up.

It’s a cute little utilities application that takes your annual salary (or hourly rate), pairs it with the amount of time you spend at work, and tells you how much you’re being paid to perform various activities. It’s full of crude humour and it’s fairly goofy, but that’s kind of the point.

You’d be mistaken, however, for thinking that such a simple premise advocates a simple execution. From the very beginning of the apps development cycle we were intent on making Hardly Working as beautiful as possible. The result is an application that is chalk full of little visual flourishes. From the LCD timer, down to the animated paper receipt your earnings are printed on. Hardly Working isn’t your standard utilities application. We wouldn’t flush our reputations down the toilet for anything less.

Episodes v1.0.1

Published on 29/01/2011


Episodes hit the App Store a few days ago and thankfully users seem fairly pleased with the work we’ve been doing. Here are the release notes for the inevitable Episodes v1.0.1 release. The purpose of this release is to fix a few stability issues as reported by users and polish a few bits and pieces.

  • Stability improvements.
  • Increased feedback during network failure events. It’s now slightly more clear when requests fail.
  • Increased feedback while searching (Episodes now lets you know about minimum search term length and when search terms turn up empty) as well as recommendations.
  • A tool tip will now appear when you first open a show within your watchlist, making the process of rating shows explicitly clear.
  • The Watchlist remove buttons visibility is now dependent upon whether or not your watchlist is empty.
  • All animations have been ported to their iOS4 block equivalents, meaning animation should be much smoother.

The 1.0.1 release has been packaged and is now awaiting review by Apple. We thought it more important to get a stability/polish release out after initial user feedback than wait for a significant point release to patch up any stray issues. We’re hoping to introduce a few additional, exciting features in 1.1.

But for now, enjoy Episodes!

Update a UITableViewCell’s appearance dynamically

Published on 23/01/2011

In a recent iOS project it was necessary for me to update the appearance of certain UITableViewCells based on their position within their parent UITableViews. Matt Gallagher wrote a wonderful piece for Cocoa with Love entitled Easy custom UITableView drawing which covers the basics of creating custom UITableViewCells.

As part of the exercise, Matt assigns separate backgroundViews to cells dependent upon whether they sit at the top, middle or bottom of their parent UITableView. By querying the UITableView for the cells indexPath it’s fairly easy to ascertain where things sit. Things only become slightly more complicated when your UITableView handles dynamic insertions/deletions.

Due to the nature of UITableViewCells, you’ll soon notice that existing cells are cached and recycled in such a way that cell backgroundViews quickly appear out of sync. Dependent upon how the user interacts with your UITableView, a UITableViewCell with a backgroundView intended for cells at the bottom of your table may shift up towards the middle, and so on and so forth.

I had a few ideas as to how I would go about solving the issue, but after spending a few hours consulting the iOS documentation, I decided to contact Matt directly with regards to ‘best practice’ in a situation such as this. I thought for sure there would be some delegate method or function I was otherwise missing that would allow me to dynamically adjust a UITableViewCells appearance. After receiving a helpful reply from Matt, the answer seems to be: there is and there isn’t.

The simple solution is to force the UITableView to reloadData after any insertion or deletion occurs. While this works, it has the unfortunate side effect of being fairly inefficient. It also tends to interrupt or stall the animations associated with the aforementioned actions.

Luckily, the nature of UITableViewCells means that scrolling the offending cells out of, and then back into, view will cause them to ‘course correct’, which means we’re only left with dealing with visibleCells. As luck would have it, getting a list of currently visible cells is fairly trivial. Matt’s solution is fairly simple in practice. First, we iterate through all visibleCells within the offending UITableView and then we force a reallocation of each of their backgroundViews via a custom method I’ve called: configureAppearanceOfCell:atIndexPath:

The configureAppearanceOfCell:atIndexPath: method itself is no different to Matt’s original approach. I’ve simply isolated it to ensure I can call it while iterating over visibleCells but also when my cell is first created as a result of calls to tableView:cellForRowAtIndexPath:. Here’s what it looks like:

- (void)configureAppearanceOfCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath 
{
	NSInteger sectionRows = [self.tableView numberOfRowsInSection:[indexPath section]];
	NSInteger row = [indexPath row];
 
	// Set our rows background dependent upon its positions
	UIImage *rowBackground = nil;
	UIImage *selectionBackground = nil;
 
	/* Logic to assign your backgroundView and selectedBackgroundView here */
 
	((UIImageView *)cell.backgroundView).image = rowBackground;
	((UIImageView *)cell.selectedBackgroundView).image = selectionBackground;
}

Where you choose to iterate over your UITableView’s visibleCells is really a matter of implementation. If, like me, you’re making use of a NSFetchedResultsController, I’ve found the controllerDidChangeContent delegate method to be the most suitable place for it.

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
{
	[self.tableView endUpdates];
 
	for (UITableViewCell *cell in self.tableView.visibleCells) 
	{
		NSIndexPath *cellIndexPath = [self.tableView indexPathForCell:cell];
 
		[self configureAppearanceOfCell:cell atIndexPath:cellIndexPath];
	}
}

And that’s it! I’m interested to hear of other peoples solution to this issue.

Development of native and web-based solutions

Published on 15/01/2011

Earlier this afternoon I submitted the first build of Episodes to the App Store. For all who don’t know, Episodes is a native iOS reimagining of my popular webapp Showtime. When Showtime was initially released it was amidst widespread debates over the future of the mobile platform and the significance of web-based solutions over native development. I thought it would be interesting, as a sort of retrospective, to look back at the development of both Showtime and Episodes. To try to decide whether there’s a clear cut ‘winner’ in terms of both the internal development cycle and the final product.

Development

I’ll start from the beginning. Development, for the most part, was fairly straightforward. I began by trying to summarise what I hoped the Episodes application would accomplish and then moved onto thinking about how it could accomplish those things. In terms of approach, nothing changed dramatically between either project. I compiled a feature list, created wireframes, discussed design and interface elements with my designer, and then I got to work.

Books have been written concerning the intricacies of both HTML5 and Objective-C. I don’t intend to go into any great depth regarding the difficulties I faced in developing either application. I would argue that, in terms of development time, Showtime came to fruition well before Episodes even became usable. There are a number of factors here. For one, I’m a web developer by trade. I’ve only recently branched into software development (starting first with an enterprise Mac application, and then using Episodes to get acquainted with the iOS platform). That said, I believe that were I to continue development of native iOS applications in the future, they would see a much shorter turnaround.

When approaching both the iOS platform and web-based development I relied heavily upon the MVC design pattern. Meaning, simply, that I kept logic and presentation separate where possible. In fact, I found the defining factor in terms of development time to not be based on business logic, but rather the creation of views. The simple fact of the matter is that HTML5 and CSS make it easier to style visual elements. I would say that the majority of my development time on the Episodes project was spent subclassing or otherwise manipulating standard UI classes.

In terms of business logic, I would say that the two platforms (or approaches, if you will) are pretty evenly matched. Episodes stores its internal data via CoreData, Showtime makes use of Local Storage. There’s really very little difference in anything logic related. XML is still a pain to parse and deal with. Error handling is still a drag.

Of course, where HTML5 wins in terms of presentation, Objective-C gains in terms of speed. You get more bang for your buck. But is this really something you can hold-up and celebrate? I’d speculate that in a few years client-side solutions such as Javascript will be almost impossible to distinguish from native applications in terms of speed and fluidity.

Testing

For me, developing a native iOS application became particularly interesting during the internal testing phase. This, in my opinion, is where the two approaches really start to diverge. With a web application, you upload it to a live environment and then make the link available to your testers. In order to control the environment you have a few options, ranging from managing user accounts to the extremes of restrictive firewall access.

With the iPhone, restricting your beta testing is certainly a lot easier. It’s just unfortunate that producing the beta build is a lot more involved. You’ll need to use the iPhone Member Center to configure and ultimately sign your binaries for AdHoc distribution. You do this by providing Apple with a list of your beta tester UDIDs. Each of which need to be collected in some form or another, which invariably means having a conversation about how a user can find their UDID ten or twenty times. (If someone tells me they can’t copy their UDID from within iTunes one more time, I’m likely to go thermonuclear).

With your beta builds distributed, it’s time to start collecting error reports. Much to my surprise, this proved to be far, far easier when it came to native application development. There are a few reasons for this:

  • iOS devices are, quite famously, a very closed platform. This is frustrating for many users, but a godsend for developers. Because, ultimately, bug resolution is a three stage process: identify the issue (usually due to a user report), reproduce the issue, fix the issue. If a user told me they were experiencing an issue on their device, I could almost instantly reproduce it on my side. This is the antithesis to website development, where stage two of the bug resolution process – reproducing the issue – often involves some form of virtual machine or a specifically configured browsing environment. Which brings me to perhaps my biggest gripe with the pro-web app crowd: web application development may be open, but it’s almost impossible to create a standard build to run across all devices.

    You design for the space you’re given. Were I to design a web application to run on the HTC Desire HD, I would need to re-implement the majority of its user interface to work well on the Xperia X10 Mini. Of course, it would run from a technical perspective. But to the end user it may as well not.

  • Bug reporting was made effortless on the iOS platform due to the Xcode tool suite. Crash reports sent by users were symbolicated automatically (usually giving me the offending line number) and timestamped by the Organizer in an easily browsable fashion. The majority of issues were resolved in a matter of minutes.

Release

Dun, dun, dun.. Enter the dreaded App Store distribution process. But is it really that terrible? Is it truly enough to turn developers away from native development altogether? After using iTunes Connect (Apple’s App Store distribution medium) for a month or so, I’d say probably.

This section should be a no brainer to the majority of the people reading this. Releasing web applications is just easier. Case closed. But that’s not to say that the App Store doesn’t have its advantages. Take, for example, the fact that Showtime is a free application. Episodes, on the other hand, will run you $0.99c (£0.59p for us Brits). I wouldn’t even dream of trying to monetize a mobile web application in the same way that the App Store allows me to. The bottom line is that for such a lowly one-time fee, it’s just not commercially viable to setup an entire proprietary payment process. Not to mention the time involved in handling refunds, complaints and general administration. With the App Store, that process is taken care of for me. I just have to jump through a few flaming hoops first.

What kind of hoops, you ask? Well, there’s the two months I was without access to iTunes Connect due to an internal error on Apple’s side. That required four phone calls and over twenty-five emails to fix. And then there’s the process of providing all of my tax and banking information (Negative. I am a meat popsicle). Which, I believe, comes down to the heart of the entire debate. It’s that edginess over putting your name, and in some cases your livelihood, in the hands of a company notorious for its secrecy. During my iTunes Connect issues I was left in the dark for days and weeks at a time. I often wondered, what if this wasn’t an evening and weekend project? What if I were relying on this application to put food on my table?

But there are some positives to the iTunes Connect process. For one, it terrifies you. But that’s a good thing. I read a number of unofficial release guides before I embarked on the process of submitting my application. I learnt that, for the majority of developers, applications see their largest sale spike when the application is visible in the ‘New Releases’ section of the App Store. Which, in basic terms, means you’ve got one shot to get everything about your release perfect. This lead me to go through my final testing with an added intensity which I can honestly credit for the fix of a potential crash bug.

Finally, it’s obvious from browsing Google that the iOS platform and the submission process has matured fairly swiftly in a short period of time. Approval turnarounds are significantly better, and the process of generating provisioning profiles, as well as archiving and submitting your application builds are all far more informed.

Conclusion

A number of journalists seem to have developed a ‘piss or get off the pot’ attitude when it comes to the native/web application debate. You are either for or you’re against. When I developed Showtime, I was fairly agnostic. I found the use of HTML5, CSS and Javascript to create an application that felt native to be fairly impressive. Yet, although I have received many subsequent requests to expand Showtime to other webkit enabled devices, it remains an iOS only web application. Why? Because I never approached the project with a ‘write once, run everywhere’ mindset. I don’t believe such a solution can or will ever exist. How can you write an application for a device you have never used? Logistically it’s a nightmare. Ethically it’s a sin.

Which surely means that the iOS platform has won me over? That I’m a proponent for the rise and rule of native applications? Not so much. I’m a tremendous fan of the iOS platform and I believe that, in terms of mobile hardware, you can’t get better than an iPhone. But Objective-C is a steep learning curve for outsiders, and the platform is still as closed as it has ever been. Perhaps the only solace I can find in that regard is that Apple still seem invested in HTML5, given the recent iAd announcements. While I believe Apple will remain fairly shady, fairly secretive, I have faith that their engineers will always seek the best solution to difficult problems.

And that’s all anyone can really hope or aspire to do. To use the best tool for the job at hand.

Episodes.app

Published on 17/12/2010

Over a year after launching Showtime, an iPhone web application for keeping track of your favourite TV shows, I’m pleased to announce Episodes.app. A native approach to tracking the TV you know and love on your iPhone and iPod Touch.

We spent months pouring over the hundreds of support and feature requests we received for Showtime and feel that Episodes.app is, in every way, a worthy successor. We can’t wait to show you guys what we’ve been working on. To wet your whistle, here are just a few of the things we’re most proud of:

  • An episode and series database over twice the size as that of Showtime’s
  • Full, historic episode summaries and screen captures available in-app with a single tap
  • A personalized recommendation engine and star rating system dedicated to helping you find your next favourite show
  • Handy application badge counts for at-a-glance notifications of unwatched episodes
  • A new powerful search feature

I’ll be giving Episodes.app a more detailed write-up (specifically, the decision to switch from web app to native) in a future article. But for now, signup to be notified at episodesapp.com.