Overview of zMUD Variables

This tutorial delves into the new variable options in zMUD v6.20 and higher.  In addition to floating point numbers, v6.20 introduced several new syntax options for accessing variables and dealing with arrays which greatly increased the power of the scripting language.

Contents

Introduction
Variable Types
String Variables
Integer Variables
Floating Point Variables
String List Variables
Record Variables
Array Variables
COM Objects
System Variables
MXP Variables
Summary

Introduction

The zMUD scripting language (zScript) is a Text Processing Language.  This makes it quite different from computer languages such as C or Basic that people might be familiar with.  Although the original language syntax came from the original TinTin MUD client for Unix (for compatibility purposes), zScript has closer ties to text manipulation languages such as perl.

Because zMUD is designed for efficient text processing, all variables in zMUD are stored in text format.  While this decreases performance for mathematical calculations, if provides a great deal of flexibility.  But it's important to remember that even when we talk about variable "Types", all values are stored internally as strings (with the exception of arrays).

Variable Types

Although zMUD stores variables in text format, there are several "types" of variables that can be used in scripting:

  1. String: "text" is an explicit string value.
  2. Integer: 123 is an integer. -2 is an integer.
  3. Floating Point: Single precision is supported. 1.23 is a floating point value.
  4. String List: a string that contains multiple values.  a|b|c is a string list.
  5. Record: a string that contains keys and values.  Like a string list, but each element of the list has a name (key).
  6. Arrays: formal COM-compatible array types.  Indexed by an integer starting at zero.  Each element can contain a string, integer, or floating point value.
  7. COM Objects: Variable contains a reference to a COM object.
  8. MXP Variables: Entities set by the MUD server.

In the next sections, examples of using each variable type will be given.

String Variables

Strings are the core of the zMUD scripting language.  To force a value to be interpreted as a string, enclose the value in double-quotes: "text", or in braces: {text}.  The difference between these two syntaxes is that other variables are expanded when you use the {}.  For example:

VarName = "@abc"

stores the raw text "@abc" into the variable called VarName.  Compare this to the example:

VarName = {@abc}

Without the quotes the variable named "abc" is expanded, and the value of the "@abc" variable is stored in VarName.  The above example could also be written as:

VarName = @abc

Since there are no spaces in this expression, the {} are not actually needed.

To force a value to be interpreted as a string, you can also use the %string function.  For example, the + operator performs a numeric addition, if the arguments are numbers, or performs a string concatenation if the arguments are strings.  So: 1+2 has a value of 3, but "1"+"2" has a value of "12".  Using the %string function, you can do: %string(1+2)+"4" which would have a value of "34" since 1+2 becomes 3, which is then converted to the "3" string by the %string function.

Sometimes, the trickiest part of scripting in zMUD is determining what happens to the quotes around strings.  In many cases, quotes are stripped.  For example in the above VarName="@abc" example, if you then check the actual value of @VarName you will see that it contains @abc without the quotes.  So, the next time you use @VarName in a script, the @abc variable reference will get expanded since it's no longer within quotes.

Usually the scripting language will do what you want by default.  For more information on zMUD parsing modes and how to better control how strings are expanded or evaluated, see the "zMUD Programming Language" article in the Support Library.

Integer Variables

Integers are numbers without any decimal place, with an optional minus sign in front.  Whenever zMUD performs mathematical operations, if there are not quotes around a value, zMUD checks to see if the value can be converted to a number.  Some operations depend upon whether the arguments are numbers or strings.  In the previous section, we examined the difference between numeric and string + operations.

zMUD integer variables are converted from string format to 32-bit integer format for math operations.

Division with integer variables produces an integer value.  The Division is truncated (the value after the decimal point is discarded).  So, 5/2 = 2 (since 5 divided by 2 is 2.5, the .5 is discarded, giving an integer result of just 2).

Floating Point Variables

New to zMUD version 6.20 is floating point variables.  Now, numbers with decimal places can be manipulated.  zMUD supports Single-Precision floating point, which has an accuracy of approximately 7 decimal digits.

A floating point value *must* have a decimal point.  For example, 2 is an integer, but 2.0 is a floating point value.  The %float function can be used to convert a string or integer into a floating point number.  It basically just adds the ".0" to the end of an integer.

Division with floating point variables produces a floating point value.  For example, 5.0/2.0=2.5.  Only one of the values needs to be floating point.  Once any floating point value is detected in a calculation, all other values are automatically converted to floating point.  So, 5.0/2 and 5/2.0 would also give a value of 2.5.  However, remember that 5/2 is an integer-only operation, with an integer value of 2.  So, if you aren't sure if a value is already floating point, use the %float function.  For example %float(@a)/%float(@b) divides the variable @a by the variable @b, but ensures that the result is a floating point value.  So, even if @a=5 and @b=2 are both integers, the result will still be the floating point 2.5 value.

Because of the way floating point values are stored within computers, values that should be equal sometimes are not.  For example, in format mathematics, 1.0/3.0 is the same as (4.0/3.0-1.0).  However, in zMUD you will find that 1.0/3.0 is 0.333333343267441 and (4.0/3.0-1.0) is 0.333333373069763.  Notice that these values start out looking the same, but then differ.  This isn't the fault of zMUD, but is simply a result of how floating point values are stored on binary computers.

So, given the above problem, if you try to do something like #IF (1.0/3.0 = (4.0/3.0-1.0)) {...}, you will never get a True result from this, since the values are actually not equal.  To take care of this, zMUD provides the %norm function to normalize floating point values.  In zMUD, %norm(1.0/3.0) has a value of 0.333332985639572 and %norm(4.0/3.0-1.0) has a value of 0.333332985639572 also.  Notice that these values are now the same.  In fact, zMUD automatically calls %norm whenever you use floating point values in an #IF statement.  So, in zMUD, #IF (1.0/3.0 = (4.0/3.0-1.0)) {...} is True as expected.  But if you perform your own operations, it's useful to know about the %norm function.

String List Variables

String Lists have been used in zMUD for a long time.  They provide a simple mechanism to store multiple values in a single variable.  Originally, a string list was just a list of strings separated by the | character.  In fact, in older versions of zMUD, it was really that trivial.

In zMUD v6.26 and higher, string lists were improved to support nested lists.  For example, in old versions of zMUD, the line:

#ADDITEM List a|b

actually added *two* items to the string list.  In zMUD 6.26 and later, the above statement only adds a single item to the list.  This allows zMUD to support nested lists and other operations.  It also fixes problems previous versions had with list items that already had quotes around them.

In zMUD 6.26, if you really want to merge two lists as you could in the past, simply contatenate the lists together with the | symbol.  For example:

#MATH List @List+"|"+"a|b"

would concat the "a|b" list to the end of the existing list.

Depending upon what operations are used, string lists in zMUD may contain duplicate entries, or may not.  Using the #ADDITEM and #DELITEM commands, duplicate items in the list are removed.  Using the %additem and %delitem functions, duplicate items in the list are NOT removed.  It's important to remember this distinction when choosing whether to use a command or function.  To manually remove duplicate items in a list, use the %dup function.

New to zMUD 6.20 and later is the ability to refer to string list elements as an array.  For example, if @List had the value a|b|c, then @List.1 is "a", @List.2 is "b" and so on.  NOTE: You can only *read* list values using array syntax.  If you attempt an assignment using the syntax "List.1=a" you will actually be creating an array as described later.

There are *many* zMUD functions that work with lists.  Some examples are:

%numitems(@List)
returns the number of items in a list;
%push(@List,"item")
pushes a new item onto the beginning of the list (compared to %additem which adds the item to the end of the list).
%pop(List)
returns the first item from the list and removes it from the list.  Notice only the Name of the list variable is given, rather than it's value (no @ is used).
%sort(@List)
returns a sorted list

Starting with version 6.26 you can also nest one list inside of another.  For example:

List1="a|b|c"
List2=""
#ADDITEM List2 @List1

Puts @List1 into the first element of @List2.  Using the nested index syntax, you could query @List2.1.1 to get "a", @List2.1.2 to get "b", and so on.  Nested lists are delimited using parenthesis.  So, the list:

a|(b|c)|d

actually has 3 items.  The first item is "a", the second item is the nested list "b|c" and the third item is "d".

Record Variables

Records are similar to string lists, except that each element in the list also has a name, called the Key.  Although records are stored internally by zMUD as special string lists, you should not attempt to construct records directly.  You should always use the #ADDKEY command or %addkey function to add a new key and value item to the record.

Direct key reference can also be used in zMUD, for both retrieving data, *and* for assigning data.  For example:

VarName.Key = Value

is the same as:

#ADDKEY VarName Key Value

and @VarName.Key is the same as %db(@VarName,Key).  This direct key access syntax can make scripts much easier to read.

In zMUD v6.20 and later, record variables were improved, much like string lists, to fix problems with nested values.  Now you can store string lists, or other record values into record elements.  You can also nest the syntax used to reference elements.  For example, if we stored a string list into a record variable:

Rec.List="a|b|c"

then we could use @Rec.List.1 to access "a", and @Rec.List.2 to access "b", etc.  Just how you'd expect it to work!

Array Variables

In v6.1x, basic support for arrays was added to provide COM programming compatibility.  However, arrays were still limited in their general usefulness for zMUD scripting.  Starting with version 6.20, arrays were expanded and became powerful enough to use in everyday scripting.

In version 6.20 and later, direct indexing syntax is supported for both retrieving data, *and* for assigning data.  Also, arrays are created as needed without the need for an explicit %array function call.  For example, the simple statement: Arr.1="abc" creates an array, assigns "abc" to the first element, and stores the array in the @Arr variable.  To retrieve the element, just use the @Arr.1 syntax, just like with string lists.

Anytime you assign an element to the array, the array will automatically grow to the size needed to store the item.  Be careful with this.  For example, Arr.10000="abc" suddenly creates an array with 10,000 elements in it!  Element 10000 has the value "abc", and all of the other elements from 0 to 9999 would be empty.  But the memory needed for all 10,000 elements is allocated from Windows.  To deallocate this memory, just assign something else to the variable.  For example, doing Arr="" would clear the variable, freeing up all of the memory used for the array.

In v6.20 and higher, array elements can store either strings, integers, or floating-point values.  In the case of arrays, zMUD stores the data in the native format.  Strings are OLE-compatible strings, Integers are 32-bit values, and floating-point are Single precision values.  This maintains the COM compatibility with zMUD arrays.  Note that zMUD does *not* support nested arrays.  In other words, you cannot assign an array to another array element.  You also cannot store COM objects directly into arrays.

Starting in zMUD v6.20, array variables can be stored in the character settings file, and exported/imported, just like regular variables.  In addition, the Settings Editor can be used to edit arrays just like editing string lists.

COM Objects

References to COM Objects can be stored in a zMUD variable using the %comcreate or %comactive function calls.  For more information, see the article on COM Programming in zMUD in the Support Library.

System Variables

By default, the @ character is used to retrieve the value of a user-defined variable.  For example, @ABC retrieves the value of the variable called ABC.  The % character is used to retrieve the value from internal zMUD system variables.  See the topic "Predefined Variables" in the zMUD help file for a full list of available system variables.  In general, system variables can be retrieved, but not set.  Exceptions are noted in the help file.

MXP Variables

MXP allows the MUD Server to set it's own variables, called ENTITIES.  You can retrieve the value of MXP Entities using the %mud system record variable.  For example, if the MUD uses the command:

<!ENTITY Hp 100>

to create and set an entity called "Hp", you could retrieve this in zMUD using the syntax %mud.hp.  Note that you can only retrieve entity values.  You cannot change them.  Also, you cannot query the value of a "Private" entity.

An mentioned in the MXP specification, the MUD server could also set the entity using the syntax:

<VAR Hp>100</Var>

In this case, the value 100 is displayed to the user, probably part of the MUD prompt.  This still sets the entity called "Hp" to the value of 100 and can still be retrieved by the user using %mud.hp.

Summary

Now you have an overview of all of the types of variables support by zMUD and how to use them.