...
The attributes onfail, checkinterval, checktime are not allowed for cues with event conditions.
Note |
---|
Reminder: When using an XSD-capable editor, it's a great help, but you cannot rely on that alone to verify correctness. Please also check the documentation and look for errors in the game debug output. Concretely, the schema cannot tell whether the above cue attributes are used correctly. |
...
Actions
The <actions> node contains the actions that are performed one after another, without any delay inbetween. You can enforce a delay after activation of the cue and actual action performance, using a <delay> node right before the <actions>:
...
When the ref attribute is provided, all other attributes (except for name) will be ignored and taken from the library cue instead. (By default a library creates its own namespace, as if namespace="static" were specified. See the section about namespaces.)
Also all sub-cues of the library will be created as sub-cues of the cue that uses it. They are defined in the library as <cue>, not as <library>. (Although you can define a library as a sub-cue of another library, the location in the file does not matter, as already stated above.) It is even possible to reference other libraries in sub-cues of a library!
...
So when writing the library, you don’t have to worry about name confusion, just use the names of cues in your library and it will work as expected when the library is used. Names of cues that do not belong to the library will not be available in expressions (see Foo in the example above), however, names of other libraries in the file are available when referencing them in the ref attribute.
Notes:
- It is not possible to directly call a cue which is 'inside' the library from 'outside' of the library, but it is possible to signal the library ref itself (possibly with parameters) and have a sub-cue inside the library listen to the signal on the library ref (possibly checking the parameters).
- You can access variables in the library root but generally this should be avoided in favor of parameterizing the library!
- there are some cases where you do want to access these variables directly, for example for maintaining savegame compatibility when patching.
Library Parameters
A library can be parametrised, so that it can be adapted to the needs of a missions that uses it. You can define required and/or optional parameters for a library, and it will be validated at load time that the user of the library has provided all required parameters.
...
Here is the complete list of numeric data types and corresponding unit suffixes:
Data type | Suffix | Examples | Description |
---|---|---|---|
null | (none) | null | Converted to non-null data type of value 0 when needed. |
integer | i | 42 | 32-bit signed integer. Default for integer literals, so the suffix is not required for them. |
largeint | L | 0x1ffffffffL | Large 64-bit signed integer. |
float | f | 3.14 0x100f | 32-bit float (single precision). Default for floating point literals, so the suffix is not required for them. |
largefloat | LF | 1.5e300 LF | Large 64-bit floating point number (double precision). |
money | ct (default) | 200Cr | Money in Credits or cents, always stored in cents. Do not forget to write Cr when working with Credits. |
length | m (default) km | 500m 2.3km | Length in metres or kilometres, respectively. A length value is always stored in metres. |
angle | rad (default) deg | 90deg 3.14159rad | Angle in radians or degrees, respectively. An angle value is always stored in radians. |
hitpoints | hp | 100hp | Hit points |
time | ms s (default) min h | 800ms 1.5s 10min 24h | Time in milliseconds, seconds, minutes, or hours, respectively. A time value is always stored in seconds. |
Note |
---|
All unit data types are floating point types, except for money, which is an integer data type. |
Anchoroperators operators
Operators
operators | |
operators |
You can build expressions by combining sub-expressions with operators. For Boolean operations, expressions are considered “false” if they are equal to zero, “true” otherwise. The following operators, delimiters, and constants are supported:
...
Operator / Delimiter / Constant | Type | Example | Result of example | Description |
---|---|---|---|---|
null | constant |
|
| Null value, see above |
false | constant |
|
| Integer value 0, useful in Boolean expressions |
true | constant |
|
| Integer value 1, useful in Boolean expressions |
pi | constant |
|
| π as an angle (same as 180deg) |
() | delimiter |
|
| Parentheses for arithmetic grouping |
[] | delimiter |
|
| List of values |
table[] | delimiter | table[$foo='bar', {1+1}=40+2] | table[$foo='bar', {2}=42] | Table of values |
{} | delimiter |
|
| Text lookup (page ID and text ID) from TextDB |
+ | unary |
|
| Denotes positive number (no effect) |
- | unary |
|
| Negates the following number |
not | unary |
|
| Yields true if the following expression is false (equal to zero), false otherwise |
typeof | unary |
|
| Yields the data type of the following sub-expression |
sin | unary |
|
| Sine (function-style, parentheses required) |
cos | unary |
|
| Cosine (function-style, parentheses required) |
sqrt | unary |
|
| Square root (function-style, parentheses required) |
exp | unary |
|
|
Exponential function (function-style, parentheses required) | ||||
log | unary |
|
| Natural logarithm (function-style, parentheses required) |
abs | unary |
| 42 | Absolute value (function-style, parentheses required) (added in X4 v6.00) |
sgn | unary |
sgn( |
3.0LF
-42) | -1 | Sign function (function-style, parentheses required) (added in X4 v6.00) | ||
^ | binary |
|
| Power |
* | binary |
|
| Multiplication |
/ | binary |
|
| Division |
% | binary |
|
| Modulus (remainder of integer division) |
+ | binary |
|
| Addition String concatenation |
- | binary |
|
| Subtraction |
lt < (<) | binary |
|
| Less than |
le <= | binary |
|
| Less than or equal to |
gt > (>) | binary |
|
| Greater than |
ge >= | binary |
|
| Greater than or equal to |
== | binary |
|
| Equal to |
!= | binary |
|
| Not equal to |
and | binary |
|
| Logical AND (short-circuit semantics) |
or | binary |
|
| Logical OR (short-circuit semantics) |
if ... then ... if ... then ... else ... | ternary |
|
| Conditional operator ("inline if") |
Operator precedence rules
...
As you can see, an error is already prevented if any link in the property chain does not exist. But use the @ prefix with care, since error messages are really helpful for detecting problems in your scripts. The @ prefix only suppresses property-related error messages and does not change any in-game behaviour.
Static lookups
There are a few data types which are basically enumerations: They only consist of a set of named values, e.g. the “class” data type, which is used for the component classes that exist in the game. For all these static enumeration classes there is a lookup value of the same name, from which you can get the named values as properties by their name. So for the type “class”, there is a value “class” that can be used to access the classes.
Here are a few enumeration classes and corresponding example lookup values:
...
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 | |
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 | ||||||
---|---|---|---|---|---|---|
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:
|
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. |
...
You can access many player-related game properties via the keyword “player”, for example:
player.name: The player’s name
player.age: The passed in-game time since game start
player.money: The money in the player’s account
player.ship: The ship the player is currently on (not necessarily the player's ship), or null if the player is on a station
- player.primaryship (X Rebirth only): The player's own ship (but the player is not necessarily on board)
- player.occupiedship (X4 only): The ship that the player is currently piloting, or null if the player is not piloting
- player.entity: The actual player object
player.zone, player.sector, player.cluster, player.galaxy: Location of the player entity
player.copilot (X Rebirth only): The co-pilot NPC
The game consists of objects of different classes (zones, ships, stations, NPCs). They have the common datatype "component", however, they have different properties, e.g. NPCs have the property "race", but ships don't.
...
When formatting the money value, any specifier (such as '%s') in the format string is replaced by the money value, so usually the format string only consists of this one specifier. The following modifiers can be used between '%' and the specifier character, to enable formatting options:
1-9 | Truncation | To enable truncation, specify the number of relevant digits that should be displayed. If the money string is too long, it can be truncated and a metric unit prefix (e.g. k = kilo) is appended. (All digits are shown unless truncation is enabled.) |
c | Colouring | If truncation is enabled, the metric unit prefixes (e.g. k, M, G) can be coloured when displayed on the screen, using the escape sequence '\033C'. |
. | Cents | Usually money values have no cent part, since cents are not used in accounts or trades. However, single ware prices can have a non-zero cent part. (Cents are not displayed if money is truncated) |
_ | Spaces | An underscore adds trailing spaces to the result string for better right-aligned display in a tabular layout. |
By default, these options are disabled.
...
Note |
---|
The documentation contains some data types that are no real script data types, but which are useful for documentation purposes. For example, ships and stations are both of datatype “component”, but have different properties based on their component class. |
...
MD refreshing and patching
When a saved game is loaded, the saved MD state is restored, but also all MD files are reloaded and changes in them are applied to the MD state. This is called “refresh”. It is also possible to refresh the MD at run-time using the command “refreshmd” on the in-game command line. This is a convenient way to update MD scripts while the game is already running.
Details and restrictions
Here are some noteworthy facts about refreshing scripts and cues, and the restrictions:
...
Warning |
---|
When adding a variable in a new MD script version and using that variable in multiple places, be aware that the variable doesn't exist yet in older savegames. You may have to check the existence of the variable before accessing it, or add some patch logic that initiailses the variable after loading the savegame, if necessary. |
...
Patching
Cues can have <patch> elements with actions that will be performed when an old savegame is loaded. To control which savegames should be affected, you can add a version attribute to the <cue> node and a sinceversion attribute in the patch. When a cue is loaded from a savegame that has an older version than sinceversion, the <patch> actions will be performed immediately after loading.
...
Note |
---|
The <patch> elements will be ignored when refreshing the MD at run-time. They only affect loaded savegames. |
...
Common attribute groups
There are many commonly used actions and conditions which share groups of attributes. The most important ones are explained here.
Anchorvaluecomparisons valuecomparisons
Value comparisons
valuecomparisons | |
valuecomparisons |
...
Note |
---|
Values of most enumeration types cannot be compared via min or max (also not via lt, gt, etc.). The only data types that can be used with min and max are numbers and the enumeration types level and attention (see Boolean operators). The exact attribute can be used with any type, and is equivalent to using the == operator. |
...
Anchorrandomranges randomranges
Random ranges
randomranges | |
randomranges |
...
Warning |
---|
Although in general the expression “$foo == namespace.$foo” is true, there is one exception: When library parameters are evaluated in the referencing cue, variables are resolved using the parent’s namespace. However, the referencing cue creates a new namespace, so the namespace keyword already points to the library, not to the parent’s namespace. Example:
|