<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st April 2002 (no joke)), see www.w3.org">
<meta http-equiv="Content-Type" content=
"text/html; charset=windows-1252">
<meta name="ProgId" content="Word.Document">
<meta name="Generator" content="Microsoft Word 9">
<meta name="Originator" content="Microsoft Word 9">
<link rel="File-List" href="./exp_files/filelist.xml">
<title>Expressions</title>

<style type="text/css">
<!--
 /* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {mso-style-parent:"";
        margin:0pt;
        margin-bottom:.0001pt;
        mso-pagination:widow-orphan;
        font-size:12.0pt;
        font-family:"Times New Roman";
        mso-fareast-font-family:"Times New Roman";}
 /* Page Definitions */
@page
        {mso-page-border-surround-header:no;
        mso-page-border-surround-footer:no;}
@page Section1
        {size:612.0pt 792.0pt;
        margin:72.0pt 90.0pt 72.0pt 90.0pt;
        mso-header-margin:36.0pt;
        mso-footer-margin:36.0pt;
        mso-paper-source:0;}
div.Section1
        {page:Section1;}
-->
</style>
<style type="text/css">
 body.c4 {tab-interval:36.0pt;text-justify-trim:punctuation}
 span.c3 {mso-spacerun: yes}
 p.c2 {mso-pagination:none;mso-layout-grid-align:none; text-autospace:none}
 span.c1 {font-size:10.0pt;font-family:"Courier New"}
</style>
</head>
<body lang="EN-US" class='c4'>
<div class="Section1">
<p class="MsoNormal c2"><span class='c1'>Expressions</span></p>

<p class="MsoNormal c2"><span class='c1'>===========</span></p>

<p class="MsoNormal c2"><span class='c1'>M.U.G.E.N, (c) Elecbyte
2002</span></p>

<p class="MsoNormal c2"><span class='c1'>Documentation for version
2002.04.14</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>Beta-release
documentation</span></p>

<p class="MsoNormal c2"><span class='c1'>Updated 27 October
2001</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'>====================================================================</span></p>

<p class="MsoNormal c2"><span class='c1'>0. Contents</span></p>

<p class="MsoNormal c2"><span class=
'c1'>====================================================================</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>MUGEN supports the use of
arithmetic expressions in the CNS and CMD files. This document
gives a complete description of</span></p>

<p class="MsoNormal c2"><span class='c1'>expression
syntax.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>I.<span class=
"c3">&nbsp;&nbsp;&nbsp;</span> Data types: Ints and
Floats</span></p>

<p class="MsoNormal c2"><span class='c1'>II.<span class=
"c3">&nbsp;&nbsp;</span> Arithmetic operators</span></p>

<p class="MsoNormal c2"><span class='c1'>III.<span class=
"c3">&nbsp;</span> Precedence and associativity of
operators</span></p>

<p class="MsoNormal c2"><span class='c1'>IV.<span class=
"c3">&nbsp;&nbsp;</span> Expression syntax</span></p>

<p class="MsoNormal c2"><span class='c1'>V.<span class=
"c3">&nbsp;&nbsp;&nbsp;</span> Triggers</span></p>

<p class="MsoNormal c2"><span class='c1'>VI.<span class=
"c3">&nbsp;&nbsp;</span> Trigger redirection</span></p>

<p class="MsoNormal c2"><span class='c1'>VII.<span class=
"c3">&nbsp;</span> SC values</span></p>

<p class="MsoNormal c2"><span class='c1'>VIII. More on
function-type triggers</span></p>

<p class="MsoNormal c2"><span class='c1'>IX.<span class=
"c3">&nbsp;&nbsp;</span> Expressions in state and state controller
parameters</span></p>

<p class="MsoNormal c2"><span class='c1'>X.<span class=
"c3">&nbsp;&nbsp;&nbsp;</span> (Advanced) Optimizing for
speed</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'>====================================================================</span></p>

<p class="MsoNormal c2"><span class='c1'>I. Data types: Ints and
Floats</span></p>

<p class="MsoNormal c2"><span class=
'c1'>====================================================================</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>An int is a whole number,
such as 0, 1, -4, etc. Ints can assume values</span></p>

<p class="MsoNormal c2"><span class='c1'>between about -2 billion
and 2 billion. A float is a real number which</span></p>

<p class="MsoNormal c2"><span class='c1'>has a "decimal part", such
as 5.24, or -4247.44. Note that a whole number such as 55 can also
be represented as a float, thus: 55.0. Floats offer only 7
significant figures of precision.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>The behavior of arithmetic
expressions depends heavily on the underlying data types used to
represent numbers. Also, state controllers may expect their input
to be given as a certain type, and will give errors if the wrong
type is supplied.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'>====================================================================</span></p>

<p class="MsoNormal c2"><span class='c1'>II. Arithmetic
operators</span></p>

<p class="MsoNormal c2"><span class=
'c1'>====================================================================</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>In addition to the
familiar arithmetic operators like +, -, *, and /,</span></p>

<p class="MsoNormal c2"><span class='c1'>several other operators
exist which act on their input values in</span></p>

<p class="MsoNormal c2"><span class='c1'>different ways. This
section describes the behavior of these operators.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>+<span class=
"c3">&nbsp;&nbsp;</span></span></p>

<p class="MsoNormal c2"><span class='c1'>The familiar addition
operator. x + y evaluates to an int if x and y</span></p>

<p class="MsoNormal c2"><span class='c1'>are both ints, or a float
if x and y are both floats. If one of x or y</span></p>

<p class="MsoNormal c2"><span class='c1'>is a float, then both are
converted to floats (with possible loss</span></p>

<p class="MsoNormal c2"><span class='c1'>of precision in the
process) and then x + y is evaluated as a sum</span></p>

<p class="MsoNormal c2"><span class='c1'>of floats.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>-<span class=
"c3">&nbsp;</span></span></p>

<p class="MsoNormal c2"><span class='c1'>The familiar subtraction
operator. As with addition, x - y evaluates</span></p>

<p class="MsoNormal c2"><span class='c1'>to an int if x and y are
both ints, or a float if they are both floats.</span></p>

<p class="MsoNormal c2"><span class='c1'>If one of x or y is a
float, they are both converted to floats and the</span></p>

<p class="MsoNormal c2"><span class='c1'>subtraction is performed
as a subtraction of floats.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>-<span class=
"c3">&nbsp;</span></span></p>

<p class="MsoNormal c2"><span class='c1'>If - appears in a context
where the subtraction operator is not</span></p>

<p class="MsoNormal c2"><span class='c1'>appropriate, it is
interpreted as the negation operator. That is, given input x, "-x"
represents the value -x. Returns the same type as x's.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>*<span class=
"c3">&nbsp;</span></span></p>

<p class="MsoNormal c2"><span class='c1'>The multiplication
operator. The behavior is similar to the + and -</span></p>

<p class="MsoNormal c2"><span class='c1'>operators.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>/</span></p>

<p class="MsoNormal c2"><span class='c1'>The division operator. If
x and y are both ints, then x/y gives the</span></p>

<p class="MsoNormal c2"><span class='c1'>number of times that y
goes evenly into x. For instance, 7/2 = 3,</span></p>

<p class="MsoNormal c2"><span class='c1'>because 2 goes into 7
three times (with a remainder of 1 which is</span></p>

<p class="MsoNormal c2"><span class='c1'>discarded). If x and y are
both floats, then x/y returns a float. For</span></p>

<p class="MsoNormal c2"><span class='c1'>instance, 7.0/2.0 = 3.5.
Finally, if one of x or y is a float, they are both converted to
floats before evaluation.</span></p>

<p class="MsoNormal c2"><span class='c1'>The result of a division
by zero will be discussed in the section on</span></p>

<p class="MsoNormal c2"><span class='c1'>SC values.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>%</span></p>

<p class="MsoNormal c2"><span class='c1'>The remainder or mod
operator. If x and y are both ints, x%y returns</span></p>

<p class="MsoNormal c2"><span class='c1'>an int representing the
remainder after performing a division x/y. For</span></p>

<p class="MsoNormal c2"><span class='c1'>instance, 7%2 = 1, and 23
% 17 = 6. It is an error to use the % operator on float values, or
to compute x%0. The result of such operations will be discussed in
the section on SC values.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>**</span></p>

<p class="MsoNormal c2"><span class='c1'>The exponentiation
operator. If x and y are both ints &gt;= 0, then x**y</span></p>

<p class="MsoNormal c2"><span class='c1'>gives an int representing
x raised to the power of y (we define 0**0 =</span></p>

<p class="MsoNormal c2"><span class='c1'>1). Otherwise, x**y is
computed as an exponentiation of real numbers</span></p>

<p class="MsoNormal c2"><span class='c1'>(converting x and y to
floats first if necessary). The result of an</span></p>

<p class="MsoNormal c2"><span class='c1'>invalid exponentiation
such as -1^.5 will be discussed in the section on SC
values.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>!</span></p>

<p class="MsoNormal c2"><span class='c1'>The logical NOT operator.
!x evaluates to 0 (int) if x is nonzero,</span></p>

<p class="MsoNormal c2"><span class='c1'>and 1 (int) if x is
zero.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>&amp;&amp;</span></p>

<p class="MsoNormal c2"><span class='c1'>The logical AND operator.
x &amp;&amp; y evaluates to 1 (int) if x and y</span></p>

<p class="MsoNormal c2"><span class='c1'>are both nonzero, and to 0
(int) otherwise.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>||</span></p>

<p class="MsoNormal c2"><span class='c1'>The logical OR operator. x
|| y evaluates to 1 (int) if one or more</span></p>

<p class="MsoNormal c2"><span class='c1'>of x and y is nonzero, and
to 0 (int) otherwise.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>^^</span></p>

<p class="MsoNormal c2"><span class='c1'>The logical XOR operator.
x ^^ y evaluates to 1 (int) if exactly one</span></p>

<p class="MsoNormal c2"><span class='c1'>of x and y is nonzero, and
to 0 (int) otherwise.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>~</span></p>

<p class="MsoNormal c2"><span class='c1'>The bitwise NOT operator.
~x inverts the bits of x's binary (two's</span></p>

<p class="MsoNormal c2"><span class='c1'>complement)
representation. It is an error to apply this to a float
--</span></p>

<p class="MsoNormal c2"><span class='c1'>for the result of such an
operation, see the section on SC values.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>&amp;</span></p>

<p class="MsoNormal c2"><span class='c1'>The bitwise AND operator.
The nth bit of x&amp;y is set if and only if the</span></p>

<p class="MsoNormal c2"><span class='c1'>nth bits of both x and y
are set. Returns an SC value if either of x or y is a
float.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>|</span></p>

<p class="MsoNormal c2"><span class='c1'>The bitwise OR operator.
The nth bit of x|y is set if and only if the</span></p>

<p class="MsoNormal c2"><span class='c1'>nth bit of either x or of
y (or both) is set. Returns an SC value if either of x or y is a
float.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>^</span></p>

<p class="MsoNormal c2"><span class='c1'>The bitwise XOR operator.
The nth bit of x^y is set if and only if the</span></p>

<p class="MsoNormal c2"><span class='c1'>nth bit of exactly one of
x and y is set. Returns a SC value if either of x or y is a
float.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>=</span></p>

<p class="MsoNormal c2"><span class='c1'>The equality operator. If
x and y are both ints or both floats, x = y</span></p>

<p class="MsoNormal c2"><span class='c1'>evaluates to 1 (int) if x
and y are equal, and 0 otherwise. If exactly</span></p>

<p class="MsoNormal c2"><span class='c1'>one of x or y is a float,
then they are both converted to floats before</span></p>

<p class="MsoNormal c2"><span class='c1'>testing for
equality.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>:=</span></p>

<p class="MsoNormal c2"><span class='c1'>The assignment operator.
An unredirected variable name (var(n) or fvar(n) for suitable
values of n) must appear on the left-hand side. If the left-hand
side contains an integer variable, then the right-hand side is
truncated to an integer before assignment. If the left-hand side
contains a float variable, then the right-hand side is converted to
float if necessary before assignment. In both cases, the value of
the expression is the value that is assigned to the
variable.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>!=</span></p>

<p class="MsoNormal c2"><span class='c1'>The inequality operator.
If x and y are both ints or both floats,</span></p>

<p class="MsoNormal c2"><span class='c1'>x != y evaluates to 1
(int) if x and y are not equal, and 0 otherwise.</span></p>

<p class="MsoNormal c2"><span class='c1'>If exactly one of x or y
is a float, then they are both converted to</span></p>

<p class="MsoNormal c2"><span class='c1'>floats before testing for
equality.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>&lt;</span></p>

<p class="MsoNormal c2"><span class='c1'>The less-than operator. If
x and y are both ints or both floats, x &lt;</span></p>

<p class="MsoNormal c2"><span class='c1'>y evaluates to 1 (int) if
x &lt; y, and 0 otherwise. If exactly one of x or y is a float,
then they are both converted to floats before testing for
equality.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>&lt;=</span></p>

<p class="MsoNormal c2"><span class='c1'>Similar to &lt;, with the
exception that if x = y, then x &lt;= y returns</span></p>

<p class="MsoNormal c2"><span class='c1'>1 (int).</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>&gt;</span></p>

<p class="MsoNormal c2"><span class='c1'>The greater-than operator.
If x and y are both ints or both floats,</span></p>

<p class="MsoNormal c2"><span class='c1'>x &gt; y evaluates to 1
(int) if x &gt; y, and 0 (int) otherwise. If exactly</span></p>

<p class="MsoNormal c2"><span class='c1'>one of x or y is a float,
then they are both converted to floats before testing for
equality.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>&gt;=</span></p>

<p class="MsoNormal c2"><span class='c1'>Similar to &gt;, with the
exception that if x = y, then x &gt;= y returns</span></p>

<p class="MsoNormal c2"><span class='c1'>1 (int).</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>=[,]</span></p>

<p class="MsoNormal c2"><span class='c1'>!=[,]</span></p>

<p class="MsoNormal c2"><span class='c1'>=[,)</span></p>

<p class="MsoNormal c2"><span class='c1'>!=[,)</span></p>

<p class="MsoNormal c2"><span class='c1'>=(,]</span></p>

<p class="MsoNormal c2"><span class='c1'>!=(,]</span></p>

<p class="MsoNormal c2"><span class='c1'>=(,)</span></p>

<p class="MsoNormal c2"><span class='c1'>!=(,)</span></p>

<p class="MsoNormal c2"><span class='c1'>Interval operators. These
take three arguments, x, y, and z. If any of</span></p>

<p class="MsoNormal c2"><span class='c1'>x, y, or z is a float,
they are all converted to floats. After conversion if necessary, x
= [y,z] is equivalent to (x &gt;= y) &amp;&amp; (x &lt;= z).
Similarly, x = (y,z) is equivalent to (x &gt; y) &amp;&amp; (x &lt;
z). The half-open intervals have the obvious meaning.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>The negated interval
operators work as follows: x != [y,z] is equivalent (after
conversion if necessary) to (x &lt; y) || (x &gt; z).</span></p>

<p class="MsoNormal c2"><span class='c1'>x != (y,z) is equivalent
to (x &lt;= y) || (x &gt;= z). The half-open intervals again have
the obvious meaning.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>You can view the interval
operators as producing the appropriate open, closed, or half-open
intervals on the ints or the floats. The = symbol means set
membership in this context.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>Some restrictions apply on
where intervals may be placed in an</span></p>

<p class="MsoNormal c2"><span class='c1'>expression. See the
section on syntax for details.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'>====================================================================</span></p>

<p class="MsoNormal c2"><span class='c1'>III. Precedence and
associativity of operators</span></p>

<p class="MsoNormal c2"><span class=
'c1'>====================================================================</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>If you consider an
expression like 3+2*5, the result is different</span></p>

<p class="MsoNormal c2"><span class='c1'>depending if you evaluate
the * first (yielding 13) or if you evaluate</span></p>

<p class="MsoNormal c2"><span class='c1'>the + first (yielding 25).
To disambiguate expressions such as this,</span></p>

<p class="MsoNormal c2"><span class='c1'>operators are assigned
distinct precedence levels. In this case, the</span></p>

<p class="MsoNormal c2"><span class='c1'>precedence of * is higher
than the precedence of +, so the * is</span></p>

<p class="MsoNormal c2"><span class='c1'>evaluated first, then the
+ is applied to the result. So the correct</span></p>

<p class="MsoNormal c2"><span class='c1'>answer is 13.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>If two operators share the
same precedence, then the expression is</span></p>

<p class="MsoNormal c2"><span class='c1'>evaluated from left to
right, except for the unary operators and the</span></p>

<p class="MsoNormal c2"><span class='c1'>assignment operator, which
associate right to left. For instance, * and / share the same
precedence, so 5.0*5/6 evaluates to 25.0/6, which evaluates to
4.166667.<span class="c3">&nbsp;</span> On the other hand, 5/6*5.0
evaluates to 0*5.0, which evaluates to 0.0.<span class=
"c3">&nbsp;</span> In contrast, because unary operators associate
right to left, -!0 is grouped as -(!0), which evaluates to -(1),
which then evaluates to -1.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>If part of an expression
is grouped in parentheses (), then that part of the expression is
evaluated first. For instance, in the expression</span></p>

<p class="MsoNormal c2"><span class='c1'>(3+2)*5, the + is
evaluated first, giving 5*5, which then evaluates to</span></p>

<p class="MsoNormal c2"><span class='c1'>25. If parentheses are
nested, the innermost parentheses are evaluated</span></p>

<p class="MsoNormal c2"><span class='c1'>first.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>Operator precedence is
basically the same as in C. The complete list of operator
precedence, from highest to lowest, is as follows:</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>! ~ -<span class=
"c3">&nbsp;</span> (Unary operators)</span></p>

<p class="MsoNormal c2"><span class='c1'>**</span></p>

<p class="MsoNormal c2"><span class='c1'>* / %</span></p>

<p class="MsoNormal c2"><span class='c1'>+ -</span></p>

<p class="MsoNormal c2"><span class='c1'>&gt; &gt;= &lt;
&lt;=</span></p>

<p class="MsoNormal c2"><span class='c1'>= != intervals</span></p>

<p class="MsoNormal c2"><span class='c1'>:=</span></p>

<p class="MsoNormal c2"><span class='c1'>&amp;</span></p>

<p class="MsoNormal c2"><span class='c1'>^</span></p>

<p class="MsoNormal c2"><span class='c1'>|</span></p>

<p class="MsoNormal c2"><span class='c1'>&amp;&amp;</span></p>

<p class="MsoNormal c2"><span class='c1'>^^</span></p>

<p class="MsoNormal c2"><span class='c1'>||</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>Programmers are encouraged
to parenthesize as necessary to maintain</span></p>

<p class="MsoNormal c2"><span class='c1'>clarity. Otherwise, bugs
due to subtle misunderstanding of operator</span></p>

<p class="MsoNormal c2"><span class='c1'>precedence are almost
assured.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'>====================================================================</span></p>

<p class="MsoNormal c2"><span class='c1'>IV. Expression
syntax</span></p>

<p class="MsoNormal c2"><span class=
'c1'>====================================================================</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>Basically, any normal
arithmetic expression is allowable. In addition,</span></p>

<p class="MsoNormal c2"><span class='c1'>since the relational
operators (&gt;, &lt;=, etc.) are viewed as returning</span></p>

<p class="MsoNormal c2"><span class='c1'>ints, it is possible to
operate on their return values, giving some</span></p>

<p class="MsoNormal c2"><span class='c1'>unusual-looking
expressions like</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>1.0 = (2 = (1 &gt; 0) +
!(0 &lt; 1))</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>The 1 &gt; 0 term
evaluates to 1, and the 0 &lt; 1 term evaluates to 0.
Hence</span></p>

<p class="MsoNormal c2"><span class='c1'>!(0 &lt; 1) evaluates to
1, so the expression simplifies to</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>1.0 = (2 = 1 +
1)</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>Since 2 = 1 + 1, the term
in parentheses evaluates to 1, so the</span></p>

<p class="MsoNormal c2"><span class='c1'>expression further
simplifies (after type conversion) to</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>1.0 = 1.0</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>which evaluates to 1
(int), since the equality holds.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>A notable restriction in
expression syntax is that interval operators</span></p>

<p class="MsoNormal c2"><span class='c1'>are only allowed to appear
on the rightmost side of an expression. If</span></p>

<p class="MsoNormal c2"><span class='c1'>part of an expression is
enclosed in parentheses, then that part is</span></p>

<p class="MsoNormal c2"><span class='c1'>considered a
subexpression, and an interval is allowed to appear on
the</span></p>

<p class="MsoNormal c2"><span class='c1'>right side of that
subexpression. So the following is a well-formed</span></p>

<p class="MsoNormal c2"><span class='c1'>expression, which
evaluates to 0:</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>(1 = [0,2]) =
(0,1)</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>But the following is not
well-formed:</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>1 = [0,2] =
(0,1)</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>In addition, no operator
symbols other than = or != may appear before an interval. So an
expression like 5 &gt; [0,2], or 4 + [1,4), is not
allowed.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>In comma-separated
parameter lists, such as the arguments to some</span></p>

<p class="MsoNormal c2"><span class='c1'>function-type triggers or
parameters to state controllers, each expression in the list is
considered a separate subexpression, and therefore intervals may
appear at the end of those subexpressions.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'>====================================================================</span></p>

<p class="MsoNormal c2"><span class='c1'>V. Triggers</span></p>

<p class="MsoNormal c2"><span class=
'c1'>====================================================================</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>For historical reasons,
two distinct constructs are both called</span></p>

<p class="MsoNormal c2"><span class='c1'>"triggers." The first is
what might be more properly called a</span></p>

<p class="MsoNormal c2"><span class='c1'>condition-type trigger,
and the second is what might be more properly</span></p>

<p class="MsoNormal c2"><span class='c1'>called a function-type
trigger. For instance, in the CNS, a typical</span></p>

<p class="MsoNormal c2"><span class='c1'>state controller might
look like</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>[State 1234, 5]</span></p>

<p class="MsoNormal c2"><span class='c1'>type =
ChangeState</span></p>

<p class="MsoNormal c2"><span class='c1'>trigger1 = time =
0</span></p>

<p class="MsoNormal c2"><span class='c1'>value = 0</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>The entire line "trigger1
= time = 0" is a condition-type trigger. If</span></p>

<p class="MsoNormal c2"><span class='c1'>the expression "time = 0"
evaluates to a nonzero value, then the</span></p>

<p class="MsoNormal c2"><span class='c1'>ChangeState controller is
executed. If the expression "time = 0"</span></p>

<p class="MsoNormal c2"><span class='c1'>evaluates to zero, then
the ChangeState controller is not executed.</span></p>

<p class="MsoNormal c2"><span class='c1'>Thus whether the condition
is zero or nonzero affects whether the</span></p>

<p class="MsoNormal c2"><span class='c1'>controller is
triggered.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>On the other hand, the
word "time" appearing in the expression is a</span></p>

<p class="MsoNormal c2"><span class='c1'>function-type trigger. It
returns a value, namely, the amount of time</span></p>

<p class="MsoNormal c2"><span class='c1'>that the player has been
in state 1234. Note that a function-type</span></p>

<p class="MsoNormal c2"><span class='c1'>trigger doesn't "trigger"
anything. It just gives a value that can be</span></p>

<p class="MsoNormal c2"><span class='c1'>acted on within the
expression.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>To further illustrate the
difference, let us consider a different state
controller:</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>[State 1234, 5]</span></p>

<p class="MsoNormal c2"><span class='c1'>type = VarSet</span></p>

<p class="MsoNormal c2"><span class='c1'>trigger1 = 1</span></p>

<p class="MsoNormal c2"><span class='c1'>v = 0</span></p>

<p class="MsoNormal c2"><span class='c1'>value = time +
5</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>Note that the
condition-type trigger "trigger1 = 1" now contains no</span></p>

<p class="MsoNormal c2"><span class='c1'>function-type triggers
within it. Since the expression "1" always</span></p>

<p class="MsoNormal c2"><span class='c1'>evaluates to 1, the
controller will be triggered every frame. To</span></p>

<p class="MsoNormal c2"><span class='c1'>determine what value to
assign var0, the expression "time + 5" is</span></p>

<p class="MsoNormal c2"><span class='c1'>evaluated. The
function-type trigger "time" returns the player's</span></p>

<p class="MsoNormal c2"><span class='c1'>statetime. Then 5 is added
and the result is stored in var0.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>A complete list of
function-type triggers can be found in trigger.doc.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>In general, which of the
two types of triggers is meant is clear from</span></p>

<p class="MsoNormal c2"><span class='c1'>context. Where there is
some ambiguity, the terms "condition-type</span></p>

<p class="MsoNormal c2"><span class='c1'>trigger" and
"function-type trigger" will be used.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'>====================================================================</span></p>

<p class="MsoNormal c2"><span class='c1'>VI. Trigger
redirection</span></p>

<p class="MsoNormal c2"><span class=
'c1'>====================================================================</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>In the above example, the
time trigger returned the statetime of the</span></p>

<p class="MsoNormal c2"><span class='c1'>player. But sometimes, one
might wish to check the statetime of the</span></p>

<p class="MsoNormal c2"><span class='c1'>player's target, or the
player's parent (if the player is a helper),</span></p>

<p class="MsoNormal c2"><span class='c1'>etc. This can be
accomplished by preceding the trigger name by a keyword indicating
whose information should be returned. This process is known as
trigger redirection. For example,</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>5 + parent,
time</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>returns 5 + the player's
parent's statetime.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>The complete list of
redirection keywords is the following:</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>*) parent</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> Redirects the trigger to the player's parent.
(Player must be a</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> helper.)</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>*) root</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> Redirects the trigger to the root.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>*) helper</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> Redirects the trigger to the first helper found.
See the related</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> trigger "NumHelper" in the trigger
documentation.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>*) helper(ID)</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> ID should be a well-formed expression that
evaluates to a positive</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> integer. The trigger is then redirected to a
helper with the</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> corresponding ID number.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>*) target</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> Redirects the trigger to the first target
found.</span></p>

<p class="MsoNormal c2"><span class='c1'>*) target(ID)</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> ID should be a well-formed expression that
evaluates to a non-</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> negative integer. The trigger is then redirected
to a target with</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> the corresponding targetID. The targetID is
specified in the "ID"</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> parameter of a HitDef controller.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>*) partner</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> Redirects the trigger to the player's partner.
Normal helpers and</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> neutral players are not considered opponents.
See the related</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> trigger "numpartner" in the trigger
documentation.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>*) enemy</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> Redirects the trigger to the first opponent
found. Normal helpers</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> and neutral players are not considered
opponents. See the related</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> trigger "numenemy" in the trigger
documentation.</span></p>

<p class="MsoNormal c2"><span class='c1'>*) enemy(n)</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> n should be a well-formed expression that
evaluates to a non-</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> negative integer. The trigger is redirected to
the n'th opponent.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>*) enemyNear</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> Redirects the trigger to the nearest
opponent.</span></p>

<p class="MsoNormal c2"><span class='c1'>*) enemyNear(n)</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> n should be a well-formed expression that
evaluates to a non-</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> negative integer. The trigger is redirected to
the n'th-nearest</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> opponent.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>*) playerID(ID)</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> n should be a well-formed expression that
evaluates to a non-</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> negative integer. The trigger is redirected to
the player with</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> unique ID equal to ID. See the "ID" and
"PlayerExistID" triggers</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> in the trigger documentation.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>If the trigger is
redirected to an invalid destination (for instance,</span></p>

<p class="MsoNormal c2"><span class='c1'>if it is retargeted to a
helper when none exist), then an error is</span></p>

<p class="MsoNormal c2"><span class='c1'>returned. See the section
on SC values.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>Note: multiple redirection
(e.g.,<span class="c3">&nbsp;</span> root,target,time) is not
currently supported.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'>====================================================================</span></p>

<p class="MsoNormal c2"><span class='c1'>VII. SC values</span></p>

<p class="MsoNormal c2"><span class=
'c1'>====================================================================</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>There are several sources
of unrecoverable error in expressions. For</span></p>

<p class="MsoNormal c2"><span class='c1'>instance, one could
attempt to divide by 0, evaluate the square root of a negative
number, or attempt to redirect a trigger to a nonexistent
destination. In these situations, SC values are used as a way to
complete expression evaluation gracefully.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>An SC value is a special
kind of int which can only take on the values 1 or 0, called SC
true (STrue) and SC false (SFalse). The result of any operation or
trigger evaluation on an SC value is that SC value. (In other
words, you can think of the SC values as variants on the "bottom"
element in computation theory. Semantically speaking, CNS
expression evaluation is strict in bottom.) If two SC values are
given to the same operator, then the leftmost one takes
priority.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>For instance, the
expression</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>4 + (1/0)*2</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>evaluates to 4 + (SFalse)
* 2, which evaluates to 4 + SFalse, which</span></p>

<p class="MsoNormal c2"><span class='c1'>evaluates to SFalse. On
the other hand,</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>STrue / SFalse</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>would evaluate to STrue,
because STrue comes on the left. Finally,</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>helper, time</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>would evaluate to SFalse
if called with no helpers.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>Currently, STrue is
unused. Only SFalse is returned in error conditions. This means
that any condition-type trigger that causes an error during
evaluation will not trigger. So, in</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>type =
ChangeState</span></p>

<p class="MsoNormal c2"><span class='c1'>trigger1 = helper,
statetype = A</span></p>

<p class="MsoNormal c2"><span class='c1'>value = 0</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>the ChangeState controller
would never be executed if no helpers</span></p>

<p class="MsoNormal c2"><span class='c1'>existed, because the
expression "helper, statetype = A" would evaluate</span></p>

<p class="MsoNormal c2"><span class='c1'>to SFalse, which is
0.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>The documentation on
function-type triggers explains exactly when those</span></p>

<p class="MsoNormal c2"><span class='c1'>triggers will return
SFalse.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>SC values were originally
called short-circuit values, because evaluation on an SC value
"short-circuits" and does not act as normal. However, this
nomenclature had the potential to cause confusion with
short-circuit logical evaluation, so it had to be changed, though
not so drastically as to cause further confusion. Hence
short-circuit values became SC values. At the moment, SC officially
stands for "skip and carry", because when an SC value is
encountered, normal calculation is skipped and the SC value is
simply carried on. Other possibilities for SC include "semantic
codomain" and "so-called". We welcome better suggestions for what
SC should stand for.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'>====================================================================</span></p>

<p class="MsoNormal c2"><span class='c1'>VIII. More on
function-type triggers</span></p>

<p class="MsoNormal c2"><span class=
'c1'>====================================================================</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>Most function-type
triggers either take no arguments or take arguments</span></p>

<p class="MsoNormal c2"><span class='c1'>in a parameter list. For
instance, the time trigger takes no arguments, whereas the ifelse
trigger takes three arguments</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'>ifelse(exp1,exp2,exp3)</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>where exp1, exp2, and exp3
are all valid expressions. In this kind of</span></p>

<p class="MsoNormal c2"><span class='c1'>situation, exp1, exp2, and
exp3 are all considered separate subexpressions, so intervals can
appear on the rightmost end of each of those subexpressions. The
order of evaluation of parameter lists is from left to
right.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>Due to irregular syntax,
some old function-type triggers cannot take</span></p>

<p class="MsoNormal c2"><span class='c1'>expressions as their
arguments. Because of this, they cannot be</span></p>

<p class="MsoNormal c2"><span class='c1'>integrated into
expressions in the standard manner. For nonstandard</span></p>

<p class="MsoNormal c2"><span class='c1'>triggers of this type, the
triggers can only appear with certain sets of operators and
arguments (which are outlined in trigger.doc). In</span></p>

<p class="MsoNormal c2"><span class='c1'>particular, these triggers
cannot take expressions as their arguments. For
instance,</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>trigger1 = AnimElem =
(1+1)</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>is an invalid
expression.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>Old-style function-type
triggers appear only in "clauses" (trigger, relational operator,
argument). These clauses are treated as a single unit
(specifically, a single nullary trigger) for the purposes of
expression evaluation. This means, among other things, that the
concept of operator precedence is not applicable to operators
appearing within an old-style function-type trigger clause. For
instance, in</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>trigger1 = AnimElem = 5 +
4</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>the expression is broken
down into three units:</span></p>

<p class="MsoNormal c2"><span class='c1'>{AnimElem=5} {+}
{4}</span></p>

<p class="MsoNormal c2"><span class='c1'>The "AnimElem=5" unit is
treated as the name of a nullary trigger, hence the + operator does
not have precedence over the = appearing within the name
"AnimElem=5". In other words, this expression means something like
"Execute the trigger called `AnimElem=5', then add 4 to the
result."</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>The list of old-style
function-type triggers, and expression-capable replacements if
applicable, is as follows:</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>AnimElem, superseded by
AnimElemTime</span></p>

<p class="MsoNormal c2"><span class='c1'>P1Name, P2Name, P3Name,
P4Name</span></p>

<p class="MsoNormal c2"><span class='c1'>StateType,
P2StateType</span></p>

<p class="MsoNormal c2"><span class='c1'>Command</span></p>

<p class="MsoNormal c2"><span class='c1'>MoveType,
P2MoveType</span></p>

<p class="MsoNormal c2"><span class='c1'>TimeMod, superseded by the
% operator</span></p>

<p class="MsoNormal c2"><span class='c1'>ProjHit, ProjContact,
ProjGuarded; superseded by ProjHitTime,</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> ProjContactTime, and ProjGuardedTime</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'>====================================================================</span></p>

<p class="MsoNormal c2"><span class='c1'>IX. Expressions in state
and state controller parameters</span></p>

<p class="MsoNormal c2"><span class=
'c1'>====================================================================</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>For the most part, any
parameter to the statedef or a state controller</span></p>

<p class="MsoNormal c2"><span class='c1'>can be an expression. The
exceptions are parameters that are given as</span></p>

<p class="MsoNormal c2"><span class='c1'>strings. For instance, hit
attributes, guardflags, etc. cannot be</span></p>

<p class="MsoNormal c2"><span class='c1'>specified as expressions.
Also, the ForceFeedback controller, as well as the ignorehitpause
and persistent parameters to all controllers, are irregular in that
they cannot take expressions.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>State controller
parameters are evaluated at the time the controller is triggered,
and are not subsequently re-evaluated unless the controller is
triggered again. Parameters that are given as comma-separated lists
are evaluated from left to right. To achieve continual evaluation
of controller parameters, the controller must be continually
triggered.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>In the case of certain
controllers such as HitDef, it is not always wise to use continual
triggering, since this decreases performance and also may lead to
undesired behavior. In this case, the programmer may wish to try to
delay triggering the HitDef as long as possible, so as to evaluate
the HitDef parameters right before they are used.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class=
'c1'>====================================================================</span></p>

<p class="MsoNormal c2"><span class='c1'>X. (Advanced) Optimizing
for speed</span></p>

<p class="MsoNormal c2"><span class=
'c1'>====================================================================</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>MUGEN evaluates
condition-type triggers for a state controller in the following
order: First it evaluates triggeralls, from top to bottom. If any
of the triggeralls evaluates to 0, the rest of the triggers are
skipped and evaluation proceeds to the next controller. If all the
triggeralls evaluate to nonzero, then the engine starts to evaluate
trigger1's, from top to bottom. If any of these evaluate to 0, then
evaluation skips to the first trigger2, and so on. If all the
triggers in a block (besides triggerall) evaluate to nonzero, then
the state controller parameters are evaluated and the controller is
triggered.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>In other words, the
logical evaluation of triggers is short-circuited.</span></p>

<p class="MsoNormal c2"><span class='c1'>In C-like notation, this
setup might be denoted</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;</span> triggerall,1 &amp;&amp; triggerall,2 &amp;&amp;
... &amp;&amp; ((trigger1,1 &amp;&amp; trigger1,2</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;&nbsp;&nbsp;</span> &amp;&amp; ...) || (trigger2,1
&amp;&amp; trigger2,2 &amp;&amp; ...) || ... )</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>where (e.g.) trigger1,2
denotes the second trigger1 line, trigger2,1<span class=
"c3">&nbsp;</span> denotes the first trigger2 line, etc. The
logical evaluation of this trigger group would then be
short-circuited as in C.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>Because of this system,
considerable performance gains can be attained by organizing
expressions so that the condition-type triggers are as simple, and
as few in number, as possible. The bulk of the "work" can be
offloaded to the state controller parameters, which are only
evaluated once at trigger time, instead of every frame that the
player is in the state. For instance,</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>[State -1]</span></p>

<p class="MsoNormal c2"><span class='c1'>type =
ChangeState</span></p>

<p class="MsoNormal c2"><span class='c1'>trigger1 = command =
"a"</span></p>

<p class="MsoNormal c2"><span class='c1'>trigger1 = power &lt;
1000</span></p>

<p class="MsoNormal c2"><span class='c1'>value = 3000</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>[State -1]</span></p>

<p class="MsoNormal c2"><span class='c1'>type =
ChangeState</span></p>

<p class="MsoNormal c2"><span class='c1'>trigger1 = command =
"a"</span></p>

<p class="MsoNormal c2"><span class='c1'>trigger1 = power &gt;=
1000</span></p>

<p class="MsoNormal c2"><span class='c1'>value = 3001</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>[State -1]</span></p>

<p class="MsoNormal c2"><span class='c1'>type =
ChangeState</span></p>

<p class="MsoNormal c2"><span class='c1'>trigger1 = command =
"a"</span></p>

<p class="MsoNormal c2"><span class='c1'>trigger1 = power &gt;=
2000</span></p>

<p class="MsoNormal c2"><span class='c1'>value = 3002</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>could be more compactly
expressed as</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>[State -1]</span></p>

<p class="MsoNormal c2"><span class='c1'>type =
ChangeState</span></p>

<p class="MsoNormal c2"><span class='c1'>trigger1 = command =
"a"</span></p>

<p class="MsoNormal c2"><span class='c1'>value = 3000 + (power
&gt;= 1000) + (power &gt;= 2000)</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>Further speedups are
possible if triggeralls that are most likely to be false are placed
highest in the triggerall block. Similarly, the trigger1 block
should be the most likely block to trigger, but within the trigger1
block itself, the triggers that are most likely to evaluate to 0
should be placed highest. For state controllers with many triggers
containing duplicated conditions, it may be faster to break the
controllers up into two separate blocks, each with its own set of
triggeralls.</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>If you have a complex
condition which is being used as the trigger condition for many
consecutive state controllers, you may wish to save the value of
the condition in a variable, then use that variable as a trigger to
the subsequent controllers. For instance,</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>trigger1 = (command="abc"
&amp;&amp; command!="holddown" &amp;&amp; power&gt;=1000) ||<span
class="c3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> <span class=
"c3">&nbsp;&nbsp;&nbsp;</span>(command="abc" &amp;&amp;
command!="holddown" &amp;&amp; var(5)) ||</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
((command != "abc" || command = "holddown") &amp;&amp;
power&gt;=2000)</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>could be written as
(assuming var(0) is available):</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>trigger1 =
(var(0):=(command="abc" &amp;&amp; command !="holddown") &amp;&amp;
power&gt;=</span></p>

<p class="MsoNormal c2"><span class='c1'><span class=
"c3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
1000) || (var(0) &amp;&amp; var(5)) || (!var(0) &amp;&amp;
power&gt;=2000)</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>Finally, since the
expression parser performs no optimization on expressions, an
expression like</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>trigger1 = ctrl</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>is slightly faster
than</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>

<p class="MsoNormal c2"><span class='c1'>trigger1 = ctrl =
1</span></p>

<p class="MsoNormal c2"><span class=
'c1'><![if !supportEmptyParas]>&nbsp;<![endif]></span></p>
</div>
</body>
</html>

