Feeds:
Posts
Comments

Archive for May, 2009

Warp Speed

In our game, there’s a lot of on-screen action that we had to be prepared for — we couldn’t have cumbersome, but necessary, calculations and memory allocation processes drop our frame rate to an unplayable level. We’re shooting for a frame rate of 45 FPS; we’ll be happy with anything between 45 FPS and 60 FPS. To help us stick to the 45 FPS end of that spectrum, here are a few things we did to keep the game running smoothly:

1.) The default setting for Xcode is set to “Compile for Thumb”. You get smaller compiled code, but it’s slower in-game. Instead, we turned that off, which makes instruction sets larger, but they get processed faster in-game.

2.) Allocating memory is a slow process and doesn’t need to be done in the game loop; we stashed it away in the loading screen. That’s a big burden off the processor’s back during game play.

3.) All calculations that we needed for our particle system in game, we precalculated. When a meteor gets zapped, or collides with another meteor, the splash for the resulting 200-odd particles is already stored in memory; no slow, ponderous calculations that can effect frame rate need to be done within the game loop.

4.) We had the option of tracking and accounting for off-screen collision detection but chose not to do it. Concentrating only on the objects on-screen requires fewer operations and we decided the benefit to the speed of the game was more valuable than accounting for whether X and Y meteor collided on the opposite side of the planet. In a related maneuver, we also did not draw X and Y meteor on the opposite side of the planet; only the meteors near the spaceship (on-screen) are drawn, thus saving the processor from accounting for meteors not directly affecting gameplay at that moment.

5.) Originally, we stuck with Apple’s convention and wrote the game in Objective-C. We suppose this language makes sense if you need the compatibility Objective-C offers for other iPhone programs (like, say, a photo album) but there really wasn’t anything on the iPhone that the game would benefit from if it were written in Objective-C, so we rewrote the game in C++. This, too, gives us greater flexibility and helps keep our frame rate at the target 45 FPS.

A great resource on optimizing your application’s performance is this page from the Apple iPhone Reference Library: http://developer.apple.com/iphone/library/technotes/tn2008/tn2230.html We used it extensively while figuring out how to keep our game humming along, here’s hoping it will help you too.

Read Full Post »

Earlier, we talked about some tips and pointers to consider when you’re trying to find the right one-two combo when it comes to your app’s name and icon. For our app here at Alley Labs, the naming process is ongoing; a slow circling pattern around a target that we’ll only know we’ve hit once we’ve hit it. So we’re going to take you through the steps we’ve gone through so far to get the name for our app. Hopefully, they’ll help you in your process, too.

1.) You want your app’s name and its game play to have an inseparable bond (this goes back to the SimCity vs. Halo distinction we discussed in the previous “naming” post). So the first thing we did; we got into our game. Zipped around blasted some hunks of space rock and let some words start to pop into our heads. Words like “frenzy,” “wild,” “space,” “asteroids”… We start simple and grow from there.

2.) The next stop was the thesaurus to get that list to grow. We plugged in whatever we came up with while playing the game and got a list going – synonyms of synonyms. In the end we had a sheet of paper with about 200 nouns, verbs, adjectives, gerunds, modifiers, dangling participles… you get the idea. Next came the narrowing process.

3.) We went straight to the app store and looked through for games similar to ours that used words from our list. Those words we cut immediately (while it’s a good idea not to sound similar to a game you might be in competition with, we did keep an eye out for words that seemed to be good “gaming” words). Any words that were too long, – we took it easy on the syllables and you should too – difficult to spell, had arcane definitions… cut, cut, cut.

4.) From then on it’s that circling pattern; like flotsam and jetsam in your bathtub while the water’s headed down the drain and it just circles, circles into that little whirlpool vortex until it gets sucked down the hole. When we got to that point we had two words left: “Meteor Blitz.”

That’s where we are now. It could be we recycle this whole process another couple times with the words meteor blitz and see what we get when we come out the other side – the narrowing process is a narrowing process of its own (it’s all very metaphysical…) – but for the moment, that’s how we got our name.

Read Full Post »

Free vs. Lite

It’s nice that you want to give prospective users an opportunity to test your game without paying, but don’t shoot yourself in the foot with the words you use to convey that fact. The two words most commonly used to notify a user that they are downloading a version of the game that they can test without paying are “Lite” and “Free.” We say, stick with Free. A user may see “Lite” and not realize that the distinction between the “Lite” and full versions of the game is whether they pay money to play or not. If a user sees “Lite” and that the game doesn’t cost money to play, they may go off in search of the full version. Upon finding the full version, and the fact that it costs $3.99 to download, you’ve probably lost that prospective customer; it’s unlikely the user will then go back to download the Lite version, get hooked, and then go back and buy the full version. By using the term “Free” instead, you note that the user will be able to experience the full range of gameplay possibilities and can notify in the description, and also later in the game, that to play all available levels of the game, they must purchase the full version. People know what “free” means – they don’t have to pay. Leave the coy term – “Lite” – to the soda and beer companies.

Read Full Post »

Compression

What’d you do to my phone bill?!

If your game is going to send data over the network, remember that it’s going to cost your users money to do that. If it costs too much – i.e. if they raise an eyebrow even a bit at the cost – you’re in trouble. To avoid this, you’ve got to compress any data sent over the network. The second place where uncompressed data can screw up your app is in the game. Uncompressed text data stored in the game can slow load times and compromise the user’s experience. Large amounts of text data in-game need to be compressed and doing so can speed up your load times, which is always a plus. Copy and add these two files to your project to get around these two landmines:

1. Xcode -> Project -> Edit Project Settings -> Linking -> Other Linker Flags -> -lz (be sure to do it for all configurations)
2. follow the usage in the main.m file below
//
//  Compress.h
//
@interface Compress : NSObject {
}
// Returns a data object containing a Zlib compressed copy of the receivers
// contents.
+ (NSData *)compress:(NSData *)data;
// Returns a data object containing a Zlib decompressed copy of the receivers
// contents.
+ (NSData *)decompress:(NSData *)data;
@end
//
//  Compress.m
//
#import “Compress.h”
#import “zlib.h”
@implementation Compress
// 16K chunks for expansion
const int CHUNK_LENGTH = 16384;
+ (NSData *)compress:(NSData *)data {
if ([data length] == 0) {
return data;
}
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.total_out = 0;
strm.next_in = (Bytef *)[data bytes];
strm.avail_in = [data length];
// Compresssion Levels:
//   Z_NO_COMPRESSION
//   Z_BEST_SPEED
//   Z_BEST_COMPRESSION
//   Z_DEFAULT_COMPRESSION
if (deflateInit(&strm, Z_DEFAULT_COMPRESSION) != Z_OK) {
return nil;
}
NSMutableData *compressed = [NSMutableData dataWithLength:CHUNK_LENGTH];
do {
if (strm.total_out >= [compressed length]) {
[compressed increaseLengthBy:CHUNK_LENGTH];
}
strm.next_out = [compressed mutableBytes] + strm.total_out;
strm.avail_out = [compressed length] – strm.total_out;
deflate(&strm, Z_FINISH);
} while (strm.avail_out == 0);
deflateEnd(&strm);
[compressed setLength:strm.total_out];
return [NSData dataWithData:compressed];
}
+ (NSData *)decompress:(NSData *)data {
if ([data length] == 0) {
return data;
}
unsigned full_length = [data length];
unsigned half_length = [data length] / 2;
NSMutableData *decompressed = [NSMutableData dataWithLength:full_length + half_length];
BOOL done = NO;
int status;
z_stream strm;
strm.next_in = (Bytef *)[data bytes];
strm.avail_in = [data length];
strm.total_out = 0;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
if (inflateInit(&strm) != Z_OK) {
return nil;
}
while (!done) {
// Make sure we have enough room and reset the lengths.
if (strm.total_out >= [decompressed length]) {
[decompressed increaseLengthBy:half_length];
}
strm.next_out = [decompressed mutableBytes] + strm.total_out;
strm.avail_out = [decompressed length] – strm.total_out;
// Inflate another chunk.
status = inflate(&strm, Z_SYNC_FLUSH);
if (status == Z_STREAM_END) {
done = YES;
} else if (status != Z_OK) {
break;
}
}
if (inflateEnd(&strm) != Z_OK) {
return nil;
}
// Set real length.
if (done) {
[decompressed setLength:strm.total_out];
return [NSData dataWithData:decompressed];
} else {
return nil;
}
}
@end
//
//  main.m
//
#import <Foundation/Foundation.h>
#import “Compress.h”
int main(int argc, char *argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *string = @”This is a test of the compression library. Usually text compresses better than binary data. Don’t forget to add ‘-lz’ to ‘Other Linker Flags’ in your project settings!”;
NSData *data = [string dataUsingEncoding:[NSString defaultCStringEncoding]];
NSData *compressedData = [Compress compress:data];
printf(“compressed bytes: %d\n”, [compressedData length]);
NSData *decompressedData = [Compress decompress:compressedData];
printf(“decompressed bytes: %d\n”, [decompressedData length]);
NSString *decompressedString = [[NSString alloc] initWithData:decompressedData encoding:[NSString defaultCStringEncoding]];
NSLog(decompressedString);
[decompressedString release];
[pool release];
return 0;
}

Read Full Post »

Encryption

No Peeking

Unless you want your high scores boards filled up with bored hackers’ fake data – 20,000 users with high scores of 999,999! – then you’ve got to encrypt any data you send over the network and any date you save on the phone. It’s too easy for hackers to snag this data and wreak havoc on your high scores or, much much worse, with the passwords, phone numbers, and/or credit card information of your users. You’re a custodian of this data and if your users don’t trust you, you’re sunk. Simple as that. Here is some code that will help keep sensitive information private and hackers out of your high score boards:

Read Full Post »

Older Posts »

Follow

Get every new post delivered to your Inbox.