Showing posts with label game programming. Show all posts
Showing posts with label game programming. Show all posts

Friday, July 19, 2013

Game Programming and 2d Art, Part 3 (Texture Atlases)

Welcome to the final part of my series on game programming with 2d art assets!

The previous 2 entries are here:
Part 1
Part 2

If you don't know already, a texture atlas (also known as a spritesheet) helps game developers to display neat 2d graphics in to their games.  There is usually some sort of organization sanity happening with them as well, for example, all of the frames of animation for a player character would be in one atlas and its file name could be "herowalking.png" or something like that.

Of course, this isn't limited in any way, I've often used atlases that are just a collection of User Interface components usually in a file called "gui.png" -- it has all the buttons, graphs, meters, check marks, and all sorts of doodads, all conveniently packed in to one GUI atlas file.

At any rate, assembling a texture atlas can be extremely tedious.  You have to make sure nothing overlaps anything else, that all your texture objects can fit, you will even need to remember where you put each object so that a game engine can subsequently extract each object.  It is so much planning and tracking!

Thankfully, there is a program out there called Texture Packer.  It is a commercial product, but all in all, it's a nice, convenient tool to have in your tool belt.  I'll even go so far to say that if you make 2d games commercially, you probably shouldn't be without it!  It's reasonably priced as well for how much time and money it would save you.

Let's put it this way, I spent about 2 weeks making a command line program to extract texture sizes and coordinates and it was a pain to deal with.  On top of that, I was still relying on manually entering texture coordinates in to our games from that program's output.  If an artist changed any graphics, it would be a nightmare changing things all over the place.

This program keeps track of all that stuff, and allows you to output all that relevant information in to various game engine formats; or for us, even a generic XML data format!

Below is a screencap of what it looks like:





Honestly, it's pretty good.  There are a couple of features that would be nice to have; like manually being able to move texture objects around (or swap places with each other), but what the tool does is automatically find a place for your sprites in the empty atlas for you, so you don't have to sit around with a magnifying glass lining pixels up manually!

There are quite a few neat features as well about it, like automatically generating different scaled versions of your atlas (click AutoSD) for catering to different resolutions, being able to specify atlas geometry (like powers of two, max width/height, etc), and it can even import SVG files.

It takes a little while getting use to, but all in all, it's a pretty useful tool and saves us quite a bit of time dealing with artwork.

I have noticed that the windows and linux ports are a little behind the mac port, and again, it is missing a couple neat features, but all in all, it is useable and useful.

They offer a trial version of the program also, so you can check it out without having to buy it first.

Wednesday, May 22, 2013

Game User Interfaces

In my last blog post, I talked about the anatomy of a simple game.  The list should be fairly comprehensive for things that all games have in common.

It was pointed out to me that there, of course, are more nuances to games than just identifying what's IN them.  The user interface (UI) is sort of an important thing if people want to be able to see all that hard work you put in to making a game!

Technically, the user interface is part of the output of any software product, but the user interface is so involved, I figured it would be best to have its own post (after I left it out last time!) - phsaw, users don't need that!

Ok, let's break UI down in to a couple of components.

User Interface Design is the craft of ratios, colors, layout, math, graphs, art, shades, and all that other stuff that artsy people do.  Those people design what the user ends up seeing, where it is, how big it is, to what scale, what perspective, and what the programmer ultimately wants to reconstruct during deployment of the product.  Design is responsible for a coherent interface (similar color schemes for example), ease of navigation, and stuff like this.

Standard UI things would be usage of color themes, using familiar user navigation mechanisms (buttons), common layout themes (close button in the upper right or upper left corner), acceptable colors for things (purple for pause button?), but really this gets even more involved.  Deeper topics would be stuff like evoking mood by shapes and colors, designing intuitive user interfaces without having someone need external help and tutorials... yea all this stuff is behind UI design.

What about UX?  When I first heard about UX, I thought it was some new technology rage and I'd have to get certified and trained in it... apparently UX just means User EXperience.  I'm still going to chalk this up to buzzword-worthy, but it essentially comes down to figuring out if the user enjoys the experience that is your product.

As a programmer, I suppose this "user experience test" doesn't really fall nicely in to one of many other kinds of tests, so sure, why not, let's have it be its own thing.  I mean, how can I really test the design of the product itself from the software level.

Usually, UI and UX can be clumped together for that nasty UI/UX combo acronym.  Basically, how "nice" can a user experience your product without being turned off by it.  Did someone need developer assistance to actually play the product?  If someone is lost trying to use the product, they probably don't want to hear programmer technical jargon on top of them trying to figure out what they are already doing wrong anyways.

As part of Game Design, the UI should be heavily considered and thought out.  Again, as a programmer, when I hear UI, I think, "meh, just put some buttons around and the user will figure it out"... while that may be true, there is some actual science behind this.  Look in to the Golden Ratio and Rule of Thirds if you don't believe me.  Combining math and art/presentation; what a scary idea.

But really, it's a lot of stuff we take for granted and "know about" without really thinking about.  Like for example, we like stuff centered -- but why?  And, centered on what, in relation to what else?  What if all my buttons were different sizes and put in different places even if they did the same thing, but it can be ok because the buttons are on different screens?

Now for the catch, if the "theme" of the product is craziness, can any and all of these rules be thrown out?  Yes.

In fact, I was told in one of my art classes that "if even the smallest thing is off, people will notice and you'll get poor reviews"... as opposed to "however, if everything on the canvas looks intentional, it is lauded for its creativity".  So the short of it, if you screw up, it better be on purpose, otherwise you'll have angry people UX'ing all over your game, then probably with the mad reviews also.

Alright, next post should get back to graphics programming stuff and texture atlases.



Saturday, May 18, 2013

Anatomy of a Simple Game

I'm going to take a quick break from the graphics programming stuff to talk a bit about all the components that make up a "simple" game.  This won't really be too technical, but rather an overview of all the parts that make up an interactive system.

Oh, and take note that some aspects of games I mention below may or may not be necessary for particular types of games, but in a nutshell, most or all of what I talk about will be needed in some capacity.

So, what makes a game, a game anyways?

Interactivity.  Without this, the "game" would just be some sort of animation maybe mixed in with some sounds.  If you want that, watch television or youtube or whatever.  While this may seem like a "duh" kind of moment, it also identifies one of the key aspects of making games -- programming how input affects the game itself.

If the game is on a computer system, this could be a keyboard, mouse, pointer, gamepad, or really many other components.  The standard to consider is keyboard and maybe a mouse.  With these days and touchscreens and mobile devices, you will likely need to consider touch interfaces as well.  Where did the user touch the screen?  How do you keep track if the screen is already touched and another touch comes in, maybe from another finger?

Ok, we got input out of the way, but what about what happens when input occurs?  This is input response.  The timing of when you handle player input is a bit technical so we'll skip those details, but suffice to say you will likely want to keep track of what new input has happened until you handle it, then discard that information because it is now "stale".  For example, in a platforming game, you probably want to move the player character to the right if a "right button" is being held down, then stop moving right when the input is no longer held down.

Take note of the usage of "if" and "then" statements above, because that is the beginning of how programming works.  Check for some condition to be true, then do something... or if it is not true at some given time, do something else (maybe just ignore the condition itself).

Input is covered now, at a high level.  Processing that input is now covered.  But what about stuff that happens not in response to input?  This is something called the game loop or update cycle.  It is the lifeline of your game's logic.  See those clouds floating around in the background?  They need to know how to move, when to move, and how much to move over some given amount of time.  This calculation is done during your update cycles.

The fact that you can actually see some graphics is also important.  Actually taking your data about the cloud and drawing it to the screen is handled in something called a render cycle.

Think of it this way, you have two people in a room, a mathematician and an artist.  The math guy calculates all the algebra involved with positional data about the cloud, then hands his results over to the art person.  The art person doesn't have to care how the math guy got the answer, but instead only needs to know where the cloud is now.  Once the art person looks at the answer, they draw the cloud in the right spot.

This is a simplified analogy and it can get a lot more complicated (and more efficient), but we'll save that discussion for later.

Ok, so we can do input, respond to input, do updates about data, draw data... now what?

Well, there is more.

Two major topics that we haven't covered yet is physics and artificial intelligence.

Physics is already tough as it is, but it gets worse in games.  There are two major categories to consider that are part of the aspect called "physics" in games.  This would be collision detection and collision response.

Collision detection is figuring out when and where interesting things collide with each other.  How do we know when this happens?  This is detecting collisions.  This topic is quite complex and can require a bit of ingenuity to "get right".  Honestly, this topic can get pretty math heavy, so if you're interested, you should probably research this as a separate topic.  Fortunately, however, computing systems don't like to do a ton of complicated math (just like us!), so if you can think of ways to do as little math as possible, the better.

The "easiest" detection to find, and think about, is how do I know when a line hits another line?  Yep, we just went back to basic algebra.  The question of "when" may be misleading, so let me rephrase, where do two lines intersect, if ever?  If they don't collide (maybe they are line segments?) we successfully detected that the two interesting lines, or line segments didn't collide!

Well, if you take that example and draw four line segments such that it makes a box, we could deduce that it is now possible to detect when our collection of 4 line segments may or may not collide with another collection of 4 line segments.  This is the basics behind Bounding Box collision detection.

Collision response is the other complicated topic under physics.  If we detected that something collided with each other, how do we want to handle it?  Does it bounce backward?  Does it pass through?  Does it accelerate in some arbitrary direction?  Does it lose speed?  Does it lose acceleration?  Does one of the objects break?  Will it cause explosions?  Do I take damage?  There are a lot of possibilities and I definitely couldn't list them all here, in fact, for the most part, your collision response will be dictated by your game design.  The important part is to detect when objects collide, then change something in response.  If nothing changes, there may have been no point in detecting the collision in the first place.  This is another complex topic of interest.

Think about it this way, if we have 100 game objects sprawled out around the screen and the player fires a ball up from the lower left corner of the screen, straight up, how do we do this?

Well, the "easy" answer is check all 100 objects to see if the ball hits any of them every update cycle, but this isn't good, because every time our game logic runs through we will have a lot of misses (probably 100 misses almost all the time!).  This is largely wasteful and actually makes your game run very terribly.  The better idea is to only check certain objects to collide against.  There are many strategies to consider with this, but some of the easier ones to think about is -- well, what if we only considered collision against the objects on the left side of the screen since that is where the ball is.  Moreover, what about the bottom left side of the screen since that is where the ball is.

Again, there are a lot of methods to consider and strategies to think about with how best to consider detecting, and handling collisions.  Unfortunately, there really isn't any universal "best" way to handle this problem, so you will need to think about it, and research, then think about it some more.

Oh, and it should be mentioned, that if some game object doesn't have any collisions, then it should move, based on it's current trajectory (vector) and speed (magnitude).  Sometimes, though, collisions aren't always obvious.  Think for example a platforming game, and your character is on the ground.  There is a collision at play, but since gravity is always at work against your player, how do you change the player's movement?  Down?  Nowhere?  Left or right?

Collision detection and response, good times.

Sound.  Really there isn't too much to be said about sound at the high level.  It can be a real pain to figure out if you're doing the actual sound programming, but for the most part, game designers and/or programmers will only need to really worry about when to play a sound effect, or play background music.  This is likely going to be a response during collision response -- ie, the ball hits an object in the sky, when that happens, make a popping sound, and also blow up the object and ball.

Artificial Intelligence.  Or "AI".  Your game can be pretty and do all this other stuff great, but what about something that challenges the player.  Something that thinks like a human, acts like a human, but isn't really a human... ya know, something like a monster.  Well, this is also a hefty topic, but really, as a developer, you will need to consider exactly what kind of AI there will be in a game.  Some games don't even need an AI to "play against"... think of "Tetris", puzzle games, games that pits the player versus a geographic maze, things like this.

Assuming you do want to have an AI in to your game, you will need to consider several broad things (none of which I'll elaborate on since this is an intro article).  First, does the AI respond to player input?  How does an an AI agent (say, a monster) idle when not challenged directly by the player?  Does the agent follow the same physics rules as applied to the player?  Does the AI "know" hidden information that the player doesn't?

Of course, these are large questions to consider, but one of the more technical one would be what AI algorithm will be used for various circumstances.  For example, you probably don't want to implement AI that would require a supercomputer to process.  How do you limit what the AI can do with what it has to know, versus what its capabilities will be?  Also, consider if the AI is even conquerable by the player?  For example, in the classic game, "Pong", where there are two paddles on the screen and a ball.  The AI could control the other paddle.  It would be possible to have the AI simply "set" their paddle position to always be in line with the ball in play, thus making it completely impossible to score against.  This is, of course, assuming your collision detection and response of the ball on the paddles is working correctly and it sends the ball back at you when it collides!

Ok, that was a lot of stuff to think about without getting too much in to the finer details.  I may have left some things out, so by all means feel free to let me know if I missed something and I'll go over it sooner or later.

Also, if you're new to game development, I'd heavily recommend looking in to any game engine to help you along the way.  It will speed up your production on a massive scale.  Yes, you won't get all the "low level" stuff -- that has its time and place in the world, but if you just want to see your ideas come to life quickly, pick up an engine, learn it for a couple of weeks and months, and see what happens.  If you can make some sort of sane game using the components reviewed above with a game engine, you can then challenge yourself to "go deeper" and try again.  These same concepts will be present, but will be completely on you with how it gets accomplished, and it will be no easy task.

As a final note, for the nit-picky, I made some assumptions about software architecture to convey certain points about how certain game logic would work (specifically with the update/render cycles).  Some of this information may not be relevant if you're using a game engine as some of this will be abstracted away and you won't have to worry about it.  Rest assured that this information is still relevant because the engine is using these concepts without you knowing about it!

Friday, May 10, 2013

Game Programming and 2d Art, Part 2

Ok, so we finally have a graphic.  This is a raster graphic, preferably a PNG file, and we need to put it in to a game.

If you're not sure what I'm talking about, check the first part of this article: Game Programming and 2d Art

As a programmer, the first step to get this art in game is to load the png file in to memory and get to the raw RGB data.  This is ideally suited for libpng (google for tech examples how to do use this library).

Once you get the pixel data, you can load it in to your favorite graphics library (opengl for example) and start putting it on quads/triangles/whatever.  Of course, other problems can come up before you might actually see your graphic (like orthogonal viewport, etc).  Those concepts are beyond this article (if you're interested, check out nehe's website for their tutorials).

This is all well and good and ideally you can finally put some basic png file to direct use in a game.  Already this probably could be a rollercoaster of learning and complexities, but the fun doesn't stop there!

The "better" way of handling 2d graphics is to use texture atlases.  Or rather, a collection of individual png files crammed in to one larger png file.  If you've ever opened "skins" or texture packs for various games (quake, minecraft, etc), you may have noticed that the graphics are all over the place in a larger raster graphic file (png).  The face is upside down and is connected to the chest, which is in turn connected to their legs and maybe their shoes below that.  It basically looks like someone took a steamroller to a player or monster and flattened them all out in to one graphic file.

Welcome to the wonderful world of texture atlases.  Before we begin, let's talk about some considerations you should take in to account.

First, atlas dimensions and memory.

Not everyone is running a desktop, especially with amazing graphics cards.  More over, if you're going to deploy on a mobile device or tablet, this is a major problematic area.  That said, you need to consider how big your atlas is.

Powers of two (1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2056, etc) or PoT is a very critical concept to understand when it comes to texture memory.  Your texture atlases should always be in perfect power of two dimensions.  Specifically, if your atlas is 256 pixels tall, it should be 256 pixels wide.

Why?

Well, if you understand basic computer science, you should understand that computers work in base 2 (0, 1).  Powers of two are significant in that it aligns memory perfectly with memory offset techniques.  It's complicated, but it boils down to optimizing how a CPU and GPU process data.  More over, older graphics cards were completely unable to use Non-Powers of Two (nPoT) at all.  Trying to load graphic data with nPoT dimensions would result in garbled graphic data... usually like someone took the bottom of your graphic and ripped it sideways as it is rendered from top to bottom... if it renders anything at all other than a white box.

So, your PoT texture atlas is fine, but there's still a problem.  There are a lot of things that can go wrong when rendering graphic data, but a common issue is that you may have exceeded a maximum amount of memory (like try loading a 2056x2056 texture atlas), while it would be nice if your program told you when you exceeded a maximum, it will likely instead crash when trying to load or use the data.

Of course, it isn't this simple, some graphics cards and computer systems will load this just fine (dependent on hardware per device), leaving you very confused when your masterpiece of a game simply won't work on your friend's computer, but works fine on yours.  Worse, sometimes hardware may actually do some sort of complicated emulation or paging to force large texture data to work.  The major drawback here is that you will be swapping data in and out of the CPU/GPU so constantly that the performance of your game will suffer tremendously.

At the end of the day, working with large atlases can give you various scenarios.  Sometimes it will work, others will make your game run like terrible, and others will out right crash the program.

There really isn't any "best" answer here other than to select some maximum atlas size during your technical design phase and stick with it.  There are software strategies to attempt to figure out a device's max texture size and to parse that large atlas data in to smaller pixel data clumps (that likely need to also follow PoT rules), but again, that can be very complicated, but may be necessary if you want to be a serious game/graphics engine programmer.

The final result that you will want to work with isn't even the atlas itself, but rather the texture objects inside the atlas that you will want to use!  All this headache just to find there's even more to it!

There is a tool that simplifies this a bit, and I talk about it here in the last article.

Wednesday, May 8, 2013

Game Programming and 2d Art

If you're a game developer, specifically working on 2d games, you will probably want some sort of graphics sooner or later.

Suffice to say, graphics aren't an easy topic for a programmer to really "get" aside from binary values for R G B A.  Yet, for art people, it's all about hues, lighting, perspective, and all that other non-programmer-technical stuff...

Why am I rambling about all of this?  Because if you want to incorporate 2d graphics, you will likely need to interact with artists (unless you're the artist, but you should still take heed!), and likewise, they will have to interact with you... and this is where things can get interesting.

Through some miracle, programmers and artists are working together, but how exactly does all this neat 2d art actually work and get in to a game?  Texture atlases.

Well, let's rewind a bit, the most basic thing is a single graphic.

Now, how you take a single graphic and display it in a game is dependent on your environment, game engine, and all that other stuff.  For the sake of this article, I will not be delving in to any technical examples of how to use any graphics libraries (you won't be seeing any code!) -- I'm more going to focus on *methods* of putting art in to a game.

Now, some programmers might think "methods" and think of programming -- well, reminder, not everyone thinks the same words mean the same things... "methods" can also mean the process of how you accomplish some task... like an artist might use a certain method to create your art, but that has nothing to do with your actual programmatic method used to display that art in your game... or your method of how to implement your method to display the art...

Anyways, back to graphics!

There are some technical issues that you and/or your artist should know right at the get go.  First, some terminology.

Raster Graphics - This refers to graphics that are pixel data.  Stuff like png files, raw RGBA binary data, bitmaps, things that are defined by pixels.  All of this stuff is collectively called "raster graphics".  This is as opposed to...

Vector Graphics - These graphics are a bit more complicated and usually not useful to implement directly in to games.  However, there are some pretty huge perks to having an artist use this format as opposed to raster graphics.  With vector graphics, the artwork is now a collection of mathematical shapes assigned various colors.  This means that, like all math, the original will always remain true, regardless of "zoom level" or how much you scale it; unlike raster graphics which use filters to "approximate" when scaling.

The issue of scaling graphics is complex and is worthwhile to research, but the skinny version is that raster graphics lose quality every time you scale up or down from the original until you will just end up with a blob.  With vector graphics, you can essentially scale up, down, shear, or do anything else to it without losing quality, as much as you want to.

Now, I mentioned vector isn't directly useful to games.  This is true, rendering vector graphics is a massively difficulty task for even today's hardware.  Sure, you could render a couple dozen vector graphics, but you need to realize that the graphic being displayed is generated by math, and if that needs to be refreshed (like during a screen redraw!), it could potentially need to be regenerated; so if the shape is complex enough, it will ruin your game's performance.

Ok, now that we got all that out there, it is really only practical to use raster graphics in games!  Graphics programming is all about using pixel data to feed directly in to some framebuffer, or use as texels for polygons, or things like this.  Someone will need to convert vector in to raster before it can be directly useful in a game.  Thankfully, most (all?) vector programs have an export feature and will allow someone to export vector art (which is flawless!) in to a rasterized version of that art.  What's even better is that you can essentially export to some given scale right away!

I was once confronted with the idea that an artist could "just give me a really large original" from photoshop and then I could just scale it down based on my need at the time.  While this may sound "ok", this is not ok.

Let's talk about graphics scaling some more to hopefully highlight why this isn't acceptable.

We're living in a day and age of thousands of devices, smartphones, tablets, computer monitors, etc.  All of them have different display sizes and capacities (what a nightmare!).  If you want to deploy your game to some/any/all of them, you will need different sizes for all of your art... meaning a LOT of scaling up and down.  But, how do you know what size art you need, or rather, what size would look the best on some given device?

The lazy answer is "just use a big version and scale down", but this actually isn't a good answer at all for 2 reasons.  One, you use excessive amounts of memory/cpu/gpu when you scale it in your game engine.  Two, the scaled version will look much worse regardless if you did the scaling in-engine or pre-rendered the scaled version (ie, you scaled it down ahead of time in gimp/photoshop).

The correct answer is you have to have an exact pixel match for your art to any given display size (read: not feasible).

Anyways, if those 2 lazy reasons don't scare you away, then consider this: scaling graphics up or down too much will always look bad regardless of the originals' size.  I believe the magic cutoff is about 50% up or down before it really starts looking terrible.

Example time.  Let's say I have a 5000x5000 original, which should be considered excessive.  Yet, it does fit the artists' idea of a very large original, and if we can just scale it down to fit our needs, what's the problem as long as we scale it down before we actually use it?

Think like an artist here.  a 5000x5000 original will look absolutely amazing, and the art going in a game should look amazing, so what's the problem?  Well, aside from the obvious memory issue (5000x5000 = 25 million pixels, at 4 bytes per pixel... 100 million bytes to even open that graphic in game!), the appearance will be very terrible if you have to scale it down to something like 128x128.  Go ahead and try it in your favorite raster art program, make a doodle at 5000x5000 and scale it to 128x128 and look what happens, especially around the edges!

Now, this issue is actually more problematic, not only will this scaled version look horrendous, it will actually likely get scaled again when you go to display it in game!  A scaled version of an already bad scaled version will look catastrophic at best.

We could take some less absurd examples, but hopefully you get the idea that a scale of a scale is bad... with larger scaling happening anywhere meaning exponentially bad results.

Vector art sort of fixes this (it's not a panacea though).  The original export will get you a more or less "perfect" raster version at your specified dimensions during the export process.  There isn't any scaling of a raster, there is just a mathematically generated piece of art.  This doesn't work too well with very small graphics (like exporting to say under 32x32ish), so if you're dealing with very small graphics, it is probably best to start doing pixel art.

This generated/exported art will still probably get scaled when it comes time to use in your game and this is the reason why you will likely want various versions of each art asset for different display densities (which is a whole other topic).  Long story short though, you will want to export new originals from the vector art at different pixel sizes rather than scaling your already generated raster art.  The result will likely be much sharper looking art in the end product!  I said likely because there are other steps that can mess up your art all along the way.

Next article I'll cover more about finally putting some of these graphics to work and texture atlases.

Check out part 2

Tuesday, January 29, 2013

Why I didn't use Unity

I was recently asked why I didn't go with Unity when developing games for smartphones.  This answer is a bit complicated and I'll have to rewind the clock a little bit, so bare with me here.

Back in mid-2011 or so when I decided to get in to Android and iOS games, I, like many other people, had to figure out what the "best" way forward was.  A lot of Googling happened.  By a lot, I mean *a lot*.

My background was pretty heavily solidified with C and C++ and I was pretty distraught over the idea that to make games on Android, I'd "have to use Java".  Initially, that was my researched impression anyway... sort of like my initial impression that "any serious and portable game needs to use Unity".

I'm going to skip the side story here on why I decided to develop for Android first here rather than iOS, maybe I'll come back to this in another post.  So, I started dabbling on a "Hello World" program for Android, just to get a basic foothold with what the heck I was doing.  It didn't take long to realize that Android was an immensely complicated and complex undertaking to even make a basic app for.  Sure, the xml, business-like app, was relatively straightforward and easy, but implementing game stuff, using OpenGL, and just drawing something to the screen was not a trivial task.

But, you may say, that drawing anything to the screen shouldn't be too hard; and that was true, until I found out that there are way too many screen sizes, resolutions, densities, and all that other jazz to make any sort of easily designed graphics and retain any sort of semblance of consistency between all these graphical problems.

I had read a couple places that Unity "just works" and my god that would have been nice.  I spent an enormous amount of time piecing together tutorials on how all this worked in the Java world.

Anyways, I always like knowing how things work, that way when something goes wrong, I know why and I can ideally can find a better alternative.  Plus, I was planning on 2d games at this point anyways, so something overly complex like Unity was starting to lose weight here as it was seemingly geared for 3d games -- and possibly 3d games only... though of course you could simulate a 2d game experience.

So, while I had Unity "on hold", I kept plowing through some pretty nightmarish lessons learning about the internal issues with Android.  My first harsh lesson hit when I realized calling an opengl function in java to render a fairly large texture ate 60% of my phone's CPU clock cycles just sitting there idle.  Needless to say, when I tried to play the game itself, the frame rate was horrendous.  The background was killing the game play -- turning that off made my game much more playable; yet all these other games out there in the world don't seem to have this problem -- was it because they were using Unity?

No?  I quickly found out that the *only* real way to make good, smooth games on Android was to use native code.  Thankfully, my C background ate this up.  After a begrudging time "porting" my Java code to native code, the game ran a ton faster, background and all!

So, would Unity have helped with all of this?  Definitely maybe.

So, I finally did crack open Unity to see what all the hubbub was about.  It was completely different.  It takes a much more, uh, designer-friendly approach to making games.  You can drag and drop files in to its project file system and things just load for you -- which is a true godsend as that code in my own engine (yes I ended up making my own portable engine) took a long time.

I see that to make things more game-like in Unity, I more or less have to (or at least should) use C#.  Now, I'm not a master with C#, but I have a couple production level projects done with it, so I can dust that skillset off and start working with it.  Right away, I'm almost devastated with some of its inefficiencies that reminded me immediately of Java on Android.

Right away, the fact that C# *forced me to instantiate new Vectors* when I wanted to manipulate thing's locations made me sick.  This will be happening a whole heck of a lot in games and in code, object instantiation, even on something simple like Vectors, will translate (haha, pun) to a lot of wasted CPU time.

Though don't get me wrong, I was very impressed with the "all in one" idea and visual aspect of Unity.  I loved the idea of "attaching" scripts to objects and I didn't have to worry about writing complex update functions, or render threads, or even game state objects while accounting for time deltas to make my game frame rate independent -- nay, all of this was taken care of by Unity; which *really* could speed up development time of any game made using Unity.  The only trade off now is that I'd have to trade in my freedom of design to make only whatever I could using this cookie cutter engine thing.

Unfortunately for game programming, part of the job *is* to do exactly those things that Unity does for us.

For example, in my own engine, I recently finished code to analyze an arbitrarily large array of pixel data.  The code would then "find" the bounding boxes around all graphics found in the pixel data.  The idea here is that it would automatically find all objects so that I can use them as textures in my game via a texture atlas.  Doing this in C# and Unity, though possible, would likely take a much longer processing time to accomplish.  Even using unsafe code.

Don't believe me?  Ok, that's fine, but remember that C# compiles to an Intermediate Language similar to Java, and that adds extra processing overhead at runtime.  Additionally, if you use unsafe code in C#; you're throwing one of the main reasons why you're using C# out the window.  Additionally, the .Net/Mono framework, again like Java, has to make assumptions about your code; usually trading performance for accuracy.  While this is usually A Good Thing (tm), in game development this can be a disaster wrapped up in the inability to be explain why "your game runs like garbage and nobody knows how to fix it".  For example, not all Android devices have a floating point unit.  Yes, that's right, no hardware floats.  Meaning your game is going to run like terrible.  In C/C++, I can detect this lack of FPU then use function pointers to perform binary coded decimal (fixed) operations using integer operations instead of floats.

In a 3d game, like many that would be made with or without Unity, this has massive implications in terms of performance.  If you try to use ANY floats without a FPU (especially multiply or divide operations), the device will use an fpu emulator of sorts and that is *not* something you want happening when trying to render at 30+ frames a second for any sizable amount of vertex data.

While this sounds like a headache, and believe me it is, this would be difficult and maybe even impossible to avoid with C# or Unityscript (javascript gone Unity).

Fast forward a bit of time and we've released 2 fairly "simple" games on Android, 1 of which was ported to iPhone.  The development process had a lot of bumps and rocks in the road.  Unity probably would have saved me a ton of headaches, but I'm still glad I didn't use it.

I now have a portable game engine that works on both Android and iOS using C and now I can just drop my game logic code in to this engine, regardless of platform, and it just works on both.  For fun, I even have a windows port of my games now all using the same code.

Is my way easy?  Definitely not.  Is it visual?  No.  In fact, on several occasions I ended up diving through zlib and libpng's source code to track down errors (all of which were my fault of course).

If I had to do it again would I use Unity?  No.  While the initial development costs would likely be less and the technical requirement of a programmer be eased, games demand optimized code.  Especially games in constrained environments.  Yes, phones and tablets are getting to be powerful and everyone "should" be getting new phones every year, but the reality is, that isn't the case.  In fact, even as of this writing, I believe most people using Android are still using Android 2.x.x and on phone models over 2 years old -- of which a sizable portion still don't have fpu's!

Which brings me to another side tangent.  Let's talk about math.  Even in 2d games, a decent amount of math is going to be coming in to play.  Even on devices containing FPUs, there can be substantial math involved with games and they will be using a lot of floating point math.  I ended up implementing a very "hackish" version of various math functions to speed them up (square root comes immediately to mind) due to the frequency in which they are called.  I got an extra couple frames per second using my hack versions of these functions.  Mind you, in something like Unity, not only will you likely NOT be using things like this, but you will be getting in to forced object instantiating issues on top of the raw math.

Next, let's talk about memory.  Doing naughty things in C and C++ have been known for a long time, and in C# you can do some dirty things also using unsafe code.

I can't stress enough that if you're using C#, you should be running unsafe almost always when making games.  Which sort of goes against one of the arguments for using C# in the first place.

I should probably also talk about garbage collection and managed memory.  In short, C and C++ don't have these issues -- for better or worse.  In games though, I can't stress enough that these things are not your friend.  I will have to have a whole other article on just this topic I bet.

Anyways, I finally also ended up googling for "pros and cons of unity".  There was some pretty thought provoking stuff and a lot of "eh, works for some, not for others"... and I kind of have to agree with that position.  I will also admit here that because I'm more comfortable with C and C++, that was also a big sway against Unity for my personal situation.

I'll wrap this lengthy post up with: so, is Unity for you?

Probaby yes if:
* you already know Unity
* you have an extensive background in C#
* you want a streamlined design/development cycle and don't mind the tradeoffs
* you "just want to make something"
* you want a job with a company that uses Unity (for whatever reason)
* you have little programming experience
* you can afford Unity

Probably not if:
* you already make games for computers/consoles with C/C++
* you are a programmer with a lot of programming experience in general, including opengl
* you like working extremely long hours, scouring through library source code, love the idea of squeezing out an extra second of performance per update cycle
* you are comfortable with command line interfaces and your own version control
* you like managing your own memory
* you want to make any kind of game with any sort of capacity you can imagine
* you can handle your own portability issues
* you can't afford Unity

This was a quick brain dump of my experience with Unity and my own development issues for games on Android and iPhone/iPad.  Hopefully this helped some people, or at least got them to rage a little bit about something.  I'm probably not 100% accurate on everything stated above and I'm more than happy to hear out people's input where I'm wrong.

I will likely get more in-depth with a lot of things mentioned here in another post later reinforcing my position, so stay tuned if you're in to that sort of thing, but I warn you, it won't be pretty.