Adventure Game Studio v2.31 (c) 1999-2001 Chris Jones

Adventure Game Studio (or AGS for short) allows you to create your own
point-and-click adventure games, like the older Sierra games (Space Quest 4,
King's Quest 5-6, etc). It includes an easy-to-use Integrated Development
Environment, and you do not need any programming experience to make a game
using it.
For more advanced users, AGS supports scripting, where you can write a sort
of program which allows you to have great control over the game.
By default, AGS will create Sierra-style adventure games, with the pop-up icon
bar, and right-click cycles through the modes (walk, look, use, speak).
However, you can change the interface completely using the Interface Editor
to make Lucasarts-style or any other type of interface you want.
AGS handles many parts of the system for you, like load/save game, character
movement and object animations.

(You may have known this program previously as the Adventure Creator: the last
version was Adventure Creator v1.14. The reasons for the name change are
described in the "Upgrading from v1" section of this document).

AGS system requirements (for 256-colour games):
 * 486 or higher processor (DX4/100 or better recommended)
 * VGA display (SVGA optional)
 * at least 16 Mb RAM, but 32 Mb is recommended
 * MS-DOS 5.00 or higher, Windows 95/98/ME or Windows 2000.
 * Games made for Windows require DirectX 7 or higher.
 * About 20 Mb free disk space (may need more or less, depending on the game)
 * Sound card optional (supports Adlib, Sound Blaster and General MIDI for
   music; Sound Blaster and ESS Audiodrive for digital sound).

Hi-colour games also require the above, but in addition:
 * Pentium or higher processor, at least 233 Mhz
 * SVGA display with VESA driver
 * 32 MB RAM
 * 1 MB Video RAM required, 2 Mb recommended

This is the text version of the manual. An HTML formatted version is also
available.
This document is set up with a quick-search facility, as long as you are using
the VIEW program to read it. Press F7 now for a list of sections.

1. Contents
-----------
This document contains the following sections:
 1. Contents (this is it)
 2. Using the run-time engine
 3. Tutorial - introduction to how to make a simple game
 4. Other features - not covered in the tutorial
 5. Upgrading from AC v1
 6. Reference - interaction events & commands, text script commands
 7. Troubleshooting
 8. Contacting the Author
 9. Credits

2. Using the run-time engine
----------------------------
The engine (also called the "interpreter") is what runs your game and is what
the end player will use.
If you are using the default interface, then you use the right mouse button to
cycle between the available 'modes', and the left button to use the current
mode on the mouse position. You can also move the mouse to the top of the
screen to bring up the icon bar where you can directly select a mode.
To exit the engine, press Ctrl-Q. You can save your game position using F5
and restore with F7.
The controls described above work with the default setup; however, you can
customize your game to use a different interface and shortcut keys.

2.1 THE DEMO GAME
The first thing you'll probably want to do is to run the demo game. This
short game (made up of 9 screens) will show you some of what AGS can do. It
doesn't demonstrate all the features, though - you'll find about them for
yourself. To run the demo, type DEMO and press return (or double-click the
DEMO.BAT file in Windows).

2.2 WINDOWS 2000 AND WINDOWS XP ISSUES
I thought I'd better bring this up quite early on because it's important -
if you are not using Windows 2000 or XP then skip this paragraph.
The AGS engine comes in two flavours - a Windows DirectX version and a DOS
version. The DOS version runs on DOS (obviously), Windows 95, 98 and Me.
The Windows version runs on Windows 95, 98, Me, 2000 and XP.
However, the AGS Editor is currently DOS-based. This may work for you in
Windows 2000, or the screen may go blank when you try to run it - this
depends on your graphics card. If it doesn't work I'm sorry but there's
nothing I can do until the Windows editor is finished (which will be quite a
while). Currently I have a duel boot between Windows 95 and 2000 to allow
me to test all versions.

2.3 RUN-TIME ENGINE SETUP
By default, the engine will automatically detect the player's sound card, and
use the low-resolution 320x200 display mode. However, the player can override
the autodetection if it cannot detect their sound card. To run the setup
program, type SETUP and press return.
In the Setup program, the user can choose their sound effect card (used for
sound effects like WAVs, and also for MOD and XM music) and their MIDI music
card (used for MIDI music only).
They can also choose what screen resolution they would like to run the engine
using. The available choices are 320x200, 640x400 and 960x600. The higher
resolution gives a better quality picture in the game, but slows the game down.
Generally, use the 320x200 mode for computers which are Pentium-100 or slower.
The 640x400 mode is the best choice and will work with Pentium-120 or higher
computers. The 960x600 mode should only be used with very high-spec machines
(ie. Pentium-II and better machines).
Note however, that the picture quality is only as good as it was drawn, so if
all the scenes in your game are drawn at 640x400, then using the 960x600
resolution will not help - it will just slow the game down.

2.3.1 THE WAVETABLE SYNTH MIDI DRIVER
New in v2.02 is a MIDI driver called "Software wavetable synth". This uses
a MIDI patch set to play MIDI music through the digital sound driver, thus
meaning that the music will sound the same on all sound cards. This is
particularly useful for standard Sound Blaster cards, where the built-in MIDI
chips on the card sound very crappy.
This driver is never autodetected; the player must choose it specifically
by running the Setup program. Note that since it uses the digital driver to
play the sound, you must have a digital sound card installed in the system
for it to work. Also note that it will slightly slow down the game over just
using a standard MIDI driver.
To use the wavetable driver, you need to get the General MIDI patch set, which
you can download from the AGS website (it's 1.5 Mb, that's why it's only
available seperately). If the patch set is not found in the AGS directory,
then Setup will not allow you to choose the driver.


3. Tutorial
-----------
This section will introduce you to the AGS by leading you through how to
create a simple game.

3.1 CREATING YOUR FIRST ROOM
In adventure games, the character moves from one screen to another, and each
screen consists of a pre-rendered background drawing with objects  and
characters on top of it to give interaction. A screen is also called a "room".
First, you need to draw a background scene for the first room. You do this in
your favourite paint program. The size must be either 320x200 or 640x400, and
you must make sure that the colour depth is set to 8-bit or 16-bit colour.
Save it as a BMP or PCX file (TIP: a PCX will give smaller file sizes since
PCXs are compressed, whereas BMPs are not).
Load the AGS editor (type ROOMEDIT and press return). It will ask you which
game you want to edit. Highlight "NEW GAME", then click OK. Here you type the
directory name for the game (up to 8 characters max), and press return. You
have now created a new game.
Choose the "ROOM" tab if it is not already displayed (The tabs are the four
buttons along the bottom of the screen). On the left hand side of the screen,
there are five other buttons, called "Setup screen" down to "Objects". By
clicking one of these, you choose which sub-mode the editor is in.
NOTE: Don't let the name "RoomEdit" fool you - it is, in fact, your integrated
environment for development of the whole game, not just the rooms.

First of all we need to import a background scene for the room. Click on
"Setup screen" and then choose the "Load scene..." button on the main panel.
You will see a file selector where you should now find the background scene
graphic which you drew. Click OK, and it will be imported.
(If you get a message asking you what resolution the picture is drawn for,
choose the appropriate button. For example, if you have drawn a 640x400-sized
scene, then click "640x400").
You will see the top half of the picture, on the screen, along with two scroll
bars which you can use to see the rest of it.
NOTE: The Editor always runs in the 320x200 graphics mode. If you have drawn
a high-resolution picture at 640x400 it will seem to have been reduced. This
is only in the editor and you will see the proper picture in the actual game.
You can check that it was imported properly by clicking the "Full screen"
button which gives you a preview at the proper resolution.
NOTE: The Room Editor has on-line context sensitive help (and now with a new
graphical help reader!) Press F1 at any time.

3.1.1 WALKABLE AREAS
Now that you have the background scene, you need to tell the game where the
player character is allowed to walk. You do this using walkable areas. Choose
the "Walkable areas" mode from the left-hand button list.
Everywhere that the character's feet are allowed to walk, you must make
walkable. Adding walkable areas works in a similar way to most paint programs:
you use three tools (line, fill and freehand) to draw them.
You will probably want to start off with the "Line" tool - click the button
in the main panel. Now, draw round the outline of the walkable areas on the
screen. To draw a line, click the left mouse button where you want to start it,
then hold down the button and drag the mouse to the finish of the line, where
you should release the button. Once you are sure that the area is completely
enclosed by blue lines, choose the "Fill" button and click inside the area -
it should be filled in. If the entire screen is filled blue, you didn't contain
the area properly. To remove the area, choose the "Wipe colour" mode and then
click on the area. Now, start over again.

3.1.2 WALK-BEHIND AREAS
The next job you need to do is to define the walk-behind areas. These areas,
also called "priorities", tell the game where the character needs to be drawn
behind the background. For example, in the three bottom screens of the demo
game, the player can walk behind the fence.
Choose the "Walk-behind" mode from the left-hand list. You add walk-behind
areas in a very similar way to the walkable areas - in fact, you have the same
three drawing tools.
Once you have finished, you need to define the base-line for the area. This
is a horizontal line which tells the game at what level the character must be
in order to be drawn behind the area. For example, when the man is standing
in front of the street lamp he must be drawn in front; when he is behind it,
he must be drawn behind. Click the "Base-line" button, then click the mouse
on the scene at the base of the walk-behind area. When the character's feet
are below this line, he will be drawn in front of the area; when his feet are
above the line, he will be drawn behind the area.
You may have noticed a window on the screen titled "Editing colour". By
default, you have been drawing blue walk-behind areas onto the screen. This
is fine for one area, but what if you have two different walk-behind areas on
the screen? They'll need different base-lines, won't they. You can change the
colour you are drawing by clicking the up and down arrows in the "Editing
colour" window. Each colour has its own base-line, which effects the areas
drawn in that colour.

3.1.3 TRYING OUT YOUR GAME
Now that you have a semi-complete first room, it would be a good time to test
it out. Go back to the "Setup screen" mode and click "Save room...". This
will save your work to disk. In the file selector, click near the top on the
line which displays the current directory, then type in the name you want to
give the room file. The game uses files called ROOMx.CRM, where x is the room
number, and the player starts in room 1, so type ROOM1 and press the OK
button.
Now, go to the "Game" tab (bottom of the screen), and click the "Save game"
button. This will create all the files necessary to run the game. Click
the "Quit" button to exit the editor. Your game is created as an EXE file
with the name you entered at the very beginning. For example, if you typed
MYGAME as the name for the new game, it will be MYGAME.EXE. Run this to test
your game.
You should see your first screen, with the man on it. Walk around the screen,
checking out any walk-behind areas you added. If the man won't move anywhere,
he probably hasn't started on a walkable area and therefore can't move.
Press Ctrl-Q to exit the engine, then load up the Room Editor again. Choose
the "Load room..." button and load in the ROOM1 you saved earlier.
(If you need to change where the man starts, choose the "Visual" tab, then
the "Characters" sub-mode, then click on the "AT 260,190" button on the right
hand side of the screen. Here you can type in the co-ordinates for where you
want the man to start. To get the co-ordinates, use the "Ask position"
function in the Rooms, Setup screen mode).
Whenever you want to test your game, ALWAYS save the room you were working on,
and then save the game before exiting the editor.

3.1.4 HOTSPOTS
Your room is now almost complete - except for one thing, interactivity. As it
is, the player can't look at anything, talk to anything, or do anything.
A hotspot is an area of the screen where the game will react if the player
clicks the mouse there. For example, a wall could be a hotspot, a fence could
be a hotspot, and so on - in fact, every part of the screen can be one hotspot
or another.
Choose the "Hotspots" sub-mode from the Rooms tab. As with the walkable areas
and walk-behind areas, you draw hotspots using the standard three drawing
modes. The different colours this time represent the different game reactions:
the player clicking on a hotspot 1 area will cause a certain response;
clicking on a hotspot 2 area will cause a different response.
Once you have drawn the hotspots on, you need to define what happens when the
player interacts with them. You do this one hotspot at a time. Use the up and
down arrow buttons to make sure that colour 1 (dark blue) is the current
hotspot. Now, click the "Interaction" button.
3.1.4.1 INTERACTIONS
The interaction window is split up into two parts: the bottom part lists all
the available events on the hotspot which you can add a reaction for. The top
part shows the reactions you have added. To start with, the top window is
empty. To respond to an event, click on the event's name in the bottom window.
For example, we want to display a message when the player LOOKs at our
hotspot 1. So, click "Look at hotspot" on the bottom list. It will be added
to the top list, along with three other columns - Score, Command and Data.
The Score column allows you to give the player points when the event occurs,
and note that this will only happen the first time they do it, so they can't
keep getting more and more points. We don't want to give our player a score
for just looking though, so we'll leave it as 0.
The Data column is used to provide additional information to certain commands;
otherwise you can just leave it as 0.
The Command column defines what happens when the event occurs (in this case,
when the player looks at our hotspot). Click on the "(Do nothing)" and a menu
appears, with all the possible responses to the event. What these all mean
is listed in section 6.2. We just want to display a message though, so
click the "Display message %d" option. The "%d" simply means that you will
have to type in a number to replace it - in this case, the message number.
On clicking, a window pops up asking you for the message number you want to
display. (We can't just type the message in there and then; we'll do it in a
second). Since this will be our first message, and since message numbering
starts at 0, type in 0 and press return.
3.1.4.2 MESSAGES
Each room has its own set of messages. These are the strings that can be
displayed during the game. Choose the "Message editor" button at the bottom
of the interaction window. The screen will switch to text-mode and you will
see displayed "No messages". To create one, press A. Now, press enter to
edit it. Type in a message appropriate to your hotspot, for example,
This is a brick wall. Nothing more exciting than that.
and press return.
Note that pressing F2 toggles "Display next message" on and off. When this
is on, the next message will be displayed after the player has clicked to
remove this one. This feature is useful for conversations and long
descriptions. We won't use it now, however, so leave it set to "No".
Now hit ESC to leave the message editor. Click OK to exit the interaction
window.
3.1.4.3 WALK-TO SPOTS
You may have noticed on the Hotspots screen, a button called "Walk-to". This
allows you to set a position for each hotspot where the character will walk to
whenever the player interacts with the hotspot. This is like the way the
Lucasarts games like Monkey Island (tm) work. If you set a walk-to point, then
whenever the player clicks interact or talk on the hotspot, the main character
will first walk to that point before the relevant event is triggered.
If you want, the man can also walk there when the LOOK mode is used - this
option is configurable in the Game tab, "Main" sub-mode.

3.1.5 SCREEN EDGES
Each room has four "edges". The edges define how near to the side of the
screen the player needs to go for him to be considered to have left the
screen. More precisely, when the man passes an edge he triggers the related
event in the room interaction screen.
Edges are the usual way that room changes take place - when the man walks off
an edge, the game responds with a "Go to screen" command to send him to a new
location.
To view the edges, go to the Room tab, "Setup screen" sub-mode, then click
the "Edges" button. The four edges will be displayed as yellow lines on top
of the background. To move an edge, click the left button on it and drag the
mouse.
To set what happens when the character walks off an edge, click the
"Interaction" button on the "Setup screen" tab. This contains four events,
called "Walk off top", "Walk off bottom", and so on, which are triggered when
the man passes the relevant edge. This interaction window also contains some
other useful room events.

3.1.6 OBJECTS
Objects, also known as "sprites", are images on the screen which, unlike the
screen background, can move, change and disappear. You use objects for things
which the player can take (so they disappear) and for things on the screen
which you want to animate.
As as example, let's say you want to have a key on the floor of your room
which the player can take. Go to the Rooms tab, "Objects" sub-mode. Now, click
the "New object" button. You now click onto the screen where you want the
object to be added. Don't worry if you don't get its position right, you can
move it later. The object will be added as a blue cup.
The first thing we want to do is change the look of the object - obviously, we
want a picture of a key. Click on the picture of the cup near the bottom-right
corner of the screen. When you do, you will be presented with a screen which
shows all the sprite graphics available. There is a picture of a key on the
top row, so click on that. (You can add your own graphics to this list; we
will describe how to do that later).
If you want to move the object, click the "Move objects" button. Then, click
and drag the left button on the object to move it.
Lastly, we need to define what happens when the player interacts with the
object. Click the "Interaction" button. This is almost identical to the way
it worked with the hotspots (see section 3.1.4.1).
You may have noticed a couple of other buttons on the Objects screen, called
"Base-line" and "Object is on". Normally, the base-line for an object is at
the base of the object (the baseline is used for front-to-back ordered drawing
of the graphics). However, in some cases you may want to override this - for
example, if a poster is lying flat on the ground, you wouldn't want the man to
walk behind it. You can override the baseline for an object by clicking the
"base-line" button and clicking on where you want the base to be (near the top
of the screen would solve our poster problem).
Normally, you want the objects to be visible on the screen to begin with.
However, in some situations you may not want the object to appear until later
on in the game. To have the object start the game "off", click the "Object is
on" button to toggle it. You can switch the object on in the game using the
"Turn on object" command.
NOTE: The game's speed is directly related to the number of objects on the
screen. Although you probably won't notice it on a Pentium, a room with 10
objects will noticeably slow down on a 486.

Now, we have a fully-working first room. Follow the procedures we did in
section 3.1.3 to try it out.

3.1.7 ROOM OPTIONS
In the "Setup screen" mode, you can set a few room options by clicking the
"Options" button. This screen allows you to configure some room-specific
things. To change an option, left-click it.
 * Play music on room load - if set, then the background music will be
   changed to the music you specify here. See section 4.1 for information
   on the music and sound support in AGS.
 * Main character visible - normally TRUE, if you set this to FALSE then
   the main character will not be visible on this screen. This is useful for
   close-up control panels, and cutscenes which the main character is not
   part of.
 * Main character view - allows you to change the main character's view
   number for this screen only. This is useful if you want, for example, an
   overhead map screen, so the character should have a birdseye-type view.
   The character's view is set back to normal when they leave the screen.
 * Music volume - allows you to change the volume of the background music
   for this screen. For example, as the player approaches a bar, on successive
   screens the music could get louder.

3.2 EDITING GAME SETTINGS
Now that you know how to create a room, it's time to set up the game-wide
settings. These include inventory objects, global messages, palette setup
and other things which do not depend on individual rooms.

3.2.1 PALETTE SETUP
The first thing you need to do when you create a new game is to decide whether
you want to use 8-bit (palette-based) colour or 16-bit (hi-colour).
If you want to use 16-bit colour, then go to the Game tab, "Palette" mode,
and click the "Make game hi-color" button. This will convert your game to
use hi-colour from now on. You can still use 256-colour backgrounds and
sprites if you want to, but the engine will only run in a 16-bit colour
resolution, thus slowing it down. See section 3.2.11 below for more info on
the hi-colour option.
If you want to use 8-bit (because it runs faster), you need to set up the
palette. This is because all sprite and background scene imports rely on the
palette setup to be the same.
Choose the Game tab, "Palette" sub-mode. Here you will see the 256-colour
palette displayed in a grid. Most of the slots are marked "X" - these are the
slots reserved for the background pictures, and will be different in each
room. The other colours will be as they look here for the entire game. These
fixed colours allow things like the main character graphics, which must be
displayed on more than one screen, to work.
If you want, you can assign more or less colours to the backgrounds. To toggle
the background assignment on/off, click on the slot, then click the button
"background" (or "un-background") to swap the slot's status.
IMPORTANT NOTE: You must set up the palette as you want it before you start
making your game - if you change it later, you will have to re-import all the
sprites and background scenes.
You can select multiple colour slots by clicking on the first slot, then
shift-clicking on the last slot in the range you want to select. You can then
toggle the background status of all the selected slots at once.
The "Export pal" button exports the entire palette to a .PAL or PCX file which
you can then use to read back into the Editor in a different game. If you
choose to export to a pcx file, then a screen shot of the Palette Editor will
be saved as the picture. This way you can see all the game-wide colours in
the file.
The "Import pal" button replaces the selected palette entries with those
entries from the PAL or PCX file you choose. It can read standard 768-byte
PAL files, SCI palette resources (renamed to extension .pal) and JASC PSP
palette files.

3.2.2 INVENTORY
Most adventure games allow the player to carry a set of objects, which he can
then use to solve puzzles. Adventure Game Studio makes this inventory easy
for you to manage.
Every inventory item which the player may carry during the game at one time
or another is listed under the Game tab, "Inventory" sub-mode. Here, each item
also has a number which you use in interactions to identify the object.
The left hand side of the screen lists all the items in the game.  On the
right is the graphic used for the object in the inventory window. To change
this, left-click the picture, then select the new graphic from the dialog
which appears.
To change the object's name, click the button marked "Name" in the bottom part
of the screen. If you want the player to start the game with this item in his
inventory, check the "Player starts with this item" check-box.
To create a new item, click the "New item..." button. You will be asked for
the new item's name, and then it will be assigned the next available number.
The last thing to do with the inventory items is to define their interactions:
what happens when the player manipulates them in the inventory window. Click
the "Interaction" button, which brings up a window which works identically
to the hotspot interactions (section 3.1.4.1). The available events are
described in the reference section 6.1.4.
NOTE: Several limitations apply to the commands you can use in the Inventory
interactions. This is because they must run from all rooms, and so cannot
have any room-specific commands. In particular, you cannot use the "Run
animation" or "Run graphical script" commands, and if you use a "Display
message" command, then it must display a global message (see section 3.2.4,
below).
To give the item to the player during the game, you use the "Add inventory"
or "Remove obj, add inv" commands. The inventory number required by these
commands is the item number from the list described above.
NOTE: Each character in the game carries their own set of inventory items.
This means, if you want to create a game like Day of the Tentacle, where the
player can control three different characters, each character will have a
seperate inventory. All inventory commands always operate on the *current
player character*.
You have two choices about how the inventory is displayed to the player.
Unfortunately, due to the way the inventory works, the two options are
built-in to the engine and are not customizable.
The default option is the Sierra-style pop-up inventory window, which is
popped up by clicking on the Bag icon on the icon bar (which uses the text
script InventoryScreen function to display it). You can also have the current
inventory item displayed in its own button on the icon bar by creating a
button on the GUI and setting its text to  (INV)  which stretches the item
picture to the button size, or  (INVNS)  which draws the inventory item
picture straight onto the button with no resizing.
The other option is a Lucasarts-style inventory window. To use this, you
will need to edit the interface to add it, so I will explain this later on.
While you are starting off with AGS, it is recommended to use the supplied
standard Sierra-style inventory window.

3.2.3 USING YOUR OWN SPRITE GRAPHICS
When you were choosing the graphics for the object earlier in this tutorial,
you probably noticed that most of the graphics available didn't look up to
much. This is no problem, because you can import your own graphics using
the Sprite Manager.
Go to the Visual tab, "Sprite mgr" sub-mode. Here, you will see the complete
sprite set for the game. There are two ways to import your graphics - either
overwrite an existing slot with your graphic, or create a new slot for it.
The "import" button overwrites the currently selected slot; the "import new"
button will create a new slot for the graphic.
When you click either of these buttons, the file selector appears, where you
can choose a BMP, PCX or GIF file to import. The graphic you choose must be
at the same colour depth as your game (ie. if you are using hi-colour
backgrounds, your sprites must be hi-colour, and vice versa).
The picture is displayed on-screen. The mouse cursor changes to a rectangle,
in which you should enclose the portion of the graphic which you want to
import. You can change the size of the rectangle by clicking the right mouse
button and dragging the mouse. When the rectangle is correctly positioned,
left-click. You can also import the entire picture by pressing Enter.
You may well find that the colours on your graphic look slightly strange in
the Room Editor. This is because the sprites are only allocated, by default,
the first 41 of the palette colours (see the palette section 3.2.1 above), so
your graphic will be remapped to this much smaller palette. If you find that
many of your imported sprites look strange, you can increase the number of
colours assigned to sprites, at the expense of background colours (again see
the section above for information on how to do this).
If your sprite will only be used in one room then alternatively you can
use the "use background palette" option, which will remap your graphic to
the palette of the room currently loaded, giving much better results. Note,
however, that if you do this, and then try and use the sprite on another
screen, its colours will most likely be screwed up. To use the room palette,
check the "use bkgrnd pal" check-box. Make sure to un-check this box before
you import any other sprites.
NOTE: The transparent colour used by AGS is palette index 0 (for 256-colour
sprites) and RGB (255,0,255) for hi-color. Any pixels you draw on imported
sprites in these colours will be transparent.

You can group imported sprites into folders. This prevents the main sprite
list from becoming very long (and you can only have 120 sprites per folder
anyway). By default, the Sprite Manager displays the Main folder, which
contains some graphics and a sub-folder called "Defaults". Folders work the
same way as Windows folders (or DOS directories) - they can be nested inside
each other, and in every folder except the main one there is a "parent" link
which will take you back to the folder above.
Note, however, that at present you cannot move sprites between folders so
they are stuck in the folder in which you create them. (Imported sprites
are placed into the currently displayed folder). Also, you cannot delete
sprites or folders.

AGS now has the ability to import tiled sprites from a single bmp/pcx file.
To do this, draw all the frames of your animation at equal spacings apart
on the source bitmap. Then, when you click "Import" in roomedit and have
selected the file, press "T". This displays a grid and allows you to position
it correctly over your graphics. Then, click the mouse button and the grid
vanishes, but now you can drag the mouse to resize the grid out to encompass
the sprites you want to import. Once it's the right size, click the mouse
again and they will be imported.

3.2.4 GLOBAL MESSAGES
While each room has its own set of messages ("local messages"), in some
situations you need to be able to display a message from more than one room,
or in a global game interaction which is not related to a room. For this
purpose global messages are provided.
Choose the Game tab, "Gl. messages" sub-mode. Here you are presented with
a list of the 500 available global message slots. By default, they are all
empty except messages 996-999 which contain the default messages for actions
on the player character. Global messages are numbered between 500 and 999 so
that they are not confused with local room messages.
To display a global message, simply use its number in any "Display message"
command. If you set the Data column, then the message will be displayed as
speech text from that numbered character (check in the Character editor for
the number of each character). If the Data column is zero, the message is
displayed in the normal dialog box.
You can include a couple of variables into global (and local) messages. You
do this by inserting special tokens into the message. When the message is
displayed in the game, the engine replaces the token with its value:
 token   replaced by
 @INx@  number of inventory item x that the player has
 @GIx@  the current value of GlobalInt x (used with SetGlobalInt/GetGlobalInt)

3.2.5 INTRODUCTION SEQUENCES
You can easily add intro, outro and cutscene sequences to your game. There
is no specific function to do these, but using the provided animation and
script commands you can create almost anything you might need.
Normally, the game will start in room 1. However, you can change this to any
room you want. Go to the Visual tab, "Characters" mode. Make sure that the
main character is selected in the list on the left. You will see on the right
hand side "Start in room:" followed by "Room 1". This is the starting room
for the player character, and it is this entry that decides which is the first
room loaded. If you set it to room 0, then a file named INTRO.CRM will be
used (not ROOM0.CRM as you might think). This is for backward compatibility
with AC 1, but it is also good practice and it is suggested that you use this
feature.
Set the starting room to room 0. Now, when you run the game, the intro will
be the first room loaded. In this room, you will probably want to disable
the main character (if you want a logo graphic up first). Remember, you do
this through  Setup Screen -> Options -> Main character visible.
TIP: The starting room facility is also useful when testing your game - you
can make the game start in any room, at the point where you are testing it,
rather than having to keep playing the game through to get there.
As an example, let's make your logo stay for 5 seconds and then go on to the
next screen. The graphical script's timer functions would be ideal here.
(You may want to read the graphical script documentation, section 3.3.3,
before continuing here).
Choose  Setup Screen -> Interaction. Now, add the "Player enters screen"
event, and set the command to "Run graphical script". Click the "..." to edit
the script, and add a single command, "Set timer to %d loops". There are
about 40 loops per second, so replace the %d with 200.
Now, press ESC to exit the graphical script editor. You are back at the
interaction screen. Add the "Repeatedly execute" event. Again, set this to
run a graphical script, and click the "..." button. For this script, we will
need the "If timer expired" command, so drag it in from the left. Remove
the "Display message" commands which it gives you, and add a "Go to screen"
command under the IF statement. Choose whatever screen number you want. You
could go to screen 1 to start the game, or to another screen to have a longer
introduction sequence. It's up to you.

3.2.6 ANIMATIONS
In most games you will use some sort of animation during the game, whether
it be a flag waving in the breeze or the man bending over to pick something
up. The term "animation" refers to the ability to change the look of, and
move, objects.
Animations in AGS are managed using Views. A "view" is a set of one or more
"loops". A loop is a set of frames which, when put together, give the effect
of movement. Each frame in the view can be set a graphic and a speed.
Go to the Visual tab, "Views" sub-mode. This is the View Editor. Here you will
see the main character's walking view.
Click the "New view" button to create us a new, empty view. Now, click the
down arrow button until the currently displayed view shows our newly created
one.
Each loop is displayed horizontally with its number at the left hand side,
frames going out to the right. To add a frame, click the grey "New frame"
button. To delete a frame, right-click it.
To change a frame's graphic, double-left-click it. The sprite list screen
will be displayed (you may remember this from the Object graphic selection)
where you can choose the graphic you want to use for this frame.
Above each frame you will see "SPD:0". This is the frame's *relative* speed,
which you can change by clicking on the word "SPD:". The larger the number,
the longer the frame stays (ie. the slower it is). When the animation is run,
an overall animation speed will be set, so the actual speed of the frame
will be:  overall_speed + frame_speed  . Note that you can use negative
numbers for the frame speed to make it particularly fast, for example setting
it to -3 means that the frame will stay for hardly any time at all.
You run an animation by using the "Run animation" interaction command or the
text script animation commands. If you use the "Run animation" interaction
command, you then click the "..." button to edit the animation. The animation
editor is very similar to the graphical script editor (see section 3.3.3),
but it has different commands available.
To animate an object, you first of all need to set the object's view to the
correct view number (use the "Set object view" animation command or the
SetObjectView text script command), and then use the "Animate using loop"
animation command or the AnimateObject text script command to actually start
the animation. The Animation Editor commands are described in section 6.8.

3.2.7 CHARACTERS
Adventure Game Studio makes it easy to add your own non-player characters
into the game. A character is similar to an object, except that it can change
rooms, maintain its own inventory, and take part in conversations (more on
these later). It can also have its own custom animation speed and movement
speed.
Go to the "Visual" tab, "Characters" mode. You will see on the left of the
screen a list of all the characters in the game, with "NEW CHARACTER" at the
end of it. To create a new character, select "NEW CHARACTER" from the list,
then click the "NAME" button in the bottom part of the screen to change its
name to whatever you want to call your character. By doing this, a new
character slot is created.
You will see that there are a lot of options which you can set for each
character. First of all, the "This is the player character" check-box allows
you to change which character the player will control at the start of the
game. When the game starts, the first room loaded will be this character's
starting room. By checking this box for one character, it will be de-selected
for any other character which was previously set.
Secondly, the "Ignore scaling" check-box allows you to specify that this
character will not be stretched or shrunk in scaling areas of the screen. This
could be useful if you have a character who always stands still in the same
place, and you want the graphics on-screen to be the same size as you drew
them, even though he is standing on a scaling area.
The "No interaction" check-box tells AGS that you want the character to be
invisible to all the interaction parts of the game. This is like the way the
main character works in Lucasarts games - if you move the cursor over him
or click to look, speak, etc, then the game will ignore the character and
respond to whatever is behind him.
To set which room this character starts in, click the "Room 1" button on the
right hand side of the screen, and type in the new room you want him to start
in. If you set this to room 0 for the player character, he will start in the
intro screen, INTRO.CRM (see section 3.2.5 for information). You can set the
character's location within this room by clicking the "AT 160,160" box and
typing in the X,Y co-ordinates you want him to start at. These co-ordinates
should be the middle of his feet. (You can find out the co-ordinates of a
screen point using the "Ask position" option in the Rooms, Setup Screen tab).
The "Default view" is where you set what the character looks like. You must
create a view in the View Editor (described in section 3.2.6, above), and this
view must have either 4 or 8 loops. If you use 4 loops, then when walking
diagonally the closest straight direction is used for the graphics. Each loop
is used for the character walking in one direction, as follows:
 Loop 0 - walking down (towards screen)
 Loop 1 - walking left
 Loop 2 - walking right
 Loop 3 - walking up (away from screen)
 Loop 4 - walking diagonally down-right
 Loop 5 - walking diagonally up-right
 Loop 6 - walking diagonally down-left
 Loop 7 - walking diagonally up-left
Once you set this option, you should see a preview of the character walking
around in the top part of the screen.
To change the rate at which the character animates, click the "Anim spd"
option. Here, a smaller number means faster animation. Note that this does NOT
effect the speed at which the character actually moves when walking.
The "Move spd" option allows you to control how fast the character moves when
walking. Here, a larger number means he walks faster.
The "Talk clr" option on the right of the screen specifies which colour is
used for the text when this character is talking. It effects both messages
displayed with "Display message" commands which are set to that character,
and also conversations. You can find out the colour for each number by going
to the Game tab, "Palette" mode.
The "Idle view" button allows you to set an idle animation for the character.
To do this, create a new view, with one or more loops of the character idle
(eg. smoking, reading a book, etc). Then, click "No idle view" and type in
the view number. If the player stands still for 20 seconds (you can change
the timeout with the SetCharacterIdle text script function), then a random
loop from the view will be played.
In the very bottom-right of the screen is a button called "Script Name". This
sets the name which the character will be referred to by in text scripts and
in conversation scripting. The difference from the main Name of the character
is that the script name may only contain letters A-Z.
To set what happens when the player interacts with the character, click the
"Interaction" button. You will be presented with the (by now familiar)
interaction window. NOTE that, as with Inventory interactions, you may NOT
use the "Run animation" or "Run graphical script" commands, or display a local
message. Basically, you need to display global messages or use text scripts
to handle character interactions.
You can also set a talking view for the character. To set one, click the
button beside where it says "Talking view:". If you set a talking view, then
that view will be used to animate the character while they are speaking. You
should generally have about 2-3 frames in each loop (the loops are used for
the same directions as in the main view).
New in v2.05 is support for exporting your characters. What this means is that
you can export a character to a file, and then import the file into a
different game - so you can share the same main character between games, or
create one for distribution on the internet. When you click the "Export char"
button, you will be asked what you want to call the file, so type a short
name and press ok. The entire character setup, and graphics, will be exported
to the file. This includes the character's walking and talking graphics.
Then, in RoomEdit (with any game loaded), press the "I" key. The file selector
appears, where you should find the CHA file which you exported earlier. A
new character slot will be created and all the settings imported.
NOTE: Because importing always creates a new slot, you cannot use it to
overwrite an existing character.

3.2.8 CONVERSATIONS
While the old Sierra games were mainly based on action and not talking, the
Lucasarts games took the opposite approach.
If you want to create a game with conversations where the player can choose
from a list of optional topics to talk about, you can now with the new Dialog
Editor. Go to the "Advanced" tab, Dialog mode.
Conversations are made up of Topics. A "topic" is a list of choices from
which the player can choose. You may have up to 14 choices in a topic.
However, not all of them need be available to the player at the start of the
game - you can enable various options for conversation once the player has
said or done other things. For example, when you talk to the man in the demo
game, the first option is just "Hi". Once he has said this, however, a new
option becomes available.
The Dialog Editor is quite self-explanitory - you view one topic at a time,
using the up/down arrow buttons to choose the current topic. Then, you see
the list of options for the topic in the top part of the screen. Each option
has a "Yes" or "No" on the right hand side, which specifies whether that
option is available to the player at the start of the game.
There is also a column headed "Say" - this defines whether the character
says the option when the player clicks it. The default is on, but if you
want options describing the player's actions rather than the actual words,
you may want to turn this column off for that dialog.
You control what happens when the player chooses an option by clicking the
"Edit script" button. This is NOT the same script language as the main text
scripts use - it is a much simplified and easier to understand language
specific to dialogs.
Each topic has its own script file. When you click "Edit script" for the
first time on a topic, all you will see is a number of lines starting with
an '@' symbol. In the dialog script, these signify the starting points of
the script for each option. For example, when the player clicks on option 3,
the script will begin on the line following "@3". There is also a special
starting point, called "@S". This is run when the conversation starts, before
any choices are given to the player. This could be used to display a "Hello"
message or something similar.
To display some speech, you begin the line with the character's SCRIPT NAME
(not full name), followed by a colon, then a space, and then what you want
them to say. For example, if my main character's script name is EGO, I would
write
ego: "I am very happy today because it's my birthday."
The character name is used by the system to choose the correct colour for
the text. You can have as many lines of speech like this as you want within
the script. You can also use the special character name "narrator", which
displays the text in the pop-up message box instead of as speech text.
To signal the end of the script for this option, place a "return" command on
the last line of it. For example,
@1
ego: "Hello. How are you?"
narrator: The man looks you in the eye.
otherman: "I'm fine."
return
This tells the program to go back and display the choices again to the player.
If you use "stop" instead of return, then the conversation is ended. You use
this after the player saying "Goodbye" or something similar.
The dialog commands available are:
add-inv X
  Adds inventory item X to the current player's inventory. This does the
  same thing as the AddInventory text script command, but is provided here
  because it is frequently used in dialogs.
goto-dialog X
  Switches the current topic to Topic X, and displays the current list of
  choices for that topic.
new-room X
  Takes the player to room X, and aborts the conversation. Since this does
  not allow you to specify co-ordinates, you may need to use some Player
  Enters Screen logic in the target screen to place the character properly.
option-off X
  Turns option X for the current topic off, meaning it won't be displayed in
  the list of choices next time.
option-off-forever X
  Turns option X off permanently. It will never again be displayed, not even
  if an "option-on" command is used.
option-on X
  Turns option X for the current topic on, including it in the list of choices
  to the player next time they are displayed.
play-sound X
  Plays sound effect SoundX.wav or SoundX.voc. You can use this to add speech
  to your game.
return
  Stops the script and returns to the list of choices.
run-script X
  Runs global text script function "dialog_request", with X passed as the
  single parameter. This allows you to do more advanced things in a dialog,
  such as adding an inventory item and so on. The "dialog_request" function
  should be placed in your game's global script file, as follows:
    function dialog_request (int xvalue) {
      // your code here
      }
set-speech-view NAME X
  Changes character NAME's talking view to X. NAME must be their script name,
  and X is the number of the new talking view.
  Use this to easily change their facial expression during a conversation.
stop
  Stops the conversation and returns the player to the game.
For an example of a dialog script, load the demo game into RoomEdit and
look at the script for its topic 0.

3.2.9 GAME OPTIONS
On the Game, Misc tab you may have noticed some check-boxes in the top half
of the screen. These set gamewide options, and mean the following things.
Note that some things listed here are explained later in the documentation,
so if you don't understand one of the items in this list, come back to it
later:
 * Debug Mode - whether the debug keys are active. When debug mode is on,
   you can press Ctrl-X to teleport to any room, Ctrl-S to give all inventory
   items, Ctrl-A to display walls on the screen, and Ctrl-D to display
   statistics about the current room. When debug mode is off, these do nothing.
   (More specifically, the text script Debug() function is disabled).
 * Play sound on score - controls whether a sound effect is played when
   the player scores points. If so, you can set the sound number, which will
   play SOUNDx.WAV (or SOUNDx.VOC), where X is the number you set.
 * Walk to hotspot in Look mode - controls whether the player will walk
   to "walk-to" spots when the player looks at the hotspot. Normally he only
   walks on use, speak and use-inv. See section 3.1.4.3 for information.
 * Conversation on GUI - controls where the player's options for dialog are
   displayed. If this option is not checked, then in a conversation, the options
   will be displayed at the bottom of the screen. If you check this box, then
   instead the options will be displayed on the GUI you specify.
 * Use "anti-glide" mode - you may notice that, as the character walks, it
   can seem as if he is gliding, especially if you have a slow animation speed
   setting. When anti-glide mode is on, the man's position is only updated
   when the frame of animation changes. You will need to increase each
   character's walking speed if you use this option.
 * Text windows use GUI - allows you to customize the standard text window
   appearance in the game, using the specified interface element. See section
   4.2.3 for more information.
 * Pixel gap between options - defines the gap between the options displayed
   to the player in a conversation. Normally this is 0, which means the
   options are right below each other. Changing it to 1 or 2 can make the
   option display look less cluttered; it's a matter of personal preference.
 * Player can't skip speech text - prevents the player clicking the mouse
   to skip conversation text. They can still use the ESC key to skip the text,
   however.
 * Buttons off when disabled - specifies that, when an interface button is
   disabled, then it is simply not displayed at all. The default action is to
   "grey-out" the button by putting alternating black pixels on it.
 * Always display as speech - if you select this option, then all normal
   text in the game will be displayed above the main character's head as speech
   text, much like the way the Lucasarts games worked. If this option is not
   checked, then normal text appears in a pop-up message box, like the way that
   the Sierra games worked.
 * Use Sierra-style speech window - normally, when a character talks, the
   speech text is displayed above their head in the game, and the character's
   talking view is used to animate the actual character. However, if you set
   this option then the talking view is used to display an animating graphic
   seperately in the top-left of the screen, with the text on the right of it.
   This is similar to the way that Space Quest 5, King's Quest 6 and other
   later Sierra games worked. You can also cycle to another option, "Sierra-
   style with background", which is the same except a text window is drawn
   behind the speech text to make it easier to read.
 * Pixel-perfect click detection - normally, when the player clicks the
   mouse, AGS just checks to see if the cursor is within the rectangular area
   of each character and object on the screen. However, if this option is
   checked, then it will further check whether the player clicked on an actual
   pixel of the object graphic, or whether it was a transparent part of the
   graphic. If this option is enabled and they click on a transparent pixel,
   then the hotspot behind the object will be activated instead.
   NOTE: This option does not currently work correctly with scaled characters.
 * No special walk-mode processing - normally, when you click the mouse in
   the Walk mode, the main character will move to where you clicked. However,
   if you want to create a game all viewed from a 1st-person perspective, and
   so don't have a main character, then selecting this option allows you to
   use the Walk mode for other things. If selected, then "Character stands on
   hotspot" events are instead triggered by clicking the Walk cursor on the
   hotspot.
 * Use 320x240 letter-box mode - normally, the available screen resolutions
   are 320x200 and 640x400; however, if you select this mode then 320x240 and
    640x480 will be used instead. The screeen will be "letter-boxed" - that is,
   there will be a black border top and bottom. You may want to use this option
   if you need a square pixel aspect ratio for your graphics.
   When this option is enabled, any 640x480 rooms you have will be expanded
   to full-screen instead of scrolling.
 * Don't modify inventory cursor - normally, when you select an inventory
   item the mouse cursor is changed into that item. However, if you want to
   create a Lucasarts-style game (where the inventory cursor is always a
   cross-hair), check this option and it won't be changed.
 * Don't automatically lose inventory - normally, when a "Use inventory"
   interaction is run (and Data is not 99), the player loses the inventory
   item. However, if you set this option then they will NEVER lose any
   inventory items automatically - you must specifically use a "Lose inventory"
   command when you want them to lose it.
 * Don't scale up fonts - normally, if the player chooses 640x400, then
   the fonts will be scaled up to match. However, if you have drawn your fonts
   for the 640x400 resolution, use this option to stop them being stretched.
 * Split resource files - see section 4.3.2 for information.
 * Characters turn before walking - specifies that when a character starts
   to walk somewhere, it will first turn round to face the correct direction
   using available animation frames, rather than just suddenly switching to
   face the right way.

3.2.10 FONTS
Adventure Game Studio allows you to replace the default font and to add your
own. This feature is currently very limited in that you can only import SCI
fonts (Sierra's font format). These can be created in two ways:
 (a) Extract the font from a Sierra game, using the SCI Decoder program
     available on the internet.
 (b) Create your own font and save it in SCI Font format, using the SCI
     Graphic Studio program  (http://scigraphicstudio.cjb.net).
Go to the "Visual" tab, "Fonts" mode. Here you can see all the current fonts
by using the arrow buttons to cycle through them. You can create a new font
slot by clicking the "New font" button. To import your SCI Font into the
current slot, click the "Import SCI font" button.
IMPORTANT: The fonts which will be used for speech should generally also have
an outline font. You can see this with the default fonts, font 1 is the speech
font, which is drawn in the character's colour, and font 2 is the outline font,
which is drawn in black behind the speech in the game. This helps avoid any
colour clashes between the font and the background.
To set a font to have an outline font, select the main (coloured) font as the
current font, then click the "No outline" button. You will be prompted for
the font number of the outline font, so type it in.
NOTE: Font 0 is used as the normal text font, and font 1 is used as the
speech font. Therefore any extra fonts you add cannot be used.

3.2.11 HI-COLOUR NOTES
AGS now supports 16-bit hi-colour graphics. In order to use this feature,
go to the Game tab, "Palette" mode and click the "Make game hi-color" button.
Acknowledge the warning and your game is converted. You won't see any change
at first - in fact, the only difference made is that it now allows you to
import 16-bit backgrounds and sprites, and that the engine will select a
 16-bit colour display mode. This means that to play your game the player MUST
have a Super-VGA card - standard VGA cannot display hi-colour. They will
also need to make sure they have all their VESA drivers correctly installed.
RoomEdit now switches to 320x200 16-bit colour, so all your backgrounds and
sprites should look as they will in the game.
Because hi-colour support is new to AGS, you may notice bugs with it in
various places in roomedit - for example, sprites showing up funny in various
modes. Don't worry though - it'll all look right when you run the game.
If you select the 640x400 video mode, and run a hi-colour game, you'll notice
that the engine is using letterboxing even if you didn't want to. This is
because there is no 640x400x16 video mode, so the engine has to use 640x480
and put black borders on the top and bottom. Sorry, no way round this.

3.3 OTHER ROOM FEATURES
This section describes slightly more advanced things you can do with the
rooms.
3.3.1 CHARACTER SCALING
AGS supports scaling of characters, where the character can appear to get
smaller as he walks away from the screen. Character scaling is supported as
part of the walkable areas in a room.
The reason why you have multiple colours available for the walkable areas is
because you can set a zoom level for each colour, which defines how large
the character will be while he is in that area. The default for all walkable
areas is 100%, ie. full size. However, you can adjust it using the "Walkable
Areas" mode to anywhere from 10% (one-tenth size) to 200% (double size).
The scaling settings effect all CHARACTERS in the game, but not objects. You
can disable the scaling for an individual character by checking the "ignore
scaling" box in that character's properties.

3.3.2 SCROLLING
If you've been wondering, I'll tell you now: Yes, you can create scrolling
rooms, like the ones used in Lucasarts games like Monkey Island (tm) and Day
of the Tentacle.
To create a scrolling room, just import a scene that is larger than 320x200.
For example, 500x200 is a good size for Lucasarts-type rooms.
When you import the scene, a message box will appear asking you what
resolution the picture is drawn for - this is because the picture could
either be a scrolling room at 320x200, or a single non-scrolling screen at
640x400. So,  with a 500x200 room you would click the "320x200" button.
That's all you have to do. Draw on the walkable areas, hotspots and so on, as
normal, and then save the room. The screen will follow the main character
around.
TIP: You can also have scrolling hi-res rooms. Just import a scene which is
larger than 640x400.

3.3.3 GRAPHICAL SCRIPTS
NOTE: the graphical script system is currently depreciated awaiting a total
rewrite. Currently you are advised to use the text script system instead, for
which tutorials and help are provided on the website and forums.
(old text follows):
While AGS provides a comprehensive text scripting system, there are some
occasions when it is easier and neater to use a graphical script. Also, if
you are new to scripting, the graphical script is the best way to learn.
A graphical script is the easiest way to add several responses to an event.
Normally, when an event occurs, you can only set one reaction using the
Interaction window, which limits your possibilities. But, by using a graphical
script, you can do much more complex things.
At its simplest, a graphical script is just a list of commands which are
carried out from top to bottom. For example, a "Display message" command
followed by a "Remove object" command. But the graphical script's main power
is in conditional statements - that is, commands which may or may not be
executed, depending on other factors.
To support conditional statements, the graphical script uses flags. Each flag
is either "Set" or "Clear". All the flags start off clear, and you can set
a flag to the "Set" state to signal that some sort of event has occured.
There are two types of flags - Local flags and Global flags. Local flags are
specific to each room, and you can give the flag a name when you create it.
Global flags are available to every room in the game. They are named GLOBAL1
to GLOBAL50, and changing one of these flags from one room's graphical script
will also change it for all other rooms.
The graphical script editor displays the current script on the left hand
side of the screen, and the list of available commands on the right. When you
start a new script, you will have a single "Display message" command on the
script to the left. To add a new command, drag it from the list on the right
to below the "display message" on the left. You will be asked to type in the
number to replace the %d if the command requires it; this is the same way as
it works in the Interaction windows. To delete a command, drag it over to the
right. You can modify a command's properties by right-clicking it.
When you add conditional ("if") statements, an indented "display message"
command will be added below it. The indented commands will only be carried out
if the condition is true. For example, consider this script:
 Display Message 1              <-- "You turn around to face the key"
 If flag GOTKEY is set
   Display Message 2            <-- "But it's gone. You've already taken it"
   Stop Script
 Set flag GOTKEY
 Display Message 3              <-- "You pick up the key"
 Add Inventory 2
 Give Score 5
You can create this yourself by dragging the commands over from the right.
The first time the script is run, GOTKEY will be Clear (remember, all flags
start "Clear"), the player will get the key and 5 points, and GOTKEY will
be "Set". The next time the script is run, instead of getting another key,
the player will be told they already have it, and the script is aborted.
(The "Stop Script" command tells the game not to carry out the rest of the
script).
Commands like "Give score" WILL be carried out every time they are encountered
(in the Interaction windows, the score is only given once), so you must make
sure to use conditional statements so that the player can't keep repeating
the action if you don't want them to.
Descriptions of the special graphical script commands are available in
section 6.7, below.

3.3.4 IMPORTING A FILE AS THE WALKABLE AREA MASK
AGS now has the ability to import an external BMP or PCX file to use as the
walkable-area, hotspot or walk-behind area mask. If you don't like the way
you have to draw these in RoomEdit itsself, you can draw them in another
program and then import them. This is also useful if you are converting a
game you were making with another game-creation system into AGS.
To use the feature, click the "IMPORT FILE" button in the relevant mode of
the Room Editor. There are some restrictions to how this file must be drawn:
it must be the exact same size as the background scene (but in the 320x200-
resolution), and it must be in 16-colour (4-bit) or 256-colour (8-bit). Then,
colour 0 on the bitmap signifies transparency and colours 1-15 are used as the
respective hotspot/walk-behind/walkable area numbers. For example, if you have
a 640x400 hi-res background scene, the mask bitmaps must be 320x200 size.
NOTE: Do NOT use any colour numbers above 15 on the mask bitmap. Use only
palette indexes 0 to 15.

3.3.5 ANIMATING BACKGROUND SCENES
If you want to have a lot of animation on the screen, you will come across
two problems if you try to do it using objects:
(a) There is a limit of 10 objects per screen, so you may not be able to
  animate everything that you want to.
(b) Objects slow down the game - the more objects on the screen, the slower
  the game runs.
The solution to these problems is to use an animating background scene.
How it works is this: Each room can have from 1 to 5 backgrounds. Normally,
each room just has one background. However, you can import up to four extra
backgrounds in each room, and if you do so then the game will cycle through
them, giving the effect of animation.
This gives two main advantages - you can animate the entire screen, and due
to the way the engine works, it doesn't slow down the game at all.
To import a second background for a room, load the room into RoomEdit, then
go to the Room tab, Setup Screen mode, and click the "Anim bkgrnd" button. A
screen appears, which lists the current backgrounds for the room. To import
a new background, click where it says "None". To delete a background, click
the "Del" button on the relevant row. That's all there is to it. To leave the
background editor, press any key.
You can adjust the speed of the animation by clicking the "SPD" button, which
is just under the "Anim bkgrnd" button. Smaller number means faster animation,
and the default is 5.
NOTE: All the background scenes must be the same size.
NOTE: All scenes are mapped to the palette of the first scene - this should
not be a problem, but if you use very different colours in the different
frames, you may need to fine-tune the graphics.

3.3.6 LIGHTING EFFECTS
New in v2.14 is the ability to use lighting effects on your characters. The
walkable areas tab has a new option in the bottom-right called "Light level".
By default this reads "Normal", but by clicking the arrows you can change it
to from -100 to +100. This number is the light level in the current walkable
area: a negative number makes the character darker (-5 is slightly tinted,
down to -100 is very dark), a positive number makes the character lighter (+5
is slightly lighter, +100 is very bright, probably ending up white).
This could be useful if, for example, you have a street lamp on your scene so
when the character walks under it they get brighter, or if a wall is shading
the character from the light they can get darker.
NOTE: Light levels only work when the character's graphic is at the same
colour depth as the background (ie. a 256-colour character in a hi-colour
game won't get lightened).
NOTE: In a 256-colour game, only darkening areas (light level < 0) will work.
Also, depending on the room palette the quality of the darkening will vary
in 256-colour games.
NOTE: Light levels affect characters only - they do not affect objects,
overlays or the background scene.

3.3.7 EXACT PALETTE IMPORT
If you have drawn a 256-colour background scene which you want to do palette
effects with (for example using the CyclePalette text script function), you
may find that Roomedit remaps the colours to different slots making it
difficult to do these effects.
To counteract this, RoomEdit now has an "Exact pal import" feature, which
will simply take the palette slots as they are from the source image and
replace the corresponding background slots with them in the room. This means
that your colours will be in the exact slots that you put them in, but you
must make sure that the scene only uses the palette slots that you have
allocated to the background in the Palette editor.
To enable/disable Exact Pal Import mode, press "P" on on the Setup Screen mode
of the editor.

4. Other features
-----------------
4.1 MUSIC AND SOUND
All good games use sound to involve and immerse the player in the game. AGS
allows you to play a background music track, and also to play sound effects
at appropriate times.
The DOS version of AGS supports Adlib, Sound Blaster and General MIDI for
background music, and it supports the Sound Blaster and ESS Audiodrive for
sound effects.
The Windows version of AGS supports all DirectX-compatible sound cards.
For background music, AGS can use MIDI, MOD, XM, S3M and MP3 music files. For
sound effects, you can use WAV and VOC files.
When AGS needs to play music number X, it will search for the files in the
following order. The first file it finds, it plays: MUSICx.MP3, MUSICx.WAV,
MUSICx,MID, MUSICx.MOD, MUSICx.XM, MUSICx.S3M.

When the game loads, music 0 will be played if it exists in the game directory.
You can change the music later by setting "Play music on room load" in a room
(see section 3.1.7 for information), by using the PlayMusic text script
command, or by using the "Play sound" interaction command. If you use the
interaction command, you must add 1000 to the music number so that AGS
recognises it as music and not a sound effect. For example, to play music 23,
use "Play sound 1023".
NOTE: MP3 files are not included in the game EXE, but can be bundled
seperately as a single data file. See section 4.3 for more information.

To play a sound effect during the game, you can use the PlaySound text script
command, or the "Play sound" interaction command. The game will search for
SOUNDx.WAV and SOUNDx.VOC, where X is the sound number.
Note: The Adlib sound card only supports MIDI music. It cannot play sound
effects, or MOD, XM or MP3 music.

4.1.1 VOICE SPEECH
With AGS you can link a line of dialog to a speech file, to enable "talkie"-
style games. Suppose you have a dialog script with the following:
ego: "Hi! How are you?"
david: "I'm fine."
Normally this would display the words in the speech text above the characters
heads. However, you can add the special character '&' to symbolise that a
voice file should also be played. The file name is made up of the FIRST FOUR
LETTERS of the character's SCRIPT NAME, then an ID number. For example,
ego: &10 "Hi! How are you?"
david: &7 "I'm fine."
This would play EGO10.WAV with the first line, and DAVI7.WAV with the second.
When a line of text has a voice linked to it, the text on the screen will not
be removed until the voice file has finished playing. If the player interrupts
it by clicking the mouse or pressing a key, the text and voice will be stopped.
NOTE: Currently, only WAV-format files can be used for speech.
If you add or update any voice files, you need to click the "REBUILD VOX FILES"
button in the Main, Game tab of roomedit which will combine them into the
speech file used in the game. This file is called SPEECH.VOX and is seperate
from the rest of your game data so that you can offer it as an optional extra
download to the player. The game will function correctly if the file is not
present.
SeeAlso: SetVoiceMode text script function.

4.2 EDITING THE INTERFACE
AGS now supports customizable interfaces. By default, the game interface is
set up to act like Sierra's point-and-click interface of its 1990-93 games.
AGS v2.07 has a completely re-written interface system, now called the GUI
system. (The name change is to help distinguish the new system from the old
system). A description of what's changed from the last version is in
section 4.2.8, below.
To change the interface (recommended for advanced users only), go to the Game
tab, "GUI" mode.
The game interface is split up into GUI "elements". Each element is a
rectangular region on the screen which is drawn on top of the background
scene. Each element can be set to either:
 * be always displayed (for example the Sierra status-line)
 * pop-up when the mouse moves to a certain position (eg. Sierra icon-bar)
 * pop-up on script command only
The default interface is made up of two elements - the status line, and the
icon bar.
In the GUI Editor, you will see several buttons. The "Export GUI" button
exports the entire interface (ie. all the GUIs, plus button graphics) to a
file, which you can then import later into a different game using "Import GUI".
This allows you to design your interface and then use it in all your games.
The "New GUI" button creates a new element. You can change which element you
are editing by clicking the up and down arrow buttons.
In the top part of the screen the current GUI element is displayed. You can
change the size of the rectangle by dragging the lower-right hand corner of
it with the mouse.
You will also notice a window titled "Properties". This allows you to edit
the various properties of the GUI, and it works something like Visual Basic
(tm)'s Properties window. In the Properties window, you can change the
background colour of the GUI, set a background picture, and manually set the
location and width/height amongst other things.
The "Visible" property allows you to set when the GUI is displayed. The
default is "Always", which is like the Sierra status-line: always present
on the screen. The "Script only" option means that the GUI will be initially
off and must be turned on by a text script command. (NOTE: With this option,
the game will be paused when the GUI is displayed. If you don't want this
behaviour, set it to "Always" and use InterfaceOff in game_start). The
"Mouse YPos" option means that the GUI only appears when the mouse vertical
position moves above the y-coordinate set with the "Popup-YP" option.
The "Clickable" check box at the bottom of the screen allows you to set
whether the GUI and buttons on it respond to mouse clicks. This is on by
default, but if you turn it off and the player clicks on the GUI, the game
will actually process the click as if they clicked behind the GUI onto the
actual screen. Useful for transparent GUIs used to display information.

4.2.1 GUI BUTTONS
To provide interactivity with the interface, you use buttons. There is no
limit to the number of buttons per GUI, but the game can only contain a total
of 80 GUI buttons.
To add a button, click the "Add button" button, and then drag a rectangle
with the mouse onto the GUI. You will see it displayed as a text button, with
the text "New button" on. Notice that the Properties window is now displaying
properties for your new button rather than the GUI.
Using the Properties window, you can set a picture for the button instead,
and you can also set various other self-explanitory attributes.
You set what happens when the player clicks on the button by using the "Left
clk" attribute. This can be set to "Do nothing" (the default), and also "Set
mode", which changes the cursor mode to the mode specified in the "Clk data"
property. The other option, "Run script", runs the "interface_click" text
script function, passing the GUI number and button number of the clicked
button.
To delete a GUI button, select it then press the Delete key on the keyboard.

4.2.2 INTERFACE TEXT
You can also display text on interfaces. For example, the Sierra-style
interface displays the score in the status bar.
To add text to a GUI, you add a label. Click the "Add label" button, then
drag out a rectangle like you did when adding a button. You can change the
text displayed in the label by editing the "Text" property. Notice that the
text automatically wraps round to fit inside the rectangle you drew.
As well as typing normal text into the label, you can add some special markers
which allow the text to change during the game. The following tokens will be
replaced with the relevant values in the game:
 @GAMENAME@    The game's name, specified on the Game, Misc tab
 @OVERHOTSPOT@ Name of the hotspot which the cursor is over
 @SCORE@       The player's current score
 @SCORETEXT@   The text "Score: X of XX" with the relevant numbers filled
                in. This string will be in the user's chosen language.
 @TOTALSCORE@  The maximum possible score, specified on Game, Misc tab
Example: You have @SCORE@ out of @TOTALSCORE@ points.
The Properties window also allows you to align the text to left, right or
centre, as well as change its font and colour.

4.2.3 TEXT WINDOWS
If you want to add a personal touch to the standard white text-boxes which
display all the messages during the game, you can create a border using the
GUI Editor. Create a new GUI element, and check the "text window" box for it.
The element will be resized to about 1/4 of the screen, and you will see 8
pictures - one in each corner and one on each side. These are the border
graphics. You change the graphic for a corner in the normal way.
In the game, the corner graphics will be placed in the respective corners of
the text window, and the side graphics will be repeated along the edge of
the window. To tell the game to use your custom text window style, go to the
Game tab, "Misc" mode, and check the "Text windows use GUI" box in the top
part of the screen. When prompted, enter the number of the interface element
which you used.
You can also set a background picture for the text window. In the GUI editor,
simply set a background picture for the GUI element. The graphic you specify
will not be tiled or stretched in the game; however, it will be clipped to
fit the window. You should use a graphic of at least about 250x80 pixels to
make sure that it fills up the whole window.

4.2.4 LUCASARTS-STYLE INVENTORY
The final option you may have noticed in the GUI editor is the "Add Inventry"
button. This allows you to drag out a rectangle which will display the
player's current inventory, in the same way as the Lucasarts games did. To
make the inventory window scrollable, you will need to add Up and Down arrow
buttons, and attach text script code to those buttons to use the avaialble
variables such as game.top_inv_item, described in section 6.4.

4.2.5 SLIDERS
You can now add sliders to your GUIs. This allows you to have a nice interface
for the player to change settings such as volume and game speed.
To add a slider, click the "Add slider" button and drag out its rectangle just
like you would for a button. You can also resize it by dragging the bottom-
right hand corner out in the same way as a button.
Sliders can be either vertical or horizontal. The direction that it is drawn
in is automatic depending on the size that you stretch the slider box to - if
it is wider than it is tall you will get a horizontal slider, otherwise you'll
get a vertical slider.
For the properties of a slider you can set the minimum, maximum and current
values that the slider can have. In the game, the user will be able to drag
the handle from MIN to MAX, and the slider will start off set to VALUE.
For horizontal sliders, MIN is on the left and MAX on the right, for vertical
sliders MAX is at the top and MIN is at the bottom. Whenever the user moves
the handle's position on the slider, interface_click is called with the GUI
and object numbers of the slider. This means that if they continually drag
the handle up and down, interface_click will get called repeatedly.
Your script can find out the value of the slider using the GetSliderValue
text script command.

4.2.6 TEXT BOXES
You can now add Text Box controls to your GUI. A text box is a simple device
that allows the player to type information into your game. Adding a text box
works like adding the other types of control.
If a text box is on a currently displayed GUI, all standard keypresses (ie.
letter keys, return and backspace) are diverted to the textbox instead of
being passed to the on_key_press function. When the player presses Return in
the text box, the interface_click function is called with the text box's GUI
and object number. You can then use the GetTextBoxText text script function
to retrieve what they typed in.

4.2.7 LIST BOXES
List box controls allow you to add a list of items to your GUI. This could
be useful for doing a custom save/load dialog box, allowing the user to
choose between various options, and so forth.
You use the ListBox text script functions to manipulate the list box - for
example, ListBoxAdd to add an item, or ListBoxGetSelected to get the current
selection.
interface_click is fired with the listbox GUI/OBJECT ID's when the player
clicks on an item in the list. You may wish to ignore this or to do something
useful with it.

4.2.8 UPGRADING INTERFACES TO GUIs
When you load a v2.06 or earlier game into RoomEdit, it will display a message
telling you that the interfaces have been upgraded. Most of the process is
automatic - however, you should check the new GUIs to make sure they converted
properly. Also, any interface text which you were using is not converted - you
will need to re-create it using labels.
A couple of major things to note with the new GUIs:
First, you can no longer access interface properties, like vtext, from the
text script using the "iface" variable. Code using this will still compile
and run, but will not have any affect on the game.
You can now change the text instead by using the SetLabelText function -
described in the text script reference, section 6.3.
Also, the "$c", "$r" and "$l" alignment tags for the status bar text are
no longer supported - they have been replaced by the "Align" attribute of
labels.
Finally, it is currently not possible to delete buttons or GUIs.

4.3 DISTRIBUTING YOUR GAME
When you choose the "Save game..." button in the Room Editor, as well as
creating data files which it needs for itsself, the program will create an
executable file with the name of your game, in the directory above where all
the other files are stored.  This single file contains all of the program
code and data for your game, and is the file you should distribute. You may
remember that AC v1.14 included the ability to make a data file so that you
only needed to distribute it and the exe file - well this goes one step
further! Copy the USERGAME.EXE file to another directory or drive, or even
another computer, and there you have your game, contained in a single file!
Note, though, that you should also include the SETUP.BAT file to allow the
user to run the Setup program.
NOTE: It is not possible to load the exe file back into the Room Editor. This
means two things when only the EXE file is available: (1) other people can't
edit your game's data, and (2) you can't either. Always keep a backup of the
other files produced (*.CRM, AC2GAME.DTA, etc) as they are what the Editor
needs to be able to load your game for editing.
NOTE: Read the LICENSE.TXT file included for information on what you may, and
may not, distribute with your game.
NOTE: MP3 music files are not included in the exe. They will instead be
built into a file called MUSIC.VOX when you click the "REBUILD VOX FILES"
button in RoomEdit. Since MP3s override all other music file types, this
allows you to have an MP3 Music Pack which you can distribute seperately to
your game. If it is present in the game directory it will be used, otherwise
any other music avialable (eg. MIDI) will be played instead.
4.3.1 CUSTOM ICON
If you wish, you can use your own custom icon when you build a Windows EXE
file. To do this, simply place your icon in your game's folder, and name
it USER.ICO. Then, load Roomedit, make sure it says "Target: Win" and click
the "Save Game" button.
Your icon must be standard 32x32 pixels in 16-colour. If it is any other size
or colour depth, RoomEdit will give an error.
4.3.2 SPLITTING RESOURCE FILES
Some people found that once their game became large, the single EXE file
was slow at changing rooms. AGS now includes an option to split up the
resource files into smaller chunks to avoid this happening. On the Game,
Main tab you'll notice a checkbox "Split resource files up into X Mb". If
you tick this, then type in a number such as 1 or 2, then save the game,
the game data will be split up into chunks that size, named GAME.001,
GAME.002 and so on. Some resources are still combined into the EXE file but
all the rooms will be placed into the other files.
If you use this option, you need to distribute your game's EXE file plus
all the GAME.00? files.

4.4 TEXT SCRIPTING
Version 2 of AGS includes a radically overhauled text scripting system which
is now much more powerful and allows you much greater control of the game
through the scripts, if that is what you want to do.

***PLEASE NOTE: There is now a much better text script tutorial in the
seperate file, actutor.htm. Please refer there first for a good introduction.

The script language is based on the 'C' programming language, and anyone
familiar with C should be able to pick it up very quickly. If not, I will
introduce it now:
Basically, the script consists of FUNCTIONS. Each function (think of it as
an event handler) is run when a particular event occurs. For example, the
"on_key_press" function is run whenever the user presses a key on the keyboard.
The code within the function is executed in procedural fashion - ie. from the
top downwards, one statement at a time. The function outlines look as follows:
function name_of_function() {
  // your code here
  }
The keyword FUNCTION identifies this as the start of the function. Next is
the function's name. This can consist of any letters A-Z, plus underscores.
Note that spaces and numerical digits are NOT allowed in the name. After the
name are the brackets (). These define what parameters will be passed to the
function. In this case, there are none. Next comes the  {  symbol. This
signifies the start of the code block. Execution of the function starts after
this symbol and finishes at the  }  symbol, which signifies the end of the
function.
To store information, you use variables. A VARIABLE is a block of memory which
holds a number or string of text. You define a variable as follows:
int  my_counter ;
The "int" is the type of variable you want to create. Available types are
"char", which stores a 1-byte character, "int" which stores a 32-bit integer,
and also "string" which stores up to a 200-byte text string.
The "my_counter" is the name of the variable. You then use this name in the
script to refer to the variable.  The semicolon marks the end of the statement.
The scripting language requires every statement to end with a semicolon. If
you get a "Parse error" when your script is compiled, this is the first thing
to check.
You declare variables at the top of the script, BEFORE any functions.
To assign a value to a variable, use the  =  operator. For example,
 my_counter = 1;
will set the "my_counter" variable to 1. Notice again the semicolon - they are
required after every statement. You can also add variables together, and do
simple maths with the assignments. For example,
 my_counter = other_counter - 5;
will set "my_counter" to the value of "other_counter" minus 5.
I think it's time for an example script function. So:
function on_key_press(int key_code) {
  my_counter = my_counter + 1;
  }
The above script will increment the "my_counter" variable every time a key is
pressed.
NOTE: If you are simply adding a value to a variable, shortcuts are available.
These are the  +=  and  -=  operators. For example,  "my_counter += 1;"  is
equivalent to   "my_counter = my_counter + 1;".
To compare variables, you use the IF keyword with the following operators:
==   is equal to
>    is greater than
<    is less than
!=   is not equal to
For example,
  if ( my_counter < 5 ) {
    my_counter = my_counter + 1;
    }
will increment "my_counter" if it is less than 5. Note the use of the curly
brackets again - these define what code will be executed depending on the
result of the comparison.
NOTE: You will notice that the "is-equal-to" operator == is different from
the assignment operator = . Do not get these mixed up, because using a single
equals in an "if" statement can cause major bugs in your script.
IMPORTANT NOTE: Do NOT use the = or == operators with string variables, or
you will get strange results. You must use the provided functions (whose
names begin with "Str") to compare and assign strings. This is VERY IMPORTANT.
IMPORTANT NOTE: The script system is case-sensitive. That means, that the
variable names "my_counter", "My_Counter" and "MY_COUNTER" are all different.

To call a function (listed in the section 6.3, below), you use the function
name, followed by its parameters in parenthesis, then a semicolon. For
example, to add inventory item 2 to the player's inventory, do this:
AddInventory (2);
The space between the function name and parenthesis is optional.
If the function returns a value, you can capture it using the standard '='
operator. So, for example:
int currentchar;
currentchar = GetPlayerCharacter();
will store the current player character number in the currentchar variable.
You can also use the function directly in a statement much as you would
use a variable, for example:
if (IsGamePaused() == 1) {
  // your code here
  }
would execute the code if the IsGamePaused function returned 1.

Section 6.3 further down lists all the text script commands that are avilable.
Each command is described with the parameters it takes, and the description
will mention if it returns a value. For example, this entry from section 6.3:
GetSaveSlotDescription (int slot, string description)
  Returns 1 if successful, 0 otherwise.
This entry means that the function accepts two parameters, the first is an
integer (ie. a number), and the second is a string. Where a string is required
you can either pass a string variable or just type the string in directly
using speech marks. So you could call that function as follows:
if (GetSaveSlotDescription (10, buffer) == 1) {
  Display("Successful");
  }
else {
  Display("Failed.");
  }

NOTE: If you are an experienced programmer, please NOTE THE FOLLOWING: The
compiler will allow you to use 'C'-type pointers in your code, for example
using int*, char* and so on. However, DO NOT DO THIS as the data will be
corrupted when the user does a Save/Load game position.

Adventure Game Studio has two types of script files - "global" scripts and
"local" scripts. There is one global script in a game, and it is always
loaded in memory. This is the script which contains instructions for game-wide
events, like the key_press event.
Each room file also has its own local script. Both types of script use the
same syntax and have the same functions available to them. The local script
for a room is only in memory while that room is loaded, in order to save
memory. So although you could put all your code into the global script, using
the local scripts for functions which you only need in that particular room
will save memory and help speed up the game.
To edit a room's local script, load the room into the Room Editor, and then
choose the "Edit scripts" button from the ROOM, Setup Screen tab.
To edit the game's global script, click the "Edit script" button on the GAME,
Misc tab.

If you want to share information between room scripts and the global script,
there are 300 global variable slots which you can store numbers in.
Use the function  SetGlobalInt (index, value);   to set variable INDEX to
VALUE, and then  GetGlobalInt (index);  to get the value back again.
You can access the graphical script's global flags by using the gs_globals[]
array, but the numbers are shifted down one. So,  gs_globals[3]  is GLOBAL4
from the graphical script. A value of 1 means flag set and 0 means clear.

Currently it is not possible to call functions in other scripts - that is,
you can't write a function in the global script, and call it from a room
script. I hope to add support for this in a later version.

All co-ordinates used with functions in the script system are from 0 to 319
for X and from 0 to 199 for Y, where (0,0) is the top-left corner of the
screen, and (319, 199) is the bottom-right corner. This is independant of the
screen resolution the user is using - all co-ordinates are converted to the
320x200 scheme for scripting.
NOTE: In a scrolling room, the maximum co-ordinates are larger than this. To
find out, go to the Rooms, Setup Screen tab, and load in your scrolling room.
Under the "Options" button is a line which says: "Size: 320 x 200" (or
whatever the size of your room is). The co-ordinates you can use range from
0 to the width/height minus 1. Remember that you can use the "Ask Position"
button to find out the co-ordinates of a point on the room.

A complete list of all the functions and variables available in the text
script system is in section 6.3, below.

4.4.1 TEXT SCRIPT EVENTS
In your main global script file, there are some functions which are
automatically added when you create the game. These are "events", and the
function is called when a particular event happens. There are also some
other events which you can add if you want to.
The available event functions are:
dialog_request (int parameter)
  Called when a dialog script line "run-script" is processed. PARAMETER is
  the value of the number following the "run-script" on that line of the
  dialog script.
game_start ()
  Called at the start of the game, before the first room is loaded. You can
  use this to set up the initial positions of characters, and to turn
  interfaces on and off.
gscript_request (int parameter)
  Called when the graphical script "Run text script" command is used.
  The value of PARAMETER is the "%d" replacement in the graphical script.
interface_click (int interface, int button)
  Called when the player clicks on a button on an interface which has its
  action set as "Run script". INTERFACE is the number of the GUI which they
  clicked on. BUTTON is the object number of the button within this GUI.
on_event (int event, int data)
  Called whenever certain game events happen. The value of DATA depends on
  which event has occured. This allows you to perform checks or update things
  every time the player does something, regardless of which room it is in.
  The possible values of event are:
  ENTER_ROOM    called just before room Player Enters Screen event is run.
                DATA = new room number
  LEAVE_ROOM    called just after room Player Leaves Screen event is run.
                DATA = room number they are leaving
  EGO_DIES      called when the "Player Dies" interaction occurs.
                DATA = the Data column value of the Player Dies interaction.
  GOT_SCORE     called whenever the player's score changes
                DATA = number of points they got
  GUI_MDOWN     mouse button pressed over a gui
                DATA = GUI number
  GUI_MUP       mouse button released
                DATA = GUI number it was pressed down over
  ADD_INVENTORY the player just got a new inventory item
                DATA = inventory item number that was added
  LOSE_INVENTORY the player just lost an inventory item
                DATA = inventory item number that was lost
on_key_press (int keycode)
  Called whenever a key is pressed on the keyboard. KEYCODE holds the ASCII
  value of the key. A list of these values is in section 6.6, below.
on_mouse_click (int button)
  Called when the player clicks a mouse button. BUTTON is either LEFT or
  RIGHT, depending on which button was clicked. The "mouse.x" and "mouse.y"
  global variables contain the mouse's position.
repeatedly_execute ()
  Called every game cycle (normally 40 times per second).
unhandled_event (int what, int type)
  Called when an interaction is run, but no events are listed in the
  interaction window. This could be used to display a default "I can't do
  that" type of message. The values of WHAT and TYPE tell you what the
  player did. The possible values are listed below:
  WHAT TYPE Description
   1    1   Look at hotspot
   1    2   Interact with hotspot
   1    3   Use inventory on hotspot
   1    4   Talk to hotspot
   1    7   Pick up hotspot
   2    0   Look at object
   2    1   Interact with object
   2    2   Talk to object
   2    3   Use inventory on object
   2    5   Pick up object
   3    0   Look at character
   3    1   Interact with character
   3    2   Speak to character
   3    3   Use inventory on character
   4    1   Look at nothing (ie. no hotspot)
   4    2   Interact with nothing
   4    3   Use inventory with nothing
   4    4   Talk to nothing
   5    0   Look at inventory
   5    1   Interact with inventory (currently not possible)
   5    2   Speak to inventory
   5    3   Use an inventory item on another
   5    4   Other click on inventory
  Note that the "Character stands on hotspot", and all "Any click" events
  do not trigger this function.

4.4.2 CALLING GLOBAL FUNCTIONS FROM LOCAL SCRIPTS
You can now call your global script functions directly from your rooms. This
means that if you have a common script that you want to use in response to
various different events during the game, you can call it from your rooms
rather than duplicating code.
To use a global function, open up the main script header (the "Edit header"
button on the Game, Main tab), and add a line similar to the following:
import function my_function_name (parameters);
Where my_function_name is the name of the global script function, and
parameters is a list of the TYPES ONLY of the parameters it takes. For example,
if you had in your global script:
function do_animation (int anim_number) {
then you would write:
import function do_animation (int);
To use the function, you just call it normally in your script, eg:
do_animation (3);
You can also return a value to the caller by using the "return" statement,
and the local script picks this up the same way it does with built-in
functions. For example, the end of your global script function could be:
return 51;
then the local script just does:
int value = do_animation(3);

4.4.3 THE SCRIPT HEADER FILE
This allows you to include the same information into all your scripts. For
example, if you have a global function you want all the room scripts to use,
you can add its import definition to the header file.
Do NOT place any actual functions or variables in this header, because if
you do you will need to re-compile ALL the scripts whenever you modify the
function. Instead, place your functions in your global script and just place
an import line in the header file to allow the other scripts to access it.

4.4.4 OTHER SCRIPT NOTES
Only one text script can be executing at any one time. A script is considered
to be "executing" if there is still code left in a script function that needs
to be executed.
What this means is that if you call a function like MoveCharacterToObject,
which is BLOCKING - that is, it waits until the character finishes moving
before continuing the script - then while the character is moving no other
scripts will be run (for example, repeatedly_execute scripts).

4.5 DUMPING TEXT TO FILE
AGS now has the ability to dump all of your in-game text out to a flat text
file, which you can edit by hand and then import back later.
This is very useful for things such as translations, where the file can
just be translated rather than having to go into each room, edit the messages
there, and so on.
The text dumper is located on the Advanced tab, then the "Dump text" mode.
Here you have five check-boxes where you can choose which parts of the game
you want exported. By default they are all selected; however, if you wish
you can de-select things you don't need to export. Once done, click the Dump
Text To File button, type a file name, and click OK. When you exit Roomedit,
you should find that file inside your game's folder ready to be edited.
NOTE: The file contains special tags, which look like this:
$$$!$$$ GM 3
DO NOT MODIFY THESE LINES IN ANY WAY. They are used by roomedit to track what
each line of the file means, and changing any of the special lines could
really mess up your game when you import it back.
When you have made your changes to the text file, and want to combine it back
into the game, first of all MAKE A BACKUP COPY OF YOUR GAME FOLDER. Because
the import operation jibbles every part of your game, if it crashes or messes
up at any point, your game is most likely lost. So, make a backup of your
game before proceeding.
Once done, go back to the "Dump text" mode, select the things you want to
import back in, then click the "Read from file" button. There you can select
the text file to import, and it should import everything back in.
In conclusion, the Dump Text feature is a very powerful tool, however you MUST
be careful with its use or you could corrupt your game beyond repair.

4.6 THE TEXT PARSER
You can now use a text parser in your games if you wish to, much as the older
Sierra games did. The way it works is as follows:
On the Advanced tab of Roomedit, go to the "Text parser" mode. There, you
will see a short list of words which are provided for you. Each word has a
number beside it.
Basically, you add words you want to use by clicking the "Add word" button.
However, the real beauty of the parser is its ability to recognise synonyms -
that is, two words that mean the same thing. So, for example, if you wanted
the player to type "look at fence", they might well type "look at wall"
instead, if that's how they see the drawing. Or, a British person might type
"colour" whereas an American might type "color", both of which should have
the same effect.
To add a synonym for an existing word, highlight the current word, and click
the "Add synonym" button. You'll notice that the new word is given the same
number as the old one. All words with the same number are considered identical
by the parser.
You will notice that the provided list has a lot of words with number 0. This
is a special number, that indicates that the parser should ignore the word
completely. In our previous example, the player might type "look at the fence",
"look at fence", or just "look fence". By adding words like "at" and "the" to
the ignore list, they get stripped out of the user's input automatically. To
add new ignore words, just select an existing one and add a synonym.
So, how do you use the text parser? Well, you'll need a text box GUI control
somewhere in order for the user to type in their input, or you could just
use the InputBox command (but it has quite a short line length).
When the user has typed in their text (you'll probably know this by the text
box's interface_click being activated), you call the  ParseText  script
function which tells AGS what input string to use in subsequent commands.
You then simply use the Said command to test what the player typed in. You
type the whole sentence (but NOT including any ignore words), and AGS will
compare it to the user's string, considering all synonyms identical.
For example (assuming our text box is object 6 on GUI 3):
  string input;
  GetTextBoxText (3, 6, input);
  ParseText (input);
  if (Said("look fence")) {
    Display("It's an old wooden fence.");
  }
  if (Said("eat apple")) {
    Display("You'd love to, but you don't have one.");
  }

There are a couple of special words you can use with the Said command.
"anyword" will match any word that the user types in. For example,
Said("throw anyword away")  will match if they type "throw dagger away",
or "throw trash away".
"rol" (short for Rest-of-Line) will match the rest of the user's input. So,
you might want to do:
if (Said("kill rol")) {
  Display("You're not a violent person.");
}
This way if they try to kill anything they will get the generic response.

Sometimes, you want to accept two different words that are not synonyms as
the same thing. For example, the words "take" and "eat" normally have totally
different meanings, so you wouldn't make them synonyms of each other. However,
if the player has a headache tablet, for instance, then "take tablet" and
"eat tablet" would both be valid. This is where the comma "," comes in - if
you include a comma in your input, all synonyms of all words seperated by
the comma will match. So:
if (Said("eat,take tablet"))
will match eat or take and all their synonyms, then tablet and its synonyms.


5. Upgrading from AC v1
-----------------------
If you have used AC version 1.xx, and you want to continue with a game you
were making using this new version, this section describes the major changes
and what to do about them.
Of course, first of all you will need to get to know the new Room Editor. I'd
recommend reading through the tutorial in this file, as it will introduce you.
Instead of the old Condition List, the conditions are now split up into the
individual events. Where there are conditions now, an "Interaction" button is
available on those tabs. Clicking this gives a window where you can set the
responses you want to implement for those events.

5.1 CHANGES FROM v1
MAJOR CHANGES
 * The walls system has been completely changed. Now, instead of defining the
   walls on the screen, you instead define where the character CAN walk, by
   using walkable areas. This is to stop the problem where the player could
   wriggle through the walls. The shadow screen (Special menu of old RoomMake)
   has been incorporated into the walls screen - you can colour-code the
   walkable areas, and each colour can be assigned a view number.
 * When importing old rooms, all misc conditions are lost. You must check each
   room, and if it uses misc conditions, replace them with either a graphical
   script or text script. The Room Editor will warn you if you load an old room
   file which uses misc conditions.
 * There is no longer just one text script file which you edit and then compile.
   Now, text scripts are built into the room files (local text scripts) and
   into the main game file (global text scripts).

OTHER CHANGES
 * The X,Y co-ordinate positions of the characters are now the bottom-middle
   of the character (in AC 1 it was the bottom-left). This makes the pathfinding
   much better than before because the man won't walk over the walls on the
   right. Note that the objects are still bottom-left.
 * In the text script, the player's inventory now has a different variable name:
   it is now  "character[EGO].inv[X]"  rather than just  "inv[X]". This is
   because v2 supports different characters each carrying their own inventory.
 * The "runcondition" text script command has been removed. It was confusing
   and everything which it could do is now done seperately by different
   commands.
 * In fact, the whole text script system has been changed, once again.
   Sorry. I promise to keep it this way from now on :-)  But you'll be glad
   to know that the language is still the same, just the commands are different.
   I'd recommend reading sections 4.4 (intro to text scripting) and more
   importantly 6.3 (text script command reference) to introduce yourself.

5.2 STEP-BY-STEP: CONVERTING v1 GAMES

From v2.2 onwards, AGS can no longer import v1.xx games.
(It's been 2 years now since v2.00 was released, so I find it unlikely that
anyone still has any).

If you need to import a v1 game, download an older version of AGS such
as v2.07, use that to import your v1.xx game, then import that game into
the current version.


6. Command reference
--------------------
This section contains a complete reference for the room "interaction" events
and commands, and a comprehensive description of all the text script functions
available.

6.1 INTERACTION EVENTS
The following events are available in Interaction windows:
6.1.1 HOTSPOT INTERACTIONS
 * Character stands on hotspot - occurs repeatedly while the player character
   is standing on the hotspot.
 * Look at hotspot - occurs when the player clicks on the hotspot while in
   the "Look" mode (cursor mode 1).
 * Interact with hotspot - occurs when the player clicks on the hotspot while
   in the "Interact" mode (cursor mode 2).
 * Use inventory on hotspot - occurs when the player clicks on the hotspot
   while in the "Use inventory" mode (cursor mode 4), but ONLY if the player
   is using the inventory item number which the Data column is set to. For
   example, if you want to respond when the player is using a key (inventory
   item 2), then set Data to 2. You can also set Data to 99, in which case the
   event will trigger for any inventory item - in this case, you can use the
   "If inventory %d was used" graphical script command (see section 6.7), or the
   text script variable character[x].activeinv (see section 6.4) to find out
   what was used.
   IMPORTANT: When this event is triggered, and if Data is not 99, then the
   player will lose the inventory item.
   NOTE: Because the Data column is used for the event, you cannot use a
   response which also requires a Data value. You must use a text script or
   graphical script to respond in this case.
 * Speak to hotspot - occurs when the player clicks on the hotspot while in
   the "Talk" mode (cursor mode 3).
 * Any click on hotspot - occurs when the player clicks on the hotspot in
   any cursor mode (except Walk). This allows you to add extra modes like
   smell, taste, push, pull, and so on. This event also occurs as well as
   the other event for the Look, Interact and Talk modes.
 * Mouse moves over hotspot - occurs repeatedly while the mouse cursor is
   over the hotspot. You can use this to highlight the cursor, and for other
   various effects.

6.1.2 OBJECT INTERACTIONS
 * Look at object - occurs when the player clicks on the object while in
   the "Look" mode (cursor mode 1).
 * Interact with object - occurs when the player clicks on the object in
   the "Interact" mode (cursor mode 2).
 * Speak to object - occurs when the player clicks on the object in the
   "Talk" mode (cursor mode 3).
 * Use inventory on object - works like "Use inventory on hotspot" - see
   that desccription (section 6.1.1 above) for more information.

6.1.3 ROOM INTERACTIONS
 * Walk off left - occurs when the player character walks off the left edge
   of the screen.
 * Walk off right - occurs when the player walks off the right edge of the
   screen.
 * Walk off bottom - occurs when the player character walks off the bottom
   edge of the screen.
 * Walk off top - occurs when the player character walks off the top edge
   of the screen.
 * First time enters screen - occurs the first time the player enters the
   room. This event occurs AFTER the screen has faded in, so it allows you to
   display a message describing the scene.
 * Player enters screen - occurs just after the room is loaded into memory.
   This event occurs every time the player enters the screen, and it happens
   BEFORE the screen has faded in, which allows you to change object graphics
   and do other things to the screen which the player won't notice.
   NOTE: This event is ONLY meant for adjusting things such as object and
   character placement. Do NOT use this event for any sort of automated intro
   to the room - use the "Enters Screen After Fade In" event for that instead.
 * Repeatedly execute - occurs repeatedly on every interpreter cycle. The
   normal game speed is 40 cycles per second, so this event occurs about
   every 25 milliseconds.
 * Enters screen after fadein - occurs every time the player enters the
   room, AFTER the screen has faded-in. Suitable for displaying text
   descriptions and so on, that you want the player to see.
 * Player leaves screen - occurs when the player leaves the screen, just
   before the screen fades out.

6.1.4 INVENTORY ITEM INTERACTIONS
 * Look at inventory - occurs when the player clicks on the inventory item
   while in the "look" mode.
 * Interact with inventory - (not yet implemented).
 * Speak to inventory - only applies to the Lucasarts-style inventory,
   occurs when the player clicks the Talk icon on the inventory item.
 * Use inventory on inv - occurs when the player uses another inventory
   object on this one. You set the Data column to the number of the other item
   which needs to be used on this item (see section 6.1.1 above for details
   on the way this works). This event allows the player to combine items, and
   so on. For example, if they had picked up a laptop computer and a battery,
   seperately, then you could use this to allow them to insert the battery into
   the computer.
 * Other click on inventory - only applies to the Lucasarts-style inventory,
   occurs when the player clicks any other cursor mode (apart from look, talk
   and use_inv) on the item.

6.2 INTERACTION COMMANDS
The following commands are available in response to events in Interaction
windows:
 * Go to screen %d - changes the player character's current room to the %d.
   If this is in response to one of the screen edge events, the character will
   be placed on the opposite side of the screen. Otherwise, you must use the Data
   column to specify where on the new screen the man is placed. You specify which
   edge by using these numbers: 1000=left, 2000=right, 3000=bottom, 4000=top.
   He will be placed in the middle of that side, unless you add the pixel offset
   along the edge, which you can get from the "Ask Position" function in the
   Setup Screen mode. For example, Data=2150 would place him near the bottom of
   the right-hand side.
 * (Do nothing) - nothing happens.
 * Stop man walking - the player character stops moving if he is currently
   moving.
 * Player dies - this command does not actually do anything other than
   call the on_event text script event.
 * Run animation %d - runs an animation. Each room has animations numbered
   from 1 to 9, so you can have up to 9 animations per room. Click the "..."
   button to edit the animation.
 * Display message %d - displays a message. If the number is below 40, then
   the room message of that number will be displayed. If the number is above
   500, then the relevant global message is displayed.
 * Remove object %d - turns the specified object off. It will no longer
   appear on this screen, until it is turned back on by the "Turn object on"
   command.
 * Remv obj %d, add inv - turns the specified object off, and adds the
   inventory number in the Data column to the player's inventory.
 * Add inventory %d - Adds the specified inventory item to the player's
   inventory.
 * Run script - Runs a text script. Click the "..." button to edit the
   script. Section 4.4, above, introduces the text script system.
 * Run graphical script - Runs a graphical script. Click the "..." button
   to create the script. Section 3.3.3 describes the graphical script.
 * Play sound %d - plays the sound effect SOUNDx.WAV or SOUNDx.VOC, where X
   is the number you supply. If the number is >=1000, then this command will
   instead change the background music to MUSICx.MID/MOD/XM, where X is the
   number you supply minus 1000.
 * Play FLI/FLC %d - plays either FLIC%d.FLC or FLIC%d.FLI. If you set the
   Data column to 1 then the player can skip the animation by pressing ESC.
   Otherwise, they must watch the whole thing. For information on converting
   AVI files to FLC, see section 7.1 .
 * Turn object %d on - turns the specified object on. Either it was
   previously turned off using the "Remove object" command, or it was set
   to initially Off in the Room Editor.
 * Run dialog topic %d - starts a conversation, using topic number "%d" from
   the Dialog Editor.

6.3 TEXT SCRIPT FUNCTIONS
PLEASE NOTE: Most of the script functions are non-blocking: that is, they
return control immediately to the script, and then the function will be
performed while the game continues. However, a few of the functions, such
as "Display", are blocking. In this case, the script does not continue until
the function has finished (in this example, the user has removed the message
box). Blocking functions are documented as such below.
The following functions are available in the text script system. In
alphabetical order:
AddInventory (int what)
  Adds inventory index WHAT to the current player character's inventory. This
  has the same effect as doing  character[EGO].inv[WHAT]+=1;  however, it
  will add the inventory to the current player character and also update
  the inventory window.
  SeeAlso: LoseInventory
AnimateCharacter (CHARID, int loop, int speed, int repeat)
  Starts character CHARID animating. See the description for AnimateObject for
  more details, as this command is identical to AnimateObject except it works
  with characters. If the character is moving it will be stopped.
  SeeAlso: AnimateObject, SetCharacterView
AnimateObject (int object, int loop, int speed, int repeat)
  Starts the object number OBJECT animating, using loop number LOOP of its
  current view. The overall speed of the animation is set with SPEED,
  where 0 is the fastest, and increasing numbers mean slower. The delay for
  each frame is worked out as SPEED + FRAME SPD, so the individual frame
  speeds are relative to this overall speed.
  The REPEAT parameter sets whether the animation will continuously repeat
  the cycling through the frames. If REPEAT is zero, the animation will start
  from the first frame of LOOP, and go through each frame in turn until the
  last frame, where it will stop. If REPEAT is 1, when the last frame is
  reached, it will go back to the first frame and start over again with the
  animation. If REPEAT is 2, it will do the animation once, but then return
  the graphic to the first frame and stop (whereas repeat=0 will leave the
  graphic on the last frame).
  SeeAlso: AnimateCharacter, SetObjectView
AreCharactersColliding (CHARID1, CHARID2)
  Checks if character CHARID1 is touching CHARID2. This function just checks
  the base line of both characters, so that if one is standing a fair
  distance behind the other, it will not be marked as colliding.
  Returns 1 if the characters feet are touching, 0 otherwise.
  SeeAlso: AreCharObjColliding, AreObjectsColliding
AreCharObjColliding (CHARID, int obj)
  Checks if character CHARID and object OBJ are touching each other.
  Returns 1 if they are, and 0 if they are not.
  NOTE: This function checks the character's feet against the whole of the
  object. This is used to see if the character is standing on an object, and
  so on. The top two-thirds of the character do not trigger.
  NOTE: This function only performs a rectangular check, even when pixel-
  perfect click detection is on.
  SeeAlso: AreCharactersColliding, AreObjectsColliding
AreObjectsColliding (int obj1, int obj2)
  Checks if object OBJ1 and OBJ2 are touching each other. Returns 1 if they
  are, and 0 if they are not.
  NOTE: This function only performs a rectangular check, even when pixel-
  perfect click detection is turned on.
CDAudio (int command, int param)
  This function allows you to play and control an audio CD in your game.
  Different tasks are performed, depending on the value of the COMMAND
  parameter. If there is no CD-ROM drive on the system, the function does
  nothing.
  The PARAM parameter is used by some of the functions for various reasons; if
  it is not needed for the particular function you are calling, pass zero
  instead.
  The tasks performed are as follows depending on the COMMAND parameter:
     0  Query CD-ROM support - checks if there is a CD-ROM drive available on
        the system. Returns 1 if there is, and 0 if there is not.
     1  Get playing status - checks whether the CD drive is currently playing
        an audio track. Returns 1 if it is, and 0 if it is not.
     2  Play track - starts playback from track PARAM on the CD. If the track
        does not exist, or if it is a data track, nothing happens.
     3  Pause playback - pauses the currently playing audio track.
     4  Resume playback - continues from where the track was paused.
     5  Get number of tracks - returns the number of tracks on the CD
        currently in the drive. If the drive is empty, returns 0.
     6  Eject - ejects the drive tray if the drive has the ability. This is
        a feature you'll play with to start off because it's neat, and then
        realize that it has no real use in your game.
        Your script does not continue until the drive is fully ejected.
     7  Close tray - the reverse of Eject. This will pull the drive tray back
        in again. Your script does not continue until the drive has been
        fully closed.
     8  Get number of CD-ROM drives - returns the number of CD drives in the
        system, normally 1.
     9  Select current CD-ROM drive - changes the current CD drive to PARAM,
        where PARAM ranges from 1 to (number of CD drives). All the other
        CD Audio functions operate on the current CD drive.
  NOTE: These CD Audio functions are slow compared to all the other script
  functions. This will not be noticeable if you call them from most scripts,
  but using CDAudio in a repeatedly_execute script will noticeably slow down
  the game.
  NOTE: If the game is run under plain MS-DOS, the user's CD-ROM driver will
  need to be loaded in memory for these functions to work. If it is not, the
  game assumes that there is no CD-ROM drive on the system.
  NOTE: The Windows version of the engine only supports a single CD-ROM drive,
  so functions 8 and 9 currently do not work.
ChangeCharacterView (CHARID, int newview)
  Changes the normal view number of character CHARID to NEWVIEW. This is
  useful if, for example, you want the character to change the clothes
  they are wearing, and so permanently alter their view number.
  SeeAlso: SetCharacterView
ChangeCursorGraphic (int mode, int slot)
  Changes mouse cursor mode MODE's cursor graphic to SLOT.
  This permenantely changes the specified mode's cursor graphic. This function
  may be useful if you need more than the maximum number of mouse cursors.
  SeeAlso: ChangeCursorHotspot, SetCursorMode
ChangeCursorHotspot (int mode, int x, int y)
  Permanently changes mouse cursor MODE's hotspot on the cursor graphic
  to (X,Y). This is the offset into the graphic where the click takes effect.
  (0,0) is the upper left corner of the cursor graphic.
  SeeAlso: ChangeCursorGraphic
CreateGraphicOverlay (int x, int y, int slot, int transparent)
  Creates a screen overlay containing a copy of the image from SLOT in
  the Sprite Manager. The image is placed at (X,Y) on the screen (these are
  screen co-ordinates, not room co-ordinates). If TRANSPARENT is 1 then the
  overlay will be drawn in the same way as characters/objects, if it is 0
  then the a black rectangle will be painted behind the sprite.
  See the description of CreateTextOverlay for more on overlays.
  SeeAlso: CreateTextOverlay, RemoveOverlay
CreateTextOverlay (int x, int y, int width, int font, int color, string text)
  Creates a screen overlay containing the text you pass at the position
  specified. A screen overlay looks identical to the way speech text is
  displayed in conversations, except that with this command the text stays
  on the screen until either you remove it with RemoveOverlay, or the player
  goes to a different room, in which case it is automatically removed.
  The X and Y parameters specify the upper-left corner of where the text
  will be written. WIDTH is the width, in pixels, of the text area. FONT is
  the font number from roomedit to use (0 is the normal font, 1 is the speech
  font). COLOR is the text color - use one of the colours from 1 to 15.
  Finally, TEXT is obviously the text that gets displayed.
  The function returns the Overlay ID, which you use later to reposition
  and remove the overlay.
  NOTE: screen overlays, in the same way as objects, slow down the game
        while displayed.
  NOTE: there is currently a maximum of 3 overlays displayed at any one time
  SeeAlso: CreateGraphicOverlay, MoveOverlay, RemoveOverlay
CyclePalette (int start, int end)
  This is used for special effects, like the flowing colours on the Space
  Quest 4 title screen, and the Sierra logo of the later Sierra games.
  The palette indexes from START to END are cycled around one slot. Using
  this call in a repeatedly_execute function gives the effect of animation.
  NOTE: This function does not work in hi-colour mode.
  SeeAlso: FadeIn, FadeOut, SetPalRGB
Debug (int command, int data)
  This function provides all the debug services in the system. It performs
  various different tasks, depending on the value of the COMMAND parameter.
  If debug mode is off, then this function does nothing. This allows you to
  leave your script unaltered when you distribute your game, so you just have
  to turn off debug mode in the Room Editor.
  The DATA parameter depends on the command - pass 0 if it is not used.
  All the valid values for the COMMAND parameter are listed below along with
  what they do:
    0   All inventory - gives the current player character one of every
        inventory item. This is useful for testing so that you don't have to
        go and pick up items every time you test part of the game where they
        are required.
    1   Display interpreter version - the engine will display its version
        number and build date.
    2   Walkable from here - fills in the parts of the screen where the player
        can walk from their current location. This is useful if you think the
        path-finder is not working properly. Yellow areas are where the man
        can walk. Blue areas are defined as walkable in the Room Editor, but
        he cannot get to them from his current position. The unaltered parts
        of the screen are not walkable.
    3   Teleport - displays a dialog box asking for what room you want to go
        to, and then calls NewRoom to teleport you there. Useful for skipping
        parts of the game or going to a specific point to test something.
    4   Show FPS - toggles whether the current frames per second is displayed
        on the screen. Pass DATA as 1 to turn this on, 0 to turn it off.
DisableCursorMode (int mode)
  Disables the mouse cursor MODE. Any attempts to set the cursor to this mode
  while it is disabled (like using SetMouseCursor) will fail. This function
  also greys out and disables any interface buttons whose left-click command
  is set as "Set mode X", where X is equal to MODE.
  If the current cursor mode is MODE, then the engine will change it to the
  next enabled standard cursor.
  SeeAlso: EnableCursorMode
DisableHotspot (int hsnum)
  Disables hotspot number HSNUM in the current room. All areas of the screen
  that were previously HSNUM now act as type 0 (no hotspot). You can turn it
  back on later with the EnableHotspot command.
  This command permanently disables the hotspot - that is, it will not be
  reset when the player re-enters the room. The only way of turning the
  hotspot back on is to use the EnableHotspot command.
  SeeAlso: EnableHotspot, RemoveWalkableArea
DisableInterface ()
  Disables the player interface. This works the same way as it is disabled
  while an animation is running: the mouse cursor is changed to the Wait
  cursor, and mouse clicks will not be sent through to the "on_mouse_click"
  function. Also, all interface buttons will be disabled.
  SeeAlso: EnableInterface, IsInterfaceEnabled
Display (string message, ...)
  Displays a message to the screen. It will be displayed in the standard
  message box, and centred in the middle of the screen. You can insert the
  values of variables using "%d" and "%s" in the message. To insert the value
  of an integer variable, use %d, to insert a string use %s. For example,
  Display ("The counter is currently set to %d.", my_counter);
  This will replace the '%d' with the value of the variable "my_counter".
  Note: Display is a blocking function - that is, control will not return
  to the script until the player has removed the text window (by pressing a
  key or clicking the mouse). While the window is displayed, all other
  processing, like animations and interface display, are disabled. This is
  usually used for responses to the player LOOKing at things.
  SeeAlso: DisplayAt, DisplayMessage, DisplaySpeech, StrFormat
DisplayAt(int x, int y, int width, string message, ...)
  Identical to the "Display" function, only this allows you to define the
  position and size of the window where the text is displayed. The X and Y
  variables define the co-ordinates of the upper-left corner of the window.
  The WIDTH variable defines the width of the window. The height is then
  automatically calculated so that the message fits into the window.
  Note: This is a blocking call. See the "Display" help for more information.
  SeeAlso: Display, DisplayAtY
DisplayAtY (int y, string message)
  Similar to the Display function, except that this will display the message
  box at the specified Y location on the screen. The Y defines the co-ordinate
  of the top of the message box. The horizontal positioning will be
  automatically calculated as usual.
  SeeAlso: Display, DisplayAt
DisplayMessage (int message_number)
  Identical to the Display function, but this uses a message text defined in
  the Room Editor rather than in the script. It will either use a message
  from the current room, or a global message (if message_number >= 500).
  SeeAlso: Display
DisplaySpeech (CHARID, string message)
  Displays the text MESSAGE as speech above the specified character's head.
  The text will remain on screen for a limited time, and the user may or may
  not be able to click it away depending on the setting of "Player can't
  skip speech text". The text displayed by this function looks identical to
  that used by the dialog system.
  NOTE: This function does not allow variables like "%d" and "%s" in the
  message.
  SeeAlso: Display, DisplaySpeechBackground
DisplaySpeechBackground (CHARID, string message)
  Similar to DisplaySpeech, except that this function returns immediately
  and the game continues while the character is talking. This allows you
  to have characters talking in the background while the player does other
  things. Note that the character's talking animation is not played if this
  function is used.
  SeeAlso: DisplaySpeech
EnableCursorMode (int mode)
  Re-enables the mouse cursor mode MODE. This function also enables any
  interface buttons which were disabled by the DisableCursorMode command.
  SeeAlso: DisableCursorMode
EnableHotspot (int hsnum)
  Turns hotspot HSNUM back on. Use this to re-enable a hotspot which you
  turned off earlier with the DisableHotspot command.
  SeeAlso: DisableHotspot, RestoreWalkableArea
EnableInterface ()
  Re-enables the player interface, which was previously disabled with
  the DisableInterface function. Everything which was disabled is returned
  to normal.
  SeeAlso: DisableInterface, IsInterfaceEnabled
FaceCharacter (CHARID, int tofaceid)
  Turns the graphic of character CHARID so that it looks like he is facing
  character TOFACEID. This involves changing the current loop of CHARID
  to the appropriate loop number, and setting the frame number to 0 (standing).
  SeeAlso: FaceLocation, MoveCharacter
FaceLocation (CHARID, int x, int y)
  Similar to the FaceCharacter function, except that this faces the character
  to screen location (X,Y). This allows him to face not only other characters,
  but also objects and hotspots as well (you can get their co-ordinates from
  the Ask Position feature in the Room Editor).
  SeeAlso: FaceCharacter
FadeIn (int speed)
  Fades in from a black screen to the current palette. This is used to restore
  the screen after a FadeOut call. SPEED is from 1 (slowest) to 64 (fastest).
  Note: This is a blocking function.
  Note: This function does not work in hi-color modes.
  SeeAlso: CyclePalette, FadeOut
FadeOut (int speed)
  Fades the screen out to black. SPEED is the speed of the fade, from 1
  (slowest) to 64 (instant). You can restore the screen with FadeIn.
  Note: This is a blocking function.
  Note: This function is slow in hi-color modes.
  SeeAlso: CyclePalette, FadeIn
FileClose (int handle)
  Closes the file with handle HANDLE, and commits all changes to disk.
  You MUST close the file after you have finished with it.
  SeeAlso: FileOpen
FileOpen (string filename, int mode)
  Opens a disk file for reading or writing. These disk I/O functions are only
  intended for simple tasks like the way the QFG series export the character
  when you complete it. MODE is either FILE_READ or FILE_WRITE, depending on
  whether you want to write to or read from the file. If you pass FILE_WRITE
  and a file called FILENAME already exists, it will be overwritten.
  This function returns a file handle, which you use in future calls to
  file functions, or returns 0 if there was a problem (eg. file not existing
  when MODE is FILE_READ).
  Example (of writing a file):
    int handle = FileOpen ("temp.tmp", FILE_WRITE);
    if (handle == 0) Display("Error opening file.");
    else {
      FileWrite (handle, "test string");
      FileClose (handle);
      }
  IMPORTANT: This function will ONLY work with files in the game directory.
  You CANNOT use a path, so any filename with "\" or "/" in it will
  automatically be rejected, for security reasons.
  SeeAlso: FileClose, FileRead, FileWrite
FileRead (int handle, string buffer)
  Reads a string into BUFFER, from a file previously opened with FileOpen
  which returned HANDLE. You should only use this with files which you
  previously wrote out with FileWrite. Do NOT use this function with any
  other files, even text files.
  SeeAlso: FileOpen, FileWrite
FileReadInt (int handle)
  Reads an integer from the file HANDLE, and returns it to the script.
  Only integers written with FileWriteInt can be read back.
  SeeAlso: FileRead, FileWriteInt
FileReadRawChar (int handle)
  Reads a raw character from the input file HANDLE and returns it. This
  function allows you to read from files that weren't created by your game,
  however it is recommended for expert users only.
  SeeAlso: FileRead, FileReadRawInt
FileReadRawInt (int handle)
  Reads a raw 32-bit integer from the input file and returns it to the script.
  This allows you to read from files created by other programs - however, it
  should only be used by experts as no error-checking is performed.
  SeeAlso: FileRead, FileReadRawChar
FileWrite (int handle, string text)
  Writes TEXT to the file HANDLE, which must have been previously opened
  with FileOpen for writing. The string is written using a custom format to
  the file, which can only be read back by using FileRead.
  SeeAlso: FileRead, FileOpen, FileWriteRawLine
FileWriteInt (int handle, int value)
  Writes VALUE to the file HANDLE. This allows you to save the contents of
  variables to disk. The file must have been previously opened with FileOpen,
  and you can read the value back later with FileReadInt.
  SeeAlso: FileReadInt, FileWrite
FileWriteRawLine (int handle, string text)
  Writes a string of text to the file in plain text format. This enables
  you to read it back in Notepad or any editor; however, your game cannot
  read the file back in. This is useful for generating logs and such like.
  The TEXT will be printed to the file, followed by the newline characters.
  SeeAlso: FileWrite
FlipScreen (int way)
  Flips the screen round either the horizontal or vertical axis, or both.
  This function is for special effects only - all co-ordinates remain the
  same and it doesn't effect any other script functions.
  The value of WAY selects:
   0  normal
   1  horizontal-flip (upside-down)
   2  vertical-flip  (left-to-right)
   3  both (upside-down and backwards)
  NOTE: This function is still a bit buggy - black parts of the screen may
  show up wrong, and and pop-up messages will flip the screen back to normal.
FollowCharacter (CHARID, int chartofollow)
  Tells the character CHARID to follow CHARTOFOLLOW around, wherever he goes.
  You could use this command to have a group of main characters who go around
  together, or for example when the hero has rescued someone from the bad
  guy, they can follow the hero home.
  Pass CHARTOFOLLOW as -1 to stop the character following.
  SeeAlso: FollowCharacterEx
FollowCharacterEx (CHARID, int chartofollow, int dist, int eagerness)
  Does the same thing as FollowCharacter (see above), but allows you to set
  extra parameters. DIST sets how far away from CHARTOFOLLOW that CHARID will
  stand. If DIST is 1, they will try to stand very close; if DIST is for
  example 20, they will stand about 20 pixels away.
  EAGERNESS sets on average how long the character will stand around before
  checking if he needs to move again. Setting this to 0 means that he will
  always be on the move until he reaches CHARTOFOLLOW; setting this to 99
  means that he will pause and think for a while on route. Values in between
  specify different lengths of idle time.
  The default values are DIST=10 and EAGERNESS=97.
  As a special case, setting DIST=0 and EAGERNESS=0 makes CHARID behave as if
  it is chasing CHARTOFOLLOW - it will try and get there as quickly as possible.
  Setting EAGERNESS=0 also tells the character not to stop when they reach
  CHARTOFOLLOW, but instead to randomly wander around the character - useful
  perhaps for a very energetic dog or something.
  SeeAlso: FollowCharacter
GetBackgroundFrame()
  Returns the number of the current background being displayed. In a room
  without animating backgrounds, this will always return 0. Otherwise, the
  current frame number is returned from 0 to 4.
  SeeAlso: SetBackgroundFrame
GetCharacterAt (int x, int y)
  Checks if there is a character at SCREEN co-ordinates (X,Y).
  Returns the character number if there is, or -1 if there is not.
  See the description of GetLocationName for more on screen co-ordinates.
  NOTE: Any characters with the "No interaction" flag set will not be seen
  by this function.
  SeeAlso: GetHotspotAt, GetObjectAt, GetLocationName
GetCurrentMusic()
  Returns the number of the currently playing background music, or -1 if
  no music is playing.
  SeeAlso: IsMusicPlaying, IsSoundPlaying, SetMusicRepeat, SetMusicVolume
GetCursorMode()
  Returns the value of the current mode of the cursor. This is either
  MODE_LOOK, MODE_USE, MODE_TALK or any custom modes you have created.
  SeeAlso: SetCursorMode
GetGameSpeed ()
  Returns the current game speed (number of cycles per second).
  SeeAlso: SetGameSpeed
GetGlobalInt (int index)
  Returns the value of global variable INDEX.
  SeeAlso: SetGlobalInt
GetGUIAt (int x, int y)
  Checks whether there is currently a GUI at screen co-ordinates (X,Y). If
  there is, returns its GUI number.
  If there is not currently a displayed, clickable GUI at the location,
  returns -1.
  SeeAlso: GetGUIObjectAt
GetGUIObjectAt (int x, int y)
  Checks whether there is a GUI object at screen co-ordinates (X,Y). Returns
  its object (button) number if there is, or -1 if there is not. You probably
  want to use this in conjunction with GetGUIAt.
  SeeAlso: GetGUIAt
GetHotspotAt (int x, int y)
  Returns the number of the hotspot at SCREEN co-ordinates (X,Y).
  If there is no hotspot there, or if invalid co-ordinates are specified,
  returns 0.
  See the description of GetLocationName for more on screen co-ordinates.
  SeeAlso: GetLocationName, GetLocationType
GetInvName (int item, string buffer)
  Fills in BUFFER with the name of inventory item index ITEM. This is the
  name which the item is given under the Game tab, Inventory mode of the Room
  Editor.
  This function is mainly useful for a lucasarts-style status line:
   GetInvName (player.activeinv, buffer);
  SeeAlso: GetLocationName
GetLanguageString (int index, string buffer)
  Reads the language text string INDEX into BUFFER. The AGS language
  definition files consist of a collection of numbered strings with various
  system text in a particular language. Whenever possible, you should use
  this function rather than putting text directly into your script file, as
  it gives flexibility and multilingual support.
  For example, if you wanted to display a message "Do you want to see the
  intro?", you should check the message file, and find that message 300
  reads "Do you want to watch the introduction?". In this case, you should
  then use GetLanguageString(300,buffer) rather than using your text directly.
  You can add your own custom strings to the message files by using message
  numbers of 500 and above.
GetLocationName (int x, int y, string buffer)
  Fills in BUFFER with the name of whatever is on the screen at (X,Y). This
  allows you to create the Lucasarts-style status lines reading "Look at xxx"
  as the player moves the cursor over them.
  NOTE: The co-ordinates are SCREEN co-ordinates, NOT ROOM co-ordinates. This
  means that with a scrolling room, the co-ordinates you pass are relative to
  the screen's current position, and NOT absolute room co-ordinates. This
  means that this function is suitable for use with the mouse cursor position
  variables.
  For example,  GetLocationName(mouse.x, mouse.y, buffer);
  SeeAlso: GetInvName, GetLocationType
GetLocationType (int x, int y)
  Returns what type of thing is at location (X,Y); whether it is a character,
  object, hotspot or nothing at all. This may be useful if you want to
  process a mouse click differently depending on what the player clicks on.
  NOTE: The co-ordinates are screen co-ordinates, NOT room co-ordinates. See
  description of GetLocationName for more info.
  The value returned means that the location is:
   0   nothing, GUI or inventory
   1   a hotspot
   2   a character
   3   an object
  SeeAlso: GetHotspotAt, GetLocationName, GetObjectAt
GetMIDIPosition ()
  Returns the current MIDI beat number of the current track. If there is
  no track playing, or if it's not a MIDI track, returns -1.
  SeeAlso: SeekMIDIPosition
GetObjectAt (int x, int y)
  Checks if there is a room object at SCREEN co-ordinates (X,Y).
  Returns the object number if there is, or -1 if there is not.
  See the description of GetLocationName for more on screen co-ordinates.
  SeeAlso: GetHotspotAt, GetLocationName
GetObjectGraphic (int object)
  Returns the current slot number that OBJECT is displayed as.
  SeeAlso: SetObjectGraphic
GetObjectX (int object)
  Returns the X co-ordinate of room object number OBJECT.
  SeeAlso: GetObjectY, IsObjectAnimating, SetObjectPosition
GetObjectY (int object)
  Returns the Y co-ordinate of room object number OBJECT.
  SeeAlso: GetObjectX, IsObjectAnimating, SetObjectPosition
GetPlayerCharacter ()
  Returns the current character which the player is controlling.
  SeeAlso: SetPlayerCharacter
GetSaveSlotDescription (int slot, string buffer)
  Gets the text description of save game slot SLOT into the provided BUFFER.
  If the slot number provided does not exist this function returns 0, if
  successful it returns 1.
  SeeAlso: RestoreGameSlot, SaveGameSlot
GetSliderValue (int gui, int object)
  Returns the value of slider OBJECT on GUI to your program. You would usually
  use this command in the interface_click function to find out what value the
  player has changed the slider to, in order to process their command.
  SeeAlso: SetLabelText, SetSliderValue
GetTextBoxText (int gui, int object, string buffer)
  Retrieves the contents of textbox OBJECT on gui GUI into the BUFFER.
  This allows you to find out what the player typed in, and to respond
  appropriately.
  SeeAlso: SetTextBoxText, StrCaseComp, StrComp
GetTime (int whichvalue)
  This function returns various values, representing the current system time.
  You could use this for timing a loop, or for effects like telling the
  player to go to bed, and so on.
  The WHICHVALUE parameter controls what is returned:
   1  current hour (0-23)
   2  current minute (0-59)
   3  current second (0-59)
   4  current day (1-31)
   5  current month (1-12)
GetViewportX ()
  Returns the X-offset of the current viewport in a scrolling room. This
  allows you to find out what part of the room the player is looking at.
  The co-ordinate returned is the left edge of the screen, and so it can
  have a value between 0 and (ROOM WIDTH - 320).
  If the room is a non-scrolling room, returns 0.
  See the SetViewport function description for more information.
  SeeAlso: GetViewportY, SetViewport
GetViewportY ()
  Returns the Y-offset of the current viewport in a scrolling room. This
  allows you to find out what part of the room the player is looking at.
  The co-ordinate returned is the top edge of the screen, and so it can
  have a value between 0 and (ROOM HEIGHT - 200).
  If the room is a non-scrolling room, returns 0.
  SeeAlso: GetViewportX, SetViewport
GiveScore (int score)
  Adds SCORE to the player's score. This is preferable to directly modifying
  the variable since it will play the score sound, update any status lines
  and call the GOT_SCORE on_event function.
  Note that SCORE can be negative, in which case the score sound is NOT played.
InputBox (string prompt, string buffer)
  This function allows your script to read a string typed in by the user.
  When this function is called it pops up a window asking the user to type
  in a string, with PROMPT as the text in the window. What they type in will
  be copied into BUFFER.
  Note that this function only allows small strings (about 20 characters)
  due to the size of the input box it uses.
  SeeAlso: StringToInt
InterfaceOff (int interface)
  Turns interface element number INTERFACE off. It will no longer appear on
  the screen (or, if it is a pop-up interface, it cannot be popped up).
  SeeAlso: InterfaceOn
InterfaceOn (int interface)
  Turns interface element number INTERFACE on and displays it on the screen.
  This can be used to display a previously turned off interface, or to bring
  up a special interface like an inventory window.
  If the specified interface is a script-only interface (set to "On script
  command" in the Room Editor), then the game will be paused while the
  interface is displayed, and you should use InterfaceOff as a reaction to
  a button click in the interface to remove it.
  SeeAlso: InterfaceOff, IsGamePaused
InventoryScreen ()
  Brings up the Sierra-style inventory window which allows the player to
  select and manipulate inventory items. If they select one, the cursor mode
  will be set to inventory-use (mode 4), and  character[EGO].activeinv  will
  be set to the inventory item selected.
  NOTE: This function does not actually bring up the window immediately;
  instead, it will show the window when the current script function finishes
  executing.
  NOTE: If the player has no inventory items, global message 996 will be
  displayed.
IsButtonDown ( BUTTON )
  Tests whether the user has the specified mouse button down. BUTTON is either
  LEFT or RIGHT. Return 1 if the button is currently pressed, 0 if not. This
  could be used to test the length of a mouse click and similar effects.
  SeeAlso: IsKeyPressed
IsGamePaused ()
  Returns 1 if the game is currently paused, or 0 otherwise.
  The game is paused when either the icon bar interface has been popped up,
  or a "script-only" interface has been displayed with InterfaceOn. While
  the game is paused, no animations or other updates take place.
  SeeAlso: InterfaceOn
IsGUIOn (int gui)
  Checks whether the specified GUI is currently displayed or not. Returns 1
  if it is, 0 if not.
  SeeAlso: InterfaceOff, InterfaceOn
IsInterfaceEnabled ()
  Returns 1 if the player interface is currently enabled, 0 if it is disabled.
  The user interface is disabled while the cursor is set to the Wait cursor -
  ie. while the character is performing a blocking Walk, or other blocking
  action.
  SeeAlso: DisableInterface, EnableInterface
IsKeyPressed (int keycode)
  Tests whether the supplied key on the keyboard is currently pressed down
  or not. You could use this to move an object while the player holds an
  arrow key down, for instance.
  KEYCODE is one of the ASCII codes from section 6.6, with some limitations:
  since it tests the raw state of the key, you CANNOT pass the Ctrl+(A-Z)
  or Alt+(A-Z) codes (since they are key combinations). You can, however,
  use some extra codes which are listed at the bottom of the section.
  Returns 1 if the key is currently pressed, 0 if not.
  SeeAlso: IsButtonDown
IsMusicPlaying ()
  Returns 1 if the background music track is still playing. If you are using
  the Repeat Music option, this will always return 1 since the music will
  loop round when it finishes. Otherwise, this will return 0 once the
  current track finishes.
  SeeAlso: GetCurrentMusic
IsObjectAnimating (int object)
  Returns 1 if the specified OBJECT is currently animating.
  Returns 0 if the object has finished its animation.
  SeeAlso: IsObjectMoving, GetObjectX, GetObjectY
IsObjectMoving (int object)
  Returns 1 if the object is currently moving, or 0 if not.
  SeeAlso: IsObjectAnimating
IsSoundPlaying ()
  Returns 1 if there is currently a sound effect playing. This could be
  a manually started sound (eg. with PlaySound) or an automatic sound (eg.
  with GiveScore).
  If the sound has finished, or none was played, returns 0.
  NOTE: Be careful with this function for actions like looping sounds, since
  if the user doesn't have a sound card this will always return 0.
  NOTE: This function does not report if background music is playing.
  SeeAlso: GetCurrentMusic
IsTimerExpired (int timer_id)
  Checks whether the timer TIMER_ID has expired.
  If the timeout set with SetTimer has elapsed, returns 1.
  Otherwise, returns 0.
  Note that this function will only return 1 once - after that, the timer
  is placed into an OFF state where it will always return 0 until restarted.
  SeeAlso: SetTimer
IsVoxAvailable()
  Returns whether the SPEECH.VOX file is being used by the game.
  This could be useful if you have an optional speech download pack, and
  you want to know whether the player has it or not.
  Returns 1 if the speech files are available, 0 if not.
ListBoxAdd (int gui, int object, string newitem)
  Adds NEWITEM to the list box OBJECT on GUI. The item will be appended to
  the end of the list.
  SeeAlso: ListBoxClear, ListBoxDirList
ListBoxClear (int gui, int object)
  Removes all items from the specified list box.
  SeeAlso: ListBoxAdd
ListBoxDirList (int gui, int object, string filemask)
  Fills the list box OBJECT on gui GUI with a list of filenames matching
  the FILEMASK in the current directory. This could be useful if you have
  various data files and the player can choose which one to load.
  FILEMASK is a standard DOS/Windows search expression such as "*.dat"
  or "data*.*".
  SeeAlso: ListBoxAdd, ListBoxClear, ListBoxSaveGameList
ListBoxGetItemText (int gui, int object, int item, string buffer)
  Fills BUFFER with the text from list item number ITEM in listbox OBJECT on
  gui GUI. This is useful for finding out the name of the option the user
  selected.
  SeeAlso: ListBoxGetSelected
ListBoxGetNumItems (int gui, int object)
  Returns the number of items in the specified listbox. Valid item indexes
  range from 0 to (numItems - 1).
  SeeAlso: ListBoxGetItemText
ListBoxGetSelected (int gui, int object)
  Returns the index into the list of the currently selected item. The first
  item is 0, second is 1, and so on. If no item is selected, returns -1.
ListBoxSaveGameList (int gui, int object)
  Fills the specified listbox with the save game list, sorted correctly
  with the most recent game at the top of the list.
  The global  savegameindex  array is updated with the actual slot numbers
  of the entries. So, you could do:
    int index = ListBoxGetSelected (GUI_NUMBER, OBJECT_NUMBER);
    RestoreGameSlot (savegameindex[index]);
  NOTE: The save game list can only hold 20 save games. If ListBoxGetNumItems
  returns 20 and you are doing a Save dialog box, you may want to make the
  user replace an existing file rather than saving a new one.
  SeeAlso: ListBoxDirList, ListBoxGetSelected, ListBoxGetNumItems
ListBoxSetSelected (int gui, int object, int selection)
  Changes the currently selected item in the list to SELECTION. Indexes start
  at 0 for the first item, 1 for the second, and so on. If you specify an
  item that does not exist (eg. -1), the highlight will be removed.
LoseInventory (int what)
  Removes inventory item WHAT from the current player character's inventory.
  If they do not have the item, nothing happens.
  SeeAlso: AddInventory
MergeObject (int object)
  Merges object number OBJECT into the background scene for this room.
  By doing this, the object becomes part of the background and so does not
  slow the game down. This is a 1-way operation - once the object has
  been merged, it cannot be changed back and the state of the room is
  permanently altered. Therefore you should only use this function if a game
  event has occured that means the room is permanently changed.
  NOTE: after calling this function, you cannot use the object any more and
  it is permanently removed from the game.
  NOTE: objects can only be merged if the object graphic was imported at
  the same colour depth as the background graphic
MoveCharacter (CHARID, int x, int y)
  Moves the character CHARID from its current location to X,Y. CHARID can
  be either the character's number (as GetPlayerCharacter returns) or its ID
  set in the Room Editor. If the character cannot get to X,Y it will be moved
  as close as possible.
  Note: this function only works with characters which are on the current
  screen.
  Note: if you need to find out when the character has reached its destination,
  use the  character[charid].walking  variable. See the variables section below
  for more information.
  SeeAlso: FaceCharacter, MoveCharacterToObject, MoveObject, StopMoving
MoveCharacterBlocking (CHARID, int x, int y, int direct)
  Moves the character CHARID to location (X,Y), waiting until they arrive
  there before returning to the script.
  If DIRECT is 0, this acts like MoveCharacter; if it is 1 then this acts
  like MoveCharacterDirect.
  SeeAlso: MoveCharacter, MoveCharacterDirect
MoveCharacterDirect (CHARID, int x, int y)
  Moves the character CHARID from its current location to (X,Y) directly,
  ignoring walkable areas on the screen. This is identical to the "Move to,
  ignore walls" animation command.
  SeeAlso: MoveCharacter, MoveCharacterStraight
MoveCharacterStraight (CHARID, int x, int y)
  Moves the character CHARID from its current location to (X,Y) in a straight
  line as far as is possible before hitting a non-walkable area. This is
  useful for use with the arrow keys for character movement, since it
  guarantees that the character will move in a straight line in the direction
  specified. This function is non-blocking.
  SeeAlso: MoveCharacter, MoveCharacterDirect
MoveCharacterToHotspot (CHARID, int hotspot)
  Moves the character CHARID from its current location to the walk-to point
  for the specified hotspot. If the hotspot has no walk-to point, nothing
  happens.
  This is a blocking call - control is not returned to the script until the
  character has reached its destination.
  SeeAlso: MoveCharacter, MoveCharacterToObject
MoveCharacterToObject (CHARID, int object)
  Moves the character CHARID from its current location to a position just below
  the object OBJECT. This is useful for example, if you want the man to pick
  up an object. Example:
    MoveCharacterToObject (EGO, 0);
    ObjectOff (0);
    AddInventory (3);
  This is a blocking call - control is not returned to the script until the
  character has reached its destination.
  SeeAlso: MoveCharacter, MoveCharacterToHotspot
MoveObject (int object, int x, int y, int speed)
  Starts the object OBJECT moving from its current location to (X,Y). It will
  move at speed SPEED, which uses the same scale as the character Walk Speed
  values in the Room Editor.
  SeeAlso: MoveCharacter, MoveObjectDirect
MoveObjectDirect (int object, int x, int y, int speed)
  Starts OBJECT moving from its current location to (X,Y), ignoring all
  walkable areas on the screen. The object will therefore move directly to
  the destination in a straight line.
  SeeAlso: MoveObject
MoveOverlay (int overlay_id, int x, int y)
  Repositions screen overlay OVERLAY_ID to have its upper-left corner
  at (X,Y). The move is instant (ie. it doesn't gradually glide over to the
  new position).
  SeeAlso: CreateTextOverlay, RemoveOverlay
MoveToWalkableArea (CHARID)
  Places character CHARID in the nearest walkable area to its current
  location. If the character is already on a walkable area, nothing happens.
  Otherwise it is placed in the nearest available area.
  This is useful for placing for example in the Player Enters Screen event
  of a screen, to make sure the character can move if a NewRoomEx has been
  issued to get there. You could also use this in on_event for ENTER_ROOM
  to use whenever a player enters a room.
NewRoom (int room_number)
  Changes the room the player is in. This command unloads the current room
  from memory and loads instead ROOMx.CRM, where X is room_number.
  IMPORTANT: This command does not change the room immediately; instead, it
  will perform the actual room change once your script function has finished
  (This is to avoid problems with unloading the script while it is still
  running). This means that you should not use any other commands which rely
  on the new room (object positionings, and so on) after this command within
  the same function.
  SeeAlso: NewRoomEx
NewRoomEx (int room_number, int x, int y)
  Identical to NewRoom, except that the player character is placed at
  co-ordinates (X,Y) in the new room.
  SeeAlso: NewRoom
ObjectOff (int object)
  Turns object number OBJECT off. It will no longer be displayed in this room
  until you use an ObjectOn command.
ObjectOn (int object)
  Turns object number OBJECT on. It may have been turned off previously with
  ObjectOff or may have been set initially off in RoomEdit.
ParseText (string text)
  Stores the supplied user text string for later use by Said.
  You need to call this command first with the user's input before using
  the Said command. You probably want to call this inside the interface_click
  function when your text box control is activated.
  SeeAlso: Said
PauseGame ()
  Stops the engine processing character movement and animation, and other
  game features. This has the same effect on the game as happens when a
  script-only interface is popped up. The processing will not resume until
  you call the UnPauseGame function.
  SeeAlso: UnPauseGame
PlayFlic (int flic_number, int options)
  Plays a FLI or FLC animation. The game checks for FLICx.FLC and FLICx.FLI
  (where X is FLIC_NUMBER) and if it finds one, plays it.
  OPTIONS has these meanings:
    0  player can't skip animation
    1  player can press ESC to skip animation
    2  player can press any key or click mouse to skip animation
  +10 (ie.10,11,12) do not stretch to full-screen, just play at flc size
  This is identical to the room interaction command "Play FLI/FLC %d". The
  game is paused while the animation plays.
PlayMusic (int music_number)
  Changes the currently playing background music to MUSICx.MID, MUSICx.MOD
  or MUSICx.XM (where X is MUSIC_NUMBER). The game will search for the files
  in that order until it finds one to play.
  SeeAlso: PlaySound
PlaySound (int sound_number)
  Plays a WAV or VOC sound effect. The game will search for SOUNDx.VOC
  and SOUNDx.WAV (where x is SOUND_NUMBER) and play it. This is identical to
  the room interaction command "Play sound %d".
  Pass -1 as SOUND_NUMBER to stop any currently playing sounds.
  SeeAlso: PlayMusic
ProcessClick (int x, int y, int mode)
  Simulates clicking the mouse on the location (X,Y) on the screen, in the
  cursor mode MODE. Any conditions attached will be executed. For example,
  ProcessClick (100, 50, MODE_LOOK);
  will simulate clicking the mouse on co-ordinates (100,50) in the Look mode.
  NOTE: This function ignores all interfaces and acts as though the point is
  directly visible. In other words, if the co-ordinates you pass happen to
  lie on a button on an interface, what actually happens will be as if the
  user clicked behind the interface onto the actual screen.
  Available cursor modes: MODE_WALK, MODE_LOOK, MODE_USE, MODE_TALK,
  MODE_USEINV, MODE_PICKUP.
  SeeAlso: RunHotspotInteraction
QuitGame(int ask_first)
  Exits the game and returns to the operating system (DOS, Windows, etc).
  If ASK_FIRST is zero, it will exit immediately. If ASK_FIRST is not zero,
  it will first display a message box asking the user if they are sure they
  want to quit.
Random (int max)
  Returns a random number between 0 and MAX. This could be useful to do
  various effects in your game.
RawClearScreen (int colour)
  The family of "raw" functions allow you direct access to the screen to
  do whatever you want with it. However, anything you do with these functions
  is permanent on the screen until the player leaves the room. They are
  most useful for things like a character stats screen where you want to
  print information directly to the screen.
  This function clears the screen to the specified COLOUR. (this is a number
  you can find in the Game, Palette mode of roomedit). Whatever is currently
  on the background will be wiped.
  NOTE: any GUIs you have will still appear on top of the screen, so if you
  want complete control you'll need to turn the GUIs off too.
  SeeAlso: RawSetColor
RawDrawImage (int x, int y, int slot)
  Draws image SLOT from the sprite manager onto the screen at location (X,Y).
  SeeAlso: RawPrint, RawDrawLine
RawDrawLine (int from_x, int from_y, int to_x, int to_y)
  Draws a line from (FROM_X, FROM_Y) to (TO_X, TO_Y) in the current raw
  drawing colour.
  SeeAlso: RawSetColor, RawDrawTriangle
RawDrawTriangle (int x1, int y1, int x2, int y2, int x3, int y3)
  Draws a filled triangle in the current colour with corners at the points
  (x1,y1), (x2,y2) and (x3,y3).
  Well, don't look at me, you might find it useful for something :-)
  SeeAlso: RawDrawImage, RawDrawLine
RawPrint (int x, int y, string text, ...)
  This function prints the specified TEXT to screen location (X,Y). It
  accepts Display-style "%d" and "%s" arguments to display variable values.
  The text will be printed using the normal font and the current raw colour.
  SeeAlso: RawSetColor, SetNormalFont
RawRestoreScreen ()
  Restores the screen from the backup image created with RawSaveScreen.
  Use this when you want to get back what was there before you started
  drawing.
  SeeAlso: RawSaveScreen
RawSaveScreen ()
  Makes a backup of the current background screen, in order that it can be
  restored later. This could be useful to back up the original image before
  writing over it, or to save a certain state of your drawing to restore
  later. Only one raw backup image can exist at a time, so this overwrites
  any previous saves you made.
  NOTE: The backup image is lost when the player leaves the screen, or if
  they load a saved game position. Therefore, this is best only for short-term
  effects.
  SeeAlso: RawRestoreScreen
RawSetColor (int colour)
  Sets the colour to be used for future raw drawing routines to COLOUR. This
  is a number you can obtain from the Game, Palette mode in roomedit.
  SeeAlso: RawClearScreen, RawDrawLine, RawPrint
RefreshMouse ()
  Updates the global variables "mouse.x" and "mouse.y" with the current
  position of the mouse. Normally, these variables are set just before each
  script function is executed. However, if you have a very long script where
  the mouse may have moved since the start of the function, and you need the
  exact current location, then RefreshMouse will update the variables.
ReleaseCharacterView (CHARID)
  Allows the engine to automatically control the character's view, as normal.
  Use this once you have finished doing the animation which you started with
  the SetCharacterView command.
  SeeAlso: SetCharacterView
ReleaseViewport ()
  Releases the lock on the screen viewport, allowing it to automatically
  scroll around following the player character as normal.
  SeeAlso: SetViewport
RemoveOverlay (int overlay_id)
  Removes the specified overlay from the screen. OVERLAY_ID is the value
  returned from the overlay creation functions like CreateTextOverlay.
  SeeAlso: CreateTextOverlay
RemoveWalkableArea (int areanum)
  Removes the walkable areas in colour AREANUM from the current room. You can
  put the area back with RestoreWalkableArea.
  NOTE: When the player leaves the screen, all the walkable areas are reset.
  Therefore, if you want an area to remain off when they leave the screen,
  you will need to set a flag, then run the RemoveWalkableArea command in
  the "Player enters screen" event when they return.
  SeeAlso: RestoreWalkableArea
ResetRoom (int room_number)
  Discards all the data that the engine has in memory about when the player
  last visited ROOM_NUMBER, and resets it as if they'd never been there. The
  next time the player goes to that room, all the objects and scripts will
  be in their initial state (as set up in roomedit), and not how they were
  when the player left the room. The "First time enters screen" event will be
  run when they enter this room again.
  This function is useful if you want to have a "View intro" option to allow
  the player to watch an intro again - this function can reset all the
  objects in the intro rooms to their starting positions.
  NOTE: You cannot reset the current room (ie. the room that the player is in).
RestartGame ()
  Restarts the game from the beginning.
RestoreGameDialog ()
  Displays the restore game dialog, where the player can select a previously
  saved game position to restore.
  The dialog is not displayed immediately; instead, it will be displayed when
  the script function finishes executing.
  SeeAlso: RestoreGameSlot, SaveGameDialog
RestoreGameSlot (int slot)
  Restores the game position saved into slot number SLOT. You might want to
  use these specific slot functions if for example you only want to allow the
  player to have one save game position rather than the usual 20. If this slot
  number does not exist, an error message is displayed to the player but the
  game continues. To avoid the error, use the GetSaveSlotDescription function
  to see if the position exists before restoring it.
  NOTE: The position will not be restored immediately; instead, it will be
  restored when the script function finishes executing.
  SeeAlso: GetSaveSlotDescription, RestoreGameDialog, SaveGameSlot
RestoreWalkableArea (int areanum)
  Makes the area AREANUM walkable again.
  SeeAlso: RemoveWalkableArea
RunCharacterInteraction (CHARID, int mode)
  Processes the interaction list as if the player had clicked the mouse
  on character CHARID in cursor mode MODE. MODE is one of the MODE_* constants
  listed in the ProcessClick description.
  SeeAlso: ProcessClick, RunHotspotInteraction
RunDialog (int topic)
  Starts a conversation using topic number TOPIC. This is identical to the
  "Run dialog topic %d" room interaction command.
  Note: The conversation will not start immediately; instead, it will be run
  when the current script function finishes executing.
  SeeAlso: SetDialogOption
RunHotspotInteraction (int hotspot, int mode)
  Processes the interaction list as if the player had clicked the mouse
  on hotspot number HOTSPOT in the current room, using cursor mode MODE.
  MODE is one of the MODE_* constants listed in the ProcessClick description.
  May be useful with the text parser for simulating a mouse click if they
  type specific words in.
  SeeAlso: ProcessClick, RunCharacterInteraction, RunObjectInteraction
RunObjectInteraction (int object, int mode)
  Processes the interaction list as if the player had clicked the mouse
  on object number OBJECT in the current room, using cursor mode MODE.
  MODE is one of the MODE_* constants listed in the ProcessClick description.
  SeeAlso: ProcessClick, RunCharacterInteraction, RunHotspotInteraction
Said (string text)
  Checks whether the player typed in TEXT in their input passed to ParseText.
  Returns 1 if it matches, 0 otherwise.
  See section 4.6 for a more detailed description.
  SeeAlso: ParseText, SaidUnknownWord
SaidUnknownWord (string buffer)
  If a word not in the game dictionary was submitted to the last ParseText
  call, then BUFFER is filled with the word. This allows you to display a
  message like "Sorry, this game doesn't recognise 'XXXX'."
  Returns 1 if the player typed an unknown word, or 0 if all words were
  recognised.
  Example use:
    string buffer;
    if (SaidUnknownWord (buffer)) {
      Display("You can't use '%s' in this game.", buffer);
    }
  SeeAlso: ParseText, Said
SaveGameDialog ()
  Displays the save game dialog, where the player can save their current
  game position. If they select to save, then the game position will be saved.
  SeeAlso: RestoreGameDialog, SaveGameSlot
SaveGameSlot (int slot, string description)
  Saves the current game position to the save game number specified by SLOT,
  using DESCRIPTION as the textual description of the save position.
  Be careful using this function, because you could overwrite one of the
  player's save slots if you aren't careful.
  The SaveGameDialog function uses slots numbered from 1 to 20, so if you
  don't want to interfere with the player's saves, I would recommend saving
  to slot numbers of 100 and above.
  SeeAlso: RestoreGameSlot, SaveGameDialog
SaveScreenShot (string filename)
  Takes a screen capture and saves it to disk. The FILENAME must end in
  either ".BMP" or ".PCX", as those are the types of files which can be saved.
  Returns 1 if the shot was successfully saved, or 0 if an invalid file
  extension was provided. For example,   SaveScreenShot("capture.bmp");
SeekMIDIPosition (int position)
  Seeks the currently playing MIDI file to midi beat number POSITION. If
  the current track is not a MIDI track, has no effect.
  SeeAlso: GetMIDIPosition
SeekMODPattern (int pattern)
  Jumps directly to PATTERN in the currently playing MOD/XM music. If the
  pattern does not exist, the music will stop.
SetActiveInventory (int inv_item)
  Sets the current active inventory item for the current player character
  to INV_ITEM. This function changes the player.activeinv variable, and also
  sets up the mouse cursor as necessary.
  To deselect the current inventory, pass INV_ITEM as -1.
SetAreaLightLevel (int area, int level)
  Changes walkable area number AREA to have light level LEVEL. This does
  the same thing as the Light Level buttons in roomedit, but allows you to
  change it at run-time.
  AREA is from 1 to 15 (the walkable area number), and LEVEL is from -100
  to 100. (0 is the defualt non-lit level).
  NOTE: The light level will be reset when the player leaves the room,
  so you need to use it in Player Enters Screen if you want a permanent
  change.
SetBackgroundFrame (int frame)
  Locks the background to frame number FRAME of an animating-background
  screen. (Values for FRAME are from 0 to 4). This allows you to use the
  animating backgrounds feature for another purpose - you can have two
  frames of the background, one for example with a spaceship crashed on it.
  Then, once the right event has happened, call SetBackgroundFrame in the
  Player Enters Screen event to set the background before the screen fades in.
  Call SetBackgroundFrame(-1) to set the default animating frames.
  The frame lock is released when the game changes rooms.
  SeeAlso: GetBackgroundFrame
SetButtonPic (int gui, int object, int which, int newslot)
  Changes a GUI button's graphic to the one you specify. This could be used
  as an indicator of whether a feature is switched on or off by changing its
  picture. Sets object number OBJECT on gui GUI to NEWSLOT from the sprite
  manager.
  The WHICH parameter selects which picture to change. It can have these
  values:
   1  normal picture
   2  mouse-over picture
   3  button pushed picture
  Note that you can pass NEWSLOT as -1 to disable the mouse-over and pushed
  pictures. For example, if the GUI setup in roomedit specifies a pushed-pic,
  but you want to change the main picture in the game (and so remove the
  old pushed picture), you can do something like this:
   SetButtonPic (2, 3, 1, new_picture);
   SetButtonPic (2, 3, 3, -1);
  which will change button 3 on GUI 2 to have normal picture NEW_PICTURE and
  not have a pushed graphic.
  SeeAlso: SetLabelText
SetCharacterBaseline (CHARID, int baseline)
  Changes CHARID's baseline to BASELINE. This allows you to set a specific
  base line for the character, which works similarly to walk-behind area and
  object baselines.
  BASELINE can be from 1 to the height of the room (normally 200), or set it
  to 0 to go back to using the character's feet as the baseline.
  SeeAlso: SetObjectBaseline, SetWalkBehindBase
SetCharacterClickable (CHARID, int is_clickable)
  Sets whether the character CHARID is recognised as something which the
  player can interact with. This allows you to modify the "No interaction"
  tick-box set initially in RoomEdit.
  If you pass IS_CLICKABLE as 1, then the player can look at, speak to, and
  so on the character (as with the old Sierra games). If you pass IS_CLICKABLE
  as 0, then if the player clicks on the character it will activate whatever
  is behind them (as with the old Lucasarts games).
  SeeAlso: SetObjectClickable
SetCharacterIdle (CHARID, int idleview, int delay)
  Changes the character CHARID's idle view to IDLEVIEW, with a timeout
  of DELAY seconds of inactivity before it is played. Inactivity is defined
  as when the character is not moving and not being animated.
  Setting DELAY to 0 causes the idle view to be looped continuously when
  the character is not moving - this is useful when for example the character
  is swimming and they need to tread water when idle.
  Pass IDLEVIEW as -1 to disable the idle view completely.
SetCharacterIgnoreLight (CHARID, int ignore)
  Allows you to dynamically modify the "ignore lighting" checkbox for the
  character in roomedit. Pass IGNORE as 1 for this character to always look
  the same, and not be affected by the light level of walkable areas.
  Pass 0 for this character to behave as normal and be affected by area light
  levels.
SetCharacterIgnoreWalkbehinds (CHARID, int ignore)
  Sets whether character CHARID is affected by walkbehind areas. Passing 0
  (the default setting) means that the character will be placed behind walk-
  behind areas according to the relevant baselines.
  Passing 1 means that the character will never be placed behind a walk-behind
  area. This is useful if for example you want to use the character as an
  overlay to display rain or snow onto a scene.
  SeeAlso: SetObjectIgnoreWalkbehinds
SetCharacterSpeed (CHARID, int newspeed)
  Changes the character CHARID's walking speed to NEWSPEED. The values
  used for NEWSPEED are identical to those set in the Room Editor for
  walking speed.
  NOTE: This function CANNOT be called while the character is moving, so
  you must stop him first.
  SeeAlso: MoveCharacter, StopMoving
SetCharacterTransparency (CHARID, int amount)
  Sets character CHARID to be AMOUNT % transparent.
  This works in a similar way to SetObjectTransparency - see that description
  for more information.
  SeeAlso: SetObjectTransparency
SetCharacterView (CHARID, int view)
  Sets character CHARID's view to VIEW. This can be used to perform animations
  with charaters, for example bending down to pick something up, which don't
  use the default view.
  NOTE: This function locks the character's view to the specified view, so
  that it can only be changed by other script commands (ie. it won't
  automatically be changed by the program on shadow areas, screen changes,
  etc). When you are done with the animation, call ReleaseCharacterView to
  allow the program to take control back.
  SeeAlso: AnimateCharacter, ChangeCharacterView, ReleaseCharacterView
SetCursorMode(int new_mode)
  Changes the mouse cursor mode to NEW_MODE. The number you pass can be
  obtained from the VISUAL>CURSORS tab of the Room Editor. This function
  changes both the appearance of the cursor and the mode used if the player
  clicks on a hotspot.
  SeeAlso: GetCursorMode, SetMouseCursor
SetDefaultCursor()
  Changes the appearance of the mouse cursor to the default for the current
  cursor mode. Use this to restore the cursor picture after you changed it
  with the SetMouseCursor function.
SetDialogOption (int topic, int option, int new_state)
  Changes whether an option in a conversation is available to the player or
  not. This allows you to add extra options to a conversation once the player
  has done certain things.
  TOPIC is the topic number, from 0 to the number of topics - 1. Find this
  out in the Room Editor.
  OPTION is the option number within that topic, from 1 to whatever the
  highest option is for that topic.
  NEW_STATE controls what happens to this option. It can have the following
  values:
    0   The option is disabled - the player will not see it
    1   The option is enabled - the player can now see and use it
    2   The option is permanently disabled - no other command can ever turn
        it back on again.
  These are equivalent to the option-off, option-on, and option-off-forever
  dialog commands.
  SeeAlso: RunDialog, StopDialog
SetGameSpeed (int new_speed)
  Sets the game speed to NEW_SPEED frames per second, or as near as possible
  to that speed. The default frame rate is 40 fps, but you can speed up or
  slow down the game by using this function. Note that this speed is also the
  rate at which the Repeatedly_Execute functions are triggered.
  The NEW_SPEED must lie between 10 and 100. If it does not, it will be rounded
  to 10 or 100. Note that if you set a speed which the player's computer cannot
  handle (for example, a 486 will not be able to manage 80 fps), then it will
  go as fast as possible.
  NOTE: Because the mouse cursor is repainted at the game frame rate, at very
  low speeds, like 10 to 20 fps, the mouse will appear to be jumpy and not
  very responsive.
  SeeAlso: GetGameSpeed
SetGlobalInt (int index, int value)
  Sets the global variable INDEX to VALUE. You can then retrieve this value
  from any other script using GetGlobalInt.
  There are 300 available global variables, from index 0 to 299.
  SeeAlso: GetGlobalInt
SetGUIPosition (int gui, int x, int y)
  Moves the top-left corner of GUI to the new location (X,Y) on the screen.
  This allows you to dynamically move GUIs around on the screen while the
  game is running. The co-ordinates are screen co-ordinates, not room
  co-ordinates, and use the same scale as in RoomEdit.
SetInvDimensions (int width, int height)
  Allows you to change the default width and height of the inventory item
  picture slots used by the Lucasarts-style inventory window. By default,
  the LEC inv window is made up of 40x22 pixel cells, but if all your
  inventory item pictures are bigger or smaller than this, you can use this
  function to adjust them.
SetInvItemPic (int inv, int sprite_slot)
  Changes inventory item INV's graphic to be slot number SPRITE_SLOT from
  the Sprite Manager. This allows you to dynamically adjust an item's
  picture in the inventory window during the game.
SetLabelText (int gui, int object, string newtext)
  Changes the text displayed in the specified label to NEWTEXT. The affected
  label will be object OBJECT from GUI. You can find out a label's object
  number by looking at the Properties window of the label.
  This command allows you to change the text during the game, for example
  to create a Lucasarts-style status line.
  SeeAlso: SetButtonPic
SetMouseCursor(int new_cursor)
  Changes the appearance of the mouse cursor to NEW_CURSOR. Unlike
  the SetCursorMode function (see above), this does not change the mode
  used if the user clicks on a hotspot. This is useful for displaying a "wait"
  cursor temporarily.
  SeeAlso: ChangeCursorGraphic, SetCursorMode, SetDefaultCursor
SetMusicMasterVolume (int volume)
  Sets the overall music volume, from 0-100. This is slightly mofidied by the
  individual room volume settings.
  SeeAlso: SetMusicVolume
SetMusicRepeat (int loopflag)
  Tells the system whether to repeat background music tracks. LOOPFLAG is
  either 1 (repeat, default) or 0 (don't repeat).
  SeeAlso: SetMusicVolume
SetMusicVolume (int volume)
  Overrides the room volume setting and sets the volume to VOLUME instead.
  The values range from 1 to 5, representing each stage in the RoomEdit
  volume options (ie. 1=quietest, 5=loudest).
  NOTE: The volume will be reset when the player enters a new room.
  SeeAlso: SetMusicMasterVolume, SetSoundVolume, GetCurrentMusic
SetNormalFont (int font_number)
  Changes the font used for all in-game text, except speech. FONT_NUMBER must
  be from 0 to the number of fonts you have. By default the only options are 0
  and 1.
  SeeAlso: SetSpeechFont
SetObjectBaseline (int object, int baseline)
  Changes OBJECT's baseline to BASELINE. This modifies the line you can
  set in RoomEdit. You can disable the baseline (and revert to using the
  base of the object's image on the screen) by passing 0 as the baseline.
  Otherwise, the baseline is the Y screen co-ordinate you want to use,
  normally from 1 to 200 unless you have a taller than usual room.
  SeeAlso: SetCharacterBaseline, SetWalkBehindBase
SetObjectClickable (int object, int is_clickable)
  Sets whether the OBJECT is recognised as something which the player can
  interact with.
  If you pass IS_CLICKABLE as 1, then the player can look at, speak to, and
  so on the object. If you pass IS_CLICKABLE as 0, then the object will not
  respond to clicks and the mouse will activate whatever is behind the object.
  This is useful if you are using the object for visual effects and don't
  want it to be clicked on by the player.
  SeeAlso: SetCharacterClickable, SetObjectIgnoreWalkbehinds
SetObjectFrame (int object, int view, int loop, int frame)
  Sets object number OBJECT's graphic to frame FRAME of loop LOOP of view
  number VIEW. This is useful if you want the object to use the second loop
  in a view for an animation, because using the SetObjectView function in
  room startup code will cause loop 0 to breifly flash on the screen first.
  SeeAlso: SetObjectView
SetObjectGraphic (int object, int slot)
  Sets the graphic for object number OBJECT to slot number SLOT. You can get
  the slot number from the Sprite Manager in RoomEdit. If the object is
  currently animating (from an AnimateObject command) then the animation will
  be stopped.
  SeeAlso: SetObjectFrame, SetObjectView
SetObjectIgnoreWalkbehinds (int object, int ignore)
  Sets whether object OBJECT is affected by walkbehind areas. Passing 0 (the
  default setting) means that the object will be placed behind walk-behind
  areas according to the relevant baselines.
  Passing 1 means that the object will never be placed behind a walk-behind
  area. This is useful if for example you want an object to be a picture on
  a wall, and the wall can be walked behind - but you also want it to act
  correctly in relation to characters, so changing its baseline wouldn't work.
  SeeAlso: SetCharacterIgnoreWalkbehinds, SetObjectClickable
SetObjectPosition (int object, int x, int y)
  Changes the object number OBJECT's position to (X,Y). These co-ordinates
  specify the lower-left hand corner of the object.
  SeeAlso: GetObjectX, GetObjectY
SetObjectTransparency (int object, int amount)
  Sets OBJECT to be AMOUNT % transparent.
  Setting AMOUNT to 100 means it is totally invisible, and lower values
  represent varying levels of transparency. Pass AMOUNT as 0 to stop the
  object being transparent.
  NOTE: Transparency currently only works in hi-color games, and the object
    must have been imported in hi-colour for the transparency to work.
  NOTE: Having a large transparent object can significantly slow down the
    engine.
  SeeAlso: SetCharacterTransparency
SetObjectView (int object, int view)
  Sets object number OBJECT's view to VIEW. The graphic is set to the first
  frame of loop 0 of the view.
  SeeAlso: AnimateObject, SetObjectFrame
SetPalRGB (int slot, int red, int green, int blue)
  Changes the RGB components of one of the palette slots. The palette is
  initially set up in RoomEdit, but you can override it during the game using
  this function for special effects. The RED, GREEN and BLUE parameters each
  range from 0 to 63 (as used in the Palette Editor).
  If SLOT is a background slot, then this function's effect will last until
  the player changes screen, when the palette is changed to the new room's
  palette. If SLOT is not a background slot, the effect of this function is
  permanent.
  Note: This function will allow you to change the colours which are "locked"
  in the Room Editor. However, you should not normally do this as it can
  cause strange colours in the game.
  SeeAlso: CyclePalette, FadeIn, FadeOut, UpdatePalette
SetPlayerCharacter (int char_id)
  Changes the character which the player controls to CHAR_ID. You can either
  use the character's number, or the ID string set in the Room Editor.
  This function will also cause the room to change to the room which the
  chosen character is currently in. (It calls NewRoom with the character's
  room, so the change won't happen until the end of the script).
  Note: The "player" global variable is not updated with the new character;
  so using "player.x", "player.name" and so on will change the original
  character, not the current player character.
  SeeAlso: GetPlayerCharacter, NewRoom
SetRestartPoint ()
  Changes the game restart point to the current position. This means that
  from now on, if the player chooses the Restart Game option, it will return
  here.
  This function is useful if the default restart point doesn't work properly
  in your game - just use this function to move it.
SetScreenTransition (int trans_type)
  Changes the default screen transition. trans_type can be one of the
  following:
   TRANSITION_FADE
   TRANSITION_INSTANT
   TRANSITION_DISSOLVE
  All future transitions will be done as specified until you call this
  function again.
SetSkipSpeech (int new_mode)
  Changes whether the player can skip speech text by clicking the mouse.
  This option is initially set in a checkbox in the Main tab of RoomEdit, but
  this function allows you to change it at run-time.
  The value of NEW_MODE means the following:
   0  player can skip text by clicking mouse or pressing key
   1  player can skip text by pressing key only, not by clicking mouse
   2  player cannot skip text with mouse or keyboard
   3  text does not time-out; player must click mouse or press key each time
SetSliderValue (int gui, int object, int value)
  Changes the specified slider (object number OBJECT on GUI) to have the
  new value VALUE. VALUE must lie between the MIN and MAX settings for the
  slider, as set up in the GUI editor.
  SeeAlso: GetSliderValue, SetLabelText
SetSoundVolume (int volume)
  Sets the sound effect volume. VOLUME ranges from 0-255, where 255 is the
  loudest. This also effects MOD and XM music.
  SeeAlso: SetMusicVolume
SetSpeechFont (int font_number)
  Changes the font used for character speech. FONT_NUMBER must be from 0
  to the number of fonts you have. By default the only options are 0 and 1.
  SeeAlso: SetNormalFont
SetSpeechStyle (new_style)
  Changes the way in which speech text is displayed. This modifies the setting
  originally set in roomedit. NEW_STYLE can be:
    SPEECH_LUCASARTS     speech text over character's head
    SPEECH_SIERRA        close-up portrait of character
    SPEECH_SIERRABKGRND  close-up portrait + background window for text
    SPEECH_FULLSCREEN    QFG4-style full screen dialog pictures
SetSpeechVolume (int volume)
  Sets the volume for in-game speech. VOLUME ranges from 0-255, where 255 is
  the loudest. The default speech volume is 255 so this function can only
  be used to reduce the volume.
  SeeAlso: SetMusicVolume, SetSoundVolume
SetTalkingColor (CHARID, int newcolor)
  Changes the character CHARID's speech text color to NEWCOLOR. This could
  be useful if in a particular room, the background colour is very similar
  to the speech colour, so you can override it using this function.
  NEWCOLOR is the colour slot index from 0 to 255.
SetTextBoxText (int gui, int object, string newtext)
  Changes the text box OBJECT on gui number GUI to contain NEWTEXT. This
  might be useful to reset the text box to blank after the user has typed
  something in, or to fill in a default value.
  SeeAlso: GetTextBoxText, SetLabelText
SetTextOverlay (int overlay_id, int x, int y, int width, int font, int color, string text)
  Similar to CreateTextOverlay, except that this function replaces an
  existing overlay with the new text. This has two advantages over simply
  using RemoveOverlay followed by CreateTextOverlay to change the text -
  it is one function call, and it allows you to keep the same overlay ID
  number.
  SeeAlso: CreateTextOverlay, RemoveOverlay
SetTimer (int timer_id, int timeout)
  Starts timer TIMER_ID ticking - it will tick once every game loop (normally
  40 times per second), until TIMEOUT loops, after which it will stop.
  You can check whether the timer has finished by calling the IsTimerExpired
  function.
  Pass TIMEOUT as 0 to disable a currently running timer.
  There are 20 available timers, with TIMER_IDs from 1 to 20.
  SeeAlso: IsTimerExpired
SetViewport (int x, int y)
  Locks the screen viewport to having the top-left hand corner at (X,Y) in
  a scrolling room. This allows you to manually pan across a scrolling room
  or to have the screen follow a non-player character.
  The lock is released when you either call ReleaseViewport or the player
  changes rooms.
  NOTE: The co-ordinates supplied are 320x200-scale co-ordinates, and will
  be automatically multiplied up by the engine.
  NOTE: This function has no effect if the current room isn't a scrolling room.
  For example, to scroll around and follow character MAN in a specific room,
  put this in the room's repeatedly execute event:
    SetViewport (character[MAN].x - 160, character[MAN].y - 110);
  SeeAlso: GetViewportX, GetViewportY, ReleaseViewport
SetVoiceMode (int new_mode)
  Changes whether voice speech is used with dialog lines. The default
  is on if the voice file is present, or off otherwise.
  Valid values are:
   0  no voice, text only
   1  both voice and text
   2  voice only, no text
  WARNING: you should only ever use mode 2 at the player's request to do so,
  because there is no guarantee that they even have a sound card and so may
  not understand what is going on.
SetWalkBehindBase (int area, int baseline)
  Changes the walk-behind AREA to have new BASELINE. This effectively allows
  you to turn walk-behinds on and off, although you can do other tricks with
  it as well. BASELINE is from 1 to the height of the room (normally 200) and
  moves the line which you set originally in RoomEdit.
  Passing BASELINE as 0 disables the walk-behind area, so that the player
  will always walk in front of it.
  Basically, if the character's feet are below BASELINE, he will be drawn in
  front of it, otherwise he will be drawn behind it.
  SeeAlso: SetObjectBaseline
ShakeScreen (int amount)
  Shakes the screen to simulate, for example, an earthquake. AMOUNT is
  how much the screen shakes: 1 is hardly anything, and 25 is a lot.
StopDialog ()
  This command can only be used from within the dialog_request function. It
  tells AGS that when dialog_request finishes, the whole conversation should
  stop rather than continuing with the dialog script.
  You can use this function to end the conversation depending on whether the
  player has/does a certain thing.
  SeeAlso: SetDialogOption
StopMoving (CHARID)
  Stops the character CHARID moving and sets its graphic to the standing frame
  of the current loop.
  SeeAlso: MoveCharacter
StrCat (string str1, string str2)
  Appends STR2 to the end of STR1. For example, if STR1 contains "Hello"
  and STR2 contains "world", then after this function has been called, STR1
  will contain "Helloworld".
StrCaseComp (string str1, string str2)
  Does a case-insensitive comparison of STR1 and STR2. Using this function,
  "Dog", "dog" and "doG" will all be considered equal.
  Returns 0 if the two strings match, non-zero otherwise.
StrComp (string str1, string str2)
  Compares the strings STR1 and STR2. Returns zero if they are identical, and
  non-zero if they are not.
StrCopy (string str1, string str2)
  Copies the contents of STR2 into STR1, overwriting STR1's original contents.
  Use this instead of the assignment STR1=STR2 .
StrFormat (string destination, string fmt, ...)
  Processes the string FMT in the same way as the Display function does (ie.
  replace %d and %s with values of variables), but instead of displaying it
  on the screen, puts the result into DESTINATION.
  For example,
    StrFormat (buffer, "The got_stuff variable is %d.", got_stuff);
  SeeAlso: Display
StringToInt (string str1)
  Converts the string STR1 into an integer, and returns that value. Returns
  zero if the string does not contain a number.
  For example,
  StringToInt("53");     would return 53.
  StringToInt("hello");  would return 0.
  This function is useful for processing strings input from the user.
  SeeAlso: InputBox
StrLen (string str1)
  Returns the length, in characters, of the string STR1.
TintScreen (int red, int green, int blue)
  Tints the screen with the specified RGB values. RED, GREEN and BLUE range
  from 1 to 100. For example, to tint a heavy dose of red, you could
  call TintScreen (100, 50, 50);
  Pass (0, 0, 0) to turn off the tinting and go back to how the screen
  normally looks.
  NOTE: This command is currently experimental, since it causes a massive
  slowdown in the engine, especially at high resolutions. If you use it, you
  should provide an option for the player to turn it off.
  NOTE: This feature only works in hi-colour games.
UnPauseGame ()
  Resumes the game.
  SeeAlso: PauseGame
UpdateInventory ()
  Updates the player's inventory display. If you add or remove inventory
  items manually (ie. by using the character[].inv[] variables rather than
  the AddInventory/LoseInventory functions), the display may not get updated.
  In this case, after making your changes, call this function to update
  what is displayed to the player.
  SeeAlso: AddInventory, LoseInventory
UpdatePalette()
  Commits the changes you made to the game palette.
  The text script global variable  palette[]  stores the state of all the
  colours of the palette. You can access the red, green and blue components
  with .r, .g and .b. The values range from 0 to 63.
  For example,   palette[16].r = 60;   would make the black colour turn
  bright red. When you actually change the variable, nothing happens. Call
  this function to update the screen.
  SeeAlso: SetPalRGB
Wait (int time)
  Pauses the script and lets the game continue for TIME loops. There are
  normally 40 loops/second (unless you change it with SetGameSpeed), so using
  a value of 80 will wait 2 seconds. Note that no other text scripts can
  run while the Wait function is in the background.
  SeeAlso: WaitKey
WaitKey (int time)
  Pauses the script and lets the game continue until EITHER:
  (a) TIME loops have elapsed, or
  (b) the player presses a key
  Returns 0 if the time elapsed, or 1 if the player interrupted it.
  SeeAlso: Wait


6.4 TEXT SCRIPT GLOBAL VARIABLES
The following variables are available to your script. Those marked with
an asterisk * are read-only and should NOT be modified by your script.
 (For the characters, CHARID is the script ID name as set in the Room Editor).
*character[CHARID].x         X co-ordinate of the character (see Note1 below)
*character[CHARID].y         Y co-ordinate of the character
 character[CHARID].name      The character's full name
 character[CHARID].prevroom  The room it was in before this one
 character[CHARID].room      Which room the character is in
 character[CHARID].activeinv The currently selected inventory item (or -1)
 character[CHARID].inv[x]    Whether the character is carrying inventory X
*character[CHARID].walking   Whether the character is currently moving
*character[CHARID].animating Set to 1 while an AnimateCharacter animation runs
 character[CHARID].talkview  The character's talking view number minus 1
*character[CHARID].view      Current view of the character graphic (minus 1)
*character[CHARID].loop      Current loop of the character graphic
*character[CHARID].frame     Current frame of the character's graphic
 game.debug_mode         Whether we are in debug mode or not.
 game.following_room_timer How long to wait before following char emerges in
                           new room, default 150. (higher is longer).
*game.items_per_line     Number of inventory items displayed per line (useful
                           for working out how much to scroll the window down)
*game.num_inv_displayed  Number of inventory items which can be seen in the
                           inventory window.
*game.num_inv_items      Number of different inventory items which the current
                           player is carrying.
*game.score              The player's score.  (see Note2 below)
 game.sierra_inv_color   The background color of the sierra-style inventory.
 game.skip_display       Setting for how Display() messages are skipped;
                           valid values are same as for SetSkipSpeech (def 3).
 game.speech_text_gui    The textwindow GUI number used for sierra-style spch.
 game.swap_portrait      Set to 1 to make sierra-style speech swap the portrait
                           image from left to right when diff people talk.
 game.talkanim_speed     The animation speed for talking views (default 5).
 game.text_shadow_color  Color used for speech text shadow (default 16).
 game.text_speed         How long speech text stays on the screen. Default 15,
                           lower number means shorter time.
 game.top_inv_item       Index of the first inventory item in the window
 game.total_score        Maximum possible score, initially set in roomedit.
 game.used_mode          Cursor mode used with last click (use with "any click"
                           events to find out which mode was used)
 gs_globals[50]         The graphical script global flags (0=clear, 1=set)
*mouse.x                Mouse X co-ordinate when the script was started (0-319)
*mouse.y                Mouse Y co-ordinate when the script was started (0-199)
 palette[SLOT].r        The red component (0-63) of palette slot SLOT
 palette[SLOT].g        The green component (0-63) of palette slot SLOT 
 palette[SLOT].b        The blue component (0-63) of palette slot SLOT
 player.[x,y,name,...]  Alias to character[EGO]. Note: only set at game start,
                          does not update if you change the player character.
 savegameindex[20]      Save game slot order - see the ListBoxSaveGameList
                          description in text script reference for more info.
*system.screen_height   The vertical screen resolution (200 or 400) see Note3
*system.screen_width    The horizontal screen resolution (320 or 640)
*system.color_depth     The color depth (8 or 16).
*system.os              Interpreter version (1=AGS-DOS, 2=AGS-WIN).
*system.windowed        How game is running: 0=full screen, 1=window
Notes:
(1) The character X & Y co-ordinates may be modified as long as the character
  is stationary; changing these while the character is moving will cause it
  to start moving off in the wrong direction.
(2) To modify the score, use the GiveScore function.
(3) The system information is provided in order for your game to behave
  differently if it needs to; however, do NOT use this information to force
  the player to use a specific resolution. The AC engine is designed to allow
  players with varying speeds of computer to enjoy the game at a playable
  speed; people with a 486 would rather see blocky graphics at 320x200 than
  be forced to run very slowly at 640x400.

6.5 SYSTEM LIMITS
This section tells you the maximums for various parts of the system. If you
have been wondering "How many rooms can I have?" or something similar,
chances are this section will answer it.
There are maximum...
  10  objects per room
 100  messages per room
 500  global messages
  10  commands per animation
  10  commands per 'if' block of graphical script
 299  rooms per game
  98  inventory items
5000  imported sprites
 240  sprites per folder
 200  views
   8  loops per view
  10  frames in each loop
  50  characters
  20  GUI elements
  30  controls on each GUI
  80  total GUI controls of each type
 200  dialog topics
2000  dialog-script messages
  14  options per topic
   8  screen overlays at a time
 300  text script GlobalInts

If you think any of these limits is a serious problem, contact me and I can
probably increase it.

6.6 ASCII CODE TABLE
This section lists the key codes which can be passed to  on_key_press  and
which keys they represent:
 1..26     Ctrl-A .. Ctrl-Z
 13        Enter (Ctrl-M is also Enter)
 27        Escape
 32        Space
 48..57    '0' key .. '9' key
 65..90    'A' .. 'Z'  (letters are always passed as uppercase)
 316..325  Alt-Q/W/E/R/T/Y/U/I/O/P
 330..338  Alt-A/S/D/F/G/H/J/K/L
 344..350  Alt-Z/X/C/V/B/N/M
 359..368  F1 .. F10
 371       Home (numeric pad)
 372       Up arrow
 373       PgUp (numeric pad)
 375       Left arrow
 376       '5' (numeric pad)
 377       Right arrow
 379       End (numeric pad)
 380       Down arrow
 381       PgDn (numeric pad)
 433..434  F11 .. F12
Extra codes, which only work with IsKeyPressed (ie. on_key_press is never
called with these codes):
 403       Left shift
 404       Right shift
 405       Left ctrl
 406       Right ctrl
 407       Alt

6.7 GRAPHICAL SCRIPT COMMAND REFERENCE
While many of the graphical script commands mirror the behavior of the
standard Interaction commands with the same name, there are some extra
commands special to the graphical script:
 * Clear flag FLAGNAME
   Sets the flag's state to "Clear".
 * Every XX loops
   The indented commands are carried out once every XX game loops. There are
   approximately 40 game loops per second, so specifing '40' will mean that
   the commands will be carried out once a second. This is only useful with
   the "repeatedly execute" room event.
 * If flag FLAGNAME is set
   The indented commands are only carried out if the specified flag is
   in its "Set" state.
 * If flag FLAGNAME is clear
   The indented commands are only carried out if the flag is in its "Clear"
   state.
 * If inventory XX was used
   The indented commands are carried out if the player used inventory item XX
   to cause the event. You use this with the ability to set Data column to 99
   on a "Use inv" event (see section 6.1.1 for information).
 * If player has inv XX
   The indented commands are only carried out if the player has the specified
   inventory item.
 * If timer expired
   The indented commands are carried out if XX loops have passed since
   the "Set timer" command was executed. (See "set timer").
   NOTE: There is only one timer, and it is global. That is, starting the
   timer on one screen can trigger an "if expired" event on another screen
   if the player changes screens before the timer expires.
 * Move man to object XX
   Walks the main character to the object number specified. This is a
   shortcut for having to create an animation just to move the man up to
   the object he is interacting with.
   The character is moved to 5 pixels below the bottom of the object.
 * Random chance 1 in XX
   Probably only useful with the "repeatedly execute" event, the indented
   commands will be carried out if a random number selection by the game
   turns out. For example, if XX is 3, the command will probably be carried
   out about once every three times the script is executed, but this isn't
   gauranteed. This is useful for things like adding a flying bird to the
   screen which would appear at random intervals while the player was on the
   screen.
 * Set flag FLAGNAME
   Sets the specified flag's state to "Set".
 * Set timer to XX loops
   Starts the user timer counting down from XX - that is, the timer will
   expire after XX loops. (See "If timer expired"). This is similar to the
   "Every XX loops" command, except that the timer will expire XX loops FROM
   WHEN THIS SET TIMER COMMAND IS EXECUTED. This means that you can set another
   event to happen an exact time after this.
   NOTE: Using this command with XX as 0 will deactivate the timer.
   NOTE: The timer will be deactivated if the player leaves the room where it
   was activated.

6.8 ANIMATION EDITOR COMMANDS
This section describes all the commands available in the Animation Editor.
The editor is explained in section 3.2.6.
For all of the commands, you set the Object number to the number of the
object you want the command to operate on (from 0 to number_of_objects), or
you can set it to 99, in which case the command refers to the player
character.

 Set object view to %d
    Changes the view assigned to the object. The '%d' is the number of the
    view, from the status bar in the View Editor. This command also resets
    the object's graphic to the first frame of loop 0 in the chosen view.
    You can use a special view number 0, which is the main character's default
    view. This is useful to put back the main character if you changed his
    graphics during the game.
 Animate using loop %d
    Starts the object animating using loop number '%d' of its current view.
    The object will cycle through all the frames in the loop and then stop.
    If the Wait column is set, the next command will not be executed until
    the animation has finished.
    If you set the "second value" number to 1 then the animation will repeat
    continuosly. If it is 0 (default) the animation will run once then stop.
    NOTE: Don't set the Wait column AND set "second value" to 1, or you will
    be waiting a LONG time!
 Move to %d,%d
    Starts the object moving to the specified co-ordinates. You can find out
    the co-ordinates of a point by using the  Misc | Ask Position  feature
    in RoomMake. If the Wait column is set, the next command will not be
    executed until the object has reached its destination.
    NOTE: If you specify a target point which cannot be reached, there will
    be a short delay and then the next command will be executed immediately.
 Move to %d,%d no walls
    Identical to "Move to %d,%d", except that the object will move in a direct
    path straight to the destination, ignoring all the walls on the screen.
    This is useful if you want to have the man, for instance, walking into a
    door once it's open (which would mean crossing the base of the door,
    presumably a wall to the player). It can also be used to simulate flying
    objects.
 Place at %d,%d
    Moves the object's position to the location immediately. Note that this
    will only work if the object is turned OFF. Useful with the "player enters
    screen" event to move objects around or to place the main character
    somewhere which isn't on a screen edge.
    Note that the position specified is the BOTTOM LEFT of the object graphic.


7. FAQ & Troubleshooting
------------------------
This section is split up into three parts:
 * frequently asked questions, which answers questions people have about
   the system, rather than problems using it.
 * run-time engine problems, which deals with problems getting the engine
   to run, sound card issues, crashes, and other game-independant problems.
 * game creation problems, which deals with common problems you are having
   with your specific game.
 * known bugs, which lists problems known to exist with AGS and what to
   do about them.

7.1 FREQUENTLY ASKED QUESTIONS

Q. Can I play an AVI file?
A. No, not directly. However, you can convert an AVI file for use with the
   program. You've probably noticed that AGS supports WAV files for sound
   effects and FLI/FLC for animations. By using a "Play sound" command straight
   before a "Play FLC" command the sound should be in sync with the animation.
   To split an AVI file into WAV and FLC components, I recommend the excellent
   Smacker tools (www.smacker.com) which are free to download and also do
   a VERY good job of reducing true-color AVIs down to 256-colours.

Q. Why is AGS so slow compared to the original Sierra/Lucasarts games? I
   could run Space Quest 3 on my 286, but AGS needs 16 Mb RAM????
A. There are several reasons why AGS is not as fast, and more resource
   hungry than the original games. First of all, AGS is not optimised for
   speed, I admit that. Luckily however, most people these days have at
   least a Pentium-class system so that's no big problem.
   Second, consider that AGS supports up to 640x400 hi-colour resolution,
   whereas the original Sierra/LEC games only did 320x200x256.
   Thirdly, the Sierra/LEC systems were entirely script-based - that is, the
   programmers created the game without any features like interaction lists,
   GUI editors and Dialog editors. These features, while making AGS a lot
   easier to use, also have their toll on memory and processor usage. If I
   was to convert AGS to a script-only system, it would probably only need
   a fraction of the system resources. But would you use it then?
   Finally, yes I could spend a month or so optimising the engine to be as
   fast as possible. However, you the users have made it clear that you
   prefer new features and bug fixes to speed improvements, so that's what
   I'm trying to give you.
   At time of writing this (December 2000), a mid-range new PC is 750 MHz,
   with most people currently using around a 450 MHz system. Therefore, I am
   not going to spend a lot of time doing speed improvements just so it'll run
   on your 486. Sorry, but that's the way it is.

Q. Are you going to do a Windows port of the editor?
A. Probably some day, yes. However, it's something that I'll start from
   scratch if I do it, so it'll take a long time to finish.

Q. It's a bit cheap, the way you use MS-DOS EDIT to edit the text scripts.
   Why not have an integrated editor?
A. An integrated text editor will probably come soon, but in order to release
   the program as quickly as possible, I felt it best to leave a well-tested,
   reliable editor there instead of delaying the release while I write my own
   text editor. Also, this way you can use your favorite text editor instead by
   copying it to EDIT.EXE in the RoomEdit directory.

Q. What's the deal with the license? What does it mean in plain English?
A. Adventure Game Studio is swap-ware. That means, that if you use and like
   the program, you should send me something in return. This could be a game
   you have made using it, some new graphics, a new translation for the system
   messages, or even money! You don't HAVE to do this though, if you're really
   mean, and I won't hold it against you :-)
   There is one requirement - if you want to SELL a game you make, for profit,
   then you must contact me beforehand as there are some licensing issues
   which you may need to be aware of.
   When you finish your game, feel free to post it on the AGS Announcements
   forum so that everyone can give it a go.

Q. Why the swapware license? Why aren't you charging for it?
A. Because I want to. Mainly because if you see a program claiming to create
   adventure games, but charging you a registration of $100 if you want to
   distribute a game, you're not likely even to try it. A few people are doing
   this, for example Twilight Software with their system, but at $40 for a
   single user registration, just to make freeware games with it, that's a sure
   way to make it unpopular. Remember "Klik'n'play"? Hmmm.....

7.2 RUN-TIME ENGINE PROBLEMS

Q. The engine quits with "Aborting due to signal SIGxxxx, Shutting down
   allegro" and a load of numbers. What's going on?
A. You may have found a bug in the engine. First of all, check that you
   haven't done anything silly, like assigning a view number to an object
   where the view doesn't exist.
   Otherwise, try and work out when the problem happens - does it always
   happen at the same time (like whenever you turn an object on).
   Write down the list of numbers (each begins with "0x") and mail me with
   the problem. Even better, take a screen shot of the complete error display
   and send me that.

Q. When I choose the 960x600 mode in Setup, the game appears in a box in the
   middle of the screen surrounded by black borders. What's wrong?
A. Nothing, that's just how it is. The reason: a monitor can only use certain
   specific resolutions, like 320x200, 640x400, 640x480, 1024x768, and so on.
   So, to get the 960x600 mode, AGS tells the monitor to use its 1024x768 mode,
   and place the game window in the centre.

Q. Then why doesn't AGS support a 1024x768 mode?
A. For compatibility. The lowest resolution supported is 320x200, and all
   other supported resolutions are multiples of this. This gives 640x400 and
   960x600. Without this, AGS would be stuck in 1024x768 and would not allow
   different video modes. Whether you think that would be a good thing or
   not isn't the issue :-)

Q. I don't get sound from my SB Live! soundcard.
A. That's not a question.

Q. Ok, how do I get sound from my SB Live! soundcard?
A. To get any sound at all, you need to have the SB16 emulation enabled. (The
   SB Live install program should have done this for you).
   First of all, run AGS Setup and change the MIDI music card to the "General
   MIDI" option. This gives much better sounding MIDI music than the Sound
   Blaster midi driver which is autodetected.
   Secondly, digital sound. This appears to be an incompatibility between
   the SB16 emulator which comes with the SB Live, and AGS's sound driver. As
   far as I've tried it, you can get digital sound if you run AC from a Windows
   DOS-prompt, but not if you restart in MS-DOS mode. If you have more luck
   in MS-DOS mode, I'd like to hear about it. You can try setting the digital
   sound driver to "Sound Blaster Pro" in Setup, as this is more compatible
   than the SB16 driver. Also, the IRQ which the SB Live emulation program
   uses can cause problems. Try setting the SB16 emulation to use various IRQ
   lines (5, 7, 9 for example) until you find one which works.

Q. Where can I get a "DOS mouse driver"?
A. If you have Windows installed, it comes with a DOS mouse driver, so just
   try typing MOUSE and press return. If not, try typing C:\WINDOWS\MOUSE and
   press return (change the directory if Windows is installed elsewhere).
   If you don't have one, you can download the Microsoft DOS mouse driver
   from Microsoft's web site.

Q. I don't get sound under Windows 2000!
A. This is due to the way that Windows 2000 works, and cannot be fixed for
   the DOS engine. You need to run the Windows version of the engine instead,
   which will give you sound using DirectX.

7.3 GAME CREATION PROBLEMS

Q. How do I import this character I downloaded in CHA format?
A. In Roomedit, go to the Visual, Characters tab and press 'I' on the keyboard.

Q. On my screen, I can't move the main character. Wherever I click to move him,
   he just stands there.
A. If the main character isn't on a walkable area, he will not be able to move.
   Load the screen into the Room Editor, and check that the location where the
   man is has a walkable area there.
   If you are upgrading from AC v1, you need to upgrade the room - see
   section 5 for information.

Q. When I enter a certain room, I just get a black screen.
A. Make sure that you haven't used a Display Message command in the "Player
   enters screen" event for that room. Remember that this event happens BEFORE
   the screen fades in.
   To make sure, when you get the black screen, try pressing enter, or clicking
   the left mouse button. If nothing happens then something more serious may
   have happened. If this is the case, press Ctrl-Break, which should exit the
   program and give you a list of numbers which you can send to me to
   investigate.

Q. The character isn't drawn behind my walk-behind areas!
A. You need to define the base line for the area, or he will always be drawn
   in front. See section 3.1.2 for information.

Q. My USERGAME.EXE file seems to have disappeared.
A. Because this file is your entire game, including the room files, when you
   save a room in the Room Editor it will delete the exe file (because the
   room contained in the exe is out of date). To get it back, simply save the
   game again by going to the Game, Main tab and choosing the "Save game"
   button.

Q. I get a message "Exiting due to signal SIGxxxx, Shutting down Allegro"
   and it says it "exited without requesting it".
A. If you see a list of numbers, each starting with "0x", please write them
   down and contact me. Check that you haven't done anything silly, like used
   a sprite or view number which doesn't exist.

7.4 KNOWN BUGS
Please refer to the online Knowledge Base for a proper list of current
bugs and fixes. It's under the "Support" link on the AGS website. This
section of these docs is very rarely updated.

 * AGS does not run from a UNC-style network path (eg. running the game
   from a path like \\MYCOMP\GAMES\AC.EXE ) - you will get a "AC2GAME.DAT not
   found" error. The network drive must be mapped to a drive letter for the
   game to run. For example, do this:
   NET USE V: \\MYCOMP\GAMES
   V:\AC.EXE
 * Roomedit has problems editing text scripts when 4DOS is running. If you
   use 4DOS, please disable it before using roomedit.

If you think you've found a different bug, first of all check out the
Knowledge Base, and if it's not listed there post on the Technical forum
(info in section 8, below).


8. Contacting the author
------------------------
If you have any comments/suggestions, the first place to go is the AGS
messageboard. Linked off the main AGS website, it's where the AGS community
meets and you will find answers to many questions there.
If you think you've found a bug, if you need help or can't get it to work,
please check the following:
 * That your question is not already answered in this file. AGS has been
   painstakingly documented, so PLEASE read this file through before asking
   me a question.
 * If it is not covered in this file, check the CHANGES.TXT file. If a new
   feature has been added then it will be described there, if it has not yet
   been added to this manual.
 * That you are using the most recent version of AGS. You can find out the
   most recent version by checking the website (address below).
   You can find out your version by typing  ACDOS /?  and noting the line that
   reads "ACI version 2.xx.yyy" (where 2.xx is the version number, and yyy
   is the sub-version number).
 * If you are receiving an error message, please write down the EXACT message
   and any other information which you think is appropriate. PLEASE WRITE THE
   EXACT ERROR MESSAGE TEXT, don't just say "I get a message about it not being
   able to find a file".
 * If you are getting lock-ups or techno-garbage printouts, please try to
   give a situation which causes the problem. For instance, if you notice that
   it only happens on certain screens, or only if there is an object, etc then
   please state that - it makes replying a lot easier and faster.

Whatever the problem, if you can't solve it then post to the messageboard
for help. I also read the messageboard quite regularly, so chances are
someone will be able to help you.
Please only e-mail me as a last resort, as I get too much e-mail as it is
and I actually check the messageboard more frequently than my mail.
NOTE: If you want to mail me an attachment to demonstrate a problem you are
having, PLEASE COMPRESS IT using WinZip, PKZIP, etc and send it to me as a
zip file. I don't have the time or money to download massive 500 k BMP files
which compress to 20 k when zipped - if you send me an uncompressed BMP then
I will not respond to your mail.
PLEASE NOTE: I usually check my e-mail two or three times a week, so give me
about a week to reply before assuming your message didn't get through. The
same applies to the message board.
The AGS website: http://www.adventuregamestudio.co.uk
The AGS forum:   http://pub6.ezboard.com/bdosuserforums
My e-mail:  dosuser@bigfoot.com


9. Credits
----------
The Adventure Game Studio v2 was programmed by Chris Jones.
The DOS version uses DJGPP, a free 32-bit C/C++ compiler by DJ Delorie,
  which you can get from http://www.delorie.com/djgpp/
Graphics and sound are courtesy of the Allegro graphics library by Shawn
  Hargreaves and many others. You can get it at
  http://alleg.sourceforge.net/
MP3 player is almp3 v1.5, by Javier Gonzalez and the FreeAmp team.
Uses JGMOD mod player by Guan Foo Wah. You can find it at
  http://surf.to/jgmod
The demo game backgrounds and main character were drawn by D281@aol.com.
The icon bar graphics and Finnish translation were done by Teemu Eramaa
  (teemue@nic.fi)
The Dutch translation and the website logo were done by Erix Designs
  (erixdesigns@hotmail.com).
The German translation was done by Wolfram Guenther.
The Portugese translation was done by Nuno Costa (ncosta@mail.telepac.pt).
The Norwegian translation was done by Martin Seterstoen (martin-s@online.no).
The Spanish translation was done by Javi G.G.
The French translation was done by Pierre-Marc Jobin
  (djobin1@globetrotter.qc.ca).
The Lithuanian translation was done by Tomas J. (thebandit@takas.lt)
The Slovenian translation was done by Janez Kranjc (janez.kranjc@amis.net)
The Bulgarian translation was done by Alexander Alexandrov.
The Czech translation was done by Lukas Rachunek.
The Polish translation was done by Jakub Offierski.
The Swedish translation was done by Arn.
The Italian translation was done by Mario from Naples.
Includes CWSDPMI DPMI host (c) 1994-1997 by Charles W. Sandmann
Executables compressed with DJP v1.07 (c) 1996-1998 by Laszlo Molnar

LEGAL STUFF
-----------
Pentium is a trademark of Intel corporation.
Windows is a trademark or registered trademark of Microsoft corp.

THIS SOFTWARE IS PROVIDED WITH ABSOLUTELY NO WARRANTY, NOT EVEN THE IMPLIED
WARRANTIES OF MERCHANTIBILITY OR FITNESS FOR A PARTICULAR PURPOSE.
USE THIS SOFTWARE AT YOUR OWN RISK. CHRIS JONES IS NOT RESPONSIBLE IF YOUR
COMPUTER STARTS BURPING, CATCHES FIRE, GETS A SENSE OF HUMOUR OR ANYTHING
ELSE WHICH HAPPENS DUE TO THE USE OF THIS SOFTWARE.

SEE THE ACCOMPANYING LICENSE.TXT FILE FOR INFORMATION ON GAME DISTRIBUTION.
