iOS Updates and version numbers

First of all, the update to Catchup I mentioned a while back is finally live in the app store today! This got hung up a bit because Nick wanted me to make the new catchup rule the default. I told him I would definitely do this if he would handle translations of the rules update. (But of course wrangling a bunch of translators is much more difficult than the few lines of C++ needed to make the rule change itself!) So as of this writing, the rules change is still optional (and off by default). If and/or when we get some translated rules, I’ll probably push out another update to flip the default.

I’m also working on updates to some of my other apps. Unfortunately, it’s not really a straight-forward process, and there are some that will still probably not get an update at all. (Action Chess, for instance, just needs to be entirely re-written, which I’ve pretty much decided I’ll just do in Unity rather than go for iOS native.)

But in all the apps I’ve done so far, one thing I’ve had to do is change the code that shows the version number. I thought I’d write a mini-tutorial because this is kinda dumb. In pretty much all my apps, I previously had this block of code somewhere (usually in an AboutViewController class’s ViewDidLoad or ViewWillAppear method):

[self.versionLabel setText:[NSString stringWithFormat:@"v%@", [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]]];

…but now I’ve changed it to the following:

[self.versionLabel setText:[NSString stringWithFormat:@"v%@.b%@", [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"], [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]]];

This results in a version number that looks something like v1.4.b2.

(It’s worth noting that I highly recommend putting a user-facing build number in your all your apps somewhere. This is super important for getting bug reports and feedback. The technique above allows your code to update that user-facing number without having to include it in your code directly.)

In case it’s not clear, self.versionLabel is a UILabel instance, either initialized in code elsewhere, or (more likely) in a Xib or StoryBoard.

Anyway, Apple put out a technical note about version numbers and build numbers back in 2015, but somehow I missed it. Now I’m not 100% sure about this (possible it’s just that I was always confused about this), but my theory is that, at some point (maybe around 2015), the CFBundleVersion key changed functionality, from the version number to build number, and the CFBundleShortVersionString was introduced as the new version number. (This is really difficult to google for, I tried, so if anyone has a more accurate historical rundown, I’d be interested in hearing it.) Anyway, both string are required, but the build number is specific to the version number. (I.E. both have to increment for actual releases, but if you bump the version, you can reset build number back to 0 or 1, or whatever.)

These values are changed in Xcode, in the general project settings. Worth noting that the version number is shown to the user in the app store, but I don’t think build number is exposed anywhere (that I’ve seen). I usually try to follow semantic versioning, with the actual version number containing the first two dots (major and minor version changes), and more or less use the build number as the third “patch” number.

I guess the thing I find the weirdest about these bundle keys is that neither one is named “build”. And I would expect the build number to be the shorter one, not the version number. But maybe that’s just me! Hope this helps someone.

A Catchup Rules Change

Some time ago, Nick Bentley, the game designer behind my app Catchup, proposed a slight change to the rules over in the forums on board game geek.

Please see the forum link above for all the specifics, but the crux of it is that in the original version of Catchup, you could claim a hexagon creating a group up to the largest group on the board without triggering the catchup mechanic. But with this new rules change, even tying with your opponent now triggers an extra claim for them on their following turn.

I’m working on an update to Catchup to make it iOS 11 friendly, and support the new iPhone X screen size, and figured while I’m at it, I’ll add this new rule as an option in the app. So I’ve created a new toggle in the game options, and I’m leaving it off by default, because I don’t think most people will know about it, and I don’t want it to take anyone by surprise. Also, for now, because I don’t really know how I would indicate which version is being played in the UI, you won’t be able to play with the new rule in online games. If there is enough (any?) clamber for it in online play, I may consider adding that in the future.

Catchup Reviews

Screen Shot 2014-08-07 at 2.46.50 PMI’ve been meaning to write a post for a while now with pull quotes from the two big Catchup reviews. (It’s kind of a shame I haven’t even mentioned them yet on here.)

But before I get to those, Catchup is free in the App Store today. I’m hoping for a big influx of new players who might then tell their friends about how great it is, and maybe some of those folks will purchase the app tomorrow, when it’s back to $2.99. So if you haven’t already, go download it now! (But if you’re reading this, my guess is you’ve already got it, so thanks for that.)

Anyway, Catchup’s first big review came from Pocket Tactics on the 14th of August, exactly a week after its release. It’s an absolutely stellar review, giving the game 5 out of 5 stars, and I’ll just let some of the quotes speak for themselves:

“Catchup is as elegant as a game can reasonably be, presented in a marvelously user-friendly way.”

And later:

“…it’s packed with all kinds of options, some of which are unprecedented in my experience.”

In another quote that I found quite amusing, the author, Kelsey Rinella, also manages to call Nick (the game’s designer) a yahoo, while still complimenting him:

“I am not amused that some yahoo can waltz in and make what I do look easy and sound like a caring, brilliant guy at the same time.”

Catchup’s second big review was from the iOS Game review behemoth Touch Arcade. It absolutely floored me to get a full review on the front page of Touch Arcade, and they gave it 4.5 out of 5 stars to boot. Here are a couple of quotes from author Shaun Musgrave’s review:

“If you’re even a little bit into strategy games, you need to get some Catchup all over your mobile device.”

“There are also a number of achievements set up through Game Center, some of them very cleverly devised to force you to play outside of your comfort zone. That’s my favorite type of achievement.”

The Touch Arcade review didn’t appear until August 22nd, slightly more than a week after the Pocket Tactics review. Another week after that, Catchup was back on Pocket Tactics (on the 29th) for their “Games of the month” for August. Here is another great quote from that:

“The greater the ratio of fidelity to a complex system to rules overhead, the better I tend to like a design. Catchup doesn’t even attempt to satisfy my strongest gaming craving, and yet I feel excitement every time I see the badge saying it’s my turn in a game. It’s like rediscovering excellent vanilla ice cream after years of trying all sorts of tarted-up frozen confections. It’s such pure gaming goodness, without dissonance or unpleasantness of any kind.”

Obviously, I’ve added some of the above to the app’s app store description. (Let me know if you have any opinions about the ones I chose!)

I will probably write another post at some point about stats, including download numbers, and what kind of impact these reviews had on those. But anecdotally, the Pocket Tactics review got us slightly more downloads on the day of the review, (I’m guessing because their readers are closer to our core demographic), but the TA review had a longer impact, for more days. Possibly we fell off the front page of PT faster.

Catchup v.1.0.1 & v.1.0.2

Screen Shot 2014-08-07 at 2.46.50 PMHere are the release notes for Catchup version 1.0.1, which was approved and went live in the App Store sometime late last Saturday night (September 6th).

* added a setting to let you change who goes first in a vs AI game
* minor changes to text strings, mostly consistent capitalization of AI and Catchup (thanks go out to Martijn Althuizen for help with this work!)
* minor changes to Dutch localization
* relatively significant changes to the german translation
* fix for the “next game” button flashing after you take an async turn
* close the GameCenter UI if the app goes into the background
* misc additional minor bug fixes

Thanks again for playing Catchup!

After getting two emails almost simultaneously on Sunday morning, both letting me know their game over screens were reporting the wrong winner, I pre-pended the following message to the 1.0.1 release notes, and sat down to find the problem:

WARNING: this update actually causes inaccurate end-game win reporting on the game over screen. (The stats and leaderboard submission should still be correct.) This will be fixed in the next update.

And here are the release notes for version 1.0.2 that I submitted to apple on Sunday afternoon, (September 7th):

* fixed bug with incorrect winner name on game over screen (Sorry!)
* corrected title bar string on game screen

All of this illustrates one of the frustratingly difficult aspects of solo application development — regression testing. Or, for anyone unfamiliar with the term, testing existing functionality after a code change “to make sure everything still works”. Basically, it was my work on the new feature (letting the user pick whether or not they go first in an AI game) that broke the game over screen reporting. As bugs go, it’s fairly minor. (I don’t mean to belittle the frustration if you encounter it!) Nothing is crashing, and the win statistics are reported correctly, both to Game Center and the internal stats page. I definitely tested quite thoroughly playing against the AI before submitting 1.0.1, but I just plain didn’t think to check local multiplayer, and might have played through an async game, but I’m not 100% sure. Anyway, I clearly didn’t encounter the bug. (Or didn’t notice if I did.) The specifics are kinda funny: the wrong player name is reported as winning the game in async, but only to one of the players. (Which player depends on who actually won the game.) In the local multiplayer scenario, it basically always reported player 1 as winning.

I have plenty more features to work on for the next build I submit, but figured I should get this fix out there ASAP.

Catchup v.0.9.1 & v.0.9.3 – release notes

Screen Shot 2014-08-07 at 2.46.50 PMCatchup version 0.9.1 hit the app store earlier this week. Here are the notes that shipped with that version:

* russian localization
* german localization
* settings screen: delete local saved game when changing manual AI level
* fixed a bug with tutorial step 3 not getting displayed
* made popover text scrollable if necessary
* translated a few more strings for all localizations

new in 0.8.x
* traditional chinese localization
* added HSB sliders to color screen, cleaned up UI
* fixed crash in iOS 6

I have been learning a lot with this release, namely about how much extra work localization entails, but Game Center async code stuff also. In fixing a bug at the last minute related to determining whether a Game Center game was still valid (specifically, it goes through and checks all the players to make sure their “match outcome” isn’t set), I introduced another bug, this one making Game Center invitations completely fail, as the match outcome is in an “unknown” state for those, since the invited player hasn’t accepted it yet at that point. Apologies to all the folks who ran into this!

A few minutes ago I submitted build v.0.9.3 to fix this issue. The complete release notes are as follows:

This build fixes a really horrible bug with Game Center “invite” games ending as soon as they began. My apologies!!!

Thank you very much for playing Catchup!

v.0.9.3 details
* fixed “invite” games ending as soon as they are created
* number of “your turn” games is sometimes incorrect, (I need to reset all helper arrays when the UI opens)
* crashing bug when you delete an async game in which it is your turn, start a new one, then click next game after taking your turn (need to re-create all the arrays in the async helper)
* swapped positions of share and close on the game over screen.
* added a new “use english instead of XXX” button for non-english localizations
* lots of fixes for Dutch translation text, some english ones
* credit for Dutch translator in English localization

* dutch (nl) translation
* minor change to make one of the tutorial steps a bit more consistently worded

I did use the official form to request an “expedited review”. I have had good results with that in the past, but also know someone who had it “not work” recently, so we shall see.

Catchup Postmortem – after one weekend

iOS Simulator Screen shot Jul 29, 2014, 6.16.46 PMMy latest game release, Catchup came out for iOS last Thursday, and I thought I’d write a bit about my experience developing it.


First up, how’s it doing? Well, despite a surprise conversation with Apple the Friday before launch, we didn’t get an app store feature. I could show you the typical “long tail” graph, but if you’ve seen any of them before, you know exactly what it looks like. We started with a day of 88 sales, (this at $2.99), followed it up with 34, 26, and 16 sales yesterday. I’m hoping we have a boost again today because it’s no longer the weekend, but essentially, I do not have high hopes. The game’s designer, Nick Bentley, did a great job writing about the game, and making a lot of noise about it in the weeks/days before launch. I definitely credit his efforts for the downloads we did get.

The app ended up climbing to #51 in the “top paid board games” category of the app store.

Reactions / Responses

I think partly because only folks who really care about Abstract Strategy games for iOS have even heard about it, Catchup has had a really great response so far. We’ve got about 12 ratings in the app store, and all but 1 are 5-star. Here are some quotes from the handful of reviews:

“Great implementation of an indie boardgame. The controls are very easy and there are many customization options. The AI has a wide range of levels so it is nice to play at low or high levels of skill.”

“This is definitely one of those games you learn something new every time you play. App is well designed for it and runs really smoothly.”

And some more quotes from around the web:

“Wow. This is beautiful! I thought the ai was crap until i found the manual setting for it… I got pommelled at level 20. The whole ap experience is really very impressive. Nicely minimal and functional… The way i like my abstracts.” – Facebook user

“I like the minimal but pleasantly functional interface.” – BGG user

And I saved my favorite public quotes for last, from Touch Arcade forum user Nachtfischer:

“This is simply brilliant. Just as clean and efficient as the implementation of For The Win was, but even better, with asynchronous online play, dynamically adjusting (and very good!) AI and all kinds of stats you could ever want (it even has a stat for “times you checked the stats screen”, I felt a little caught there, haha).

The game itself is a beloved board game. It has incredibly simple rules, but a ton of emergent complexity, which makes it very elegant – easy to learn, hard to master indeed. There’s a lot of depth beneath the surface here.

It might not look like something special, but if you really love games (and not just semi-related crafts such as audiovisual spectacle, storytelling, Skinner Box mechanisms or whatever), depth and challenge, then you should definitely buy this without a doubt.”

…later, he posted:

“After playing some more, it looks like this is probably going to be my favorite app release of the year so far!”

What could I have done better?

These post-mortems typically have a section for “things I could have done better”, right? But as far as I’m concerned I could have done everything better, so consider all the rest of the headings below a minor subset of bullet points in that overwhelmingly long list.

Beta Testing & Bug fixing

When I decided we should definitely do a beta test, I think I had the right idea. This is a multiplayer application, and I wanted to get people using that multiplayer code ASAP, both to find bugs, but also to gauge the user experience and figure out what I could be doing better. I seriously under-estimated the time needed to run a beta test, (both to find people, and get them playing it, as well as respond / record / react to their suggestions). And then I ended up starting it about two weeks later than intended.

Here’s what I did: I put up a quick google form to collect interested people, then sat on that list for about three weeks. (I’d meant to let it accumulate for maybe a week, but I was still fixing stuff!) When I finally picked users, I basically just sent promo codes to all the ones in the US (because I have evidence that the promo codes only work for US app store users), and who also indicated they would give feedback even if they didn’t like the game. Along with the promo codes, I also sent them a link to a form to collect feedback. The responses were okay, but nothing super revelatory. They definitely helped me find bugs, but the bulk of good UX feedback came from a single individual who would probably have tested the app without our running a beta test at all. (More about that below.)

In short, I still feel like it was extremely useful. It was more useful in terms of finding async bugs, but I could probably have played more games with my handful of friends who had it to get that kind of feedback. If I’d had about two or three more weeks, I think it would have been great to have run more organized play sessions with the beta testers, and perhaps that would have led to more valuable feedback.

Never enough time (or, Things I Never Got Around To Doing)

I really wish I’d spent another week or two polishing the app. In particular, there are some async features I really meant to write in the last month or so of development and just never got around to doing. The main one (which is definitely still on my plate) is opening each individual game when the user opens the app from a notification. I might still get to sneak that into the next release, which is primarily a bug fix release meant to fix Game Center invitations, which I broke in the current app store build (while fixing another bug, of course).

I also wish I’d spent more time working with Nick on promoting the game. I basically let him run with it, and didn’t even hold up my end of the deal by writing a blog post every week until release. (Although this was more a promise to myself rather than a promise to him.) I actually brainstormed a HUGE list of posts I could write, and then only ended up writing a single blog post four weeks before launch, and then finally writing a “release notes” post the day of launch.

Metagame Progression

I’m a big fan of games giving you a solid reason to keep playing. Just about the only thing Catchup does in that regard is show you the level of the AI player, and how that increases/decreases after each game you win or lose. There are also a bunch of Game Center Achievements. While I was implementing the achievements, it occurred to me to space them out so you wouldn’t get a bunch of them after winning one game. So a lot of the achievements are actually dependent on reaching a certain level of AI player. It only occurred to me belatedly (maybe a week before launch) that it would have been really cool to point out that achievement progression in some kind of “campaign screen”, or at the very least in popover messaging after you reach a level where that achievement is available. I have really given this almost no thought, but it feels like something that’s lacking to me.

Programmer UI / UX

Screen Shot 2012-12-11 at 3.26.20 PMI’ve written a bunch about how long it took me to make Catchup… and talked about some of the reasons, but there is maybe one reason that I don’t think I’ve talked about yet. Mainly, it didn’t even occur to me until today, but essentially, the UI changed quite a bit in various iterations of Catchup. And each one of those iterations took some time. To the right you can see the first (totally playable!) version. Obviously, I knew this was going to change, but if I’d known by how much, and how well the app was going to do on release, I might have been more okay with just releasing that version. (OK, probably not really.)

As someone who presented at GDC this year on UX, you’d think I know a thing or two about it. But the not-so-secret truth is that I really don’t. I can probably fake it better than most, but when someone who really does know a lot about UX gives you honest feedback about it, it just becomes super clear that you don’t know jack. That person for me was Nate Weiner (of Pocket / Read it Later fame). When I got his email, it was one of those moments where you realize you’ve been doing something wrong all along. Fortunately, he was kind enough to preface it by saying that none of them were things he would allow to delay launch. Anyway, here’s a list of UX stuff that I could really have done better. (Over half of these points were made originally by Nate in that aforementioned email.)

  • all the popover menus — in particular, I remove the nav bar when I show ’em, and not only does that look weird, but it’s the cause of a number of bugs.
  • replacing the “default” Game Center UI — This is another one that, surprise, surprise, would have fixed a number of bugs. In particular, if someone “swipes to delete” a game from the default Game Center UI, your app is not notified, and (AFAIK) there is really no way (no status change even!) to detect that the delete has happened. Plus, it looks like butt. Would have been a lot of work tho.
  • Onboarding / tutorial — I sorta knew I was doing this the “easy way”. Even though it’s an interactive tutorial, I basically show all my messages on a popover that doesn’t change contextually. I should have been highlighting all the things the tutorial talks about (and just assumes you will be able to find as soon as you close the popover).
  • Game Over Screen — Similar to the tutorial popover, the game over screen could have been made contextually. In particular, it’s been suggested that it should at the very least highlight the group that won the game. (And this should be fairly easy to do, I just wish I’d thought of that before I made the current version of the game over screen!)
  • the Color picker screen — This screen just really blows. I’m happy with how it LOOKS, but it’s not at all obvious how it functions. And there is literally nowhere in the app that explains it. I should probably add a help popover at the very least, but that hasn’t even made the TODO list yet. (OK, now it has.)
  • the Game Settings screen — I really tried to make this screen as flexible as possible, but I think there are probably significantly clearer ways to present and allow you to change the AI level. It gets a little better in one of the updates that hasn’t been approved yet, but it’s definitely still a pain point, I think.
  • the game screen itself — I would love to still include Game Center icons on this screen. I do also feel like it could better (more clearly) indicate whose turn it is.

When I estimate client work, I always emphasize how much less work there will be for me if the graphic designer has already completed their work by the time I begin. I don’t know why it didn’t occur to me that it would of course take longer for me to do that UX and graphic design myself. Well, if you’d asked, I might have told you it was true, but nobody asked, and I just kept plugging away.


I hope someone finds this useful. Thanks for reading.

EDIT(s): Edited to clarify some points, directly name Nate Weiner, and add references to the “top paid board game” category numbers.

Catchup v.0.8.1 now available in the Apple App Store

Catchup - Abstract StrategyThe day is finally here, and my latest game, Catchup has been released for iOS. The game is a two-player abstract strategy game, with asynchronous multiplayer via Game Center.

Here is the app store description:

Catchup is a simple game of surprising turnarounds.

Can you have the largest group at the end of the game? Connect your hexes to master this beautiful abstract strategy game.

– an interactive tutorial to teach you how to play
– a challenging AI opponent whose difficulty changes as you play
– online turn-based multiplayer via Game Center
– two-player pass-and-play on the same device
– beautiful and haunting music by Tori Kamal
– minimalist graphics with customizable colors
– GameCenter Leaderboards & Achievements
– simple and easy to learn rules and gamplay
– difficult to master strategy

Here are all the rules:
1. One player plays all the hexes of one color and the other player plays all the hexes of the other color. The first player begins by claiming 1 empty hex for their color.

2. Starting with the second player, each player must claim 1 or 2 hexes on their turn.

3. If the largest group of hexes at the end of a turn is larger than the largest group of hexes at the beginning of that turn (regardless of color), the next player may claim up to 3 hexes on their turn. (This does not apply after the first player claims a single hex in step 1 above.)

4. The game ends when the board is full. The player with the largest group wins. If the players’ largest groups are the same size, compare their second-largest groups, and so on, until you come to a pair which aren’t the same size. Whoever owns the larger of the two wins.

Catchup is an original Board Game designed by Nick Bentley.

For posterity, here’s the “What’s new in this version” text for the last few versions (because I’ve been submitting all these versions to Apple for approval, these are actually visible in the app store if you dig):

What’s new in Version 0.8.1:
– Spanish, Simplified Chinese, and French localization
– Added a link to the game rules from the game menu
– Lots of bugs fixed in prep for launch!

What’s new in Version 0.7:
– Fixed crippling bug starting Game Center async games.
– Localized Rules text.
– A few other minor formatting and bug fixes.
– …more hexagons!

Catchup Release Date, Trailer

I’m happy to announce here that Catchup will be released on August 7th, 2014.

Last wednesday I put together the gameplay trailer (above) for Catchup and showed it at our local IGDA Twin Cities meeting. I’ll be showing the game again tomorrow night at our Multiplayer Mixer. Then next month, the week after launch, I’ll also be heading to GenCon in Indianapolis to show off the game on their expo floor.

This is definitely the most work I’ve put into a game. (If I were following my standard launch M.O., I’d have already pushed the release button in iTunes Connect.) This time around I’m trying to follow more “game release best practices”. This is mostly because I feel like this game deserves more attention. There are a couple of reasons for this, and the first is that it’s an absolutely great board game that I really like playing! Of course every game I make is one that I want to play, but it’s extra true in this case. I can’t wait to have dozens of async games going of this. (One of my beta testers has already reported playing over 25 games in one sitting, which speaks well toward engagement. Don’t worry if you signed up to be a beta tester, we’re going to be starting the “official” beta testing push sometime later this week.) The second reason for giving this extra marketing is that I think this app is some of my best work. It’s definitely well into the realm of the quality and polish that I would prepare for client work. I’ve been trying to squash every bug as soon as I see it. (There are of course one or two that I haven’t had time to fix yet, but nothing major.)

Another contributing factor to officially spending more (time, effort, & money) to market this game is that Nick Bentley, the game’s designer, has committed to doing so also. He’s already started writing about the release, offering an extremely generous “stretch goal” if we can reach 10,000 downloads. He’s going to be helping out with trying to get reviewers to write about it, and joining me at GenCon. My feeling is that getting 10k downloads is basically next-to-impossible unless we get an app store feature. But if we can get there, I have lots of ideas for additional features, including a very cool new game mode Nick has already been putting some thought into balancing and designing. I guess another reason for all this buzz and pre-release is so I can play that new game mode. I hope we can make it happen.

Color changing in Catchup

Previously on Chesstris…

I have already written a couple of times in the last year about color customization in iOS. My post on how to change the color of a transparent image on iOS is actually one of my most popular posts (based on “organic” traffic coming from google). The other instance was when I posted the slides from my talk about Customizing iOS UI (subtitled “Fonts, Controls & Color”). Neither post stated this explicitly, but basically the main reason any of this was relevant to me was for use in Catchup, a forthcoming game release which will allow you to customize the colors of the entire application. Here are some screenshots from Catchup’s game screen, in the three “default” color schemes:


Color changing with [Style sharedInstance]

In the beginning of the project, after implementing a centralized “style” class, (as I sometimes do, usually to facilitate getting a font), I realized that it would be relatively easy to implement color customization throughout the app. That “relatively easy” feature turned into dozens of hours of extra work, and I’m going to go into detail about some of those hours here.

The basic technique was to keep track of four UIColor properties in my style singleton, loading them at application startup, and then making sure that all of my UIViewController subclasses made sure to set all the colors appropriately in viewDidLoad or viewWillAppear:. This necessitated lots of (otherwise often unnecessary) IBOutlets, but that itself was not a lot of extra work. It was definitely more work to just decide which of the four colors in the scheme should be used for each UI element, but I would not consider even that to have been a pain point.

navigation bar hell

So… I was taking my time with Catchup. Early on it was going to be a quick project, but then I decided it was a great game, and this was a showpiece for my board game conversion prowess! I wanted to do it right. That meant it was going to be done when I felt it was done. Long story short, I thought I was maybe half-finished with development when iOS 7 was announced (with its complete graphic design overhaul).

Screen Shot 2013-02-18 at 9.29.38 AMThis wasn’t necessarily a bad thing! I’d already decided to go for a flat UI design, (especially because I was drawing nearly all the graphics programmatically!) So the aesthetic of the app didn’t need to change, but in those early days, I hadn’t been using navigation bars. I was using a navigation controller in the project, but pushing and popping the view controllers with custom buttons everywhere (to the right is an early screenshot from that era). This made sense if I wanted a flat design in iOS 6, but iOS 7 was flat by default. During the iOS 7 beta, I spent an hour or two experimenting with the look of the new nav bars, and really liked how the look of the game changed with a consistent iOS 7 style nav bar.

So I bit the bullet and ripped out all my custom buttons and implementing a more traditional navigation bar based navigation. For whatever reason, (somewhere between translucency settings, barTintColor vs tintColor, not to mention Extended Edges) it ended up taking a long time to master the nuances of the new iOS 7 navigation bars. It was a lot of work just figuring out the best way to arrange my storyboard elements, but additionally I needed to change all the nav bar colors based on my color scheme! I tried a lot of different techniques before I settled on the ones I think are definitely “working” in the app today. First I tried using the appearance proxy, but that was super problematic and the colors seemed to be cached weirdly. At one point I thought I needed to style the nav bar in every UIViewController subclass, but eventually I figured out that all I needed to do was call this code on app launch (and any time the color scheme changes):

	// tintColor for the whole app (status & nav bar)
	NSArray *ver = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."];
	BOOL isiOS7 = ([[ver objectAtIndex:0] intValue] >= 7);
	if (isiOS7) {
		// tint color affects the navigation bar links
		[[[UIApplication sharedApplication] delegate] window].tintColor = fontColor;
		[[(UINavigationController*)[[[UIApplication sharedApplication] delegate] window].rootViewController navigationBar] setBarTintColor:[Ketchup_StyleHelper color2]];
	else {
		// ios 6
		[[(UINavigationController*)[[[UIApplication sharedApplication] delegate] window].rootViewController navigationBar] setTintColor:[Ketchup_StyleHelper color2]];
		[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];
		[[(UINavigationController*)[[[UIApplication sharedApplication] delegate] window].rootViewController navigationBar] setTitleTextAttributes:@{UITextAttributeTextColor: [UIColor whiteColor]}];

As you can see, a lot of this was to keep my backward compatibility with iOS 6, but unfortunately that meant one really big compromise — there would be no flat nav bar aesthetic in iOS 6. I’ve made my peace with that. The app looks pretty horrible in iOS 6, but it’s totally functional, and… oh well.

One additional thing I spent time on was changing the status bar text to white or black, depending on the darkness of the tint color. This only applies to iOS 7, and looks like this:

		// dark or light determines styles for status bar and nav bar
		UIColor *colorThatMatters = self.neutral;
		CGFloat hue = 0.0f, saturation = 0.0f, brightness = 0.0f, alpha = 0.0f;
		BOOL success = [colorThatMatters getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha];
		if (success) {
			if (brightness < 0.7) {
				[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
				[[(UINavigationController*)[[[UIApplication sharedApplication] delegate] window].rootViewController navigationBar] setTitleTextAttributes:@{UITextAttributeTextColor: [UIColor whiteColor]}];
			else {
				[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];
				[[(UINavigationController*)[[[UIApplication sharedApplication] delegate] window].rootViewController navigationBar] setTitleTextAttributes:@{UITextAttributeTextColor: [UIColor blackColor]}];

Watching the status bar when you manually change that color from dark to light is actually pretty cool, so time well spent, IMO.

Actually Changing Colors – compromises, or lack thereof

Once I decided color schemes were in, there were a number of additional questions. Would I implement a “fixed” (hard coded, but changeable later, of course) set of color schemes and allow the user to select from those? Or would I give the user rope to hang themselves and allow them to change each individual color willy-nilly? (If the former, I needed to pick some good ones, but it would also give me the option of in-app purchase for additional ones, or “unlocking” them via achievements or something.) And finally, could I allow them to choose a single color, and make a scheme programmatically from that color?

IMG_2203Eventually I decided I’m a big fan of the infinite color schemes, so I definitely wanted to give the user a color picker. That didn’t leave reason to do in-app purchase or unlocking, so that was out. Right now there are three default color schemes, but you can change each of the four colors at any time. I also implemented choosing the scheme from a single color without much trouble (you can see a purple version of that on the right), which allowed me to also throw in a button to change the scheme to match any of the 5C colors. I spent some time trying to figure out if there was a way to get at the color of a user’s phone which would allow me to default to their 5C color, but I couldn’t find a sure-fire way, and I don’t like the single color schemes quite as much anyway, so I dropped that after an hour or so of googling.

For the really curious, here’s the code I’m using to generate my four-color schemes from a single color:

	CGFloat lightBrightness = 1.0f;
	CGFloat darkBrightness = 0.2;
	CGFloat neutralBrightness = 0.6;
	CGFloat baseBrightness = 0.8;
	CGFloat hue = 0.0f, saturation = 0.0f, brightness = 0.0f, alpha = 0.0f;
	BOOL success = [newBase getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha];
	if (success) {
		self.color1 = [UIColor colorWithHue:hue saturation:(saturation/1.5f) brightness:darkBrightness alpha:alpha];
		self.color2 = [UIColor colorWithHue:hue saturation:(saturation/1.5f) brightness:lightBrightness alpha:alpha];
		self.color3 = [UIColor colorWithHue:hue saturation:saturation brightness:neutralBrightness alpha:alpha];
		self.color4 = [UIColor colorWithHue:hue saturation:saturation brightness:baseBrightness alpha:alpha];

RSColorPicker vs NOT RSColorPicker

There are a few open source color pickers out there for iOS. After I found one I liked pretty well, I didn’t spend much time looking around. (I found out later I actually know someone who maintains one, and felt slightly guilty for not using it.) Unfortunately, the one I picked, RSColorPicker, while it had a decent interface and an API that I liked, really ended up being a pain in the ass to use. I updated the code to work with a new version of it at least twice, and both times spent at least a day wrestling with it. Oddly, my initial integration probably only took a day, so my initial impression was that it was great. I think the first time was when I decided Catchup should be universal. Turns out the color picker didn’t handle @2x very well, so it was slow on iPad. Supposedly this had been fixed… but it wasn’t as easy as just updating to the latest, there were some hacks that had to be applied. I lost at least a day.

Then another time when I switched to using Cocoapods for the project, I figured this was perfect, RSColorPicker was a cocoapod! Only, no it wasn’t. They had a podfile in there, but the project didn’t use tags, and as far as I could tell it had never been added properly to the pods repository. I’d probably totally forgotten what a pain it was to update the previous time, so after a day or so, I threw up my hands in frustration and ripped the whole project out. (I had been running into compiler issues trying to just use the latest version, and it was starting to feel like amateur-hour to me.)

IMG_2201I looked around briefly for another open source project. (Evaluated my friend’s picker, but the UI wasn’t as customizable as I wanted.) Eventually I just thought to myself, “Can’t I use an image and just pick whatever color the user’s finger lands on?” That’s the solution I went with, more or less implementing the colorAtPosition: method outlined in this stack overflow answer. After all that RSColorPicker hassle, my new solution took only a few hours to implement. (You can see the picker open to the right.)

coming to color conclusions

It remains to be seen whether any of this work was “worth it”, but I definitely enjoy showing off the color changing feature because it demos well. I guess that’s basically what I’m doing in this post. Thanks for reading!

Catchup for iOS – the last 10%

I just looked back through older blog posts on here, and realized that I have not talked about Catchup as much as I should be talking about it given that it’s my next big game release. (I didn’t even have a blog category for Catchup until I added one just now!)

The game is really starting to shape-up and near completion. A few weeks ago I posted the vine above of the new hex particles when I got those working, and I don’t know why I didn’t post that here. My list of bugs is basically just down to one, and the list of features I want to add is also miniscule. Oddly, my TODO is still super long, but the only real tasks that I’ve committed to completing before release are: 1) Flush out achievements (there are a few in there right now, but potential for so many more), and 2) really hammer on the async code to make sure I’m utilizing all of apple’s push notifications to their full effect. This second one includes writing some code to show the async move as it comes from the server, if you happen to be looking at the game screen when that happens. It’s an edge case that a lot of apps ignore, but I feel a relatively frequent use-case, given the short-timeframe nature of turns in Catchup. Also, it will allow you to essentially play games in real-time, even though it’s still async code through-and-through.

One question I ask myself a lot is why it has taken me this long to get Catchup this near completion. There are lots of factors, of course, but I’d initially scoped the game (back when it was Ketchup) as a very quick-and-dirty conversion, really just the simplest game I could think of that would allow me to write the GameCenter asynchronous code that I’d been wanting to write. But after I got Tysen Streib to agree to help write the AI, and as soon as the game was playable against that AI, I quickly decided I should really make an attempt to put out a “full featured” board game conversion on my own. This meant a lot of things to me, but psychologically, I think the scope of the game ballooned WAY out of control. For a while there, I really thought I was going to write ALL the features I put in the TODO. If I’d had nothing else to do the entire year, from when I started Catchup in Jan 2013 until now, I might have completed all those features. (Instead, I spent about six or seven months of last year working freelance gigs so I could pay my bills.) I’ve also taken relatively frequent “breaks” to work on other games, mostly game-jam scope games, but I’ve spent over a month at this point working on Action Go, as well as about a week writing universal updates for DrawCade and my Fez Translator.

There are a lot of posts I could write about Catchup for iOS. Here are some ideas for topics:

– Why (else) has it taken me over a year to put this game out? (Short answers, which could all probably be their own blog posts: Polishing a game is hard! Managing scope on a personal project is hard! A “minimum” list of features for successful board game conversions turns out to actually be A LOT of features. And finally — this could probably be its own post — how bugs in your code can move into the realm of psychologically demoralizing and depressing, and possibly keep you from wanting to work on your project.)

– About Color customization, or why you shouldn’t allow your users to customize the colors in your app. (How I did it for Catchup; why it was “easy” but still took up A TON of time; and the trials and tribulations of using an open source library that is poorly written.)

– How catchup uses Generic Game Model. (Which is basically the story of why GGM has hex support at all.)

– About the features that I cut for version 1.0 of Catchup: showing a list of games with visual previews (like in Carcassonne!); ELO for online games; saving of all completed games, and the ability to review them turn by turn; IAP and/or Ad supported version of the game, Player avatars (or even just showing GameCenter avatars in-game). I could talk about how I chose (or basically, for a long time, didn’t choose) which features would “make it”, and which wouldn’t.

– A post about how much money Catchup needs to make for me to break even. (I’ve actually started this post already, but didn’t get too far, as it’s rather a depressing topic.)

– A post about the Game Center asynchronous code, possibly including making my GameCenterAsyncHelper class available publicly.

– A post about convincing other folks to work for nothing on your personal projects. Why it’s generally (I think now) just a bad idea. I suppose this could also be a post about paying for artists versus just making all the art yourself (where I started versus where I ended up).

Let me know in the comments if you really want to see a particular one of these ideas flushed out, or if you have some other specific question!