Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Note

Even if your script is free of XSD errors, that does not mean that the script syntax is correct. For example, there are XML elements that require at least one of multiple attributes, but this requirement cannot be reflected in a schema (apart from documentation text). Please notice the XSD documentation of the elements and attributes, e.g. displayed via tooltips in Visual Studio / Visual Web Developer. Please also note additional requirements for MD cue attributes in this guide (see Conditions).

To check for errors, please pay attention to in-game error messages that are produced while your script is imported, and run-time errors while the script runs. The XSD files can help you a lot, but you should not rely on the absence of XSD errors.

...

Note

Messages printed with <debug_text> are usually only visible when the “scripts” debug filter is enabled, see Script debug output.

Each child action in a <do_any> node can have a weight attribute, which can be used to control the random selection of an action node. The default weight of a child node is 1.

...

Note

This sub-section requires basic knowledge of script expressions.

In case of instances with sub-instances, you will often want to access a related instance from the current one. Like in the non-instance case, you can simply write the cue name in an expression to reference that cue. However, you should be aware of the pitfalls that are accompanied by this.

...

 

Operator / Delimiter / Constant

Type

Example

Result of example

Description

null

constant

null + 1

1

Null value, see above

false

constant

1 == 0

false

Integer value 0, useful in Boolean expressions

true

constant

null == 0

true

Integer value 1, useful in Boolean expressions

pi

constant

2 * pi

6.2831853rad

π as an angle (same as 180deg)

()

delimiter

(2 + 4) * (6 + 1)

42

Parentheses for arithmetic grouping

[]

delimiter

[1, 2, 2+1, 'string']

[1, 2, 3, 'string']

List of values

table[]delimitertable[$foo='bar', {1+1}=40+2]table[$foo='bar', {2}=42]Table of values

{}

delimiter

{101, 3}

'Some text'

Text lookup (page ID and text ID) from TextDB
(Note: Braces are also used for property lookups)

+

unary

+21 * (+2)

42

Denotes positive number (no effect)

-

unary

-(21 * -2)

42

Negates the following number

not

unary

not (21 == 42)

true

Yields true if the following expression is false (equal to zero), false otherwise

typeof

unary

typeof null

typeof 0

typeof 'Hello world'

datatype.null

datatype.integer

datatype.string

Yields the data type of the following sub-expression

sin

unary

sin(30deg)

sin(pi)

0.5

1.0

Sine (function-style, parentheses required)

cos

unary

cos(60deg)

cos(pi)

0.5

0.0

Cosine (function-style, parentheses required)

sqrt

unary

sqrt(2)

1.414213LF

Square root (function-style, parentheses required)

exp

unary

exp(1)

2.71828LF

Exponential function (function-style, parentheses required)

log

unary

log(8) / log(2)

3.0LF

Natural logarithm (function-style, parentheses required)

^

binary

10 ^ 3

1000.0LF

Power

*

binary

21 * 2

42

Multiplication

/

binary

42 / 10
42.0 / 10.0

4
4.2

Division

%

binary

42 % 10

2

Modulus (remainder of integer division)

+

binary

1 + 1

'Hello' + ' world'

2

'Hello world'

Addition

String concatenation

-

binary

1 - 1

0

Subtraction

lt

&lt; (<)

binary

1 lt 3

1 &lt; 3

true

Less than

le

&lt;=

binary

1 le 3

1 &lt;= 3

true

Less than or equal to

gt

&gt; (>)

binary

1 gt 3

1 &gt; 3

false

Greater than

ge

&gt;=

binary

1 ge 3

1 &gt;= 3

false

Greater than or equal to

==

binary

1 + 1 == 2.0

true

Equal to

!=

binary

1 + 1 != 2.0

false

Not equal to

and

binary

true and false

false

Logical AND (short-circuit semantics)

or

binary

true or false

true

Logical OR (short-circuit semantics)

if ... then ...

if ... then ... else ...

ternary

if 1 == 2 then 'F'

if 1 == 2 then 'F' else 'T'

null

'T'

Conditional operator ("inline if")

 

...

  • Of course a Boolean operation always results in true or false (integer 1 or 0).

  • Values of any type can be used as Boolean operands, e.g. for “and”. They will be interpreted as “true” if they are non-zero or non-numeric.

  • != and == can be used with any data types, even non-numeric ones. When comparing two numeric values, they are converted using the rules above. Values of non-numeric types are never equal to null, or to any other numbers.

  • “and” and “or” use short-circuit semantics: The right side of the operation can be skipped if the left side already determines the outcome of the operation

    • Example: false and $foo false (the value of $foo is not checked at all)

  • Unlike != and ==, the comparison operators <, <=, >, >= are only supported for numeric values, difficulty levels, and attention levels. Comparing other non-numeric values will result in an error and an undefined result.

  • <, <=, >, >= cannot be used in XML directly, so lt, le, gt, ge are provided as alternatives. In some cases you won’t have to use them, though - using range checks with additional XML attributes can be more readable.

...

See also the section about value properties.

Instead of ‘%1 %2 %3’, you can also use ‘%s %s %s’, which is also compatible with Lua string formatting in the UI system. However, this should only be used if you are sure that the order is the same in all supported languages. If you want to make translators aware that they can change the order of parameters, you should prefer '%1 %2 %3'.

...

Info

There are also special methods to format money values and time values using the "formatted" property.

...

Another example for a non-numeric value is a list: It is an ordered collection of other arbitrary values (called array or vector in other languages). It can be constructed within an expression using the [] syntax. It may also be generated by special actions and conditions, and there are actions that can insert or remove values.

A list can contain values of arbitrary data types, even mixed in the same list - so a list can actually contain other lists. However, some of the things that you can do with lists require that all contained elements are of a certain type. The contents of a list can be accessed via properties, see the section about value properties. Lists can be empty, these are written as “[ ]”.

...

Lists are stored in variables as references, so multiple variables can refer to the same shared list: If you change a shared list through a variable, e.g. by changing the value of an element, you change it as well for all other variables. However, the operators == and != can also be used on two distinct lists to compare their elements.

Note

When using <remove_from_list/>, be aware that all elements are checked and potentially removed during the action. Do not provide this action with a index lookup of that list as it may become out of bounds.

Bad usage attempting to remove the last element of the list: <remove_from_list name="$List" exact="$List.{$List.count}"/>

If you know the index, simply use <remove_value/> e.g. <remove_value name="$List.{$List.count}"/>


Anchor
tables
tables
Tables

Tables are associative arrays - they are like lists, but you can assign values to (almost) arbitrary keys, not just to index numbers. A table is constructed within an expression using the table[] syntax. See the section about value properties for how to access the contents of a table. Creating and removing entries works similarly to lists, but instead of inserting, you simply assign a value to a table key. If the key does not exist yet, it will be created.

...

Note

The string formatting syntax that you have seen above is also based on the property system. You basically pass a list as property key to a string. Braces around the brackets are not required, so 'foo'.[...] is just a convenient alternative notation for 'foo'.{[...]}.

...

 

Data type (= value name)

Examples

Description

class

class.ship

class.ship_xl

class.space

class.weapon

Component classes

purpose

purpose.combat

purpose.transportation

Purposes

killmethod

killmethod.hitbybullet

killmethod.hitbymissile

Ways to die (already used before destruction)

datatype

datatype.float

datatype.component

datatype.class

datatype.datatype

Script value datatypes

profile

profile.flat

profile.increasing

profile.bell

Probability distribution profile (see random ranges)

cuestate

cuestate.waiting

cuestate.active

cuestate.complete

Cue states

level

level.easy

level.medium

level.veryhard

Mission difficulty levels (comparable with each other using lt, gt, etc.)

attention

attention.insector

attention.visible

attention.adjacentzone

Attention levels (comparable with each other using lt, gt, etc.)

ware

ware.ore

ware.silicon

Wares

race

race.argon

race.boron

Races

faction

faction.player

faction.argongovernment

Factions

Note

Anchor
typeof
typeof
With the typeof operator you can get the datatype of any expression and compare it with what you expect, for example:

typeof $value == datatype.faction

However, you should not compare the type to datatype.string because there are strings that have different data types. To check for a string you should use the datatype's property "isstring" instead. For example, to check if the variable $value is a string, use the following term:

(typeof $value).isstring

Info

There is also the datatype “tag” with the lookup name “tag” - however, this is not an enumeration type. Looking up a value by name never fails, you actually create a tag value for a given name if it does not exist. For example, if you have a typo, like “tag.mision” instead of “tag.mission”, there won’t be an error because any name is valid for a tag, and the tag “mision” is created on its first use.


...

Numbers don't have any properties, except for money and time: They have a "formatted" property, which allows you to get a custom string representation with more advanced options than the generic formatting method for numbers.

  • $money.formatted.{'formatstring'} 
  • $money.formatted.default (using default format string '%s')
  • $time.formatted.{'formatstring'}
  • $time.formatted.default  (using default format string '%T')

...