Monday, October 8, 2012

Running Silent

I wanted to throw something up here so the blog didn't look like it had gone dead, but there's nothing really new to show for the work that's gone into the project recently.

An interesting part of programming is how much you can do for no visible difference.  My focus has recently been on improving the resource infrastructure of the code, specifically creating a generic resource package class that can hold serializable data for the engine to convert at run-time into the actual 3d assets for the game (models, props, all that fun stuff).  This also required a quick thrown-together packaging tool to be built.

Initially, (as I've mentioned using Assimp.NET before) I was loading from the COLLADA model format because it had a handy exporter from Blender and is known for playing nice between most graphics tools and pipelines.  Part of this is because it's designed to store as much information as possible about the 3d scene.  My engine only needs a handful of data types from the .dae file (mostly vertex information, a material string, and skeleton/animation keyframes).  That meant everything else that Assimp loaded from the file (and the resulting Scene object in memory during the load process) was superfluous wasted effort during runtime.  The process (while the game was running, mind you) went

  • Load COLLADA file from disk
  • Parse COLLADA file into Assimp's Scene object
  • Hand completed Scene object to content manager
  • Have content manager pick apart Scene object and convert data types into SharpDX-specific formats
  • Build new Mesh object (specific to my library) from the few pieces content manager pulled out of the Scene
  • Delete Scene and Importer objects
  • Return the Mesh
Deciding this was all better done offline, I moved all that functionality into a new Resource Packager tool.  This is one reason I love C#: you can throw together a Windows tool in an afternoon with WinForms.  Yes, I know WPF is the new, Win8-friendly answer, but since this is just for in-house work, I'm fine with drag-n'-drop winforms for now.

Now the tool does all the conversion (of multiple COLLADA files, as many as I want really) to in-memory Mesh objects, and then packs those objects into a tight, serializable format that only stores specifically what I need to re-create the object at runtime.  That data (in memory) is then written out to a proprietary resource pack file format (on disk).  This all means smaller resource files, fewer files to manage on disk(since the resource pack tracks everything internally, I just have to know which resource file holds which models), and faster loading of resources on the fly.

The new resource flow?
  • At level load-time, read list of required resource packs from level file
  • Pass list to resource manager, loads any not currently ready from disk and closes handles to those no longer needed
  • Call "ResourceManager.Load(modelX)" for resource named modelX at any point I need to create a mesh object (again, mostly at initial level load).
This lets me group assets thematically (i.e. "props for desert level" vs "props for snowy level") and future plans include adding other asset types to the packaging process (audio, textures, scripts, etc).

As a bonus, I tasked the Resource Manager with smart object loading: it tracks which meshes have been deserialized into memory, and if a requested object is already built, it just copies the existing object instead of building a brand new one.

The funny part, appropriate to the post title, is that my metric for completion is that there is no visible difference in the game with the new resource system.  It makes my code simpler and more data-driven, but if someone were to run the previous build alongside the new enhanced-resource-manager version, it just looks like I sat on my hands for two weeks.

Other than that, I've been making tweaks to the level editor, camera system, and laying some groundwork for AI and Physics.  Thinking I'll need some kind of marshaller between data the physics library can play with, and data the AI routines can use for Navigational-Mesh generation.

Oh, and I've been exploring character designs and more bug concepts to nail down the look of the heroes and their new unfriendly neighbors.  Getting close, I like what I'm homing in on, so I should have more of that available to show soon.

Man, these video games are a lot of work.  Who knew? :)

Sunday, September 16, 2012

In search of an enemy

Having run into a couple code hiccups in a row with some of my final missing pieces of graphics rendering (I'll get you sooner or later, skybox!) I took a little break from left-brain land to try and nail down the visual style of my "bugs".

The player is going to control a character on a future distant planet in a sort of techno-gold-rush after the discovery of some very useful elements.  Almost immediately (as the central conflict of gameplay will rely on it) player(s) will discover that certain properties of this element make it very attractive to the insect-like species that already lives on this new frontier, especially when put through the stressful mining process that converts it into portable material.

Short version: mining this stuff will bring bugs down on the player.  The more precious the resource, the stronger the draw on local bug swarms.

At any rate, I want the species to have some cohesive style elements that help sell the fact they're all from the same origin species and can be controlled by a singular hive "overmind" (lets just step in as many sci-fi tropes and starcraft references as we can, I haven't come up with fun IP-unique names for this stuff yet).

I also want them to be fun to hate.  Hence, bugs.  Barring collections of entomologists and the odd monk, I think almost everyone can agree bugs are better off squished.  At least when they're human-sized and packing ranged chemical weaponry.

Finally hit on something I'm happy with (yay for lunch breaks): this is the first pass at the standard "soldier" bug.  (The head in my logo is an older concept for the same critter).  More specialized variants will round out the swarms, but there needed to be a grunt that could serve as a mirror unit to players: someone standing behind alien cover on the other side of a battle line aiming alien weapons back at the human element.

This'll definitely require normals maps, I'm not fielding dozens of 250k-poly grunts...
I'll have to clean him up and draw the full front/side/detail orthographic view before I model 'im.  Drawing concept art for yourself is kind of odd: there's still a few rounds of "nah, I like this part, but the rest needs to be better" but all 'parties' are already working from the same singular vision.  Jury's out on whether or not that's a good thing.

Just remember: if it has 6 eyes, you should probably shoot it.

Friday, September 7, 2012

New and Improved Editor

I've banged my XNA-based level editor into shape with the new SharpDX-based graphics engine, and now have prop manipulation implemented!

click to enlarge
On the bottom there are two differently scaled copies of the same rock prop, and the (incredibly low-detail) rock bridge is another stand-in prop.  (It will still be in later, I just exported it from Blender as soon as it had a basic shape and texture coordinates.  I'm continuing to refiine it and create a proper texture for the mesh)  You can see the debug views of the deferred rendering targets across the top.  A rough cut of my ink-style outline shader is in use as well, though it could use some blur passes and tweaks to really be more what I was intending.

I've wanted to get this functionality in place ever since I first watched someone demoing the Hero Engine level editor a few years ago and realized how varied you can make a scene just by rotating and scaling a handful of props.

Someday soon I'll get the rest of my editor buttons in place :)

Tuesday, August 28, 2012

Forging ahead into DX11 : Lessons Learned

It's a good thing I'm not feverishly attached to any of the code I write, as I've probably scrapped entire sub-frameworks three times over in the process of building, then learning, then rebuilding my graphics and content pipeline with the SharpDX libraries.  I can definitely say XNA makes things neat and tidy for development, and I think I'll stick with it if there's anything in the near future I just want to hash together to prototype something.  At any rate, the good news is I've gotten back to where I was with XNA, only now it's built on a much cleaner framework with a newer underlying graphics API, and a snazzy deferred-rendering pipeline with a handful of associated flexible utility classes for multiple-render-target functionality.

The main intent of this post is to try and help out those people trying to move from XNA into a lower-level yet still managed graphics library.  What follows after the jump is some of the things I had to replace and rebuild once I pulled the "using Microsoft.XNA" statements from my code.  It's mostly a high-level look, I'll go into more depth (and more code) on specific issues down the line.

Monday, August 6, 2012

Conversion Updates

Talk about a learning experience!

So I've mentioned that I want to port the current code over to a different graphics framework, and had originally mentioned SlimDX as the targetted library.  After doing some research around the net, I discovered (as in most cases with APIs) I was chasing the tail of a "dying" resource.  SlimDX is still fully functional and perfectly useful, but apparently the authors (all three of them) are turning away to focus on alternate projects or generally move on with their lives.  The project has been a lot of work over many years, as you can tell from the revision number (above 2200 last I checked), and you can't honestly begrudge the guys for wanting to focus on other things by now.

That being the case, I did want to work with something that had some more active support and development, and turned to SharpDX.  From what little I gleaned, the author of SharpDX actually used to work with the SlimDX team, then yadda yadda differences of opinion etc etc.  The end result is they both stick very close to the native DirectX libraries, with SharpDX continuing to be grown as new releases of DirectX come out.  Apparently he's even working on a SharpDX version of the new toolkit that will bring things like built-in Font and Sprite frameworks (something you currently have to home-brew in Direct3D11).  Color me excited :)

So with my API choice settled, I've been porting things over and building new framework elements where needed to replace things like XNA's content import pipeline and effect support system.  I've rebuilt my camera system and deferred rendering chain from the ground up to be cleaner, more organized, and legible, and with the new API paralleling the DirectX native libraries, I can use a host of references aimed at C++ development for solving any problems I run into.

This whole process has given me a much clearer view of the Direct3D11 rendering pipeline, and some of the fog of XNA's high-level interface has been cleared away to see what was being done with .fx files and techniques.

I've also brought in Assimp's .NET wrapper API, AssimpNET, for doing all my mesh loading.  Their scene objects and all-inclusive data parsing give me the best flexibility while not requiring me to write my own model parsers.

Once I get the game and level editor functioning at the same level they did originally, I'll post up some comparison code in case anyone else is wondering how you make the transition from XNA to a more future-friendly API.

Tuesday, July 24, 2012

Hooray for objects!

The level editor finally lets you place objects on the map!  (It's a hobby project, I have to settle for the little victories).  This actually provides for a lot of added value, because anything that's not the raw terrain mesh is an object (or "prop" as the engine refers to them), which means the code side of having everything from little rocks and trees to giant canyon-spanning rock bridges and piles of ammo boxes is now done!

Of course this also means I need to pick up the slack on the art side of the house and put together a collection of resources...

In other news, I'm paralleling work on the editor with an overhaul of the game engine to use SlimDX instead of XNA.  XNA is a great tool, and has let me make a lot of headway in short order, but I'm starting to get frustrated with the limitations of the "profile" concept (XNA projects let you either target a "reach" profile which limits all kinds of values and ranges in your code so that more low-end systems will be able to run it, or a "hi-def" profile which is pretty self explanatory).  Working much closer to DirectX with the SlimDX library will give me access to DirectX 10 and 11 features, and with the DirectX10 tools that down-level to DirectX9 feature sets, my game could be much more flexible in its contents while still being available on Windows XP machines with older hardware.

Right now I'm working in SlimDX's Direct3D10 libraries, as 11 really changed the game in terms of available classes and structs (I'm a sucker for meshes, I'd rather not have to roll my own everything just yet).  Some stuff ports from XNA very smoothly, for instance I can keep all my shaders exactly as they are, but the lack of a fancy Content Pipeline and the need to overhaul my deferred rendering chain are certainly slowing progress in that department.

Thankfully all my graphics code is pretty separated from the rest of the engine (as things mostly refer to camera objects if they need to be drawn) so once I get the main graphics classes converted I should be all set to continue all work in a SlimDX environment.  In the meantime, I'm building all new features (everything else I update about) in the same XNA framework until the graphics conversion is complete.

Monday, July 2, 2012

Editor moving along

Just a quick progress update with screenshot.  I have the 4-texture painting/blending working, a modifiable brush and opacity that raises/lowers/smooths/planes/balances terrain, a more cohesive button theme (for the buttons that have icons so far...) and an undo stack.  Major hurdles left include prop and trigger additions, and it's irking me that I can't see the brush radius by default, so I need to add a brush-perimeter indicator.  Otherwise it's close to "done enough" for more game development!

(Click to enlarge)

I do need to add: the textures seen here are placeholder and belong to their respective artists (thanks google images).  Now that I have them painting properly I can work on my own assets to replace them.