Difference between revisions of "SCM language"
(Overwrote the HTML code of the table of the "Commands" section with the WIKI code to save a lot of bytes.) |
m (Minor overall fixes applied.) |
||
Line 27: | Line 27: | ||
A ''multiline comment'' embraces a particular area of the source code, starting by the opening tag '''/*''' (slash and asterisk) and ending with '''*/''' (asterisk and slash): | A ''multiline comment'' embraces a particular area of the source code, starting by the opening tag '''/*''' (slash and asterisk) and ending with '''*/''' (asterisk and slash): | ||
− | + | [...] | |
− | /* | + | /* |
− | + | * Some multiline comment | |
− | + | * ... | |
− | + | */ | |
− | [...] | + | [...] |
Currently, more than one multiline comment is allowed per line: | Currently, more than one multiline comment is allowed per line: | ||
Line 91: | Line 91: | ||
=====Timers===== | =====Timers===== | ||
− | A ''timer'' is a ''singular local variable'' whose value rises automatically. It starts incrementing since the beginning of the [[#Structure|script]] where it has been placed. There are ''2 usable timers'' which are already defined as '''TIMERA''' and '''TIMERB''', | + | A ''timer'' is a ''singular local variable'' whose value rises automatically. It starts incrementing since the beginning of the [[#Structure|script]] where it has been placed. There are ''2 usable timers'' which are already defined as '''TIMERA''' and '''TIMERB''', therefore they do not need to be declared. |
===Types=== | ===Types=== | ||
Line 134: | Line 134: | ||
As mentioned in the sections above, local variables have to be put within [[#Curly brackets|curly brackets]]: | As mentioned in the sections above, local variables have to be put within [[#Curly brackets|curly brackets]]: | ||
− | + | { | |
− | + | {varscope}_{vartype} {varname0}[,] [... {varnameN}] | |
− | + | ||
− | + | [...] | |
− | } | + | } |
''Inline variable declaration'' is allowed, you just have to separate them by ''spaces'' or ''tabulations''. Adding a preceding ''comma'' before these characters is optional. | ''Inline variable declaration'' is allowed, you just have to separate them by ''spaces'' or ''tabulations''. Adding a preceding ''comma'' before these characters is optional. | ||
Line 486: | Line 486: | ||
===WHILE=== | ===WHILE=== | ||
− | Alike the '''IF''' construct, '''WHILE''' is a conditional statement. The only difference | + | Alike the '''IF''' ''construct'', '''WHILE''' is a conditional statement. The only difference consists in how it performs the ''consequence'', that is it ''loops'' every line of code built into if the boolean flag is true: |
WHILE [NOT] {condition0} | WHILE [NOT] {condition0} | ||
Line 538: | Line 538: | ||
==Identifiers== | ==Identifiers== | ||
− | ''Undefined | + | ''Undefined constants'' of model identifiers, whose name refers to a ''DFF'' which is presumably archived into any of the ''IMGs'', loaded by the game, are overwritten by a decrementing value in the order they get compiled. These ''model names'' are then put into the second segment of the ''SCM header''. |
==Offsets== | ==Offsets== | ||
− | An ''offset'' is a ''32-bit signed integer'' value which points to a location of the source code. Those of [[#Scripts|scripts]] and [[#Modules|modules]] are ''absolute offsets'' that start from the beginning of the main script, while the ones of [[#Missions|missions]] and [[#Allocating Scripts|allocating scripts]] are ''relative offsets'' starting from their beginning. | + | An ''offset'' is a ''32-bit signed integer'' value which points to a location of the source code. Those of [[#Scripts|scripts]] and [[#Modules|modules]] are ''absolute offsets'' that start from the beginning of the main script, while the ones of [[#Missions|missions]] and [[#Allocating Scripts|allocating scripts]] are ''relative offsets'' starting from their beginning. They always take 4-bytes when they are compiled as [[#Arguments|arguments]]. |
==Variables== | ==Variables== | ||
Line 569: | Line 569: | ||
|} | |} | ||
− | {{note|mblock}} Although the mission block is allocated as an unique script, [[#Local|locals]] point to the same storage location, therefore they are some kind of [[#Global|globals]]. | + | {{note|mblock}} Although the [[#Missions|mission]] block is allocated as an ''unique [[#Scripts|script]]'', [[#Local|locals]] point to the same storage location, therefore they are some kind of [[#Global|globals]] for missions only. |
==Commands== | ==Commands== | ||
Line 577: | Line 577: | ||
===Arguments=== | ===Arguments=== | ||
− | An ''argument'' is some data given as input to a command. | + | An ''argument'' is some data given as input to a command. Normally, commands have a defined amount of arguments up to 32. Those not, such as '''START_NEW_SCRIPT''', can pass as many arguments as the available [[#Local|local variables]] are, except [[#Timers|timers]]. This limitation is game specific. |
===Internal=== | ===Internal=== | ||
Line 2,737: | Line 2,737: | ||
{{note|likely}} It is a likely definition of the standard [[#Natives|native]]. | {{note|likely}} It is a likely definition of the standard [[#Natives|native]]. | ||
− | {{note|dbgstr}} The native still accepts an argument which can admit up to ''128 characters''. In the compiling process, the argument is skipped but its string is copied to a predefined ''128-bytes buffer'' compiled afterwards. These are the predetermined bytes that seem to do nothing: | + | {{note|dbgstr}} The native still accepts an argument which can admit up to ''128 characters''. In the compiling process, the argument is skipped but its string is copied to a predefined ''128-bytes buffer'', compiled afterwards. These are the predetermined bytes that seem to do nothing: |
00 00 41 00 09 2E 00 00 00 00 00 00 <span style="color: blue">'''00'''</span> 00 00 00 | 00 00 41 00 09 2E 00 00 00 00 00 00 <span style="color: blue">'''00'''</span> 00 00 00 | ||
Line 2,767: | Line 2,767: | ||
!Compiled | !Compiled | ||
|- | |- | ||
− | | | + | | |
− | [AND|OR [NOT] {condition8}] | + | IF [NOT] {condition0} |
− | + | [AND|OR [NOT] {condition8}] | |
− | [ELSE | + | {consequence} |
− | + | [ELSE | |
− | ENDIF | + | {alternative}] |
− | | | + | ENDIF |
− | {....} | + | | |
− | {....} | + | {006D} |
− | {004D} | + | {....} |
− | {....} | + | {....} |
− | {0002} | + | {004D} |
− | + | {....} | |
− | {....} | + | {0002} |
− | + | ---- | |
− | | | + | {....} |
− | {....} | + | ---- |
− | {....} | + | | |
− | {004D} | + | {00DB} |
− | {....} | + | {....} |
− | {0002} | + | {....} |
− | + | {004D} | |
− | {....} | + | {....} |
− | + | {0002} | |
− | | | + | ---- |
− | {....} | + | {....} |
− | {....} | + | ---- |
− | {0022} | + | | |
− | {....} | + | {0078} |
− | {0002} | + | {....} |
− | + | {....} | |
− | {....} | + | {0022} |
− | + | {....} | |
− | | | + | {0002} |
− | + | ---- | |
− | + | {....} | |
− | ELSE | + | ---- |
− | + | | | |
− | + | {value} | |
− | ELSE: | + | [NOT] {condition0} |
− | + | [[NOT] {condition8}] | |
− | ENDIF: | + | ELSE |
+ | {consequence} | ||
+ | [GOTO ENDIF | ||
+ | ELSE: | ||
+ | {alternative}] | ||
+ | ENDIF: | ||
|} | |} | ||
Line 2,822: | Line 2,827: | ||
!Compiled | !Compiled | ||
|- | |- | ||
− | | | + | | |
− | [AND|OR [NOT] {condition8}] | + | WHILE [NOT] {condition0} |
− | + | [AND|OR [NOT] {condition8}] | |
− | ENDWHILE | + | {consequence} |
− | | | + | ENDWHILE |
− | {006D} | + | | |
− | {....} | + | ---- |
− | {....} | + | {006D} |
− | {004D} | + | {....} |
− | {....} | + | {....} |
− | {0002} | + | {004D} |
− | + | {....} | |
− | | | + | {0002} |
− | {00DB} | + | ---- |
− | {....} | + | | |
− | {....} | + | ---- |
− | {004D} | + | {00DB} |
− | {....} | + | {....} |
− | {0002} | + | {....} |
− | + | {004D} | |
− | | | + | {....} |
− | {0078} | + | {0002} |
− | {....} | + | ---- |
− | {....} | + | | |
− | {0022} | + | ---- |
− | {....} | + | {0078} |
− | {0002} | + | {....} |
− | + | {....} | |
− | | | + | {0022} |
− | {value} | + | {....} |
− | + | {0002} | |
− | + | ---- | |
− | ENDWHILE | + | | |
− | + | WHILE: | |
− | + | {value} | |
− | ENDWHILE: | + | [NOT] {condition0} |
+ | [[NOT] {condition8}] | ||
+ | ENDWHILE | ||
+ | {consequence} | ||
+ | GOTO WHILE | ||
+ | ENDWHILE: | ||
|} | |} | ||
Line 2,870: | Line 2,880: | ||
!Compiled | !Compiled | ||
|- | |- | ||
− | | | + | | |
− | + | FOR {varname} FROM {value0} TO {valueN} | |
− | ENDFOR | + | {code} |
− | |width=1px| | + | ENDFOR |
− | + | |width=1px| | |
− | {....} | + | {0004} |
− | {0008} | + | ---- |
− | {0028} | + | {....} |
− | {004D} | + | {0008} |
− | |width=1px| | + | {0028} |
− | + | {004D} | |
− | {....} | + | |width=1px| |
− | {0009} | + | {0005} |
− | {0029} | + | ---- |
− | {004D} | + | {....} |
− | | | + | {0009} |
− | + | {0029} | |
− | {....} | + | {004D} |
− | {0007} | + | | |
− | {0015} | + | {0004} |
− | {0022} | + | ---- |
− | | | + | {....} |
− | LOOP: | + | {0007} |
− | {code} | + | {0015} |
− | ++ {varname} | + | {0022} |
− | + | | | |
− | LOOP | + | {varname} = {value0} |
+ | LOOP: | ||
+ | {code} | ||
+ | ++ {varname} | ||
+ | {varname} >= {valueN} | ||
+ | LOOP | ||
|} | |} | ||
Line 2,908: | Line 2,923: | ||
!Compiled | !Compiled | ||
|- | |- | ||
− | | | + | | |
− | + | CASE {varname} | |
− | + | WHEN {value0} | |
− | + | {consequence} | |
− | + | [WHEN {valueN} | |
− | + | {consequence}] | |
− | + | [ELSE | |
− | ENDCASE | + | {alternative}] |
− | | | + | ENDCASE |
− | {0872} | + | | |
− | + | {0871} | |
− | {....} | + | {0872} |
− | {0002} | + | ---- |
− | + | {....} | |
− | {....} | + | {0002} |
− | {0002} | + | ---- |
− | + | {....} | |
− | {....} | + | {0002} |
− | {0002} | + | ---- |
− | + | {....} | |
− | | | + | {0002} |
− | [-1 ENDCASE -1 ENDCASE -1 ENDCASE -1 ENDCASE -1 ENDCASE -1 ENDCASE -1 ENDCASE -1 ENDCASE -1 ENDCASE] | + | ---- |
− | WHEN0: | + | | |
− | + | {varname} {cases} {iselse} ELSE {value0} WHEN0 {valueN} WHENN -1 ENDCASE -1 ENDCASE -1 ENDCASE -1 ENDCASE -1 ENDCASE | |
− | + | [-1 ENDCASE -1 ENDCASE -1 ENDCASE -1 ENDCASE -1 ENDCASE -1 ENDCASE -1 ENDCASE -1 ENDCASE -1 ENDCASE] | |
− | [WHENN: | + | WHEN0: |
− | + | {consequence} | |
− | + | GOTO ENDCASE | |
− | [ELSE: | + | [WHENN: |
− | + | {consequence} | |
− | + | GOTO ENDCASE] | |
− | ENDCASE: | + | [ELSE: |
+ | {alternative} | ||
+ | GOTO ENDCASE] | ||
+ | ENDCASE: | ||
|} | |} | ||
Line 2,950: | Line 2,968: | ||
!Compiled | !Compiled | ||
|- | |- | ||
− | | | + | | |
− | + | CASE {varname} | |
− | + | WHEN {value0} | |
− | + | {consequence} | |
− | + | [WHEN {valueN} | |
− | + | {consequence}] | |
− | + | [ELSE | |
− | ENDCASE | + | {alternative}] |
− | |width=1px| | + | ENDCASE |
− | {0038} | + | |width=1px| |
− | {004D} | + | ---- |
− | {....} | + | {0038} |
− | {0002} | + | {004D} |
− | + | {....} | |
− | {0038} | + | {0002} |
− | {004D} | + | ---- |
− | {....} | + | {0038} |
− | {0002} | + | {004D} |
− | + | {....} | |
− | {....} | + | {0002} |
− | + | ---- | |
− | + | {....} | |
− | |width=1px| | + | ---- |
− | {0039} | + | ---- |
− | {004D} | + | |width=1px| |
− | {....} | + | ---- |
− | {0002} | + | {0039} |
− | + | {004D} | |
− | {0039} | + | {....} |
− | {004D} | + | {0002} |
− | {....} | + | ---- |
− | {0002} | + | {0039} |
− | + | {004D} | |
− | {....} | + | {....} |
− | + | {0002} | |
− | + | ---- | |
− | | | + | {....} |
− | {001B} | + | ---- |
− | {0022} | + | ---- |
− | {....} | + | | |
− | {0002} | + | ---- |
− | + | {001B} | |
− | {001B} | + | {0022} |
− | {0022} | + | {....} |
− | {....} | + | {0002} |
− | {0002} | + | ---- |
− | + | {001B} | |
− | {....} | + | {0022} |
− | + | {....} | |
− | + | {0002} | |
− | | | + | ---- |
− | + | {....} | |
− | WHENN | + | ---- |
− | + | ---- | |
− | + | | | |
− | WHENN: | + | WHEN0: |
− | + | {varname} = {value0} | |
− | + | WHENN | |
− | + | {consequence} | |
− | + | [GOTO ENDCASE0 | |
− | + | WHENN: | |
− | + | {varname} = {valueN} | |
− | + | ELSE | |
− | ENDCASE0: | + | {consequence} |
+ | [GOTO ENDCASEN | ||
+ | ELSE: | ||
+ | {alternative}] | ||
+ | ENDCASEN:] | ||
+ | ENDCASE0: | ||
|} | |} | ||
Line 3,030: | Line 3,053: | ||
{{N|3|VC|SA}} | {{N|3|VC|SA}} | ||
+ | |||
+ | {{Script-stub}} | ||
[[Category:Mission Script]] | [[Category:Mission Script]] | ||
− | |||
− |
Revision as of 12:41, 28 August 2012
It may contain non-standard SCM definitions as R* hasn't published enough documentation about it yet.
On the occasion of the GTAIII's tenth anniversary, after a long period of darkness where we fell about the real SCM sintax, R* finally treated us by attaching part of its own original source code into the GTAIII Anniversary game, available for iOs and Android devices. As far back as 2001, a snip of some debugging scripts has been already provided with main.sc and debug.sc files. However, many secrets are unrevealed yet, thus some things cannot be documented fully and so they can be only guessed. The SCM format denomination is one of countless proofs of this inconvenience, which may stand for Script Controlled Missions. Other doubts come with source files, whose SC extension appears to be very close to Script Control. At first, someone could have asked oneself how R* named its own programming language: R#? R-Sharp? Rockstar Sharp? Who knows. We simply call it SCM language due to the lack of information.
Preliminary remarks
This article makes use of formatted codes to improve the reading comprehension. Note that:
- Square brackets mean everything inside may be omitted.
- Curly brackets denote the presence of useful codes but not necessarily needed.
- Vertical bars divide what can be chosen alternatively.
Fundamentals
Comments
A comment is an additional text that may be helpful for the code writer or other users, in short for the reader. It is the only part of the source code which gets always ignored when compiling.
Inline
An inline comment, denoted by // (two slashes), makes everything that follows some plain text:
[...] // Some inline comment
Multiline
A multiline comment embraces a particular area of the source code, starting by the opening tag /* (slash and asterisk) and ending with */ (asterisk and slash):
[...] /* * Some multiline comment * ... */ [...]
Currently, more than one multiline comment is allowed per line:
[...] /* Some inline comment */ [...] /* Some inline comment */ [...]
- Limit
- Comments cannot be nested.
Brackets
Brackets play an important role, especially when organizing multiple scripts in a single file becomes necessary.
Curly brackets
Curly brackets (or multiline brackets) act like a local variable scope. Essentially, they enclose the code where local variables are used, including timers. They can be opened and closed many times in a script:
{ [...] }
Round brackets
Actually, the round brakets (or multi inline brackets) behaviour sounds trivial, that's to say they simply highlight one or more arguments per native, individually or together. In , they appear to be used only for SETUP_ZONE_PED_INFO (in a various order) and GXT keys:
SETUP_ZONE_PED_INFO FISHFAC DAY (0) 0 0 0 (0 0 0 0) 0 PRINT_BIG (T4X4_1) 5000 2
They might lock up null values.
Labels
A label is a sequence of characters which identifiy a location of the source code useful for jumps. To define a label just append : (colon) to its name:
[...] {lblname}: [...]
At the compiling time, they are automatically converted into an offset.
Variables
A variable is a storage location assigned to a symbolic name which contains a value of any type.
Scope
The usage of a variable depends on the scope, that is the context where a specific variable is declared. At this point, we can distinguish the global and local scope.
Global
The global scope grasps the whole source code. Variables defined as globals are visible in any script. They are declared by appending the VAR prefix.
Local
The local scope wraps a localized part of the source code. Variables defined as locals are visible only in the code enclosed by curly brackets. They are declared by appending the LVAR prefix.
Timers
A timer is a singular local variable whose value rises automatically. It starts incrementing since the beginning of the script where it has been placed. There are 2 usable timers which are already defined as TIMERA and TIMERB, therefore they do not need to be declared.
Types
Among the available types, some are equivalent to the most known programming types. Their length is up to 4, 8 and 16 bytes. Each type is appended as a suffix in the variable declaration.
INT
The INT type handles 32-bit signed integer values. It is also used to store values with less bytes, such as a bool.
FLOAT
The FLOAT type handles 32-bit floating-point values. As it normally does, decimal precision is usually stuck to 6 digits beyond which it may get lost.
CONST
CONST is a special type that handles 32-bit signed integer values. It is used only to compare constants of model identifiers, task statuses or ped events.
STRING
The STRING type handles 8-byte strings. Generally, a string is an array of 1-byte characters. It often requires 7 characters plus the null-terminator (a blank byte meaning the end of the string). It is used to hold GXT keys (those of town zones, interiors, help textes or dialogue subtitles) or script names.
NAME
The NAME type handles 16-byte strings. Like the previous type, it often holds 15 characters plus the null-terminator. It is used to store model and texture names of player clothes or animation names.
Declaration
Defining a variable means assigning a token string to a memory cell at the compiling time. Variables must be declared in the following manner:
{varscope}_{vartype} {varname0}[,] [... {varnameN}]
As mentioned in the sections above, local variables have to be put within curly brackets:
{ {varscope}_{vartype} {varname0}[,] [... {varnameN}] [...] }
Inline variable declaration is allowed, you just have to separate them by spaces or tabulations. Adding a preceding comma before these characters is optional.
- Limit
- Whereas the variable buffer is limited, you can declare a certain amount of globals and locals. Numerical (INT, FLOAT) and special (CONST) types take 1 variable, while string types (STRING, NAME) occupy respectively 2 and 4 variables to store some data (have a look here for further details).
Arrays
A array is a collection of variables having the same type which can be accessed by an index, an integer value enclosed by square brackets:
{varscope}_{vartype} {varname0}{[arrsize0]}[,] [... {varnameN}{[arrsizeN]}]
Operators
In general, operators help programmers to do math calculations or operations of any other kind.
Assigning
Assigning is both initializing a variable and giving any value to the variable itself or the content of another one:
{varname} = {anyvalue|varname}
Calculating
Calculating is achieved by using the most common algebric operations. Sadly, the game has only support for adding, subtracting, multiplying and dividing:
{varname} += {anyvalue|varname} {varname} -= {anyvalue|varname} {varname} *= {anyvalue|varname} {varname} /= {anyvalue|varname}
Yet, you can combine assigning and calculating as follows:
{varname} = {anyvalue|varname} + {anyvalue|varname} {varname} = {anyvalue|varname} - {anyvalue|varname} {varname} = {anyvalue|varname} * {anyvalue|varname} {varname} = {anyvalue|varname} / {anyvalue|varname}
String (STRING, NAME) and special (CONST) types are free from these calculations. For a better code understanding, the expression of incrementing or decrementing by a unit can be written as:
{varname} ++ {varname} -- ++ {varname} -- {varname}
The compiler doesn't care about pre-increment or post-increment. Both are translated into:
{varname} += 1 {varname} -= 1
- Limit
- Multiple operations per line are not allowed.
Converting
Converting means casting a variable having a particular type into another. You can convert integer to floating-point values or viceversa:
{varname} =# {varname}
Ofcourse, the left variable will contain the result of the conversion of the right one.
Comparing
Comparing is the evaluation of a boolean flag regarding the comparison between two values or variables:
{varname} = {anyvalue|varname} // equal to {varname} > {anyvalue|varname} // greater than {varname} < {anyvalue|varname} // lesser than {varname} >= {anyvalue|varname} // greater than or equal to {varname} <= {anyvalue|varname} // lesser than or equal to
Theorically, string types (STRING, NAME) should be compared with the first operator only, but the presence of the COMPARE_STRING increase the doubts concerning the existence of such operator for strings.
Natives
A native is a symbolic name associated to a command which executes a portion of code that specifies the operation to be performed by passing zero or more arguments. Commands do not return values that can be assigned to a variable, even though the boolean flag is kept whenever they are used as conditions. It follows the common programming sintax adopted for procedure or function calls:
{nativename} [{anyvalue0|varname0} ... {anyvalueN|varnameN}]
Built-in
Built-in natives are those which are associated to more commands that differ each other by argument types or actions:
- :
- TIMESTEP
- TIMESTEPUNWARPED
- ABSI
- ABSF
- :
- COMPARE_STRING
- SAVE_STRING_TO_DEBUG_FILE
- IS_BIT_SET
- SET_BIT
- CLEAR_BIT
- IS_STRING_NULL
- COMBINE_STRING
This section is incomplete. You can help by fixing and expanding it.
WAIT
A WAIT skips the execution of a script according to some milliseconds after which it will resume again. Indeed, it is absolutely necessary into infinite loops or those that break after more than one frame, such as the WHILE statement. In this case, a value equal to 0 is passed.
GOTO
A GOTO is the jump to the label of any location of the source code. It is also used internally to build other statements:
jump: GOTO jump_2 [...] jump_2: GOTO jump
GOSUB
A GOSUB is the jump to the label of a subroutine, which executes some code and returns back to the place it was called with RETURN.
Embedded
Embedded GOSUBS are those enclosed into a file script. If local variables are used within the subroutine, you should put it into the local scope of the calling script. When included in a module, they seem to behave like embedded scripts.
Trigger
GOSUB jump
Code
jump: [...] RETURN
File
File GOSUBS are those included into a script file singularly. It's likely GOSUB_AT_FILE loads a module that can call other embedded gosubs or scripts.
Trigger
GOSUB_AT_FILE gosub.sc
Code
// File: gosub.sc [...] RETURN
Constants
A constant is a symbolic name associated to a specific value. When compiling, their caption is converted in the assigned value. They are listed into TXT files, whose name follows the Pascal Notation which implyies that all first letters of the words are in uppercase and other characters are lowercase (eg. AudioEvents.txt). These files respect the sintax below:
{constname0} {constvalue0} {constnameN} {constvalueN}
Constant names and values are divided by as many spaces or tabulations as you want. Constant lines are distinguished by two \n (new line) characters. The model names which aren't assigned to a constant are still valid (see Identifiers for further information).
Others
The arguments of some natives accept only constant values of a single namespace. Instead, the CONST type can hold every constant of any namespace.
This section is incomplete. You can help by fixing and expanding it.
Formatting
Everything is case-insensitive, that means the uppercase and lowercase letters are computed as the same character. Usually, the source code is formatted as shown in this table:
Entity | Uppercase | Lowercase |
---|---|---|
Label | X | |
Declaration | X | |
Variable | X | |
Native | X | |
Constant | X | |
Statement | X |
Compiling
Structure
The source code is split up into several SC files which comprehend scripts, missions, allocating scripts and modules.
Scripts
A script is a code block which takes part of a queue of other scripts. As long as it isn't terminated with TERMINATE_THIS_SCRIPT or TERMINATE_ALL_SCRIPTS_WITH_NAME (elsewhere in another script), its execution never expires till the end of the game process. Each one works independently, even though they are able to share global variables.
Embedded
Embedded scripts are those started by SC files where their body is included into. Note START_NEW_SCRIPT has an undefined amount of arguments which match with each local variable of the starting script.
Trigger
START_NEW_SCRIPT script [{anyvalue0|varname0} ... {anyvalueN|varnameN}]
Code
script: SCRIPT_NAME script script_loop: { [LVAR_{vartype} {varname0}[,] [... {varnameN}]] [...] } //GOTO script_loop TERMINATE_THIS_SCRIPT
File
File scripts are those which enclose none or more embedded scripts other than their main script. The MISSION opening and closing natives let us supposing scripts that own a SC file are computed as missions. MISSION_START is a special directive which doesn't get compiled, whereas MISSION_END is an alias of TERMINATE_THIS_SCRIPT. Yet, you can also start the scripts embedded in other files.
Trigger
START_NEW_SCRIPT_FROM_FILE script.sc
Code
// File: script.sc MISSION_START [VAR_{vartype} {varname0}[,] [... {varnameN}]] SCRIPT_NAME main main_loop: { [LVAR_{vartype} {varname0}[,] [... {varnameN}]] START_NEW_SCRIPT script [{anyvalue0|varname0} ... {anyvalueN|varnameN}] [...] } //GOTO main_loop MISSION_END script: SCRIPT_NAME script script_loop: { [LVAR_{vartype} {varname0}[,] [... {varnameN}]] [...] } //GOTO script_loop TERMINATE_THIS_SCRIPT
Missions
A mission is a script which takes part of the mission block. When it is launched, the pointer is moved to the corresponding mission offset located somewhere in the mission block. Do not forget to begin a mission with MISSION_START (ghost native) and stop its execution with MISSION_END. Although missions are file scripts, you are able to start embedded scripts, whether they are put in the current file or not.
Trigger
LAUNCH_MISSION mission.sc
Code
// File: mission.sc MISSION_START GOSUB mission_start IF HAS_DEATHARREST_BEEN_EXECUTED GOSUB mission_failed ENDIF GOSUB mission_cleanup MISSION_END [VAR_{vartype} {varname0}[,] [... {varnameN}]] mission_start: REGISTER_MISSION_GIVEN SCRIPT_NAME mission // Variables initialization { [LVAR_{vartype} {varname0}[,] [... {varnameN}]] [...] } GOTO mission_passed mission_failed: [...] RETURN mission_passed: REGISTER_MISSION_PASSED mission //PLAYER_MADE_PROGRESS 1 [...] RETURN mission_cleanup: // Mark everything as no longer needed [...] RETURN
Allocating scripts
This section is incomplete. You can help by fixing and expanding it.
Modules
The module has been introduced since but it was never completed. It is unused in and got removed in , but then it was fully implemented in and .
This section is incomplete. You can help by fixing and expanding it.
Statements
As usual, the evolution of something implies its development over the years. Alongside, the statements implementation has been distributed equally into every chapter. Their definitions are similar to those used in pseudocodes resulting in a raw source code.
IF
IF is one of the most widespread conditional statements which executes some codes by evaluating a boolean flag, also known as a condition. According to the returning value, either the consequence or the alternative will be performed. The condition result can be inverted by appending the NOT clause before. More conditions require the use of logical operators, they are AND, when verifying if all checks are true, and OR, while testing if one of all checks is true. The sintax below summarize the whole explanation:
IF [NOT] {condition0} [AND|OR [NOT] {condition8}] {consequence} [ELSE {alternative}] ENDIF
- Limit
- More than 9 conditions per statement are't supported.
WHILE
Alike the IF construct, WHILE is a conditional statement. The only difference consists in how it performs the consequence, that is it loops every line of code built into if the boolean flag is true:
WHILE [NOT] {condition0} [AND|OR [NOT] {condition8}] {consequence} ENDWHILE
FOR
Similar to the WHILE construct, FOR iterates some code depending on an incremental variable which goes through the given range, whose ending value must be subsequent to its beginning.
FOR {varname} FROM {value0} TO {valueN} {code} ENDFOR
- Limits
- It is supported since .
- The range accepts only integer values.
- Values must be subsequent.
- The code will be read at least once in any case.
CASE
Basically, CASE is a group of concatenated IF statements. When a condition is false the next case gets performed, otherwise the consequence is executed and the code jumps to the end of the construct. If none of the cases is true, an ELSE clause may be carried out:
CASE {varname} WHEN {value0} {consequence} [WHEN {valueN} {consequence}] [ELSE {alternative}] ENDCASE
- Limits
- It is supported since .
- The WHEN clause allows the use of integer values only.
- In , values must be sorted.
- Multiple cases per consequence aren't allowed.
FUNCTION
This section is incomplete. You can help by fixing and expanding it.
Decompiling
Structure
For any information about the SCM file format, read this article.
Identifiers
Undefined constants of model identifiers, whose name refers to a DFF which is presumably archived into any of the IMGs, loaded by the game, are overwritten by a decrementing value in the order they get compiled. These model names are then put into the second segment of the SCM header.
Offsets
An offset is a 32-bit signed integer value which points to a location of the source code. Those of scripts and modules are absolute offsets that start from the beginning of the main script, while the ones of missions and allocating scripts are relative offsets starting from their beginning. They always take 4-bytes when they are compiled as arguments.
Variables
The following table shows the variables range of the local scope for each game version:
Scope | |||||
---|---|---|---|---|---|
Script | 0-15 | 0-15 | 0-31 | 0-95 | 0-95 |
Mission[*] | 0-15 | 0-15 | 0-1023 | 0-95 | 0-95 |
Allocating script | n/a | n/a | 0-31 | n/a | n/a |
Module | 0-15 | 0-15 | n/a | 0-95 | 0-95 |
Function | n/a | n/a | n/a | 0-95 | 0-95 |
Timer | 16-17 | 16-17 | 32-33 | 10-11? | 254-255 |
^ Although the mission block is allocated as an unique script, locals point to the same storage location, therefore they are some kind of globals for missions only.
Commands
A command is a 16-bit unsigned integer value referring to a portion of code the game executes when it is called by passing an undefined or absent amount of arguments. The maximum number of available commands is 0x7FFF, since the last bit (0x8000) is set whenever they are used as negative conditions (those with the NOT clause).
Arguments
An argument is some data given as input to a command. Normally, commands have a defined amount of arguments up to 32. Those not, such as START_NEW_SCRIPT, can pass as many arguments as the available local variables are, except timers. This limitation is game specific.
Internal
Here is the list of all commands handled arbitrarily by a hypothetical compiler:
Acronym | Description | Acronym | Description | Acronym | Description | Acronym | Description | Acronym | Description | Acronym | Description |
---|---|---|---|---|---|---|---|---|---|---|---|
IV | INT value | FV | FLOAT value | CV | CONST value | SV | STRING value | NV | NAME value | LO | Label offset |
GI | Global INT | GF | Global FLOAT | GC | Global CONST | GS | Global STRING | GN | Global NAME | MN | Mission number |
LI | Local INT | LF | Local FLOAT | LC | Local CONST | LS | Local STRING | LN | Local NAME | AN | Allocating script number |
Native or Operator | Command | Args | Arguments | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | ||||
MISSION_START[*] | 0 | ||||||||||||||||||||||||||||||||||
GOTO[*] | 0002 | 1 | LO | ||||||||||||||||||||||||||||||||
INT Operator = | 0004 | 2 | GI | IV | |||||||||||||||||||||||||||||||
0006 | LI | IV | |||||||||||||||||||||||||||||||||
0084 | GI | GI | |||||||||||||||||||||||||||||||||
0085 | LI | LI | |||||||||||||||||||||||||||||||||
008A | GI | LI | |||||||||||||||||||||||||||||||||
008B | LI | GI | |||||||||||||||||||||||||||||||||
FLOAT Operator = | 0005 | 2 | GF | FV | |||||||||||||||||||||||||||||||
0007 | LF | FV | |||||||||||||||||||||||||||||||||
0086 | GF | GF | |||||||||||||||||||||||||||||||||
0087 | LF | LF | |||||||||||||||||||||||||||||||||
0088 | GF | LF | |||||||||||||||||||||||||||||||||
0089 | LF | GF | |||||||||||||||||||||||||||||||||
INT Operator += | 0008 | 2 | GI | IV | |||||||||||||||||||||||||||||||
000A | LI | IV | |||||||||||||||||||||||||||||||||
0058 | GI | GI | |||||||||||||||||||||||||||||||||
005A | LI | LI | |||||||||||||||||||||||||||||||||
005C | LI | GI | |||||||||||||||||||||||||||||||||
005E | GI | LI | |||||||||||||||||||||||||||||||||
FLOAT Operator += | 0009 | 2 | GF | FV | |||||||||||||||||||||||||||||||
000B | LF | FV | |||||||||||||||||||||||||||||||||
0059 | GF | GF | |||||||||||||||||||||||||||||||||
005B | LF | LF | |||||||||||||||||||||||||||||||||
005D | LF | GF | |||||||||||||||||||||||||||||||||
005F | GF | LF | |||||||||||||||||||||||||||||||||
INT Operator -= | 000C | 2 | GI | IV | |||||||||||||||||||||||||||||||
000E | LI | IV | |||||||||||||||||||||||||||||||||
0060 | GI | GI | |||||||||||||||||||||||||||||||||
0062 | LI | LI | |||||||||||||||||||||||||||||||||
0064 | LI | GI | |||||||||||||||||||||||||||||||||
0066 | GI | LI | |||||||||||||||||||||||||||||||||
FLOAT Operator -= | 000D | 2 | GF | FV | |||||||||||||||||||||||||||||||
000F | LF | FV | |||||||||||||||||||||||||||||||||
0061 | GF | GF | |||||||||||||||||||||||||||||||||
0063 | LF | LF | |||||||||||||||||||||||||||||||||
0065 | LF | GF | |||||||||||||||||||||||||||||||||
0067 | GF | LF | |||||||||||||||||||||||||||||||||
INT Operator *= | 0010 | 2 | GI | IV | |||||||||||||||||||||||||||||||
0012 | LI | IV | |||||||||||||||||||||||||||||||||
0068 | GI | GI | |||||||||||||||||||||||||||||||||
006A | LI | LI | |||||||||||||||||||||||||||||||||
006C | GI | LI | |||||||||||||||||||||||||||||||||
006E | LI | GI | |||||||||||||||||||||||||||||||||
FLOAT Operator *= | 0011 | 2 | GF | FV | |||||||||||||||||||||||||||||||
0013 | LF | FV | |||||||||||||||||||||||||||||||||
0069 | GF | GF | |||||||||||||||||||||||||||||||||
006B | LF | LF | |||||||||||||||||||||||||||||||||
006D | GF | LF | |||||||||||||||||||||||||||||||||
006F | LF | GF | |||||||||||||||||||||||||||||||||
INT Operator /= | 0014 | 2 | GI | IV | |||||||||||||||||||||||||||||||
0016 | LI | IV | |||||||||||||||||||||||||||||||||
0070 | GI | GI | |||||||||||||||||||||||||||||||||
0072 | LI | LI | |||||||||||||||||||||||||||||||||
0074 | GI | LI | |||||||||||||||||||||||||||||||||
0076 | LI | GI | |||||||||||||||||||||||||||||||||
FLOAT Operator /= | 0015 | 2 | GF | FV | |||||||||||||||||||||||||||||||
0017 | LF | FV | |||||||||||||||||||||||||||||||||
0071 | GF | GF | |||||||||||||||||||||||||||||||||
0073 | LF | LF | |||||||||||||||||||||||||||||||||
0075 | GF | LF | |||||||||||||||||||||||||||||||||
0077 | LF | GF | |||||||||||||||||||||||||||||||||
INT Operator =# | 008C | 2 | GI | GF | |||||||||||||||||||||||||||||||
008E | LI | GF | |||||||||||||||||||||||||||||||||
0090 | GI | LF | |||||||||||||||||||||||||||||||||
0092 | LI | LF | |||||||||||||||||||||||||||||||||
FLOAT Operator =# | 008D | 2 | GF | GI | |||||||||||||||||||||||||||||||
008F | LF | GI | |||||||||||||||||||||||||||||||||
0091 | GF | LI | |||||||||||||||||||||||||||||||||
0093 | LF | LI | |||||||||||||||||||||||||||||||||
INT Conditional Operator = | 0038 | 2 | GI | IV | |||||||||||||||||||||||||||||||
0039 | LI | IV | |||||||||||||||||||||||||||||||||
003A | GI | GI | |||||||||||||||||||||||||||||||||
003B | LI | LI | |||||||||||||||||||||||||||||||||
003C | GI | LI | |||||||||||||||||||||||||||||||||
FLOAT Conditional Operator = | 0042 | 2 | GF | FV | |||||||||||||||||||||||||||||||
0043 | LF | FV | |||||||||||||||||||||||||||||||||
0044 | GF | GF | |||||||||||||||||||||||||||||||||
0045 | LF | LF | |||||||||||||||||||||||||||||||||
0046 | GF | LF | |||||||||||||||||||||||||||||||||
INT Conditional Operator > | 0018 | 2 | GI | IV | |||||||||||||||||||||||||||||||
0019 | LI | IV | |||||||||||||||||||||||||||||||||
001C | GI | GI | |||||||||||||||||||||||||||||||||
001D | LI | LI | |||||||||||||||||||||||||||||||||
001E | GI | LI | |||||||||||||||||||||||||||||||||
001F | LI | GI | |||||||||||||||||||||||||||||||||
FLOAT Conditional Operator > | 0020 | 2 | GF | FV | |||||||||||||||||||||||||||||||
0021 | LF | FV | |||||||||||||||||||||||||||||||||
0024 | GF | GF | |||||||||||||||||||||||||||||||||
0025 | LF | LF | |||||||||||||||||||||||||||||||||
0026 | GF | LF | |||||||||||||||||||||||||||||||||
0027 | LF | GF | |||||||||||||||||||||||||||||||||
INT Conditional Operator < | 002A | 2 | IV | GI | |||||||||||||||||||||||||||||||
002B | IV | LI | |||||||||||||||||||||||||||||||||
FLOAT Conditional Operator < | 0032 | 2 | FV | GF | |||||||||||||||||||||||||||||||
0033 | FV | LF | |||||||||||||||||||||||||||||||||
INT Conditional Operator >= | 0028 | 2 | GI | IV | |||||||||||||||||||||||||||||||
0029 | LI | IV | |||||||||||||||||||||||||||||||||
002C | GI | GI | |||||||||||||||||||||||||||||||||
002D | LI | LI | |||||||||||||||||||||||||||||||||
002E | GI | LI | |||||||||||||||||||||||||||||||||
002F | LI | GI | |||||||||||||||||||||||||||||||||
FLOAT Conditional Operator >= | 0030 | 2 | GF | FV | |||||||||||||||||||||||||||||||
0031 | LF | FV | |||||||||||||||||||||||||||||||||
0034 | GF | GF | |||||||||||||||||||||||||||||||||
0035 | LF | LF | |||||||||||||||||||||||||||||||||
0036 | GF | LF | |||||||||||||||||||||||||||||||||
0037 | LF | GF | |||||||||||||||||||||||||||||||||
INT Conditional Operator <= | 001A | 2 | IV | GI | |||||||||||||||||||||||||||||||
001B | IV | LI | |||||||||||||||||||||||||||||||||
FLOAT Conditional Operator <= | 0022 | 2 | FV | GF | |||||||||||||||||||||||||||||||
0023 | FV | LF | |||||||||||||||||||||||||||||||||
TIMESTEP | 0078 | 2 | GF | FV | |||||||||||||||||||||||||||||||
0079 | LF | FV | |||||||||||||||||||||||||||||||||
007A | GF | GF | |||||||||||||||||||||||||||||||||
007B | LF | LF | |||||||||||||||||||||||||||||||||
007C | LF | GF | |||||||||||||||||||||||||||||||||
007D | GF | LF | |||||||||||||||||||||||||||||||||
TIMESTEPUNWARPED | 007E | 2 | GF | FV | |||||||||||||||||||||||||||||||
007F | LF | FV | |||||||||||||||||||||||||||||||||
0080 | GF | GF | |||||||||||||||||||||||||||||||||
0081 | LF | LF | |||||||||||||||||||||||||||||||||
0082 | LF | GF | |||||||||||||||||||||||||||||||||
0083 | GF | LF | |||||||||||||||||||||||||||||||||
ABSI | 0094 | 1 | GI | ||||||||||||||||||||||||||||||||
0095 | LI | ||||||||||||||||||||||||||||||||||
ABSF | 0096 | 1 | GF | ||||||||||||||||||||||||||||||||
0097 | LF | ||||||||||||||||||||||||||||||||||
Jump If False[*] | 004D | 1 | LO | ||||||||||||||||||||||||||||||||
TERMINATE_THIS_SCRIPT | 004E | 0 | |||||||||||||||||||||||||||||||||
MISSION_END | |||||||||||||||||||||||||||||||||||
START_NEW_SCRIPT[*] | 004F | 1 | LO | _ _ _ | |||||||||||||||||||||||||||||||
GOSUB | 0050 | 1 | LO | ||||||||||||||||||||||||||||||||
RETURN | 0051 | 0 | |||||||||||||||||||||||||||||||||
Comparing Rule[*] | 00D6 | 1 | IV | ||||||||||||||||||||||||||||||||
START_NEW_SCRIPT_FROM_FILE[*] | 00D7 | 1 | LO | ||||||||||||||||||||||||||||||||
LAUNCH_MISSION | 0417 | 1 | MN | ||||||||||||||||||||||||||||||||
Jump If True[*] | 004C | 1 | LO | ||||||||||||||||||||||||||||||||
RETURN_TRUE[*] | 00C5 | 0 | |||||||||||||||||||||||||||||||||
RETURN_FALSE[*] | 00C6 | 0 | |||||||||||||||||||||||||||||||||
GOSUB_AT_FILE[*] | 02CD | 2 | LO | LO | |||||||||||||||||||||||||||||||
CONST Operator = | 04AE | 2 | GC | CV | |||||||||||||||||||||||||||||||
04AF | LC | CV | |||||||||||||||||||||||||||||||||
CONST Conditional Operator = | 04A3 | 2 | GC | CV | |||||||||||||||||||||||||||||||
04A4 | LC | CV | |||||||||||||||||||||||||||||||||
CONST Conditional Operator > | 04B0 | 2 | GC | CV | |||||||||||||||||||||||||||||||
04B1 | LC | CV | |||||||||||||||||||||||||||||||||
CONST Conditional Operator < | 04B6 | 2 | CV | GV | |||||||||||||||||||||||||||||||
04B7 | CV | LC | |||||||||||||||||||||||||||||||||
CONST Conditional Operator >= | 04B4 | 2 | GC | CV | |||||||||||||||||||||||||||||||
04B5 | LC | CV | |||||||||||||||||||||||||||||||||
CONST Conditional Operator <= | 04B2 | 2 | CV | GC | |||||||||||||||||||||||||||||||
04B3 | CV | LC | |||||||||||||||||||||||||||||||||
STRING Operator = | 05A9 | 2 | GS | SV | |||||||||||||||||||||||||||||||
GS | GS | ||||||||||||||||||||||||||||||||||
GS | LS | ||||||||||||||||||||||||||||||||||
05AA | LS | SV | |||||||||||||||||||||||||||||||||
LS | LS | ||||||||||||||||||||||||||||||||||
LS | GS | ||||||||||||||||||||||||||||||||||
NAME Operator = | 06D1 | 2 | GN | NV | |||||||||||||||||||||||||||||||
GN | GN | ||||||||||||||||||||||||||||||||||
GN | LN | ||||||||||||||||||||||||||||||||||
06D2 | LN | NV | |||||||||||||||||||||||||||||||||
LN | LN | ||||||||||||||||||||||||||||||||||
LN | GN | ||||||||||||||||||||||||||||||||||
INT Conditional Operator = | 07D6 | 2 | LI | GI | |||||||||||||||||||||||||||||||
FLOAT Conditional Operator = | 07D7 | 2 | LF | GF | |||||||||||||||||||||||||||||||
STRING Conditional Operator = COMPARE_STRING |
05AD | 2 | GS | SV | |||||||||||||||||||||||||||||||
GS | GS | ||||||||||||||||||||||||||||||||||
GS | LS | ||||||||||||||||||||||||||||||||||
05AE | LS | SV | |||||||||||||||||||||||||||||||||
LS | LS | ||||||||||||||||||||||||||||||||||
LS | GS | ||||||||||||||||||||||||||||||||||
NAME Conditional Operator = COMPARE_STRING |
08F9 | 2 | GN | NV | |||||||||||||||||||||||||||||||
GN | GN | ||||||||||||||||||||||||||||||||||
GN | LN | ||||||||||||||||||||||||||||||||||
08FA | LN | NV | |||||||||||||||||||||||||||||||||
LN | LN | ||||||||||||||||||||||||||||||||||
LN | GN | ||||||||||||||||||||||||||||||||||
SAVE_STRING_TO_DEBUG_FILE[*] | 05B6 | 0 | |||||||||||||||||||||||||||||||||
IS_STRING_NULL | 0844 | 1 | GS | ||||||||||||||||||||||||||||||||
0845 | LS | ||||||||||||||||||||||||||||||||||
0846 | GN | ||||||||||||||||||||||||||||||||||
0847 | LN | ||||||||||||||||||||||||||||||||||
Initialize Table Of Jumps | 0871 | 18 | GI | IV | IV | LO | IV | LO | IV | LO | IV | LO | IV | LO | IV | LO | IV | LO | IV | LO | |||||||||||||||
LI | IV | IV | LO | IV | LO | IV | LO | IV | LO | IV | LO | IV | LO | IV | LO | IV | LO | ||||||||||||||||||
Append Table Jumps | 0872 | 18 | IV | LO | IV | LO | IV | LO | IV | LO | IV | LO | IV | LO | IV | LO | IV | LO | IV | LO | |||||||||||||||
IS_BIT_SET | 08B4 | 2 | GI | IV | |||||||||||||||||||||||||||||||
08B5 | GI | GI | |||||||||||||||||||||||||||||||||
08B6 | GI | LI | |||||||||||||||||||||||||||||||||
08B7 | LI | IV | |||||||||||||||||||||||||||||||||
08B8 | LI | GI | |||||||||||||||||||||||||||||||||
08B9 | LI | LI | |||||||||||||||||||||||||||||||||
SET_BIT | 08BA | 2 | GI | IV | |||||||||||||||||||||||||||||||
08BB | GI | GI | |||||||||||||||||||||||||||||||||
08BC | GI | LI | |||||||||||||||||||||||||||||||||
08BD | LI | IV | |||||||||||||||||||||||||||||||||
08BE | LI | GI | |||||||||||||||||||||||||||||||||
08BF | LI | LI | |||||||||||||||||||||||||||||||||
CLEAR_BIT | 08C0 | 2 | GI | IV | |||||||||||||||||||||||||||||||
08C1 | GI | GI | |||||||||||||||||||||||||||||||||
08C2 | GI | LI | |||||||||||||||||||||||||||||||||
08C3 | LI | IV | |||||||||||||||||||||||||||||||||
08C4 | LI | GI | |||||||||||||||||||||||||||||||||
08C5 | LI | LI | |||||||||||||||||||||||||||||||||
COMBINE_STRING[*] | 098B | 3 | GS | GS | GS | ||||||||||||||||||||||||||||||
098C | GN | GN | GN | ||||||||||||||||||||||||||||||||
CONST Operator = | 04B3 | 2 | GC | CV | |||||||||||||||||||||||||||||||
04B4 | LC | CV | |||||||||||||||||||||||||||||||||
CONST Conditional Operator = | 04A8 | 2 | GC | CV | |||||||||||||||||||||||||||||||
04A9 | LC | CV | |||||||||||||||||||||||||||||||||
CONST Conditional Operator > | 04B5 | 2 | GC | CV | |||||||||||||||||||||||||||||||
04B6 | LC | CV | |||||||||||||||||||||||||||||||||
CONST Conditional Operator < | 04BB | 2 | CV | GV | |||||||||||||||||||||||||||||||
04BC | CV | LC | |||||||||||||||||||||||||||||||||
CONST Conditional Operator >= | 04B9 | 2 | GC | CV | |||||||||||||||||||||||||||||||
04BA | LC | CV | |||||||||||||||||||||||||||||||||
CONST Conditional Operator <= | 04B7 | 2 | CV | GC | |||||||||||||||||||||||||||||||
04B8 | CV | LC | |||||||||||||||||||||||||||||||||
Comparing Rule[*] | 00DB | 1 | IV | ||||||||||||||||||||||||||||||||
START_NEW_SCRIPT_FROM_FILE[*] | 00DC | 1 | LO | ||||||||||||||||||||||||||||||||
GOSUB_AT_FILE[*] | 02D2 | 2 | LO | LO | |||||||||||||||||||||||||||||||
LAUNCH_MISSION | 041C | 1 | MN | ||||||||||||||||||||||||||||||||
Call Function[*] | 05AE | 4 | IV | IV | IV | LO | _ _ _ | ||||||||||||||||||||||||||||
05AF | |||||||||||||||||||||||||||||||||||
INT Operator = | 0004 | 2 | GI | IV | |||||||||||||||||||||||||||||||
LI | IV | ||||||||||||||||||||||||||||||||||
0035 | GI | GI | |||||||||||||||||||||||||||||||||
GI | LI | ||||||||||||||||||||||||||||||||||
LI | LI | ||||||||||||||||||||||||||||||||||
LI | GI | ||||||||||||||||||||||||||||||||||
FLOAT Operator = | 0005 | 2 | GF | FV | |||||||||||||||||||||||||||||||
LF | FV | ||||||||||||||||||||||||||||||||||
0036 | GF | GF | |||||||||||||||||||||||||||||||||
GF | LF | ||||||||||||||||||||||||||||||||||
LF | LF | ||||||||||||||||||||||||||||||||||
LF | GF | ||||||||||||||||||||||||||||||||||
STRING Operator = | 0006 | 2 | GS | SV | |||||||||||||||||||||||||||||||
LS | SV | ||||||||||||||||||||||||||||||||||
0037 | GS | GS | |||||||||||||||||||||||||||||||||
GS | LS | ||||||||||||||||||||||||||||||||||
LS | LS | ||||||||||||||||||||||||||||||||||
LS | GS | ||||||||||||||||||||||||||||||||||
INT Operator += | 0007 | 2 | GI | IV | |||||||||||||||||||||||||||||||
LI | IV | ||||||||||||||||||||||||||||||||||
0029 | GI | GI | |||||||||||||||||||||||||||||||||
GI | LI | ||||||||||||||||||||||||||||||||||
LI | LI | ||||||||||||||||||||||||||||||||||
LI | GI | ||||||||||||||||||||||||||||||||||
FLOAT Operator += | 0008 | 2 | GF | FV | |||||||||||||||||||||||||||||||
LF | FV | ||||||||||||||||||||||||||||||||||
002A | GF | GF | |||||||||||||||||||||||||||||||||
GF | LF | ||||||||||||||||||||||||||||||||||
LF | LF | ||||||||||||||||||||||||||||||||||
LF | GF | ||||||||||||||||||||||||||||||||||
INT Operator -= | 0009 | 2 | GI | IV | |||||||||||||||||||||||||||||||
LI | IV | ||||||||||||||||||||||||||||||||||
002B | GI | GI | |||||||||||||||||||||||||||||||||
GI | LI | ||||||||||||||||||||||||||||||||||
LI | LI | ||||||||||||||||||||||||||||||||||
LI | GI | ||||||||||||||||||||||||||||||||||
FLOAT Operator -= | 000A | 2 | GF | FV | |||||||||||||||||||||||||||||||
LF | FV | ||||||||||||||||||||||||||||||||||
002C | GF | GF | |||||||||||||||||||||||||||||||||
GF | LF | ||||||||||||||||||||||||||||||||||
LF | LF | ||||||||||||||||||||||||||||||||||
LF | GF | ||||||||||||||||||||||||||||||||||
INT Operator *= | 000B | 2 | GI | IV | |||||||||||||||||||||||||||||||
LI | IV | ||||||||||||||||||||||||||||||||||
002D | GI | GI | |||||||||||||||||||||||||||||||||
GI | LI | ||||||||||||||||||||||||||||||||||
LI | LI | ||||||||||||||||||||||||||||||||||
LI | GI | ||||||||||||||||||||||||||||||||||
FLOAT Operator *= | 000C | 2 | GF | FV | |||||||||||||||||||||||||||||||
LF | FV | ||||||||||||||||||||||||||||||||||
002E | GF | GF | |||||||||||||||||||||||||||||||||
GF | LF | ||||||||||||||||||||||||||||||||||
LF | LF | ||||||||||||||||||||||||||||||||||
LF | GF | ||||||||||||||||||||||||||||||||||
INT Operator /= | 000D | 2 | GI | IV | |||||||||||||||||||||||||||||||
LI | IV | ||||||||||||||||||||||||||||||||||
002F | GI | GI | |||||||||||||||||||||||||||||||||
GI | LI | ||||||||||||||||||||||||||||||||||
LI | LI | ||||||||||||||||||||||||||||||||||
LI | GI | ||||||||||||||||||||||||||||||||||
FLOAT Operator /= | 000E | 2 | GF | FV | |||||||||||||||||||||||||||||||
LF | FV | ||||||||||||||||||||||||||||||||||
0030 | GF | GF | |||||||||||||||||||||||||||||||||
GF | LF | ||||||||||||||||||||||||||||||||||
LF | LF | ||||||||||||||||||||||||||||||||||
LF | GF | ||||||||||||||||||||||||||||||||||
INT Operator =# | 0038 | 2 | GI | GI | |||||||||||||||||||||||||||||||
GI | LI | ||||||||||||||||||||||||||||||||||
LI | LI | ||||||||||||||||||||||||||||||||||
LI | GI | ||||||||||||||||||||||||||||||||||
FLOAT Operator =# | 0039 | 2 | GF | GF | |||||||||||||||||||||||||||||||
GF | LF | ||||||||||||||||||||||||||||||||||
LF | LF | ||||||||||||||||||||||||||||||||||
LF | GF | ||||||||||||||||||||||||||||||||||
INT Conditional Operator = | 001B | 2 | GI | IV | |||||||||||||||||||||||||||||||
LI | IV | ||||||||||||||||||||||||||||||||||
001C | GI | GI | |||||||||||||||||||||||||||||||||
GI | LI | ||||||||||||||||||||||||||||||||||
LI | LI | ||||||||||||||||||||||||||||||||||
LI | GI | ||||||||||||||||||||||||||||||||||
FLOAT Conditional Operator = | 001D | 2 | GF | FV | |||||||||||||||||||||||||||||||
LF | FV | ||||||||||||||||||||||||||||||||||
001E | GF | GF | |||||||||||||||||||||||||||||||||
GF | LF | ||||||||||||||||||||||||||||||||||
LF | LF | ||||||||||||||||||||||||||||||||||
LF | GF | ||||||||||||||||||||||||||||||||||
STRING Conditional Operator = COMPARE_STRING |
001F | 2 | GS | SV | |||||||||||||||||||||||||||||||
LS | SV | ||||||||||||||||||||||||||||||||||
0020 | GS | GS | |||||||||||||||||||||||||||||||||
GS | LS | ||||||||||||||||||||||||||||||||||
LS | LS | ||||||||||||||||||||||||||||||||||
LS | GS | ||||||||||||||||||||||||||||||||||
INT Conditional Operator > | 000F | 2 | GI | IV | |||||||||||||||||||||||||||||||
LI | IV | ||||||||||||||||||||||||||||||||||
0011 | GI | GI | |||||||||||||||||||||||||||||||||
GI | LI | ||||||||||||||||||||||||||||||||||
LI | LI | ||||||||||||||||||||||||||||||||||
LI | GI | ||||||||||||||||||||||||||||||||||
FLOAT Conditional Operator > | 0012 | 2 | GF | FV | |||||||||||||||||||||||||||||||
LF | FV | ||||||||||||||||||||||||||||||||||
0014 | GF | GF | |||||||||||||||||||||||||||||||||
GF | LF | ||||||||||||||||||||||||||||||||||
LF | LF | ||||||||||||||||||||||||||||||||||
LF | GF | ||||||||||||||||||||||||||||||||||
INT Conditional Operator < | 0016 | 2 | IV | GI | |||||||||||||||||||||||||||||||
IV | LI | ||||||||||||||||||||||||||||||||||
FLOAT Conditional Operator < | 0019 | 2 | FV | GF | |||||||||||||||||||||||||||||||
FV | LF | ||||||||||||||||||||||||||||||||||
INT Conditional Operator >= | 0015 | 2 | GI | IV | |||||||||||||||||||||||||||||||
LI | IV | ||||||||||||||||||||||||||||||||||
0017 | GI | GI | |||||||||||||||||||||||||||||||||
GI | LI | ||||||||||||||||||||||||||||||||||
LI | LI | ||||||||||||||||||||||||||||||||||
LI | GI | ||||||||||||||||||||||||||||||||||
FLOAT Conditional Operator >= | 0018 | 2 | GF | FV | |||||||||||||||||||||||||||||||
LF | FV | ||||||||||||||||||||||||||||||||||
001A | GF | GF | |||||||||||||||||||||||||||||||||
GF | LF | ||||||||||||||||||||||||||||||||||
LF | LF | ||||||||||||||||||||||||||||||||||
LF | GF | ||||||||||||||||||||||||||||||||||
INT Conditional Operator <= | 0010 | 2 | IV | GI | |||||||||||||||||||||||||||||||
IV | LI | ||||||||||||||||||||||||||||||||||
FLOAT Conditional Operator <= | 0013 | 2 | IV | GI | |||||||||||||||||||||||||||||||
IV | LI | ||||||||||||||||||||||||||||||||||
TIMESTEP | 0031 | 2 | GF | FV | |||||||||||||||||||||||||||||||
LF | FV | ||||||||||||||||||||||||||||||||||
0032 | GF | GF | |||||||||||||||||||||||||||||||||
GF | LF | ||||||||||||||||||||||||||||||||||
LF | LF | ||||||||||||||||||||||||||||||||||
LF | GF | ||||||||||||||||||||||||||||||||||
TIMESTEPUNWARPED | 0033 | 2 | GF | FV | |||||||||||||||||||||||||||||||
LF | FV | ||||||||||||||||||||||||||||||||||
0034 | GF | GF | |||||||||||||||||||||||||||||||||
GF | LF | ||||||||||||||||||||||||||||||||||
LF | LF | ||||||||||||||||||||||||||||||||||
LF | GF | ||||||||||||||||||||||||||||||||||
ABSI | 003A | 1 | GI | ||||||||||||||||||||||||||||||||
LI | |||||||||||||||||||||||||||||||||||
ABSF | 003B | 1 | GF | ||||||||||||||||||||||||||||||||
LF | |||||||||||||||||||||||||||||||||||
CONST Operator = | 02E2 | 2 | GC | CV | |||||||||||||||||||||||||||||||
LC | CV | ||||||||||||||||||||||||||||||||||
CONST Conditional Operator = | 02DB | 2 | GC | CV | |||||||||||||||||||||||||||||||
LC | CV | ||||||||||||||||||||||||||||||||||
CONST Conditional Operator > | 02E3 | 2 | GC | CV | |||||||||||||||||||||||||||||||
LC | CV | ||||||||||||||||||||||||||||||||||
CONST Conditional Operator < | 02E6 | 2 | CV | GV | |||||||||||||||||||||||||||||||
CV | LC | ||||||||||||||||||||||||||||||||||
CONST Conditional Operator >= | 02E5 | 2 | GC | CV | |||||||||||||||||||||||||||||||
LC | CV | ||||||||||||||||||||||||||||||||||
CONST Conditional Operator <= | 02E4 | 2 | CV | GC | |||||||||||||||||||||||||||||||
CV | LC | ||||||||||||||||||||||||||||||||||
Jump If True[*] | 0021 | 1 | LO | ||||||||||||||||||||||||||||||||
Jump If False[*] | 0022 | 1 | LO | ||||||||||||||||||||||||||||||||
TERMINATE_THIS_SCRIPT | 0023 | 0 | |||||||||||||||||||||||||||||||||
MISSION_END | |||||||||||||||||||||||||||||||||||
START_NEW_SCRIPT[*] | 0024 | 1 | LO | _ _ _ | |||||||||||||||||||||||||||||||
GOSUB | 0025 | 1 | LO | ||||||||||||||||||||||||||||||||
RETURN | 0026 | 0 | |||||||||||||||||||||||||||||||||
RETURN_TRUE[*] | 005E | 0 | |||||||||||||||||||||||||||||||||
RETURN_FALSE[*] | 005F | 0 | |||||||||||||||||||||||||||||||||
Comparing Rule[*] | 0078 | 1 | IV | ||||||||||||||||||||||||||||||||
START_NEW_SCRIPT_FROM_FILE[*] | 0079 | 1 | LO | ||||||||||||||||||||||||||||||||
GOSUB_AT_FILE[*] | 01BA | 2 | LO | LO | |||||||||||||||||||||||||||||||
LAUNCH_MISSION | 0289 | 1 | MN | ||||||||||||||||||||||||||||||||
Call Function[*] | 037A | 1 | IV | IV | IV | LO | _ _ _ | ||||||||||||||||||||||||||||
037B |
^ A special mission directive which is never compiled.
^ It is hidden when used to build statements.
^ It is hidden in the source code.
^ It has an undefined amount of arguments.
^ It is a likely definition of the standard native.
^ The native still accepts an argument which can admit up to 128 characters. In the compiling process, the argument is skipped but its string is copied to a predefined 128-bytes buffer, compiled afterwards. These are the predetermined bytes that seem to do nothing:
00 00 41 00 09 2E 00 00 00 00 00 00 00 00 00 00 09 2E 00 00 00 00 00 00 1C FB 12 00 D8 A8 41 00 00 00 41 00 09 2E 00 00 00 00 00 00 01 00 00 00 09 2E 00 00 00 00 00 00 1C FB 12 00 D8 A8 41 00 00 00 41 00 09 2E 00 00 00 00 00 00 02 00 00 00 09 2E 00 00 00 00 00 00 1C FB 12 00 D8 A8 41 00 00 00 41 00 09 2E 00 00 00 00 00 00 03 00 00 00 09 2E 00 00 00 00 00 00 1C FB 12 00 D8 A8 41 00
^ It gets transformed when compiling.
This section is incomplete. You can help by fixing and expanding it.
Analysis
As an overview of the compiled source, statements are literally nested meaning that the code is unoptimized. Furthermore, the jump of an embedded construct doesn't get merged with that of the construct itself, which consists of a benefit for the code parsing.
IF
The IF statement can handle up to 9 checks per construct. 006D (, , ), 00DB () and 0078 ( indicate you are verifying a single check (0) or multiple checks with either AND clause (1 to 8) or OR clause (21 to 28). When the consequence is performed, the code jumps to the end of the construct:
WHILE
The WHILE statement is pretty much similar to the previous, even though when the consequence is read the code is moved to the beginning of the construct:
FOR
Seemingly, the FOR statement is the first construct ever optimized as a result of a possible R* compiler fault. Moreover, it sounds ambiguous as it loops at least once. This was probably the intention of R*'s programmers, that is iterating at least twise else the construct is useless. However, there are some chance they decide to use such structure to avoid some conflict with the WHILE construct:
CASE
In , the CASE statement is more complex and efficient because the game uses internally a binary search algorithm to jump at the label that matches with the value of a particular case. This method requires a known amount of cases which is up to 75. When a case is true, a consequence is executed and the code jumps to the end of the construct, otherwise the alternative may be performed. As the code is unoptimized, the GOTO of the last case is still compiled even though its label points to the end of the jump itself:
In and , such statement is a set of nested IF constructs which causes a very slight loss of performance by considering that 00DB () and 0078 ( aren't compiled:
FUNCTION
This section is incomplete. You can help by fixing and expanding it.
Optimization
In and , whenever a single condition is checked 00DB () and 0078 () don't get compiled cause no logical operator (AND, OR) is used and so they become really useless. Its lack increase the script efficiency a lot. However, the jump of the ELSE clause of an IF statement which points to the end of the construct is still compiled after a GOTO.