Indie Game Development 2012: A Look At My Third Year

by Josh Tynjala

At the end of 2010, I finished the year feeling a little underwhelmed. I earned less from game development in 2010 than I had in 2009—the year I started my indie adventure. I hadn’t found much success in mobile, and I was hoping to take a different approach in 2011. For some reason, I didn’t quite get around to that, though. 2011 became another year of mobile exploration, with some successes that make me pretty happy. Yet, the final numbers totaled up to almost exactly the same as last year’s earnings. Still, I’m a little more optimistic this time around because the underlying trend shows an encouraging shift in the right direction.

The Breakdown

In total, I earned $21,551 from game development in 2011. This includes mobile device game sales, non-exclusive licensing of Flash games to portals, ad revenue from free Flash games, and a couple of small game-related freelance projects (short-term contract work). As always, I’m sharing only my earnings as a game developer. I also work on a variety of other freelance projects throughout the year that are mostly RIAs, and I sell an educational app called Logicly.

Chart of 2011 Revenue, By Type

Let’s start by comparing the differences in the percentage breakdown from last year to this year. Last year, freelance work brought in 79% of my game development revenue. In other words, the vast majority of my earnings came from working on games for other people. That doesn’t exactly matching my goal of eventually going totally independent (or nearly so). This year, freelance work dropped to 14% (again, this is for game development only. RIA freelance projects still make up the majority of my total income). Mobile game sales went in the opposite direction from a mere 8% last year up to 80% in 2011. In spite of total earnings staying nearly the same from year to year, I’ve seen a major shift in what is earning me money, and it grew significantly.

The Best App Stores

Next, let’s take a look at why my mobile game sales increased so strongly. Seeing which app stores performed best should make it particularly obvious:

Chart of 2011 Revenue, By App Store

The device that deserves to be in the spotlight is the NOOK Color (and now the NOOK Tablet too) from Barnes & Noble. As you can see, NOOK apps make up 90% of my app sales. It seems to be kind of a dark horse in the app store world. I think most mobile developers don’t know about the NOOK store, or they haven’t given it a fair look. NOOK readers are very willing to pay for e-books, or they probably wouldn’t have bought the NOOK. I took a peek at some of my favorite novels, and they sell for at least 7 or 8 bucks a piece. An extra 50% or more for newer releases. Compared to that, an app that sells for 2 to 4 dollars is no big deal. This is an audience that seems to be even more willing to spend money than iOS users—at least in my experience so far.

NOOK sales brought in over ten times more than iOS sales, while the Android Market and the BlackBerry PlayBook both got lost miles behind. Neither of those two earned over $200 (although, full disclosure, two of my games aren’t yet out on Android Market and one isn’t on PlayBook yet). The Amazon Appstore for Android didn’t even make the cut. I hadn’t earned enough to get a check in the mail from them by the end of 2011. However, Christmas sales of the Kindle Fire must have been halfway decent. App sales finally started trickling in from Amazon around Christmas. At the moment, my Amazon sales are comparable to my iOS sales. If I were to limit myself to three stores, it looks like NOOK, Amazon, and iOS come out on top, with NOOK being the absolute first priority.

Everything Else

Other revenue either came from small projects, like some portals that wanted an older Flash game site-locked or quick freelance projects that took no more than a day. Nothing significant, but a quick buck here and there for very little effort. To my surprise, ad renveue from MochiAds, MindJolt, and Google AdSense is still coming in. Ads earned me enough to pay my bills for about a month, and I did all the work to make that happen 1-2 years ago. This ad revenue won’t last forever, but it’s nice to have it while it lasts.

Into 2012

The huge jump in sales thanks to NOOK is awesome, and I hope to continue exploring this platform and finding apps that resonate with its unique audience. However, each new release was just a little bit less successful. I was lucky to get in at the very beginning when the number of apps was well under 1,000. As with the iOS gold rush, it was easy to get recognized by potential users because you couldn’t drowned out by everyone else clamoring for attention. Thankfully, as with the Amazon Appstore, NOOK sales spiked on Christmas, and they still haven’t completely dropped back down. There’s still a little time to enjoy the benefits of being an early developer.

My first game, Chroma Circuit, is my absolute favorite of my creations. It wasn’t the very best seller, but the fans it found have some real enthusiasm that is inspiring, and I hope I can find more of them. I’ve been working to release a huge new content update for quite some time, actually. Several new elements are all coded up. Some rotate like the others. Some slide around instead. They’re fun new additions and there are a lot of little animations and things that add to the aesthetic experience that I didn’t have the time/brainspace to add when I first released Chroma Circuit three years ago. The biggest barrier now is building new levels. I built a great little visual level editor (unlike the original version, which had hand-coded XML!), but it’s still a time consuming process, and I don’t want to release anything until I have over 100 levels. I’m at about 60 now, and I think I’m going to set some daily or weekly goals to get me over the last hill and to the finish line.

Other than that, I don’t have many other concrete plans for the new year. I mainly want to continue releasing games that can sell decently as NOOK apps. Whether they’re unique games like Chroma Circuit, or more generic ones like Sweet Shop Slots and Rivers of Olympus, I’m willing to explore both directions. I’d like to stick to shorter projects that don’t go longer than a month or so, and then I can see if a bigger collection of games can create the foundation on which I can become more and more independent. If some turn into real hits, even better, but I’ll be happy with small and modest successes.

Stop dwelling. Look forward.

by Josh Tynjala

Developers around me have recently begun to look more closely at the fuzzy area where one should choose HTML/CSS/JS over Flash for rich browser content. Unfortunately, conversations on the topic have a tendency to get derailed almost immediately because features like Canvas, and even the whole JavaScript language, get dismissed entirely by a vocal few. When that happens, everyone heads off on a tangent to argue a couple points, and then the conversation pretty much ends. Without a clear winner, the dismissal becomes the defacto conclusion and further exploration within the group is halted, at least temporarily.

We’re all aware that certain options may be technically or aesthetically inferior. Yet, we can’t improve the situation without getting our hands dirty. Rather than preach to the choir, we should be providing clear, visible evidence of where web standards (or implementations of the standards) need improvement. We should be creating publicly visible works that push the limits of the browser as it exists today, even if doing so requires the nastiest of workarounds. In fact, finding those workarounds should be a priority because I want us to be able to point to them and say, “Hey browser vendors: I made this, and users love it, but check out this code that’s going to make you want to puke (or this overworked CPU, or excessive memory, or whatever). You need to fix that.” By showing truly compelling projects that can hit barriers and raise awareness of web development pain points that anyone can see, I think we’ll find that browser vendors can be far more agile than some people assume.

The open web community has been calling out Flash for many years, whether their arguments were accurate or not. Now that they’ve “won” for certain use-cases, I think that it’s time for the tables to turn, but in a more productive way. Targeted and actionable feedback, measurable data, along with impressive content will do much more to improve the web than complaining that we miss the good old days. Our jobs may not be as fun at first, but wouldn’t you rather make it better sooner than later?

Corona versus AIR again: Where Corona falls behind

by Josh Tynjala

Now that Adobe has released AIR 3, it’s time to expand on my previous comparisons between AIR and Corona and to take note of some places where Corona definitely doesn’t offer what I need. Because I’m a fan of both technologies, I’m trying to continually put a little pressure on both sides to offer the right capabilities for modern mobile apps. This time, Corona gets a turn again.

Native Extensions

One question native-only developers ask people like me, who use AIR or Corona, is why we would limit ourselves to the features that Adobe and Ansca are willing to implement for us. It’s a valid question, and I can see why some developers might feel too restricted. Personally, I prefer to work with languages that I will enjoy using and to have quick and easy APIs like display lists that don’t require screenfuls of low-level code. I prefer those sugar features so much that I have no hesitation living without the rest.

Thankfully, though, AIR 3 comes with support for native extensions. If Adobe hasn’t exposed a feature that I need in my AIR app, and I’m willing to write a little native code to implement it, then I can add that feature myself by including a library with my app. To me, that makes AIR the best of both worlds. It’s almost as if AIR is just another native framework, but it has the support of all the tools and libraries of the Flash ecosystem.

Now, if only I had the same opportunity to extend Corona. This, to me, is a huge change in the balance between choosing AIR or Corona. Almost any capability Corona offers out of the box that AIR does not, I can implement myself, if needed (or maybe someone in the community already has!). The only places where I might prefer Corona is graphics performance because Stage3D in AIR is only on desktop for now (and TV, I think, but who actually cares about that?) and Lua support because Lua is more fun to write than ActionScript. Not that I’d use Lua for a Flex-like project, of course. Each language has its place.

Shaders

Flash Player and AIR support Pixel Bender shaders. These allow developers to manipulate display objects with cool rendering effects, at pretty impressive performance levels. Drop shadows and glows, color manipulation, distortion, blend modes, and all sorts of fun stuff are possible. The closest thing Corona has is additive blend, which is nice, but a single blend mode seems strangely out of place. Oddly enough, I can’t even find it listed in the Corona API docs.

At Adobe MAX this week, we also saw a preview of CSS Shaders. Eventually, web frontend developers will be able to enhance their content in very cool ways. I know it’ll be awesome for games. Love the flip-book effect video. I have a similar 3D-like manipulation I want to include for the powerups in Gridshock HD (notably, a game that I built with Corona).

Interestingly, that blog post from Ansca on the additive blend mode mentions shaders, so it looks like they may have it on the roadmap. Hopefully, sooner than later.

Build iOS Apps on Windows

Finally, something that isn’t related to AIR 3′s recent release, but I didn’t mention it in earlier posts. Each time I work with Corona, this one becomes more and more annoying. I can’t build a Corona app for my iPad or iPhone from my Windows machine (which is my main development machine). Instead, I need to grab my old Mac laptop, transfer the files over somehow, and do the build over there. Adobe has provided the ability to create iOS apps with AIR on Windows since they first introduced it as the “Packager for iPhone”. Yes, Apple had a huge hissy fit about this a while back, but they got over it.

Switching computers to do a build, especially if I can only test something on a device, is a major time sink (and mental context switch) that I shouldn’t need to deal with. I’ve been building iOS apps with Adobe software on Windows for two years. Isn’t it about time to play catch up on this one?

More grudge matches to come, I’m sure, as AIR and Corona continue to evolve.

Dev Journal: Ancient Temple Puzzle Game #1

by Josh Tynjala

Here’s a very, very early preview of a game idea that I’ve been playing around with for the last week or so. My plans around this idea are still extremely vague, and everything here is subject to change. I’ve already scrapped the earliest seed of this process completely, and I’m not yet sure that I’ve arrived at the final game that I’ll commit to finishing. To get out of the block I’ve been experiencing lately, I’ve been trying to push myself away from my comfort zone as much as possible. Sharing something in the brainstorming to early prototyping stages is part of this process. For science!

Screenshot 1 of Ancient Temple Puzzle Game

The idea here is that it’ll be an escape the room by moving things around, setting up mechanical contraptions, and deactivating obstacles sort of game. As you go from room to room, the puzzle solving gets more complicated. I guess it’ll be kind of like Portal, but without the portals (and in 2D, obviously). The player will be be a bit more omnipresent, though. It won’t involve controlling a character restricted to the world necessarily. I may have a “token” that must advance to a specific goal in each level, but the player will be able to manipulate the entire level from a higher plane. I want to try to make multi-touch an important component too, as this game will be targeted at tablets and phones.

Screenshot 2 of Ancient Temple Puzzle Game

As you can see from the artwork, I’m going for kind of an ancient temple theme. Yes, it’s looking rather pristine at the moment. That’s just me fighting myself over how complex I want to make this thing. Ultimately, I don’t think it will look right without some wear and tear. Though it’s not too detailed yet, I have a feeling that this will become some of the most ambitious game artwork I’ll have created so far. Earlier this evening, I started considering an idea of ever increasing damage to the structure as the player advances to higher levels. As you get deeper in this temple, these changes may be part of a simple narrative of some sort. Maybe puzzles will start to work incorrectly, and odd workarounds will create a “new” solution. I think it’s possible make this game fun, even without a narrative underlying the player’s progress, but this is just another place where I think I can benefit from pushing myself to try new things.

The code I’m running at the moment is targeted at Corona. I wanted to play around with Lime, a tile map library for Corona, and I’m experimenting with the built-in physics too, which Lime integrates with rather nicely. I was a little wary of using Lime because there are supposedly performance issues on devices (which the website makes abundantly clear), but I found that my initial test “level” is running great on a first-generation iPad. It’s likely that people developing platformers and other games with Lime have much larger levels than I intend to build. Additionally, my tile size is currently 138px, which is probably enormous in comparison as well, and I assume that can end up making the level simpler to draw due to fewer tiles filling up the space.

Side note: I’m stubbornly and irrationally opposed to using graphics with dimensions at powers of two. Ever since I realized how often people suggest it, I’ve had the quirk of purposefully choosing something else. Yes, I realize that it’s generally suggested for good reason, but my inner artist will not be obstructed by silly technical restrictions.

As I get further along, I’ll try to share more. Perhaps when I begin experimenting with more puzzles and obstacles, I’ll highlight a few and explain how they came about. I expect things to continue being experimental going forward for a while. The artwork itself involved some playing around in Photoshop on one boring Saturday afternoon. I had some basic ideas for a physics stacking game that I wasn’t really committed to. I made the block with the gem in the middle (from the first screenshot above), and I immediately felt how it could be manipulated by touch, and I could start to imagine the temple-like environment that would surround it. With that small success as a foundation, I intend to continue using play and experimentation as my primary motivator for continuing to build upon this idea.

Corona continues to add essential features ahead of AIR

by Josh Tynjala

As an update to my previous post, Adventures with Corona, Part 1: What Corona offers that’s better than Adobe AIR, I thought I’d take note of some new features in a recent release of Ansca’s Corona SDK. In particular, Corona developers now have access to more useful services. Services that we simply cannot use in AIR today, for various reasons.

Game Network

Last time, I noted that OpenFeint support in Corona could only be used with iOS. Thankfully, OpenFeint works on Android now too. Moreover, Corona developers have been given a choice between OpenFeint and PapayaMobile. Leaderboards and achievements for all. More and more, I’m finding that I’d rather integrate a service that focuses exclusively on this sort of thing because the experience can be far better than a home-grown solution (at least for an indie developer, like me).

Advertising

Ansca has also partnered with InMobi to bring advertising to Corona apps. Whether it’s to monetize a lite version or to go completely free and try to mimic the typical route of free web games, ads are extremely important. I’ve been waiting for quite a while now for the ability to try releasing a free game with ads. Since I’d rather not go fully native, I needed a supported library from an ad network (which apparently isn’t a priority), or ad support in my platform (thanks, Corona!).

Hold on there, AIR

Day by day, I realize that while AIR is getting some cool features that can wow the senses (like Stage3D), Adobe is forgetting, ignoring, or not prioritizing features that keep a roof over a developer’s head. Some things players expect or demand in games, like popular social networks for leaderboards and achievements. Others help us earn just a little more money, like advertising and in-app purchases (both of which can be useful outside of games too). I immediately felt limited without these essentials back when AIR on mobile was first introduced, and it’s been frustrating to see little support from Adobe or third-parties after so long. Maybe that’ll change with native extensions, but those are still a bit further away in the future.

Adventures with Corona, Part 2: Where Corona Needs Improvement

by Josh Tynjala

In my first look at Ansca’s Corona SDK, I mentioned several features that Corona offers where Adobe AIR is currently lacking. These were compelling enough for me to rewrite my tablet game, Gridshock HD, with Corona for the iPad version. That said, it wasn’t all sunshine, lollipops, and rainbows. Some of Corona’s core APIs and functionality can feel a bit half baked in places. Let me share some of the places that seem, to me, in most need of some love.

Platform API Support

In Corona, there are a number of features that are currently only supported on iOS. Among the most compelling features, I noticed that In-App Purchase and OpenFeint are both marked iOS-only, and there are some others too. In particular, OpenFeint’s leaderboards and achievements are a big reason for why I chose Corona for Gridshock HD on iPad. I know that players demand OpenFeint and/or Game Center, and I simply cannot use either in AIR right now. As great as it is to see OpenFeint available in Corona, I’m not a big fan of runtime-included features that aren’t cross-platform.

On the other hand, the ability to extend Corona with native code would be awesome, just like it would be awesome to have the same thing in AIR. If native extensions existed, the power would be in my hands to choose whether I want to (or am even able to) implement a feature on a specific platform. The development effort for robust extension APIs is, of course, a big task, and I understand that a young platform like Corona might want to include a few high-demand third-party features out of the box before they get around to more daunting things.

Regardless, I’m sure that there are constantly feature requests for Corona to include an API for <insert personal favorite library here>. If native extensions were available, individual developers would be free to add two very valuable types of functionality:

  1. Highly specialized features that few other developers need.

  2. Features that might be coming the future, but there’s an immediate need that cannot wait.

With those out of the way, Ansca can focus on core APIs that work well across all supported platforms and that are useful to the largest majority of their customers—making everyone happier. In addition to native extension support in the runtime, a place to share (or maybe even sell) extensions would be ideal so that folks like me, who never want to touch Objective-C, can look through what others have already built.

Simulator

In the simulator, what you see on your PC may not be what you see on the device. Sometimes, that’s impossible to fix, since some features just can’t work on desktops (Although, I’d like to see more console output that basically says, “you called function X correctly, but it cannot be used in the simulator. Please test on device”). Sometimes, though, the simulator can do things that device builds cannot. In my opinion, that’s much worse. For instance, I saw multi-line text working in the Windows simulator, but discovered that an iOS build only displayed a single line. With simulators, it’s best not to get my hopes up.

The Mac version of the simulator has skins for iPhone and iPad. It makes sense, on one hand, because the Windows version can’t output iOS builds due to Apple’s stupid rules. However, I can’t be the only Corona developer who codes on Windows and builds on Mac. Even if it requires extra notification that I can’t build for iOS, those skins would be super helpful. Alternatively, I would like to be able to add completely custom device skins. In the latter case, all I really care about is specifying a custom screen resolution for the device. If I can get 320×480 or 640×960, then I simply don’t care if the skin looks like an iPhone or not.

Finally, the console output for runtime errors in the simulator always seems to get cut off. On Windows, at least. I can’t remember off-hand if the Corona Terminal on Mac has the same problem. Anyway, I can live without a debugger, but then the stack trace must be as detailed as possible when that’s the case. Half missing information could be the difference in finding an error in seconds versus finding an error four hours later. I’m sure you can guess which I’d prefer.

Language

Lua’s standard library is probably as stark and barebones as you can get. Basically, it provides some math functions, some string functions, and a few functions that turn a table (usually called an object in other languages) into an array by adding and removing from numeric keys. Some of the most basic things I’ve come to expect from a standard library just aren’t there. For instance, how often do you call indexOf() on arrays? I do it all the time, and I was forced to write my own version in Lua. It may not be optimal, and I’d rather use something that a dedicated person or team has vetted better than I could with my time constraints.

On one hand, the small standard library makes sense. The language itself is tiny, and that’s a big advantage. On the other hand, I wonder if the wheel has been reinvented tens of thousands of times by various Lua developers. From what I can tell, there isn’t one true community-supported standard library out there, like I would have expected. Maybe I missed it. Honestly, though, I get the impression that most people throw the Lua interpreter into their C++ games and write super short scripts that don’t need much supporting utility code. Anything complex just goes in the C++ layer.

Corona is different. In Corona, all your code except the super low-level stuff is written with Lua. Corona developers have a more pressing need for a robust standard library that is closer to what’s available from the top-level classes and functions in JavaScript or ActionScript. If Ansca has big dreams for much larger game projects built with Corona, they need to spend some time filling in the gap here so that developers aren’t bogged down in low-level implementation.

Moreover, if Ansca wants to support any kind of open source community, a standard library declared from on high will nip a couple of potential problems in the bud. Since I’ve yet to see any Lua code that uses some sort of namespacing, name collision is pretty much inevitable. Likewise, duplicate functionality will be rampant as everyone includes their own flavor of the missing core library. For anyone that wants to mix and match third-party libraries, that’s going to be a mess of headaches. As Corona-targeted libraries get more complex, the chances of this happening grow exponentially.

Choose the Best Tool for the Job

I enjoyed porting Gridshock HD to Corona. I learned a new language that I hope to develop with again in the future, and I was able to take advantage of features that aren’t available to me in my usual environments. It has given me some inspiration and expectations that I intend to take back with me to Flash. I might be a little more harsh on Adobe’s runtimes when I give feedback now, but any criticism I make will be because I want to see Flash Player and AIR continue to be the best at what I use them for.

Am I now a Corona developer? I’m certainly not leaving Flash behind. However, I’ll be keeping an eye on Corona to see where it ends up. I don’t have current plans for more Corona games, but I may change my mind if certain features are compelling enough, or if I decide that I haven’t played with Lua enough lately. We’ll see. It’s another useful tool to have at my disposal. I’m very glad that I spent some time learning to use it.

Adventures with Corona, Part 1: What Corona offers that’s better than Adobe AIR

by Josh Tynjala

During the last month or so, whenever I could spare an hour, I’ve been working on a port of my game, Gridshock HD, from Adobe AIR to Ansca Corona so that I could release it for iPad. If you’re not aware, Corona is a mobile development platform that can target iOS and Android. It was created by some folks who were once involved with Flash Lite, so it’s quite relevant to Flash developers. It’s not perfect, but there are a few useful features that Corona offers and AIR is missing. I want to use my experiences to make some requests that I hope Adobe will address in upcoming versions of AIR.

Language

I, and I think many Flash developers who have been around for a while, kind of miss dynamic languages. I often hear that Flash isn’t as “fun” as it used to be. I can relate. It would be great if we could use something less strict than ActionScript 3 in our Flash projects. Yes, I know I can turn off strict mode, but if I’m going to use ECMAScript, I want AS3′s dialect to be updated with features that have been added since ES4 was dropped by the committee. There’s some cool stuff coming in Harmony.

Lua logo

Corona includes Lua, which is my new favorite language of the moment. It’s super flexible and a lot of fun to work with. If there were a way to compile it down to bytecode that could run in Flash, I’d consider switching to Lua over ActionScript 3 for much of the Flash content I create. AS3 is good for Flex apps, but for games, web experiences, and stuff like that, a dynamic language like Lua (or modern ECMAScript) would be more fun for me, and enjoying my work is a top priority.

For reference, this is a minor need compared to the ones that follow. I can live with AS3 for all my Flash development. It’s a decent language, but I simply desire a little more choice. If you look at JVM or other runtimes, they all have extra languages beyond the main one(s). I want to branch out more, and it would be awesome if I could keep a foundation in Flash.

Graphics

OpenGL logo

Corona offers OpenGL-accelerated graphics. I had no rendering performance bottlenecks, and it was a dream. However, we all know that AIR will be getting Molehill hardware-accelerated APIs in an upcoming release. Corona has the advantage now, but it may not be for long.

Libraries

Corona includes out-of-the-box support for OpenFeint and Game Center. These services are considered a requirement by many mobile gamers these days, and they’re sorely missed in mobile AIR game development.

OpenFeint logo

Developers simply need a way to run native code with AIR. There are compelling third-party services that only provide native libraries, and we can’t use them if we want to develop with AIR. Even worse, many are unlikely to be added to the runtime, so without native libraries, we’ll never be able to use them. In addition to game leaderboards and achievements, I know many would like to access things like in-app advertising and custom hardware or accessories. Moreover, being able to use native libraries will help us avoid rewriting existing libraries that are already working well in a native form. It expands the reach of AIR and saves time and headache. Native code would be a major win, for sure.

Runtime

Everything you need for Corona is included in the output. There’s no separate runtime. I suppose it’s similar to how AIR app work on iOS. Developers like me want to include the AIR runtime with Android apps too. I strongly dislike requiring my users to install a runtime before they can play my games. It’s an extra potential point of failure, and it feels somehow unprofessional as a potential source of annoyance for the user. While you’re at it, allow me to include the runtime on Windows, Mac, and Linux as well.

Adobe AIR logo

The age when separate app runtimes were a valid choice for targeting consumers is gone. I know games are a big focus for Adobe right now. Flash Player is a huge target for casual games. I’d love to use AIR to release commercial desktop games that are more polished, bigger, and better than my free web games. However, asking potentially-inexperienced users to install or update AIR is a big reason for why I’m not exploring AIR on desktop for games. Adobe has probably done the best it can to make the install experience painless, but I just can’t get over being wary.

As for updating AIR, let’s be honest. The latest version of AIR doesn’t get installed as quickly as Flash Player. I’ve never heard Adobe talk about stats for AIR runtime installs. Given how often Adobe presentations include the graph with Flash Player installs, I refuse to believe that they wouldn’t be sharing AIR install graphs too… unless they’re just not impressive. Let me package in the runtime, and I’ll never need to worry about the AIR runtime version. I’ve heard that a ton of Java apps package in the Java runtime now for similar reasons, and I’m sure that’s way bigger than AIR, so let’s get with the times.

Mobile is still a new frontier, and closer to the casual experience on the web, so I’m tolerating a separate runtime on Android, but my feelings are much the same as with the desktop runtime.

A Tight Race

In a follow-up post, I take a look at a few things that I don’t like about Corona. Yes, the coin flips both ways. Corona has some advantages that made it an obvious choice for my iPad game… today. However, AIR is not that far behind Corona in this particular race. In some ways, AIR is much further ahead. To put it simply, I was willing to make some trade-offs in development comfort to get the features I wanted. I didn’t like that, but I sucked it up and only grumbled to myself.

I know both technologies will be improving over time, but I think that Corona is going to need to fight harder to stay on top in the situations where it holds my interest right now. So far, I’m only interested in Corona for iOS support. That’s a precarious place to be when there are a variety of pros and cons on both sides.

Choice

by Josh Tynjala

Where I am today, in life and my career, is thanks to a powerful drive to always learn, grow, and push my limits. I’ve rarely encountered much internal conflict related to this process. Often, I have a wealth of things that I might choose to work on. In the past, I typically picked something that seemed fun or interesting at that particular moment. That was pretty much the only criteria. Now that I have the freedom to spend more time on personal projects, especially ones that earn revenue, I’m having difficulty continuing with the same process. These days, I feel like I need to prioritize. As a result, I feel like I’m missing out on wider explorations that I would have chosen in the past. Lately, that’s been troubling me.

As you probably know, I started creating casual games a couple years ago. Within about four or five months, I released three games. Since then, I haven’t finished a single new game. Actually, no, it’s time to be blunt. I haven’t started a single new game either. I played around with some ideas, but they didn’t make it beyond the early prototype stage. Those ideas simply didn’t resonate the same way that my first game, Chroma Circuit, made me want to start creating games in the first place. Gridshock and Qrossfire, my other two games, were deliberately derivative because I wanted to spend time focused on building a foundation of knowledge and code that could be used across many games in the future. Qrossfire, in particular, cemented this new direction of how to decide what to work on.

Since then, instead of starting fresh with new ideas, I’ve mainly continued iterating. I haven’t stopped expanding my knowledge in this pursuit, even with the same three games, and I’ve found enjoyment during every step of this process. I’m experimenting, adding features, and refining the experience in many ways. I’ve improved the controls, refreshed the graphics with better artwork and special effects, and I’ve added new mechanics. I still have many avenues I could explore with these games. Their modest success on mobile is just good enough that I don’t feel like they’re a complete dead end, but they’re also doing just bad enough that I’m driven to continue with them just to prove that I can do better.

For some reason, though, I feel kind of stuck. Part of me wants to move on and try new genres of games. I want to get back out of my comfort zone and force myself to write code for things that are more advanced than what I’ve done so far, or at least work on things that feel newer to me. Obviously, I’ve only focused on the same sort of game. Maybe that’s slowing my advancement. Not to a halt, or I’d be completely bored, I would have moved on to something different by now. Instead, it’s enough to keep me interested, but I’m clearly not propelling the same way I used to in school and during my early career.

I can see the deceleration just in the fact that I don’t blog as much anymore. I don’t say, “hey, look at this random cool thing I worked on last weekend” very often these days. I’m okay with that, to a certain degree, because my blog posts have been getting longer too. When they’re finished, I feel like I accomplished something, and that they include more insightful information now than I could include in my old writings. Of course, I’m far more active on Twitter now than when I was blogging weekly or monthly, so it’s not like I’ve disconnected myself from the Flash community that I first joined thanks to my blog posts.

Even after writing down my thoughts, I’m not feeling any more decisive. I’m frustrated with myself for not finishing a few projects that would bring my existing games to new platforms. They’re at least halfway done, if not more, so I’m feeling like I wasted time if I don’t get back on track with them. Then there are way to improve the games and learn more by adding features that I’ve not tried implementing yet. Micro-transactions. Achievements. Stuff like that. On the other hand, I have those prototypes that would easily make playable games, if not necessarily breaking new ground for me, and I have a few ideas that are still simmering in the back of my mind that I want to start exploring. I want to reach a point with one of them where I’ve verified that the idea is fun, and it excites me to move from prototype to the complete game.

Both directions that I keep comparing pull at my interest, but I don’t want to split up my time between both of them either. I feel like I need to choose because the day has too few hours to work on everything at once. I’ve already divided my time between games and other software. There are other activities, not involving programming, that I want to dabble in too. Every project I continue to work on is interesting to me in different ways. That’s the hardest part about making choices in this area. I want to fit everything in, and I want to get it all done in the time it would take if I chose just one. You might say that all that potential is a good thing, but it feels like a major barrier to me.

Indie Flash Game Development: 2010

by Josh Tynjala

About a year ago, you may remember that I shared my revenue numbers for indie game development in 2009. I had big plans for Bowler Hat Games in 2010, but I guess I spent my time going in the wrong directions. Here’s a look at how my business is doing one year later.

The Breakdown

In total, game development earned me $20,009 in 2010. That’s about 32% lower than last year, and I spent an equal amount of time developing games during both years (I worked on other projects for about four months during both years). Revenue is divided between four sources, game contracts, mobile sales, advertising from existing web games, and non-exclusive licensing. I didn’t create any new Flash web games, so there were no primary sponsorships this year.

2010 Revenue Breakdown

As with last year, most of my income came from contract work, earning me $15,900. I spent the least amount of time on those projects—maybe a month and a half. Continuing ad revenue from the three Flash games I released on the web last year earned me an average of $198 per month. Mobile app sales brought in an average of $131 per month. I sold one non-exclusive license of a Flash web game for $150. In total, that’s an average of $1667 per month, with contract work covering the vast majority of that amount. Living in the California Bay Area, that covers my rent for a one bedroom apartment and groceries, but between other bills and, of course, income tax, I’ll need to make a lot more if games are going to cover my expenses.

iOS and Android Games

At the end of last year, I had converted two of my three Flash games to iPhone, and revenue was already proving to be modest at best. This year, I finished porting my third Flash game to iOS, and I released some updates for each of them. Sales never picked up much, though. Additionally, I removed my games from the App Store for a couple of months while Apple was being stubborn about the Flash Packager for iPhone, so there was a bit of time mid-year where I received no income from selling apps.

Adobe released AIR for Android this year, and I had all three of my mobile games ready for sale at launch. Unfortunately, I had them ready for several months before I could actually sell them. Unlike Adobe’s solution for iPhone, which embeds the runtime into the app, the Android version of AIR is a separate install, so I had to wait for the official release. I’m finding that sales of my games are lower in the Android Market than in the iOS App Store. In December, iOS sales were about five times higher than Android sales. It’s too bad because creating mobile AIR games on Android is actually a lot of fun.

Mobile isn’t a walk in the park

Ultimately, I believe that I spent too much time on mobile this year. I would have been better off designing new games and getting sponsorships instead, or maybe I should have started exploring downloadable desktop games or microtransactions. Last year, I said that sponsorships didn’t seem like they could earn me enough (at least for the type of games that I make), but mobile has proven to be an even harder nut to crack. It’s probably my lack of marketing skills. With sponsorships, I can visit FlashGameLicense and have a community of portals and other sponsors who are there to pay for games like mine. With mobile games, I don’t have a central source to locate my audience. At best, I know that players of the web game might be willing to buy a mobile app, but beyond that, I’m a little lost.

I’m still waiting on a supported advertising solution for AIR mobile. I don’t want some API that the ad network says works for “everything else” while only native code gets a real SDK. Free versions of games that are ad-supported can be a great way to get players to consider the paid version while still bringing in revenue. I’ve considered the possibility of converting my mobile games to HTML and JavaScript because I know there are frameworks that integrate better with native libraries that provide advertising and other services for games. However, with such low revenue on mobile already, I’m worried that I might be wasting even more time by trying that. It will require more development and testing than my recent HTML5 port of Gridshock, which was more of a fun project for the holiday break than a serious one. I was able to take shortcuts. With a paid product, shortcuts are not an option.

2011

I’m probably not touching mobile for a while, except maybe for fun weekend projects. Even so, I very much want to play with tablets at some point, but I think I’ll wait until some are released with Android Honeycomb. All the hardware coming out is kind of overwhelming. As an indie developer, my wallet cringes at the idea of ensuring I own even a minimal collection of test devices.

As for what I will be doing this year, I intend to start out with a sequel to Gridshock. Hopefully, with Gridshock’s success as evidence, I can get a better sponsorship deal than the original. From there, I may consider a desktop version that combines both games. However, I kind of want more than two game modes in a desktop app, so I may explore other ideas for sequels first. I might include an exclusive game mode or two in the desktop app to ensure that it provides enough value over the free versions. That’s still brewing for the moment. Right now, I just want to focus on finishing a game to be sponsored.

With lower numbers in 2010 than in 2009, I’m feeling a little down. At the same time, though, I’ve found myself surprisingly motivated over the last couple of weeks. I spent one night coding until 4:00am. I’m attacking my to-do list with enthusiasm every day. Last year’s numbers, I think, are helping me work harder because they’re more frustrating to me than depressing. I want to make Bowler Hat Games a success, or at least ramen profitable. The way I did things last year clearly didn’t work, so I’m just going to try harder and see if I can figure out what works better. Wish me luck.

Flash to HTML5: Gridshock Remade

by Josh Tynjala

Over the holiday break, I decided to spend some time on an interesting project. I wanted to remake one of my Flash games on a different platform. Don’t get me wrong. I thoroughly enjoy developing for Flash Player and AIR. I just wanted to try something new. A little cross-training to give me a fresh perspective. Over the last several months, this idea has been stewing a bit. I considered things like going all out and learning Python to try pygame, but that seemed like it might take up a little too much of my time. Ultimately, it seemed that HTML5 and JavaScript were probably the best way to go due to JavaScript and ActionScript having a similar language heritage.

The result of my efforts over the last couple of weeks is Gridshock in HTML5:

Screen shot of Gridshock in HTML5

Gridshock, a Flash game remade with HTML5

Picking a Game Library

Not too long ago, I discovered Crafty, a JavaScript library for games. The documentation describes components that are simple and to the point, and I felt like I already had a pretty good understanding of the library after a quick glance over the APIs. As of this writing, Crafty is still at version 0.1, so it’s not exactly mature. Let’s be honest, though, most JavaScript game libraries are brand new anyway. I attribute that to IE9 finally getting Canvas support. Anyway, like I mentioned earlier, I wanted to branch out and try game development outside of Flash, but I have other projects I need to get to soon, so I needed to pick a library as a foundation so that I didn’t get stuck on low-level architecture decisions. Crafty seemed like the right choice for me.

Crafty logo

Crafty, a JavaScript game library

Very recently, Grant Skinner released Easel, a JavaScript graphics library based on the display list in Flash. This, of course, should be an obvious choice for the conversion of a Flash game. It’s hard to explain what made me stick with Crafty (which I discovered first). I think my decision ultimately came down to the fact that I wanted to work with a library created by someone from outside the Flash community. More chances to learn new techniques. That said, if I ever make another JavaScript game, Easel will be a top contender so that I can make comparisons and decide on which one I like best.

Other Libraries

Playtomic is way ahead of the curve. In addition to Flash support, they offer a leaderboards API for HTML5 too. I was pretty excited to discover them one afternoon because, otherwise, I would have only stored high scores locally. I am not a backend guy, and I have zero desire to set up high scores on my server. Mochi Leaderboards are great for Flash, and it appears that Playtomic is a great way to go for HTML5. Please note, however, that Playtomic is currently only free for one casual game. However, the flat-rate prices don’t seem too steep.

humaneDate() is a nice little JavaScript function for converting dates to something that’s a bit more readable (like “2 hours ago”). Playtomic provides dates like this automatically, but I needed humaneDate() for the local player’s high scores that I store for convenience. Unfortunately, the written format is a little different between the two. The non-humane date returned by Playtomic isn’t an exact time, either, so I can’t accurately reuse that with humaneDate(). If this were more than just a learning exercise, I would have modified humaneDate() to match Playtomic’s output.

I ported GTween to JavaScript. It’s my tween library of choice in Flash, and the Flash version of Gridshock uses it, so I figured it would save more time if I made GTween work in JavaScript instead of converting to an existing JavaScript tween library. Edit: gtween.js on Github.

Crafty logo

Modernizr, a JavaScript feature detection library

Modernizr offers an excellent way to detect modern browser capabilities and display alternate content if the current browser doesn’t stack up. If you load Gridshock in an older browser, you’ll see a message that suggests upgrading and links to the Flash version. Modernizr helped me detect if JavaScript is enabled, and whether the browser supports HTML5 Audio, Canvas, and Local Storage. I also included some manual checks for JavaScript features I needed, like defineProperty(), which is JavaScript’s version of getters and setters.

From ActionScript to JavaScript

JavaScript is a different beast than ActionScript 3, as we all know. They may have originated in the same place, but there’s a certain extra comfort AS3 provides with classes, strong typing, and the automatic compiling during development in Flash Builder.

Still, though, there’s something kind of elegant about JavaScript. It’s looser, but I thoroughly enjoy playing with closures and things like that. In fact, after I spent a few months a couple years ago writing a wrapper for my Flash charts to make them available to YUI JavaScript developers, I started using closures in ActionScript quite a bit more. This previous experience made conversion of Gridshock to JavaScript a lot easier.

Image of Xzibit, from the 'Yo, Dawg' meme

You dawg, I heard you like functions, so I put a function in your function…

Crafty has a component system that creates “entities” with mix-ins. If you add the 2D component, the entity will have x, y, w, and h properties, along with some methods for working with them. If you add the canvas component, the entity will draw itself on Crafty’s stage. If, on the other hand, you add the DOM component, it will add an image to the page’s DOM on top of the canvas.

I quickly started creating new components for Crafty. One for alpha was the most obvious because I like fading things in and out (like the lights on the grid). Another, that I called “autoz”, I created to automatically manage depth. Similar to older versions of Flash, I discovered that I was forced to manage depth manually with Crafty. This simple component kept me from tearing my hair out when I discovered that the order of drawn entities wasn’t always consistent.

Both of those additions mixed-in with existing components right away, and I found myself enjoying this approach over inheritance. In my experience, inheritance in JavaScript can be a pain. It’s certainly doable. I liked YUI’s implementation back when I was using it. However, I found myself embracing composition and mix-ins more easily than I would in ActionScript 3. I think a lot of developers moving to JavaScript from a language with classes should take a moment to consider living without inheritance, if only to learn something new from the experience.

HTML5 features

While creating Gridshock, I worked with three features of HTML5—Canvas, and Local Storage, and Audio.

HTML5 Logo

Canvas

I actually did very little coding directly with Canvas. Crafty had most of that covered. There was a bug or two in Crafty that I needed to workaround, but my tweaks were minimal.

To be honest, I think the Canvas drawing implementation in Crafty is a nice start, but it’s certainly not the most optimal. I noticed my laptop’s fans powering up a lot whenever I was testing Gridshock. Crafty draws sprites too often. There’s no invalidation system to draw all changes in one go on each frame (yes, Crafty has an enterframe event similar to the one in Flash). Instead, if I change the x position of a sprite, it draws to the Canvas immediately. Then, if I change the y position on the next line, it draws again. For my needs, with a simple casual game like Gridshock, that’s fine. However, I hope that the author will look into improving this in the future.

I didn’t run into any cross-browser issues with Canvas.

Local Storage

Local Storage worked like a charm across all the browsers I tested on. If you’re unfamiliar, Local Storage is similar to Flash’s SharedObject. However, it’s a bit more primitive. Everything is stored as a string. To store complex objects, you need to encode to JSON. Not a difficult workaround there, and that’s probably what the HTML5 working group intends.

I used Local Storage to store a list of the player’s own high scores, and I store the game’s settings with it as well (sound effects and patterns mode, as found on the Options screen).

The only cross-browser issue I ran into here was that Date objects weren’t encoded to JSON the same way in some browsers. That’s the JSON implementation, though, not Local Storage. Regardless, the workaround was easy. I just stored the UTC date string instead. That’s easy to parse with new Date(utcString).

Audio

Oh man, getting audio to work cross-browser is a major pain. Canvas and Local Storage are both pretty much fully baked in all browsers at this point, from my experience. The audio situation, on the other hand, is still very raw.

Image of guy with bull horn

I did not have a protective suit like this. Photo by vacantfever.

Crafty has a very simple audio API that wraps HTML5 Audio, and it seems to work consistently. However, it didn’t meet my needs. I need to play a sound effect every time the player clicks on the light grid. A single Audio instance can only play itself once, and you must wait until it is done playing until you can play it again. That means I have to store multiple instances of the same audio file so that I can loop through and pick one that isn’t currently playing.

That’s easy enough. Annoying coming from Flash’s sound capabilities, but easy enough. However, I still ran into other issues. Chrome stops being able to play certain sounds after a while. They’ll play over and over without issue for a couple of minutes, but then I suddenly hear nothing when I try to play them again (while the other sounds continue working). Opera has loud clicks at the end of every sound. Firefox won’t loop audio (that’s why I didn’t include a music track). IE won’t let me create an Audio object and play it right away (or, at least, once a load event fires). Some browsers don’t play the click sound on buttons. It seemed that every variation of the Audio APIs that I tried failed in at least one browser in some subtle, or not so subtle, way. The code I settled on seems to be the most stable, but audio is often delayed before it gets played, and Chrome still stops playing certain sounds sometimes.

In short, Audio isn’t ready for prime-time. The two days I spent hammering on it were extremely frustrating. There’s probably some magical combination of APIs that will fit my use-case in a cross-browser way, but I didn’t find it.

Other Challenges

A couple other things weren’t straightforward.

Preloader

A preloader is easy in Flash. A game SWF is distributed on its own as a single file, so you just have to display some animation on the first frame until the rest of the frames load. In HTML, I had to structure my page so that JavaScript files loaded in the right order, and I had to extend Crafty to preload any images I needed for the sprites before I started the game. Yes, technically the game would run fine if the images loaded as they were needed, but that sort of ruins the experience for a game. Fine for a document, not so much when games need more real-time interaction that could be affected by assets that display too late.

UI Controls

Not super easy, especially when trying to make something work with Crafty. I ended up making my own button and toggle switch components within Crafty’s architecture. When I realized the work required to manually draw a list component for my high scores, though, I felt like gagging. I ended up putting a scrolling div on the DOM with a skinned table inside. This approach felt hacky, since I integrated with Crafty a lot more when I made the other two controls. However, it got the job done. I think if I gave myself some more time, I could have built the list a bit more elegantly and had a nice minimum set of UI controls that could be reused across games. Maybe I’ll explore this more later if I decide to make another HTML5 game.

Screen shot of toggle switch UI controls in Gridshock

After seeing switches like this in iOS, I often choose them over checkboxes.

Parting Thoughts

I enjoyed this little field trip into the land of HTML5. Though I intend to continue making games in Flash, it provided me with a new perspective, and I’m happy to know that I can return to HTML5 with confidence at some point in the future, if I need or want to do that.

For instance, I may be interested in converting my AIR mobile games to an HTML5 mobile framework, like Phonegap, to take advantage of the greater native integration. For instance, I can’t release free, ad-supported versions of my games with AIR mobile because there’s no ad provider that works with the runtime. That’s been very frustrating for me. While I enjoy AIR on Android for easy porting from desktop to mobile, man, it feels limited sometimes.

Anyway, HTML5 feel like it’s nearly ready for casual web games. Currently, there seem to be two reasons to wait a bit longer:

  1. As I discovered, the Audio support in browsers needs work. A lot of it. Audio is important in games, so this is a big one.

  2. Most casual game players are regular people, and they may be stuck on IE at work, or maybe they haven’t yet upgraded at home. Once IE9 is released and has gained a critical mass among IE installations, then I think games may be ready to run on HTML5.

Of course, that doesn’t account for distribution. I don’t expect the HTML5 version of Gridshock to end up on portals. Unlike the Flash version’s single SWF that can easily be uploaded anywhere, the HTML5 version involves an HTML file, a folder of images (which could be put on a single sprite sheet, but that’s kind of a pain without an automated tool), a couple of minified JavaScript files, and a minified CSS file. The HTML, JavaScript, and CSS could be combined, I suppose. However, the images are a bit tougher. I guess if it were a giant sprite sheet converted to a data URI, that would get everything into the single HTML file. Definitely something that game developers and portals will have to think about for anyone who wants web games to move from Flash to HTML5. Unless a dozen portals email me tomorrow to say that they want to feature this version of Gridshock on their sites, I’m not worrying about distribution yet.

Enjoy the game? You can play Gridshock on iPhone and Android. By purchasing the apps and supporting me, you’ll be able to see more in-depth looks at my game development projects, like this one.

Pages: 1 2 3 4 5 6 7 8 9 10 ...18 19 20 Next