Sunday, December 16, 2012

A Little Success With Graphics

After a couple days of work, there's been some success along with a frustrating and perplexing mystery.

The Good News
The PC platform in windowed mode works, rendering scenes using nothing but calls to overridden abstract methods.



The Bad News
The display mode selector is completely, inexplicably broken, so full-screen mode doesn't work.  Neither does windowed mode unless I bypass the selector entirely when retrieving the platform graphics context.

So, it's a start, but there's still some distance to travel before I'll call it "ready".


Thursday, December 13, 2012

A First Look at a Possible High-Level Architecture

Here's a very high-level look at one possible architecture for the new engine.  Essentially, it just takes the features of the current MHFramework, adds a few requirements of the new engine, and organizes them based on dependency and abstraction.

It's rough, but it's a much better start than MHFramework 1 and 2 had.

Sunday, December 9, 2012

First Draft of the Graphics Layer Design

Here is the first draft of a possible solution to the graphics portability problem.  Next I'm going to experiment with it and see what shakes loose.  I'll update the diagram as I figure stuff out.



Platform Layer Elements

One does not simply port from Windows to Android.
...but one could if this experiment works.
In the effort underway to create a reliable, flexible, easy-to-use platform framework, my associate Patrick and I have identified three essential cores:  At a minimum, platform support must include input handling, graphics, and audio.

Input Handling

Handling input devices will be fairly straightforward.  Key presses are common across both platforms, and Android's touch input works in much the same way as a normal computer mouse.

I believe the only feature that cannot be explicitly supported in a platform-independent fashion is multitouch, but since the Ouya doesn't support it either, this really isn't a problem.  Most likely, I'll implement support for multitouch and just throw an exception if it's invoked from a non-Android app.

Like the current version of MHFramework, I intend to implement the input handlers to support polling as well as registering event listeners.

Graphics

Without a doubt, the graphics will be the most challenging part of this layer.  I will try to explain the problem.

In Java SE (and therefore in the current version of MHFramework), rendering to the screen is accomplished via the Graphics object.  The Graphics class interacts with Font, Paint, Color, and other classes to perform a variety of tasks, but Graphics and its Graphics2D subclass are at the heart of it all.

In Android, the equivalents are not absolute.  Rendering is accomplished via a Canvas, which also contains several other methods that resemble Java SE's Graphics methods.  However, the Android Paint class takes over some of these responsibilities, as well as the responsibilities of the Color and Font classes.  In essence, there is no way to do a straight one-to-one mapping between these classes.

So, to solve this problem, we will need to address the question of granularity.  Should we attempt to generalize the canvas/graphics object and the paint/color object?  Or should we opt for a much coarser grain and consolidate it into one large rendering class?  Would this lack of cohesion outweigh the overall simplicity and relative ease of use?  Since there is already such heavy coupling between the graphics-related classes, it is my opinion that we should consolidate these things into two separate classes -- one for Java SE and one for Android -- with a common interface to both.

This decision is far from finalized at this point.  I intend to prototype it and see how it goes.

Audio

The audio interface should be remarkably easy.  From what I can tell, the interface to the Android system is nearly identical to the one in the current version of MHFramework.  This should require little more than straightforward delegation to existing implementations.


TL;DR: For starters, we'll need to support input, graphics, and audio. Input and audio should be easy. Graphics could prove challenging.


Sunday, December 2, 2012

Considering an Architecture for the New Engine

In my last post, I identified the top priority quality attributes for my new game engine. In a nutshell, they are:
  1. Portability to allow testing of console and mobile games in a PC environment, plus the ability to offer games to a broader market. 
  2. Performance to utilize resources economically, allocating them to the game code as much as possible. 
  3. Extensibility to provide simple hooks and interfaces for connecting game code and other custom components without excessive coupling.
After doing some reviewing, pondering, and literally sleeping on it, I think I have a pretty solid idea.  Here I will attempt to describe it and how I arrived at it.

First, the top priority is portability, which implies to me that we must follow the old object-oriented design principle of separating the parts that vary (those relating to the platforms) from the parts that stay the same (the core of the engine).  The part that varies here also represents a dependency of sorts because it provides the link between the application code and the operating system.  So if we step back and look at this from a distance, we see that layers become visible -- the hardware supports the OS supports the platform layer supports the engine core supports the game code.  A layered architectural structure emerges on its own, very naturally.


A fortunate side effect of this layered architecture is that it produces a modular structure, which goes far to support the goal of extensibility.  If I were to refine this (which, of course, I will), the game engine itself would also be broken into layers, from lower-level interfaces with third-party libraries, all the way to up to higher-level services such as artificial intelligence support and custom UI components.  I will document these things in greater detail as the project progresses.

The only high priority attribute remaining is performance, which, although not expressly encouraged by the layered approach, it isn't necessarily hindered either.  Within the engine's layers, there will be countless decisions to be made that will affect performance.  The architectural structures used in various parts of MHFramework (particularly for shared data and object caching) are likely to survive into this engine as well, with an attempt at compromise between high performance and loose coupling.  Easier said than done, I know.

TL;DR:  A layered architectural structure will directly support at least two of the three driving qualities for my new engine.

Saturday, December 1, 2012

Debating Game Engine Quality Attributes

I love my MHFramework game engine.  It's like an old friend who has grown up with me through the years, rolling with the punches and becoming ever more resilient because of them.  I'm intimately familiar with its capabilities and its drawbacks, and can accommodate them like it's second nature.

I feel like Han Solo with his Millennium Falcon, where, in the face of outright criticism, he says, "She may not look like much, but she's got it where it counts, kid.  I've made a lot of special modifications myself."

However, recent events in the game industry as well as in my personal and professional life have given me reason to consider building a brand new game engine from the ground up.  The motivation for this new system is driven by two major influences:

  1. The strengths and weaknesses of MHFramework.
  2. The known challenges and opportunities of current and future projects and platforms.

At the moment, all I can do is speculate on the features and qualities that I want to create in the new engine.  After all, I want to avoid the mistakes I made in MHFramework, such as the lack of a comprehensive architecture, the lack of portability, and the lack of cohesion that is especially evident in some of the older modules.  Diving in head-first would simply be repeating the failures of the past.

So let's figure out which qualities will truly matter in this new system so that we can design a solution that will perform under the pressures that are currently storming their way down the pipe.  Let's run down the list and consider the priorities of each with regard to the high-level software architecture.

AttributePriorityRationale
FunctionalityMediumIn reality, functionality is priority number 1. Though it will not be a heavy influence on the architecture, it will obviously play a huge part in component design.
UsabilityLowAs the engine will be driven by a code library rather than a GUI, this attribute gets a low priority. However, the interfaces to classes will place a very high value on usability, and consistent documentation will receive focus throughout.
ReliabilityMediumAgain, reliability is an obvious desire, but not an influence on the architecture. Like functionality, it will be addressed at the component level.
PerformanceHighTypical of most game engines, the performance of the real-time player experience is crucial. Many decisions in the development of MHFramework did not prioritize performance, and instead favored usability and supportability. In the new engine, I would like to find better compromises between these equally valid aims.
SupportabilityHighMHFramework did a great job of allowing open extension of engine classes, and also left many decisions up to the programmer regarding which engine parts to use and which to ignore or replace. I want to maintain that same degree of freedom in the new engine. Also, portability will be a top concern because I want the engine to enable games for the PC in full-screen exclusive mode as well as in a window, games to be played in a web browser, games for Android smartphones, and, of course, games for the upcoming OUYA console.

So, by this reasoning, the highest initial priorities, in order, will be:

  1. Portability
  2. Performance
  3. Extensibility

TL;DR: I'm going to build a new game engine that emphasizes portability, performance, and extensibility.


Saturday, November 17, 2012

SpecTrek (Android Game)

As I was randomly browsing the web recently, I came across a really cool little augmented reality game called SpecTrek, developed for Android by Games4All.  SpecTrek is a ghost hunting game where the player must explore his/her real-world environment to find and capture virtual ghosts who are haunting the area.  This description sounded fun and interesting, so I downloaded the free, "lite" version onto my Samsung Infuse.  Today, fortune conspired to give me the time to play, a very promising place to play, and someone with whom to play.

The game uses many of the phone's features to impressive effect.  It uses the GPS to build the gameplay area in the player's actual, physical environment as well as to locate the player in the playing field.  It uses the compass to know which direction the player is facing, as well as provide an on-screen compass to aid in navigating the play area.  It uses the camera to provide an augmented reality view of the environment.  It uses the accelerometer to switch between the map mode (when the phone is held flat) and the ghost capture mode (when the phone is held upright).

When one begins a game in SpecTrek, the app gets a GPS fix to determine the player's location, which then becomes the center of the real-world play area.  A short game has a fifteen-minute time limit in which the player must find and catch all of the ghosts that spawned in the play area -- a circle with about a 410-foot radius.  In the few times that I played, the number of ghosts ranged from three to five.

I played the first game of the day by myself.  First I held the phone flat to get a look at the map.  It showed where the ghosts might be, so I immediately headed off toward the nearest one.  The first one was on private property, and it was outside of my capture range, so I had to write that one off.  The next nearest one was just south of my current position, but when I approached it, I got too close without capturing it and it ran away.  By this point, I only had about four minutes remaining and I hadn't captured one single ghost yet.  So I ran to the far opposite side of the play area where there were three ghosts hanging around.  I wasted a whole minute trying to catch the first one who always managed to evade my sights.  Two more were due north of me, so I ran that way and found them both hanging out together between a fence and a shed.  I captured them both, back to back.  Only 40 seconds remained in the game now, so I ran back to the one I had failed to capture just seconds before...and I caught it without a problem.  Time expired six seconds later and I had managed to catch three out of five ghosts, all within the last three minutes of the game.  What a thrill!

I enjoyed the game so much, I purchased the full version.  It's well worth the $2.49 price tag, no doubt.

Then my brother-in-law Kevin joined me and we sought out a good place to begin the game.  We estimated that the best place to start would be the place that would give us access to as much of the play area as possible, hoping to avoid the problem I faced with the unreachable ghost in the private property.  Even on the smallest setting, the play area was so large that it extended into areas we could not reach no matter where we centered it, so we just did the best we could to be strategic about it.  We played three games before the battery died on my phone, two of which we were able to win by catching all of the ghosts within the time limit.  I gained enough experience to level up after the second game, so I spent my skill points on increasing the capture range so that I could capture ghosts who were farther away in areas that I couldn't enter.  We played one final game to take advantage of this upgrade, and it worked very well.

The only problem I discovered with the game was a glitch with the map.  It would occasionally lose track of where we were and try to say that we had suddenly teleported a few hundred feet northeast.  I found a workaround that seemed to fix it each time it would happen though:  Go back to the info/summary screen, wait a few seconds, and then press Continue to go back into the game.  That seems to resync it correctly.

Ah, what a fun game!  It's disappointing that the winter months are coming and will make it difficult to play this game since it requires a lot of time outside.  I'll just eagerly await the return of spring and use this game as a great excuse to get out of the house and get some exercise from time to time.

TL;DR:  SpecTrek is a very fun augmented reality game that is well worth its low price.

Friday, November 16, 2012

Return of the...Me

I have decided that it's time to start blogging again. I must get over the profound sense of loss arising from my inexcusable failure to save my old Yahoo blog. I need to get past the sickening, gut-wrenching regret that I didn't act in time. I need to stop beating myself up over my easily avoidable lack of wisdom in choosing not to back it up.
Why am I so upset over losing a stupid blog? Mostly because of what it represented. It was not only a collection of my thoughts. It was also a detailed diary of the first few years with my wife. It recorded events with my beloved pets. It provided a creative outlet for lyrics and poetry. It was a place to jot down notes on my plans and projects. It was so many things that are now gone forever. I feel physically ill every time I think of it, especially since it could easily have been avoided if I hadn't been so overconfident in my ability to transfer it manually before the deadline.
But life goes on, and so does my need to continue all of those things I mentioned above.  Every time I think about blogging again, I remember how much I've lost and it stops me in my tracks. It's debilitating, but it's time to stop mourning and move on. I still have ideas to share and things to express, and that'll never happen as long as I let the failures of the past hold me back.

So consider this my formal declaration that I am returning to the world of blogging. This blog will become what my old one was: a place to spew forth whatever random thoughts dominate my mind at any particular point in time, and encourage me to organize them into some sort of semi-coherent order.
There's still no guarantee of frequency, but it is time to start moving forward again. If you're reading this, you are invited to join me on this journey at your leisure.
I shall return!