GameMaking Guide for BAGS v0.1

Copyright 2005 M. Aaron Wadley

Created 2005-07-14 by M. Aaron Wadley <admin@cyberlizard.org>

This will eventually be a development manual for authors wishing to create 
Interactive Fiction games for BAGS.  

For greater detail about the syntax, you should take a look at the 
documentation available at www.beanshell.org.  Basically, the syntax is the 
same as Java, with a few tweaks.  The full-blown manual (when it's written) 
will contain more details, especially BAGS-specific objects and methods.

For now, let's take a look at the source for the sample game included with 
this distribution.  This source can be found in the 'wadley' subdirectory of 
the installation.

Here's a list of the files and their purpose:
bags.properties   - Core definition of the game
WadleyPreload.bsh - Any pre-game initialization or text to display goes here.
WadleyRooms.bsh   - Defines all the rooms and the connections between them.  
WadleyObjets.bsh  - Defines all the objects available to interact with.   
WadleyParser.bsh  - Custom code for parsing commands as well as custom verbs.
WadleyHelp.bsh    - Eventually, this will be for the help/hints system.

The first file to look at is called 'bags.properties'.  This is the core 
definition of a BAGS game.  It is relatively well documented and fairly self-
explanatory.  There are a number of properties defining options that we 
can specify.  I've included in the sample all of the options and their default
values.  

I'm sure you've seen the correlation between the *Implementation properties 
and the files for the game.  These files can be named anything you want, 
however I've found it easiest to name them with the form <game><function>.bsh  
The extension isn't strictly necessary either, it just makes it easier to 
identify BeanShell script files.

The next thing to look at are all the files defined in the *Implementation 
properties from 'bags.properties'.  These contain custom code specific to the 
game itself.  

Let's look into the WadleyRooms.bsh file.  The rooms form the world that the
player character will wander through.  You'll have to scroll down past all of 
the connections to reach the room definitions.  I'll explain connections in a 
minute.  

The first room definition you see is the FrontWalk.  This is the simplest 
room you can define.  It shows only the required elements.  Each room 
definition must at least include these.

The next definition is FrontPorch.  This is one of the more complicated 
definitions.  It shows several of the optional features.

Now let's look at Connections.  Back at the top of the file there is a whole
list of connections defined.  A connection is a link between two rooms.  It 
consists of a two locations, pointA and pointB, and two directions.  Look at
the first connection defined, the one with "Front porch" and "Walkway" in it.
It says that if you exit the Front porch to the south, you will enter the 
Walkway from the north.  And vice-versa.  Connections are inherently 
bi-directional.

Connections can get a little tangled.  I find it easier to draw a simple map
consisting of boxes for rooms and lines for connections to help me visualize
all the connections I need.

Next file to look in is WadleyObjects.  Here are all the objects that the 
player character can interact with in your world.  The first object defined is
called Stick.  This is the simplest implementation.  At the bare minimum, 
your objects need to implement these properties.

Ball is next.  It has a few more properties and a method called TAKE().  As 
you can probably guess, the TAKE() method is called when the PC tries to TAKE
the object.  This example shows that the PC's score will go up by 5 points if
they TAKE the ball.

There are two kinds of properties that an object (or a room, for that matter) 
can have: builtin and custom.  Builtin properties are those that the BAGS 
engine recognizes and uses under the covers.  Custom properties are fields 
that you define and are only used by your custom code.  You can add any custom 
property that you want to your objects.  

In the Ball object, scored is a custom property.  It is used so that we only 
score points the first time we TAKE this object.  canBeTaken is a builtin.  
Its default value is false, so if you don't define it, the BAGS engine will not
let the PC pick up an object.  See the appendix for a list of builtin 
properties for objects and rooms.

How are you doing, are you keeping up?  I realize that there is a lot of info
missing in this manual, but rest assured that I will be adding more and more 
as BAGS development continues.  Besides, this manual is for version 0.1.  
Everything will probably be completely different for version 0.2.  Doesn't
that just give a warm and fuzzy feeling? ;-)

OK, now that we've had a little breather, let's take a look at 
WadleyParser.bsh.  This is where any special command processing you want to do
will take place.  You'll notice at the top that there's a line that says 
'source("WadleyHelp.bsh");'  You have the ability to source any additional 
bsh files that you want to help keep things more organized.

Anyway, within the CustomParser object, the first thing you will encounter is
the customVerbs HashMap.  Don't worry if 'HashMap' means nothing to you.  It
is just Java's way of storing key-value pairs.  In the BAGS world, you add
key-value pairs like this: customVerbs{"key"}="value";

You'll notice that there are three keys, but two of them have the same value.
This is how we implement synonyms for verbs.  In this case if the player types
either CUSTOM or CUST, the same verb, CUSTOM, will be executed.  That way you
don't have to define handlers for all the synonyms that a command might have.

Each custom verb that you define must have a corresponding method with the 
following form: execute_<someverb>(game, theCommand) {}.  Take a look at the 
execute_CUSTOM method in the file.  This method must return true or false.
This lets the BAGS engine know if the command was handled or not.  Any kind of
logic you want can go in here.  There's some tricky stuff going on in the next
method, execute_KNOCK.

I guess that now is a good time to talk about Commands.  A Command in BAGS has
several properties; verb, subject, subjectAdjective, modifier, target and 
targetAdjective.  A verb defines a command, but there is more to it than that. 
Suppose a player types 'throw ball'.  Obviously 'throw' is the verb (remember 
English class?), but what about 'ball'?  In BAGS, 'ball' would end up in the 
subject field of the command.  How about 'throw ball at door'?  Well, 'throw'
would still be the verb, 'ball' the subject, but now 'door' would be in the
target field.  'at' would now be the modifier.  If we had typed 'throw ball
over door', 'over' would be the modifier.  To go further, let's try 'throw 
the ball at door'.  The result would be the same as before.  'the' would be
ignored.  You could also say 'throw the ball at the door' and have the same
result.  

Now I'll introduce a twist.  What do you think would happen if I typed 
'throw the red ball at the door'?  The same thing as before, only now the 
subjectAdjective would be 'red'.  This is useful for differentiating between
two objects of the same type.  If the PC had two balls in her inventory, one 
red and one blue, and she typed 'throw ball', the system wouldn't know which 
one to throw.  For now, to handle this situation, custom code would have to 
be written in the execute_THROW method of your custom parser.  Eventually,
I'd like the BAGS engine to recognize a potential conflict and ask the user
for more details, but for now, you have to do it by hand.  Sucks, I know, but
I'm working as fast as I can.

Now that we understand Commands, we can see how our logic can be manipulated
in our custom parser based on what the user typed.

Whew!  OK, the last file to look at is called... wait a minute, there's no
files left.  We covered them all!  

To sum up, I realize that this is a really rough guide, but please take pity
on me and understand that this is just the first attempt.  Mostly a rough
draft.  Future versions will almost certainly change a great deal of this, so
I wouldn't spend too much time writing enormous IF games with this, but if 
you are so inclined (and you probably are since you managed to finish this 
whole guide), please take a stab at making a simple game and let me know your
thoughts, ideas, criticisms, comments; any feedback would be most appreciated.

M. Aaron Wadley <admin@cyberlizard.org>
