...yet. But is it not the dream of every software developer to build games? Thinking back to my childhood and my early interest in computers, I can say for certain that it may not be. Indeed, my early computers could not play games -- nor could I afford them. I therefore spent far more time sitting in the aisles of the public library, reading outdated operating systems books, hardware books, tinkering with Linux and programming crude windowing and application user interface systems with Borland's C and Pascal compilers (I remember having to make my own cursor blink).
It is not until now - in my early 30's - that I attempt to build a game. I think it's more of an adult dream than it ever was a childhood dream.
The advantage of this is that I need not worry about how much money I can make as a game developer, or whether I'm wasting my time learning how to build games. That said, in my short time spent building a game, I have learned of new challenges, patterns and software development techniques. This is wonderful, as I've been shoveling bits from one database to another in "Enterprise" software development for 12 years now, so it's rare that I come across anything really new and interesting in that space.
Perhaps the dream is not of the game itself, but what the game can teach me as a software developer. I've always been a practical learner, so I purposefully read no books about game development -- I've just purchased my first, now having written a significant portion of the game. I suppose I want to see what I naturally got "right", and what "I didn't know that I didn't know".
Being a fan of RPGs, and currently only possessing the graphics programming skills to build a 1980's style NES Zelda type game... that's what I targeted. While they can be simple on the graphics side, RPGs are known to be quite complicated in many other respects -- and in total, are probably the toughest type of game to build.
The User Interface
Some of the most interesting challenges obviously come in the user interface. A game built with Swing, Flex or WinForms would probably suck. :-)
For someone like me, it's not every day that I get to calculate the positions, viewable areas and movable areas within a virtual map etc. But that might not be entirely unique to game development. Anyone doing Google Maps style work or any GIS project may experience this kind of challenge. But I took a very raw approach to building this first game of mine. I used no frameworks or libraries to help. I really wanted to know what went into such things.
The math wasn't rocket science by any means. But the OO design decisions were definitely interesting. Should the map know about the character position? Should the character know about its position on the map? Both? Neither? Furthermore, what should decide what is visible to the player? The map is bigger than the available screen space, so a scrollable window is necessary. What decides what is viewable in that window?
It sounds so simple.. but I think I wrote that part about 12 times before coming up with something I was happy with.
Movement and Zone Detection
A typical RPG doesn't really have a lot of complex collision detection, but what it does have is places where you can walk, and where you cannot walk. It also needs hot spots for loading maps, starting encounters, finding treasure, triggering story lines etc. I had nightmares about calculating polygon shapes and sizes, or using bitmasks with complex bitwise operations for determining the characteristics of a certain part of the map. Programmatically it's not that hard to implement something like that. But where it becomes complex is in actually creating a map. Thus special tools become necessary to create a map. I didn't want my game development experience to begin with having to build a map editor. I wanted to just paint up a map with Paint.NET and be done with it. The approach I took might be a bit grunt, but at the end of the day, I think it works quite well. I chose to use a color mask, where the colors can be configured (by their easily readable HTML hex code). For example, here is the first map, with 4 zones:
I could say 0x000000 (black) is the no-walk zone, 0xFF0000 (red) loads the cave map, and 0x0000FF (blue) loads the map to the east. The default zone is 0xFFFFFF, which is walkable and does nothing else (but could -- definable on a per map basis). This approach allows me to use any simple paint program and a text editor to create my maps. There are more than enough colors definable that I won't run out of easily identifiable colors on any single map (I can't see using more than 12 or so on any one map). Furthermore, it is also pretty easy to create a custom map editor when the time comes. But it's not required to get me past the point of map creation and into the development of the game.
I am also not an artist...
Now that I have a couple of screenshots up, I can point out that I am not an artist. First, I didn't create any of the above art. Of course I created the map and the mask, but not the elements of the map, like the trees and cave etc. And while the art seems simple, I think it's great. Both the map assets and the characters were found online with friendly licensing like Creative Commons. It's a good thing, because my backup plan was stick men.
As simple as these graphics are, I have to give full respect to the creators. Something like those little 2 frame character animations are actually an incredible amount of work to create -- at least for me. I'm sure there are people out there who can crank out a full set of 8 direction, 2 frame character sprites (total 16 images) in an hour. But to get them all matching and looking like they belong in the same game -- that's entirely different. It's not just pixel pushing, it's art.
For sound, I took a similar approach. There were plenty of Creative Commons or at least friendly licensing terms for simple sound effects and background music.
Java as a web game platform
I have 15 years of Java development experience, and therefore defaulted to Java as a target platform. Even though I have never built an Applet that was actually used for anything (has anyone?). I also had this sinking feeling that there must be a reason that I've never seen a serious game build with Java on the web.
Without question Flash dominates this space. But I hypothesized that the reason for this was simply due to the heritage of the two languages. Java has foundations primarily in enterprise computing, business software, web applications, web services, and the odd successful desktop software (usually development tools). Flash on the other hand has a heritage in graphics, animation, and rich media on the web. I'm sure the multimedia programs taught at colleges around the world target Flash in their curriculum and not Java.
So I figured that there's no reason why Java couldn't be a decent platform for game development -- for a Java developer.
Unfortunately this is not the case. The sad thing is that it isn't due to the libraries, the language or other aspects of software development. Although, Flash has some clear advantages in the tools and libraries available.
The big problem for Java though, was the end user experience.
The JVM is a brilliant piece of software. But as a browser plugin and an end user runtime environment, it is very large (at least 5x the size of the Flash Player), and its security policies are outrageous. In addition, even something as simple as the Java logo during the initialization of the JVM has a significant impact on the end user experience -- especially when we're talking about a game. Games are about tone, environment, feel and player immersion. Having the player's first experience be a security policy dialog box and a Java logo is a pretty terrible consequence for choosing the Java platform. Furthermore, the Java Runtime Environment is not as ubiquitous as Flash, and only recently has it had an updater that could be trusted to keep it up-to-date (around Java 1.5 and 1.6).
Now, let's not give up just yet.
- The security policy issue can be improved a couple of ways. First, simply don't use any features that require special security permissions. My game doesn't need access to the disk, or arbitrary network access to servers other than the one it was served from. No, the only thing I wanted to do in my applet was utilize modern practices for mapping rich domain classes to an HTTP friendly data format like XML or YAML. Thus I wanted to use reflection to serialize and deserialize my domain classes to these text based formats. However, reflection is restricted in the Applet sandbox, and thus requires special permission. Signing the JAR at least allows the user to see what they're accepting and from who... but it is a hideous limitation of the JRE. I understand why it was necessary, but it is a flaw of the runtime environment. Reflection upon my own classes should be perfectly allowable, and only reflection upon JRE or perhaps even 3rd party JARs should be restricted.
- The Java splash screen is required, but the image can be replaced by one that you specify. It's a minor improvement, but the only reason such a loading screen is required must be that the JRE is slow to load, and/or it needs to finish dealing with the above security policies before it can move beyond the loading screen. And thus the issues are compounded.
- As for the Java version, there's not much you can do about that one. Most players of a game such as mine would not know what Java or Flash are. They just know it's a game that magically works in their browser. And Flash has long been masterful at keeping this magic transparent, invisible, fast and simple for users. As of this writing, Flash player 10 is available on 98% of computers running various operating systems. That's greater penetration than the Windows OS itself. By contrast, the JRE has about an 80% penetration rate, for all versions -- I have no idea what percentage of which versions are available where... Thus one's only recourse is to put a big note: "Hey you require Java 1.6. If the game doesn't work, go to ORACLE (a pinnacle of end-user friendliness) for an upgrade."
Credit for what it's worth...
So the end-user experience was the show stopper for me. It was truly unfortunate, because when it came to developing the game, I was mostly happy. Like all Java APIs, the Java 2D graphics libraries are overcomplicated and often require chains of various classes and approaches to do something relatively simple. But that said, I was able to do everything I needed, even if I had to look up a lot of examples from the web.
- As a side note, I also built this same game for Android and I found the graphics APIs for Android to be superior to Java 2D. It's clear why Google did not want to use the plain Java 2D APIs for Android. And oops, they're getting sued for it. But I digress...
I was able to easily implement double-buffered scrolling and sprite animations. I was able to use Swing components seamlessly underneath the game view. Also, there were a lot of good methods for drawing polygons, filled, with alpha transparency and other treats that ultimately allowed me to do exactly what I wanted, even if it took a few extra lines of code and some arm waving to achieve it.
Probably my favourite part of using Java was its ability to play MIDI files. Although I was ultimately disappointed by excessive complexity and ultimately the inability to control the volume properly (a known issue). But I love MIDI and think it's totally underutilized today. It's a very small file (because it uses hardware sound banks) and yet the sound can be very good. A large reason why it's probably not used in games is that it can be inconsistent. One computer might sound like a live orchestra, whereas another might sound like a C64. But I love it nevertheless, and being a retro game, the C64 consequence could be a perk for some in this case.
The biggest annoyance, as mentioned, was the graphics APIs. Between Image, BufferedImage, ImageObservers, Graphics, Graphics2D, Rectangle, Rectangle2D.... it was all too much. There's at least two of any class that you would expect, and it becomes a chore trying to figure out which is compatible with which, or which you need to do any one thing. It's not unlike other Java APIs that have multiple implementations, like collections and dates to name a couple.
Sidebar: My Learning Goals
Experts recommend that anyone serious about software development should learn one new language per year. I've generally succeeded at that, although for me, most of them have been cast aside, leaving only Ruby, Java and C# as relevant. This is not to say that those other languages aren't awesome and great, I just had no need for them. As hard as I tried, I could not find a place for Groovy, Scala, Go or D in my world (but I'm still trying for D!). That said, learning each new language teaches us not only the language, but the motivations behind it and new techniques for solving problems that we hadn't thought about before. Learning Ruby made me a better Java developer.
That said, learning a new language, while useful and important, is only part of the story. Doing the same thing with a different language doesn't teach you as much as you'd think. It teaches you new ways to solve the same problems, but it doesn't teach you any new problems. And that's where the excitement and larger value comes in -- at least in my opinion.
Ultimately I decided I wanted to build a game after I watched the entire end credits for Assassin's Creed 2 scroll by. And then the credits screen for Fallout 3. I was blown away. The sheer number of people and amount of effort that goes into a game is astonishing. The largest enterprise Java project I can think of does not come close.
I wanted to know that. I don't care what language I have to learn to do it.
So Flash was it.
I already had experience with Flex and ActionScript 3. So the language really was not all that new. I already knew that I preferred AS3 to Java in almost every respect. I missed nothing about the Java language, AS3 is cleaner, more modern and enjoyable. The things I miss were largely in the libraries... like having equals and hashCode available on all classes, and having more advanced collections APIs.
My first approach is probably pretty predictable... I tried to start with a Flex project. That is, I figured I could utilize Flex components to lay out the game, use it for the control panel interface and then just slap a canvas on the component tree and draw on it -- much the same approach I took with the Java Applet -- which was a JApplet with Swing components and a JPanel that I drew the game view on.
Unfortunately I was stopped short in my tracks. Flex dominates the Flash player in such a way that there is little left of actual Flash behavior. The Stage is overtaken, keyboard inputs swallowed, the rendering pipeline is completely bastardized and redraw regions are completely out of control. So without any way to use reliable keyboard input or to draw the a specific zone on the screen easily (which I did solve), I decided to abandon Flex altogether.
Goodbye Application, hello Sprite.
This is where it got scary... and exciting. Learning was about to happen. I had to dispense altogether with everything I knew and was comfortable with. Suddenly I had only a Sprite class and a rendering lifecycle that I had no knowledge of. I made good use of Google.
Keep in mind, that I do not own a license for Flash Pro, or Adobe CS. I was simply coding from scratch, and compiling with the free Flex SDK. All of my graphics were bitmaps or programmatically created with the vector drawing APIs. This was fine with me, as Flash Pro leans toward the artistic side, and in my hands it would be like watching someone paint with oven mitts on.
I was able to reuse my domain model classes, and in general I kept the same application design. The biggest difference was the graphics APIs and the lifecycle.
I have to say that while I was not thrilled with the Java graphics libraries, I was also not impressed by the Flash APIs. For a platform that specializes in this area, I found them cumbersome and limiting. That said... I know I was developing with Flash a little differently than most people would. I'm sure typical Flash devs would use Flash Pro to create the graphics and animations ... rather than code them (thus I am not doing as the Romans do in Rome). Fair enough. But still... the APIs are pretty disappointing. I was expecting something more slick and consistent. Java 2D had a method to draw arbitrary point, filled polygons with alpha transparency. I could find no such beast in the Flash drawing APIs. I used that to draw conversation bubbles above my characters. But I may have missed it somewhere.
The other big departure was the control over the rendering lifecycle. In Java I controlled the main thread (or the main game loop). In there I accept input, update my game, update the graphics etc. In Flash, I had to hook into the existing rendering pipeline through an ENTER_FRAME event. This did save me having to manage the thread myself. But at the same time, I felt like I was hacking into something by latching onto this one event. It was fine, I'm probably just demonstrating discomfort with something new, but it was not how I expected it. At the end of the day, this is a pretty small part of the code anyway. However, it was also one of the main keys to performance, which I'll talk to later.
Event Driven Development
But by far the biggest leap that I had to make moving from Java to Flash was from a synchronous programming style to an asynchronous one. Flash is heavily event driven. As mentioned above, the very first thing you do to hook into the rendering pipeline is create an event listener for the ENTER_FRAME event. And that continues for absolutely everything. You cannot just simply make a web request for an image, wait for the image to load, and then use it. The second you make the web request, your application continues on and the asset is loaded asynchronously --and fires an event to notify you when it's done. Yeah, I've coded like this before, of course. Every rich user interface on earth, be it Swing, WinForms or Flex uses an event based component model. And they all require management of concurrent activities so that you don't freeze up the application while waiting for DB or network IO, usually with thread, a monitor, a progress bar and a cancel button.
But this is different. When building a Flash application, you're always in a state of responding to an event. Or in double-negative speak: you're never not in an event handler. It's event after event, chained together. After a while it feels like Tarzan swinging from vine-to-vine.
I'm not complaining though. Somehow this approach seems right. After all, requesting an image from the web synchronously and waiting for it would probably be bad for game playability... or any kind of animated application for that matter. The Flash environment seems to be focused on always moving, and never stopping for anything, ever. And thinking about the domain, that sounds like exactly what it should do.
This is what I mean about learning new languages vs. learning new domains... I knew AS3 via Flex already. But it was the same problem space. Now I knew AS3 and Flash in a whole new way...
That said, I have a whole new appreciation for Flash developers. To think in these terms is actually quite complex. You can't think linearly anymore, in terms of doing step A, then B, then C. You have to be able to start A, do B, and do something interesting before starting C after A is done. This was mostly felt during the loading of assets. In the Java version I simply loaded each resource in order, waited for each and then moved on when everything was loaded. With Flash there was no way to wait, and no way to know what would load first, or when if ever.
The End Result
Overall I was thrilled with building the game with AS3 and targeting the Flash VM. The end user experience was better, the language was more fun to work with, the libraries were a trade-off (no winners there). I feel like this is the right way to build a game, and that I've learned a lot about how games should be built.
My biggest challenge in Flash came with the control panel that is seen at the bottom of the game window here. Since Flex was impossible to integrate with the Flash, I thought that I could perhaps use the Flash Controls instead. Yes, Flash has another whole set of buttons, drop lists and other UI components that are not Flex. It's not unlike the Java's AWT controls vs Swing controls. Unfortunately the Flash controls don't come as part of the free Flex SDK that I was using. And they are included as FLA binaries, which are not compatible with the command line compiler. So I was out of luck there. I ultimately found a simple set of open source components online though, called Minimal Comps. Time will tell if they're the right long term solution. But for now, they're perfect.
In addition, I had to switch to MP3 for the music, as MIDI is not supported by Flash. But as I said, I think I'm alone in the MIDI space... I don't think anyone is investing new solutions there. MP3 is obviously great, but it's also big... which compounds that whole asynchronous asset loading issue.
Flash does not kill browsers. Flash developers do. I should know, as I got pretty good at killing the Flash Player when I first started out. Creating bitmaps with negative sizes, and various other tricks. That said, I was disappointed a little in that. Sure, it was a programming error... show the error and move on. But the whole player just tanks on some pretty basic programming errors common during development.
However, I never experienced a player crash that I did not cause through a programming error. So blame whomever you want... yes the Flash player should deal with these better. But bugs are bugs too...
As for performance, I learned very quickly that the key to Flash performance is managing framerate -- or the number of times per second that the ENTER_FRAME event fires. Flash has an upper bounds for framerate that you can set on the Stage. In addition to that though, each object drawn to the screen will likely need separate framerates depending on the number of frames they have. For example, my little character sprites have only 2 frames, so 30 FPS will have them moving like Scooby-Doo and Shaggy on the run. So they need about 10 FPS to look right. But other animations might need 30... or 60 if it's really high quality. You can always limit downwards, but the upper bounds will be whatever is set on the stage.
The framerate combined with what your code does upon each cycle is the difference between 100% CPU usage, and 5% CPU usage. If you've ever hit a Flash site that uses 100% of one of your CPU cores, don't blame Adobe...
With both the Java and Flash versions I could easily pin the CPU. But given the same framerate settings, I was able to keep them both under 5% CPU usage on my i5.
So there you have it.
That's my early experience with game development. I'm having a blast and learning a lot. I hope to release this game in some capacity, at some point. I'm trying to keep the engine flexible to allow for better graphics and animations with more than 2 frames. In the mean time, I encourage software developers to not just learn new languages, but learn to do new and different things with them.