'Game Development'

Let’s Back This Up A Bit…

Ok, so I didn’t really follow through with the tutorial regarding how to create a Zen Plugin — I’ve actually been in the throes of refactoring the terrain related interfaces for the AIR MMO, so anything I would have posted in regards to that would have changed.

That being said, I’m working on some pretty awesome stuff at the moment.  Yes, it still has to do with terrain rendering (at least part of it, anyways) :P .

As some who might be reading this may already know, I’ve been working on a terrain rendering component to support dynamic, efficient, and realistic rendering of floating islands (also referred to as Eyots in the vocabulary we’ve been using).  I’ve had to return to the drawing board at least three times in this particular endeavor — needless to say, getting it right hasn’t been particularly easy.

However, I think the latest approach is going to pay dividends :) .  I’ve been using Sinbad’s terrain implementation in Ogre3D as a reference for developing a custom Ogre terrain component, and Britonia’s post regarding planet rendering as a reference for how to handle cube-to-sphere mapping for an eyot terrain instance.  The current in-progress implementation will support dynamic paging of eyots into and out of memory as well as dynamic paging of regions of said eyots in and out of memory.  Pair that with dynamic LOD rendering of the eyot surface using a combination of a cube-to-sphere mapping technique and use of a quad-tree implementation, and it will be able to support fairly large eyots – I haven’t really sat down and crunched any numbers here, but we’re talking tens of miles here if your unit of measure is a foot…

The other thing I’m working on is an inferred lighting rendering pipeline implementation (a good reference on this can be found here).  I’m going to be implementing it with a custom geometric buffer configuration that will support diffuse maps, normal maps (and maybe parallax – I haven’t decided yet), specular power and intensity maps, dynamic light maps, and emission maps.  It should be able to support a large number of dynamic lights, handle alpha textures, and support multi-sample anti-aliasing while still maintaining a healthy frame rate.  The initial implementation of this will be part of the material and shader generation code that will be part of the terrain component mentioned above with the intent of later moving it to a more general implementation for all rendered assets.

I’m not going to lie – it’s a lot of work for just one person. But when it’s done, it’ll be visually stunning :)

Good thing for us our lead game designer is equally committed and as much of a perfectionist (if not moreso) as I :)

Zen Plugins

Ok, so far I haven’t really posted anything of a technical nature, so I guess I better jump on that grenade.  For now, I’m going to start with something relatively simple — a stubbed in plugin for ZenEngine.  Over the next several posts,I’m going to illustrate how to create the skeleton code for a terrain plugin using the ZenCore and ZenEngine framework.

I will warn you beforehand — this is not novice stuff, and I’m probably going to assume that you both know a little about C++ and the inner workings of Zen.  That being said, if you don’t know much about the Zen framework but manage to hold on throughout my ramblings, you might walk away a little bit wiser.

Generally speaking, source code for a Zen compatible plugin consists of the following files/file structure:

ZGenericPlugin – Plugin top level folder.

CMakeLists.template – CMake template file used to generate the CMakeLists.txt file used to generate Visual Studio/Eclipse/Make compatible builds

Configuration.hpp – Configuration header for specifying things like class and method import/export properties when dealing with dynamically linked libraries (DLLs).

plugin.xml – Plugin metadata describing the extension point and plugin type for this plugin.

ZGenericModule.hpp – Header declaring the getModule() method used to load this plugin.

src – Plugin source implementation folder.

ZGenericPlugin.hpp – Header containing a concrete class declaration of the Zen::Core::Plugins::I_Plugin interface for ZGenericPlugin

ZGenericPlugin.cpp – Source file containing a concrete class implementation of the Zen::Core::Plugins::I_Plugin interface for ZGenericPlugin

ZGenericModule.cpp – Source file containing a concrete class declaration and implementation of the Zen::Core::Plugins::I_Module interface for ZGenericPlugin as well as an implementation of the getModule() method declared in ZGenericModule.hpp

ZGenericServiceFactory.hpp – Header file containing a concrete class declaration of the service factory interface specific to the extension point to which ZGenericService is bound.

ZGenericServiceFactory.cpp – Source file containing a concrete class implementation of the service factory interface specific to the extension point to which ZGenericService is bound.

ZGenericService.hpp – Header file containing a concrete class declaration of the service interface specific to the extension point to which ZGenericService is bound.

ZGenericService.cpp – Source file containing a concrete class implementation of the service interface specific to the extension point to which ZGenericService is bound.

Other Files – Any additional class headers and source necessary to support the functionality of ZGenericService and implementation of additional interfaces specific to the extension point to which ZGenericService is bound.

Now, you may have noticed that I mentioned extension points multiple times in that little outline. The extension point dictates what kind of plugin this is – since we’re going to be developing a terrain plugin, we will be binding this plugin to the Zen::Engine::World::Terrain extension point.  This extension point exposes the following interfaces that should have concrete implementations in said terrain plugin:

I_TerrainServiceFactory – Interface for factory patterns used to instantiate I_TerrainService instances.

I_TerrainService – Root interface for the terrain API exposed by a plugin bound to the Zen::Engine::World::Terrain extension point.

I_Terrain – Interface for a terrain instance created via the API exposed by I_TerrainService.

In the next post, we will lay out our initial plugin directory structure and stub out concrete implementations of these interfaces.  I’ll try to keep the next post a little less dry than this one :) .

Time For Another Blog Post…

So yes, it’s been a while since I last posted — what can I say; I’ve been busy!!!

Between parenting, working my day job, and doing what I can in the hours in-between, finding time to post hasn’t exactly had high rankings on my priorities leaderboard.  Regardless, it was bound to happen eventually…

So what’s happened in the interim:

More concept art from the AIR dev team has been released.

An internal alpha release of the game client has been released to the AIR dev team for importing and testing of art assets.

The new AIR website is nearing completion and will soon be released.

We’re officially taking on two concept art interns from the Savannah College of Art and Design (SCAD) this summer.

Chris Dodson and the rest of the design team has fleshed out more of the AIR crafting system details.

    I’m sure I’m leaving something out there…  In any case, enjoy the following concept art from AIR — sorry for the wait (and resulting backlog).

    Coming Up for AIR…

    For the last few days, I’ve been elbow deep in code during any reasonable chunk of free time, trying to get the Account services implemented for the Zen::Community services.  I’ve learned a few things while working on this particular service…

    • Code generators are awesome.  We have some custom code generation scripts for generating a data model from a database schema and for generating network message classes for service protocols.  Needless to say, I’ve saved countless hours in implementation of the literally hundreds to thousands of lines of code that these code generators have taken care of for me…  (Thanks, SgtFlame, for making my life that much easier :) )
    • Nothing is ever as easy as it seems.  When I started laying out the initial design for the Account services, I thought, “Hey, this is going to be so straightforward and easy!”  Straightforward, it was, and still is — easy, however, was a bit of an understatement…  Just because a design is easy to understand doesn’t mean it’s easy to sit for hours and implement the same mundane design pattern in code over and over and over and over and – well, I think you get my point…  Needless to say, it’s taking a little bit more time and effort than I originally estimated :P
    • Which brings us right back to the code generators I mentioned — once I get these Account services done, SgtFlame and I are most probably going to use them as a reference for the design and implementation of more meta-data driven code generation scripts.

    Essentially, what this boils down to is code generators and SgtFlame are both awesome ;)

    In other news, the AIR art team has released another piece of concept art to the public

    New AIR Logo

    Here’s a low rez teaser of the new AIR logo.

    Enjoy ;)

    Mail Server Migration

    For those of you on the AIR development team, we’ll be migrating to a new server for our mail and mailing list services.  Downtime is expected for this Saturday, 2/20/2010.  Get with me or Jason in IRC about any questions or concerns you might have about this.

    Sometimes You Just Need to Rip the Bandage Off Quickly…

    So you’ve been developing a piece of software for some time, and you or your teammates committed to using a specific API or engine earlier in your development timeline. A few thousand man-hours into the project, you discover that instead of helping accelerate your development process, this API or engine is actually getting in your way!!! What do you do?

    Some would just suffer through it — they figure that they’ve already invested a great deal of sweat equity in using the equivalent of a boat anchor around one’s neck that it would be a waste of time to pick up something new.  Additionally, it is usually the case that these same people are also reluctant to admit that their decision to go with a particular API or engine was indeed a poor one.

    Instead, just bite the bullet and ditch the boat anchor!  You’ll find that you’ll save yourself a lot in the way of headache and heartache if you just remove the obstacle altogether — sure, it might take you longer to do things the right way (whatever that ends up being), but you’ll save yourself time and effort in the long run in regards to maintenance and upkeep of your source code.

    Depth and Breadth

    Unofficially, AIR has been in development for a little over two years.  During that time, everything about the game — backstory, design, concepts, etc. — has been worked and reworked at least two times over if not more.  And in doing so, we’ve ended up with a rich and diverse environment within which (we hope) players will immerse themselves time and again.  Storyline development, concept art, game design, and other disciplines — disciplines that have little to nothing to do with technology — are the heart and soul of games like AIR, and we are making great strides to ensure that playing AIR will be a unique and rewarding experience.

    Granted, we are still working out a great deal in the way of technological hurdles as well, and will probably be doing so for some time now.  But tech doesn’t make the game — in all honesty, tech should only serve to support the game.  What makes a great game is content — be it storyline, side quests, gameplay, etc.  You can have a visually stunning tech demo blow people away, and still have a less than desirable game in the eyes of your target demographic…

    Case in point — take a look at some of the re-releases of the Final Fantasy series of games by Square-EnixFinal Fantasy VI, originally released in the US as Final Fantasy III on the Super Nintendo, was released on the Game Boy Advance back in 2006.  By today’s standards, FFVI doesn’t come anywhere close to pushing technological boundaries today, nor did it do so back in the hey-day of the Super Nintendo.  However, the rich content of the game keeps myself and others coming back time and time again to rediscover Terra’s Esper heritage and make a final stand against the sinister Kefka.  In short, the game world and story of FFVI turned a relatively modest game experience into a classic.

    That’s not to say that using the bleeding edge of technology may not be necessary — one just needs to make sure that it supports the game content and not the other way around…