How I tend to build projects, or why it’s usually painful on build tools

I’ll typically setup what I call a tripple-tree, or a quad-tree layout. Each project has three top level tree structures that represent a phase of “Getting it done”. Hacking it, building it, and distributing it.

A source directory (typically src or Source), that houses  the projects code, and basically everything you/I want under version control. Structure varies but I tend to create modular bundles out of habit.

A build directory (typically Build/Architecture/OS or Build/Architecture.OS), that houses all essential build time files for that configuration, that won’t be distributed. I test builds against multiple Operating Systems, and synchronise the work directory between machines; so being able to have builds of each concurrently tucked away is a bonus. Sometimes I go further and subdivide the build tree into different configurations, such as Release/Optimised/Debug builds, but I rarely have need to.

A distribution directory (typically Dist/Architecture/OS or Dist/Architecture.OS), that contains all the files needed for a user to simply extract to a folder on that given system, and run the program. Worth while for me, for the same reasons as the build tree, plus the added benefit of simple a zip/tar installation!

Sometimes I also create a fourth tree called ‘Vendor’ or ‘Deps’, that functions like the source tree, but instead contains the code for whatever libs are required. Plus customised project files/build scripts to compile them when needed.

Like wise, I’ll often have an associated set of FILES in the top level, and a documentation directory providing all pertinent information. I particularly pay attention to writing down notes about boot strapping builds, and porting the system to a new environment; because you never know when the next sap sending patches will be you.

Oh so many people ship IDE project files that reek of laziness or brain damage. Me, I’m so damn lazy that I don’t want to have to explain it, in fact, I don’t even want to edit it later. I just want the thing to *work* when I tell it to build sth. It takes time to do it that way, but it is usually worth it. At least, for cross-platform freaks like me.

Programming is a subject that I do take seriously.

Quick & Painless C/C++ header installations using rake

In wrapping up and refactoring my new rake driven build system, I’ve written numerous utility functions. Most stuff specific to compiling crap is in a custom “Builder” module that provides a templated interface to the current OS/Compiler kit, via environment variables and methods like make_object, make_shared_library. My top level rakefile also has a neato inference rule rigged together for handling my triple-tree and quad tree build patterns.

The real fun of the day however, is this baby:


#
# A magic function that generates file tasks that copy all headers from
# directory ind # to directory outd.  Any missing directories are created as
# needed.
#
# The return value is a list suitable for the right hand side of a task, e.g.
#
#   task :headers => header_magic(src, dest)
#
def header_magic(ind, outd)
  dirs = []
  hdrs = []

  find_files(ind, /.*.h[hxp]*$/) do |p|
    outdir = File.dirname p.sub(ind, outd)
    outfile = File.join(outd, File.basename(p))

    directory outdir
    file outfile => p do
      cp_r p, outdir
    end
    dirs.push outdir
    hdrs.push outfile
    CLEAN.include outfile, outdir
  end

  dirs+hdrs
end
find_files is another custom function, it simply takes a block and yields and file names matching the specified pattern. (In this case, more liberal than the usual header extensions but sufficient for my needs)
I call it header_magic, because it after all the other stuff I played with, it’s the closest to Clarke’s third law. Which is exactly what I want!
footnote: I just have my top level clean task nuke the entire build tree; so the CLEAN part hasn’t been tested.

In looking closer at things, somehow I think that by cica GCC 5.0, either the GNU compiler will have imploded upon it’s own weight :-o, or it will become an impressively powerful compiler, in place of an impressively portable one.

The feature set being grown, may even give old MSVCs optimization setup a good run for it’s money someday, only the best tools with Visual C++ cost a few thousand dollars and GNUs is given away for free lol.

Me, I would just settle for a generally portable compiler that generates decent code, and complies with the bloody standards… So far I personally like pcc.

Jokes sometimes place the yoke on you

In writing a small module, that in part of it looks like this:

    switch(function parameter of some enum type) {
      case SomeEnumValue:
        handle it
        break;
      // done for each enumerated value
      default:

        // crash program? *evil grin*
        2/0;
     }

    // use the function parameter

This was written as a joke to allow me to test the function by forcing the compiler to pass an invalid integral value, which would trip the default label. Obviously the final code needs to do something besides float around oft’ undefined behaviour, but one has to have a little fun in idiot proofing your code ;).

The funny thing was instead of crashing, it continued on and triggered the (testing) assert() checking the function parameter, which then caused the program to terminate. Even more enjoyable was changing it to `int x = 2/0;`, causes the program to halt due to a floating point exception. Someday I need to thumb through the C++ standard and take a look.

Oh well, I had planned to throw something from stdexcept anyway, or carry on with reduced functionality; so it’s no real loss lol.

Why C++ is a failure

In reading through Scott Meyers book,  Effective C++, his expression that it should actually be viewed as a federation of languages, is actually a great way to look at it. He describes it in terms of C++ the C, Object-Oriented, Template, and STL groups (I would’ve skipped the STL) is fairly accurate.

The true gem however, I think is Item 19: Treat class design as type design. This IMHO, is more true in languages like C++, Java, and C#, than what some folks are accustomed to. You’re playing with the type system, so act like it.

He points out 12 issues involved with developing a new type or ‘class’, I’ll summarize them briefly:

  1. How should objects of your new type be created & destroyed?
  2. How should initialization differ from assignment?
  3. How should passing-by-value work with your type?
  4. What restrictions are their on legal values for your new type?
  5. How does inheritance effect your new type?
  6. What kind of type conversions should be allowed?
  7. What operators and functions make sense on it?
  8. What standard functions should be disallowed?
  9. Who should have access to its members?
  10. What kind of guarantees does it make?
  11. How general is it?
  12. Is a new type really what you need?

If anything, I would say rip out those pages of the book, and make it a required `check list`  of ground new programmers must cover before they are allowed to add a new type to the code base. The book gives excellent explanation of each point, so I won’t offer much deep exposition here on them: I’ve just tried to condense them. (Buy or borrow the book lol.)

If you’re going to be creating a new type; which you are effectively doing when creating a new class in C++, then these issues all apply to you. I would argue, that most of this applies to any language with user defined types and operator overloading; which is also most main stream language supporting OOP.

Points 2, 3, 4, 6, 7, and to an extent 8, all make sense in the domain of creating a new ‘type’. Personally, I tend to skip much of it unless for example, overloading certain operators offers serious savings on expressiveness, or the default copy constructor / assignment operators are insufficient. These points that the book outlines, really are the source of most complexity in developing C++ classes, perhaps because like C-strings and good ol’ malloc(), it exposes a lower level picture of things to the programmer. Everyone can program in C, but not everyone should.

Points 1, 5, and 9, are more unique to designing a class than the others are, at first glance. Simply put you can’t create a class without taking 1 and 5 into consideration, it’s just required. Although admittedly you can skimp a little on 5 in some cases but probably shouldn’t. If you know jack about OOP, let along designing software, you know the answer to 9 is the minimalist level of access required. I actually enjoy that Scott Meyers work demonstrates, that OOP goes a lot further than the class keyword! Abstraction, encapsulation, and modularity are an integral part of doing quality work, and object oriented programming is but a useful paradigm for modeling that, especially when polymorphic inheritance is applicable. Point 5 becomes a bit easier to live with as time goes on, although I still suggest favouring object composition over inheritance when a class hierarchy isn’t the most appropriate thing for solving the problem at hand (and minimizing the ruddy singletons).

Points 10, 11, and 12 are true of most elements of composition within a program: from even for functions. Those kind issues get easier with experience, assuming you learned a slugs worth about software design in the first place. Some people never learn it, period.

Why based on those oh so true points, would I conclude that C++ is a failure? Because the “Average” slep is just not competent enough to deal with most of it as often as necessary. Heck, I still encounter code bases where the programmer can’t tell the fucking difference between signed and unsigned integers when designing their interface. There are some truly brilliant programmers out there, and many of them do use C++ quite heavily, but in the wider majority, as with most majorities: you’ll find more Homer J. Simpson’s than Sir Isaac Newtons in the crowd. This goes for just about every thing on earth :'(. We could use some more clones of Newton and a few less Apple and Fig Newtons walking around. So long as the average is sufficiently uneducated, and still allowed to (ab)use the language, I think it’s a failure; but hey, who ever said C++ was designed with the incompetent people in mind ;).

It is simply to much for the average Tom, Dick, and Harry to be able to consider it. Not that those proverbial average three bozos should be screwing with a complex system… half as often as they are found to be. Maybe I’m more inclined to make such statements, as I still know average adults who can’t understand a + b = b + a; yet, and I have met a whole lotta stupid people: without even counting programmers.

disclaimer: I drew this conclusion ages ago after reading EC++s item 19, that “C++ is a failure”, and was in a more stable state of mind at the time then the one used to finally type this out.

In reading through Steve Yegge’s old blog, I found a statement that perfectly summarises what selecting a programming language for a complex project is like:

So… the best way to compare programming languages is by analogy to cars. Lisp is a whole family of languages, and can be broken down approximately as follows:

  • Scheme is an exotic sports car. Fast. Manual transmission. No radio.
  • Emacs Lisp is a 1984 Subaru GL 4WD: “the car that’s always in front of you.”
  • Common Lisp is Howl’s Moving Castle.

This succinct yet completely accurate synopsis shows that all Lisps have their attractions, and yet each also has a niche. You can choose a Lisp for the busy person, a Lisp for someone without much time, or a Lisp for the dedicated hobbyist, and you’ll find that no matter which one you choose, it’s missing the library you need.

Except replace the lisp dialects with every language ever written, and factor in portability issues, and you now know what it’s like to be a multi-lingual programmer xD.

Conceptual: Stargellas Revenge

Premise

You take on the role of Stargella, a lonely star fighter pilot just returning home to the beautiful world of Freyja0 after a long patrol in deep space aboard the carrier ship Hofvarpnir1. Sadly in your absence, the evil Viekasiekian Empire has begun laying waste to your luscious planet! Deploying all fighters, as a group of imperial Triremes2 begin encircling the carrier,  the tides turn in the enemies favour. Soon you find yourself the sole survivor to reach Freyja alive, as all remaining hands go down with the Hofvarpnir.

Far from fearing a single star fighter in their midst, you must exploit that Viekasiek pride in order  to liberate your planet from the clutches of Emperor Zurick. Battling across the polar ice caps, over the sea, and into the forests of Freyja, you must push the Viekasiekian forces back into space: facing hordes of enemy fighters along the way. Among these include the heavy Ballista and Scuta, as well as lighter Velites3 and scout pods that make up the invasion force. Finally punching through the fleet in orbit, for a final show down against the emperor.

Game Play

The game is meant to be played in a 2D-esque top down point of view, utilising the mouse to manoeuvre across the screen. At it’s heart, is the intention to keep the action alive, blending an array of attachable/ejectable weapons and combat styles with a large amount of adversaries. My idea for a game, you can play additively as an arcade classic but with a pace that better befits the modern style. It’s aimed at folks like myself, who can still sit down and play Centipede or Tetris all day long with a grin, but would like a bit more spice.

It is meant to be more or less, ‘traditional’, in the sense that power ups drift across screen to be collected, and fairly simple on the graphical spectrum.

Current specs call for about 11 enemy craft and 3 more usable by the player5. The players ship is basically given a capacitance based on its size: larger equals more guns and harder to kill. Depending on the class of ship5, will also limit its ability to bring that heavier ordinance to bear upon the Viekasiekian slime.

  • The light fighter given at the start, being designed as a simple but agile craft, is meant to reflect an association with nature. It is obviously limited to only a few weapons because of its small size, but has a regenerative armour skin around a highly effective power plant, that makes for a long lasting craft with some serious skill. It gives extra advantage to players focused on not getting hit all the time, and favouring a few lasers backed by a heavier weapon for dispatched more powerful foes.
  • Medium class, being a more conventional ship of the line gained after a a certain amount of game play. Trading the lighter vessels regenerative skin, for a deflector shield and larger weapons bays, every hit on the shields will reduce the power available to laser weapons; thus off setting the greater capability to carry heavier missile and cannon than smaller craft. It’s meant to be a middle of the line way of playing, that rewards those who can balance its abilities during furious combat and still come out on top of the scrap heap.
  • Where as the heavy class, is basically the big bruiser of the bunch. It’s meant to be an unlock for scoring a good bit of points during the course of play, yet still balanced enough so that even the light fighter from the start can still stand a chance at winning the same fights as the heavy. Combing a large weapons payload with enough armour to last a while, it makes up for needing ‘armour patches’ during a long engagement, by being able to smash through anything that can’t kill it. Think about a dump truck turned into a war marchine lol.

 Weapons can be equipped when found, or jettisoned to make room for others. The hit list includes various strength of laser, that balance energy use to power consumption<6, as well as several class of heavier particle beam and ballistic cannon style weapons. My favourite being the missile types, hehe.

Each ship can only carry X slots in weapons with so much ammo, so one has to balance out what you have collected, when it’s fired, when it’s dropped, and do it all tactically during the regular course of game play. Weapons come in several principal varieties based on the kind of ammunition they utilise, making it simpler for the player to calculate a weapons value in the present situation.

  • Energy
    • Drains part of your energy gauge with every shot, but other wise never runs out of ammunition.
    • Types:
      • Blue Laser
        • Low output for short range combat, aimed to minimise energy drain whilst dealing with cannon fodder.
      • Green Laser
        • Typical energy weapon offering moderate damage to energy consumption. It’s a staple weapon but lacks serious punch.
      • Red Laser
        • Packs a hard punch but requires plenty of energy for each shot. Best suited for destroying targets that you can actually hit.
      • Particle Cannon
        • Fires a stream of charged paricles, consuming a large portion of energy in exchange for a solid knock down punch. It’s the plasma cannons younger brother ;).
      • Plasma Cannon
        • Very powerful but sucks up energy like a thirsty vampire. Ideal for quickly dispatching Viekasekian scum.
      • Overcharger
        • Drains all available energy and unleashes a devastating shock wave, dealing a proportionate level of damage to anything caught within the waves radius. A weapon of last resort!
  • Missiles
    • Uses up so much missile ammo per shot, but only a nominal amount of energy drain per firing. Some offer a form of lock, fire, and forget capability.
    • Types:
      • Micro Missiles
        • A small cluster of homing missiles, that gives chase to any craft in their line of fire. Not very powerful but amazingly handy in a brawl.
      • Heavy Missiles
        • Less intelligent than micro missiles, but capable of dealing strong damage to watever it manages to hit.
      • Spread Bombs
        • The tactical nuke of your arsenal. It fires straight ahead and explodes, dealing massive damage to anything within its corona. Best used as a weapon of last resort or against a tight group of enemies.
      • Zip Mines
        • Explodes a small zero point charge whenever a craft comes within a short radius of the “Zip” mine. They gradually float off screen, making it hazardous to player and enemy alike. This is your only rear firing weapon.
    • Shells
    • Requires “Shells” for ammunition and packs a strong wallop with low energy drain.
    • Types:
      • Auto Cannon (AC)
        • a
      • Rotary Cannon (RC)
        • A multi-barreled, large bore Gatling gun. Fires less powerful shells than the AC, but offers a more rapid rate of fire. Can quickly burn through smaller craft and shells alike, but it also jams with frequent use. Fire it in short bursts.
      • Cluster Cannon (CC)
        • In effect, a giant shotgun. Deals massive damage to anything up close but is practically useless for more distant targets.

Technical

Stargellas Revenge in it’s own right, is only the equal of about 6-12 months worth of coding, leaving most of the effort to graphics creation. An early prototype was built in C++, around SDL for graphics and Xerces for data serialisation tasks. Soon however, I realised that it would be worth my while to make it more general, so that much of the games insides could be redeployed for other game projects7.

This makes the game much more time consuming, particularly when you consider its a ‘side’ project, but the advantages are worth the delay. One reason I like it, is it allows me to flesh out the systems resource, multiplayer, AI, and various other infrastructure tasks without having to do it while coding around a much more complex game.

Most likely, it’ll be the test bed for a custom rendering system8 focused on stressing the API. The overall design of the games internal, is designed to be pluggable9 enough to allow easy access to some very professional strength rendering technologies, as well as being able to hot swap as much of the componentry as needed. Thus allowing the graphical quality to be reduced on systems where the better tools, are sadly, unavailable… without having to give up on them where so available10. The main reason for this being, I want to be able to play Stargella on my laptop11, as well as the 3D games on my desktop!


Footnotes:
0 Freyja is a goddess in Norse mythology, associated with attributes appropriate for describing Stargellas home world.
1 Hófvarpnir another reference to Norse mythology.
2 The triremis being a type of Roman warship.
3 These are all references to Roman military weapons and armour. In particular watch out for the Celeres defending Zurick.
4 It’s a fairly consistent theme, that names of Viekasiekian fighters stem from the Roman military, where as those assoicated with Stargella, have roots in Norse and Germanic mythologies.

5 Will probably be named after Valkyries.
6 Blue = low drain / damage; Green = medium; Red = kick ass and slurp power.
8 Think W3D level of complexity rather than COD6 graphics, but than again, this is a game inspired by games built during the 1970s.
9 I only intend to do OpenGL for most things, doing an equalivulent in DirectX 9/11 is left as an exercise to another geek, or a bored weekend.
10 You can have very high quality graphics under Windows NT, GNU/Linux, and Apple stuff: but FreeBSD is rather lacking in ease of deployment for games :-(.
11 FreeBSD.

At long last

My forum account on www.sasclan.org is finally ready op! It was unsuspended a few days ago, once WIZ completed the usual procedures. Kicking the bigger system into obedience, +1 for [SAS] admin power. Last time, I had to respond to a chit chat post via private e-mail.

One thing that I do not miss about being in [SAS], is having to deal with the ‘magic’ behind it, any more than it takes to make a forum post. Although I know my way around blindfolded in spots… I ain’t never gonna miss that code base.