Tuesday, November 27, 2012

Once more unto the chopping block

So some great news for me, the SharpDX Toolkit was released at the end of October, providing a clean high-level interface with DirectX11 similar to the XNA model, only not reliant on XNA support.  I'm especially excited because it allows me to fall back on what is most assuredly a better-structured library than what I cobbled together while learning how to program a DirectX pipeline.

While this doesn't break my current code, it does give me a great foundation to make one final sweeping overhaul to the main engine/library to focus on a data-centric model.  My existing code wraps a lot of data objects with personality and functions that really should just belong to an authoritative "Renderer" object, so I've started moving towards a design that simplifies my camera classes, effect libraries, and other infrastructure entities and makes them components of a primary Renderer.  That renderer will work with a single source of world data and state data to render the entire scene (from world geometry to actors, UI, etc) appropriately for the gamestate.

The other impetus for cleaning up and officializing (is that a word?) my data components is interoperability with other sub-systems.  My physics and AI managers are going to need to access subsets of the world data to do things like calculate navigation meshes and collision hulls based on a dynamic worldspace, as the players will be creating (and destroying) walls, buildings, nests, resources, and so on.  Moving data management and world change responses into a singular "world manager" that can handle manipulation and access to a geometry and materials heirarchy will keep that organized and clean behind some simple interface calls.

So aside from the (I promised myself, final) design overhaul, I've been off in right-brain land honing my art chops before I start cranking out assets I actually want to use in the game.  I'm pleased with the practice and progress, and should have some character sheets of the main characters (in their designer-blessed officialdome) available shortly, with environment shots to follow.  Everybody loves some good concept art.

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.

Monday, June 11, 2012

Level Editors and Splat Maps!

Got busy working on a level editor for Hazard Pay, as I was already reaching a point where I wanted to build up a test level for running around, and wanted to get some of the tool development out of the way.  I want to make this a user-friendly, intuitive editor as I'll likely bundle it with the game once it's all finished so people can easily (and immediately) start making custom maps for the game.  Us creative types just love mucking with other people's tools (see all BethSoft construction kits, for example).

This is additionally forcing me to define a level file, and solidify some of the framework for file loading, which is all good stuff.

I've also gotten to play with texture splatting in HLSL, which basically involves taking a base texture (the splat map) and converting, at each pixel, its RGBA values into alpha-blending values for up to 4 individual textures.  This allows for nice things like seamlessly blending from sand/rocks into grass, or whatever alien surfaces you might encounter ;)

WPF makes GUI editing incredibly quick (yay C#), even if I have had to do a little hacking to get button images to show up.  Apparently the way I put together the project (making the Windows Form a member of an XNA project, and not the other way around) screws up the ability for the Form to recognize resources it needs, even if they're a part of the project and the form has an associated .resx file.  Luckily, you can just jump into the designer code and manually point to image resources, so I end up with little gems like this in the form constructor:

//Begin button image hacks
this.raiseTerrainButton.Image = Image.FromFile(contentPath + "Icons\\RaiseTerrainIcon.png");
this.lowerTerrainButton.Image = Image.FromFile(contentPath + "Icons\\LowerTerrainIcon.png");
//End button image hacks

As far as splatting, once you've confirmed that your terrain textures are indeed loading (that was 2 hours of pointless debugging...) the following pixel shader function makes splatting a snap.  Just make sure you load up one Texture2D for the "splat map" (i.e. the texture whose color channels will dictate visibility of your palette textures) and up to 4 more for your terrain textures (in the example above, I'd loaded up a cartoony sand texture, a plain green texture, and a plain light-blue texture.)

float4 QuadPixelShader(MTVertexShaderOutput input) : COLOR0
{
 
 float4 splat = tex2D(TextureSampler0, input.BaseTextureCoords);

 float3 pixColor = float3(0,0,0);

 pixColor += tex2D(TexSampler1, input.TileTextureCoords).rgb * splat.r;
 pixColor += tex2D(TexSampler2, input.TileTextureCoords).rgb * splat.g;
 pixColor += tex2D(TexSampler3, input.TileTextureCoords).rgb * splat.b;
 //pixColor += tex2D(TexSampler4, input.TileTextureCoords).rgb * splat.a;

 pixColor.rgb *= saturate(input.LightingFactor) + xAmbient;
 float4 finalColor = float4(pixColor, 1);

 return finalColor;
}
(the 4th alpha channel was ignored for now, as I discovered my test splat map was set to full alpha, meaning I'd paint over everything with the 4th texture until I use a file that has varied alpha.  Paint order matters!  Also, that saturate line is for the normal-calculated shadows, you can ignore that if you're just looking for a simple splatting technique.  I defined a custome vertex structure that takes two texture coordinates, because I wanted my splat map to scale to the size of the terrain mesh, but still tile the paintable textures for better detail.  That's why there's two texcoord types in the sampler calls.)

The fun part of all this is that with those shaders and structures in place, once I get the brush tool working, I can re-paint a terrain mesh in real-time by having it alter the channels of the underlying splat map, then just roll that up with the level file during the save process.  Whee!

Cheers,
-Brandon

Sunday, May 13, 2012

Blog, interrupted

Went quiet for a month or so to finish up my CS degree, just did the whole cap/gown walk this morning, expect this to pick back up now that finals are out of the way ... for good :)

Thursday, April 19, 2012

Smoo~th...

Tweaked the mesh-building algorithms somewhat to get smoothing working properly, much more pleased with the outcome.  It'll look much better with the multi-texture gradients applied, once I get that added in.

I also threw together a character model stand-in to get a sense of scale, you might be able to see it in the first screenshot, but let's zoom in...

Ah, there we are, guess that's a pretty large mountain with the current y-scale.  Consider this a proto-concept-art shot for one of the two main character models...like a w.i.p. of a w.i.p... there's some Inception joke there, I'm sure.

...and really, what good is a stand-in if it's not made of cardboard.

Sunday, April 15, 2012

Heightmaps!

Just got heightmaps working, thought I'd post up the first-ever in-development screenshot of Hazard Pay:
And yes, that IS a photoshop brush artifact in the source bitmap.  That's how you know it's genuinely unfinished.  Totally on purpose.  Yup.

Saturday, April 14, 2012

Cameras, shaders, and input oh my?

Lots of work being done on the rendering portion of the game's engine (which is really just an engine insomuch as it sits in a separate project that is referenced by my actual game project, so it's content-unaware).  Almost done coding up the camera so that it swaps in before- and after-effects dynamically.  The framework for deferred rendering is already in place, which means lots of fun shader programming down the line.

I dove in to the graphics pretty early as the sooner I could get visual feedback, the more enjoyable the rest of the coding could be, and the better momentum I could keep on the project.

Elsewise the engine just has stubbed-out managers for other systems (AI, physics, world resource content) and an input handler so I could use controls to roam around the gamespace.

Currently working on: implementing a heightmap for level terrain with 4-texture blending.  Once I get that done, I'll be happy to start throwing in screenshots, but right now the entire project just renders a  spaceship from an open-source shader demo.

Monday, April 9, 2012

'ello world

Thought I should jot this down somewhere, my first post seems a good enough place.

Hazard Pay started life in March of 2012, with the vision of providing a fun first/third person combat game with base-building and resource-gathering mechanics thrown in amongst hostile alien bugs, pve/pvp multiplayer matches, and a single-player (or co-op) storyline campaign.

Inspirations reach as far back as Dune II and Battlezone, through Giants: Citizen Kabuto, Starship Troopers, Borderlands, and Natural Selection.

This blog will be a place to track development and for me to store thoughts, images, and other errata.

I'm Brandon, the designer, programmer, concept artist, modeler, and animator for Hazard Pay. I work on this in my spare time, when I'm not busy completing my CS degree or working as a SysAdmin. I look forward to sharing more with you as development continues.