I thought for a long time about an easy way to track achievements for my latest game Hippo Blast. The game is built using Cocos2d and uses OpenFeint for leaderboards and achievements. This turned out to be a very simple process with a SQLite database, and I thought I should share it with the community.
To understand my solution, you need to realize that it’s all about statistics. Achievements are unlocked when our statistics reach a certain value. If you think about Modern Warfare 2, the game is tracking tons of stats! How many shots have you taken with the SCAR-H? How many miles have you sprinted while using the Lightweight perk?
It’s the same thing in Hippo Blast: When a user jumps on 50 bats, they unlock the “Dinner With Ozzy” achievement. So our primary goal should be to create a statistics engine, and define achievements that can be conditionally unlocked.
1. Create your achievements on OpenFeint. The Developer Portal allows you to define all of your achievements. You simply set the name, description, and specify how many OpenFeint points the player will receive upon earning the achievement. Icons are optional, but they add a little extra flare to your app.
2. Create your database. I use Base to maintain my databases. We only need two tables:
Statistics – Name value pairs of metrics that we want to track, and their current value. For example, I have a “bat” statistic, and every time the player jumps on a bat, the value is increased by one.
Achievement – This is where we define our achievements. The primary key is our OpenFeint Achievement ID. We specify which statistic this achievement is based on, and the condition required to unlock it. Finally, we store a boolean value for whether the player has already unlocked the achievement.
3. Track your statistics. Every time the user performs a relevant action, we need to record it in the database. I created a singleton class called “StatisticsManager” with a few helpful methods:
- (void) increaseStatisticByOne:(NSString *)statID;
- (void) increaseStatistic:(NSString *)statID byValue:(int)value;
I can quickly call these from anywhere to update the user’s statistics as needed. Finally, when the round is over, we need to see which achievements have been unlocked:
4. Get the unlocked achievements. Using a simple structure like this allows us to retrieve all unlocked achievements with a single SQL select statement:
SELECT openfeintid FROM achievement, statistic WHERE achievement.statisticid = statistic.statisticid AND statistic.count >= achievement.condition AND achievement.iscompleted = 0
Finally, update your database to indicate that the user has already completed the recently unlocked achievement.
All done! Hopefully this has helped you create a simple statistics engine for use in managing your OpenFeint achievements. Please let me know if you find improvements on my method. Happy coding
Since Mac OS X Leopard, I have become hooked on using Spotlight to look up word definitions and find related words using the thesarus. However, with Snow Leopard, the default behavior of the Dictionary App is to open up a new window for each word query. Some people love this functionality but it doesn’t fit my workflow. Thankfully, a friend turned me on to this Apple default that you can use to make Apple Dictionary use a single window whenever you open it.




