Tuesday, December 4, 2012

Animation Day 2; inking, animating, etc

Yesterday was mostly side tracked with "how best to ink drawings" in Illustrator so that I can import them in to Toon Boom Studio (TBS).

Well, the time crunch is a factor here and I realize I'm not the most experienced artist, or have a very steady hand/arm to do this stuff... so I think I'm going to fall back to consistent line width and using the pen tool to ink everything.

Now, don't get me wrong, I'm all for using a tablet and going that way, but for this project, I don't have enough time to get really good enough to make it "good" looking.

The obvious issue here is that I can't really do good line art in TBS itself without getting TB Harmony or something crazy... or using the eraser tool and getting all obsessive over how my lines aren't lining up, being overshot, can't zoom in far enough to round things out good enough, etc... hence why we're starting out with Illustrator in the first place.

I have the power to line up my vector art accurately and consistently.  I can mess with strokes and utilize all of the tools Illustrator gives me.  This in and of itself was a challenge to learn and get used to, but at the end of the day, I decided to use strokes (instead of fills with the blob tool) to ink everything.

On the note of coloring, this will likely be an after thought, but I've done some small pet projects to see how it works so I don't accidentally shoot myself in the foot if I can go down this road some day.  After some experimenting, the "easy" coloring option was to use Live Paint, but this was its own issue when importing to TBS (it left weird lines around the edges of the painted areas)... so Live Paint was out.  I ended up resorting to making a layer under the line art, using big blob tool to paint in areas, then cleaning up the overflows with some pathfinder magic and using copies of line art to "clip" away the excess.

This definitely isn't the only way to do it and I'm sure there is a better way out there, but again, more time and ambition will lead to me finding these options.

It is today's hope that I will finish up the first 4 or 5 storyboard cards for my animation project in TBS.  With that said, Animate day 2, begin!

I don't know yet if I'll be posting my work as I get it done on the blog or not.

Monday, December 3, 2012

Inking Characters in Illustrator, en route to Toon Boom

From my previous post, I took my paper inked drawings, scanned them in, then inked them in Illustrator.

I'm now realizing that this is much more difficult than I had originally thought.

Just looking at John K's inking tag on one of his blogs, really makes me see I have long way to go!

http://johnkstuff.blogspot.com/search/label/inking

Anyways, here is the rasterized version of the vectored character from the previous post.





I was trying different techniques with inking each of those poses above hence why they look a bit different from each other.

Looks like the rest of today is going to be dedicated to practicing this more instead of working on animation!

Character Model Design (drawing)

As a fair warning, I'm a fairly novice art person.  We are doing a very short animation and as such, we designed a story and some characters.

Below is one of the main characters.  First, I did about 6 sketches, which resulted in throwing out the first 5 simply because they didn't look... acceptable.

Anyways, I scanned in the original pencil sketch, but as expected, it was really difficult to see anything, so we went ahead and inked them on paper, then put them up here.

This is, more or less, the design for this character model.




We'll be sending these over to Illustrator next and drawing this young lady in a whole lotta frames and getting her ready for animation in Toon Boom Studio.  If I have time, I'll do a color skit and try out various colors, but due to time constraints on this project, that will be one of the last things I do.

Naturally, she'll start looking more refined (in the cartoony way of course) as I get better at drawing this over and over again.

Thursday, November 29, 2012

Line drawing in Illustrator

This took me a while to figure out the "best way" to do... but I eventually stumbled on to this blog:

http://danidraws.com/2007/01/08/creating-line-drawings-in-adobe-illustrator/

Good stuff.

Basically...

1) Take your hand drawn sketch, scan it in
2) Place it on a new Illustrator document
3) Turn it to a template
4) Make a new layer (this will be the inking layer)
5) Use brushes and a drawing tablet to "ink" the lines, don't worry about over-shooting lines
6) Use pen tool to add anchor points where lines intersect and overshoot each other
7) Use direct select tool to delete the overhanging parts

This is very useful because importing vector art in to Toon Boom Studio is how we're doing things on our end.  Drawing in TBS is nice, but really awkward correcting my line art.

Oh, and if you don't know how to import AI files in to TBS, you have to save your Illustrator art as CS2 format otherwise TBS can't read the data.  This information is current as of TBS version 7.1

Wednesday, November 28, 2012

Storyboarding, scripts, oh my!

Part of my studies in to animation requires the use of storyboards.  It makes sense, how do I know what to make and how to present it... and in what order?

Needless to say, my original "rough draft" outline for a quick story was totally redone after I ended up writing the script for it.  The basic ideas stayed the same, but actually focusing on how cameras move around, zoom, which characters are animated, things fading in and out... yea stuff changed.

I was asked today how my animation is coming along... my answer was "animation is the last thing I'll be doing".

Tuesday, November 27, 2012

Intro to Animation Endeavors

So, this blog has been mostly about programming, game development, design, smart phone stuff, technical rants, and stuff like this... and has been idle for a little while again.  Well, a small and somewhat crazy offshoot to all of this has been all about visual things that look pretty.  Worse yet, pretty things that move.

I've been learning more about how cartoon animation works and some of the software that powers these pretty cool things.  The adventure led me acquire Toon Boom Studio and take a related class or two at the local community college.  Ideally with the lofty goal of implementing pretty, moving things in our games and heck, maybe even do some of our own animation work!

I found a couple random blogs that really helped me out in addition to the classes.

Of particular note:
http://animationcraft.blogspot.com/2007/04/toon-boom-studio-learning-track.html

This guy is clearly an industry veteran with very helpful articles.

I also came across John K's blog (yea, one of the guys that did Ren And Stimpy back in the day).

http://johnkstuff.blogspot.com/

To get this party started, we had done various assignments for our classes, but with all things, it usually takes a wiping of all your old stuff before you feel somewhat confident enough to actually feel like it is going anywhere.  At any rate...

Here is my *second* ball bouncing animation that turned out pretty decent.

Thursday, May 31, 2012

Java obfuscation, ndk, jni, and proguard.

We recently had the pleasure of posting an update to one of our apps - Bubble Zing - on to a couple Android markets.  Everything looked great on the development side and everything was pretty much tested and ready to go, so we exported our apk in Eclipse and sent it out!

Then the problems started trickling in (of course).

This was quite baffling that the same code running in Eclipse was completely breaking when running from an exported/signed APK file.  What was going on here?!  I googled around for various errors and almost all of them talked about missing libraries and such.  Well, none of those things were my issue.

I finally started getting some useful information from logcat about ClassNotFound and being unable to get new instances of *my activity* or various other failures about FindClass failing.

I was pretty stumped by the whole thing, so I ended up opening the APK like a zip file to check out what was actually IN the apk.  Everything looked as it should have been.  All my resources were there, the class path stuff was set as well (really confusing me why all this classnotfound stuff was happening now).  It wasn't until I ran apktool on my apk to get some actual additional information about my java files that I started to trace down the issue.  I noticed that all of my Java classes which were called from my native library were named "a.java" and "b.java", etc.  As opposed to all the normal java files which were not interacting my native shared library were fine.  So, it seems like we narrowed down what sort of thing was happening here.

Ok, somewhere in the export process, I was was losing my actual java names... and with things like fully-qualified names everywhere, I suspect this was a major problem.

So, I found that Proguard was obfuscating away my class names during the export process, meaning once my app was in apk form, calls from native code were completely unable to find half of what it needed to talk to for it to work!

For those interested, I added the following lines to proguard.cfg to inform proguard that I would like to keep most of my stuff unmangled please:


-keep public class [FULLY.QUALIFIED.PACKAGE.NAME].* {
public static *;
public static *;
private static *;
}

For us, only static methods were being called from native code.  We also set *all* of our classes in our package to be saved with the "-keep public class" line.


In retrospect, this totally makes sense, since during the apk packaging process, it realized that at no point were some of my chunks of java code being called by any other java code, so proguard figured it was ok to munge those up in to various cryptic alternate symbols.  I suppose it wasn't proguard's fault, but really my own misunderstanding of how the export process works and what proguard did for you automatically (or why).

I'm glad that was over, lesson learned?!  Always test an APK on my devices BEFORE sending it out to the market, even if we completely ran through all our tests before the export process.

Friday, April 27, 2012

Welcome to iOS

We've been sitting on our iOS developer license for a little while since we've been fairly occupied catering to the problematic nature of our Android apps.  As soon as we can get our existing products on Android to an acceptable level we'll begin porting Bubble Zing and possibly Simple Match over to iOS.

One of the major changes in our process and code was to put as much game logic in to portable C code for Bubble Zing so that, in theory, we could just wrap the game code in to iOS objective-c wrappers and retain the java wrappers for Android.  Of course, this major shift in philosophy warranted a huge time undertaking on our Android ports as we essentially had to recode everything... meaning we may as well put a lot of code in to libraries and that whole thing.

On the plus side, all this "nativeification" of game code has excellent performance indicators and should increase our product exposure to older devices that needed all the speedups (fairly badly might I add).

I suppose this process was inevitable anyways.  I mean after all, Bubble Zing 1.0.3 (the latest public version as of this writing), showed that just drawing a background graphic during gameplay - JUST DRAWING THE BACKGROUND - took 60% of the processor in several test devices.  That was horrendous and completely unavoidable due to the nature of java, dalvikvm, and opengl es.  The only way around it was to go native code and start screwing with lower level stuff... and this has already paid off in huge ways... but it was not without its own drawbacks and tradeoffs.  Specifically, things that use to work great now require extensive rework and compromises.  Some things now look "worse" than in 1.0.3, but perform a ton better, yet the overall gameplay experience has been increased a lot.

Anyways, once we get Bubble Zing 1.1.0 up and in to public hands, our iOS adventure shall begin!  We took a look at XCode and their iOS stuff already, and I must say it was quite welcoming from a developer's perspective and I'm going to assume from a business perspective as well once we get there!

Hopefully from here on out, all our products will see a simultaneous Android and iOS release at the same time!

Saturday, April 14, 2012

Complexities of Android development

As an indie mobile developer, I can personally attest that making things on Android - especially games - is pretty difficult.

I ran across this article about Battleheart's developer basically giving up on the Android platform as being "unsustainable" (original blog post by the developer here).

Now, this person has quite a lot of good points that works against Android devices in the business sense.  Why would you want to support something that takes a vast disproportionate amount of money to create?

Android has lots of problems for developers, and one of which is that simply Android users are generally more frugal with buying things (to include newer devices).  This means that as a developer, we should cater to old technology because a decent segment of the Android market are using old devices.

For example, I attempt to target Android 1.5 devices when and where possible so that, in theory, all newer devices should be able to run our games.  That sounds good at first, but this isn't always the reality, and this is where Battleheart's developer has a good point.  The only sure-fire way to guarantee that apps will work on a device is to physically test it on that device.

I wish it was an easy case were we can just load up our apps in an emulator, test, fix, deploy, but it definitely isn't that simple.  Each device manufacturer seems to have implemented various things about Android in their own way; forcing developers to cater to each device maker!

For example, only Android 2.1 allows for multitouch.  We created a virtual Dpad app that accepts user input on a circle (simulated analog dpad if you will) along with 2 virtual "buttons" - think like a Nintendo controller, but with a virtual directional pad.

After several days of developing and testing, it works 100% on our Motorola RAZR, but breaks horribly on Samsung Galaxy Tablet... and it all came down to the fact that Samsung implemented multitouch differently than Motorola (Motorola seemingly did it in accordance with the Android dev specs... Samsung apparently didn't?!).  As a developer, there would be no way for me to know this unless I physically had both of these devices... and this is a major problem with deploying games/apps on Android without having hundreds/thousands of Android devices to test against.  As a small indie shop, this means very unlikely to fork up all this cash for devices just to get meager amounts of downloads in Google Play market.

I can definitely feel what Mika Mobile is talking about as we've run in to these barriers as well.  It isn't impossible, but it sure raises the bar for "quality" (ie, not crashing/breaking) apps to have widespread deployment on the Android platform.

Wednesday, April 11, 2012

Getting the "density" of your Android device

This is one of those crazy small things you'll be needing sooner or later in game development on Android devices.

How to get the "density" of your device?  Or more specifically, how many physical pixels are there per inch, how big is my display?

Well, first of all, we need to get data from our device.

DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);

That will fill in everything we will need to know. From there, we can get all sorts of useful information.

How many pixels can we work with horizontally and vertically?  *Warning*: These are filled in based on the current orientation of the device!!!
xpixels = dm.widthPixels;
ypixels = dm.heightPixels;

How about pixels per inch on the display?
xpixelsPerInch = dm.xdpi;
ypixelsPerInch = dm.ydpi;

If we know how many pixels are given in a dimension, and how many pixels there are per inch, we can determine the exact inches of our display (more or less).
displayWidth = xpixels / xpixelsPerInch;
displayHeight = ypixels / ypixelsPerInch;

Now, for the part that can be a little bit more mysterious.  What about the actual "density"?  Well, in Android API 4+, our DisplayMetric (dm) has a property conveniently called "densityDpi".  This is well and good for Android 1.6 and beyond, but what about our poor Android 1.5 customers where this field didn't exist?  Fear not, we can still get this information!

There is a field called "density" which is a floating number based on the scaling factor of our pixels in comparison to a 160 DPI device.  In other words, if our device is "160 dpi", this scaling factor is 1 (160/160 = 1).

Common DPIs for Android devices are: 120, 160, 240, and 320.  Knowing this, we can now cater to Android 1.5's missing densityDpi field by making our own.
if (dm.density == 0.75)
    densityDpi = 120;
if (dm.density == 1.0)
    densityDpi = 160;
if (dm.density == 1.5)
    densityDpi = 240;
if (dm.density == 2)
    densityDpi = 320;

Normally it is NOT a good idea to do a straight floating point equality comparison check (rounding errors, precision point problems, etc), but in this case, there shouldn't be any issue.


Correction: Do not do it this way.  We recently received a problem report from a user with a 148 density, which is seemingly not standard.  I will leave this code in here for illustration and so that the reader gets an idea of catering to different hardware displays.

The following way is how you should calculate the density.

densityDpi = (int) (dm.density * 160.0f);

*Update* 4.29.2012 : Added the note about a user with a 148 density.

Monday, April 2, 2012

So many Android devices to cater to...

In follow up to my earlier post about being envious of software houses of yesteryear, I have to admit that in a sense, they had it easier.

When they made their games and products, they had a single target system with known specs and limitations.  Code that relied on *timing* of events and things like this can be planned for meticulously.  Developers also knew 100% ahead of time what features a system did or did not have.  Yet, they also dealt with 8-bit / 16-bit processors, no FPU, no advanced graphics pipeline, and all sorts of "limitations", and they still cranked out great products after great products all without needing all these patches and what not.

Well, fast forward a bunch of years, and here we're in the age of the smartphone.  In some regards, we have it easy - a powerful CPU (relatively speaking), an amazing graphics processor, and sometimes a FPU.  Wait, sometimes?!  Yes, that's right, if you're a developer for the Android platform, you can't be guaranteed to have a floating point unit.  You also have no guarantee of having any given amount of RAM, disk space, or really much of anything.  Sure, you can *use* float data types, but on devices with no dedicated float processor, it is software emulated!!! Talk about a massive performance hit if you want to do updates and renders at any sane framerate!

Our earlier game, Bubble Zing, ran amazingly awesome on newer Android phones, but on older phones, it ran terribly.  With the 1.0.3 release of the game last month, we thought all major compatibility issues were resolved; well, that was only partially correct.  The major bugs seemingly were ironed out, and the core game "worked", but with no guarantee of how well it would work - sometimes outright unplayable on some devices!

So, we delve further in to the "why is this running like terrible on x,y,z,q,f devices, but great on others".  Well, this is where the things Android does is both great and bad at the same time.  We coded 1.0.3 in 100% Java as this was seemingly the correct way to make any app on Android devices.  In theory, it sounded good since Java apps are suppose to work 100% on devices with a compatible JVM (ie, all Android devices) - clearly something we wanted, and it is fairly easy to crank a Java program much faster than an equivalent C/C++ program, so it sounded like a great idea at the time.

Our test system was a Droid RAZR with Android 2.3.6.  Our initial testing was running well, FPS was over 40 and everything seemed great.  The emulator running an AVD 1.5 seemed sluggish but that could be written off as being an emulator and running not on the most powerful host computer.

Things got really confusing and exciting when we tested 1.0.1 and 1.0.2 on a Samsung Galaxy tablet -- that's when all hell broke loose.  Everything that should have been working in theory wasn't.  On top of that, the frame rate was a dismal 10 to 15!  What the flying expletive!  How can a program go from 40+ FPS to 10!  It wasn't an issue with the version of the Android OS, it must have been something device specific.

I ran a traceview to track what was eating all the processing time and it came down to rendering a full screen background PNG file.  On the phone, this wasn't such a big deal, but on the tablet, it was eating almost 60% of all CPU time!

We're sitting here with a complete Java game that worked ok on an emulator and great on our target test phone, yet are dumbfounded with why the same exact Java code on the tablet ran so terribly.

A lot of trial and error later we figured that to get things working faster and better, the only way was to ditch Java and start programming on a closer-to-the-hardware level as we could to squeeze out a lot more performance and manage memory more effectively.  Java made it very frustrating with garbage collecting at some fairly inconvenient times and this compounded other issues making the game run very badly at certain instances.  It was time to bring on the NDK.

Frustration is what is in store for Android developers.  It can be done, but good apps will need a very persistent set of people to make these products and make them well.

Oh, and I'm still in awe of game programmers from decades ago on consoles, but at the same time, I'm jealous of their "single architecture" deployment platform as that probably simplified a lot of these problems thousands fold.  I suppose this is another reason Apple is winning the smartphone wars with developers as it is "easier" to make apps on iOS with very heavily controlled hardware features by Apple.

Thursday, March 29, 2012

Android NDK loading resources and PNGs

After following the nice code sample from http://androgeek.info/?p=275 about how to load a PNG file by accessing the Android APK file directly using only the NDK, everything seemed awesome.

It uses libzip and libpng to manually load the APK, then load a png file right from the APK itself without using any Java or the Android SDK.

Why would you want to do this?  Well, aside from liking complicated stuff, it is useful for us because now we can put all of our "portable" resource loading code in c/c++ files so it is more easily moved to iOS, windows, whatever, without being bound to using only the Android SDK, thus having to recode loading logic over and over again for each target deployment architecture.

Everything worked well, until something didn't go quite right.  Some of my textures were corrupted and worse, some actually crashed my app!

It took 4 days to track down what exactly was happening.

Common problems usually indicate I was doing something wrong with opengl and the textures themselves...

* All my textures were perfect powers of two (64x64, 128x128, etc)
* All my textures were 32-bit RGBA files
* I fixed a warning and error from the given sample code to correctly read the libzip'd apk file

So, it was time to dig deeper with what was going on.

First, I noticed that my glGenTextures calls were giving me very large opengl texture ids so I thought this was a huge problem as it was not continuous numbers, and in C, any time you have generating wild numbers, it usually means a bad pointer somewhere.  I spent about a day analyzing and referencing code and started to realize that the generated numbers were always the same (this usually rules out a memory corruption issue if the results are *always* the same).

I noticed that the generated opengl texture ids always followed this pattern on my Droid RAZR:
100271
315638026
534244737
1505553200
-1563003837
...
etc.

Yet, on my Android emulator, the texture id's were:
1
2
3
4
5
...
etc

I had found this thread on google groups that I thought was my problem since it sounded really similar, but it didn't actually help.

Knowing that glGenTextures expects an *unsigned* integer as the data type, I realized that the negative number was an overflowed signed integer and actually nothing to worry about.  In my debugging print code I needed to change "%d" to "%u" to see the actual unsigned value.

Since these numbers repeated on every subsequent run of the program, I decided to test the idea that maybe my code had nothing at all to do with the "corrupt" large texture ids.  Indeed, I made a program that literally only called glGenTextures about 100 times right at startup time and did nothing else.  The result?  The exact same large numbers showed up in my device, and was "normal" on the emulator, as expected.  This left me with the conclusion that whatever logic is in my Motorola device in terms of picking a unique texture ID that this was normal - next.

Yet, this didn't answer my question as to why I was seeing an app crash occur and seemingly only when loading a certain texture or two.  My first order of business was to rule out if my other code was at fault, or was it somehow related to ONLY those sets of textures (somehow). Strangely, dozens of tests indicated that it was only the problem of 3 specific textures being loaded as I added lots of additional textures, even loaded some textures multiple times, then finally ONLY loading one of those 3 problematic textures.  The app would only crash at loading any of the 3.

Frustrated, I ended up putting a ton of extra debugging code all over my apps trying to track down what in the world was wrong.  All indicators were pointing to the idea that a problem was with either libzip or libpng since libc.so itself was crashing in a call to a libpng function -- great, time to track down potential bugs in those libraries.

Now, let me put a disclaimer up here, it is almost never a good idea to assume a mature code library has a bug in it; especially one this severe, yet here I am with a consistent crash always calling a specific line of code that libpng was using leaving me to believe this could be the case.

First, I downloaded the most recent version of each library and replaced the old versions that were provided in the linked post above.  I was now using libzip 0.10.1 and libpng 1.5.9.  This had promise since each of those had a bit of fixes/enhancements along the way.  I was hopeful that this would magically fix my problems.

Well, it did - sort of.

Whatever wizardry was happening internally in those libraries helped indicate that libpng was crashing specifically on this line:

png_read_info(png_ptr, info_ptr);

Great, all this work only to help reinforce the idea that libpng was broken for my special case.  Yet, I still couldn't rule out that libzip somehow corrupted my image data while decompressing my APK so libpng might not be at fault trying to load corrupted data.  Worse, all error checking came up empty for all libzip and libpng calls!  I even checked my opengl calls for errors using glError -- NOTHING!

Well, the next step was to dive in to those library's source code and start tracking stuff down, the last resort I guess was to find the problem in one of these libraries and fix it myself and give the respective team a patch!

One of my testing tangents included making a stand alone C project to test very specific sets of code to completely rule out any Android Java JNI mysticism causing problems.  Everything was pointing to only those textures being a problem in the libpng loading code.  So I ran the libpng test program on those 3 test pngs and the only thing that sounded remotely threatening was:

Files aaaa.png and pngout.png are different
Was aaaa.png written with the same maximum IDAT chunk size (8192 bytes), filtering heuristic (libpng default), compression level (zlib default), and zlib version (1.2.5)?


It certainly sounded menacing and I was convinced that somehow my textures were corrupted.  I ended up regenerating those textures using the latest version of Gimp (2.6.11 at the time) -- plugged those in to my app in excitement; and they still crashed.

Strangely, the libpng test program generated pngout.png which was seemingly the same exact copy of my original texture, but a different filesize; something was different, and different was good at this point.  For giggles, I put that pngout.png file in to my Android's APK res/raw folder in place of my original texture and much to my surprise the texture loaded!!!  Ah-hah, the answer finally!

Unfortunately, things weren't over yet, the texture loaded completely corrupted.  Everything was misaligned, the colors were wrong and the texture was completely garbled with random colors all over it.  Basically, I've gone nowhere.

3 days in and I'm still struggling with what is wrong here.  I'm still baffled, why is it that my 10 other textures work fine, yet these 3 don't want to work at all?!  I decided to write my own texture loading function from scratch to ensure I understood exactly every step of logic that was taking place.  The same result happened.  I did all sorts of strange additional tests, hex dumps, you name it.  I was at the end of my rope on this one, I was getting angry.

Finally, I saw an interesting article somewhere that said I needed to rename my png files to mp3 files.  I thought to myself, that's the dumbest thing I ever heard - why would I ever want to do that?!  Well, if you're programming for Android, you might be crazy enough to hear this out.

Apparently, during the APK packing process *SOME* of your png textures are automagically compressed and others are not.  Renaming your png files tells the apk packing process to not mangle/compress that file, and my happy 3 textures were some of the lucky selected ones for this process; which completely broke the texture loading code.  In a move of desperation, I did rename my files to mp3 to verify this was the case, and they worked perfectly.  I was enraged and ecstatic at the same time.

On the bright side I got a better understanding of both libpng and libzip (we got a little familiar with each other, if you know what I mean).

Alright, so the magic bullet answer is that I need to rename all my PNG files to MP3 (test.png.mp3 if you will) or simply dump them all in to a game data file of sorts (probably the better idea).

So, I make a quick resource packing program (using zlib) and I find out that during the APK packing process again, my GZ files are also modified!!!

I quickly found this link explaining it a little bit.

I wonder what other goodies are in store for me to discover by accident!?

Hope this article is found by anyone else stuck in my situation and save you all a couple days of madness.

Friday, March 2, 2012

Awe at software development houses of yesteryear

After making another small game, I can't help but be in total stupor over how... easy software houses have it today.  I mean, seriously, back in the day when I was playing things like Nintendo way more often than I should have been, I never even thought about how much time was invested in to making all those games I played.

Back then, it's not like game dev houses could just send out a patch to fix things over the Internet.  When products were shipped, they were shipped for real!  Imagine, this had to be the final product, no going back; we're about to manufacture millions of cartridges and customers will get their hands on all our hard work, period, no going back.  Dev houses had to be pretty damn sure that what they were packaging up was 99.99% perfect.

Ok, a company probably could have done a product recall if the game was horrendously broken, but honestly, we just "shipped" Bubble Zing yesterday, and I already found 2 or 3 small bugs that should be fixed!  Talk about maddening for the devs of yesteryear!  Now granted, we made that game in 3 weeks with a really small team, but still... it is mind boggling to know that these guys did it, and did it well is stupendous... well, for the most part... games like Action 52 did exist, and that was... well... a broken down mess incurring the wrath of gamers lucky enough to play it.

If you're unsure about Action 52, check out James Rolfe's review of it on cinemassacre, it is pretty funny.  James, being the "angry video game nerd", can be a tad vulgar (just a little), so if bad words offend you, you might want to stay away from his review.

On a side note, I guess this would help explain why no version numbers were prevalent in old games, no such thing was important because what you got was it!  In rare cases, a second or third production run was accomplished and it was during this time a dev house could slip in a revision copy of the game, fixing a couple things, but still, we almost never saw any indication of what version number our copies were running.

So yea, one of our products just shipped and I'm already getting a laundry list of things to put in to a patch within the first day of release!

Thursday, March 1, 2012

Design to Product - Post-Production (17 / 17)

Now that the product has been released, it is time to look back, recollect on lessons learned, and already be buried in to the next adventure.

If you took a look at the game design from the previous section and took a look at the game video (or played the game itself ideally) you might notice quite a few discrepancies from what is described in the document as opposed to what actually was developed.  I cannot stress enough that this is what happens.  Throughout the articles I talked about stuff like requirements creep, play testing, and things like this.  Pretty much all of those things happened, we applied our creative process on to the original game design, and ended up with the product you [hopefully] saw.  Yes, we were bad and never updated the original document, but we also ended up preserving what we started with, and what the end result was.

During development, and using the design as a guideline, we also took a bit of time discussing what features were necessary as opposed to being acceptable for future updates.  One of the fairly easy features to figure as "something for later" is code optimizations.

The game needs to be playable, some minor speed enhancements are ok during development, but finer tuning the engine performance isn't required to get the product completed.  Thus, these things are "nice to haves".

We will also be tweaking some graphics, offering different qualities of game resources, and changing things like timing, based on customer feedback now that the initial product has been released.  We did some basic play testing while the product was under development, but we admit that we are a bit subjective with what is and is not "good" from an outsider's perspective.  Therefore, we will also not rule out "customer feedback" as a guiding principle in what we will still do to the product in to the future.

Of course, some of the blatant things we will work on is when the inevitable "omg this doesn't work on my phone/tablet" feedback comes in.  This is expected to happen and we just await the first complaints.  There really is no way to guarantee that our software will work on all of those device configurations short of us physically testing our product on all hundreds/thousands of them ourselves.  Yes, we can use the emulators, and we do, but this is different than using the actual devices.  For example, it is impossible to test application performance against an emulator if the emulator itself is at the mercy of the power of the computer in which it is run against... this complicates accuracy of the performance testing.

From here, we gaze out in to what we will accomplish with this product.  Minor feature corrections, product enhancements, and possibly even small new features will likely occur and we will be delighted to integrate those things as they happen.  Any major new thing will either warrant a re-release of the product in the form of "2.0" or possibly become a whole other product all together.

At the end of the day, version 1.0 shipped and now we can expect all those hundreds of pennies to come piling in over the months/years it is active in the market!  The product that went from "design to product" took just over 3 weeks to go from start to finish and only time will tell how much money we will gain or lose in the bigger picture from this endeavor.

Design to Product - Release (16 / 17)

Release time is around the corner, some things you might want to check over:

  • Take several screenshots of gameplay, use them for marketing purposes
  • Save local copies of everything, and I do mean everything, then back them up somewhere
  • Make sure the release version number is correct in the software and documentation
  • Do one last final general test of the product on your deployment platform

Once everyone on the team has given the thumbs up for release, it is time to package everything up, do one last sanity check over everything, and then publish the product!

Below you will find our original design, screenshots of gameplay, and a link in to the Android marketplace where our product, Bubble Zing, may be found.  This product was in development over the duration in which these series of blog articles were written and took approximately 3 weeks to go "from design to product".

Game Design:
Bubble Zing Design (pdf)

Screenshots:
Menu Screen

Gameplay

Gameplay

Oo, a heart!

Gameplay

Options
Video of Gameplay:


Bubble Zing:
https://market.android.com/details?id=com.eondev.bubblezing
http://slideme.org/application/bubble-zing

Design to Product - Software Testing (15 / 17)

When is a software product "finished"?  This all depends on who you're asking and in what aspect.  One of the crucial aspects of software houses is testing.  Unlike play testing where people have the potential to have fun with the product, software testing is mostly the opposite.

There are several types of software testing, and this article isn't meant to be a definitive guide on how to perform this job, but I will give a quick run down of what it means and what we do.

Data Validation
During any testing, are the proper inputs handled?  This should be one of the first questions that arise.  Of course, what is good input data, if we can't throw some bad input data in there to spice things up.  Data validation is the process of testing software against good, bad, and unknown data.  What happens when that 0 or 1 input was actually a -1 as input?  Does the program blow up?  We won't know unless we test it!

Unit Testing
This is basically the smallest form of testing.  Do small units of logic perform as expected.  This usually means I test a specific function or method and if the resultant output from that logic is what is expected, I could say that this unit test passed -- it performed as expected.  This testing is more or less automatically performed by the programmer as code is written, or at least it should be!

Performance Testing
Does the software do what it is suppose to do, and do it fast enough?  We may make the next best game ever, but if it runs at 8 frames a second... that's probably bad.

Compatibility Testing
This can sometimes go overlooked (especially on Android phones!), does the software work on multiple different configurations?  Are there weird effects?  Specifically for Android, will the product work on a phone, and an Android tablet?


Acceptance Testing
This is like Software Quality Assurance or Quality Control.  Does the software deliver, on a high level, what the design is?  Think of this like a marriage of software testing with play testing.  Does the product allow the player to actually play the game as designed?  Does the code actually allow for the player to launch new marbles and perform all the functions needed to play?  If these are both yes, then it passed both the play test, and the software test, this the product can be accepted as the product.

For more information about testing, validation, methods to perform them, etc... really, we encourage you to look at the wikipedia article here: Software Testing.  The trick is to find what works for you and use that.

Design to Product - Play Testing (14 / 17)

We constantly do general "play testing" - or rather, a general form of playing the game and noting any discrepancies that happen.  This could be referred to as finding bugs, but really it isn't.  It serves as a way to see if the game is any fun, if the design is "good" and what may have been overseen as pitfalls earlier in the design stages of production.  Can things be improved? Does everything "feel" right?  Are there overlapping aspects?  Simply put, this form of testing finds design flaws not software flaws.

This method of testing happens all throughout the development of the product.  This is by no means the only form of testing (nor should it be), but instead gives us the ability to second guess some of our designs as it is being developed and explore some options before publishing the product - more on software testing coming later.

One of the fairly humorous aspects of this is that back in our article about the graphics design where we showed the proposed layout for the game, we had big black circles at the bottom of the screen above the ads that indicated where marbles would occupy.  These "slots" were to be used to launch marbles from.

During the development, we ended up shrinking those slots to about half that size so that the launcher graphic underneath could be seen more; since we made those graphics, may as well have people see them, right?  Well over dozens of play tests, we found that it was difficult to correctly touch and drag marbles from those slots and be able to actually play the game.  We ended up increasing their sizes back to the original layout sizes - taking up the entire height of the launcher.

The gameplay became much smoother and easier to drag marbles out, but the launcher graphic isn't seen easily, yet overall, the game is now smoother and the user should have an easier time actually playing the game; rather than seeing some eye candy.  Aesthetics versus function is the issue here, and we chose gameplay over showing off artwork.

This detail was really only found after performing a lot of play tests and from different people.  The general feedback was "we like this... but...".  This should be taken seriously and addressed during development.  Yes, the catch phrase of what users say can take a lot of extra time to implement.  Fortunately for us, the slot sizes in this case was easy to change because only two variables controlled the width and height of the slot which "magically" handled both the visual display, and the collision detection of the user input.  If these values were hardcoded, this could have been a fun hour or two adventure hunting down and "fixing" all the math that referenced the slot sizes.

When your friends say they want to be game testers, this is generally what they mean without actually knowing it.  They want to be play testers, not software testers.  Unfortunately for them, usually play testing is a team effort and isn't a dedicated job.  For example, this is why software publishers utilize beta tests, they literally outsource play testing to users and gather feedback about the design of the game in a distributed manner -- if they find actual software bugs as well, that's a nice side benefit, but in reality the primary purpose is to assess the value of the design of the product.  It is also a nice way to get the word out and serves as a nice marketing gimmick, but that's a whole other issue.

Wednesday, February 29, 2012

Design to Product - Software Design Pt 2 (13 / 17)

After coding for a bit, redesigning, testing, then coding some more, we ended up with the basic elaboration to our software design.  Please note that this is a live process.  In other words, when we found snags, re-analyzed what we were doing, and asked ourselves how we could go about doing it better, we scrapped some work "for the greater good" (whatever that means).

So, here is a breakdown of the major classes of the project and what they do on a conceptual level.  Normally a UML diagram or something here would be sufficient, but we're renegades like that.

Bubble
This class deals with every "bubble" in the game.  The gameplay is such that new bubbles are spawned at the top of the playing field and slowly descend towards the bottom of the screen.  This class handles the updating process (how much and how far does each bubble move), as well as drawing each bubble.  Each bubble also has a value which pertains to its assigned color  (which is randomly assigned in generation).

For some static functionality, this also handled loading all game resources associated with bubbles (like the bubble graphics themselves).  The most important point here is that all graphics should be loaded once and only once then drawn per instance of a bubble.

Gamedata
This is a convenience class that handles persistent data about the game itself.  Specifically, this remembers the player's options whether to have the sound on or off.  Originally, it was designed to also keep track of in game purchases with points, but as the design evolved, this feature was removed.  Because all of the "persistence layer" stuff was conveniently packaged in this one class, adding and removing new things is easy.

GameThread
The bulk of the higher level stuff is in this class.  Big questions are handled here, like "is the player in any menu", what to do when the player wants to pause/resume the game (this is the in game feature, not the activity pause/resume), high level resource initialization, the game loop itself, touch event propagation to support classes/objects, and things like this.

This class also handles the Android lifecycle events of pausing and resuming, which is completely different than the in-game feature.  We put this functionality here because it has high level access to basically everything in the actual game logic that needs to know about activity life cycle events such as these.

GameView
Not too much to say here other than this is our version of the SurfaceView class used by Android.

Marble
Like the bubble, this class handles everything that has to do with the player marbles.  These marbles need to be updated every game cycle so they have an update method, need to be drawn on the playing field, and need to be spawned based on player input.

There are some methods that let us query what kind of marble this is.  Specifically, is this a "normal" marble or is this a "special" marble.  In the gameplay, normal marbles are simple red, green, blue, yellow playing pieces, and special marbles are just that.  They do things that normal ones don't.  The game design had changed over development - originally, we had rainbow marbles, rocks, purple marbles, and heart marbles.  This changed to only have rocks and purple marbles (more on this in the post-production article later).

At any rate, this class is very similar to bubbles and share the same design, but different code from each other.


MarbleSlot
This class is "part of" the playing field.  This handles the player's desire to launch marbles from it.  Each slot contains a marble value and when it comes time, the playing field spawns a new marble based on which slot the player initially touched.

Logically, these slots are just defined zones in the playing field that define whether or not the player touched a specific area and don't do much else other than that.  Based on the assigned marble value, it also draws a colored marble to represent what marble will spawn when interaction occurs.

PlayingField
This is the over-arching class one step down from the game thread itself.  This "contains" every intractable aspect of the game, all marbles, all bubbles, and even the GUI while playing.  This large class handles all the essential gameplay logic to include setting up a new game, actually creating new marbles from the slots, propagating update method calls, propagating draw method calls, increasing player marble stock, harming the player, resource management, and lots of supporting methods - including collision detection/response.

From the game thread, a playing field instance is created and basically sticks around until the program is considered "finished".


PlayingPiece
This class is a parent class to Marbles and Bubbles and defines what exactly makes them playing pieces.  The class defines a collision flag (used for collision detecting), a velocity vector, a RectF object used to define piece positions (and drawing boundaries), a method to calculate the distance to another playing piece (used again for collision detection between marbles and bubbles), and some convenience methods shared by marbles and bubbles.

Almost anytime there is overlapping features or methods used by more than one class, it is almost always a good idea to create a parent class.  Essentially, this is like saying "ok, so, we have this cool new game, it involves some playing pieces that collide with each other"... what does that mean?  Well, those pieces are either marbles or bubbles and their interaction with each other.  Excellent candidate for a parent with two children sort of situation.

Wednesday, February 22, 2012

Design to Product - Software Design (12 / 17)

Finally, let's talk about how the code should be set up.

We mentioned earlier that we took the game design, analyzed it, and figured that nouns become classes and verbs become methods.  This sounds good on paper, and there are even tools available to help this process.  We could sit around and chart UML all day, every day in regards to the design, but is it necessary?  That depends.

Because our product isn't an enterprise solution, our team is small, and one guy is basically doing everything, a massive UML chart isn't really necessary.  Of course, we could never discount the idea that someday in the future these things could become useful (like if we sold our products off to another company, as an example).

Regardless, the best way forward for us is to pick apart the major components of the design and start designing what logic should go where and what it should be called.

Honestly, because of our development methodology (or lack there of, depending on who you ask), we take more of an extreme programming measure in this regard.  We make classes as we need them.  We start with a basic skeleton framework, then start adding new classes as they are needed in the code itself as we program the meat and bones of the product.

We start with the largest classes in the skeleton.  Specifically, for Android programming, we start with the GameActivity class.  This class acts, more or less, as the "starting point" for the program and interfaces with the OS.  Because of how Android itself is designed, we must make a GameThread class that contains the top level logic for the flow of the game itself.  We also will need an extension of a View class so that we can interact with the screen and display stuff.

Right away we have:
GameActivity
GameThread
GameView

Without really even going further, based on the game design, we know we already have 2 major components to the product, a Marble, and a Bubble.  These playing pieces are what are the basic, interactable things in the game itself.  Because both things follow the same physics, we decided that it is best they share a common parent class; PlayingPiece.  This parent class defines movement vectors, collision information, the abstract methods of how the pieces are updated and that each child class should know how to draw itself to the screen.

At the same time, we can't really play the game without some sort of logical thing to interact with and where the playing pieces do their magic.  Enter the PlayingField, a logical container that contains everything the player can interact with and see.

The game design indicates the need for persistent data over game launches, so we made another class Gamedata that is our "middle man" that handles data saved and loaded between game sessions.

We also ended up needing a class called MarbleSlot, a place where players can touch and interact with the playing field in which marbles can be spawned from.

All that said we now have:
Bubble
Gamedata
GameThread
GameView
Marble
MarbleSlot
PlayingField
PlayingPiece

There are one or two utility classes that are used to assist in the passing of data and messages between classes, but those are fairly technical and don't have anything to do with the direct design of the content of the game.  Suffice to say, those can take a while to design and program as well.  Just because a game design is "simple" doesn't mean the work behind it will take a set number of hours based on the relative ease of that design.  Lots of "stuff" can go on behind the scenes that can take days or even weeks to implement that have no actual, obvious visual effect on the product itself.

For example, a programmer could spend a month just drawing some graphics on a display.  They are very proud of this accomplishment, but to non-programmers they usually have the attitude of "you spent a month on this, and only have this to show for it?!".  Get used to scenarios like this because it happens more often than not.

Anyways, now that we have our basic classes determined, the essentials are fleshed out.

Tune in next time for elaboration of the class designs and the overall flow of the logic for some of them.

Tuesday, February 21, 2012

Design to Product - Requirements Creep (11 / 17)

While designing, programming, and testing, we came up with some new ideas of how to make the game better.

The dreaded phrase "ya know, this would be cool if...".  Yes that.  What just happened is something called requirements creep, or rather, features and things that were not part of the original design document, but have become desired enough to "add in" some extra things or at least change a couple of things that we had already designed.

This sneaky way of adding new things in to the product forces us to change code, update documentation, and start our testing all over again with the new things put in to the product.  Long and sad story short, it simply means more time is required before the product can be released.  WARNING: If this gets out of hand, your product will be delayed indefinitely as more and more new things keep getting piled on!

Fortunately, some of these sneaky new features that were drafted up can wait until after the game is released and we can put the new content in with a content patch later.  If you've been reading along, during an earlier blog article I mentioned separating things that we need versus what we want.  Requirements creep operate the same way.  What must we absolutely have to have in the initial product release versus what can wait.  There is a risk involved with this.  The more we "must" have before initial release, the longer the product will take to get out the door... but if those new features really enhance the product and make it more appealing or playable, we certainly should include it.

For example, during our play testing, we saw that most the gameplay levels were "too easy".  The player could easily fly through the game levels without much of a challenge.  According to the design, this was basically as the product was designed.  Well, unhappy with it, we decided that different sized bubbles should play a part of making the game more difficult as the game levels were increased.  This new "feature" wasn't part of the original design - nor was the existing code ready to make such a new leap in to catering to differing size bubbles.

Because we felt that this sort of thing should be required to make the game more challenging and offered in the initial product, we accepted the new feature, and the recoding of the necessary systems began.

Since our code was relatively easily adapted to the change, it took about 4 hours to modify the existing code and test it to approve that the game now has incorporated the changed feature.  If your software person/team is inexperienced, or the code you've inherited is "bad", even a simple change like this could take days to implement.  You may scoff at this idea, but I will reiterate my earlier warning, even the smallest things can take a dreadful amount of time to incorporate.  Even something as so much as changing the color of something can take a very long time - it all depends on how the software was designed, their existing features, and how well things were programmed, and of course there could be other unforeseen technical problems further complicating the desired changes.

During our testing and development, we also found it necessary to upgrade our core code reuse library to incorporate more graphics utility functions because of the demands on this product.  This took a couple extra hours to research, code, and test.  The tradeoff is such that now projects in the future can reuse this code, saving the time and headache later of having to redevelop it again.

While programming a game, or really any software, the programmer should always be aware of what they are making could be generalized in to useful and reusable modules for other projects.  There is, again, a tradeoff to "just make this feature" and "generalize" it for generic use.  It usually is quicker just making the solution once while specifically tailoring it for the one active project, but if another project needs that functionality, it takes more time later to surgically remove that code from the project and alter it later for the newer product.  The experience of the programmer here will help them dictate when and what they should generalize.

A specific example of this - one of our products that hasn't been released yet uses a feature to flash the screen red when the player takes damage.  During the development of the new product, it was mentioned "hey, it would be nice to have a visual indicator for when the player takes damage".  It was quite apparent that the code from the older, unreleased project should be recycled in to this new project.  Of course, this functionality wasn't generalized in to a code library; however, the existing feature was found to rely on almost no external variables in the older product, and the code was easily extracted from the 3 different functions that it was hooked in to.  There were a couple of dangling variables that was required for the code to work as well, so there was some time needed to track those down and copy those over as well.  These variables had to do with the time involved with "how long to flash the screen" as well as "how much red is flashed at a given time".

If the older code was sloppy, or had I not been intimately familiar with the code, a job like this - tracking down code/features to extract - can take a while.  This is something that shouldn't be taken lightly when planning how long a product will take to develop.  Code reuse is good and saves time, but if you have to attack another product with a scalpel to find all the code to reuse, it can be a nightmare in itself.

Ok, so, we had a requirements creep with the flashing feature.  It took about 30 minutes to track down our existing code to make this happen and we integrated it in to the new product -- in theory.  Remember, we need to test the new code to make sure it wasn't rejected by the new product!  Sure enough, we attempted to test it; and nothing happened when it was suppose to.

A quick "oh duh" moment later, and we realized we forgot to call our new flashing code when the condition warranted it.  We integrated the code, but forgot to actually use it.

We decided to call the new flash code from inside the method where players take damage and decided to test it again.  Huzzah, it worked!  Not only did it work, but it worked as expected!

Long entry, but take away from this that new things, small things, and even big things can, and will, come up during coding and testing.  Some of these things fall in to the "need to have" category and can add substantial time involved in to the development of your product.

Next time we'll get in to the software design aspect of the product, I hope!



Sunday, February 19, 2012

Design to Product on Android - Delays (10 / 17)

During our software design and programming of the app, various delays have already been cropping up.  Specifically with the business side of the house.  We've been meeting with people and potential contractors for other projects we're working on.  While ultimately this is a good thing, it does take a toll on the direct development of the project.

Truth be told, these were fairly predictable delays and were taken in to account during earlier phases of planning.

In other good news, we acquired a music track that will be placed in one of our products.  In addition, we have been created more artwork and content for this new product.

Er, instead of going in to software design next, we'll be talking more about a prevalent issue with software development - the requirements creep.  A dreaded topic in all software shops and definitely something of prominence in the games industry.

Wednesday, February 15, 2012

Design to Product on Android - OMG Code, well almost! (9 / 17)

Ok, finally, we're talking about the core of app development, the coding!

First, I must emphasize that it is probably in your best interest to consider using an app library, or writing your own.  This will substantially cut down on the time needed to make a game (or probably any app for that matter).  Of course the trade off is learning the external library, figuring out its limitations, and making new products with it, which translates to more initial time involvement, but could pay out in the end.

As for us, we developed a small game library that has some very basic code all wrapped up in to a tiny, neat package.  It mostly allows us to mangle with time functions, "button" code, random numbers, and some other graphical utility functions (like getting the current display orientation, the density of the screen, the screen dimensions, etc).

If you make your own library, like we did, I highly recommend putting any and all code that you think is generic enough that *all* projects of yours in the future could want.

If you didn't already know, you will have to have some way of writing code.  We recommend using Eclipse with the Android SDK, it's free, works, and packs various useful conveniences while developing.  You will also need someone versed in Java and able to use the Android SDK.

If your person doing the development is new to Android, Java, or both, we highly recommend making some test projects first, before attempting to make your dream game/app.

It is our intention for this to not be a tutorial on how to make an app in detail, but rather talk about designs and coding specifics instead, more or less from a management perspective/process.

Ok, so once we have our IDE all set up, we can look over our game design and start plotting how we want to design the software itself.

Different software process methodologies deviate greatly in this area, our studio essentially identifies major topics/nouns used in the design of the product and USUALLY makes an assumption that those will be Java classes.  I mentioned *usually* because this isn't always the case and we also do not use any automated tools or UML or anything goofy like that.

Instead, we look at the major concepts of the design and turn those in to classes first.  Specifically, we know that we will need a PlayingField where by all "game playing" will take place.  That becomes a class (and a very useful one at that).

Because of how Android works, we must have an Activity class.  From there, we also must have our own SurfaceView class (we implement a GameView class that inherits from SurfaceView), and a class which encapsulates the main processing of the game.  We make a GameThread class that inherits from Thread so that all our game processing can take place on its own.

So, without really getting in to picking apart our design, we know we have the following classes already:

GameActivity
GameView
GameThread
PlayingField

While we pick apart our design and start coding, the blog will be inactive for the next couple of days.

Monday, February 13, 2012

Design to Product on Android - Art Design (8 / 17)

Ahh, what the game will look like.  More importantly, how does the art work in a game title anyways?  What is the visual play experience?  Also, the design of the art had better match the programming capabilities of the game engine!  No point in making beautiful 3d graphics if the software you're making cannot do 3d anything!

For sake of simplicity, our studio is currently using mostly Inkscape (it's free!) for high quality Scalable Vector Graphics.  We have limited talent in-house for art, so this takes us a little while to "get right".

Android apps require some special handling when it comes to the artwork, specifically with catering to different graphics densities on various displays.  This means that ideally, we will have a couple different versions of the same piece of art so that displays that can do "high definition" can use higher quality graphics, while displays that are from forever-ago can still render something (albeit very pixelly - hah new word).

The design of the art should be such that the same art can be easily scaled up and down.  This requirement led us to Inkscape (or Illustrator I suppose if you wanna pay money) so that we retain ultimate flexibility with scaling stuff up or down while using the same piece of art.  Short of pixel art, vector graphics are simply amazing and save a ton of time later down the road when you want to recycle graphics.

To keep things simple, we usually try to make hard colored, cartoony like graphics.  The lighting and shading  usually translate very well to small display sizes, and that is a big bonus for small displays.

Something that we learned from our earlier title Blocks Away! Is that we can use a grayscale version of a graphic and apply colors (using a multiply colorfilter) to the graphic in the game engine, this reduces the graphics work needed by quite a lot if the graphics themselves are simple enough and don't require too much recoloring work.  For example, in that game, we used a single white block, then just recolored the other blocks in the engine.  For this new game, we will try to reuse this trick to save work on the art, but ultimately, we may need to have different graphics for differing colors of game pieces.

Regardless of what we do, we need to consider the design of the art itself.  Shy away from ultra realistic and super mega amazing high quality stuff -- it simply does not translate well to small screens of phones, plus the production time and cost involved can be astronomical for small studios if this is outsourced, meaning we sort of have to do this ourselves with out limited experience in this area.

Some of the graphics we're probably going to use are here, don't worry, these are just samples and are really low quality -- they are meant to be teasers, rather than directly useful to you the reader.  Let's not go stealing people's work now (something that is rampant in the app markets as it is anyways!).

Sampling of actual game graphics

I probably should have mentioned this in the beginning of this article, but our first step here was to more or less finalize what the game visual layout would be.  In other words, we took our doodles, cleaned them up, and made actual graphics that represented what the game layout would be.  Where does the ad go?  How much space would it take up?  Where is the playing field, how big is it relative to other graphical assets?  From there, then we started making the actual graphics that filled in those zones.

The pic here is our first draft of the layout of the playable game area and where stuff goes.  Naturally, this can change a bit over the course of development, but this serves us sufficiently for now.

Layout

As a bonus to this article I should mention a bit about display densities.  When first developing for Android, I was accustomed to dealing directly with pixel sizes and spaces.  This is not generally a good thing for the novice Android developer.

Each Android device has something called a display density, or how many pixels per inch exists on the physical display.  This is stupendously important for knowing about how your graphics work with Android apps (specifically for placing them in the correct position!).

A point of reference:

Low density (LDPI) -> 120 dpi
Medium density (MDPI) -> 160 dpi
High density (HDPI) -> 240 dpi
Extra high density (XDPI?) -> 320 dpi (used for tablets probably)

In other words, when making mobile apps and games, you will likely need code that handles each specific density because you definitely have no guarantee that all your customers will be running on the same display density!

For example, if you want to place a graphic "in the middle of the screen", what does that mean?  How do you know at what pixel location is the middle of the screen?  I will get to these answers during the development cycle in a couple of articles from now.  However, an honorable mention happened here because when designing your artwork, you will likely want separate graphic assets for each different density that exists.  This directly translates to additional time required to make your product, catering to differing hardware by your customers, and this is only the graphics end of the deal.

Next up, we will start talking about some code (finally!).



Thursday, February 9, 2012

Design to Product on Android - Game Design (7 / 17)

Finally, we can start making a game!!! Let's crack open our favorite Integrated Development Environment (Eclipse in this case) and start forging all that hot code all over the place... err wait, what am I going to make?!  Oh who cares, I can make a game/product on the spot!

Whoah easy there code vigilante!  Let's take a moment to actually design what we're doing first.  Again, in software engineering, lots of people assume that programmers just make code.  Well, that's nice, but there probably should be at least some documentation in terms of what are the features needed in a project to make. Programmers use this as a roadmap (and even a task list) of what they need to make.  Once made, it serves doubly useful as a checklist of what to test to make sure the product was made correctly.  Remember, at this point, we're not even talking about software design, just the content of the product itself -- not even code yet!

Of course, testing the product is a fairly large topic in itself as well and will likely get its own article.  Suffice to say, an acceptance test looks at a design, looks at a software product and then validates and verifies that the product is what was desired in the first place -- thus it is accepted as the product.

We will come back to game design on and off throughout the series.

*** Updated section ***
Originally, we did not post the game design here because it wasn't finalized, plus we didn't want the "spoilers" of the actual game getting out before we really thought the whole game through.  Since the product was posted, the finalized game design can be found here:
BubbleZing game design

This game design document was first linked when we released the product at the end of this series, but is now retroactively linked here for convenience.
*** End new section ***

Next up, let's start analyzing what kind of art specifications and styles we want to incorporate in the game.  Once our design was completed, we started toying with ideas of what it should look like, the theme, how to go about generating/acquiring the art assets.  So, next up is the design of the art itself.

Wednesday, February 8, 2012

Design to Product on Android - Risk Management (6 / 17)

In Software Engineering, one of the evil parts of making products is the Project Management aspect of the whole thing.  Ya know, the guys that always tell programmers what they can and cannot do; as well as how everything was due yesterday.

Well, as a small software shop, we have the luxury of being our own managers, for all its amazing glory, and huge amounts of risks.  Everything you do and plan for needs to be evaluated for risks, especially in software.  Even the smallest feature can take weeks to accomplish!

Before designing a game, think heavily about what features should and should not be part of a product.  Yes, it would be great if a game was a simulated virtual reality, or interacted with websites, or touched on databases all over the world to present a real time view of the world in to your digital dream of a game... but all these amazing features have tradeoffs in terms of time involved to make it happen, and problems testing/debugging.  Everything remotely complicated can take large amounts of time to make, and even sometimes simple things turn out to be a lot more complicated than originally planned.

Good project managers have a wide understanding of programming and should give lenient amounts of time to get anything done on software projects.  If this person is you, the rule of thumb is to take any time estimate for getting anything done and multiply it by 3 and that's probably more realistic.  As the manager gains more experience with more varieties of software features and products, their "expert opinion" will likely become more accurate over time.

But I digress, let's focus back on the Risk side of things.  This aspect of the software process is fairly complex but essentially boils down to assessing what is and is not an acceptable risk to take.  This can apply to lots of things, but for our sake, we will focus only on the risk of adding features to our small software project.  Throughout the development cycle, risk assessment and reassessment will happen, so this isn't like we can just up and say "yea, I'm done figuring out the risks for this project".  However, having a good place to start couldn't hurt.

Projects do not need risk assessment, but it sure can save you a lot of time, effort, and headache in the long run.  Unfortunately, it usually requires a well-experienced project manager to make this really effective.

At any rate, things you will want to assess for risks, specifically for games, is what features are worth the time investment.  In other words, what features MUST be in the product versus what features would be nice to have.  There's kind of a 3rd category also, what features can wait for a future patch/release... things that really should exist sooner or later, but can wait.

When considering features that must exist in the product, assess features worth the time involved to make, or can the design of the game change a little bit to cater to time constraints (budgeting, investors, your boss, bills, etc).  There is nothing worse than developing a feature in a product and realize halfway through that you will run out of money or time making it happen -- worse yet, your business may have already paid for supporting services and resources for that feature (art, music, etc), and now you might have to scrap or change the design -- huge waste of time and money.  This is why assessing risk is fairly important, it is an attempt to mitigate as much problems as possible before dumping a lot of effort in to things that really might never make it through to the end of the day.

Did I mention risk management happens throughout the project?  I did?  Let me say it again here, this should be a constant nagging during software development, not enough to drag you down and admit defeat before you start, but should be just close enough to have you on the edge of your seat.  Never be too proud to admit defeat (just 3 more weeks to get this done, I swear!).  Always think about how long things will take and, well, assess if it is worth the time and bother.  At the end of the day, is your hard work worth the risk of ultimately getting money for your efforts?

A specific example to watch out for -- "wow, this anti-aliasing on this button is so awesome cool, but it took me 4 weeks to make happen".  Yea, users will love that their button looks all slick, but if it took you 4 weeks to make happen, that was a lot of time wasted that could have been spent somewhere else!  But don't worry, you have a slick button... and 3 weeks of lost time to play happy fun make-up crunch time with.

"Uh, yea, we're gonna need you to go ahead and come in on Saturdayyy, mmkay... oh and, I'm going to have you come in on Sunday too".  Yes, it was from Office Space, but really, that is what is going to happen if you have to play catch up.  Risk management isn't the magic bullet (nothing in Software Development is) to solve all your problems with time management, but it sure can help give a better perspective on what is and is not important enough to dump a lot of time and money on during the whole ordeal.

Tuesday, February 7, 2012

Design to Product on Android - Game Doodles (5 / 17)

After yesterday's rant about the vision documentation, we sat down and started tossing ideas around for a new game.  We started out by saying what we can't do -- specifically, a project that doesn't involve complex graphics or animation, and to speed things up a bit, recycling simple graphics, and redoing and upgrading existing assets that the business already owns, specifically for art, but really should recycle anything and everything to save time and money.

If you're familiar with our catalog of titles, you know that we don't particularly have a strong set of visually intensive titles at our disposal.

On our budget, we can't really afford an animation house and lack the experience in-house to really make it happen... therefore, the design of the game had to involve basic elements and basic graphics.  More visual candy will come in time, but we'll work our way up.

That said, we began throwing ideas around about a board game, and a bubble popping game.  We went back and forth a bit, but settled on the bubble popping game (oh no, not another one of those!).  "The project" was now being fleshed out.  Attached here is our gibberish of ideas, which by themselves don't really mean too much, but combined with the talk we had back and forth, makes more sense to us.

The scans of the documents turned out "meh", but you get the idea, basically in the doodling vision stage, we put down ideas and jotted some notes while having discussions.  Here are scans of two of the documents we came up with.





The next logical step is to start creating the game design by combining the talking with these notes.  However, the next blog entry will reflect on Risk Management (arg, management stuff), then we'll get to the design of the actual game.