This document contains a brief introduction into the scripting language as implemented so far. See PCC2 Quick Documentation for documentation about PCC2 as a whole.
Like PCC 1.x, PCC2 now contains a script interpreter. The script interpreter understands a simple programming language remotely based upon newer BASIC dialects, and extended to be useful in a VGAP context.
The scripting language is intended to be mostly identical to the PCC 1.x language. However, the underlying implementation is completely different (and, as I hope, more logical and consistent).
As of beta 12, PCC2 is able to evaluate expressions and execute commands. You can therefore use the search function, the console ("calculator"), and unit labels, and bind key using the Bind command. See How to add your own scripts to PCC for information about, well, how to add your own scripts to PCC.
! | This document is still incomplete.
In particular, it is missing the description of object properties.
You can refer to the PCC 1.x scripting manual for those.
However, please be aware that it is not yet 100% implemented yet.
Use the console to try out expressions if in doubt. Remarks about future features of PCC2 have been formatted in this style. |
Names identify things. Many programming languages therefore call them identifiers. A name can contain letters, digits, and the special characters "." (dot), "$" (dollar), and "_" (underscore); it may not start with a digit or dot, and may not end with a dot, though. PCC2 predefines many names you can use in various ways. Those are called properties (properties of objects, such as the name of a ship) and functions. You can also define your own names: variables and subroutines.
The meaning of a name depends on the current context. For example, the word Mission can stand for the mission of a ship or for the mission of a starbase, which are governed by completely different rules. However, names have been chosen in such a way that similar things are represented by similar names. For example, you can use Name="Ares" to search for ships and planets having that name, and Owner$=7 searches for everything owned by player 7.
The current context is determined by the place you're invoking a script from. For example, a planet label expression is always evaluated in the context of the planet. A search expression is evaluated in all possible contexts, as defined by your selection in the search dialog.
Contexts stack. You can temporarily open another context to look at another object's properties. For example, using the Find function to find a ship, as in Find(Ship, Name="Ares", Id), will evaluate the test and return expressions (second and third parameter) in ship context. Names not found in that context will be looked up in the previous contexts.
There are important exceptions to these rules. For example, in Sin(30), Sin always means the sine function, no matter what context is active. Those exceptions are:
Those always mean the same thing, regardless of the current context, and cannot be redefined.
Property names follow some simple guidelines that aim to help you memorize properties.
The shortest name always gives a nice human-readable summary of an item. For example, Mission yields a ship's mission in text form ("Tow a ship"). By adding more words, you can ask for details. For example, Mission.Tow yields the "Tow" parameter of the mission. Alternatively, adding a dollar sign gives the internal representation. For example, Mission$ yields the mission number (7).
For programming, writing search queries, etc., you will probably use the "$" forms most often. For formatting text, you will most likely use the short standard form.
When you define your own names, it makes sense to give them a unique prefix to avoid clashes with others' names (in case you're using scripts developed by others).
Internally, PCC2 uses some names starting with CC$. Those names are undocumented and subject to change without notice. You should not use them. Currently, many keybindings are implemented using a CC$ name. If you want to modify such a keybinding, it's best to copy the existing one. For example, as of beta 9, the "change primary enemy" function (E on ship screen) is implemented as CC$ChangePE. To assign this function to the P key, you should write
Bind Ship "p" := Key(Ship, "e")
instead of Bind Ship "p" := "CC$ChangePE". This is guaranteed to keep working in future versions.
All names, values and expressions have a type. The type defines what you can do with the thing. PCC2 internally tracks these types. If you use a value in a way its type does not allow, PCC2 will show you an appropriate error message. The following types exist:
A very special value is Empty. This value is used for unknown values. For example, when you don't own a ship, it will yield Empty for its Cargo.N (fuel amount). As a general rule, an operation will yield Empty if one of their operands are Empty, and a command will not do anything if a mandatory argument is Empty, but exceptions exist. In a boolean context (If), Empty counts as False.
Technically, subroutines and regular (=not elementary) commands are also represented as values. The only thing you can do with those, however, is invoke them in a command. You cannot use them meaningfully in expressions
PCC2 currently permits all sorts of interesting (and dangerous) things. For example, you can "assign" arrays, functions, and commands, as in Ship := Planet or NewLine := NewRectangle. This will, of course, break a lot of things. For example, when you do Ship := Planet, ships will no longer be accessible, and the expression Ship(3) will refer to planet #3. On the other hand, this can also be used for good, for example to pass a function name to another function ("function pointer" or "closure" as known from other programming languages). PCC2 doesn't yet block those things. Future PCC2 versions may block them to avoid getting you into difficult situations. Rules have not yet been decided.
Some commands require you to specify an amount of cargo. They will accept a specially-formatted string: the string consists of zero or more components separated by spaces. Each component starts with a cargo amount followed by one or more cargo type letters:
Letter | Meaning | Letter | Meaning | Letter | Meaning |
---|---|---|---|---|---|
T | Tritanium | N | Neutronium | S | Supplies |
D | Duranium | F | Fighters | $ | Cash |
M | Molybdenum | W | Torpedoes | C | Colonist clans |
For example, the cost of a starbase can be specified as "900$ 402T 120D 340M". The cost of a Mark 5 Photon can be specified as "1TDM 31$".
Since beta 12, scripts can access files. The commands work almost identical to the commands used in PCC 1.x; many limits have been raised. Well-written code can be used unchanged.
Files must be opened using the Open command before you can work with them. When opening, you associate a file number with the file. The file number is an integer between 1 and 100. You can assign your own file number, or use the FreeFile() function to get an unused one. When you're done with the file, you close it using the Close command. This makes the file number available for future re-use.
In all commands, the file number is, by convention, written with a leading #. This is optional for all file-related commands except for Print (which needs the # sign to know that this is a file number, not a value to print).
Text files can be accessed using the Input and Print commands. PCC2 will automatically convert them from the game character set. As an exception, if they start with a UTF-8 byte order mark, they will be read as UTF-8.
Binary files can be accessed using the Get and Put commands. Those transfer data to and from a special data block object stored in a variable. You can dissect this data block using the GetWord() function and its relatives, and modify it using SetWord and relatives.
In PCC 1.x, a data block was just a string. In PCC2, it is a whole new data type which cannot be used with string manipulation functions (which was possible but deprecated in PCC 1.x).
File I/O is buffered. When you write something to a file, the change may not immediately show up on the disk. If you open the same file on another file number, that other file number will also not immediately see the changes. Changes will be written out when you call Close.
There are a few ways to have PCC2 execute your scripts automatically. This part of PCC2 is not yet complete and will change.
These scripts can contain your code. In particular, it makes sense to put the following things into your startup scripts:
In addition, you can load script files from the console by typing a command such as Load "/path/to/script.q", and you can execute subroutines by simply calling them from the console.
Expressions compute values. They do so by combining elementary values (literals, properties, variables) using operators and functions. The following sections describe expressions in an informal style. For people who prefer it, there's a formal grammar at the end.
Decimal numbers can be used to specify integers or real numbers. The "." is used as the decimal point. A number is integer if it fits into a 32-bit integer number, otherwise it's treated as real.
Strings can be specified in two ways:
Special values are Pi (=3.14159265..., circumference/diameter ratio of a circle), True and False.
Most operations return Empty when one of their arguments is Empty. Operations taking more than one argument usually evaluate them all, even if the result would be known after evaluating only some. Exceptions are explicitly specified.
String operations are case-insensitive by default. That is, "A" compares equal to "a". To get case-sensitive operations, use the StrCase() function. Note that only the basic latin letters are treated case-insensitively; special characters such as "ä" or "д" are always handled case-sensitive.
Some operations taking numerical operands only work with integers. When doing arithmetic, PCC2 keeps track of which values are integers and which are fractions. Arithmetic operators and "+", "-", "*" yield integers when their operands are integers, others like "/" may generate fractions even when used on integers.
The following table shows all operators supported by PCC2. Operators have a certain precedence or binding strength, which determines which parts of the expression belong to that operator. For example, in 2 + 3 * 4, the precedence of * is higher than the precedence of +, so the multiplication is performed first. The addition then adds 2 and the result of 3 * 4. The table shows operators in increasing order of precedence, i.e. later operators are evaluated before those shown first.
a; b | Sequence: evaluate a, discard its result, then evaluate b. |
a := b | Assignment: evaluate b, and assign it to a. Returns b. |
a Or b | Logical Or: return True if either operand is True. If the result is known after evaluating a, does not evaluate b (short-circuit evaluation). |
a Xor b | Logical Exclusive-Or: return True if one operand is True and one is False. If the result is known after evaluating a, does not evaluate b (short-circuit evaluation). |
a And b | Logical And: return False if either operand is False. If the result is known after evaluating a, does not evaluate b (short-circuit evaluation). |
Not a | Logical Not: return True if, False if operand is True. |
a = b | Comparison: return True if a is identical to b. |
a <> b | Comparison: return True if a is different from b. |
a < b | Comparison: return True if a is less than b. |
a > b | Comparison: return True if a is greater than b. |
a <= b | Comparison: return True if a less or equal to b. |
a >= b | Comparison: return True if a is greater or equal to b. |
a # b | Concatenation: convert a and b to strings and concatenate them. |
a & b | Concatenation: convert a and b to strings and concatenate them. If either is Empty but the other is not, treat the Empty one as empty string. |
a + b | Addition: add a and b, which may be numbers or strings. |
a - b | Subtraction: subtract b from a, which must both be numbers. |
a * b | Multiplication: multiply a and b, which must both be numbers. |
a / | Division: divide a by b, which must both be numbers. |
a \ b | Integer division: divide a by b, which must both be integers, and discard the remainder. |
a Mod b | Integer remainder: divide a by b and return the remainder. Both operands must be integers. |
-a | Negation: change sign of a, which must be a number. |
+a | Unary plus: do not change sign of a, which must be a number. Exists for symmetry with "-". |
a ^ b | Power: compute a-to-the-bth. Both operands must be numbers. |
Elementary functions are recognized whenever their name is followed by a parenthesized expression list. Elementary functions thus bypass normal name-lookup.
Most functions are regular, that is, they evaluate all their arguments, and yield Empty if an argument is Empty. Functions that do not follow these rules are marked as irregular.
Most functions expect their parameters of a particular type. In the descriptions, this is denoted by ":type" behind their name: Int=integer, Num=any numerical value, Str=string.
Those items are found by regular name lookup. If you define a local variable named identical to one of these, using that name will find the local variable.
All items that are documented as func(...).prop are actually arrays that can also be used with the Find function, as Find(func, ...).
sequence: assignment sequence ";" assignment assignment: or-expr assignment ":=" or-expr or-expr: and-expr or-expr "Or" and-expr or-expr "Xor" and-expr and-expr: not-expr and-expr "And" not-expr not-expr: comparison "Not" not-expr comparison: concat-expr comparison "=" concat-expr comparison "<" concat-expr comparison ">" concat-expr comparison "<=" concat-expr comparison ">=" concat-expr comparison "<>" concat-expr concat-expr: add-expr concat-expr "#" add-expr concat-expr "&" add-expr add-expr: mult-expr add-expr "+" mult-expr add-expr "-" mult-expr mult-expr: neg-expr mult-expr "*" neg-expr mult-expr "/" neg-expr mult-expr "\" neg-expr mult-expr "Mod" neg-expr neg-expr: pow-expr "-" neg-expr "+" neg-expr pow-expr: primary-expr primary-expr "^" neg-expr primary-expr: "(" sequence ")" string-literal integer-literal float-literal "True" "False" "Pi" identifier invocation* invocation: "(" arguments ")" "." identifier arguments: nothing sequence ("," sequence)* identifier: sequence of letters, "$", "_", digits, ".", not starting with a digit or period not ending with a period string-literal: "'" (any character except for "'")* "'" """ (any character except for """ and "\", or "\" followed by any character) """ integer-literal, float-literal: digit digit* digit digit* "." digit* "." digit digit* A value is an integer if it has no decimal point and fits into 32-bit range. Otherwise, it's float.
Statements tell PCC2 to do something. You can enter statements at the console, or place them in files for execution.
PCC2 distinguishes one-line commands and multi-line (block) commands. A one-line command can be used everywhere a multi-line command can be used, but not vice versa.
A one-line command can be one of the following:
Multi-line commands are always elementary commands. You cannot define own multi-line commands.
PCC2 decides a statement's kind by looking at the first one or two tokens. There is an ambiguity if the statement starts with If. Such a line is always interpreted as an If statement. If you have written an expression-If (If(a,b,c)) instead, which is not a valid If statement, you will get a syntax error. If you really wish to have an expression-If, enclose it in parentheses to make it unique.
command-list: (one-line-command | block-command)*
one-line-command: "Abort" [expression]
Abort: Generates an error. The expression is evaluated and produces the error message. If the expression is not specified, a default error message is generated. The error can be caught using a Try command.
If a=0 Then Abort "a must not be 0"
one-line-command: "Bind" identifier key-binding ("," key-binding)* key-binding: expression ":=" expression
Bind: Defines a key. The identifier specifies a keymap (see CreateKeymap). The key-bindings assign a command (right side) to a keystroke (left side). Both are strings.
Keystrokes consist of zero or more modifiers (Ctrl-, Alt-, Shift-, Meta-, may be abbreviated to C-, A-, etc.), followed by a key name. A key name is either an ASCII character, or a special key name: F1 to F15, Backspace/BS, Pause, Del, Down, End, ESC, Home, Ins, Left, Num5, PgDn, PgUp, Print, Ret/Enter, Right, Space/Spc, Tab, Up, or WheelUp/WheelDown for mouse wheel events. In addition, Quit means the "close-me" button on the window frame ([X]).
As a general rule, PCC2 allows you to bind all printable ASCII characters, i.e. latin letters, digits, and various punctuation marks. This is guaranteed to be supported in all PCC versions.
In addition, as of PCC2 beta 12, you can bind all keys from the game character set. That is, when you play a Western European or American game using the cp437 or latin1 character set, you can bind the Ä key; when you play a Russian game using the cp866 or koi8r character set, you cannot. This restriction may be lifted in the future.
Unlike PCC 1.x, PCC2 is case-sensitive. When you bind Shift-A, you must actually type an upper-case A to trigger this function (i.e. press Shift-A). PCC 1.x didn't distinguish between upper and lower case for (latin) alphabetic keys. Otherwise, PCC2 ignores the Shift modifier for printable keys. Shift-4 generates a "$" sign, so you have to bind $, not Shift-4, if you want something to happen on Shift-4. When in doubt, use the keymap debugger.
Bind ShipScreen "alt-x" := "Print 'Alt-X pressed'" Print AtomStr(Key(ShipScreen, "alt-x"))
As a special case, the right side of a key assigment can also be a value returned by the Key function. This will copy a function from one keymap to another. Unlike PCC 1.x, which had many uncopyable "magic" commands, almost anything sensible can be copied this way in PCC2.
Bind BaseScreen "s" := Key(PlanetScreen, "s")
one-line-command: "Break"
Break: This command is only valid within loops (Do, For, ForEach). It continues execution after the loop, cancelling all iterations that would normally follow.
For i:=1 To 100 If i Mod 7 = 0 Then Break Print i, " is not divisible by 7" Next
one-line-command: "Close" fileNr
Close: Closes the specified file. This will write all buffered data to the disk, and make the file number available for re-use.
one-line-command: "Continue"
Continue: This command is only valid within loops (Do, For, ForEach). It terminates the current iteration and continues with the next iteration of the loop, if any.
one-line-command: "CreateKeymap" keymap-definition ("," keymap-definition)* keymap-definition: identifier identifier "(" identifier ("," identifier)* ")"
CreateKeymap: Create one or more keymaps. The first identifier in each keymap-definition is the name of the new keymap, which must not yet exist. Optionally, you can specify one or many parent keymaps in parentheses. Those are searched in left-to-right order if a key is not found in the keymap itself. Normally, PCC creates all necessary keymaps so you don't have to use CreateKeymap yourself.
CreateKeymap Global, Ship CreateKeymap ControlScreen(Global) CreateKeymap ShipScreen(Ship, ControlScreen)
one-line-command: "CreatePlanetProperty" identifier ("," identifier)* "CreateShipProperty" identifier ("," identifier)*
CreatePlanetProperty, CreateShipProperty: These commands create new planet or ship properties. You can access those like regular properties, and store arbitrary values (strings, numbers) in them. They are automatically stored in the starcharts file and restored when you reload your game.
CreatePlanetProperty Value Planet(10).Value := 9000
one-line-command: "Dim" [storage-class] variable-definition ("," variable-definition)* storage-class variable-definition ("," variable-definition)* storage-class: "Local" "Static" "Shared" variable-definition: identifier identifier ("="|":=") expression identifier "(" expression ("," expression)* ")"
Dim/Local/Static/Shared: Defines new variables. If the variable is indeed new, it will be pre-initialized with the expression, if specified. If you try to redefine a variable that already exists, nothing will happen.
When you specify dimensions, Dim will make an array. You can specify as many dimensions as you want, but the total number of elements in the array must be less than about 100 million. Dimensions must be integers. Specifying a dimension of n means that the array will contain elements 0 .. n-1, i.e. Dim zz(10) will make an array containing ten elements, zz(0) up to zz(9). As usual, if you try to redefine a variable that already exists, nothing will happen.
The storage-class defines the lifetime of the variable:
The following three commands are synonyms:
Dim i=7 Local i=7 Dim Local i=7
When a variable name is mentioned in an expression or statement, PCC2 checks all active contexts:
This means that it's possible to define variables that immediately become inaccessible again because they're shadowed by an "inner" context. For example,
With Ship(10) Do Local Name="foo" Print Name EndWith
will print ship 10's name, not "foo", because the With statement is checked first.
block-command: "Do" [loop-condition] command-list "Loop" [loop-condition] loop-condition: "While" expression "Until" expression
Do: Repeats the command list. Before each iteration, checks the top loop-condition, if specified. The iteration is only performed if the While condition yields true or the Until condition yields false or empty. If no top condition is specified, the iteration is started unconditionally. After each iteration, checks the bottom loop-condition, if specified. Likewise, the loop continues with the next iteration if the While condition yields true or the Until condition yields false or empty. If no bottom condition is specified, the loop continues unconditionally.
i:=0 Do While i < 10 Print i i := i+1 Loop
one-line-command: "End"
End: Terminates this script. This command normally makes no sense in regular code such as keybindings, but it may be useful in scripts intended to run stand-alone. To exit from a subroutine, use Return.
one-line-command: "Eval" expression ("," expression)*
Eval: Builds a temporary script from the parameters, and executes that. Each parameter is one script line.
Eval "For i:=1 To 10 Do Print x"
one-line-command: "For" identifier ":=" expression "To" expression "Do" one-line-command block-command: "For" identifier ":=" expression "To" expression ["Do"] command-list "Next"
For: Counting loop. The identifier names a variable. The variable is set to the value of the first expression, and counts up in steps of one until it reaches the value of the second expression. Both expressions must be numeric.
For i:=1 To 10 Do Print x
one-line-command: "ForEach" expression "Do" one-line-command block-command: "ForEach" expression ["Do"] command-list "Next"
ForEach: The expression must yield an array. The contained command is executed once for each element of the array. This is the command version of Find() and Count().
ForEach Ship Do Print Name Next
block-command: "Function" identifier [parameter-list] command-list "EndFunction" parameter-list: "(" parameter ("," parameter)* ")" parameter: identifier "Optional" identifier
Function: Defines a function. Whenever the function name (the identifier) is invoked in an expression, the command-list will be executed. The command-list should contain a Return statement which determines the function result.
The parameters must be specified in parentheses at the function call. Their values will be available to the command-list as if they were local variables. One parameter can be preceded by Optional, which means that all following parameters may be omitted at the call. They will then be empty within the function body.
Note that function invocations always need parentheses.
Function Square(x) Return x*x EndFunction Print Square(7)
one-line-command: "Get" fileNr "," dataBlock "," length
Get: Read binary data from a file. Reads length bytes from the file fileNr, and stores them in dataBlock, which should be a variable. The dataBlock can then be examined using functions such as GetWord().
Local e Open "xyplan.dat" For Input As #1 Get #1, e, 6 Print "X coordinate of planet #1 is ", GetWord(e, 0)
one-line-command: "If" expression "Then" one-line-command block-command: "If" expression ["Then"] command-list ["Else If" expression ["Then"] command-list]* ["Else" command-list] "EndIf"
If: Conditional execution. Evaluates the expression. If it yields true, executes the command following Then. Otherwise, executes the first matching Else If part, if any. If none of those matches, executes the commands following Else, if specified.
If a Then Print "a is nonzero" If a>10 Then Print "a is greater than 10" Else Print "a is zero or empty" EndIf If i=1 Then Print "One" Else If i=2 Then Print "Two" Else If i=3 Then Print "Three" Else Print "None of one, two, three EndIf
one-line-command: "Input" fileNr "," string ["," flag]
Input: Read text line from a file. Reads a line from the file fileNr and puts it into the string. When the end of the file has been reached, and no line can be read, this command generates an error by default. When the flag is given as True, however, the command succeeds in this case and sets string to Empty.
one-line-command: "Load" expression
Load: The expression yields a file name. That file is opened as a script file and executed.
one-line-command: "On" identifier "Do" one-line-command
On: Registers the one-line-command for execution upon the event named by the identifier. This feature is called hooks because it allows you to hook into various parts of PCC functionality.
Currently, PCC implements the following hooks. Note that this is incompatible to PCC 1.x, and still subject to change.
You can also define your own hooks which you can then invoke using RunHook. A hook is defined by simply using it with an On statement.
On Load Do MyInitialisation
one-line-command: "Open" name "For" open-mode "As" fileNr open-mode: "Input" "Output" "Append" "Random"
Open: opens the file specified by the name, and associates it with the given file number. The open-mode specifies the desired operations:
When you try to open a file number which is already open, PCC2 closes it first.
block-command: "Option" option ("," option) option: identifier ["(" parameters... ")"]
Option: This command is special. It does not by itself do something, but affects how the script interpreter reads and executes your script. It is similar to a pragma or compiler directive in other programming languages.
Option is followed by the option name, an identifier, optionally followed by parameters in parentheses. The actual content of the parentheses depends on the option, but in any case, parentheses must pair up. Multiple options can be combined into a single command. Options not known to the interpreter are ignored. In particular, PCC 1.x ignores the whole Option command.
Although Option takes only a single line of code, it is classified as a block-command. It can thus be only used alone on a line. This is to emphasize the effect that it is processed even when the particular piece of code actually never executes.
one-line-command: "Print" [expression ("," expression)*] "Print" "#" fileNr ["," expression ("," expression)*]
Print: Evaluate all expressions, concatenate their result, and write them to the console. If the first expression is a file number, output is written to that file instead.
one-line-command: "Put" fileNr "," dataBlock ["," length]
Put: Write binary data to a file. Writes length bytes from the dataBlock into file fileNr. If length is omitted, it defaults to the size (highest used index) of the data block. It is recommended to always specify the length.
one-line-command: "Return" [expression]
Return: Stops execution of the current Sub or Function and returns to the caller. If this is a function, the expression must be specified and contains the function result. For subs, the expression must not be specified.
one-line-command: "RunHook" identifier
RunHook: Runs the hook named by identifier. That is, if there are any commands associated with that event, those are run (in the context of your script). See On...Do for more information about hooks.
one-line-command: "Seek" fileNr "," position
Seek: Set the file pointer of the file. The position counts from 0. The file pointer specifies the next position from which data is read, or at which data is written.
block-command: "Select Case" expression ("Case" case-selector ("," case-selector)* command-list)* ["Case Else" command-list] "EndSelect" case-selector: expression "Is <" expression "Is <=" expression "Is =" expression "Is >=" expression "Is >" expression "Is <>" expression
Select Case: Evaluates the Select Case expression. It then selects the first case whose selector matches the result of the expression, and executes the corresponding command-list. If no selector matches, executes the Case Else part, if given.
The expressions used in the selectors should be constants. This is currently not enforced.
Select Case i Case 1 Print "one" Case 2,3,4 Print "two to four" Case Is < 10 Print "below ten, but not one to four" Case Else Print "anything else" EndSelect
one-line-command: "SelectionExec" [selection-expr ":="] selection-expr
SelectionExec: evaluate a selection expression. If an assignment operator is used, assigns the right-hand side to the left-hand side, which must be a layer name or Current. Otherwise, assigns to the current layer. The selection expressions are the same as the ones used for the Selection Manager's "Copy" command, see there for more information.
one-line-command: "SetByte" dataBlock "," index "," value "SetWord" dataBlock "," index "," value "SetLong" dataBlock "," index "," value
SetByte/SetWord/SetLong: Store integer value in a data block. Those commands are the opposite of the GetWord function and its relatives. They store the given value as a 1/2/4-byte integer at the given index in the given dataBlock.
one-line-command: "SetStr" dataBlock "," index "," length "," value
SetStr: Store string in a data block. Those commands is the opposite of the GetStr function. It stores the given string in a length-byte field at the given index in the given dataBlock.
one-line-command: "Stop"
Stop: Suspend this script. Stops execution of this script until the script is woken up again.
The script's entire state is saved, and restored when the script wakes up. PCC2 wakes up all scripts once when it loads a turn. This can be used to wait for certain game events to happen, for example, a ship reaching a planet.
Local and static variables will be preserved. Shared variables are shared between all scripts, and may be changed by scripts that run while this script is suspended.
Some context cannot be saved. For example, when the script is currently displaying a dialog, it cannot suspend. If it attempts to suspend anyway, it will be forcibly terminated.
block-command: "Sub" identifier [parameter-list] command-list "EndSub"
Sub: Defines a subroutine. The identifier becomes a new one-line command. It can be invoked by specifying the identifier followed by the parameters. See Function for more details about the subroutine body.
Subroutines must be invoked as one-line command, without parentheses around the parameters.
Sub PrintSquares(from,to) Local i For i:=from To to Do Print "The square of ", i, " is ", i*i Next EndSub PrintSquares 1, 10
one-line-command: "Try" one-line-command block-command: "Try" command-list ["Else" command-list] "EndTry"
Try: Executes the command following Try. If that command generates an error, and an Else part is specified, System.Err is set to contain the error, and the Else part is executed. Otherwise, the error is ignored.
Try a:=b/c Else Print "Something happened: ", System.Err Print "Usually, division fails due to c being zero" EndTry
one-line-command: "TryLoad" expression
TryLoad: The expression yields a file name. That file is opened as a script file and executed. It is not an error if the file does not exist.
one-line-command: "With" expression "Do" one-line-command block-command: "With" expression ["Do"] command-list "EndWith"
With: Evaluates the expression. The result must be a context. That context is temporarily entered for executing the contained command.
With Ship(10) Do Print "The name of ship 10 is ", Name EndWith Print "The name of ship 10 is ", Ship(10).Name