It’s been a rather busy last couple of weeks. I’ve actually had a few coding sessions at night, and that hasn’t happened in months. Been having a blast working on Outwitters and we’ve been play testing maps on a weekly basis.

In other news, Craig and Gavin, of Retro Dreamer fame, recently released their Velocispider iphone/ipad game. If you haven’t checked it out by now, then you’re missing out on some good old-school arcade fun. What’s impressive is how quickly that game came together :). I believe they had mentioned it was about a month of development? Man I wish we could crank out quality games that fast. Maybe we’ll try that after Outwitters to help ease us into something less ambitious.

Back in Outwitters land, I just recently got sprite animation implemented into the framework. Having the characters comes to life on the gameboard is pretty exciting. I still need to write a state machine to manage the different animations for the characters, and that’ll take some effort.  Speaking of state machines, one of the initial problems I had to solve was how to implement Outwitters’ core game logic.

In a traditionally academic solution, I initially just wrote a state machine that has the different states of gameplay and transition functions to drive the game forward. On my first run through, the game was working but it was extremely painful adding new rules, tweaking rules, or removing rules to the game. It became a huge mess. I could see writing a ‘graph-based’ state machine would be really complex in the long run. I started to see if there was anything written on turn-based games architecture, and I came across this really helpful post on stackoverflow.com. It described a really elegant way to express game rules without having to couple them with specific ‘states’ of the game in a sequential order.

I took the advice of that post and re-wrote the game using the Command pattern described. It’s been a big win for me thus far in not only implementing the prototype, but helping to quickly iterate on game rules over play sessions. Instead of thinking of all the ways a game state can transition I became more focused on the discrete actions a player can make in a game and thinking of all the conditions that need to be valid (or invalid) in order for that action to be legal. This became much more flexible when iterating, as the logic for actions was isolated to single actions, and changes to them didn’t ripple throughout the whole game’s ruleset. Some of the more complicated conditions for actions were a bit challenging, but far more readable than if I had written it the ‘old way’.

Another nice thing that comes out of this design is the ease of serializing actions and game states. Instead of pulling in a bunch of random data from within the game to create a coherent picture of the game, I ended up creating a single class that encapsulates the status of the game. It’s fairly lightweight, and gave me the added benefit of having a central object to query for information about the game. Adding asynchronous play and saving the game to disk were very straightforward.

I have gone with a component-oriented design for the game objects in my framework. So render components are attached to lightweight gameobjects, and any other special functionality is wrapped inside another component and attached as well. In the past, game logic was usually decentralized throughout the components, as the games tended to be more open-ended with very little structure enforcing the flow of the game (for instance, platformers, and even Tilt to Live). I almost went that route again for Outwitters, but the design used to enforce the rules of the game were at odds with the decentralized component design I was accustomed to. Fortunately, the way things panned out was my components ended up being the ‘View’ and ‘Controllers’ of an MVC model, and the central game state object being the model. When the model changes, events are sent out to my components to update health huds, change character colors, etc. It can get pretty verbose at times, but I’ve loved the fact that the game logic is isolated from how things are positioned on the screen or rendered. It’s helped debugging a great deal.

In the end, the command pattern I’m using for the game rules is still in essence a state-machine, it’s just organized in a very different manner than the common “updatestate(), getNextState()” mentality.

About two weeks ago I mentioned I was looking into using the open source library, gameswf to integrate into our little 2D engine for iOS. I was at the point where I needed a UI solution for Outwitters, and I had a few options:

  1. Keep doing what I was doing with Tilt to Live and create the UI by handing coding everything and procedurally animating it
  2. Create a UI editor to help automate some of the UI features I had created in Tilt to Live
  3. Look into gameswf and see if I could go for the whole she-bang and just use Flash for the UI.

I’m happy to report the gameswf seems to be doing just dandy on iOS. When researching, I was hearing a lot of complaints on performance and compatibility (it’s only compatible with actionscript 2.0), and if you’re using a lot of complicated vector shapes you can bog down the FPS. Well reading the post date on a lot of those articles I found that some were pre-dating the 3GS! So in the end, I just put aside a week to mess around with gameswf on an ipad 2 and try to convert some of the ‘hand coded UI’ in our prototype to using flash.

Exhibit A

Just a disclaimer, all that you see in this video is a work-in-progress and extremely early. It was mostly a mock up to play around with the UI.

So in the video you see the main menu with the Outwitters logo, some buttons, a blue blade, and a background illustration being animated. This is entirely made in flash with pngs and some static text as buttons (just a full screen swf). As I press a map to load a pop up blinks into existance asking if I want to resume a previous game or not. This pop up doesn’t have any external bitmaps or pngs in it, it was made as vector shape rectangle with curved corners and some static text (which actually are bitmaps, but this is handled internally in gameswf). And finally, the mock up game board screen you see a flashy banner come across the screen announcing the player’s turn and shimmering, and then pulling away when the player taps the screen.

The animations weren’t anything too special as my flash skills are pretty horrible these days, but hopefully one can see that in the right hands this can be an incredibly useful tool to making games look that much prettier and be more engaging.

The best thing that’ll come out of this, is now the artist, Adam, has a large amount of creative control of how the UI will look and feel. Before it was heavily on the programmer side to make things work, and the fidelity suffered for it.

The Downside

Now for the things that might be problematic going forward:

Memory

Nothing has changed about this as far as I know, but images are required to be sized at powers of 2. When your working with the lower level api’s this isn’t a limitation that is difficult to overcome because you have so much control over what’s being loaded and how it’s organized in memory (for example, texture atlases). With gameswf, images are handled internally and they do 1 of two things:

  1. If the image is a non-power of 2 size, it will be resampled into a power 2 size using a software-based resizing algorithm. This can be a rather expensive performance hit if you don’t take this into account. The side effect as well is images that go down this pathway end up being rather blurry
  2. If the image’s height and width are a power of 2 then it uses the image directly.

My current solution? Just making image sizes a power of 2 before importing them into the Flash library. Yea it’s a lot of wasted space, but given how the UI functions currently, they aren’t long-lived objects so the memory is freed shortly after the user dismisses the screen or moves on. Of course, in the actual gameplay screen any flash-based UI elements have to be optimized. Sprite sheets aren’t exactly feasible in the traditional sense, but you can emulate sprite sheet functionality in flash by creating a movie clip that is masked differently on each of it’s frames. It’s tedious, but I imagine if you’re needing the extra memory savings this could be the way to go. There are a few other memory saving techniques I haven’t explored, like shared libraries that might provide some benefit as well.

In any case, if you’re targeting really low hardware (3G and below), you’ll most likely run into memory issues. The iPad 2 handled it just fine, but I imagine once I get down to the 3GS model and iPad 1 I’ll have to tighten my belt on the memory usage a bit, but it certainly seems doable.

Resolution

I had spent about a week coming up with a small body of photoshop scripts in conjunction with TexturePacker to help streamline our process for creating assets at different native resolutions. The upshot is we have the assets. The downside is now they can’t be used as-is. I don’t have a ‘swf generator’ to generate iphone, retina, and ipad resolution swfs. So right now it’s looking like it’ll be a completely manual process of us creating separate swfs for each platform/resolution. Of course, if our swfs were 100% vector graphics, this wouldn’t be an issue :).

I’ve pondered some possible solutions, but haven’t experimented with any yet. One idea I had after browsing some of the source was using the ‘scaling’ feature of gameswf to scale the rendering of swfs, but inside the actual flash files do some actionscript magic to display the correctly sized graphics in the UI. Not sure how much tedium this would save in the long run without some sort of automated way to do this. On one hand, Adam or I would be laying out 3 individual flash files to be used. On the other, we’d be laying out a single flash file but then I would be scripting the resolution changes in the file itself. I would have to come up with some sort of ‘utility’ style movie clips in the flash library to help with this, but maybe it could work better than managing 3 files for every UI screen?

Scalability

Given the tests I’ve done so far, there’s nothing there that has lead me to believe that doing a commercial quality game on the iphone/ipad with gameswf isn’t possible. In fact, I’m sure it’s probably been done by now and it just hasn’t been talked about? Which is kind of strange, considering how awesome it is. But maybe that’s just me geeking out. This isn’t so much as a concrete downside as it is more of an ‘unknown’. My concern is once we’ve got a lot of in-engine animations/particles running how will it fair with a flash player running the UI. The other caveat is Outwitters lends itself really well to this type of setup as it’s not a very fact paced game. So this solution might only be feasible for particular types of games (in the same way that using UIKit and CoreGraphics instead of OpenGL is feasible for some types of games). I guess only time will tell.

The Upside

Some of the positives of using gameswf particularly:

Lazy loading of images

When a bitmap is being rendered inside gameswf, the texture isn’t sent to openGL until the first time it is drawn. It’s a nice thing to know. We can kind of ‘stuff’ our flash files with image assets and not worry about them taking up tons of memory at runtime as long as we don’t render it all at once. This is useful for HUDs that are themed, in our case, by team colors, shapes, and logos. A point of caution is the the image *isn’t* unloaded from memory (even if you call an unloadMovie() from ActionScript on an externally loaded flash file).

Auto-rotation support seems feasible

Prior to this development I haven’t really considered doing anything too extravagant with support for auto-rotate. If we did support it, it would simply switch to the correct orientation and be done with it. But now it seems pretty trivial to have the UI do a fun but subtle animation as it stretches, squashes, or moves over to accomodate the different screen real-estate. It’ll be a ‘nice touch’ if we get that working.

It isn’t an all-or-nothing setup

Giving the sample project of gameswf for iOS a quick look it seemed at first that running flash was an all-or-nothing deal. It was initializing in the main method and pretty much took over how things were rendered onto the screen. This part was time consuming but after experimenting around with it a few days, I got gameswf to play nice with my already established framework for game screens and UI. Each screen in our game is just a subclass of a ‘Screen’ class that houses ui widgets and any logic particular to that screen. I was able to refactor a few things, and now I have just a subclass called ‘FlashUIScreen’ that takes in a flash file name and a ‘controller’ class as constructor parameters. It now functions and renders identically to anything I previously did. The point being, that if the need arose for something to render in-engine (perhaps using game assets already in memory for some sort HUD) I can still fall back to my previous method of hand coding UI. Hopefully that will be the rare exception than the norm.

Some Things To Know

It’s been a quick 2 weeks since I decided to investigate it and there’s still a few things left to answer, but currently I’m moving forward with the assumption we’ll be using gameswf for this project, and that is a fun thought to entertain :). For anyone else that is curious on getting gameswf up and running here are just some things I ran into while working with it:

If you’re loading separate movie swf files you’ll need a separate gameswf::player instance. I first went with the approach of having a single player and calling load_file() on anything I needed to render because I didn’t completely understand the relationship between a player and a gameswf::movie isntance. But the player tends to house the actionscript VM for a “root movie”, so loading 2 movies from a single player gave me some wonky actionscript behavior.

If you delete all the gameswf::player instances at any point in time, the library goes through a ‘complete clean up’ phase of gameswf. This game me some issues when I would transition from a main menu to an all OpenGL view (no flash UI) so the swf players were delete, and when I went back to a flash-based menu the app would crash with an EXC_BAD_ACCESS error. I got around this by instantiating a single gameswf::player instance that didn’t load any files and is held in my singleton service-based class. It’s only ever deleted when the app shuts down.

Getting the GL state setup correctly was probably the most time consuming part. The library worked great in isolation, but when combined with the framework I was working with, there were all sorts of states I had to track down in order to render a flash file and still be able to render openGL correctly right after. Below is just the snippet of the code I wrapped around a flash movie’s display() method.

Somethings to note, it likes a blank projection matrix (had to reset it to an identity matrix) and you have to disable a few client states in order to render flash properly. Once, you leave the display() method you need reset your gl color, blend functions, and possibly any other states you have may used with the assumption that they are enabled:

[code]
const int w = GetDisplayWidth();
const int h = GetDisplayHeight();

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
_movie->set_display_viewport(0, 0, w, h);
_movie->set_background_alpha(0);

glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
_movie->display();
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
SetGLColor(1, 1, 1, 1);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

[/code]

And with that, I’m off to do some more work on Outwitters. Adam and I just played a few games over lunch and I actually WON. Mark this day, for this is the first day I didn’t get completely rolled in my own game.

So what’s new in the world of OML and Outwitters? Not much really. Just keeping our heads down and working through some of the boilerplate stuff. We iterated a bit on the prototype over the week for visual elements to help make the game more approachable. I got my feet wet in Google App Engine and threw together really basic asynchronous functionality into the prototype in about a day just so I have a clearer understanding of how those things are going to work. Best way to figure out how to do something is to just do it sometimes.

The next thing I’m focusing on is UI and UI tools. In Tilt to Live I had a lot of fun coding up a basic UI system that allowed for easily adding transitions on a per element basis. The problem? modifying the UI was extremely cumbersome as it required a code change and re-compile. Not to mention there was no visual aid in laying it out, so beyond just looking at jpeg mock ups in photoshop, there was a lot of trial and error in getting things lined up correctly. The “screens” are still organized as a stack. You can push new screens on top, remove then, etc. This setup makes it much easier in handling things like “going back”,  switching game state, or handling pop ups.

I’m using a similar system for Outwitters again with a few modifications. I’ve separated out the UI logic from the Screen class into a controller class for a more traditional MVC setup. So now layout data (even if it’s still c++ code) is separate from UI logic and I can edit it with reckless abandon.  This also opens the door for making the layouts data driven. I can put together a layout tool that allows me to visually layout elements on a screen and save them into some sort of format for the game to load up and attach a controller to. This by itself would really help speed up the process of creating the UI we need for the different elements in Outwitters, which is a bit more UI heavy than Tilt to Live.

Yet, I’m wanting to take it one step further and allow me to author transitions in the tool so the UI can be animated in a similar manner to how Tilt to Live’s UI worked. This would be a huge boon and allow us to create fancy-shmancy UI presentation without all the verbose function calls I previously used to achieve the same effect. I guess at this point it’s just a matter of deciding “how detailed” I want this tool to be in terms of animating the elements. There’s no way I’ll be able to achieve the fidelity of what a flash powered UI with an actual artist/animator can achieve, but hopefully it will still be better than the basic ‘powerpoint presentation’ feeling I get when I play some games.

I’ve been looking at “off-the-shelf” solutions of flash integration recently and I haven’t found anything that’s been satisfactory. Usually, there’s a huge gotcha in the free/cheap areas (incomplete implementations, or said to be buggy) and in the commercial market, it’s just too cost prohibitive for a small team to use (looking at you, ScaleForm). Yet, like many things, I won’t truly know the extent of what GameSWF can do until I give it a try. I suspect it’s using standard OpenGL, but looking around there seems to be an iphone compatible version floating around. Just briefly glancing around the net on discussions about this topic, the arguments seem to be wishy-washy. There’s mentions that it’s usable for UI, but actionscript support is spotty in a few places. Seeing that all I want is a way to animate bitmap transforms easily, and get callbacks for taps on menus, my requirements hopefully aren’t too strict. The few that have reported back on their success/failure of using gameswf seem to be stating that writing UI may require scripting, which isn’t friendly to artists. Since I’m handling a lot of the UI work, it doesn’t seem like a huge hurdle. Performance has been listed as an issue, but that was pre 3G.

In any case, I’ll be playing with gameSWF over the next couple of weeks and report back, while we continue work on game balance for Outwitters. If it doesn’t work out, I’ll continue on with my original plan of writing a custom tool for my specific UI needs. Next week is lots of playtesting, tweaking, and also fixing some Tilt to Live bugs!

As we’ve announced on the OML site, our new game has a name: Outwitters. It’s been quite busy for the last couple of weeks, but I’m loving it. Being able to tackle new problems and going outside my comfort zone in terms of game development has been pretty fun so far. I’ve never coded a turn-based strategy game from start to finish, so I’m having to learn a slew of new concepts and design patterns to help mitigate the complexity of the game’s rules. I’m usually coding physics-based dynamic gameplay where things are far less rigid and you are coding a vague system of rules the user can easily manipulate.

A hurdle I recently got over was managing the complexity of all the animations Adam is churning out. We have quite a few frames of animation that needed to be edited in bulk with all the color permutations and classes. With the help of Blitzmax, Photoshop scripting, and TexturePacker, I set out to write a simple character animation editor that allows us to edit one animation and apply it to all the different team colors and different resolutions (iphone,retina,ipad). Also when new units are done and ready to be animated, the editor automatically generates stock animations for each new character so we’re only going in and adding in a few frames and tweaking timings in some of the more elaborate animations.

The art pipeline  process for characters has become:

  1. Run a photoshop script to process all PSD files to convert layers into separate pngs in set folders.
  2. Run a command line script (written in blitzmax actually) that takes the pngs and automates TexturePacker to spit out spritesheets and json files for all the different resolutions into a designated folder
  3. Open Character editor, and if it’s a new character go to file->initialize character and all the stock animations and animation files will be generated based off the pngs and json files in the chosen folder
  4. do any manual edits to animations in the editor itself
  5. File->save and go celebrate since you’ve just processed a couple thousand files in about a minute.

I probably could have automated step 3 itself, but since one of us is usually going straight to the editor to edit the new character, it’s just an extra click so I took the lazy route there.

 

We hit another major milestone earlier this week with the fully playable ipad prototype finished with our first iteration of the UI/Interaction. So now we can get a decent number of games played. This’ll hopefully help us get a good amount of feedback on balance, game rules, and how usable the game UI is, while working in parallel on some of the ‘shiny stuff’ for the game. Lots of progress in the past week! Now I’m going to scurry back to my cave as there is still lots of science left to do…

 

Wow, time flies when you’re busy. As seen on the OML site, we’ve announced we’re working on our next game. With that out of the bag, I’ll probably be blogging about the progress of it, obstacles I run into, and things that are helping us along with the development that might prove useful to other iOS devs. With that, the first major issue we’ve come across is trying to develop 2D assets for a game that is planned to run in 3 different resolutions.

The first step to working around this problem is having your art assets in vector form. Adam uses Illustrator and Flash to do pretty much all of our assets. This is great because we don’t lose any fidelity in assets when resizing them. The alternative for those that are doing raster-only would be to to develop assets at the highest res and shrink them.

When working with a ton of assets, a major pain point came up when we wanted to export a set of images for the different devices (iphone, iphone retina, ipad). The process was very manual:

  1. Create an action to resize our asset to the needed size. Save it.
  2. re-use the action on each individual asset to get the 3 different sizes.
  3. rinse-repeat anytime an asset has changed

The above process worked for us more or less for Tilt to Live because the assets were less numerous and not much changed. But it doesn’t scale. Any programmer will see that this should be automated. But then the problem is audience, as the user of this script/automation will most likely be the artist….who happens to be on windows. So what to do?

Are You Using Smart Objects?

During GDC we met up with the awesome Retro Dreamer guys, Gavin Bowman and Craig Sharpe, and had a discussion on asset generation while riding back to the airport. The idea of Adobe CS’s new-ish “smart object” feature came up in conversation, and was something we looked into recently. Another thing that I discovered was the whole world of scripting in Photoshop. Not actions recordings, but full on javascript/VB/AppleScript support. So I took those two ideas and ran with it, and we came up with a pretty basic asset pipeline for getting our assets ready to be used in the game.

Using smart objects has some pretty cool benefits, which you can read about here. The biggest benefit to us was that the assets weren’t rasterized until saved as PNGs. So whether we blew our assets up or shrank them, it made no difference in quality. This tiny aspect helped a bit later in our script. The other neat benefit of smart objects is being able to link them to allow you to update all your instances with a click. We don’t use this feature ourselves, but it’s something definitely worth knowing about. John Nack has a brief post about this feature if you want to know more (as well as a mention of an obscure PS feature called ‘PS variables’, which seems it could be rather useful). So how do we use smart objects? Adam does his magic in illustrator, then pastes an illustration into a psd file in photoshop as a smart object. This becomes a ‘master’ file of sorts.

Yummy Scripting in Photoshop

Now onto the scripting part. We could have used actions, but it didn’t really allow us much flexibility in where assets go, what they are named, all in 1 pass instead of having an action for each resolution output. I decided to use javascript, mainly because it works both on Mac and Windows, and I was a bit more comfortable using it. The script is rather straightforward in that it prompts for a directory selection, creates a ‘pngs’ subfolder in it, and then scans it for psd files. Any files it finds, it’ll then take the original psd with the smart object, save it out as ‘pngs/whatever_iPad.png’, shrink it by 60% and save as ‘pngs/whatever.png’, and finally blow it up by 200% and save it as ‘pngs/whatever@2x.png’. Nothing too mind blowing here. You can find the script in full at the bottom of this post if you wish to try it yourself.

So why not use something like ImageMagick since it’s a simple re-size?  A few reasons:

  1. It excels as a command line tool for the most part. command line sucks on windows, and if your artist isn’t comfortable using one, it’ll just be another pain point.
  2. Scripts that are native to photoshop show up under File->Scripts. Click it, and it runs. No prior setup. No ‘cd’ing into a current directory or typing in parameters, or trying to code up a custom UI. Very quick to knock together scripts.
  3. The biggest reason is the power these scripts grant you. You have access to a lot of internal data about the current file you’re working with in a very manageable way. We’ve  brainstormed some ways to help automate animation exports from any hand-drawn animations Adam has done by organizing the layers into groups and having the script run through the groups to get the necessary frames out (again, in all 3 resolutions).

So now with the click of a button and a folder selection I can generate the different asset sizes I need for the game. Still a bit tedious if you have to do it for each folder, yes? It’s trivial to add recursive folder searching, and is something I actually did. Now I can simply click our root project folder and regenerate all of the game’s asset in one go, without human error.

Just to show how simple it is to do resizing here is a snippet of the ‘meat’ of the script. ‘saveImage’ is just a 5 line function that outputs the image to a PNG:

[javascript]
var fileList = GetFiles(docFolder,myPSDFilter);
for(var i = 0; i < fileList.length; ++i) {
var file = fileList[i];
var docRef = open(file);
var docName = docRef.name;
var oldWidth = docRef.width;
var oldHeight = docRef.height;

var fileNameNoExt = docName.substr(0, docName.lastIndexOf(‘.’)) || docName;
// save out ipad 1x size
saveImage(pngFolder, fileNameNoExt+”_iPad.png”);

// save out 60% size for iphone
var iphoneW = Math.ceil(oldWidth * .6);
var iphoneH = Math.ceil(oldHeight * .6);
docRef.resizeImage(iphoneW,iphoneH,72);
saveImage(pngFolder,fileNameNoExt +”.png”);

// save out double that size
var retinaW = iphoneW * 2;
var retinaH = iphoneH * 2;
docRef.resizeImage(retinaW,retinaH,72);
saveImage(pngFolder,fileNameNoExt+”@2x.png”);
docRef.close(SaveOptions.DONOTSAVECHANGES);
}

[/javascript]

Now I had made a point earlier about how using smart objects gives us more flexibility in the script, and the above script shows why. It was more straightforward to go from ipad to iphone (an arbitrary percentage) and then double whatever the iphone size is for retina, instead of calculating each separately. You wouldn’t be able to do that with rasterized images. Another nuance in there is the use of Math.ceil(). When shrinking by a fraction you can end up with non-whole number dimensions, and photoshop truncates the number. This can lead to weird retina resolutions that don’t have even-numbered dimensions (one pixel off).

No Vector Graphics? No Problem!

Now even those people that are using raster graphics aren’t completely left out in the woods either if they want to shrink then grow their assets. For our animation script I had to deal with raster-only graphics but I wanted to keep the same “shrink to iphone then double” procedure. The problem would be that going from iphone to retina would cause blurry graphics. Not so, if you look into using historyStates in your scripts! Here’s the same basic procedure as above except used in raster-only graphics:

[javascript]
var docRef = open(file);
var docName = docRef.name;
var oldWidth = docRef.width;
var oldHeight = docRef.height;

var origState = docRef.activeHistoryState;
// save out ipad 1x size
var ipadW = Math.ceil(oldWidth * .5);
var ipadH = Math.ceil(oldHeight * .5);
docRef.resizeImage(ipadW,ipadH,72);
saveImage(ipadFolder, docName);

// save out 60% size
var iphoneW = Math.ceil(ipadW * .6);
var iphoneH = Math.ceil(ipadH * .6);
docRef.resizeImage(iphoneW,iphoneH,72);
saveImage(iphoneFolder,docName);

docRef.activeHistoryState = origState;
// save out double that size
var retinaW = iphoneW * 2;
var retinaH = iphoneH * 2;
docRef.resizeImage(retinaW,retinaH,72);

saveImage(retinaFolder,docName);
docRef.close(SaveOptions.DONOTSAVECHANGES);
[/javascript]

Notice in the last resizing batch I set the docRef’s activeHistory state to the original State. This is effectively automating an ‘undo’. I reset the graphic to be the super high-res ipad2X size and then shrink down from there again. No blurry graphics! Hurray!

I’m planning on looking into scripting possibilities in flash as well, as automating our exporting for that would be a huge help there too. But for the time being those are exported as a png sequence, and then another photoshop script goes in and organizes the 3 different sizes in 3 different sub-folders. Nifty, eh?

The last step in this pipeline is creating texture atlases, and is something I’ll be automating as well in a couple weeks time possibly using Texture Packer’s command line interface.

Here is a download link to the script in full in case you want to try it out, change it, tailor it to your needs, go wild:

geniOSAssets

My first GDC conference was an awesome experience! I’m sure my head exploded multiple times throughout the week attending talks, meeting awesome people, eating great food, and a bit of sight seeing around San Francisco. Unfortunately, I came down with a double whammy of the flu/cold and bronchitis. Being ill the last couple of days of GDC were pretty miserable, but I was able to keep my head up for the rest of the week and try to enjoy what little I could. The flight back felt like a death sentence though. It was a bit of a downer coming back from GDC so energized and ready to work only to be out of commission for the next week and a half recovering from bronchitis (the cold symptoms went away a couple days after getting back).

In any case, I’m finally able to work (and write!) again this week with only minor coughing fits. And there is so much to cover, but being my first iDevBlogADay in a long time I’d like to focus on a little problem and a possible and exciting solution facing a lot of indie devs these days.

Multi-platform support.

Keep in mind, as I write this I’m thinking from the perspective of an iOS developer looking to branch out. One of the biggest successes in the past couple of years is the explosion of devices that have become accessible to indie developers to make games on. Yet, one of the biggest downfalls is tendency for the software/hardware vendors to do what they can to create ‘vendor lock-in’. Apple iPhone with Obj-C, Microsoft windows phone 7 with C#, Android with Java (and the fragmentation of hardware within this ecosystem). I’m not going to speculate whether this ‘lock-in’ is a priority/intentional, but it’s a factor nonetheless when developing these days.

Even now, as an indie dev I’m still primarily focused on iOS development because it’s what’s working for us. I’m sure if I started out on Android (and I almost did a few years ago when deciding between getting an iphone or a G1) we may have the same but opposite opinion looking from the Android world. Yet, as I work on iOS games it’s becoming increasingly harder to ignore Android as it becomes more prevalent in the market. Lately, I’ve been trying to keep tabs on different technologies to hopefully allow me to keep development of our games in-house as much as possible.

I got into this line of work because of the joy I experience creating, developing, and releasing games. I would hate to see a future where I’m simply orchestrating contractors to port our games to platforms x,y, and z. Going along with Joel Spolsky’s advice, I’ve always had an aversion to outsourcing our core competencies:

If it’s a core business function — do it yourself, no matter what.

Pick your core business competencies and goals, and do those in house.

 

I think there’s an unstated assumption when talking ‘multi-platform’ with iOS devs that what they really mean in general is iOS + Android. It’s still a shame that to go to Android pretty much means “Hey, I don’t care what language you wrote your game in, re-write it again…in Java…muahahahahah”. In fairness there is something called the NDK that seems it might be feasible, but I haven’t look too far into it. Despite me wanting to keep development in-house, I think Android may be a lost cause without 3rd party engine or library support that will allow me to abstract away the platform I’m writing for. Tons have been written on Unity 3D so that’s not what I’m interested in. In fact, Unity3D’s 2D support is still lacking (though they have plans to improve this soon). What I am interested in keeping an eye on is Monkey.

Monkey

Why? It’s written by Mark Sibly, the man behind Blitz Basic and Blitzmax family of languages. Coming from Blitzbasic and Blitzmax, I’ve become quite jealous when working in plain on Obj-C or C/C++ because these languages weren’t designed with ‘game development’ in mind. The biggest plus that came out of Blitzmax was true cross-platform compatibility. I can write code, compile it, and run it on Windows, Mac (Intel/PowerPC), and Linux.  And true, the same can be said for C/C++, but the brilliance is you don’t have to think about it ahead of time. I’m currently writing some game framework code for our next project and I’m constantly having to ask myself, “What platform is this code specific to and what do I need to abstract away?”.

I’ve written networked, multiplayer games in isolation on Windows with Blitzmax only to drop the source on a Mac, compile it and instantly have a native mac client play against a windows client. This is the dream setup for mobile devices, and it something Mr. Sibly seems to be striving for with Monkey. Monkey allows you to create games for iOS, Android, Flash, HTML5, and even XNA with hopefully the same ease. While I’m only playing around with it right now, I’d love to see this get wider , more serious adoption as it’d be harder to be held hostage by a single platform, but still have more ‘lower level’ access to writing a light game instead of using a massive engine and workflow like Unity. The HTML5 demo was pretty mind blowing as to what can be done in modern browsers now, and you can try out a bunch of the HTML5 monkey demo apps here.

I’ve actually even went the route of writing some of our first tools for our next game in Blitzmax. Adam is on a Windows machine and I work primarily on a Mac, so having tools for both OS’s without having to write anything for a particular OS was a nice plus.

I’ve pretty much resigned myself from re-writing games from scratch for Android. In order to target Android in-house I feel I would have to write the game in a higher-level language or toolset (be it Unity or Monkey) to make it worth it. I think going forward any indie has to think long and hard about their target platforms they wish to hit before writing a single line of code, because once you’ve started on one path you might not be able to turn back easily. The work I’m doing now is to allow us to move our future games to other C++ friendly platforms like Mac/Windows, which I think could be pretty exciting. In the meantime, I’ll be monkeying around with Monkey.

 

Seems this past week I’ve been slammed with a ton of stuff. Had to take a breather, step back and get a bit more organized to gain some perspective. Tax season is in full swing, so that’s always biting at my ankles as this is my first year filing as a self-employed tax payer. Tilt to Live Viva la Coop is close to being live on the app store (hopefully), and HD will be followed up shortly after. In the meantime, I’m tasked with starting a brand new project, and it’s an exciting one indeed. The biggest hurdle so far is trying to mitigate the second-system effect. With all the problems encountered developing Tilt to Live, I want to try to get rid as many of them as possible the 2nd go around. Yet, trying to eliminate all of them doesn’t seem like a wise choice because even though there were a few ‘snags’ in developing TTL, they weren’t big enough problems that would justify going out of my way writing custom tools, scripts, or whatever to relieve them.

One of the bigger problems (or a possible non-problem depending on where we go in the future) was the realization of how locked into the app store and iOS system we were. Tilt to Live and it’s HD counterpart were pretty much written in pure Objective-C. Very little constructs of C or C++ were used. There were only a handful of structs for networking, and vector functions, but that was about it. When faced with the decision of wanting to try out the game on different platforms, it was a non-starter as all the gameplay code would have to be rewritten in C or C++ (of course Android is a beast on it’s own using Java). It wasn’t a problem at the time because we were focused on simply trying to succeed in the quickest and easiest way possible. But looking forward, I’d like to have the option to go to another platform without the pain of starting from scratch.

GDC is looming around the corner, and it’s really exciting to think after so many years of following GDC in the news I’ll finally be going to this awesome event not as just a spectator, but as a game developer. Exciting times indeed.

Tilt to Live HD’s Viva la Turret mode is now live and people seem to be enjoying it. One of the bigger hurdles in this prior update was getting in app purchases to work the way we wanted them to without violating the standard user experience of IAP. I figured I’d share how I went about solving this for Tilt to Live HD specifically. We had a few business goals in mind:

  • We wanted to maintain parity with the upgrade model we went with on the iPhone, which was a simple in-app purchase to get the new mode.
  • We still wanted to maintain the ‘demo then upgrade to full version’ packaging of Tilt to Live HD for a single price, as we still believe it appeals to a certain type of gamer that wants a more traditional model for buying a game.

In a way, it seems our two goals were at odds with each other. We wanted players to have an optional upgrade, but at the same time we didn’t want the ‘full version’ to break down into “meh..it’s kind of the full version..but not really”. Our solution was to treat it as a paid upgrade for existing users, but bundle the new mode in with any new customers who bought the full version of Tilt to Live. The caveat being we did not want to break it down into some sort of ‘store’ list, where a user could inadvertently end up buying the wrong version and be double charged for overlapping content. We were pretty proud of the IAP integration in HD where it was a relatively seamless experience that didn’t involve any UI that required a “store” button. We simply showed you the gametype option and it was locked if you didn’t have it, and unlocked if you did.

With the additional new mode, we now had 3 basic states you could possible be in.

1. You have the demo version of Tilt to Live HD, so the gametype select screen is pretty standard and you see 1 in app purchase that includes everything:

2. You have the full version of Tilt to Live HD prior to February 8th. The gametype select screen should show you just the small IAP for the single Viva la Turret game mode:

3. You have the brand new full version of Tilt to Live HD, so everything is unlocked:

Now this sounds all well and good and pretty straight forward when I first considered it. Then came the technical details:

  • The behavior of IAP is such that it mirrors functionality like App Store purchases. If you’ve ever bought that IAP before, you can buy it again, but a pop up will notify you that you already own it and are downloading it again for free.
  • If a person has never restored, then simply checking what modes in the client are unlocked is sufficient and is the path of least resistance.
  • If a person has restored/re-installed, there is no API from Apple to determine if a person has already bought a piece of content before they try to buy it again, which could result in angry customers being double charged if they were in state #2 (pictured above) but have re-installed and ended up buying the full version again as if it was in state #1 (pictured above).

Essentially, when a prior customer re-installs our game for whatever reason, there was no way for me to determine whether they never bought the old full version and we should upsell the entire new full version, bought the old full verison and we should upsell just the game mode, or if they already have the entire thing unlocked (either by buying the old full version + the turret IAP or by buying the new full version that includes everything). Confused yet?

The riskiest thing was that I did not want to have a situation where a person could inadvertently buy the entire brand new ‘full version’ IAP when all they needed to buy was the small turret IAP. With the StoreKit API lacking any sort of method to determine a user’s purchase history, and with Tilt to Live HD not using any sort of server solution to track receipts,  I was running out of ideas. Then I got the idea of experimenting with a little “hack” to simulate the same IAP experience.

When a user taps on the ‘buy’ button for any IAP in the game I decided to instead force it to restore purchases all the time. Using a small collection of state variables when a restore was finished I would check to see if what they were purchasing was in line with what was restored:

  • If so, do nothing and give a standard dialog showing they restored successfully.
  • If it was in conflict, let them know nothing was purchased but their previous items restored. I would then refresh the upsell screen showing what they could really purchase.
  • If there was no conflict and they, in fact, don’t own any part of the IAP, then I would immediately push the purchase through. The great thing here is since it happens right after the restore, the user is never prompted for their password again since they already did so during the initial tap of the buy button to trigger the restore.

When going about implementing this I had a few false starts and dead ends, but after re-reading the documentation and a bit of experimentation I finally grokked most of the restoration API from StoreKit.

There are two methods involving the end of restoring tranactions. There is one that is called at the end of each IAP item restored:

[code]
-(void)restoreTransaction:(SKPaymentTransaction*)transaction
[/code]

And then there’s a method that is called when none, or all IAP items have been restored:
[code]
-(void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
[/code]

The former I left alone to act as it normally would under any restoration of transactions. The latter method, I modified to behave as an ending point if the user really tapped on ‘restore purchases’ or a beginning point to analyze what was restored and to continue with the purchase if needed. Below is the method in full in case you’re curious:

[code]
-(void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
if(iapTransactionState == kIAPTransStateRestoring) // restore as is.
{
[[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseRestoreSucceededNotification object:self userInfo:nil];
}
else if(iapTransactionState == kIAPTransStatePurchasing)
{
if([self isContentUnlocked:purchaseItemID])
{
// if it’s been restored or unlocked already then no need to do it again.
[[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseTransactionAlreadyHaveItemNotification object:self userInfo:nil];
} else {
//…unless we’re already in some half-bought state (full -> full+turret)
bool makePurchase = true;
if([purchaseItemID isEqualToString:kIAPFullAndVivaLaTurretID])
{
// if after restoring we found the player purchased the full and viva separately
// don’t go forward with payment for the bundle.
if([self isContentUnlocked:kIAPVivaLaTurretID] || [self isContentUnlocked:kIAPFullVersionID])
{
makePurchase = false;
#ifdef DEBUG
NSLog(@”bundling purchase error”);
#endif
}
}

if(makePurchase)
{
// continue with the purchase
SKPayment *payment = [SKPayment paymentWithProductIdentifier:purchaseItemID];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
else {
// send a bundling error message
// or a restore complete if they have entire bundle
// because they purchased it separately (upgraders)
bool hasBundle = [self isContentUnlocked:kIAPVivaLaTurretID] && [self isContentUnlocked:kIAPFullVersionID];
if(hasBundle)
{
#ifdef DEBUG
NSLog(@”has complete bundle, no purchase made”);
#endif
[[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseTransactionAlreadyHaveItemNotification object:self userInfo:nil];
}
else
{
[[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseTransactionAlreadyHavePartialBundleNotification object:self userInfo:nil];
}

}

}
}
#ifdef DEBUG
NSLog(@”restore done”);
#endif
// [[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseRestoreSucceededNotification object:self userInfo:nil];
}
[/code]

I can’t say this is the most ideal solution since I feel it’s using the StoreKit API in a slightly unorthodox way, but it works well. So this is one way of implementing a ‘paid upgrade’ for IAP items. If we were selling more items in a more ‘freemium’ type model it might’ve been a good idea to generalize the above code to handle upgrades for any item, but since Tilt to Live HD’s model is a one-off IAP I didn’t bother generalizing.

I’m still in the middle of finishing up our Co-op mode for Tilt to Live and coding in the last odds and ends to polish up the UI. The gameplay rules have be finalized and it’s been a hoot to play. Yes, I said hoot. We’ll be playtesting the mode in the coming weeks to do any minor tweaking to the physics and balance.

The wireless P2P GameKit API has been pretty cool to work with. It certainly takes a bit longer to get something tangible out of it because it’s a relatively ‘invisible’ piece of the iOS SDK  (as opposed to Core Animation, UIKit, and the like). Yet there’s always something inside me that goes “that is so damn cool” when I finally see a game running on two separate devices and are interacting with each other.

I’d like to write up a mini post-mortem after the co-op update is done looking back at adding real-time networked play to an iphone game. But for now, the biggest hurdle was realizing that running with the GKPeerPickerController  limited you to only bluetooth. The docs weren’t 100% clear on this and I was beating my head on my desk seeing people claiming GameKit worked over Wi-fi with no issues and I couldn’t get any device to talk to each other without bluetooth. Couple that with a faulty router setting keeping my iDevices from connecting to each other and it was a painful couple of days. In any case, let it be known, that if you wish to support local Wi-Fi and Bluetooth transparently you’ll need your own custom UI outside of GKPeerPickerController for clients connecting a host.

Oh, and the utter joy I experienced when I realized I had to change zero networking code to have it work over w-fi was indescribable. I think I fell in love with GameKit at that point since I was anticipating  a day of refactoring, integrating bonjour directly, and whatever else I had in mind to keep the game-level networking code intact.

For anyone thinking about doing some real-time multiplayer game on the iPhone, the biggest problem you’ll probably face is interference, followed by throughput (when dealing with bluetooth anyway). iPhones are jam packed with so much wireless technology that it seems if the wifi or 3G antenna so much as thinks about sending or receiving data, bluetooth communication suffers horribly.  I’ve had many a game end in death when I received an e-mail or text during gameplay. We originally intended on supporting nothing but bluetooth, but given this type of wildly varying performance we needed to have a fall back solution that was a bit more reliable. Thankfully, GameKit made it easy. While I was hoping I wouldn’t have to code up a custom UI (pictured above) because of GKPeerPickerController’s magic, in the end it added more robust functionality, as well as felt a lot more integrated into the game.

Wow, last week was an intense week, focusing on pretty much Tilt to Live exclusively. Took a nice break/road trip up to North Carolina to do a bit of snowboarding to cap off the week. Conditions weren’t that great, but it was close, cheap, and still fun versus going back out to Colorado. Back today somewhat recharged and ready to go. Haven’t had time to work in Blitzmax at all last week, I hope that’ll change after this week as well.

I’m planning on doing a redesign of my blog as well. I like the theme, but the really thin layout and bad font choice hurts readability. When the RSS feed is more pleasant to read there is something wrong. I may simply just widen the template, and pick a more readable font. Hopefully after that it’ll be more functional.

I haven’t done anything concrete yet, but I know for our next game we’re going to look into using Google App Engine for some of the functionality, as well as Push Notifications.  Ken Carpenter over at Mind Juice had a really nice write up about it. it’s pretty exciting to see how large scale technologies are becoming affordable for even 1 or 2 man shops. Trying to launch a game with a potentially huge influx of users and data use to be only in the realm of studios with large amounts of funding.

The news that Garage Games is back and is going to continue to sell their Torque line of game development tools is great to hear. I used TorqueX to develop Gunstyle on XNA and it was a blast. Torque2D seems really appealing to look into for development on the PC/Mac platform. iTorque2D looks neat, but I’ve heard performance had been an issue for it.

2D engines are a weird beast because their on the edge of that line where the trade off between rolling your own or just buying a package seems very even. I know from experience in TorqueX, the fidelity of control you get content-wise is amazing, but a lot of low level details tend to be out of your grasp without a large investment in modding the source itself. I recall having to write my own map editor, despite the awesome 2D editor in TorqueX, simply because I didn’t have access to the tools to create the physical geometry needed by our game. So creating a level ended up being a two step process of having a level designed and laid out with all art assets and trinkets in the Torque editor, but then loading that into a bare-bones homemade editor to add in the physical geometry for the levels. And this all arose out of a really basic limitation of the T2D editor not allowing the creation of concave polygons with their line editor tool. Surprisingly looking at Torque2D for Mac/PC this doesn’t seem to be the case.

It’s very true that these engines will get you 90% or even 99% of the way there, but then there’s this one crucial element that typically is what is unique about your game or game’s data that the engine simply has no way of accomodating. Looking back, I think it was a nice motivating factor that getting the game setup on just pure TorqueX and having it look great with minimal effort was awesome. The rest of the development cycle was spent bending the engine to our will.