Adding Save Game to Battle for Vesta
by john on Mar.08, 2010, under iPhone
One of the most requested features for Battle for Vesta is the ability to save a game. This is an entirely reasonable request. Playing the game all the way through can take some time and it is inevitable that you’ll get interrupted by a phone call or some other distraction and find yourself wanting to pick up where you left off.
Also, over the last few updates the game has gotten a lot harder. I find myself getting shot much more frequently and making it through the last few missions is really difficult. Sometime I just want to replay the mission that I just died on rather than start over from scratch.
I started thinking that the retry functionality was the low-hanging fruit and that I should implement it first. Then after some thought it occurred to me that I could kill two birds with one stone. The simplest way to do this was to save the starting conditions at the start of each level and then add a new way of starting the game, a “retry” button. Pressing the retry button would start the game up on the same mission that was last played. So if you die or get interrupted you can always go back to the start of the last mission you were playing.
It turns out that this requires very little code, but it took me a bit of googling to find the bit of the iPhone framework that does what I need. It turns out that there is a persistent dictionary for the iPhone called NSUserDefaults that allows you to store key/value pairs. It also handles persisting them to flash so you don’t even have to worry about the filesystem. So now I have some simple code to save a game in my startLevel() function:
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setInteger:level forKey:@"levelKey"];
[prefs setInteger:myLevels.goodRemaining forKey:@"goodRemainignKey"];
[prefs setFloat:shieldPower forKey:@"shieldKey"];
[prefs synchronize];
and some complementary code to pull that information back up when a user hits the retry button:
void retry()
{
gameOver = false;
if (isHit && deathCounter <= 0)
{
isHit = false;
uKills = 0;
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSInteger retryLevel = [prefs integerForKey:@"levelKey"];
NSInteger retryGoodRemaining = [prefs integerForKey:@"goodRemainignKey"];
float retryShield = [prefs floatForKey:@"shieldKey"];
if (retryLevel == nil)
{
shieldPower = 6.0f;
level = 1;
energyCollected = 0;
}
else
{
shieldPower = retryShield;
level = (int)retryLevel;
energyCollected = 0;
myLevels.goodRemaining = (int)retryGoodRemaining;
}
startLevel();
}
}
And that's about all it took to add both save and retry to Battle for Vesta. I'll be submitting this update to the App Store today, so you'll be able to use this feature soon.
I should mention that my Googling eventually led me to the the iCode blog which had a helpful walkthrough of how to use NSUserDefaults and which convinced me that it was the correct (and simplest) way to implement what I wanted. However the blog states that the synchronize message is not needed. In my experience it is needed as I tried it without it and it didn't work.
MacWorld Reviews Battle for Vesta
by john on Feb.24, 2010, under Uncategorized
James Savage at MacWorld took a look at Battle for Vesta today. It came away with 3 out of 5 mice in what I think was a very fair and accurate review. As positives he cites intuitive controls, “buttery smooth” graphics, and solid space combat. As cons he lists pretty much what I myself think are the problems: need more variety in enemies, upgradable ship, and multiplayer.
I can say right now that head to head multiplayer isn’t happening, but all the rest is coming eventually. I do wish he had used a more compelling screenshot, but the game is so fast that it is really hard to generate your own while playing.
NSConf: Game Kit and Online Play
by john on Feb.21, 2010, under Uncategorized
Jeff LaMarche
GameKit is a provided framework that only works over bluetooth. Some hardware doesn’t have support for this functionality.
Handles peer discovery and connection.
Three modes: Server, Client, and Peer. Peer is the friendliest to use.
Important to set delegates to nil prior to releasing the associated object.
Very easy to send data to all peers. You can send to specific peers as well.
Data always arrives intact so one send results in one receive.
Bluetooth is a very easy way to have multiplayer.
Online play is more difficult.
Apple doesn’t want you to use threads for networking. Use the UIApplication event loop instead.
NSStream doesn’t have a concept of discrete data. So sends don’t equal receives.
Use Bonjour to be able to find peers.
http://iphonedevbook.com/ has code for this networking stuff.
NSConf Notes: Games with Core Animation
by john on Feb.21, 2010, under Uncategorized
Drew McCormack wrote Sumo Master as a hobby project and to learn Core Animation.
Pretty simple top down 2d game.
Iterative design process. Accelerometer control didn’t work out. Went with touch.
Wrinklypea.com does design work, has some really nice looking UI and character design work.
For many things you can let Apple handle the animation for you. Views, buttons, help system, etc. Use modal transition styles to control how view controllers come in and out of view.
You can apply CA animations to UI elements in order to spiff up your UI.
Trick for squashing sumos: move the origin from the center of the sumo to the rear and then scale in along the y.
Performance tips: reduce the number of layers, merge layers that you can, make layers smaller, opaque layers are faster, cache CATransform3D objects.
http://bit.ly/sumophysics for info on the physics of the game.
NSConf Notes: Mini Sessions
by john on Feb.21, 2010, under Uncategorized
Mark Aufflick: Notifications.
http://mark.aufflick.com/talks/apns
Limited to 256 bytes. Register device with Apple and then pass token back to your server. Then your server can use the token to send a message to Apple which will be passed to the device.
The notification itself is a binary format. 256 byte limit is payload only. Payload is json formatted.
If a user removes the app you get a notification.
There is a Perl library available that sends notifications.
Separate Sandbox(test) and Production connections for push notifications.
http://github.com/aufflick/p5-net-apns-persistent
Justin Williams from Second Gear Software
Sold off his iPhone business and is focusing on Mac products.
Hard to find a marketing niche in the app store.
Had to find a buyer for his app. Complained enough on twitter that someone approached him asking if he was serious and wanted to sell it. Sold it for 2 to 3 years worth of revenue for the app.
Once you agree upon a price you might want to get lawyers involved. Then sign papers, get money.
Transferring ownership of the application is likely impossible. You have to contact World Wide Developer Relations. They email you a list of four questions. Then they don’t respond. After 90 days got unofficial notification that unless you are selling the whole company they won’t do the transfer.
To ease the pain of the transfer the new owner offered the apps for free for a week, hoping that old users would figure it out and update to the new app.
A workaround might be to create an LLC for each app in case you want to sell it. Very annoying. Apple is not talkative on this topic.
Rod Strougo of Prop.gr – Cocos2D
Wraps a bunch of more complicated technologies for making games.
Two physics engines. Box2D is C++. Squirrel is C.
Box2D is tuned for 1 meter objects, so scale your objects to that.
Cocos2d is at http://www.cocos2d-iphone.org which comes with Box2d, but you can get Box2d from Google Code as well.
Looks like a cool set of libs to quickly build 2d games.
NSConf Notes: Core Data Synchronization
by john on Feb.21, 2010, under Uncategorized
Marcus Zarra
ZSynch – desktop and iPhone data synchronization
CoreData is the best way to persist data on the iPhone.
Bare minimum for using ZSynch is two calls: set up a delegate and request a synch.
Eventually will synch to the cloud. You’ll be able to run your own server or pay for central hosting.
BSD license.
NSConf Notes: Hard and Fast OpenGL
by john on Feb.21, 2010, under Uncategorized
Jeff LaMarche
http://iphonedevelopment.blogspot.com
A bit of OpenGL history.
OpenGL ES removes parts that were redundant or killed performance. This includes direct mode, which was great for learing the API. Now you have to jump into the deep end.
Static inline functions for small bits of logic that are called frequently.
Avoid allocating memory a lot. Reuse memory between loop runs when possible.
Use the “f” versions of math.h functions so sqrtf() instead of sqrt() which expects and returns doubles.
Make universal apps to enable Thumb for Armv7 and disable it for Armv6.
Default is counter-clockwise winding.
Pycon Notes: Natural Language Processing
by john on Feb.20, 2010, under PyCon
Nitin Madnani
Python is well suited to NLP due to nicode support, C/C++ extensibility, etc.
NLTK comes with its own corpora, lots of tools, and WordNet integration. Has its own O’Reilly book.
Dumbo is Python bindings for Hadoop Streaming. Hadoop Streaming lets you use any executable or script for mappers and reducers.
Word association example is trivially parallelized using Hadoop on EC2.
Pycon Notes: Building Open Source Communities in Rio de Janeiro
by john on Feb.20, 2010, under Python
Henrique Bastos – @henriquebastos
Small Acts are only the essential things.
Python 2008 was hosted in Rio. They had 400 people over 3 days. Henrique sent out an email asking for more information. The python population in Brazil is young, majority under 30, tend to be students, use it for web development (mostly Django) and consider Python essential to the work they do.
http://pythoncampus.org/ does tutorials and talks on university campuses in Brazil. Did 4 sessions last year. Will do one a month this year.
Rio Pythonistas run dojos weekly. Team coding in front of an audience with a projector showing their work.
Horaextra (Overtime) is a weekly social hour for technology enthusiasts.
Python enthusiasts attend conferences for other languages to meet other developers and build community.
They gave a Python t-shirt to President Lula, video of this became a hit at conferences and on YouTube.
SmallActsManifesto.org lists the principles used to build the community in Brazil.
Pycon Notes: Composing Python Tools
by john on Feb.20, 2010, under PyCon
Raymond Hettinger
Deque is like a list. Pronounced “deck” and stands for double ended queue. Can append() and pop() at both ends, can be indexed but not efficiently, no insert. Basically efficient on the ends. In collections.deque().
Timsort uses partially sorted lists to sort in O(n) time.
Random.sample() picks between two algorithms depending on how you are going to use it because 1,000 choose 900 is very different from 1,000,000 choose 10.
OrderedDicts usually have O(n) performance for deletion. By using a doubly linked list to store items in order and a dict for lookup you get O(1) for all operations. New code is in Python 3.
Python has native support for sets of sets. This enables easy translation of English description of problems involving sets to Python code in a few lines. Applicable to translating an NFA to a DFA.
