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.