Friday, 1 April 2011

Introducing ARIADNE

One of the problems with having an external 2D view of the player's ship is that, while the action may be fun, it's not very conducive to storytelling, as the ship does not portray any sort of character.  As I wanted Juggernaut to be quite a story-based game, I needed some way of telling the story without a) requiring FMV or b) full voiceovers because c) my budget is tighter than a gnat's anus.

Of course, this only really leaves some kind of text-based approach, but I really didn't want to assail players with walls of dry text.  Instead, I decided on a comic-based approach, where the story is conveyed by the main characters talking to each other.  Each character is vector-based, and may be posed in a variety of ways to portray emotion, with comic speech bubbles (and the emphasis therein) used to get across additional character.

The two primary characters are the protagonist Captain P. Tenuous (cookie to anyone who manages to work out *that* reference), a space trader undergoing a midlife crisis, and his belligerent navigational computer ARIADNE, who assumes the role of the deuteragonist.  Most of the dialogue within the game will be plot points and general banter between these two characters, and also serve to break up the action.  There is also a human antagonist who will be involved in dialogue less frequently.

Anyway, as a first character to implement in this system ARIADNE is the ideal choice, because its basic facial structure is so simple that it may be hardcoded.  In the game world, ARIADNE's model comes with a wide variety of different and engaging personalities, but since Tenuous was too cheap to upgrade he gets an annoying cynic with a face made of 16 triangles.

Each character is defined as a mesh with a neutral pose and a number of different sub-expressions that define delta vectors for a subset of the mesh vertices.  For example, ARIADNE has sub-expressions to raise its eyebrows, as well as close its mouth vertically/horizontally and move its eyes etc.  Larger expressions (such as happy/angry etc.) can then be generated as a linear blend of these sub-expressions. 

On the current test implementation of ARIADNE, the results look like this:

Example ARIADNE expressions.  The top left image shows the neutral expression (which is symmetric with strong right angles), while the other panels show various mixtures of sub-expressions that break the symmetry and add character to the mesh.  You can see the start of the speech bubble to the right.
As well as the expressions, there will be different framing options for each character, such as zoom level/angle, which can be used to imply 'intensity' and add additional graphic variation.

When Macros Invade Your Home

It's not very often I'd be inclined to post code bugs that I come across during development, but this one foxed me for sufficient time and the answer was face-palming enough that I thought I'd post it.

This is a little excerpt from some of the GUI handling code.  When you click on a control, it iterates through any sub-controls in a recursive fashion and calls the same function on those:
      virtual int mouseDown(const Tuple2f& Position, const IBaseMouseEvents::mouseStateChange& State ) override
         int Result = -2;
         //Check for intersecting with this control's layout
         if ( Overlaps(Position) )
            Result = -1;
            //Call mouse down on subobjects
            for( uint32 i=0; i<Objects(); i++)
               //Update the final result
               Result = max(Result, Object(i)->mouseDown( Position, State ) );
         return Result;
This seems pretty straightforward, but when I'd added a Next button to the GUI it was oddly getting clicked 8 times every time I pressed it, and I just couldn't work out what was happening for about 20 minutes. 

Worked it out yet?  If so, congratulate yourself on being a smug bastard.

The problem is that the max() function in C++ is defined as a macro, rather than a function, and this macro is (((a) > (b)) ? (a) : (b)).  As a result,the mouseDown() method could get called twice per loop iteration, and as my button control was 3 levels down the GUI hierarchy, this meant 2^3 = 8 clicks rather than 1. 


Right, now back to programming rather than scratching my head!

Tuesday, 29 March 2011

Font woes

OK, the title is not quite accurate.  What I'm currently having trouble with is finding a reasonably cost-efficient way of embedding a font into my game.  I've found a font, and it is lovely and perfect but, unfortunately, it will cost a total of $300 to purchase a license such that I can legally embed it within my game.  It's slightly irksome that this cost is basically 10x the fee for using the same font in unlimited commercial print media.


Sunday, 27 March 2011

Today I've been mainly sexing things up.

I've spent a bit of time today sexing my blog up, as it's been going for a while now but I hadn't gotten around to adding on all the standard gadgets yet.  So, I've added some tags to entries and the first couple of related blogs to my blog roll.

Up until now I've been a bit insular, but I'm making an attempt to engage the video indie game development community as a way of exchanging ideas and also hearing about other people's experience in the industry.  Mr. Tengu also wants me to slowly work out where my competitors live and have them assassinated, but as it is our budget barely stretches to kicking one person in the shin.

More ship upgrades!

OK, I've gotten quite a bit further with the ship editor now, and have gone as far as implementing a couple of new ship components in order to increase the variety of test configurations available.  One of the important things that's changed is the addition of a proper engine type.  Up until now, the main weapon component also served as a thruster for simplicity's sake.  There's also a new structural wing-type element (which looks much better than the old strut type), and I've redrawn the generator type to fit into the new graphic scheme more effectively. 

The screenshots only show two weapons: the standard cannon and basic laser type.  One of the things I need to do in the near future is create a proper ship weapon that implements the lightning weapon in a specified arc (rather than hitting absolutely everything as the test implementation did).

That laser effect still needs some sexing up.  It's on my todo list.

After a bit of improvement of the spawning framework I have once again gotten the laser weapon to leave a set of custom explosions at the point where it intersects the environment. 

The white lines that you can see between certain Scourge spores are for debugging some of the swarming algorithms, and obviously will normally be invisible.  I plan to redraw that turret weapon as well, it no longer fits in with the new ship parts that well.