Showing posts with label graphics. Show all posts
Showing posts with label graphics. Show all posts

Wednesday, May 5, 2010

Bad Demo, Good Demo

So, here's the final update about Space Combat Sim as a school project. I'll follow up with a postmortem and a bit about what I'm doing in the future.

Bad Demo
The first presentation was to faculty and some industry representatives (fortunately their thing seemed to be anything but games.) It was originally going to be in a classroom setting but moved to the lounge in the student life center due to the number of people attending. The lounge, which happened to have one, maybe two, network ports. Both which were in use by other equipment... sigh. Without being able to play with someone all I could do was crash into scenery. Not much of a demo.

I was able to re-show the project in a lab, with a proper network, but the damage was done. My kingdom for Fraps... and the time (and people) to use it effectively. The fact I didn't have a fallback in case of network failure was a pretty major oversight on my part. Still that last minute venue change was really frustrating.

The most frustrating issue though was the fact the most vocal representative was most interested in how a project was supposed to make money. The fact he seemed more impressed about a group wearing suits than their actual project (which was quite slick) was particularly rankling. Why in the fuck are superficial details such as what the presenter is wearing even considered relevant? Caring more about clothing than the product demonstrated is not something to be proud of!

The impression he left me is that I could have run a pre-rendered video (not a recording of the game) and made up some bullshit about online gaming being worth billions and not been called on the fact I didn't even present a product. That would have saved a couple months of effort... At least the other members of the panel were willing to ask some technical questions during all the presentations.

Good Demo
The second demonstration was at the technology program showcase for the college. This was a 3 hour affair where a large number of people in the various technology programs at the school got to show off their projects. This time a lot more time was given to setup, last time there was a token effort in setting up a router which didn't work at all when used for wired networking. The project was set up on two PCs and running with proper Live accounts. There was some pain as some old bugs managed to magically un-fix themselves, and I didn't actually have the passwords for the Live accounts that were set up for the demo, but that got worked out early on.

The big lifesaver was having Heather (from Slime Cat Blog) and her sister to demo playing the game while I could talk about what it was and how it worked. They would fly around, shoot at each other, be silly, laugh and generally have fun. This attracted a lot of attention from the various people attending the showcase. It also nicely showed what the project was without me having to go into crazy amounts of detail describing how it worked. I'm glad they were there because a lot of the people coming to see the project weren't gamers.

By the way, if you're wondering how those photo****d textures turned out; here's a rendering of the three fighter types.


Not great but still decent for about 2-3 hours per ship I think.

Wednesday, April 28, 2010

Imporing blender models to XNA as FBX

This post was meant for release on April 28th. I've been very busy in May and hadn't had much chance to update until now. Sorry.


For Space Combat Sim I've been making game models using Blender. It's powerful, it's free and it's got an active development community churning out new versions regularly. Check it out.


Like most modelling programs Blender uses its own file format for model data. XNA projects can't read these files. You normally can only add .X and .FBX files to games using XNA (though there are ways of adding your own model file importers via content pipeline extensions.) Fortunately Blender provides exporters for both X and FBX. I chose FBX due to the readability of the format and the fact the exporter worked more consistently for me.


Exporting from Blender to XNA created two major issues for me. One was ensuring the right material shaders were used. That was handled by writing a simple custom content processor. I simply named materials using "shader-name" which worked nicely. The second issue was more annoying. Blender uses a different co-ordinate system from XNA.

Huh? All modelling programs express positions using three numbers representing the object's position on three axes called X, Y and Z. Each axis represents one direction an object can move. In XNA, the X axis goes left to right, the Y axis goes from upward and the Z axis goes out from the screen (backward in the game.) In Blender the Z axis goes upward and the Y axis goes into the screen.

The result is that if I export a model and use it in XNA as is, it faces downward. Obviously that's a problem. Fortunately XNA provides a nice simple solution.


Just rotate it!

As you can see here the content processor lets you specify a rotation to be applied to the model before it's used by the game. This takes care of things nicely.

To finish, here's a list of things to watch out for.

  • Scale. If you don't make your models size consistent with each other you'll need to deal with this in the content processor.
  • Shaders. By default the model processor in XNA will assign the model a basic shader to render it. Not much good for fancy lighting effects and such.
  • Orientation. I tended to model my ships facing along the negative Y axis keeping rotation simple. If your models aren't facing straight along an axis importing can be more painful

Wednesday, April 21, 2010

More Spit and Polish

The project demo is in just a few days now. So I'm going crazy with minor bug fixes and polishing to ensure the demo goes well. For example:


  • The game join menu doesn't crash when no games are available

  • The game join menu will poll for new games if none are available

  • Beam weapons now do damage when swept through other ships

  • All incomplete scenarios are have been disabled

  • Fighters have photo****ed textures instead of default test patterns

  • Minor damge model bugs fixed

  • Thrusters flicker slowly enough to be noticable

  • Sound effects fade correctly



Regarding the photo****: One thing I really wanted to do in this game was give the fighters a nice metallic look. Metal is shiny! But, if I add shininess to the game it gets choppy. Ugh. But I might have a solution. Rust! Patina! etc.

I want to avoid making the game a rusty-brown shitefest so I'm hoping to go for more of a tarnished silver/brass/bronze/copper look. If, later, I manage to get some decent shininess at decent speed I'll bring back the metal look I wanted originally.

Saturday, April 17, 2010

Spit and Polish

Not much to say about the last couple weeks of work. I've added some new visual effects to Space Combat Sim and completed the three different fighter types. At this point the game is somewhat demonstratable but still kinda unstable and needing significant testing to improve its balance. Here's a screenshot of the new effect I added to the game.



I've been making a lot of small tweaks to the game of late. My primary objective is to be ready for the project presentation which is coming alarmingly soon. After that I need to have an open demo at the school's Tech@Work event. The most noticable changes to the game are the addition of a semi-working server selection screen, and a lobby screen. These aren't all that interesting to talk about but they produced a spectacular number of bugs during development.

The other feature in the game is the menu background. Very minor when compared with stuff I talked about earlier but it has an amazing effect on how complete the game feels. All I did was randomly spawn objects (that look exactly the same as the ships but without all of the movement code) and have them move toward and past the camera.



Much better than plain old CornflowerBlue eh?

Saturday, March 20, 2010

Slightly late. Slightly different.

So I show up to school on Friday, slightly bleary from a late night, ready to get cracking on the testing the game and... pretty much nobody shows up. In fact, those who did show up were far too busy to help out with testing. The screenshots I promised on Thursday were supposed to be from some multiplayer testing but that didn't work out.

Today I added point lights to the game. These are nice for lights which come from a location and affect a specific, limited area. Great for more dramatic explosions, shooting and so on. Here's a pic


Lighting in Space Combat Sim is done using some fairly simple math. One topic covered in high-school geometry was the dot product. The dot product is a scalar product of two vectors. One property of a dot product is that, when it's produced from two unit vectors, its value is equal to the cosine of the angle between the vectors.

Why is that useful? Try shining a flashlight on a marble, or ball bearing, or basketball (anything round will do.) Notice that the brightest parts are those that face the light. As the surface of the ball faces away from the light it darkens. If you remember that old high-school math cosine is one for an angle of zero and zero for an angle of ninety degrees.

Cool. But this still doesn't say how light or dark a surface is... We need one more piece of data. The surface normal. This is a unit vector points straight off of the surface being lit. Let's express the direction of some infinitely far away light source with another vector. Remember what I said in the previous paragraph? The dot product of the two vectors is one if the surface is facing the light perfectly and zero if it isn't facing the light at all. Cool, eh?

This is the shader code for a directional light. It's a nice stand-in for some sunlight. Notice there's a little bit of extra work here so that it can render eight lights at a time.


float4 outputColor = float4(0, 0, 0, 0);
for(int i = 0; i < GlobalLightCount; i++)
{
float LightFactor = dot( GlobalLights[i].Vector, input.WorldNormal );
float4 color = GlobalLights[i].Color * LightFactor;
outputColor += color;
}
outputColor.a = 1;
return saturate( outputColor ) * tex2D( DiffuseSampler, input.TextureCoord );


Now to extend this to point lights.

Point lights are a little different in that they have a definate location and a limited range. Both of these are fairly easy to deal with. Instead of specifying the direction of the light explicitly we calculate it by finding a unit vector that points from the light source to the object being lit. Cake.

The range limitation can also be made quite simple if we don't care about being 100% realistic.
Get distance between the light and the object being lit.
Divide that distance by the radius of the light.
Clamp the value to a range between zero and one
Subtract the value from one

This gives an additional value that we use to adjust the light's intensity based on distance. Here's the resulting HLSL shader code
float3 lightVector = GlobalLights[7].Vector - input.WorldPosition;
float lightDist = length( GlobalLights[7].Vector - input.WorldPosition );
float3 directionToLight = lightVector / lightDist;

// falloff light intensity linearly between alpha*radius and radius
float baseIntensity = 1 - saturate( lightDist / GlobalLights[0].Radius );
float diffuseIntensity = saturate( dot( directionToLight, input.WorldNormal ) );
outputColor += GlobalLights[7].Color * baseIntensity * diffuseIntensity;

outputColor.a = 1;
return saturate( outputColor ) * tex2D( DiffuseSampler, input.TextureCoord );



Saturday, February 20, 2010

Particles - Part Deux - The Sequel

The Movie - The Game - The... I'll stop now.

It's been another long hiatus since my last entry where I discussed a bunch of semi-boring crap about how stuff gets loaded in Space Combat Sim. Last week (that is the week ending on the 13th) I worked out the protocol for sending the initial game state from one player to another. That part is running somewhat nicely though I've got a bunch of other broken crap to fix before I can really give the details of what I'm doing.

This week, as you may guess, I'm going to talk about particle effects! Yay! Celebration!!! Peanut butter!

Ahem. Last part I discussed some basic theory on particle effects and had a pretty screenshot from an old project. Now I was hoping to talk about a clever method I had devised for making really versatile effects with relatively little shader code and some HLSL snippets. The idea was to store positional, colour and scaling data in the form of textures. Unfortunately this method turned out to be less than workable.

The idea originated when I was mulling over using cubics, or higher order functions to define the movement and other functions for particles. I figured this would result in a great deal of operations since the function would have to be completely integrated every time a particle gets rendered. At some point I began thinking about such functions in relation to producing complex colour gradients that the particles would run through as they did their thing. I got the idea that if I used a texture I could get a great deal of versatility. By using one texture co-ordinate to represent time and using a random value for the second I could have a particle effect with tens or hundreds of subtly different colour gradients with the hardware doing all of the hard interpolation work practically for free.

After a little more thought I figured this could be applied to particle positioning. Much in the way a normal map texture's colours represent vectors instead of actual colours I could have a texture whose colours represent a position in space. Depending on implementation this might add expense in the form of providing a normal, tangent and binormal to individual points sprites. Lots of floats but makes for very simple math in aiming a particle effect in a particular direction.

So, where did this go wrong? A few places. The first, and biggest, was that doing texture lookups in the vertex shader (which is where effects are applied to points sent to the graphics hardware) is apparently unsupported. If anyone knows a way of doing texture lookups in the vertex shader PLEASE TELL ME. This wasn't enough to prevent me from using the texture to provide fancy colour gradients however. Instead of looking up the colour in the vertex shader I'd simply pass the co-ordinates (time, and a random value) on to the pixel shader. So, it's not a complete loss.

I have yet to implement the gradient texture due to some stupidity on my part (I used a texture co-ordinate at first which the hardware happily interpolated for me utterly destroying my lookup values.) I can probably salvage it by passing the lookup in a colour semantic since those aren't interpolated. For now I am lerping between a randomly selected starting and ending colour.

What I have now is basically a stripped down version of Microsoft's Particle3D sample which I'm mutating into a setup that meets my needs. I'll leave you with a screenshot of my particle effect editor tool to finish.

Saturday, January 9, 2010

Particle Systems - Part 1

The Basics

One of the most fundamental visual effects in games is the particle system. At their simplest a particle system is a collection of objects which can each be described with a single vector quantity. Their position.

Even these incredibly simple particles can be moderately versatile producing effects such as clouds, fog, plants and so on. Where particles really shine though is when they're allowed to change appearance over time. The simplest way of doing this is adding one more vector quantity to each particle's description, the particle's velocity. Once each frame we add the particle's velocity to its posision then draw it. This allows particles to simulate simple explosions, fires, smoke, bullets, sparks and so on. As well as clouds, fog and so on...

How? Just change the values that are assigned to position and velocity when the particles are created.

Photobucket

Several simple particle systems. From a previous game project of mine

In this example the blue bullets all launch from the same position but are assigned velocities that cause them to spray outward. The explosions are similar but the velocities point in all directions rather than just to the right. The smoke in the middle appars to drift behind the flame by being created slightly later and given a slower speed. This particular example has a few other variables for particles, namely colour and scale. This saves on art production since a the same clouds can be used for both smoke and fireballs.

For Space Combat Sim

Relatively modern 3D hardware supports drawing particles quickly via what is known as point sprites. Instead of drawing a particle using a billboard, which requires four vertices, each particle only requires one vertex. This is great since we can pump out more particles with less data going between main memory and video memory. However this only gets us as far as drawing the very simple particles I mentioned in the beginning. What's worse is as we add variables to particles we increase the amount of data that needs to be sent to the graphics hardware quite rapidly. This gets even worse when varying a particle's properties over time... at least if we do it all on the CPU.

Besides the CPU computers and game consoles also come with another extremely powerful processor capable of chugging through obscene numbers of operations rapidly, the GPU, on the video hardware. This requires some rethinking of how we do some operations like repositioning particles since programming on a GPU is quite different from a general purpose CPU. The GPU is amazingly fast at doing floating point math and vector operations BUT it adds the caveat that changing input data (i.e. changing the vertices that have been passed from the CPU) isn't feasible. I won't go into a huge explanation why but this will help. The gist of it is that vertices are processed in something like a water pipe. Data can only flow in one direction. You can change it as it flows from one process to another but you can't reverse the flow. (there are ways around this but they're painful and I'm not going to go into them)

So we can't apply velocity to a particle by simply adding to its position repeatedly. What can we do? If you remember your kinematic equations an object's position can be expressed in relation to time with the equasion Pt = P0+V*t

Getting the initial position (P0) of a particle to the GPU is easy since that's simply the vertex position for the point sprite. Getting the time and velocity to the GPU are fairly simple but generally require a bit more thought since this is where the particle systems can be made extremely fast and flexible at the same time. I'll leave that for next time however since this entry is already getting rather long.

Sunday, November 15, 2009

Neat effect

I've been trolling around for information on how I could make a better looking beam weapon. One idea I had was to render them as volumes instead of flat lines. In my research I stumbled across Graphics Runner who has some neat tutorials posted on rendering volumetric effects on his blog. Check 'em out.

I'm likely to not use 3D textures like in these blogs so that I can save on resources. Instead I hope to derive the thickness of a particular section of a beam from the alpha value of that section of beam.

Stay tuned for followups, and Part 1 of my custom content processor series.

Saturday, November 14, 2009

Non-Trivial Custom ContentProcessor - Intro

The network component is finally done for this sprint. Yay! And I have a project that compiles for the X-Box 360. Yayy!!

This past week has been interesting so far since I found that my initial solution for batching objects for drawing was impractical when it came to the critical stage of actually doing the batching. So I had to tear it out and start over. The new solution is quite clean and has an added advantage of reducing the amount of data stored for render objects. Only one set of render data is stored no matter how many objects that use it exist. But this change started a cascade of extra changes which has led me to begin developing a custom content processor for XNA.

I'm working on generalizing the code needed to spawn in-game objects. My original method of loading in-game object data was to load a model and create one in-game object for each mesh that makes the model. The properties of the in-game objects were encoded in the names of the meshes. Initially this worked surprisingly well. The biggest advantage is that I didn't have to spend time on tool development and could focus on getting the game working.

There are, however, four problems.
  • No two objects defined in a model can have the same properties (due to mesh names having to be unique)
  • There's no easy way of creating a deep tree of attached objects (e.g. a capital ship with turrets)
  • Using names severely limits the number of properties that can be defines
  • Not all objects need to be models (e.g. beams and bullets)

My solution is to split off loading of graphics and defining in-game objects. Graphics are loaded and tossed into a pool for later use. Each graphical item has a unique name which can be used to reference it. Once the graphics are loaded the game then has to load information on how to create in-game objects using the graphics.

This is where the ContentProcessor comes in. My current plan is to create a custom XML document which defines a tree of in-game objects and their properties. Each file lists a set of in-game objects to be created. Each object is a single block in the XML file defining the following.

  • What appearance the object has (references a loaded bit of graphics)
  • What the object's type is
  • What the object's reference name is
  • What the object's parent's reference name is
  • A set of properties specific to the object's type

In order to keep the code for the game clean this XML data is to be loaded using a custom ContentProcessor. There are at least some resources out there on the internet including this (tutorial 21, PDF Alert!) and this which provide some nice sample code. I like the first since it distills the process down to its simplest form. Useful for learning, but it doesn't cover all the nuances I need for what I'm doing.

Stay tuned as I post more details on the content processor.

Thursday, October 15, 2009

Another Nasty Bites the Dust

As I mentioned in previous blog entries. This development cycle has been far more involved than the first. Mostly due to the fact that it involves a great deal of interdependent parts which all have to be developed at roughtly the same time. In this case I'm getting controls shared across multiple objects, object relationships and physics all working at once to support movement by simulating thrust.

I've figured out most of the math for the physics but it took several hours of effort to learn the basic math enough to even start. It was a few hours ago that I realized I'm starting to seriously diverge from what I want to be working on. What I'm trying to do is make the game look believable. I didn't originally intend to make the game accurate. *forehead slap* Out goes the physics, back to the drawing board.

My new method of simulating thrust is essentially a cheat. I'll just have thrusters appear to turn on and off in relation to the controls. Instead of simulating the behavior I'm simulating the appearance of the thrusters. This is far easier to build saving probably a day or more of work implementing it plus who know how long in getting it to be fun.

Wednesday, October 14, 2009

The Second Nastyish Problem

I now have the critical part of the batching portion working. Objects are decomposed to their smallest constituant parts which can then be rendered in groups. The actual grouping is still to be done but that's relatively straigtforward. I want to be able to measure how slow/fast I'm making my game's graphics before diving in to some hardcore algorithm hacking.

The next nasty problem for me to deal with is the issue of getting the game's controls working across multiple objects. For example, the player's fighter can be composed of a hull, a few guns and several thrusters. Input would need to be affect only relevant objects without causing weird side-effects in the others.

This problem is half solved currently. A single controller object, which is responsible for receiving and processing input from somewhere into actions. Any entity can attach itself to the controller and alter its state based on input from the controller.

A thruster, for example, can decide whether it should turn on based on whether the controller is saying "turn left" or not. This nicely addresses the issue of getting weapons firing in groups, thrusters firing appropriately and so on.

The second half of the problem isn't so easily resolved however. I also have to get state data from the enties that are attached to the controller back to the controller so that they can be sent to the network. My other option is to send complete object state data directly from each entity to/from the network, however that defeats the original purpose of the controller.

An additional problem I didn't quite want to solve this early, but have to, is getting the in-game physics working. This is due to my choice of controlling fighters via believable application of thrust and counter-thrust.

Plenty to mull over. I probably won't have a solution until the end of this week at earliest.

Tuesday, October 13, 2009

First Nastyish Problem Part 2

A nice bit of bone-headedness on my part. I spent around 40 minutes scratching my head trying to find how to get the VertexBuffer from ModelMeshPart so I could render it... only to find that it's in the ModelMesh that owns it. D'oh.

It really helps to look in the right place.

Monday, October 12, 2009

First Nastyish Problems

Now that the first phase of getting the basics up and running is done I'm starting to confront the nastier issues of getting this project to resemble a game that might, some day, be fun to play. Not to mention fleshing out the game's internals so they function as I originally intended them to.

The focus of the effort for the next couple days is on getting the graphics system batching objects to be rendered correctly.

The concept behind batching is to group together all similar objects to the video card in one big chunk. The hard part is that my graphics system is meant to contain very different types of objects (e.g. both 2D particles and 3D models) in a particular scene.

Technical crap below
My solution is to build two interfaces. The first, known as IRender, represents a complete drawable thing, for example a laser cannon on a fighter. This exposes objects which have the second interface, IRenderPart. These represent a piece of the whole object which has its own special appearance. For example an IRenderPart could be a glowing tip on the laser cannon and a second could be the actual body of the cannon.

The IRenderPart is the critical piece for batching. The IRenderPart exposes instructions on how it is to be drawn. The rendering enging groups all IRenderParts with similar instructions and draws them all at once. This, in theory, saves time used in sending different sets of instructions to the game console's video hardware since each set of instructions only needs to be sent once.

The big advantage of using interfaces is that they allow the graphics engine to see only the information it cares about to group the objects without having to worry about what, exactly, those objects are. This addresses the nasty issue of handling the variety of visible objects in the game that need to be drawn.
End of technical crap

Now it's down to implementing the changes. I'm approximately 25% done. In addition I need to implement a performance measuring harnass in the game so that I can perform adjustments to the game's code and know exactly what effects they have on the game's speed.

Thursday, October 8, 2009

The Cockpit

Today I'm going to talk about the cockpit in the game as it is right now. When you're playing you see everything as if you're the pilot sitting in the cockpit of a starfighter. What I hope to do is display all information relating to the state of a player's fighter as part of the fighter's cockpit. This dictated that the cockpit be one of the first things to be coded since it will be critically important to the player's in-game experience. The fundamentals (code-wise) are there now but they're not much to look at currently since I don't have much of any artwork done.
Cockpit test

I was motivated to do the cockpit this way by a pet peeve I have with space combat games like, for example, Freespace. The in-flight displays are just sprites, they're not part of the fighter! While this is primarily an aesthetic complaint it's something I feel is a major detriment to the immersion factor of games that often purport themselves as simulators.

There are a number of challenges with building the game's displays this way. Foremost is layout. The displays need to be placed such that they make sense and all of the information on them can be read easily. Also I need to decide how many displays there are, and what each should contain. Finally, I need to decide if there are to be any controls which change a display's appearance, for example switching between text and visual diagnostics. And, just for extra spice, the layout must fit completely within the "title safe" area which is the area visible on all TVs. If the displays don't fit then they'll be cut off for some players on the X-Box. Oops.

Currently I'm drawing inspiration from the F-16 fighter for a general layout of the cockpit. The F-16 features a HUD and three large displays for various tactical data.
F-16 Cockpit
In the game the cockpit will be somewhat similar. The HUD will display navagational and targeting data. The left screen will display sensory data and weapon status (e.g. ammo.) The right screen will display diagnostic data (i.e. what is, and what is not damaged.) The central screen will display tactical data. Additional information, such as score, is still displayed as text and graphics on the screen outside of game space.

Friday, October 2, 2009

Perhaps we have a muse

The first few builds of the project have been finished. Nothing too interesting to look at but you can fly around in space and the cockpit (but none of the information it should display) renders. After some initial testing with the demos I've downloaded I've decided that the Nuclex framework fits my needs better than Titanium XNA. It's a much more minimal product in that it's more of a toolbox than a game engine but the quality of those tools is excellent. Props to you Cygon!

For the past few days my girlfriend and I have started watching Batman: The Animated Series. One of several excellent cartoon series released by Warner Brothers in the mid ninties. I'm still impressed with how they managed to create such a surprisingly mature cartoon that was still accessable to children.

"But, what does this have to do with the game?" you might ask... One feature with Batman that stood out for me when I first watched it, and stands out even more now, are the amazing Art Deco images that pervade the entire series. I love the dichotomy of the style. With the right execution it can look both elegant and inviting in one moment then evil and terrifying the next. It looks both futuristic and anachronistic at the same time. Art Deco is an incredibly rich artistic style which I'd love to explore within the game. The future of the past if you will.




Just imagine something like this locomotive as a huge space-faring battleship... yeaaahhh :)

Sunday, September 27, 2009

About the Project...

I've always developed games as a hobby since I was a kid. I started with text-based games in QBASIC when I was about 7. Since then I've made shooters, puzzle games, tools and other stuff for my own amusement and the amusement of my friends in school. When I found out we had to do a large software project over eight months in our last year of school I immediately wanted to do a game.

The project, currently untitled, is a space combat simulator game in the same vein as the Freespace series and X-Wing series of games. The game is planned to be set up something like Quake 3 with one player hosting a game session and other players joining. Game types would be free for all (deathmatch, keep-away etc.) and team-vs-team (capital ship assault, etc.)

At this point I've finished enough of the initial planning and school-related junk that I can actually start development. I'm using XNA Game Studio 3.1 foras a development framework for the project. This provides a nice multi-platform base to work from and a good collection of documentation and sample code to boot. I'm mulling over using an existing graphics engine or rolling my own at the moment.

There seems to be a decent selection of graphics engines aimed at the XNA environment out there however most of the ones I've looked at are specifically aimed at rendering terrains which isn't particularly helpful. I've narrowed my list down to TXNA and Nuclex. My choice now comes down to how easily I can exploit the engine for my vile purposes and, if I can't whether it'd be easier to tear the engine apart or code what I need as I need it.

I'll be making my decision later this week.