Tuesday, March 26, 2013

btrxml

Parsing XML; while not really an ideal solution for game technology, it has its uses.  XML is useful for data exchange between programs in a somewhat human readable form.

Well, games are all about machine readable form and could care less about the human part; I mean really, only programmers have to care about game data, and they are barely human as it is anyways... at any rate, converting text to binary is not a good way to tackle large, complex data; especially since text (ascii/unicode/whatever) is problematic in and of itself.

So, it came to pass that we needed to parse XML and either make a conversion method per project and implement plugins, or just implement XML directly in to our programs.  We did just that and open-sourced it and put it on sourceforge under the zlib license.  It is written in C and should be used solely to consume well-formed XML.  It cuts a lot of features out of a normal parser, can't output, but does use a DOM structure.  The idea here is that it should be used to eat XML quickly and efficiently on devices with little memory.

I've never contributed to FOSS stuff before and I never though I'd see the day that I would, but here it is.  I look forward to maintaining this project (it's only 2 files as is it!) and seeing where this project gets implemented in to the future.

The project can be found here:
http://sourceforge.net/projects/btrxml/

Tuesday, February 26, 2013

Autonomous Weapons

Progress in the fields of robotics, systems engineering, manufacturing, energy production, and even computer engineering and computer science are nothing short of spectacular.  Our every day lives reap the rewards of an ever-increasing life style afforded through implementing automation.

We can see amazing 3d animated movies from Pixar/Disney, we can install and use prosthetic limbs, we have smartphones, and many other wondrous applications of technology.  There is one industry that also benefits from the direct application of technology.  The war industry.

What does this mean and how does it impact civilization?

For as long as humans have known to exist, we have always been territorial in so much that we get in to conflicts with one another for various reasons throughout the ages.  At the end of the day, though, there was almost always some winner, and some loser.

We started with bare fists then moved on to tools and machines.  This last part brought on a whole new, and potentially devastating aspect to war and conflict.  To what extent can we damage and destroy each other and potentially the planet itself?

These days, it is common to hear about collateral damage - or the "accidental" damage caused to unintended targets (usually civilians).  This almost always indicates accidental casualties in the form of human lives or unrelated structures and/or services.  With the use of technology, our destructive capacity has increased well beyond where we have come from in humanity's early days.

During recent conflicts, a spotlight has been put on covert operations ("blowback"), show of force, nuclear weapons deterrence, terrorism, and whole lot of other scary stuff.  One thing that made traditional war mongering unappealing with a domestic populace was the political cost of human lives -- no politician wants to be seen as the person that killed off a generation of their own "sons and daughters" in some foreign war.  While the ideas of patriotism hold true in any population supporting the current aristocracy, death brings a quick reminder that any leader is working with borrowed time before a population grows tired of their war endeavors.

Fortunately for the political machine, at least in the United States, the civilian population is somewhat removed and apathetic from the political throes of unending war (though they certain carry the burden of funding said war efforts).  The US has been involved with the Middle East in combative/support type roles for over 2 decades almost non-stop, and a lot of regular people just don't care -- unless their friends and family are dying or get maimed.  

Even the fact that it's hard to say what exactly we're doing over there is tough because it all depends on who's defining "combat".  What does that mean?  If we listen to politicians, they claim combat is over and now we're there to be everyone's friends.  The reality is, combat still happens with our guys and their guys every day.  Who's the winner, who's the loser?  War has changed, just as our weapons have.  The line has blurred between enemy combatant and a kid using a machine gun.  Who's defending what?  Why are we there anyways?

I ask these questions because in the realm of "Autonomous Weapons", these sorts of questions would possibly be decided by software.  Currently, many machines are remote controlled, still directly influenced by some sort of human "pilot".  They may be predator drones, or be a land mine recovery robot; it doesn't matter, a human is still controlling their action directly and would be more or less responsible for their actions or misdeeds.  What would happen if an automated weapon performed a misdeed?  Who's to blame, the software programmer?

Our human pilots [attempt] to follow certain laws of combat (which also get blurry) or at least certain orders from their chain of command (in the military anyways).  This doesn't even touch the idea of the current privatization of our military capacities to mercenaries ("privatized security firms") as this brings a whole other aspect to war worthy of its own tirade.

War is also a blame game these days.  Who can shirk responsibility to someone else the longest.  This is the world of politics and that is what runs the war game.  People will believe what THEY want us to believe because we don't know enough about what happens in the world to know any better.

So, let's get back to the topic at hand.  With all that said, how do we define an automated weapon?  It can "think" on its own?  As a computer scientist, I deal with software in many aspects.  Software would be responsible for the decision making process of any said automated weapon.  During academia, I saw many complicated proofs that basically asserted that computers (the "brains" of any automated weapon) operate with logic, yet still require constant input either from the environment or from a programmer to assert facts about existence so that it can make "logical" connections.
Now, I'm also a fan of philosophy and will admit that humans almost never act in a 100% logical fashion, and this is what sets "US" apart from "THEM".  What we're basically proposing here is that a killer robot would be able to understand abstract ideas and make automated decisions without the need for human input -- then put that same robot in to a position of lethal authority over perceived enemy combatants.

No problem we think, we'll just program Asimov's three laws of robotics in to all death dealing machines and we'll be ok!

Wrong.

Technically speaking, an automated weapon doesn't even have to be complicated.  It could just be a gun connected to a motion detector and fire when something moves.  There is no complicated AI here, just an "if then else" type of situation (one which all software incidentally will be using).  The psuedocode would be:
if (motiondetected AND has human form) fireLasers at target

At any rate, what all the excitement is about would be to essentially replace actual ground soldiers with robots.  How could this happen?  You can bet your money (and everyone else's money in the form of taxes) that our government is looking for a way to make this happen.  An automated military would save a lot of political face when we remove the human cost to war, meaning we would see a lot more inclination to use force to get our way.  It would be somewhat easy to just crank out 100,000 deathbots in a factory and deploy them to, say Africa, to claim all their diamond mines because we can.  No soldiers needed anymore, and because nobody is dying (our guys anyways), nobody cares!

One of the other "benefits" of deathbots would be that we would no longer need such a large standing military.  Think of all the money saved in health care costs, life insurance pay outs, training costs, etc!  In fact, this would be so amazing, we wouldn't need veterans benefits anymore because the veteran population would dwindle to nothing through attrition!  Because enlistment rates would plummet, we really wouldn't need things like the GI bill (which was arguably a major factor creating the current middle class in the USA)... the list could go on.

I would like to say I'm joking, but these would be perceived benefits, depending on who you are in the political machine.

Next rant about this, I'll go in to software aspects on how automated deathbots would theoretically work, or not work.  Until then, enjoy Asimov's Three Laws of Robotics (rule 0 exists as well)

0. A robot may not harm humanity, or, by inaction, allow humanity to come to harm.

1. A robot may not injure a human being or, through inaction, allow a human being to come to harm.

2. A robot must obey the orders given to it by human beings, except where such orders would conflict with the First Law.

3. A robot must protect its own existence as long as such protection does not conflict with the First or Second Laws.

Oh yea, and here's an article if you haven't gotten enough reading yet.

http://www.guardian.co.uk/technology/2013/feb/23/stop-killer-robots



Saturday, February 16, 2013

Compiling libcurl for Android

Curl is a pretty nifty package and it can be useful on lots of platforms to provide a fairly sane way to contacting and downloading network stuff (webpages for example).  Now to only get this to work on Android for games or whatever...

This was a bit tricky.

I used the standalone toolchain with API level 9 (gingerbread, Android 2.3) and did not use ndk-build script.

Two things ultimately had to be done before libcurl would successfully compile for Android using the toolchain.  I opted for using a Makefile and good old fashioned make... but there was some "convincing" needed to be done to make this happen.

First, I defined two symbols during compile time.  This would be -DANDROID_NDK and -DHAVE_CONFIG_H.  You will want the second one as is, the first can be renamed to whatever you want so long as you know this is selecting Android specific code during compilation and this is the same symbol to check for below.

Now, you need to add a section in [curl]/include/curlbuild.h

I added the following code above the "penultimate" section for MSVC.  These defines MUST go in curlbuild.h unless you want to make curl angry with you.

#elif defined(ANDROID_NDK)
#  define CURL_SIZEOF_LONG           4
#  define CURL_TYPEOF_CURL_OFF_T     long long
#  define CURL_FORMAT_CURL_OFF_T     "lld"
#  define CURL_FORMAT_CURL_OFF_TU    "llu"
#  define CURL_FORMAT_OFF_T          "%lld"
#  define CURL_SIZEOF_CURL_OFF_T     8
#  define CURL_SUFFIX_CURL_OFF_T     LL
#  define CURL_SUFFIX_CURL_OFF_TU    ULL
#  define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
#  define CURL_SIZEOF_CURL_SOCKLEN_T 4
#  define CURL_PULL_SYS_TYPES_H      0
#  define CURL_PULL_SYS_SOCKET_H     0

This defines some macros needed to build curl for Android, but wait, there's more.

We also have to make curl know we want to use a curl_config.h file (which is normally generated with ./configure, but we like to do things our own way).

Because we defined HAVE_CONFIG_H (-DHAVE_CONFIG_H), curl is now instructed to look for this file when compiling.

It took some trial and error, and this probably isn't totally correct, but I got curl to compile and seemingly functional with this manually constructed file.  It originally was the windows config file I think warped to a more linux-like configuration.  At the end of the night (read: week), it resulted as follows:



#ifndef HEADER_CURL_CONFIG_H
#define HEADER_CURL_CONFIG_H

/* ================================================================ */
/*               Hand crafted config file for Android               */
/* ================================================================ */

/* ---------------------------------------------------------------- */
/*                          HEADER FILES                            */
/* ---------------------------------------------------------------- */

/* Define if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1 */

/* Define if you have the <assert.h> header file. */
#define HAVE_ASSERT_H 1

/* Define if you have the <crypto.h> header file. */
/* #define HAVE_CRYPTO_H 1 */

#define HAVE_PERROR 1
#define HAVE_PIPE 1
#define HAVE_POLL 1

#define HAVE_GETADDRINFO 1
#define HAVE_FREEADDRINFO 1

#define HAVE_PWD_H 1

/* Define if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1

/* Define if you have the <err.h> header file. */
#define HAVE_ERR_H 1 */

/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1

/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
#define HAVE_FCNTL_O_NONBLOCK 1

/* Define if you have the <getopt.h> header file. */
#define HAVE_GETOPT_H 1

/* Define if you have the <io.h> header file. */
/* #define HAVE_IO_H 1 */

/* Define if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1

/* Define if you have the <locale.h> header file. */
#define HAVE_LOCALE_H 1

/* Define if you have the <netdb.h> header file. */
#define HAVE_NETDB_H 1

/* Define if you have the <netinet/in.h> header file. */
#define HAVE_NETINET_IN_H 1

/* Define if you have the <process.h> header file. */
/* #define HAVE_PROCESS_H 1 */

/* Define if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1

/* Define if you have the <sgtty.h> header file. */
/* #define HAVE_SGTTY_H 1 */

/* Define if you have the <ssl.h> header file. */
/* #define HAVE_SSL_H 1 */

/* Define if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1

/* Define if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1

/* Define if you have the <sys/select.h> header file. */
#define HAVE_SYS_SELECT_H 1

/* Define if you have the <sys/socket.h> header file. */
#define HAVE_SYS_SOCKET_H 1

/* Define if you have the <sys/sockio.h> header file. */
/* #define HAVE_SYS_SOCKIO_H 1 */

/* Define if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1

/* Define if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1

/* Define if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1

/* Define if you have the <sys/utime.h> header file. */
/* #define HAVE_SYS_UTIME_H 1 */

/* Define if you have the <termio.h> header file. */
/* #define HAVE_TERMIO_H 1 */

/* Define if you have the <termios.h> header file. */
/* #define HAVE_TERMIOS_H 1 */

/* Define to 1 if you have the <sys/uio.h> header file. */
#define HAVE_SYS_UIO_H 1

/* Define to 1 if you have the <sys/un.h> header file. */
#define HAVE_SYS_UN_H 1

/* Define to 1 if you have the <sys/utime.h> header file. */
#define HAVE_SYS_UTIME_H 1

/* Define to 1 if you have the <termios.h> header file. */
#define HAVE_TERMIOS_H 1

/* Define to 1 if you have the <termio.h> header file. */
/* #undef HAVE_TERMIO_H */

/* Define to 1 if you have the <time.h> header file. */
#define HAVE_TIME_H 1

/* Define if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1

/* ---------------------------------------------------------------- */
/*                        OTHER HEADER INFO                         */
/* ---------------------------------------------------------------- */

/* Define if sig_atomic_t is an available typedef. */
#define HAVE_SIG_ATOMIC_T 1

/* Define if you have the ANSI C header files. */
#define STDC_HEADERS 1

/* Define if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1

/* ---------------------------------------------------------------- */
/*                             FUNCTIONS                            */
/* ---------------------------------------------------------------- */

/* Define if you have the closesocket function. */
/* #define HAVE_CLOSESOCKET 1 */

/* Define if you don't have vprintf but do have _doprnt. */
/* #define HAVE_DOPRNT 1 */

/* Define if you have the ftruncate function. */
#define HAVE_FTRUNCATE 1

/* Define if you have the gethostbyaddr function. */
#define HAVE_GETHOSTBYADDR 1

/* Define if you have the gethostname function. */
#define HAVE_GETHOSTNAME 1

/* Define if you have the getpass function. */
#define HAVE_GETPASS 1

/* Define if you have the getservbyname function. */
#define HAVE_GETSERVBYNAME 1

/* Define if you have the getprotobyname function. */
#define HAVE_GETPROTOBYNAME

/* Define if you have the gettimeofday function. */
#define HAVE_GETTIMEOFDAY 1

/* Define if you have the inet_addr function. */
#define HAVE_INET_ADDR 1

/* Define if you have the ioctlsocket function. */
/* #define HAVE_IOCTLSOCKET 1 */

/* Define if you have a working ioctlsocket FIONBIO function. */
/* #define HAVE_IOCTLSOCKET_FIONBIO 1 */

/* Define if you have the perror function. */
#define HAVE_PERROR 1

/* Define if you have the RAND_screen function when using SSL. */
#define HAVE_RAND_SCREEN 1

/* Define if you have the `RAND_status' function when using SSL. */
#define HAVE_RAND_STATUS 1

/* Define if you have the `CRYPTO_cleanup_all_ex_data' function.
   This is present in OpenSSL versions after 0.9.6b */
#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1

/* Define if you have the select function. */
#define HAVE_SELECT 1

/* Define if you have the setlocale function. */
#define HAVE_SETLOCALE 1

/* Define if you have the setmode function. */
#define HAVE_SETMODE 1

/* Define if you have the setvbuf function. */
#define HAVE_SETVBUF 1

/* Define if you have the socket function. */
#define HAVE_SOCKET 1

/* Define if you have the strcasecmp function. */
#define HAVE_STRCASECMP 1

/* Define if you have the strdup function. */
#define HAVE_STRDUP 1

/* Define if you have the strftime function. */
#define HAVE_STRFTIME 1

/* Define if you have the stricmp function. */
#define HAVE_STRICMP 1

/* Define if you have the strncasecmp function. */
#define HAVE_STRNCASECMP 1

/* Define if you have the strnicmp function. */
#define HAVE_STRNICMP 1

/* Define if you have the strstr function. */
#define HAVE_STRSTR 1

/* Define if you have the strtoll function. */
#define HAVE_STRTOLL 1

/* Define if you have the tcgetattr function. */
#define HAVE_TCGETATTR 1

/* Define if you have the tcsetattr function. */
#define HAVE_TCSETATTR 1

/* Define if you have the utime function. */
#define HAVE_UTIME 1

/* Define to the type qualifier of arg 1 for getnameinfo. */
#define GETNAMEINFO_QUAL_ARG1 const

/* Define to the type of arg 1 for getnameinfo. */
#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *

/* Define to the type of arg 2 for getnameinfo. */
#define GETNAMEINFO_TYPE_ARG2 socklen_t

/* Define to the type of args 4 and 6 for getnameinfo. */
#define GETNAMEINFO_TYPE_ARG46 size_t

/* Define to the type of arg 7 for getnameinfo. */
#define GETNAMEINFO_TYPE_ARG7 int

/* Define if you have the recv function. */
#define HAVE_RECV 1

/* Define to the type of arg 1 for recv. */
#define RECV_TYPE_ARG1 int

/* Define to the type of arg 2 for recv. */
#define RECV_TYPE_ARG2 void *

/* Define to the type of arg 3 for recv. */
#define RECV_TYPE_ARG3 size_t

/* Define to the type of arg 4 for recv. */
#define RECV_TYPE_ARG4 int

/* Define to the function return type for recv. */
#define RECV_TYPE_RETV ssize_t

/* Define if you have the recvfrom function. */
#define HAVE_RECVFROM 1

/* Define to the type of arg 1 for recvfrom. */
#define RECVFROM_TYPE_ARG1 int

/* Define to the type pointed by arg 2 for recvfrom. */
#define RECVFROM_TYPE_ARG2 void

/* Define to the type of arg 3 for recvfrom. */
#define RECVFROM_TYPE_ARG3 size_t

/* Define to the type of arg 4 for recvfrom. */
#define RECVFROM_TYPE_ARG4 int

/* Define to the type pointed by arg 5 for recvfrom. */
#define RECVFROM_TYPE_ARG5 struct sockaddr

/* Define to the type pointed by arg 6 for recvfrom. */
#define RECVFROM_TYPE_ARG6 socklen_t

/* Define to the function return type for recvfrom. */
#define RECVFROM_TYPE_RETV ssize_t

/* Define if you have the send function. */
#define HAVE_SEND 1

/* Define to the type of arg 1 for send. */
#define SEND_TYPE_ARG1 int

/* Define to the type qualifier of arg 2 for send. */
#define SEND_QUAL_ARG2 const

/* Define to the type of arg 2 for send. */
#define SEND_TYPE_ARG2 void *

/* Define to the type of arg 3 for send. */
#define SEND_TYPE_ARG3 size_t

/* Define to the type of arg 4 for send. */
#define SEND_TYPE_ARG4 int

/* Define to the function return type for send. */
#define SEND_TYPE_RETV ssize_t

/* ---------------------------------------------------------------- */
/*                       TYPEDEF REPLACEMENTS                       */
/* ---------------------------------------------------------------- */

/* Define to the return type of signal handlers (int or void). */
#define RETSIGTYPE void

/* ---------------------------------------------------------------- */
/*                            TYPE SIZES                            */
/* ---------------------------------------------------------------- */

/* Define to the size of `int', as computed by sizeof. */
#define SIZEOF_INT 4

#define SIZEOF_LONG 4

/* Define to the size of `long double', as computed by sizeof. */
#define SIZEOF_LONG_DOUBLE 12

/* Define to the size of `long long', as computed by sizeof. */
#define SIZEOF_LONG_LONG 8

/* Define to the size of `short', as computed by sizeof. */
#define SIZEOF_SHORT 2

/* Define to the size of `size_t', as computed by sizeof. */
#define SIZEOF_SIZE_T 4

/* ---------------------------------------------------------------- */
/*                          STRUCT RELATED                          */
/* ---------------------------------------------------------------- */

/* Define if you have struct sockaddr_storage. */
#define HAVE_STRUCT_SOCKADDR_STORAGE 1

/* Define if you have struct timeval. */
#define HAVE_STRUCT_TIMEVAL 1

/* Define if struct sockaddr_in6 has the sin6_scope_id member. */
#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1

/* ---------------------------------------------------------------- */
/*                        COMPILER SPECIFIC                         */
/* ---------------------------------------------------------------- */

/* Define to nothing if compiler does not support 'const' qualifier. */
/* #define const */

/* Define to nothing if compiler does not support 'volatile' qualifier. */
/* #define volatile */

/* Windows should not have HAVE_GMTIME_R defined */
/* #undef HAVE_GMTIME_R */

/* Define if the compiler supports C99 variadic macro style. */
#define HAVE_VARIADIC_MACROS_C99 1

/* gcc variadic macros */
#define HAVE_VARIADIC_MACROS_GCC 1

/* Define if the compiler supports the 'long long' data type. */
#define HAVE_LONGLONG 1

#define SIZEOF_TIME_T 4

/* ---------------------------------------------------------------- */
/*                       DNS RESOLVER SPECIALTY                     */
/* ---------------------------------------------------------------- */

/*
 * Undefine both USE_ARES and USE_THREADS_WIN32 for synchronous DNS.
 */

/* Define to enable c-ares asynchronous DNS lookups. */
/* #define USE_ARES 1 */

/* Define to enable threaded asynchronous DNS lookups. */
/* #define USE_THREADS_WIN32 1 */

#if defined(USE_ARES) && defined(USE_THREADS_WIN32)
#  error "Only one DNS lookup specialty may be defined at most"
#endif

/* ---------------------------------------------------------------- */
/*                           LDAP SUPPORT                           */
/* ---------------------------------------------------------------- */

#define CURL_DISABLE_LDAP 1
#define CURL_DISABLE_LDAPS 1

/* ---------------------------------------------------------------- */
/*                       ADDITIONAL DEFINITIONS                     */
/* ---------------------------------------------------------------- */

/* Define cpu-machine-OS */
#undef OS
#define OS "arm-android-linux"

/* Name of package */
#define PACKAGE "curl"

/* If you want to build curl with the built-in manual */
#define USE_MANUAL 1

#define ENABLE_IPV6 1

#endif /* HEADER_CURL_CONFIG_H */


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.

Tuesday, January 15, 2013

Back to Basics and Understanding Application Performance

The article I'm linking here was written back in 2001, it is "old" in technology terms, yet is still 100% completely accurate and relevant!

http://joelonsoftware.com/articles/fog0000000319.html

Java, C#, .NET, database languages like MySQL, and things like this all benefit from someone with a nice, solid understanding of how "lower level" technology works.  The linked article delves in to a bit of C code in which all these other languages implement on some level.

I will be forthcoming on this, I do not agree, even today, that universities should remove a C programming class from any Computer Science curriculum.  I believe it teaches vital "low level" understanding of fundamental concepts of how software works.  Sure, one level further down and we get to assembly and all that good stuff, and while I think that should be taught as well to some degree - maybe as an elective - C is probably the "best" starting point.

I also agree with Joel, the article's author, with the essence of this quote.

I am actually physically disgusted that so many computer science programs think that Java is a good introductory language, because it's "easy" and you don't get confused with all that boring string/malloc stuff but you can learn cool OOP stuff which will make your big programs ever so modular. This is a pedagogical disaster waiting to happen. Generations of graduates are descending on us and creating Shlemiel The Painter algorithms right and left and they don't even realize it, since they fundamentally have no idea that strings are, at a very deep level, difficult, even if you can't quite see that in your perl script. If you want to teach somebody something well, you have to start at the very lowest level.