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

Tuesday, June 24, 2014

It is dangerous to go alone, take this!

While creating a game engine, or just programming in general, lots of things can go wrong! Certainly, tools can also prove some immensely useful aid in the task at hand as well.  That said, here is a listing of tools and software we're using while making our own game engine.  They won't get the job done for me, but they certainly alleviate problems and make things more productive in the long run.

[Programming IDE]
The defacto standard is seemingly Visual Studio for developers on Windows.  For my game engine, being cross-platform, I don't really have a luxury of sticking with any one specific IDE.  On Windows, I've found that Code::Blocks works just fine.  For OSX and iOS, XCode is the standard.  For Android, Eclipse seems to be the way to go (in combination with cygwin), and last, but certainly not least, for Linux, I generally use KATE, or whatever text editor is loaded on that flavor of XWindows that supports syntax highlighting... in a pinch I do use vim as well.

Compilers
Well, can't really get too far in programming without these.  On Windows I use MingGW, Android and Linux use GCC, and OSX/iOS are using Clang/LLVM.

CppCheck
Let's face it, even the best of us crazy programmer people make a mistake every now and again.  Probably more if you listen to other people, but why do we listen to other people anyways?!  So, this neat tool that helps find errors in logic and what not here is with CppCheck.  Using this in addition to the compiler's analysis and warnings should at least find a large portion of issues and bugs before they become too problematic.

XVI32
My hex editor of choice.  If you'll be doing data file editing, checking little or big endian, or doing any sort of binary things, looking at the raw bytes is immensely useful sooner or later, especially in files on the file system.  XVI32 is free and fantastic.  It might be useful for other things than programming, but I will leave that as an exercise for you to figure out.

Mercurial
Version control is a necessity with software development (and likely other things NOT software-related!).  I converted from subversion a while ago and I'm pretty happy with the switch.  I highly recommend checking hginit.com for help learning the commands to use this really neat version control system.  Mercurial is decentralized and robust.  Naturally, a more visual way of dealing with the tool could be useful...

SourceTree
In my personal quest to rule the world, this was one of the latter additions to my growing arsenal of tools to help with development.  I was doing things on the command line with Mercurial when finally I bit the bullet and tried this new GUI approach to things.  I was skeptical at first, but honestly, this thing really helps see things and speed things along with managing version control.  I'll still drop down to command line and use hg directly, but for the most part, SourceTree covers my day to day version control interfacing.

Notepad++
Editing text files happens.  This fantastic editor is my default editor on Windows.  It does syntax highlighting for tons of languages, it's zippy and responsive, supports massive files, and all sorts of good things.  I even use this to edit source code outside of IDEs when necessary.  Yea, it is that good.  Get Notepad++ and live a better life on a computer; well, at least when you're editing text.

Wireshark
The premiere tool to watch network traffic.  Wireshark is essential when figuring out what in the world is happening with your network and the software you may or may not be having issues with.  Ideally, you can troubleshoot your network code that is giving you guff.  I suppose it could be used for other interesting things as well, but hey, that's on you.

Putty
SSH shell on Windows?  Yes please.  Essential with a multiple system set up across multiple Operating Systems.  Putty has captured the hearts of many over the years.

WinSCP
It copies files over SSH, really convenient to transfer files to computers only listening for SSH traffic.  WinSCP is particularly nice sending/receiving files to/from linux hosts, especially if Samba is acting up or not working right for whatever reason.

Filezilla
Good `ole FTP.  Can't go wrong with either the client or server version of Filezilla.  I don't find myself using FTP too much anymore, but every now and again with webhosts this is still useful.  With cloud computing and what not, this is seemingly less popular these days, but hey, it is still kicking for now.

[Word Processor]
I'm using the excellent LibreOffice.  It replaces MS Office.  It can make PDF files.  It is free.  Get it.

[Web Browser]
Lots of choices here.  If you're a developer, and I hope you are if you've read this far, you won't go far without looking stuff up anymore on the internet... I'm generally a Chrome guy, but as a developer, get used to using all of them, especially if you do web dev at any point.  In order of personal preference, I choose:
Chrome, Firefox, SeaMonkey, Opera, Internet Explorer, Safari, everything else I didn't mention

Gimp
Hey, part of developing games incurs the necessity for graphics.  Gimp is the forefront winner in the free graphics category.  It can take a while to get used to, but it isn't so bad once you get over the learning curve.  It can be quite picky with drawing tablets (GTK+ fault most likely), so if/when you get that to work, it's a pretty well rounded raster art image editor.  The commercial alternative is, of course, Photoshop.

Trello
Not really a downloadable product, this web service is a great way to apply some sanity to organizing all sorts of complex tasks.  I don't think I can do it justice by explaining it, but it is a system where you put cards together in to lists, assign them to people, give them due dates, color code them, etc.  It is very visual.  Things can be dragged around and prioritized and stuff.  Trello is a nice way to keep yourself organized with what you have to do or facilitate communication with team members so everyone know what needs to be done!  Less forgetting the small stuff, give yourself todo notes!

There are probably more tools that I use, but those are the more frequently used ones in my quest to make software.

Monday, June 23, 2014

Remember, our game engine is a learning experience...

So, when I first started the adventure of making a game engine, I had some grandiose ideas of what it would do.  Quite a few of my initial goals have actually been met (almost suprisingly); but that isn't to say I had quite a few bumps in the road with some faulty goals.  Most of the time these misbegotten ideas were crafted up because I didn't understand something or know enough about the topic to begin with (like 3d data formats with animation!).

Here, I will showcase some of my mistakes and talk about my troubles.  For your time, I will offer my lessons learned and elaborate on why what I was doing was good/bad/indifferent.

So, here we go, some of the times where I really messed up.  For fun, I'm going to rate how bad I messed something up on a scale of 1-10, with 1 being a minor lapse in judgement to 10 being evidence for logical absurdity and possibly insanity.

Floating point precision (Score: 9 / 10, I will regret this later in life once I figured out what happened).

So, you're playing a game, and lo and behold we fall through the floor.  Sheesh, these programmers must be lousy, they can't even tell where the ground is!  As it turns out, figuring out where the ground is located is actually not a trivial task!

Other neat things include objects moving through each other, falling out of a game level through arbitrary walls, the game camera clips though walls, things get stuck in the floor, and of course falling through the floor.

I can't speak for all engines, but in all likelyness, floating point precision is a likely culprit of at least some of these problems.

Early in my engine code, I had things like:

void someFunction(float x, float y)
{
	if (x == y)
		doStuff();
	else
		doOtherStuff();
}

While this looks innocent enough, it is a very, very bad idea.  Not only is this a bad idea, it is a stupendously, compoundingly bad idea with cross-platform development and bad for your general sanity when you use this code and get unexpected results in ways you have no idea yet.

Bruce Dawson has two really good articles about floating point comparisons that you really need to read that will hopefully enlighten you enough to realize a couple things.  One, computers suck at math, just like us, and two, you need to know what they are doing to use fractional numbers correctly (like, just where is that floor in 3d space anyways).  Sort of summing up what Bruce talks about (you should read it all anyways)...

There is no 100% awesome way of solving the floating point issue, but you, the engine developer, need to figure out the "best" way forward with some strategy and stick with it.  If you want a 100% accurate way of always having 100% accurate real number representation, you may wish to look in to scientific computing as opposed to game engine development as you will need a decent set of math understanding (and raw CPU power) to figure all that out.

Some caveats to watch out for are constant Epsilons and always thinking straight equality comparisons of floats are bad.

Example of a straight equality that is a Good Thing (tm).

float x = 1.0f;
if (x == 1.0f)
	hurray();

or even

double x = 1.0;
if (x == 1.0)
	hurray();

With no math involved after the initial assignment, this conditional should be fine. However, notice that I use the character 'f' on my number in the first example.  This forces single point precision, as opposed to double representation.  Depending on the system this is running on, if you leave the 'f' off, this comparison may or may not be equivalent!!!!  Do NOT mix having an 'f' on a float constant and then comparing it to one without! Example of messing up:

float x = 1.0f;
if (x == 1.0)
	hurray();

What about Epsilon? This is a reasonable strategy, albeit not very accurate, sometimes.  Epsilon is some margin of error.  The trick is that this margin of error grows as each float gets further away from 0 and sadly shrinks as they get closer to true 0.

It is a tad tricky to pin down exactly how much Epsilon should be given as it depends on the magnitude of the float number in question.  There is seemingly no tried and true solution here - or at least a provable superior solution given program execution performance as a requirement. For our engine, we combined an absolute Epsilon (for numbers near 0) and relative Epsilons (for numbers not near 0).

If you're making your own engine, this is a topic worthy of extensive research and testing because all games made on top of the engine will suffer from your failings to deal with this issue "in the most correct way".
Oh, and if you think this is fun now, just wait, there are more woes to talk about with floating point issues with game engine development, not just precision, but we'll get to those soon enough!

Sunday, June 22, 2014

How the cross-platform, custom game engine integrates in the big picture

 
While designing and developing the game engine, it became somewhat necessary to start drawing some pictures to help get a bit of visualization going on.  This picture here shows, hopefully, that the engine itself is merely a component in the "bigger picture" of how a bunch of code and logic fit together to finally and actually be able to make a real game product.

Because the engine is C (read here for the reasons why it is C), the source code should be written such that we can take the C files over to platform x, compile it, and it just works.  In theory that sounds great, but in practice it isn't quite that simple.  As long as I can separate out the cross-platform code from the platform specific code, then all will be [mostly] well.  Fortunately, this design also lends flexibility in how we go about implementing those platform specific things while allowing the vast majority of the engine to be compiled, more or less, as is across multiple platforms.

The top part of the this picture shows the various Operating Systems we plan to support.  Each, of course, has their own considerations that don't play well with other OS's though -- so we had to split those "platform specifics" away from the "core" of the game engine.  By decoupling them, we can make lots of upgrades, fixes, and what not to the core and have it be fixed instantly across all platforms.  We can also write the platform specific parts once and never really need to change it once it works.


The Platform Specifics are:
  • compiled 3rd party libraries (static or dynamic, depending on the platform/license)
  • windowing code (hey, they all speak differently with their host OS!)
  • device data gathering about hardware capacities
  • core input handling
  • opengl setup
  • utility things, like figuring out storage paths, how to talk to file system
  • platform specific scripts, batch files for windows, bash for the others
The Game Engine then is:
  • Lots of header files for 3rd party libraries
  • Lots of loading data routines
  • Lots of math, geometry, collision detection routines
  • Random number generator
  • Lots of graphics functions
  • Lots of utility functions (think buffering files, writing strings in binary, delay functions, etc)
  • Generalized/abstracted input handling
  • Generalized/abstracted sound output handling
  • Logging functions
  • Networking code
  • Physics
  • Vector stuff
  • Matrix stuff
  • Time/Date handling
  • String handling
  • Memory handling
  • Specialized data support for game data files
  • Embedded Lua script engine
  • Everything else not platform specific
The Game Core is:
  • Art, sound, data loading/destroying
  • Game objects
  • Actors
  • Artificial Intelligence
  • Player input response
  • Game networking
  • Game physics (in addition or by compliment to the game engine's)
  • Everything else that makes the game
Once all of these things are combined and compiled/linked together, the actual game can be spit out and run on any of the supported platforms!  It is quite exciting to see our Windows version work near flawlessly on iOS or OSX just by pulling down the game core code, compiling, and it works... yea, sometimes there are hitches, but these are usually quick to fix as they are general oversights.

It was also quite breath-taking to see a "windows game" work on Linux almost without a hitch also.

Thursday, June 19, 2014

The supporting libraries of a custom game engine

While creating my own game engine, it became pretty apparent fairly quickly that I couldn't possibly do everything that would be required of me to reprogram "from scratch".  We are talking about stuff like opening PNG files and extracting the RGB data out of them!  (As a side note, I DID actually read the RFC  and realized very quickly this isn't something I wanted to do).

PNG files weren't the only thing I wasn't interested in figuring out myself.  There are perfectly good libraries out there that have weathered the long haul and perform very well.  Let's go ahead and admit we can use some help from others in our ambitious goals of writing a game engine from the ground up.

Oh, and a caveat, it had to be free.  I'm sure there are some great commercial libraries out there, but that's not my fancy.  Of all the years gaming technology has existed, there just HAS to be free solutions out there somewhere just for this adventure!

The libraries that I have thus settled for (at least for now!) are:

  • libcurl - CURL is a useful library for dealing with network data transfer over various protocols.  This is useful for stuff like downloading things from HTTP, FTP, and many, many others.  For my intents and purposes, I found it useful that I could post, say, patch files on a webserver and have my game clients download those patches using features of this library.  Technically, my game engine has "enough" features to be able to talk HTTP with a server but I never got around to formalizing it to be as robust as libcurl.
  • lua - Lua is a fantastic and powerful scripting language and feature to integrate in to a game engine.  What better way to extend games than allowing other people, or even the public, to create, modify, and execute their own scripts!  We integrated liblua in to the game engine and can now embed scripts directly (the engine incorporated the lua parser so it can run lua scripts in the engine!)
  • OpenAL - Really, when it comes to sound, it becomes excessively problematic dealing with the tons of options out there; many of which are platform specific.  OpenAL was kind of the only sane way of dealing with audio output in a cross-platform setup.  I attempted to write my own audio mixer and all that, got pretty far, but then I realized I needed more than just mixing, I would need to somehow talk to the sound driver(s) on each target platform as well -- way over my head and just too much to learn and do well. 
  • libpng - This one is a granddaddy library that fuels a surprising number of applications out there, may as well adopt it!  What can I say, it let's us load up PNG files and extract the much-needed RGB data from them.  It took a little while to learn how to interact with the API, but eventually I got it - perhaps I'll make an article just for this someday.  At the end of the day, this is a fantastic library to integrate with a game engine.
  • zlib - Similar to libpng, zlib is almost everywhere on the planet.  It's in your smartphones, in your computer, and in almost every application and Operating System out there!  In fact, I'd be surprised if you haven't interacted with something zlib related, even today!  It deals with compression of data files and data streams.  As well, of course, with inflating data from compressed states -- something insanely useful.
  • btrxml - An XML parser I wrote with a constrained memory footprint in mind while retaining cross-platform capabilities.  I open sourced it under the zlib license so other people can use it for whatever they want (permissable with the license, of course).  Originally this was going to be part of the game engine itself after I looked in to other XML parsers, but at the end of the day, I opened it up and generalized it in to its own project!
That's it!

Using the libraries mentioned above, combined with the other engine code, everything I can do is made possible.  There may be some additional libraries to consider in the future.  I've dabbled with a couple 3d data libraries like lib3ds and things like that to help with handling 3d data (models, animation, etc), but I haven't quite figured out how I want to handle many things yet with that aspect.  Plus, for now, my engine really only caters to 2d games.  It does have super basic support for 3d things, can even render cubes, spheres, etc, but anything beyond that is no go yet.

Speaking of new libraries to consider, I think the next library to incorporate is likely ffmpeg or some of its dependency libraries to help with audio/video playback in a cross-platform manner.



Wednesday, June 18, 2014

The dawn of a new game engine

After my [de]motivating blog post earlier about making your own game engine, this will be THE post talking about how I got started!

A long, long time ago, I set out to create my own engine.  I've always been one to need to figure everything out to understand how things work, and game engines were no exception.  In my moments of weakness, I did consider pre-made things (hey, I even used RPG Maker wayyy back in the day).  If you're curious, I even went on and on about Unity and why I didn't use it here.

It's been a while since I started the adventure of this engine, so I'm looking back on the commit history of that first legendary day of when my engine was first put in to version control (protip: use version control software when making your own engine - I MEAN IT).

According to my own notes, version 0.0.0 of my engine had the following capacities:

  • Integrated libpng (for loading png files)
  • Integrated zlib (for compression/decompression of data)
  • Engine definitions (TRUE = 1, FALSE = 0, etc)
  • Device capability reading (number of cores in the CPU, display resolution...)
  • Engine init and deinit code, engine version numbers, etc
  • Fixed math placeholders (float replacements)
  • Real basic and rudimentary bitmap font loading
  • A very, very broken, misguided, and naive set of game configuration routines
  • A box structure, used to define a region for 2d interaction on the screen (think buttons)
  • An actual button structure, the intention was to be able to just put clickable buttons anywhere
  • OpenGL initialization stuff
  • Life cycle logic (useful mainly for mobile platforms)
  • Platform agnostic logging routines (to stdout, or to a file)
  • Very, very basic network socket operations
  • Very broken sound code that required extensive rework later
  • Very broken storage routines (come to find out, this is much more complicated in cross-platform)
  • Super basic time and date handling routines
  • A generic "timer" structure to keep track of elapsed time (in milliseconds)
  • Some engine utility functions (stuff like check if integer is even, get process id, check for file exist)
  • Basic 2d vector structure
In theory, I could drop this v0.0.0 of my engine with some game logic and a real basic game could be made.  How wrong I was.

According to my version control, the notes I left for myself were mostly unhelpful at first, but it is quite apparent that I grew frustrated with myself with how broken a lot of stuff was; especially with my early cross-platform issues.  At first, this engine was to be used for Android development specifically to replace the very clunky Java solutions out there.  What I was finding out was that there is a crazy amount of problems to be solved here at these fundamental levels for a couple platforms, not just Android.

It looks like the first thing I did was make some test functions to specifically help with testing new engine code.  This way I could make an engine testing program that can test engine functionality in a sandbox-like environment -- definitely want a controlled system when testing engine logic; many times I've driven myself to the brink of insanity debugging engine code when I came to find out that it was a bug in a game's logic that actually was bugged, not the engine!  Then again, some of these sanity checks lead to more robust and fault tolerant code in the engine, so it wasn't ALL for naught.

I just realized I should back up a bit; hey there's a bit of history here and I'm getting old!

Let's go back to the design goals of the engine.
  • It should have fantastic performance
  • It must be cross-platform to the major platforms (windows, android, iOS, OSX, linux)
  • It must cater to doing as little work across platforms as possible for games using it
  • It should help me later when making games by doing a lot of the less... interesting things
  • It should help me later when making games by doing a lot of the tedious things
To cater to the first two points, I settled on making the engine in C.  Yes, straight C programming.  Not even C++ (though one of my early iterations of an engine I did utilized C++, and I certainly miss some of those features).  C's performance has the potential to destroy the competition in the compiled languages sphere (well, short of FORTRAN, I suppose, though the race is close!).

Performance issues aside, C is also one of the few (maybe only?) languages that is supported by all the mentioned platforms.  The goal here is such that I need to be able to do as little rework as possible across all platforms.

I couldn't do Java, because iOS doesn't support it (a decision I agree with!).  Getting it to work on OSX can also be a bit finicky.  I certainly have a fair share of less-than pleasurable experiences with JVMs on Windows as well... and dalvik with Android... with its extensive device fragmentation issues is a whole other terribad experience I don't recommend to anyone.  Those things ruled Java out pretty quickly -- not to mention early versions of a Java engine I attempted were met with very bad performance metrics (especially on Android).  As a game engine, the fastest performance possible should be a high priority (I'll make an article about this later in much more elaborate detail).  Java was out.

C# was a candidate.  Unity uses it, it's not completely terrible.  The Mono framework supports it on non-windows solutions.  I dabbled with it briefly, but I found myself throwing features out that were suppose to be "pros" of C#.  Stuff like garbage collection, exceptions, reference counting, running unsafe code, etc... all these things were starting to add up against C#.  Though, unlike Java, C# at least seems to be deployable to the major platforms in some way... yet I found myself too often "going native" and making the hardcore components with C/C++ anyways.

So, to cater to this newfound information, I pretty much settled that the engine must be C/C++ flat out.  It's not all bad, I mean, every major Operating System in the world uses it.  Games on consoles use it.  How bad can it be?  Thankfully, these are my primary languages as well, so there's a comfort factor involved too.  Well, time will be a casualty with how complicated "going native" is for each supported platform... the tradeoff, though, is fantastic performance, and surprisingly little administrative overhead for "write code once, run anywhere"... which is a common advantage for Java/C# -- and here we are emulating that slogan with C/C++!  While this sounds good, there are platform intrinsics that we have to manually cater to, which is far from fun and anything but straight forward.

The other bullets mentioned I will be getting to as we go forward with these articles.

This was a lot of stuff.  I settled on straight C for maximum control, portability, and performance.  I dropped a couple of months on trivial things, setting things up for the engine (the first bullet list in this article reflects that effort).  There was already a bit of cross-platform support right from the get go as reading back certain information, like getting the current process id, were platform dependent.

Remember, each platform is fueled by different system capacities and standard libraries for their respecitve operating systems.  I will be taking full advantage of POSIX functions and things in the standard C libraries when possible, and I recommend doing the same for your own game engine for maximum performance, predictability, accuracy, and compliance with those standard behaviors.

Not sure what to cover next, I'd like to talk about big picture things and super technical things... so if anyone has a request for something, by all means leave a comment and I'll focus on that specifically.


So, you want to create a game engine?

Don't.

Ok, now that we have that out of the way, and I haven't convinced you not to, let's get this party started.

I'll be blogging a bit about my own experiences with making our own game engine.  It will be part technical, maybe part code, a bit of code architecture, motivating stories, demotivating stories, nuances, and all sorts of other things.  If anything, this will be used as a self-counseling and rambling type session, and if you want to follow along, feel free.

Usually you'll hear a sizable amount of pessimism from other people when you mention a desire to make a game engine. This is probably rightfully so.  As a solo developer myself, I will have to admit I didn't truly appreciate the sheer complex, massive task that this would encompass.  As of this writing, my own engine isn't "done", it isn't "feature complete", and has a substantial amount of things todo left.  However, my engine currently DOES fuel the backbone of a couple of cross-platform, published games - so it IS functional and even usable.

I suppose the first thing we need to focus on is just WHAT exactly IS a game engine.  I could probably list out a dozen or so references and copy pasta, but I generally like to rephrase things in my own words as I feel that once I believe I understand something, I should be able to reiterate it off the top of my head in somewhat plain English.

So, without further ado, a game engine is a large, complex collection of software that other software products (in this case games) utilize to deal with inconvenient and time consuming aspects of development.

When we save time, we save money.  An endeavor to make a game engine is a non-trivial obligation and decision to invest a substantial amount of time to save you time and money later.  Return on investment is the name of the game here.

Speaking of return on investment.  There are plenty of ready made engines out there.  You will likely see people advocating their use.  Things like Unity, Cocos2d, GameMaker, and various others exist.  If you are convinced you want to make an engine, you should STILL download some/all of them and look at them.  Look at the service they provide, look at the source code (where applicable), play with them a bit.  Get a feel for how they work and what they give you.  If you are to make your own engine, YOU will be making a comparable product, with similar interfaces, with similar needs and goals.  Think of this as competitive research.

If you look at the comparable engines out there, I hope you begin to look at how overwhelming the goal of making your own is.  "Look at all this stuff, I certainly won't need all this clutter!".  Trust me, I know what you're saying.  Chances are, you're right, you likely won't need a large portion of "all that stuff".  Sadly, there is a lot of it you will need, but you won't know that until you're well in to development (likely several months or even years).  So, look at these large projects and realize one thing.  There exists the potential that YOU will ultimately make something very similar in scope and complexity, you just don't know it yet!

"But all I really need is something to load up graphics and put them on the screen... my game code will handle the rest".  This is incredibly naive and very, very far from the truth.  I know, because I thought like this once.

The small laundry list of things you think you need will grow ever so slightly at first, but it grows at a consistent pace.  Oh, I need some abstract thing that handles generic box-like shaped regions (think clickable zones, usually useful for things like buttons)... yea, we'll need that... but what about font and text handling... don't really need TTF format support... or do I?  Should I want to load in custom bitmap fonts?  Oh, I need to be able to load bitmap formats (bmp, png, jpg?).  It will probably be good to be able to display those graphics too -- hmm, OpenGL, DirectX?  Is my engine going to be cross-platform?  If so, there are major implications for choices that I can make.

Surely, we COULD support DirectX with a cross-platform engine... but that technology would only be supported for the Windows versions of our games.  This sounds fairly straightforward, but it complicates things in your graphics code, build process, and even workflow when messing with your engine, and then ultimately building games using that engine - which of course is the actual goal when rolling your own engine.

I'm going to make more articles about specifics as I go, so don't worry.

For now, know this.  The game engine I'm currently working on, and actually using, is my 4th attempt at making an engine.  It is by far the most complex and furthest developed one I've ever made (none of the other ones actually fueled any games!).

I highly recommend you not grow too overly attached to any engine you make right away.  The first engine or two you make should really be seen as a learning experience because you will need a deep appreciation for the overarching goal and understanding of what it is you need to do and actually CAN do before you can make something actually usable.

Look in to version control software.  I'm using the very awesome mercurial to track changes in my engine code (and to keep my own general sanity).  According to my commits, my current engine was first submitted to version control on 17 August, 2012.  As of this writing, it will be hitting its 2nd birthday soon.  It is still not "complete".  We have a ways to go still; especially in 3d support and having support for playing back avi/mpg files in games.  There are plenty of other things left to do as well, some of which I probably don't even know yet, but we'll get there.

What I hope you take away from this article is several things.

One, making a game engine is not trivial.

Two, making a game engine is vastly time consuming, likely taking years of fairly hard work and lots of research.

Three, making a game engine is a lot more complicated than you realize.

Four, be ready to admit your ways are wrong, to incorporate new ideas, and be ready to gut things that aren't working in favor of newer, better ways of doing things.

Five, if you're weak of heart and don't have borderline OCD, this probably isn't for you.  If you're even somewhat on the fence about this whole thing, you will likely only find disappointment.

Oh, and lastly, you should consider using other game engines still... but if you're still not actually convinced and you still want to venture forth in to this crazy goal... then by all means, let us proceed!

Next article we'll talk about choice of technology and actually getting started making your own game engine through my ramblings about how I got started with my own.

It is not for the feint of heart, but here you go, the dawn of a new game engine!







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!

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.