Jul 15

Wow, Friday almost flew right past me. I’ve been working on Outwitters practically non-stop. A lot of the major ‘components’, as I like to think of them, have been figured out and implemented in some sort of fashion. Now I have to make this big herculean effort to get it all integrated and seamless:

  • 1v1 and 2v2 pass-n-play
  • A couple of teams and their animations and unique powers
  • The ever crazy complicated (implementation-wise) UI
  • Asynchronous play using Google App Engine

Aside from team animations/powers, all those things exist in kind of their own isolated ‘prototypes’ in one way or another, and now I’m trying to get it all under one “roof”.  Our 1v1 and 2v2 pass-n-play are fully functional. We’ve had a few playtests of the 2v2 game mode with family and friends and it’s been a sigh of relief to see them genuinely enjoying themselves. Sometimes, you don’t have to look at the actual game to see if the player is ‘getting it’, just looking at their laughing faces as they all play against each other is vindication enough that you’re on the right track. The bigger task at hand his trying to make this game as close to engaging as possible in the asynchronous model as it is when in a small group of players. Realistically, we’ll never achieve that, but it’s something to shoot for.

In other news, I got my standing desk in the beginning of this week and I’ve just finished my first week of ‘standing’ while I work with my new desk. I tried it out first for a week with a small glass-top high breakfast table and liked it enough to invest in an actual standing desk. Of course, I’d like to sit in the evenings so having something adjustable is extremely handy. Noel Lllopis had mentioned his foray into this work style a while back, so I took his and several other dev’s recommendations and went with a GeekDesk, and I’m loving it. With just a couple of weeks of doing it, my back doesn’t feel completely owned every morning when I wake up (I have a bad sitting posture). I find that whenever I’m brainstorming, or thinking about a problem I tend to pace around the room or go to my whiteboard to draw stuff up. While standing, this feels a lot more natural and I tend to move around a bit more during the day. Another plus, is during the mornings I’m finding I’m a little more focused on getting through some of the less enjoyable parts of the job like managing money, bug hunting, etc.

Unfortunately, I don’t have much else to share at the moment other than Outwitters is shaping up to be pretty freaking cool. Only time will tell if we’ll be alone in that opinion.

 

Jul 1

Keep in mind, a lot of the rambling below is in the context of me being neck-deep in working on Outwitters, which is a strategy board game. I’m constantly thinking of ways to present games, their systems, and their objectives to people. Notice I said people, not gamers, or casual gamers. Sometimes I even look around my own environment and question “why the designer wrote that message the way they did”. Sometimes it’s obvious they gave little thought to the message and scribbled it on some printer paper for all to see on their store front. Sometimes it’s spot on and even clever. Other times, I question their decisions:

I’m constantly always surprised by how confusing traffics symbols can be. When your speeding down a new stretch of highway at 70mph you don’t really have a “2nd try” at figuring out what a sign means. Sure, the locals all know that this exit sign is mis-labeled or too close to the actual exit to realistically act upon it, but I’d argue those signs should be made with an emphasis on new people to the area.

The Mistaken Non-Gamer

In any case, I think about this habitually, but sometimes I wonder if it’s even making a difference to a certain segment of the potential audience. I can really only speak from personal anecdotes, but I’m starting to think reaching out to the “non-gamer” crowd is less about how well your UI is designed and more about how socially engaging it is. I will use my mother’s gaming habits, for lack of a better example.

She will not play a new game on her own accord. She does not seek them out, and the usual ‘marketing venues’ one would use to garner an audience for an iOS game completely bypass her and her demographic. I can hand her a game, but she will ‘demand’ that I tell and show her how to play it. If I walk away, she’ll lose interest. If I stay, she won’t bother with tutorials or help menus and simply ask what to do next. For her, games are social experiences and she has to be ‘introduced’ to a game by another physical person who already knows the rules. But once she does understand the game, she’s no less engaged or competitive than a ‘typical’ gamer. Am I crazy in thinking there’s a large segment of the audience like this that is incorrectly labelled as a ‘non-gamer’?

No amount of well though-out UI design, tutorials, or marketing will capture this kind of person. Is this why Nintendo struck gold with the Wii since the vast majority of their mega hits were multiplayer-centric wii games? Were they able to tap the “non-gamer” market by selling an experience that was championed by the gaming enthusiasts who brought home these devices to their curious “non-gaming” family members?

The “Gamer”

Then there’s the typical, mainstream view of a gamer. He/She isn’t afraid of new systems or paradigms. In fact, they seem to be curious and love trying out novel ideas, and don’t require another person to introduce them into the game. When something confuses them, they don’t throw up their controller in frustration, or look to a friend to get an answer immediately. They fiddle with the controls, dig through the menus, and sometimes even go online to find an answer. To them, a well designed UI means something and there’s a tangible benefit in reducing the friction to learning how to play the game.

I imagine they have their limits though, present them with a genre they feel they don’t care for and with a ruleset that takes a little more than a minute to understand and they’ll probably walk away from an experience that might’ve actually been pretty fun. Or, hell, get a console gamer to try to install, setup, and play a PC game and you’ll see what I mean, all before they even get to run the game.

Then there are hardcore gamers who just love the idea of solving problems. Games in themselves largely revolve around this fact, and anything inside or outside the game’s fiction is a problem waiting to be solved. This sometimes borderlines on ‘geekiness’.  Picture the guy that will tinker with his computer for hours to get a game to work. No amount of rules, or depth will deter them from at least trying to get involved in a game they see as potentially enjoyable.

These kind of gamers can introduce games to “non-gamers”, and the great social experience that results is better for it.

Now Back To Design…

For the iOS platform, who do you design for? It seems trying to come up with clever ways to engage the mistaken non-gamers through tutorials and UI won’t help them directly as they depend on social interactions to guide them through a game. Think of new players playing a board game for the first time with family or friends and how that interaction ensues. This is where they get most of their information. Yet, if you design with the ‘non-gamer’ in mind, you’re helping the actual gaming crowd gain easier access to your game, which hopefully will result in them being the person that introduces this game to their friends and families. In a weird way, you’re designing systems and interactions to help someone become a living tutorial for your game.

Does this mean if you wish to target the “main stream”, and as a result, the widest audience, that you should be designing games with social interactions being the core of the experience? It seems a good number of the recent iOS successes are building off of this idea. Given the pressure in most gaming enthusiast circles to always have some sort of solo experience built in, do you even bother with it knowing that most of your “non-gaming” audience doesn’t even care for it? For example, is a single-player mode for Monopoly really necessary? I could never envision my family or friends playing on their own, but put them in a room together and it’s usually a great time.

It’s all interesting stuff to think about as I look at how Outwitters is shaping up to be versus how we originally envisioned it so many months ago. The social experience I think is absolute key in making a game like this widely approachable.

 

 

Jun 17

Tomorrow (June 18th) marks the first year anniversary of me becoming a full-time independent game developer. Wow did the time fly by fast! Over the course of the past year I helped launch Tilt to Live HD, Lite, a couple of major gametype updates to Tilt to Live for free, a paid Viva la Turret update, and finally released a multiplayer co-op mode for both our games. When I think about it that way, it’s definitely been a busy year. I sometimes forget how much content we added to Tilt to Live and Tilt to Live HD, and sometimes I think to myself “man, it’s been almost a year and all we’ve done is 1 game…”.

I don’t think I could think of a more full-filling career than a independently creative one as this. I set my own hours (admittedly probably too many hours), I take days off when I feel I need to or want to. And one of the most fundamental changes I’ve noticed over the months was how I’ve lost track of holidays and weekends. Now that I wake up to go to work (rolling out of bed, freshening up, and walking into the next bedroom) eager and excited for today’s challenges and problems, I’ve found I don’t even care what day it is anymore. In school, and in previous jobs, it was always hard to not think of or be reminded of the next upcoming weekend or holiday. It’s as if people’s lives revolved around them. While I still look forward to weekends because most activities with friends and family tends to be on those days, but I guess I don’t have such a severe case of the “Mondays” as I use to :).

Looking back, if someone was wanting to go the full-time indie path with iOS in mind, what would I tell them?

Don’t chase the fads

If you’re trying to ‘one-up’ a current trendsetter, you’re not ever going to be the trendsetter. Everyone knows about Angry Birds, but you’ll never get that kind of mindshare trying to out-do Angry Birds. It seems to ring somewhat true the iOS market rewards games that bring a bit of something new to the table or ‘best of class’. Games that are top of mind that bucked the trend and did their own thing would be Pocket Frogs (talk about being a trendsetter :P), Casey’s Contraptions (this game fits so well with the iPad, it’s hard to see it not succeed), and Tiny Wings (bird themes aside).

If you have an idea that is a really interesting twist of a current game genre, or a game idea that you haven’t seen executed with much success on the app store you should probably try giving it a go. If the game flops, you’re in the same position as someone who made a ‘trendy’ game and flopped. If it succeeds, you own that niche and the rewards, emotionally and financially, can be great. With that said, don’t be different for the sake of being different. Anyone can look at Tilt to Live and see the obvious influence of Geometry Wars in it. What made it stand out? It used the device’s novel hardware to the fullest, had a non-typical art style for that genre and Geometry Wars wasn’t on the app store yet (phew). Outwitters is the same deal. There are plenty of turn-based strategy games out there already. We just haven’t seen one with our particular brand of humor and art style with a focus on simplifying the strategy element rather than trying to make it artificially deep with tons of units/choices. The takeaway is make the game that you want to make and think could succeed, not the game that the top 10 charts are telling you are currently succeeding.

Shipping a game is half the battle, and I’m not talking about marketing

Marketing and promotion aside, the iOS market has a very different set of expectations when it comes to games. The PC/Console market is very ‘packaged goods’ and ‘pay once’ oriented. We started out with that mentality thinking we would ship and move on. Yet, we’ve submitted probably over 10 updates to Tilt to Live alone, the vast majority of them adding major pieces of content and actually changing the game. The Tilt to Live at launch is no more, and Tilt to Live of today is a rather different game. We added multiplayer in Tilt to Live a year after release. People expect that their games change, and for the better. When scheduling time for a game development cycle, the ‘ship date’ is far from the end of that product’s life cycle. Pocket God is the poster child of embracing this kind of thinking.

The challenge for the developer is trying to find a way to make this sustainable. I think developers are starting to catch on that there is an audience willing to pay for the extra content, so that they can fund even more content for the games that they like. If you’ve got something on the app store people are liking and clinging to, give them more of it! We added a bunch of free content to Tilt to Live, but before moving on we wanted to give players a chance to experience one more idea we had in our heads, but without funding it just didn’t seem feasible so we charged for it. Despite all the flak from the vocal minority, it was successful. Successful enough for us to take the time to update that new gametype with it’s own Co-op mode as a free update. Free updates helps build endearment towards the developer, but it’s a two-way street. Let your customers help support you as well, it is a business after all.

Your first, second, third, or even fourth game won’t “succeed”

It’s hard to speak to this point because I got extremely lucky with Tilt to Live being our first iOS game and also being a decently successful game that allowed me to launch my full-time indie career. But with getting to know other devs in the community, and watching their trials and triumphs, there seemed to be one common factor between the ones that did “succeed”, and it’s not giving up. As cliche as it sounds, it’s hard to overstate that trait. I’ve seen several times throughout the year, a dev that stuck to their guns and eventually one of their games hit a sweet spot and became successful. The ‘overnight success’ I think is a myth that the media tends to give too much credit to and is easy to fall in love with. If you look at the history of just about any of the top selling games on iOS, you’ll find more often than not this person or team has been doing this for years prior, and sometimes in complete obscurity, like us. I’ve had communications with some devs over the months after they launched their first or second game, and then slowly disappeared from the community after those games weren’t break out ‘hits’. I was on about a month long dev cycle for each gametype update on Tilt to Live. I actually believe that had we released each one of those game types as stand alone games, the only one that would have any chance of success on its own would probably be Viva la Turret. So I tend to think of those other gametypes as our small ‘failures’ in a way as they never really became more popular than Classic or Code Red, but we were sheltered from disappointment because they were a ‘side dish’ to the main Tilt to Live game. Not everything will stick, you have to try hard to stay motivated through the ‘low times’.

 

So here’s to hopefully another wonderful year of the indie life!

Jun 3

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.

May 20

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.

May 6

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!

Apr 22

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…

 

Apr 8

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

Mar 25

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.

 

Feb 22

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.

« Previous Entries Next Entries »