Friday, December 9, 2011

Miniature Wargames are a Racket

Don't get me wrong, I love the things.  Well, more accurately, I love that they exist.  I dabbled a little bit with Warhammer 40k after getting an Eldar model, and found the modeling part of the hobby stimulating.

The rest of it, though, was not only daunting but expensive.  Very expensive.  And my area and school simply did not support the demographic that plays these sorts of games, so there was no community support either.

Games Workshop (GW) dominates this genre of table top games where armies crafted, both in miniature form and function, by the players are pitted against one another on a table top battlefield.  GW is headquartered in Nottinghamshire, and like Denmark's LEGO brand has the unfortunate property that its origin's currency is far more valuable than greenbacks.  That and the expense of producing what a friend calls " a complete hobby" and especially one of the quality of GW's work makes these things cost a lot. 

Note that I do not mean that GW makes a great product and everyone else makes something on par with green army men.  I mean that GW manages a huge number of properties accompanied by a complete line of modeling supplies, literature, rules, miniatures, events, and dedicated stores and does so with an overall very good end product.  Other companies put out comparable wargames that are cheaper and in terms of rules are probably superior.  But I am not familiar with them, except in passing, and my experience with this hobby is almost entirely in the realm of making and painting the miniatures, and mostly GW at that.

It has been said* of the table top wargame minis that there are three choices, cheap, good quality, and variety.  You of course can only pick two; GW opts for the last two.  Seriously, the number of options you have in any given GW model is stupid and I suppose the cost of the hobby can be mitigated somewhat if you keep with it because of the supply of extra bits you accumulate.

As usual, I ranted much about a subject that is tangential to what I really wanted to talk about, and that is the cost of wargaming modeling supplies.  They are numerous and specialized, from lichens and mosses to paint and finishes, there is an entire sub-market devoted to the supplies to make little plastic things look good.  In terms of performance, good modeling products need to be well suited to their task and engineered to deal with it well.  They most economically come in small packages because the rate of use is much smaller than other crafts.  They must stand up to repeated abuse, be easy to use effectively, and be something that young teenage males, the main demographic, can handle without too much of a mess.

And I think we've been conditioned to believe that makes these supplies expensive.  This is not true; the supplies we get from dedicated modeling suppliers are expensive.  Take flock for bases.  You can buy it for $4 in half cups, or make it for almost free in gallons.  Graded sand for bases as well; buy it at $0.083 a gram or buy it at $0.0065 a gram (A.C. Moore does sell a more natural color that matches the Citadel product, but it is not on the web site; in my store its in with the floral Styrofoam).  You can also get your sand from outdoors if you live in a sandy area like me.

What about paint?  Those little Citadel paints are fantastic, and fantastically expensive.  An once of paint for $4.  The colors last a long time, and the metallic colors are the best in acrylic model paint, but what about all that primer?  400 ml of acrylic white spray primer for $15.75.  Or 350 mL of enamel spray primer for $4.  Don't like spraying?  $0.30/mL for acrylic white or $0.06/mL for Liquitex Basics white.  The latter, when used the same way Citadel says to use their paints, makes a tougher, flexible, less brush-mark prone primer layer.

Painting Grey knights or some army that is mostly metallic and requires a lot of paint?  Don't spend a boat load on small pots of metallic paints, mix your own in appropriate quantities (about two bottles of pigment and one bottle of medium gets you an equivalent of $73 of Citadel paint for $16, and it can be any color metallic you want).  I did this for a friend's large aircraft model, intending to bring up images of old polished aluminum planes from the mid 20th century; it worked perfectly for dry brushing over black.  You can also buy Plaid brand metallic paints, which are comparable to Citadel's in quality, are cheaper, come in more colors, and a few even come in large bottles**.  There is one light green shade in particular that would be well suited to Necrons.

Moss speaks for itself.  There are also cheap bags of sea shells and glass shards, as well as plastic crystal chunks and Styrofoam in all manner of shapes and sizes ant craft stores.  Seashells in particular are just the sort of thing large monsters can use.

So don't go buying "official" supplies when you don't need to.  Use your smarts and look around craft stores that you would never think of for products to abuse for things the designers never thought of.

*Okay, in a paper or actual print article, this would never fly.  Its the literary equivalent of "I heard from a guy this one time..." and it is usually lazy.  However, I could not tell you where I read this other than in some forum discussion that involved Reaper Miniatures and the exorbitant cost of minis in general.  Searching for the quote is time I don't have, not to mention a difficult thing to get through Google.

**Craft grade acrylic paints are good to use, but try the brand out first before doing so.  Plaid is thick and creamy and will usually perform as well as a Citadel color, just don't water them down as much as a Citadel paint.  You should usually varnish your minis anyway, but craft paint will usually demand it.  Plaid metallic colors won't, though.

Monday, December 5, 2011

Saving Time and Saving Money

Recently, I had one of those "ah-ha!" moments while reading an XKCD comic.  Given my family's inclination to ostensibly save money, no matter the cost, it is not surprising that I never equated the act of saving money to the act of saving time.

If the comic and that sentence do not spell it out clearly enough, it basically breaks down like this: the oppurtunity cost of saving money is the time you spent doing so.  As XKCD points out, if you spend 9 minutes or more to save a dollar, you are working for $6.66 an hour or less.  This is an essential insight to saving money, and as usual, brings to mind the old adage that "time is money".

Combine it with another favorite of mine, "if you don't have time to do it correctly now, how do you expect to have time to fix it later?" and you have a powerful way to reason about your handiwork.

  • Take your time to do good quality work because every minute you spend doing it right saves at least another minute later fixing what you botched.
  • Avoid materials and methods that are unfamiliar or too involved to acquire (unless the above applies, of course).  You save time learning the new techniques and avoid using those techniques poorly, thus sidestepping possible mishaps.
  • Plan ahead and in some detail so that when you are out on a job or gathering supplies you have thought of everything you need and thus will not waste an hour picking up things you forgot.
It all seems like common sense, but it is not obvious how dire the consequences are.  For instance, say you are building a deck.  If you needed four more 2x4's than you bought, and the lumber yard is 20 minutes away, you must spend $5.00 in gas to buy $10.00 in lumber and spend an hour doing so.  If you are making $30 an hour, now you are making $15 and you have to spend an hour more later.  Do that twice a week over a three week contract, and you have to spend an additional day working and $240+ of your customer's money.

Now what if, in a similar and even more likely situation, you bought enough lumber but because you did not double check your measurement, you need those four 2x4's to fix what you botched.  If it took 45 minutes to measure, layout, and cut that lumber, then find out it was wrong, that is $22.50 and the better part of an you wasted.  Now you have to work two more days and spend more than half a grand of customer money, and that is if you are working alone!

Two working days and half a grand or 30 seconds and three cents.  Those are your choices, so you should probably double check everything you measure. Every time.

Friday, December 2, 2011

Swizzle that vector! Part 2

Well, after a long day trapped in the barn cleaning (it looks presentable now!) I return for the second part of implementing swizzling in C++.  I left off at the reasoning for using the functional operator and multiple arguments of a swizzle class, with the tantalizing hint that getting the error checking to work at compile time was weird.

So, here is the problem.  We have a Vec2, that is, a two component vector.  It should only be able to use swizzle components for the two components it has, that is, X and Y.  Something like:

vector2( x, y, x);

is valid but:

vector2( x, z, y );

should not be and ideally should throw some error at compile time.  Also, every vector type can use the swizzle components of the vector types that are smaller than it:

vector3( x, z, y );

It is clear that we can use inheritance to enforce this, but we must be careful.  When I first tried this, I made the mistake of inheriting in the direction that seemed the most logical, but that was in fact wrong.  Your gut instinct is to have the 3 component swizzles inherit from the 2 component swizzles:

class Swizz2;
class Swizz3 : public Swizz2;
class Swizz4 : public Swizz3;

But this does not solve the problem: it would mean that a Vec4 can only use the 4th component swizzle, W.  We are not following the Is A... principle here because we went with what felt natural.  It is correctly written:

class Swizz4;
class Swizz3 : public Swizz4;
class Swizz2 : public Swizz3;

And when we implement the functional operator for a Vec2 or a Vec3:

Vec2 operator() ( Swizz2 const& a, Swizz2 const& b ) const;
Vec2 operator() ( Swizz3 const& a, Swizz3 const& b ) const;

we can be sure that the operator will take only X, Y, and Z components in the Vec3 but only X and Y in the Vec2.

The final step to make all this safe from the user is to lock down the swizzle classes so that no one can alter what they mean (well, at least not easily).  I did this first by making the internal fields that govern how a particular instance of the Swizz2, Swizz3, and Swizz4 classes are used to swap components around private.  The swizzle classes are declared in the header file but omit their implementation, along with a class called SwizzleFactory:

class SwizzleFactory;
class Swizz4;
class Swizz3;
class Swizz2;

This makes it so that any other translation unit can use the classes but cannot do much with them.  In the implementation file, SwizzleFactory is declared a friend of the Swizz# classes, whose only useful constructors are private.  The swizzle components names are also declared in the header file:

extern Swizz2 const x;

/** etc. */

And then defined in the implementation by using the factory methods of a static SwizzleFactory instance:

Swizz2 const x = factory.MakeSwizz2( 1 );

Since the implementation file is the only place where the factory is defined, it is the only place where it can be instantiated. Thus, that translation unit is the only place where the swizzle classes can be defined and the whole system remains very safe from user intervention, unless they do something stupid and ugly.  To top it all off, the whole things lives in the namespace GFX, just in case you really need to use x as a variable name (do not do that).

Swizzle that vector! Part 1

If you have used OpenGL since version 2.0, you should be familiar with GLSL, the incidentally redundant 'Graphics Language Shading Language' (technically 'OpenGL Shading Language', but the "GL" stands for the above, sooooo...).

A nifty feature of GLSL is that it's primitive* linear algebra types, vectors, can use something called 'swizzling' to return a new primitive from the arbitrarily rearranged components of the first.  If you have the 3 component vector "vector1", for example, you can return a vector with the X and Z components swapped thusly:

vector1.zyx;

You can also construct vectors of a different order, that is, a different number of components:

vector1.zzyx;

This is really handy in shaders and linear algebra in general because you sometimes need to do just that, such as switching between coordinate systems.

But of course, C++ does not have this feature itself.  Not that it should, mind you; it is not a linear algebra language.  But when I was working on my own mathematics library for my work on computer graphics, I figured that if my vector package was to be really useful I should try to implement something like swizzling.

That is really difficult, as it turns out.  You cannot use the exact same syntax as GLSL and have something sensible; doing so would require all vector objects to store within themselves a copy of every combination and permutation of their four components as a field, which comes out to something like 4^4 == 256 additional float's per vector.  Memory is cheap these days, but it is not that cheap, not to mention its nauseating.

Some malign the option, but in C++ you can (and should) overload operators for your classes.  Thus, you could use the functional or subscripting operators, () and [], respectively, and have the swizzle combinations as separate, static objects with a name corresponding to the combination. Something like:


/** ... */
static SwizzleClass xyzz;
/** ... */

class Vec4 {
/** ... */
Vec4 operator() ( const SwizzleClass swizz ){ /**...*/ }
/** ... */
};


Which would be sufficient and replicate the functionality as is.  However, I found this method ugly; it felt too much like shoehorning something foreign into C++, the kind of thing a good Lisp programmer might pull if they tried to implement closures into C++ without thinking about it too much.  I was also a little worried about memory swapping; with some 256 static memory objects flying around, it sounded like a recipe for a speed bump**.

I also realized that there was something else I could make it do that GLSL could not: negate individual components.  The syntax in GLSL precludes this because it just stings component names together.  So I instead opted for using the functional operator with multiple arguments.  These arguments would be of a Swizzle class and have the negation operator overloaded so that one may write:

vector1( x, -y, y );

The number of arguments dictates the return type of the operator.  This method also solves a crucial typing issue: a two component vector cannot use swizzles for components it does not have, such as Z or W, but static, named permutations do not easily allow for this check at compile time and instead we would have to either throw exceptions or use a confusing system of classes and a royal mess of operator overloads.  That makes debugging linear algebra code blocks very difficult.  Using individual component swizzles like this allows us to solve that problem using the type system more directly, but the solution itself is a little unintuitive and will be the subject of a later post.

*To be clear, 'primitive' in the programming sense, that is, it is a feature of the core language and not a class or type implemented in it.

**The rule is "profile, then optimize".  I never profiled this option because it was a hassle to write all those permutations up when I was certain it was a bad idea for any number of reasons, memory being only one of them.  It is likely it would not have had dire implications as far as memory goes.

P.S. The HTML generated by this editor is a train wreck when it comes to changing fonts.

Thursday, December 1, 2011

I can hear the planes now...

I live in a farm house that my...great great grandfather built, if I have that right.  That was 120 years ago.  He was a carriage maker and wheelwright; the workshop was in the house next door, powered by steam.  Whatever happened to those old behemoth machines is anyone's guess.

Anyway, the barn is what was built first and what was used to build the rest.  Gramps (that is, my great grandfather) had his workshop in the barn, off to the left.  When we had to rebuild the barn's rear wall and foundation because it was sliding off, the interior got an overhaul, and ever since my father and I have been working to get it all into a coherent workshop.  That was a long while ago, and its had three layouts or more since then, but this time I think it is a keeper.

Now, not every person can claim to live in a house built a century ago by family and filled with the detritus of all that time.  Save the large machines, some unknown number of planes from GGGF's tool chest, and anything that went with the blacksmith shop*, I have located all the tools and I am currently in the middle of returning them to working order.

This has been hard; three generations have been in possession of these things with little to no knowledge of how to take care of them, let alone use them.  The "hand tool revival" has been a great help as the information is now out there for anyone to access, but rust, moisture, and insects are fierce adversaries.  I seriously doubt that today's tools could have survived so long under these conditions.

I suppose I am obligated to put some pictures up of this fabled workshop, but that will have to wait a little while longer.  Still a mess in there what with the crates of tools awaiting a long bath in Evaporust**.

*The blacksmith shop was donated to a local museum, tools and all.  The paperwork got fouled up, but when it got moved upon the closing of that museum to a new location and rebuilt, we stepped in and my mother got to help dedicate it.  Cool stuff, and I hear that in the summer there is a real blacksmith there to educate people.

**Just Google it.  Evaporust is a fantastic product that dissolves rust without harsh chemicals and easy disposal.  The process etches the surface very slightly if you leave the steel or iron in for a long time, say overnight, which some tools need.  The matte grey and black finish this leaves can be easily removed with a wire brush and some metal polish.  A side effect of the etching is that sharp edges and points get sharper.  I have yet to test it on a clean, dull file, but it seems to sharpen files as well.  Citric Acid is another solution that works a little slower, though I have not tried it myself.

Wednesday, November 23, 2011

#1

A friend once said to me "How many civilians did I kill?"

Actually, that wasn't to me, it was to our game master at the time.  And I've since had a bit of a falling out with him so he might not like the term 'friend'.  Don't worry, they weren't real civilians.  You see, we were staking out an airport in this Cyberpunk campaign and...wait, that wasn't what I was going to talk about.

Ahh, yes: a friend once said to me "Mike, you should really have a blog because you're always finding these nifty little tidbits."  Not the exact words, but close.  He is of course completely correct; I'm usually collecting random information all the time, and I generally am capable of bringing all of it to bare at any given time on any given project.

Oh yes, projects.  I have a lot of them, and I've never been good at finishing them.  With ADD, you need to really concentrate and be religious about something to get it done.  And that's real ADD, mind you, not the colloquial flavor where we chock all lapses in focus to a medical disorder.  I've been working on this, but it is slow going.

An up side to it is that I find a wide range of stuff interesting.  Cooking, woodworking, painting, miniatures, drawing, programming, whatever.  I can do and have done a lot of things, often to great praise (okay, maybe not even often, but I make good stuff).

What makes it possible is realizing that everything has something to do with everything else.  Understanding linguistics helps you name things better in your programs, knowing how the eye perceives makes 3D graphics easier to write, physics and leverage makes your carpentry easier, and chemistry allows you to understand your recipes.  Understanding the connectedness of how everything works allows you to store a great deal more information because you can reason from base principles instead of memorizing reams of facts.

So expect posts on a wide range of subjects.  These next few days will probably be a mixture of the culinary and the arboreal.