Articles
AGI FOR NEWBIES
Nat Budin and Dark Fiber
Page: 1
2
[ 3 ]
Chapter 3
An Introduction to LOGIC

The "scrolly" example in this chapter
A few words about the interpreter
The AGI interpreter works in cycles. This means that the
interpreter executes the current LOGIC not just once, but many
times. Here’s an outline of what happens in each interpreter
cycle:
- The interpreter delays for a specified amount of time. The
delay is different depending on what speed the game is set to run
at. Faster speeds mean shorter delays. On “Fastest” speed,
there is no delay.
- The interpreter clears the keyboard buffer. This means that
if any keys were pressed and for some reason were not accepted by the
game, the game forgets about them at this stage.
- Interpreter flags 2 and 4 are set to false (more on flags further
down).
- The interpreter polls the keyboard and joystick to accept new
input.
- The interpreter handles the direction that the ego (main
character) should be facing.
- The interpreter recalculates movement for animated objects.
- The interpreter updates the status display (score and sound
on/off).
- The interpreter calls LOGIC 0 (more on this further down).
- The interpreter updates objects on the screen.
This is not a complete listing of what goes on in each stage. For
more information about it, check the AGI Specifications (“How The
Interpreter Works”).
Programming in an AGI game
The AGI programming language, LOGIC, is a scripting language.
High level scripts are compiled into byte-code which is interpreted by
the game interpreter. The interpreter gives you access to up to
256 compiled scripts. Each script has global access to 256 8-bit
unsigned variables, and 256 Boolean flags.
Logic Files
You have 256 LOGIC files available for you to use. The way Sierra
used LOGIC files, and the way the AGI Studio template is set up to use
LOGIC files, is that each room in the game has its own LOGIC file,
which helps for tidier programming. In that sense, you can have
up to 256 rooms. Some LOGIC files are special to the interpreter,
LOGIC 0 being the example. LOGIC 0 is what runs the entire game.
LOGIC 0 is used to 'call' your other LOGIC files. (For C and C++
programmers, it’s your main loop. LOGIC 0 can be likened to
having a re-entrant main() function.) LOGIC 1 is set up to be
your 'introduction' system, and LOGICs 90 through 99 are set up to
perform other game functions, like initialization, debugging, and death
handling.
When a AGI game is first started…
- LOGIC 0 is executed, which calls LOGIC 1.
- LOGIC 1 plays the introduction of the game.
- LOGIC 1 then jumps to the first room in your game, which is by
default set up to be LOGIC 2.
- After the first cycle, LOGIC 0 is set up to call the LOGIC of
your current room.
Flags and Variables
All flags and variables can be accessed by any script (0-255). If
you need to pass information between one script and another, you have
to use variables and flags. Flags are Boolean and store 0 or 1
(True or False). When a flag is set to True, we say it is
“set.” When you set a flag to False, you can say you have “reset”
it. Flags are good for storing simple information in.
Instead of using a variable to just store a 0 or 1, you can use a
flag. But, like LOGIC files, some variables and some flags are
used by the system. Your best bet is not to use any flags or
variables under 40 for yourself.
For example,
You are in an old belfry. Dangling right in front
of your face is a tattered and frayed rope.
You want the rope to break after the player pulls it. There are
several ways you can code this, as with any language, you are not
locked into any one way of programming it.
You have a flag "fPulledRope", at the start of the game it is set
to False. When the player types in "pull rope" you check to see if
"fPulledRope" is False, and if it is, you can set it to TRUE and then
say "the rope breaks." The next time the player tries to pull the rope,
checking "fPulledRope" is set to True, you can say "Sorry, the rope is
broken and you can't reach what is left of it dangling to pull it."
In that scenario a flag was good, as the rope only had two states,
pulled and not pulled. What if you wanted the rope to break after
the player had pulled it three times? Obviously a flag is not
enough to hold 3 different states, so using a variable would be best.
A quick less technical recap on flags and variables, flags are good for
storing single state items, on or off. Variables are good for
counters and multiple state items.
Example
A tutorial on Logic programming is not much good without examples, is
it?
First off, we'll program something simple, such as using a message box
to show numbers. We'll create a popup message box in the middle
of the screen that has the contents of the variable 40.
We'll use AGI Studio and create a blank game, create the directory
called test-01 and hit OK. Next click on the "LOGIC editor" icon.
In that LOGIC type
and save it as LOGIC 0.
Now above that return we can put our code.
The code for our little problem is quite simple, you need one print
statement, one goto, one if, and one quit. To find what these
statements mean, look them up in the AGI Studio help file.
How did you go? A very easy exercise, I know. This is my
solution.
1
|
inner_loop: |
2
|
print("%v40");
/* our message box command */ |
3
|
v40++;
/* increment our variable */ |
4
|
if(v40!=255) {
/* test our variable */ |
5
|
goto(inner_loop);
/* jump if it’s not 255 */ |
6
|
} |
7
|
|
8
|
quit(1);
/* quit program */ |
9
|
return(); |
The syntax here should be familiar to you if you know C or
C++. If not, here’s a line-by-line breakdown of the code:
- Line 1 is a label command. It sets up a point to jump to
later in the program.
- Line 2 tells the interpreter to put a message box on the screen
containing the value of variable number 40.
- Line 3 adds 1 to the value of variable 40 and stores the result
in variable 40.
- Line 4 tests to see if variable 40 has a value of 255.
- If variable 40 does not have a value of 255, then line 5 tells
the interpreter to jump back to line 1. If variable 40 has a
value of 255, then line 5 is skipped.
- Line 8 tells the interpreter to quit. The 1 means to quit
right away. If the command was quit(0), then the interpreter
would ask the player, “Do you want to quit?”
- Line 9 is not really necessary in this program, because the
interpreter can never reach line 9 because of the quit(1) statement in
line 8. However, in most cases, return(); tells the interpreter
to return to LOGIC 0.
Ok, now that’s done, I want you to make a copy of that example.
Alter the code so that the message box closes after 1/2 a second.
(HINT: Look up “special variables” in the AGI Studio help.)
reset(f15);
/* set message box to use timed closure */
inner_loop:
v21=1; /* set message box to close
after ½ second */
print("%v40");
v40++;
if(v40!=255) {
goto(inner_loop);
}
quit(1);
return();
|
“Ok, No more sissy examples,” I hear you cry! Right-o, how about
something far more complex without being really complex? Try to
code the scrolling credits of the Kings Quest 1 intro, obviously
without the graphics of course. Still think it’s easy? It is! It
has some heavy use of variables though.
How did you do? (Without looking at the actual code from Kings Quest
1!!) This is my solution (there are others possible):
#define
speed v10
#define new_room f5
#define start_line 10
#define start_col 10
#define end_line 14
#define start_msg 20
#define end_msg 35
#define cur_line v40
#define cur_col v41
#define cur_msg v42
#define begin_msg v43
if(new_room)
{
speed=12;
set.text.attribute(15, 0);
clear.lines(0, 24, 1);
cur_line=start_line;
cur_col=start_col;
cur_msg=start_msg;
begin_msg=cur_msg;
}
inner_loop:
cur_msg=begin_msg;
begin_msg++;
if(begin_msg==end_msg){ begin_msg=start_msg; }
cur_line=start_line;
clear.text.rect(10, 9, 13, 31, 0);
jump_01:
display.v(cur_line, cur_col, cur_msg);
cur_line++;
/* increment message number, wrap if need be */
cur_msg++;
if(cur_msg==end_msg){ cur_msg=start_msg; }
/* we only want to print 4 lines of text */
if(cur_line<end_line){ goto(jump_01); }
if(have.key()){ quit(1); }
return();
#message 20 ""
#message 21 ""
#message 22 ""
#message 23 " This is our test"
#message 24 "example of a scrolly"
#message 25 " in AGI LOGIC"
#message 26 ""
#message 27 "It is supposed to be"
#message 28 " similar to the"
#message 29 "Kings Quest 1 intro"
#message 30 " scrolly credits"
#message 31 "only better coz ours"
#message 32 "wraps at the end of"
#message 33 " the scroller! ^_^"
#message 34 ""
#message 35 ""
|
Page: 1
2
[ 3 ]