Basic Tutorial: Scripting for Beginners

This section is intended for designers with no scripting or programming experience.

The objective is to teach enough to enable you to write simple scripts.

GPDL - Scripting Language contains good explanations of how GPDL works. When I first started trying to script, I read it until my brain was numb. I could not absorb much of it because I simply didn't know enough at the time. I recommend reading it, but don't be daunted by it. It will make more sense as you learn more.

In the meantime, here is some information in smaller bites to get you started.
First, the Script Editor.

Script Editor

The left window is where you write your script.
The right window contains functions. As it says, clicking once copies it to the clipboard, and double-clicking pastes it into the script at the location of the cursor, or overwrites any 'selected' portion.
Note: $TargetIndex(), listed at the bottom, is no longer valid.


The GPDL List Of Functions may as well come next. This is a list of functions with notes on what they do and, in some cases, how they're used. It also lists the values to expect, which is important when you want to perform a comparison. If there isn't a function that addresses it, it probably can't be scripted.

Syntax Basics:

Every 'logical line' must end with a semicolon. Every open parenthesis must have a close parenthesis. Every open bracket must have a close bracket.


Anything on a line that follows a double slash ( // ) is not considered part of the script, so that's where comments go. It's also handy for temporarily suppressing a line.


All variables used must be declared first, before any other actions.
$VAR tgt; // Declares 'tgt' a variable.

Variable names can take many forms, but a string of alphabetic characters, such as 'index' or 'hitpoints' is usually best. Typically something to represent what you're assigning to it.

Setting a Variable equal to a String:
tgt = $IndexOf($TargetContext()); // Sets the variable tgt equal to $TargetContext()'s index. Not only is tgt easier to type than $IndexOf($TargetContext()), it's easier for the program to retrieve.
Note: Actors can't be assigned to variables, so "tgt = $TargetContext();" won't work.


The full list, with explanations, is found in GPDL Expressions.

Operators - A Short List:

&&	Logical AND			||	Logical OR
+#	Add a number			*#	Multiply by a number
-#	Subtract a number		/#	Divide by a number


Note: Appending # to a comparator will convert both values to 32-bit integers for comparison.

==	Equal to		!=	Not equal to
<	Less than		<=	Less than or equal to
>	Greater than	>=	Greater than or equal to

Operator Notes:
= is used for assigning a value, so it can not also be used as a comparator.
+ appends a string, so 10 + 11 is 1011, while 10 +# 11 is 21.

Structure Keywords

The $IF keyword is used to execute functions if set conditions are met. The $ELSE keyword may be used in conjunction with $IF to execute functions if set conditions are not met.

$IF ($GET_PARTY_DAYS() <# 7)
- or -

$IF ($GET_PARTY_DAYS() <# 7)
 $ELSE  {$SET_PARTY_ASL("late","yes");};
Note that the closing semicolon for the $IF statement in the first example comes after the closing bracket. Each line within the brackets will have its own closing semicolon.

The closing semicolon for the $IF statement in the second example comes after the closing bracket of the $ELSE statement, because the $ELSE statement is considered part of the $IF statement

If logical ANDs or ORs are used, each comparison must be separate. For the $IF to fire if 'a' equals 1 or 3 or 5 -
$IF (a == 1 || 3 || 5) will work if a == 1, but 3 and 5 are not compared to anything. $IF (a == 1 || a == 3 || a == 5) is correct.

$IF statements may be "nested", such as the ones in the screen cap above.

$IF ($GET_CHAR_RACE(index) == "Gnome")
  $IF ($GET_CHAR_GENDER(index) != 0)
    $IF ($GET_CHAR_Lvl(index,"Thief") ># 1)
$SET_PARTY_ASL("BigTrouble", "yep");

If the character's race in the first one is not "Gnome", the others will not run. This one could have been written in one long $IF by ANDing.

$IF ($GET_CHAR_RACE(index) == "Gnome" && $GET_CHAR_GENDER(index) != 0 && $GET_CHAR_Lvl(index,"Thief") ># 1)
{$SET_PARTY_ASL("BigTrouble", "yep");};

The $WHILE keyword is used to execute functions while set conditions are met. One of the conditions MUST be incremented to a non-complying value, or the script will run in an endless loop and you won't be able to close the program by normal means. (Unless, like me, you consider killing a program with Task Manager to be normal.)

For non-combat scripts, a common $WHILE loop is:

$VAR index;
$VAR name;
index = 0;
$WHILE (index <# $PARTYSIZE())
  name = $GET_CHAR_NAME(index);
  // If an actor is required for a function, fetching the character's
  // name will allow you to use the actor $Name(name).
  // Replace these comments with whatever you want to do.
  index = index +# 1;
This will apply whatever functions are within the brackets to each member of the party.


For a novice scripter, $DEBUG is probably the most useful tool in your box. (Aside from the syntax checker, of course.) If you don't know whether a script is running, insert $DEBUG("scriptname running"); immediately following any variable declarations. If "scriptname running" doesn't show up in the interp.log or UafErr_Engine.txt, the script wasn't called. This also works in $IFs, $WHILEs, and anywhere else a script might hang up.

Reporting variable values with a $DEBUG is important to ensure the numbers are being crunched and applied as you intend them to be.

Once the script runs smoothly and reliably, the $DEBUGs should be removed, so as not to clutter the error and interp logs.

$DEBUG Syntax:

The $DEBUG will return the string values of whatever you tell it to. The only spaces included will be those you insert between quotes.

If 'name' equals the target's name, and 'index' equals the target's index, and the target is orc number 17 who has 7 hit points, then -

$DEBUG(name + " index " + index + " | HP = " + $GET_CHAR_HITPOINTS(index));
- will output -

$DEBUG(Orc index 17 | HP = 7)

Back to Design Tutorials

Back to Designer's Guide Index