Tales of the Rampant Coyote
Adventures in Indie Gaming!


(  RSS Feed! | Games! | Forums! )

Thursday, June 14, 2007
 
Frayed Knights Dev Diary: Catching The Fly!
I knew an old lady who swallowed a Bird
How absurd, to swallow a bird
She swallowed a bird to catch the spider
That wiggled and jiggled and tickled inside her
She swallowed the spider to catch the fly
But I don't know why she swallowed the, fly
Perhaps she'll die

This week, I felt a lot like the old lady in the song. Last month, I finished the design document and worked to stub and rough out Frayed Knights, adding stand-in elements to all the code that needed to be done. An "outline" of the whole game if you will. A week ago, I talked about putting together a schedule and trying to implement the "First Five Minutes" of gameplay.

Side Note: I got TONS of great comments about the FFM document - both in the forum and via email. Thank you! That really helped crystalize some ideas in my head, and caused me to reconsider some elements. This is exactly what I needed. You guys rock.

This week, I've gone down the path of trying to implement that first five minutes. I started with a simple task, and watched it compound into multiple prerequisite tasks. Eating one in order to eat the other. As happens in all software projects... and many other projects in life too.

The Fly
The main menu of Frayed Knights is already more-or-less working, so I focused on what should happen the moment the player presses the "Begin New Game" button. The player finds himself just inside the threshold of a temple, and a static dialog fires. I'd even already implemented the core of the static dialog system. EASY! Except... uh...

Swallowing the Spider To Catch the Fly
Okay. First of all... the static dialog system code was just using a hardcoded dialog. Now that I'm going from quick-and-dirty visual prototypes to a less-quick-and-less-dirty functional code, though, I need to create functions to read in static dialog scripts and handle them. So what format do I use?

Well, the absolutely easiest thing to do was to cut and paste the dialogs I'd already written, and see if I could get the game to use them as-is. So I did. Oh, there's more to it than just that. The dialogs will have to have some additional commands in place to do things like change the characters facial expressions, force multiple lines of dialog to occur simultaneously, flag a line as an "aside" so that it gets a different-colored background, and so forth. But some of that can wait for later - it's not part of the first five minutes. I just had to leave things flexible.

The cool thing was that, after implementing this (which didn't take long at all... sometimes Torque really does work nicely), I suddenly had several dialogs "done" from work I'd done during design. Cool!

Swallowing the Bird to Catch the Spider
Now there was another problem. There are two ways (according to my design) to display static dialogs I'd just thrown together. The first - and the only one implemented - was actually the more complex of the two. It's the timed display of text, without user input. This only occurs in certain circumstances - such as in the middle of combat, where the dialogs are very short (maybe only one line), and the player is expected to be busy doing other things.

The other kind of static dialog is where the player is manually clicking "next" after every dialog, or "cancel" to prematurely shut it down. So I had to implement this second system, and hope it didn't break the original. No biggie... I just had to create a new UI overlay with the new buttons, and call the events via buttons instead of scheduling.

Except there were bugs. Like what happens when the player is moving or turning when the static dialog comes up... the player kept on moving forward, unable to stop his movement at all because he's currently in a "different" UI. Oops! Little things like this needed to be addressed.

Swallowing the Bird To Catch the Spider...
Next - this dialog (and the two proceeding directly afterwards --- the "Who Is Pokmor Xang" dialog and the "Brittlebone Skeleton" dialog) need to be fired off by events. So I needed to create a game event system. This is basically a somewhat generic approach to triggering game events, like dialogs, combat encounters, descriptive text, tutorial messages, or what have you.

Ideally, trigger conditions should include all kinds of different logical conditions, like random dice rolls, the health of the party, whether this trigger has fired before, etc. This is actually ultra-easy to do in a scripting language like TorqueScript, as I can have it evaluate an expression at run-time. So I can stick any amount of additional logic as simply part of the data for a trigger, and have the code check to see if it evaluates to true. To keep track of how many times the trigger has fired, I maintain a master trigger list which keeps track all the IDs of all triggers which have gone off, how many times they've gone off, and whether or not their state is supposed to be saved (nearly all triggers will have their state information saved when the player saves the game, but I left the option for triggers to be session-only).

I also created an EXTREMELY simple queueing mechanism, which consists of the current event and the next event. I don't predict ever dealing with a backlog of queued events, but I have it providing me with big red error messages if I do so I can decide whether or not to expand the queue or adjust the events.

I may do more complicated things with it later, but for now I left things simple. I put the details of the event on the aptly-named trigger volumes in Torque (well, a data-driven subclass of the trigger volume), which then call the event system with their event information. Other kinds of triggering activities (such as events themselves) will also have to be checked. As an immediate example (which I haven't implemented yet), monster encounters are also triggering events. The first time the player encounters certain monsters, for example, the game launches some expository (but hopefully humorous) dialog.

How Absurd, To Swallow a Bird
Right out of the starting gate, I ran into a bug with my dialog events. The first dialog wasn't firing. I tried using the timed-mode dialog instead, and it fired just fine... but it was skipping the first line of dialog (where Arianna says, "Okay, people, let's do this one by the numbers! I don't want a repeat of last time!")

The problem was that the dialog was firing BEFORE the UI had "awakened" and built the character portraits. My solution wasn't very elegant. If the UI wasn't available when a dialog event fired (which should only be a problem with the very first event - the one I was working with), it calls Torque's "schedule" function to reschedule itself for a quarter-second later.

More Flies!
The next type of event I needed to deal with is combat events. The first combat is triggered by the player approaching the first doorway. I was able to trigger my faked-up combat UI easily enough... that took only a few minutes to add a new event and a trigger.

But the point now is to make combat work "for real." For the immediate-term, I'm going to focus only on simple melee combat. No inventory-item usage, no feats, no spells. The player characters and monsters will be using default starting equipment only. The pus golem will be using its bare, pussy hands, with no special abilities.

Even with such a narrow goal, there is a ton of fun stuff to do to support it. This means the character system must be working. And the game rules system. And things like equipped armor and weapons. Some of this code has been written already, but only marginally tested. This is the heart of the game, and simple melee combat will not only exercise the code for bugs, but will also be a major playtest of the game system.

If it turns out not to work, I'm gonna have to go back to the drawing board in a big hurry.


(Vaguely) related thought-droppings:
* Dev Diary: The First Five Minutes
* Dev Diary: Stupid Is As Stupid Fights
* RPG Combat Design
* The Evolution of Computer RPGs


Join the Discussion on the Forum...

Labels: ,



Did you enjoy this post? Feel free to share it: del.icio.us | Digg it | Furl | reddit | Yahoo MyWeb



Links to this post:

Create a Link



<< Home

Powered by Blogger