nathandemick.com

App Pricing Experiment: Results

If you'll recall, a month ago I decided to experiment with the price of Nonogram Madness. Since launch, I had it priced at $2.99; playing the game through to completion will take even the most hardened nonogram master an hour or two, so I figured three bucks was a fair price. Plus, it seems the conventional wisdom is to price niche games a bit higher. The idea is that people who are actually searching for an uncommon genre will be more inclined to pay a slightly higher price, because, since their genre isn't as well-populated as others, they have to take what they can get. I was also influenced by the standpoint of other developers who push back against the "$0.99 default" of the App Store. They argue that $0.99 is an artificially low price, and that developers can't make sell enough volume to make up the difference.

Well, fortunately, since I'm just writing games as a side biz, I can pretty much do whatever I want in the pricing realm and the results are more of a curiosity, rather than something I have to depend on for my livelihood. I wanted to see what effect lowering the price of Nonogram Madness had on sales. All of my sales come through people searching on the App Store. I don't have any other sort of outside promotion going on, so I think it's reasonable to assume that the difference in sales numbers is based purely on price. (Although in this case, there are websites that list apps that have had their prices dropped, so it's possible sales could have come from one of those.)

I put the game at $0.99 for two weeks and $1.99 for two weeks in January. The results were, as you can imagine, pretty obvious.

Not super high numbers either way, but not too bad for a relatively unknown (compared with something like sudoku) niche. It seems pretty obvious from these numbers that more income is derived from the lower price point, and that the "conventional wisdom" that I referred to earlier is bunk. So, naturally, I've changed the permanent price point of Nonogram Madness to be lower. More money + more people playing my game is hard to argue against.

This experiment has made me also reconsider the pricing of Revolve Ball. Originally I was thinking about going with $1.99, due to the length of the game. However, it's now clear to me why other developers price their (high quality) apps at $0.99 — if they can get enough momentum out of the gate, they have a better chance of recouping their development costs. For better or for worse, while iOS users are used to paying for apps, they're also used to paying $0.99. I think that the only developers who can actually buck this trend are those who are more well-known, or whose games have gone viral on another platform (as an example, consider Canabalt, priced at $2.99, which originally started as a Flash web-based game).

The other thing that I've had to consider is the length and scope of future games that I make. Since I develop games part-time, it makes no sense for me to make a large game that I can't sell for its' real value. That means that I should aim for creating games that are shorter, or at least less time-intensive to make, but that contain enough gameplay to justify a $0.99 price.

EDIT: After another two weeks of $0.99 pricing, I'm not seeing the increased sales numbers that I was expecting. There were two days that had sales spikes (from Japan, no less), but after that the numbers went down to ~5/day. So, I'm raising the price back up to $1.99.

· 2 comments

Review: Horror Vacui 2

Well, boys and girls, it’s review time again! The game that I decided to check out recently is called Horror Vacui 2. Horror Vacui 2 is an iOS strategy/board game designed by Shaun Inman, who is perhaps best known for his web apps Mint and Fever. However, he also seems to have a pretty strong interest in game programming, pixel art and chiptunes, which of course I can relate to. I never got around to playing the original Horror Vacui, but the game mechanics are the same in both games. Since the difference is apparently purely cosmetic, I figured I might as well try out the newest version.

Horror Vacui 2 Title Screen Horror Vacui 2 pits two players (or one player an an AI) against each other, one controlling the water element, the other controlling earth. The goal of the game is to place more of your own pieces on the game board than your opponent. The twist, however, is that each piece can have a hot or cold temperature. Hot or cold pieces don’t count towards your piece count, so you need to “normalize” each temperature by placing a piece with the opposite temperature next to it. However, your opponent’s pieces affect yours as well, which means that you both are trying to normalize your own pieces while freezing or heating up your opponent’s.

The game is turn based, and the pieces you get are random (there’s an option to dispense pieces in slot machine fashion too), so there’s elements of both strategy and chance as you place hot, cold, or normal pieces on the board. In addition, special “Extinction Level Event” cards can be drawn randomly, which affect all the pieces on the board with either a hot or cold temperature. The game ends when all the empty spaces on the board are filled.

Horror Vacui 2 Gameplay My only complaint about the game is that playing versus the AI is not much of a challenge. You’re basically guaranteed to win unless you get totally hosed by piece selection. While there is an option for “local” multiplayer (i.e. put the device on the table in front of two players), there’s no option to play via the internet. Supposedly Game Center makes such matchmaking easier to implement, but since I haven’t tried programming it yet, I’m not in a position to comment on how easy/hard it would be to add to the app. But it definitely would add a lot of replay value.</p>

All told however, I really enjoyed Horror Vacui 2. The game mechanics work really well, and it’s a great example of a board game adapted to electronic game format. The music is catchy, although sadly there’s only one main track (after reading the developer’s blog about his NSF-related pursuits, I was hoping there would be more music). The graphics are well done, with lots of polish put into little details (such as little animations that play after you place a piece on the board). For only $1.99, it’s a great app to add to your library.

★★★★★ — Horror Vacui 2 - Shaun Inman

· 0 comments

Tab wrangling in Safari

Most people know that you can drag tabs out into their own separate window in Safari. But did you also know you can combine them again? Yep, just make sure that the tab bar is set to always be displayed (Shift + Command + T) and then you can drag tabs from one window to another easily. If a window only has one tab, it'll disappear when you move the tab to the second window. Jawesome!

(Also, Command + Click opens links in a new tab. When I had a scroll wheel mouse, I used the wheel click to open/close new tabs, but since I'm Magic Mousing it up, I've had to drop that habit.)

· 0 comments

Menus and buttons in cocos2d

What the what? It's tutorial time again! This time the subject will be a bit smaller in scope than some of my previous entries: menus and buttons. Buttons are obviously a key ingredient in any game's UI. While iOS games might not use buttons for actual gameplay, at the very least your game will have a title screen with a "start playing" button on it. So I'm going to give a brief rundown of cocos2d's buttons, and their containers (appropriately enough, called "menus").

Take another look at the "scenes" tutorial. Now say that we have two scenes and want to flip back 'n forth between them, and we'd like to use a button to do it. Well, unfortunately in cocos2d you can't just plop a button down in your scene; first you have to add a menu to the scene, then add "menu items" (read: buttons) to the menu. The advantages of using a menu are apparent when you have lots of buttons you need to wrangle, but it's annoying to have to use one for just one button.

You can create a menu just like you would any other cocos2d object. The constructor takes a comma-separated list of menu items that you want to store in your menu, so you'll have to make sure to create your buttons before the menu. Also, you'll need to make sure you end the list of buttons you send to the constructor with nil. Once you create and populate the menu, you can specify the layout of the buttons. Layout options include a horizontal or vertical layout (with or without padding), as well as alignment in columns and rows. Here's an example:

// Pretend that buttonOne and buttonTwo are already created
CCMenu *myMenu = [CCMenu menuWithItems:buttonOne, buttonTwo, nil];
[myMenu setPosition:cpp(160,240)];
[self addChild:myMenu z:1];

[myMenu alignItemsVertically];
[myMenu alignItemsVerticallyWithPadding:10];	// 10px of padding around each button
[myMenu alignItemsHorizontally];
[myMenu alignItemsHorizontallyWithPadding:20];	// 20px of padding around each button
[myMenu alignItemsInColumns:3];					// 3 columns
[myMenu alignItemsInRows:3];					// 3 rows

So you now know all about menus. How about their contents (aka menu items)? While there are a number of different options for creating buttons in cocos2d, we're going to focus on the two most useful ones, CCMenuItemFont and CCMenuItemImage, which allow you to easily create text- or image-based buttons. I'll also demonstrate CCMenuItemToggle, which is a button container that stores multiple buttons, but only one is shown (or "active") at a time. CCMenuItemToggle is perfect for a settings menu where you want to have on/off switches for different options.

CCMenuItemFont is the class you'll use when you want a text-only button. This is often most useful for rapid prototyping, since in a "real" game, you'll want to make sure your button looks like it'll do something if tapped. However, if you want to just get something in place that actually works, then go back and create a button graphic later, this class is quite useful.

// Create a button (aka "menu item"), have it execute the "buttonOneAction" method when tapped
CCMenuItemFont *buttonOne = [CCMenuItemFont itemFromString:@"Tap Here!" target:self selector:@selector(buttonOneAction:)];

// Specify font details
[CCMenuItemFont setFontSize:32];
[CCMenuItemFont setFontName:@"Helvetica"];

When you create any button, you will probably want something to happen when a player taps the button. The second two arguments to the CCMenuItemFont constructor specify what will happen when the button is tapped. In the example above, the button will send a message to "self" (that is, the layer that holds the button) and call the buttonOneAction method. So this means you'll have to write a new method in the layer called "buttonOneAction" and have it do something. Here's my example:

- (void)buttonOneAction:(id)sender
{
	// Get a reference to the button that was tapped
	CCMenuItemFont *button = (CCMenuItemFont *)sender;

	// Have the button spin around!
	[button runAction:[CCRotateBy actionWithDuration:1 angle:360]];
}

Pretty simple, eh? With iOS 4, Apple has also introduced the concept of "blocks" (AKA closures) to Objective-C. Some cocos2d methods have block support, so you can write the code you'd want to run in-line. So instead of writing out a new method for code that runs when your button is tapped, you'd just create your button like this (keep in mind this won't work on iOS 3 without extra hackery beyond the scope of this tutorial):

CCMenuItemFont *buttonOne = [CCMenuItemFont itemFromString:@"Tap Here!" block:^(id sender)
{
	// Get a reference to the button that was tapped
	CCMenuItemFont *button = (CCMenuItemFont *)sender;

	// Have the button spin around!
	[button runAction:[CCRotateBy actionWithDuration:1 angle:360]];
}];

The other "most useful" button I'll go over is CCMenuItemImage. This class will load up to three images to be used as a button (normal, active, and disabled states). It is initialized and used in a similar fashion to CCMenuItemFont... you just need to make sure all your images have been added to your Xcode project.

CCMenuItemImage *buttonTwo = [CCMenuItemImage itemFromNormalImage:@"button-normal.png" selectedImage:@"button-selected.png" disabledImage:@"button-disabled.png" block:^(id sender)
{
	// Get a reference to the button that was tapped
	CCMenuItemImage *button = (CCMenuItemImage *)sender;

	// Move the button around
	CCJumpBy *action = [CCJumpBy actionWithDuration:1 position:ccp(windowSize.width / 3, windowSize.height / 3) height:25 jumps:2];
	[button runAction:[CCSequence actions:action, [action reverse], nil]];
}];

Finally, let's talk about CCMenuItemToggle. I was a bit confused about this class at first — I thought it would display multiple buttons in a "radio" style; that is, only one button in the group could be active, and tapping one would disable the others. In reality, CCMenuItemToggle only shows one button at a time, and tapping the button makes the next one "active." A perfect example is an "on/off" button. When it shows "on," tapping it turns the button to "off." Take a look at the following code. When the toggle is tapped, it runs the specified block of code (in this example, we just log which button is selected). In practice, you could modify NSUserDefaults or something.

// Create on/off buttons to go in toggle group
CCMenuItemFont *buttonThree = [CCMenuItemFont itemFromString:@"ON"];
CCMenuItemFont *buttonFour = [CCMenuItemFont itemFromString:@"OFF"];

// Create toggle group that logs the active button - the group is then added to a menu same as any other menu item
CCMenuItemToggle *toggleGroup = [CCMenuItemToggle itemWithBlock:^(id sender)
{
	NSLog(@"Selected button: %i", [(CCMenuItemToggle *)sender selectedIndex]);
} items:buttonThree, buttonFour, nil];

Screenshot of the tutorial Xcode projectWith that, you should have a good grasp of menus and buttons in cocos2d. Feel free to download an Xcode project with some of the sample code used in this tutorial, and ask any questions you might have in the comments. Thanks for reading!

· 5 comments

IE8 "Browser Mode" option

Hey web developers, check this out. I've been using IE8 recently to do cross-browser testing, and have been using the "compatibility mode" to simulate IE7. Well apparently you can lock IE8 into running a specific mode by using the developer tools (Tools > Developer Tools). Kinda nice if you want to focus on a particular browser, but then again you have to remember which one you're using.

· 0 comments