Difference between revisions of "SCM language"

From GTAMods Wiki
Jump to navigation Jump to search
(Fixed something wrong that usually occurs after a huge update.)
m (Opcode)
(40 intermediate revisions by 6 users not shown)
Line 1: Line 1:
 +
<center><span style="color: #CC0000">'''Announcement''': This article is currently being reworked. Check out the progresses by visiting [http://pastebin.com/raw/YfLWLXJw this] link from time to time. Contact [http://www.gtaforums.com/index.php?showuser=172776 Wesser] for any suggestion.</span></center>
 
{{This|This section deals with the native SCM syntax of GTA 3 series, nothing other than [[GTA 3|III]], [[GTA VC|VC]], [[GTA SA|SA]], [[GTA LCS|LCS]] and [[GTA VCS|VCS]].<br/>
 
{{This|This section deals with the native SCM syntax of GTA 3 series, nothing other than [[GTA 3|III]], [[GTA VC|VC]], [[GTA SA|SA]], [[GTA LCS|LCS]] and [[GTA VCS|VCS]].<br/>
 
It may contain non-standard SCM definitions as R* hasn't published enough documentation about it yet.}}
 
It may contain non-standard SCM definitions as R* hasn't published enough documentation about it yet.}}
{{TocRight}}On the occasion of the GTAIII's tenth anniversary, after a long period of darkness where we fell about the real ''SCM'' syntax, 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 abbreviation is one of countless proofs of this inconvenience, which may stand for ''Script Multifile''. Other doubts come with source files, whose ''SC'' extension appears to be very close to ''Mission SCript''. 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. Nevertheless, the '''SCR language''' name is cropping up gradually. However, it is definitely based on [[Wikipedia:BASIC|BASIC]].
+
{{TocRight}}On the occasion of the ''GTAIII's Tenth Anniversary'', after a long period of darkness where we fell about the real ''SCM'' syntax, 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 abbreviation is one of countless proofs of this inconvenience, which may stand for ''Script Multifile''. Other doubts come with source files, whose ''SC'' extension appears to be very close to ''Mission SCript''. Although we have enough information to suppose the currently unknown mysteries of the used language, we still have no safe clue about which was its original denomination. Furthermore, it is a matter of fact that R* developers have been left untouched the ''miss2'' executable name of the ''GTA 3 series'' compiler since the chapter 2. In this connection, we could imagine the new language is a variant or an evolution of the '''GTA2script'''. The ancient documentation by ''DMA'' (at present ''Rockstar North''), mentions GTA2script as a successor to GBHscript - a language used in [[GTA 1]] (''GBH'' was a planned name for GTA). Therefore, the language used in GTA 3 series should've been called '''GTA3script'''. It was influenced by both [[Wikipedia:BASIC|BASIC]] and [[Wikipedia:C_(programming_language)|C]] programming languages.
  
  
Line 8: Line 9:
 
This article makes use of formatted codes to improve the reading comprehension. Note that:
 
This article makes use of formatted codes to improve the reading comprehension. Note that:
  
* ''Square brackets'' mean everything inside may be omitted.
+
* ''Square brackets'' mean everything inside may be omitted;
* ''Curly brackets'' denote the presence of useful codes but not necessarily needed.
+
* ''Curly brackets'' denote the presence of useful codes but not necessarily needed;
* ''Vertical bars'' divide what can be chosen alternatively.<br/><br/>
+
* ''Vertical bars'' divide what can be chosen alternatively.<br/>
 +
 
 
=Fundamentals=
 
=Fundamentals=
  
 
==Comments==
 
==Comments==
 +
''Comments'' are notes left in the code to aid readability or to explain a part of code that may be confusing otherwise. Comments are ignored by the compiler. R*'s compiler supports C++ style comments – single-line comments and multiline 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.
+
A single line comment only affects a single line. They are prefixed with <code>//</code> (two slashes). Anything between these slashes and the end of the line is a comment. Single line comments may appear at the end of a line of code as well as on their own line.
 
 
===Inline===
 
  
An ''inline comment'', denoted by '''//''' (two slashes), makes everything that follows some plain text:
+
<syntaxhighlight>
 +
[...] // This comment is at the end of a line.
  
[...] // Some inline comment
+
// This comment is on its own line.
 +
</syntaxhighlight>
  
===Multiline===
+
Multiline comments appear between <code>/*</code> and <code>*/</code>. They do not actually have to span multiple lines, and anything outside of the opening and closing tokens is '''not''' ignored (i.e. these comments may appear with code on either side on the same line).
  
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):
+
<syntaxhighlight>
 +
[...]
 +
/*
 +
  This comment spans
 +
  multiple lines.
 +
*/
 +
[...]
  
[...]
+
[...] /* This comment is within a line */ [...] /* As is this one */ [...]
/*
+
</syntaxhighlight>
  * Some multiline comment
 
  * ...
 
  */
 
[...]
 
Currently, more than one multiline comment is allowed per line:
 
  
[...] /* Some inline comment */ [...] /* Some inline comment */ [...]
+
R*'s compiler allows multiline comments to be nested.
  
 
==Highlighters==
 
==Highlighters==
  
''Highlighters'' behaviour sounds trivial, that's to say they simply highlight one or more [[#Arguments|arguments]] per [[#Commands|command]] within ''round brackets'', individually or together. However, a ''comma'' can be used aswell to distinguish each argument. In {{icon|3}}, they appear to be used only for '''SETUP_ZONE_PED_INFO''' (in a various order) and ''GXT keys'':
+
''Highlighters'' behaviour sounds trivial, that's to say they simply highlight one or more arguments per [[#Commands|command]] within ''round brackets'', individually or together. In {{icon|3}}, 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
 
  SETUP_ZONE_PED_INFO FISHFAC DAY (0) 0 0 0 (0 0 0 0) 0
 
  PRINT_BIG (T4X4_1) 5000 2
 
  PRINT_BIG (T4X4_1) 5000 2
 +
 +
;Limits
 +
:Opening and closing round brakets are treated as blank spaces;
 +
:An optional ''comma'' can be used as well to distinguish each argument, processed as a space.
  
 
==Scopes==
 
==Scopes==
  
''Scopes'' are delimited by ''curly brackets'' (or ''multiline brackets'') which act like a [[#Local|local]] [[#Variables|variable]] [[#Scope|scopes]]. Essentially, they enclose the code where local variables are used, including [[#Timers|timers]]. They can be opened and closed many times in a [[#Structure|script]]:
+
''Scopes'' are delimited by ''curly brackets'' (or ''multiline brackets'') which act like a [[#Local|local]] [[#Variables|variable]] [[#Scope|scope]]. Essentially, they enclose the code where local variables are used, including [[#Timers|timers]]. They can be opened and closed many times in a [[#Structure|script]]:
  
 
  {
 
  {
Line 52: Line 60:
 
  }
 
  }
  
;Limit
+
;Limits
:Scopes cannot be nested.
+
:Scopes cannot be nested;
 +
:Opening and closing curly brakets are real commands.
  
 
==Labels==
 
==Labels==
  
A ''label'' is a ''sequence of characters'' which identifiy a location of the source code useful for ''jumps''. It can be accessed by any part of the source code. To define a label just append ''':''' (colon) to its name:
+
A ''label'' is a ''sequence of characters'' which identify the reference of a location of the source code useful for ''gotoes''. It can be accessed by any part of the source code. To define a label just append ''':''' (colon) to its name:
  
 
  [...]
 
  [...]
Line 67: Line 76:
  
 
==Variables==
 
==Variables==
 +
A ''variable'' is a memory address that is given a name. Variables are used to reference values that are stored in the game's memory and that can change (hence the name "variable"). Instructions may read the variable's memory or write to it. They act in the same way as [[wikipedia:Pointer (computer programming)|pointers]] in other programming languages.
  
A ''variable'' is a ''storage location'' assigned to a ''symbolic name'' which contains a ''value'' of any ''type''.
+
There are several words related to variables that are important to know:
 
+
* The ''value'' of the variable is the data that lies at the variable's memory address.
===Value===
+
* The ''type'' is what kind of value the variable stores.
 
+
* The ''scope'' is the region of code in which the variable may be used (and in which it is declared). There are two types:
A ''value'' represents ''any data of any type'' it is.
+
** The ''global'' scope is shared between all game [[#Structure|scripts]]. Global variables have the same value everywhere. They are declared with the <code>VAR</code> prefix.
 +
** The ''local'' scope is a region of code within a script. Locals are only visible to other code inside the same pair of curly braces. They are declared with the <code>LVAR</code> prefix.
 +
* A ''timer'' is a unique local variable whose value rises automatically. They start counting when the script starts executing, and continue counting indefinitely. There are two such timers, <code>TIMERA</code> and <code>TIMERB</code> which are always defined, so do not need to be declared.
  
===Scope===
+
===Data types===
 
----
 
----
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.
+
Among the available data types, some are equivalent to those of the most known programming languages. Their length is up to 4, 8 and 16 bytes. Each type is appended as a suffix in the ''variable declaration''.
  
====Global====
+
''For an in-depth description of different data types, see [https://gtamods.com/wiki/SCM_Instruction#Concrete_data_types the SCM instruction page]''.
  
The ''global scope'' grasps the ''whole source code''. Variables defined as ''globals'' are visible in ''any [[#Structure|script]]''. They are declared by appending the '''VAR''' prefix.
+
====LABEL====
  
====Local====
+
The '''LABEL''' type handles ''variable-length strings''. It can refer to either a ''[[#Labels|label]] name'' or a ''file name''.
----
 
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''. You can put them everywhere and as many times as you want in the source code. They are declared by appending the '''LVAR''' prefix.
 
  
=====Timers=====
+
;Notes
 +
:While inside a script file, R* compiler treats it unambiguously as a label;
 +
:R* compiler allocates 32 bytes per label.
  
A ''timer'' is a ''special local variable'' whose value rises automatically. It starts incrementing since the beginning of the script where it has been placed and grows endlessly. There are ''2 usable timers'' which are already defined as '''TIMERA''' and '''TIMERB''', therefore they do not need to be declared.
+
;Limit
 
+
:'''LABEL''' variables aren't available.
===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====
 
====INT====
Line 100: Line 109:
 
====FLOAT====
 
====FLOAT====
  
The '''FLOAT''' type handles ''32-bit floating-points''. As it normally does, decimal precision of a [[Wikipedia:Floating_point|float]] is usually stuck to 6 digits beyond which it may get lost.
+
The '''FLOAT''' type handles ''32-bit floating-points''. As it normally does, decimal precision of a [[Wikipedia:Floating_point|float]] is usually stuck to 6-7 digits beyond which it may get lost.
 +
 
 +
;Notes
 +
:R* compiler also accepts ''f'' and ''F'' suffixes for the immediate value.
  
 
====TEXT_LABEL====
 
====TEXT_LABEL====
  
The '''TEXT_LABEL''' type handles ''8-byte strings''. Generally, a [[Wikipedia:String_(computer_science)|string]] is an ''array of 1-byte characters''. It requires ''7 characters plus the [[Wikipedia:Null_character|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'') ''script names'' or any short string.
+
The '''TEXT_LABEL''' type handles ''8-byte strings''. Generally, a [[Wikipedia:String_(computer_science)|string]] is an ''array of 1-byte characters''. It requires ''7 characters plus the [[Wikipedia:Null_character|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'') ''script names'' or any short string. Literal only '''TEXT_LABEL*''' strings are probably marked by ''single quotation marks'' to distinguish them from variable and constant identifiers:
 +
 
 +
PRINT_BIG 'GXT_KEY'
  
 
;Limit
 
;Limit
 
:'''TEXT_LABEL''' variables are supported in {{icon|sa}} and {{icon|vcs}}.
 
:'''TEXT_LABEL''' variables are supported in {{icon|sa}} and {{icon|vcs}}.
  
====STRING====
+
====TEXT_LABEL16====
  
The '''STRING''' type handles ''16-byte strings''. Like the previous, this type holds ''15 characters plus the null-terminator''. It is used to store ''model and texture names of player clothes'', ''animation names'' or any long string. It may be a ghost type as later R* compilers might choose between the two string types automatically according to the length of the string itself.
+
The '''TEXT_LABEL16''' type handles ''16-byte strings''. Like the previous, this type holds ''15 characters plus the null-terminator''. It is used to store ''model and texture names of player clothes'', ''animation names'' or any long string.
  
 
;Limit
 
;Limit
:'''STRING''' variables and values are supported in {{icon|sa}}.
+
:'''TEXT_LABEL16''' variables and values are supported only in {{icon|sa}}.
  
====OFFSET====
+
====TEXT_LABEL32====
  
The '''OFFSET''' type handles ''16-byte strings''. They can refer to either a ''[[#Labels|label]] name'' or a ''file name''.
+
The '''TEXT_LABEL32''' type handles ''32-byte strings'' or larger, depending on how many continuous parameters of the same type there are, each of which occupies 32 bytes. It can hold up to ''127 characters plus the null-terminator'', after which another '''TEXT_LABEL32''' argument may begin. Strings of such type must be put within ''double quotation marks'':
  
;Limit
+
SAVE_STRING_TO_DEBUG_FILE "32B-128B TEXT"
:'''OFFSET''' variables aren't available.
 
  
====NUMBER (pseudo)====
+
;Limits
 +
:'''TEXT_LABEL32''' values are supported since {{icon|vc}};
 +
:'''TEXT_LABEL32''' variables aren't available.
  
The '''NUMBER''' type handles ''32-bit signed integers'' or ''32-bit floating-points''. It is used only to assign and compare ''numbers'' to '''INT''' or '''FLOAT''' variables. It is a pseudo type of '''INT''' or '''FLOAT'''.
+
====TEXT====
  
====CONSTANT (pseudo)====
+
The '''TEXT''' type handles ''N-byte strings''. It holds ''N characters plus the null-terminator''. Strings of this type mustn't exceed 255 characters (including the null-byte).
  
The '''CONSTANT''' type handles ''32-bit signed integers''. It is used only to assign and compare [[#Constants|constants]] to '''INT''' variables regarding ''model [[#Identifiers|identifiers]]'', ''task statuses'', ''ped events'' and such. It is a pseudo type of '''INT'''.
+
;Limits
 +
:'''TEXT''' values are supported since {{icon|sa}};
 +
:'''TEXT''' variables aren't available.
  
;Limit
+
====CONST (pseudo)====
:The [[#Arithmetic|assignment]] and [[#Comparison|comparison]] of '''CONSTANT''' values are supported since {{icon|vc}}.
 
  
====BUFFER====
+
The '''CONST''' type handles ''32-bit signed integers''. It is used only to assign and compare [[#Constants|constants]] to '''INT''' variables regarding ''model [[#Identifiers|identifiers]]'', ''task statuses'', ''ped or audio events'' and such. It is a pseudo type of '''INT'''.
  
The '''BUFFER''' type handles ''128-byte strings''. It holds ''127 characters plus the null-terminator''. Strings of such type must be put in ''quotation marks'':
+
;Limit
 
+
:The [[#Arithmetic|assignment]] and [[#Comparison|comparison]] of '''CONST''' values are supported since {{icon|vc}}.
SAVE_STRING_TO_DEBUG_FILE "128B TEXT"
 
  
;Limits
+
====MULTI (pseudo)====
:'''BUFFER''' values are supported since {{icon|sa}}.
 
:'''BUFFER''' variables aren't available.
 
  
====VARLEN====
+
The '''MULTI''' type handles a group of few data types acceptable per argument. It is used only for commands featuring optional arguments, those whose type is unpredictable before the compilation. It can be a pseudo type of '''INT''', '''FLOAT''' and '''TEXT_LABEL'''.
  
The '''VARLEN''' type handles ''N-byte strings''. It holds ''N characters plus the null-terminator''. Strings of this type mustn't exceed 255 characters.
+
;Notes
 +
:'''INT''' and '''FLOAT''' can be used interchangeably in {{icon|3}}, {{icon|vc}}, {{icon|sa}}, {{icon|lcs}} and {{icon|vcs}};
 +
:{{icon|vcs}} also admits '''TEXT_LABEL''' arguments.
  
;Limits
+
===Declaration===
:'''VARLEN''' values are supported since {{icon|sa}}.
 
:'''VARLEN''' variables aren't available.
 
 
 
===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:
 
''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}]
+
  VAR_* {varname0}[,] [... {varnameN}]
 +
LVAR_* {varname0}[,] [... {varnameN}]
  
 
As mentioned in the sections above, local variables have to be put within curly brackets:
 
As mentioned in the sections above, local variables have to be put within curly brackets:
  
 
  {
 
  {
     {varscope}_{vartype} {varname0}[,] [... {varnameN}]
+
     VAR_* {varname0}[,] [... {varnameN}]
 +
    LVAR_* {varname0}[,] [... {varnameN}]
 
   
 
   
 
     [...]
 
     [...]
Line 168: Line 181:
 
''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.
  
;Limit
+
;Limits
:Whereas the ''variable buffer'' is limited, you can declare a certain amount of globals and locals. [[#INT|INT]] and [[#FLOAT|FLOAT]]) types take 1 variable, while [[#TEXT_LABEL|TEXT_LABEL]] and [[#STRING|STRING]] types occupy respectively 2 and 4 variables to store their data (have a look [[#Variables_2|here]] for further details).
+
:Whereas the ''variable buffer'' is limited, you can declare a certain amount of globals and locals. [[#INT|INT]] and [[#FLOAT|FLOAT]] types take 1 variable, while [[#TEXT_LABEL|TEXT_LABEL]] and [[#TEXT_LABEL16|TEXT_LABEL16]] types occupy respectively 2 and 4 variables to store their data (have a look [[#Variables range|here]] for further details);
 +
:{{icon|vcs}} isn't affected by what said above;
 +
:Global and local variable names must not collide.
  
 
====Arrays====
 
====Arrays====
  
A ''array'' is a ''collection of variables'' having the same type which can be accessed by an ''index'', a 1-based integer lesser than or equal to the size specified, enclosed by ''square brackets'':
+
A ''array'' is a ''collection of variables'' having the same type which can be accessed by an ''index'', an '''INT''' lesser than or equal to the size specified, enclosed by ''square brackets'':
  
 
  {
 
  {
     {varscope}_{vartype} {varname0}{[arrsize0]}[,] [... {varnameN}{[arrsizeN]}]
+
     VAR_* {varname0}{[arrsize0]}[,] [... {varnameN}{[arrsizeN]}]
 +
    LVAR_* {varname0}{[arrsize0]}[,] [... {varnameN}{[arrsizeN]}]
 
   
 
   
 
     [...]
 
     [...]
Line 182: Line 198:
  
 
;Limits
 
;Limits
:The usage of arrays is allowed since {{icon|vc}}.
+
:The usage of arrays is allowed since {{icon|vc}};
:Variable indices are quite buggy in {{icon|vc}} and therefore unrecommended, but they are fully supported since {{icon|sa}}.
+
:Variable indices are quite buggy in {{icon|vc}} and therefore unrecommended, but they are fully supported since {{icon|sa}};
 +
:The aforesaid indices are one-based, possibly zero-based since {{icon|sa}};
 +
:Multidimensional arrays are not supported.
  
 
====Handles====
 
====Handles====
  
 
A ''handle'' is an univocal identifier assigned to a game entity. It is given by the following statement:
 
A ''handle'' is an univocal identifier assigned to a game entity. It is given by the following statement:
 +
 
<source lang=cpp>short nHandle = (iEntityIndexInPool << 8) | ucEntityFlag;</source>
 
<source lang=cpp>short nHandle = (iEntityIndexInPool << 8) | ucEntityFlag;</source>
R* compiler won't let you assign different entity types to the same variable or using a variable which hasn't been assigned to any '''CREATE_*''' or '''ADD_*''' entity [[#Commands|commands]].
+
 
 +
;Note
 +
:R* compiler won't let you assign different entity types to the same variable or using a variable which hasn't been passed to any [[#Commands|command]] designated to the creation of an entity.
  
 
==Operators==
 
==Operators==
Line 197: Line 218:
 
===Arithmetic===
 
===Arithmetic===
  
''Arithmetic operators'' compute some of the most common algebric calculations between either a [[#Variables|variable]] and a [[#Value|value]] or two variables. As well as in some programming language happens, [[#CONSTANT|CONSTANT]], [[#TEXT_LABEL|TEXT_LABEL]] and [[#STRING|STRING]] types are free from these operators, except for the ''basic assigment''  (see also [[#Operators composition|Operators composition]]):
+
''Arithmetic operators'' compute some of the most common algebric calculations between either a [[#Variables|variable]] and a [[#Value|value]] or two variables. As well as in some programming language happens, [[#CONST (pseudo)|CONST]], [[#TEXT_LABEL|TEXT_LABEL]] and [[#TEXT_LABEL16|TEXT_LABEL16]] types are free from these operators, except for the ''basic assignment''  (see also [[#Operators composition|Operators composition]]):
  
 
{|class=wikitable
 
{|class=wikitable
 
!width=70px|Operator
 
!width=70px|Operator
!width=200px colspan=2|Name
+
!width=225px colspan=2|Name
!width=200px|Syntax
+
!width=225px|Syntax
!width=500px|Description
+
!width=550px|Description
 
|-
 
|-
!<code>=</code>
+
!=
 
|align=center colspan=2|Assignment
 
|align=center colspan=2|Assignment
 
|align=center|<code>expr0 '''=''' expr1</code>
 
|align=center|<code>expr0 '''=''' expr1</code>
 
|Store ''expr1'' to ''expr0''
 
|Store ''expr1'' to ''expr0''
 
|-
 
|-
!<code>+</code>
+
!+
 
|align=center colspan=2|Addition
 
|align=center colspan=2|Addition
 
|align=center|<code>expr0 '''+''' expr1</code>
 
|align=center|<code>expr0 '''+''' expr1</code>
 
|Add ''expr1'' to ''expr0''
 
|Add ''expr1'' to ''expr0''
 
|-
 
|-
!<code>-</code>
+
!-
 
|align=center colspan=2|Subtraction
 
|align=center colspan=2|Subtraction
 
|align=center|<code>expr0 '''-''' expr1</code>
 
|align=center|<code>expr0 '''-''' expr1</code>
 
|Subtract ''expr1'' from ''expr0''
 
|Subtract ''expr1'' from ''expr0''
 
|-
 
|-
!<code>*</code>
+
!*
 
|align=center colspan=2|Multiplication
 
|align=center colspan=2|Multiplication
 
|align=center|<code>expr0 '''*''' expr1</code>
 
|align=center|<code>expr0 '''*''' expr1</code>
 
|Multiply ''expr0'' by ''expr1''
 
|Multiply ''expr0'' by ''expr1''
 
|-
 
|-
!<code>/</code>
+
!/
 
|align=center colspan=2|Division
 
|align=center colspan=2|Division
 
|align=center|<code>expr0 '''/''' expr1</code>
 
|align=center|<code>expr0 '''/''' expr1</code>
 
|Divide ''expr0'' by ''expr1''
 
|Divide ''expr0'' by ''expr1''
 
|-
 
|-
!<code>+@</code>
+
!+@
 
|align=center colspan=2|Timed addition
 
|align=center colspan=2|Timed addition
 
|align=center|<code>expr0 '''+@''' expr1</code>
 
|align=center|<code>expr0 '''+@''' expr1</code>
 
|Multiply ''expr2'' by delta time and add the result to ''expr1''
 
|Multiply ''expr2'' by delta time and add the result to ''expr1''
 
|-
 
|-
!<code>-@</code>
+
!-@
 
|align=center colspan=2|Timed subtraction
 
|align=center colspan=2|Timed subtraction
 
|align=center|<code>expr0 '''-@''' expr1</code>
 
|align=center|<code>expr0 '''-@''' expr1</code>
 
|Multiply ''expr2'' by delta time and subtract the result from ''expr1''
 
|Multiply ''expr2'' by delta time and subtract the result from ''expr1''
 
|-
 
|-
!rowspan=2|<code>++</code>
+
!rowspan=2|++
 
|align=center rowspan=2|Increment
 
|align=center rowspan=2|Increment
 
|align=center|Pre{{ref|preinc|[*]}}
 
|align=center|Pre{{ref|preinc|[*]}}
Line 249: Line 270:
 
|align=center|<code>expr0 '''++'''</code>
 
|align=center|<code>expr0 '''++'''</code>
 
|-
 
|-
!rowspan=2|<code>--</code>
+
!rowspan=2|--
 
|align=center rowspan=2|Decrement
 
|align=center rowspan=2|Decrement
 
|align=center|Pre{{ref|preinc|[*]}}
 
|align=center|Pre{{ref|preinc|[*]}}
Line 266: Line 287:
 
{|class=wikitable
 
{|class=wikitable
 
!width=70px|Operators
 
!width=70px|Operators
!width=200px|Name
+
!width=225px|Name
!width=200px|Syntax
+
!width=225px|Syntax
!width=500px|Description
+
!width=550px|Description
 
|-
 
|-
!<code>= +</code>
+
!= +
 
|align=center|Addition and assignment
 
|align=center|Addition and assignment
 
|align=center|<code>expr0 '''=''' expr1{{ref|expr01|[*]}} '''+''' expr2</code>
 
|align=center|<code>expr0 '''=''' expr1{{ref|expr01|[*]}} '''+''' expr2</code>
 
|Add ''expr2'' to ''expr1'' and store the result to ''expr0''
 
|Add ''expr2'' to ''expr1'' and store the result to ''expr0''
 
|-
 
|-
!<code>= -</code>
+
!= -
 
|align=center|Subtraction and assignment
 
|align=center|Subtraction and assignment
 
|align=center|<code>expr0 '''=''' expr1{{ref|expr01|[*]}} '''-''' expr2</code>
 
|align=center|<code>expr0 '''=''' expr1{{ref|expr01|[*]}} '''-''' expr2</code>
 
|Subtract ''expr2'' from ''expr1'' and store the result to ''expr0''
 
|Subtract ''expr2'' from ''expr1'' and store the result to ''expr0''
 
|-
 
|-
!<code>= *</code>
+
!= *
 
|align=center|Multiplication and assignment
 
|align=center|Multiplication and assignment
 
|align=center|<code>expr0 '''=''' expr1{{ref|expr01|[*]}} '''*''' expr2</code>
 
|align=center|<code>expr0 '''=''' expr1{{ref|expr01|[*]}} '''*''' expr2</code>
 
|Multiply ''expr1'' by ''expr2'' and store the result to ''expr0''
 
|Multiply ''expr1'' by ''expr2'' and store the result to ''expr0''
 
|-
 
|-
!<code>= /</code>
+
!= /
 
|align=center|Division and assignment
 
|align=center|Division and assignment
 
|align=center|<code>expr0 '''=''' expr1{{ref|expr01|[*]}} '''/''' expr2</code>
 
|align=center|<code>expr0 '''=''' expr1{{ref|expr01|[*]}} '''/''' expr2</code>
 
|Divide ''expr1'' by ''expr2'' and store the result to ''expr0''
 
|Divide ''expr1'' by ''expr2'' and store the result to ''expr0''
 
|-
 
|-
!<code>= +@</code>
+
!= +@
 
|align=center|Timed addition and assignment
 
|align=center|Timed addition and assignment
 
|align=center|<code>expr0 '''=''' expr1{{ref|expr01|[*]}} '''+@''' expr2</code>
 
|align=center|<code>expr0 '''=''' expr1{{ref|expr01|[*]}} '''+@''' expr2</code>
 
|Multiply ''expr2'' by delta time, add the result to ''expr1'' and store everything to ''expr0''
 
|Multiply ''expr2'' by delta time, add the result to ''expr1'' and store everything to ''expr0''
 
|-
 
|-
!<code>= -@</code>
+
!= -@
 
|align=center|Timed subtraction and assignment
 
|align=center|Timed subtraction and assignment
 
|align=center|<code>expr0 '''=''' expr1{{ref|expr01|[*]}} '''-@''' expr2</code>
 
|align=center|<code>expr0 '''=''' expr1{{ref|expr01|[*]}} '''-@''' expr2</code>
Line 313: Line 334:
 
{|class=wikitable
 
{|class=wikitable
 
!width=70px|Operator
 
!width=70px|Operator
!width=200px|Name
+
!width=225px|Name
!width=200px|Syntax
+
!width=225px|Syntax
!width=500px|Description
+
!width=550px|Description
 
|-
 
|-
!<code>+=</code>
+
!+=
 
|align=center|Addition assignment
 
|align=center|Addition assignment
 
|align=center|<code>expr0 '''+=''' expr1</code>
 
|align=center|<code>expr0 '''+=''' expr1</code>
 
|Add ''expr1'' to ''expr0'' and store the result to ''expr0''
 
|Add ''expr1'' to ''expr0'' and store the result to ''expr0''
 
|-
 
|-
!<code>-=</code>
+
!-=
 
|align=center|Subtraction assignment
 
|align=center|Subtraction assignment
 
|align=center|<code>expr0 '''-=''' expr1</code>
 
|align=center|<code>expr0 '''-=''' expr1</code>
 
|Subtract ''expr1'' from ''expr0'' and store the result to ''expr0''
 
|Subtract ''expr1'' from ''expr0'' and store the result to ''expr0''
 
|-
 
|-
!<code>*=</code>
+
!*=
 
|align=center|Multiplication assignment
 
|align=center|Multiplication assignment
 
|align=center|<code>expr0 '''*=''' expr1</code>
 
|align=center|<code>expr0 '''*=''' expr1</code>
 
|Multiply ''expr0'' by ''expr1'' and store the result to ''expr0''
 
|Multiply ''expr0'' by ''expr1'' and store the result to ''expr0''
 
|-
 
|-
!<code>/=</code>
+
!/=
 
|align=center|Division assignment
 
|align=center|Division assignment
 
|align=center|<code>expr0 '''/=''' expr1</code>
 
|align=center|<code>expr0 '''/=''' expr1</code>
 
|Divide ''expr0'' by ''expr1'' and store the result to ''expr0''
 
|Divide ''expr0'' by ''expr1'' and store the result to ''expr0''
 
|-
 
|-
!<code>+=@</code>
+
!+=@
 
|align=center|Timed addition assignment
 
|align=center|Timed addition assignment
 
|align=center|<code>expr0 '''+=@''' expr1</code>
 
|align=center|<code>expr0 '''+=@''' expr1</code>
 
|Multiply ''expr1'' by delta time, add the result to ''expr0'' and store everything to ''expr0''
 
|Multiply ''expr1'' by delta time, add the result to ''expr0'' and store everything to ''expr0''
 
|-
 
|-
!<code>-=@</code>
+
!-=@
 
|align=center|Timed subtraction assignment
 
|align=center|Timed subtraction assignment
 
|align=center|<code>expr0 '''-=@''' expr1</code>
 
|align=center|<code>expr0 '''-=@''' expr1</code>
Line 354: Line 375:
 
{|class=wikitable
 
{|class=wikitable
 
!width=70px|Operator
 
!width=70px|Operator
!width=200px|Name
+
!width=225px|Name
!width=200px|Syntax
+
!width=225px|Syntax
!width=500px|Description
+
!width=550px|Description
 
|-
 
|-
!<code>=#</code>
+
!=#
|align=center|Conversion assignment
+
|align=center|Cast assignment
 
|align=center|<code>expr0 '''=#''' expr1</code>
 
|align=center|<code>expr0 '''=#''' expr1</code>
|Convert ''expr1'' to any other type and store the result to ''expr0''
+
|Cast ''expr1'' to any other type and store the result to ''expr0''
 
|}
 
|}
  
Line 372: Line 393:
  
 
{|class=wikitable
 
{|class=wikitable
!width=70px|Operators
+
!width=70px|Operator
!width=200px|Name
+
!width=225px|Name
!width=200px|Syntax
+
!width=225px|Syntax
!width=500px|Description
+
!width=550px|Description
 
|-
 
|-
!<code>NOT</code>
+
!NOT
 
|align=center|Logical negation
 
|align=center|Logical negation
 
|align=center|<code>IF '''NOT''' condition0</code>
 
|align=center|<code>IF '''NOT''' condition0</code>
 
|Test if ''condition0'' is false
 
|Test if ''condition0'' is false
 
|-
 
|-
!<code>AND</code>
+
!AND
 
|align=center|Logical conjunction
 
|align=center|Logical conjunction
 
|align=center|<code>IF condition0<br/>'''AND''' condition8</code>
 
|align=center|<code>IF condition0<br/>'''AND''' condition8</code>
 
|Test if both ''condition0'' and ''conditionN'' are true
 
|Test if both ''condition0'' and ''conditionN'' are true
 
|-
 
|-
!<code>OR</code>
+
!OR
 
|align=center|Logical disjunction
 
|align=center|Logical disjunction
 
|align=center|<code>IF condition0<br/>'''OR''' condition8</code>
 
|align=center|<code>IF condition0<br/>'''OR''' condition8</code>
Line 399: Line 420:
 
{|class=wikitable
 
{|class=wikitable
 
!width=70px|Operator
 
!width=70px|Operator
!width=200px|Name
+
!width=225px|Name
!width=200px|Syntax
+
!width=225px|Syntax
!width=500px|Description
+
!width=550px|Description
 
|-
 
|-
!<code>=</code>
+
!=
 
|align=center|Equal to
 
|align=center|Equal to
 
|align=center|<code>IF expr0 '''=''' expr1</code>
 
|align=center|<code>IF expr0 '''=''' expr1</code>
 
|Test if ''expr0'' and ''expr1'' are equal
 
|Test if ''expr0'' and ''expr1'' are equal
 
|-
 
|-
!<code>></code>
+
!>
 
|align=center|Greater than
 
|align=center|Greater than
 
|align=center|<code>IF expr0 '''>''' expr1</code>
 
|align=center|<code>IF expr0 '''>''' expr1</code>
 
|Test if ''expr0'' is greater than ''expr1''
 
|Test if ''expr0'' is greater than ''expr1''
 
|-
 
|-
!<code><</code>
+
!<{{ref|inverr|[*]}}
 
|align=center|Lesser than
 
|align=center|Lesser than
 
|align=center|<code>IF expr0 '''<''' expr1</code>
 
|align=center|<code>IF expr0 '''<''' expr1</code>
 
|Test if ''expr0'' is lesser than ''expr1''
 
|Test if ''expr0'' is lesser than ''expr1''
 
|-
 
|-
!<code>>=</code>
+
!>=
 
|align=center|Greater than or equal to
 
|align=center|Greater than or equal to
 
|align=center|<code>IF expr0 '''>=''' expr1</code>
 
|align=center|<code>IF expr0 '''>=''' expr1</code>
 
|Test if ''expr0'' is greater than or equal to ''expr1''
 
|Test if ''expr0'' is greater than or equal to ''expr1''
 
|-
 
|-
!<code><=</code>
+
!<={{ref|inverr|[*]}}
 
|align=center|Lesser than or equal to
 
|align=center|Lesser than or equal to
 
|align=center|<code>IF expr0 '''<=''' expr1</code>
 
|align=center|<code>IF expr0 '''<=''' expr1</code>
Line 429: Line 450:
 
|}
 
|}
  
Theorically, [[#STRING|STRING]] values should be compared with the first operator only, but the presence of '''COMPARE_STRING''' increase the doubts concerning the existence of such operator for this type.
+
;Note
 +
:{{note|inverr}} As a result of a critical bug, R* compiler mistakenly applies the operator inversion.
  
 
==Commands==
 
==Commands==
  
A ''command'' is a ''symbolic name'' associated to an [[#Opcodes|opcode]] which executes a ''portion of code'' that specifies the operation to be performed by passing ''zero or more [[#Arguments|arguments]]''. Opcodes do not return [[#Value|values]] that can be assigned to a [[#Variables|variable]], even though the boolean flag is kept whenever they are used as ''conditions''. It follows the common programming syntax adopted for ''procedure or function calls'':
+
A ''command'' is a ''symbolic name'' associated to an [[#Command ID|identifier]] which executes a ''portion of code'' that specifies the operation to be performed by passing ''zero or more arguments''. An ''argument'' is in turn some data given as input to a command. Normally, commands have a defined amount of arguments and those not, such as '''START_NEW_SCRIPT''', can pass as many arguments as the available [[#Local|local]] [[#Variables|variables]] are, except [[#Timers|timers]]. Being a procedure, a command does not return [[#Value|values]] that can be assigned to a variable, even though the boolean flag is kept whenever it is used as a ''condition''. It follows the common programming syntax adopted for ''function calls'':
  
 
  {commandname} [{anyvalue0|varname0} ... {anyvalueN|varnameN}]
 
  {commandname} [{anyvalue0|varname0} ... {anyvalueN|varnameN}]
  
===Built-in===
+
===Alternators===
 +
An ''alternator'' is an abstract operation that is implemented with a set of commands, each of which takes differently typed arguments.
  
''Built-in commands'' are those which are associated to more [[#Opcodes|opcodes]] that differ each other by [[#Arguments|argument]] types or actions:
+
Alternators are used because there are often multiple different combinations of argument types that one might wish to use for an operation. While <code>1 + 2</code> and <code>1 + 2.0</code> are equivalent to a human, they are not to a computer, so they must be implemented differently.
  
* {{icon|3}} {{icon|vc}} {{icon|sa}} {{icon|lcs}} {{icon|vcs}}:
+
Each command has the same [http://en.wikipedia.org/wiki/Arity arity] as the other commands implementing the same operation. They differ only the in combination and order of their parameters' types.
** '''OPERATORS'''
+
 
 +
<div class="toccolours mw-collapsible mw-collapsed">
 +
Common alternators
 +
<div class="mw-collapsible-content">
 +
* {{icon|t}} {{icon|lcs}} {{icon|vcs}}
 +
** '''SET (=)'''
 +
** '''CSET (=#)'''
 +
** '''ADD_THING_TO_THING (+=)'''
 +
** '''SUB_THING_FROM_THING (-=)'''
 +
** '''MULT_THING_BY_THING (*=)'''
 +
** '''DIV_THING_BY_THING (/=)'''
 +
** '''IS_THING_EQUAL_TO_THING (=)'''
 +
** '''IS_THING_NOT_EQUAL_TO_THING (NOT =)'''
 +
** '''IS_THING_GREATER_THAN_THING (>, <=)'''
 +
** '''IS_THING_GREATER_OR_EQUAL_TO_THING (>=, <)'''
 +
** '''ADD_THING_TO_THING_TIMED (+=@)'''
 +
** '''SUB_THING_FROM_THING_TIMED (-=@)'''
 
** '''ABS'''
 
** '''ABS'''
* {{icon|sa}}:
+
* {{icon|sa}}
** '''IS_TEXT_LABEL_NULL'''
+
** '''IS_EMPTY'''
** '''IS_STRING_NULL'''
 
 
** '''IS_BIT_SET'''
 
** '''IS_BIT_SET'''
 
** '''SET_BIT'''
 
** '''SET_BIT'''
 
** '''CLEAR_BIT'''
 
** '''CLEAR_BIT'''
** '''COMPARE_STRING'''
+
** '''STRING_CAT'''
* {{icon|lcs}} {{icon|vcs}}:
+
</div>
** '''CALL'''
+
</div>
  
 
{{incomplete}}
 
{{incomplete}}
  
===WAIT===
+
===Hardcoded===
  
'''WAIT''' skips the execution of a [[#Structure|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|WHILE]] statement. In this case, a [[#INT|INT]] equal to 0 is passed.
+
''Hardcoded commands'' are those which have unique characteristics and are handled internally:
  
===GOTO===
+
<div class="toccolours mw-collapsible mw-collapsed">
 +
List of hardcoded commands
 +
<div class="mw-collapsible-content">
 +
* {{icon|t}} {{icon|lcs}} {{icon|vcs}}:
 +
** '''GOTO'''
 +
** '''GOTO_IF_FALSE'''
 +
** '''TERMINATE_THIS_SCRIPT'''
 +
** '''START_NEW_SCRIPT'''
 +
** '''VAR_INT'''
 +
** '''VAR_FLOAT'''
 +
** '''LVAR_INT'''
 +
** '''LVAR_FLOAT'''
 +
** '''{'''
 +
** '''}'''
 +
** '''REPEAT'''
 +
** '''ENDREPEAT'''
 +
** '''IF'''
 +
** '''IFNOT'''
 +
** '''ELSE'''
 +
** '''ENDIF'''
 +
** '''WHILE'''
 +
** '''WHILENOT'''
 +
** '''ENDWHILE'''
 +
** '''ANDOR'''
 +
** '''LAUNCH_MISSION'''
 +
** '''SAVE_VAR_INT'''
 +
** '''SAVE_VAR_FLOAT'''
 +
** '''START_CUTSCENE'''{{ref|depcnt|[*]}}
 +
** '''PLAYER_MADE_PROGRESS'''
 +
** '''SET_PROGRESS_TOTAL'''{{ref|thgtot|[*]}}
 +
** '''REGISTER_MISSION_GIVEN'''{{ref|depcnt|[*]}}
 +
** '''REGISTER_MISSION_PASSED'''
 +
** '''SCRIPT_NAME'''
 +
** '''LOAD_AND_LAUNCH_MISSION'''
 +
** '''LOAD_AND_LAUNCH_MISSION_INTERNAL'''
 +
** '''SET_TOTAL_NUMBER_OF_MISSIONS'''{{ref|thgtot|[*]}}
 +
** '''VAR_TEXT_LABEL'''
 +
** '''LVAR_TEXT_LABEL'''
 +
* {{icon|vc}} {{icon|sa}} {{icon|lcs}} {{icon|vcs}}:
 +
** '''REGISTER_ODDJOB_MISSION_PASSED'''
 +
* {{icon|3}} {{icon|lcs}} {{icon|vcs}}:
 +
** '''GOTO_IF_TRUE'''
 +
** '''GOSUB_FILE'''
 +
* {{icon|3}} {{icon|vc}}:
 +
** '''CREATE_COLLECTABLE1'''
 +
** '''SET_COLLECTABLE1_TOTAL'''{{ref|thgtot|[*]}}
 +
* {{icon|vc}} {{icon|sa}}:
 +
** '''LOAD_AND_LAUNCH_MISSION_EXCLUSIVE'''
 +
* {{icon|lcs}} {{icon|vcs}}:
 +
** '''CALL'''
 +
** '''CALLNOT'''
 +
* {{icon|sa}}:
 +
** '''VAR_TEXT_LABEL16'''
 +
** '''LVAR_TEXT_LABEL16'''
 +
** '''SWITCH'''
 +
** '''ENDSWITCH'''
 +
** '''CASE'''
 +
** '''DEFAULT'''
 +
** '''BREAK'''
 +
** '''SWITCH_START'''
 +
** '''SWITCH_CONTINUED'''
 +
* {{icon|vcs}}:
 +
** '''SAVE_VAR_TEXT_LABEL'''{{ref|thgtot|[*]}}
 +
** '''SET_COLLECTABLE2_TOTAL'''
 +
 
 +
;Notes
 +
:{{note|thgtot}} The argument of these commands must be set respectively according to:
 +
:* The sum of '''PLAYER_MADE_PROGRESS''' values;
 +
:* The amount of '''REGISTER_MISSION_PASSED''' (those that don't have an immediate value are excluded) and '''REGISTER_ODDJOB_MISSION_PASSED''';
 +
:* The amount of '''CREATE_COLLECTABLE1'''.
 +
:If the argument of the listed commands differs from what expected, a 0-value must be passed;
 +
:{{note|depcnt}} This command was intended to be counted originally but its counter got deprecated.
 +
 
 +
</div>
 +
</div>
 +
 
 +
{{incomplete}}
 +
 
 +
===WAIT===
 +
 
 +
'''WAIT''' stops the execution of a [[#Structure|script]] according to some milliseconds after which it will resume again. Indeed, it is absolutely necessary into ''infinite loops'' or those that may or may not break after more than one frame, such as the [[#WHILE|WHILE]] control flow. In this case, a [[#INT|INT]] equal to 0 is passed.
  
'''GOTO''' jumps to the [[#Labels|label]] of any location of the source code. It is also used internally to build other [[#Statements|statements]] or singularly but then it mustn't point off the current context:
+
===GOTO===
 +
 
 +
'''GOTO''' jumps to the [[#Labels|label]] of any location of the source code but conceptually it should never point off the current context. It is also used internally to build the [[#Control flows|control flows]] offered by the scripting language:
  
 
  // File: any.sc
 
  // File: any.sc
 
   
 
   
  jump0:
+
  goto_ref0:
  GOTO jumpN
+
  GOTO goto_refN
  
 
  // File: any.sc
 
  // File: any.sc
 
   
 
   
  jumpN:
+
  goto_refN:
  GOTO jump0
+
  GOTO goto_ref0
  
 
===ANDOR===
 
===ANDOR===
  
'''ANDOR''' set out the way the comparison among more conditions have to occur (see also [[#Comparing rule|Comparing rule]]).
+
'''ANDOR''' sets out the way the comparison among more conditions have to occur (see also [[#Compare flag|Compare flag]]).
  
 
===GOTO_IF_TRUE===
 
===GOTO_IF_TRUE===
Line 484: Line 604:
 
===GOTO_IF_FALSE===
 
===GOTO_IF_FALSE===
  
Unlike [[#GOTO_IF_TRUE|GOTO_IF_TRUE]], '''GOTO_IF_FALSE''' jumps to the disired [[#Labels|label]] only if the comparison returns false.
+
Unlike [[#GOTO_IF_TRUE|GOTO_IF_TRUE]], '''GOTO_IF_FALSE''' jumps to the desired [[#Labels|label]] only if the comparison returns false.
 +
 
 +
===SCRIPT_NAME===
 +
 
 +
'''SCRIPT_NAME''' simply associates an unique name to the current working [[#Structure|script]].
 +
 
 +
;Note
 +
:R* compiler doesn't enable you to associate a name previously used for another script.
  
 
===SAVE_STRING_TO_DEBUG_FILE===
 
===SAVE_STRING_TO_DEBUG_FILE===
  
'''SAVE_STRING_TO_DEBUG_FILE''' accepts an [[#Arguments|argument]] which can admit up to ''127 characters plus the null-terminator''. 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:
+
'''SAVE_STRING_TO_DEBUG_FILE''' accepts an argument which can admit up to ''127 characters plus the null-terminator''. In the compiling process, the argument is skipped but its string is copied to a predefined ''128-bytes buffer'', compiled afterwards. Since {{icon|vc}}, these are the seemingly predetermined bytes of a random empty string block which are actually the result of uninitialized data:
  
  00 00 41 00 09 2E 00 00 00 00 00 00 <span style="color: silver">00</span> 00 00 00  
+
  00 00 41 00 09 2E 00 00 00 00 00 00 '''00''' 00 00 00  
  <span style="color: blue">09 2E 00 00</span> 00 00 00 00 1C FB 12 00 D8 A8 41 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 <span style="color: silver">01</span> 00 00 00  
+
  00 00 41 00 09 2E 00 00 00 00 00 00 '''01''' 00 00 00  
  <span style="color: blue">09 2E 00 00</span> 00 00 00 00 1C FB 12 00 D8 A8 41 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 <span style="color: silver">02</span> 00 00 00  
+
  00 00 41 00 09 2E 00 00 00 00 00 00 '''02''' 00 00 00  
  <span style="color: blue">09 2E 00 00</span> 00 00 00 00 1C FB 12 00 D8 A8 41 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 <span style="color: silver">03</span> 00 00 00  
+
  00 00 41 00 09 2E 00 00 00 00 00 00 '''03''' 00 00 00  
  <span style="color: blue">09 2E 00 00</span> 00 00 00 00 1C FB 12 00 D8 A8 41 00
+
  09 2E 00 00 00 00 00 00 1C FB 12 00 D8 A8 41 00
  
Dynamic values within a block are marked in <span style="color: silver">grey</span>, while those which differs among each block are coloured in <span style="color: blue">blue</span>. Possibly rubbish data.
+
The split of such bytes into 4 blocks of 32-bytes each is quite noticeable.
  
 
==Constants==
 
==Constants==
  
A ''constant'' is a ''symbolic name'' associated to a specific [[#Value|value]]. When compiling, their caption is converted in the assigned value. In {{icon|3}} and {{icon|vc}}, they are hardcoded as everything inside the compiler. Since {{icon|vc}}, names and identifiers of objects within [[OBJS]] and [[TOBJ]] blocks are loaded from every ''IDE'' file defined into [[gta.dat|gta_vc.dat]], then those of vehicles and pedestrians within [[PEDS]] and [[CARS]] blocks are retrieved from [[default.ide]]. In {{icon|sa}}, they are listed into ''TXT'' files, whose name follows the [[Wikipedia:CamelCase|Pascal Case]] (eg. ''AudioEvents.txt''). These files respect the syntax below:
+
A ''constant'' is a ''symbolic name'' associated to a specific [[#Value|value]]. When compiling, their caption is converted to the assigned value. Since {{icon|vc}}, names and identifiers of objects within [[OBJS]] and [[TOBJ]] blocks are loaded from every ''IDE'' file defined into [[gta.dat|gta_vc.dat]], then those of vehicles and pedestrians within [[PEDS]] and [[CARS]] blocks are retrieved from [[default.ide]]. In {{icon|sa}}, they are listed into ''TXT'' files, whose name follows the [[Wikipedia:CamelCase|Pascal Case]] (eg. ''AudioEvents.txt''). These files respect the syntax below:
  
 
  {constname0} {constvalue0}
 
  {constname0} {constvalue0}
Line 509: Line 636:
 
  {constnameN} {constvalueN}
 
  {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 also [[#Identifiers|Identifiers]]). Keep in mind [[#Arguments|arguments]] of some [[#Commands|commands]] having the [[#CONSTANT|CONSTANT]] type accept only ''constant values'' of a single ''namespace''.
+
''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 also [[#Identifiers|Identifiers]]). Keep in mind arguments of some [[#Commands|commands]] having the [[#CONST (pseudo)|CONST]] type accept only ''constant values'' of a single ''namespace''.
 +
 
 +
;Notes
 +
:Constants don't collide even though they belong to different namespaces;
 +
:In {{icon|3}} and {{icon|vc}}, they are hardcoded as everything inside R* compiler;
 +
:In {{icon|sa}}, the subdivision of constant namespaces in files might be just a listing of hardcoded constants useful for developers. The same would apply to {{icon|lcs}} and {{icon|vcs}}.
  
 
==Formatting==
 
==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:
+
Everything is ''case-insensitive'', that means the uppercase and lowercase letters have no dissimilarities when taken. Usually, the source code is conform to the same formatting according to:
 
 
{|class=wikitable
 
!
 
!Uppercase
 
!Lowercase
 
|-
 
|[[#Label|Label]]||||align=center|X
 
|-
 
|[[#Declaration|Declaration]]||align=center|X||
 
|-
 
|[[#Variables|Variable]]||||align=center|X
 
|-
 
|[[#Commands|Command]]||align=center|X||
 
|-
 
|[[#Constants|Constant]]||align=center|X||
 
|-
 
|[[#Statements|Statement]]||align=center|X||
 
|}
 
  
 +
* [[#Labels|Labels]] and [[#Variables|variables]] are entirely in lowercase;
 +
* [[#Declaration|Declarations]], [[#Commands|commands]] and [[#Control flows|control flows]] are in uppercase;
 +
* [[#Constants|Constants]] are mostly in uppercase but the lowercase variant can be seen as well.<br/><br/>
 
=Compiling=
 
=Compiling=
  
 
==Structure==
 
==Structure==
  
The source code is split up into several ''SC'' files which comprehend ''main file'', ''foreign gosubs'', ''subscripts'', ''mission scripts'', and ''triggers''.
+
The source code is split up into several ''SC'' files which comprehend ''main file'', ''foreign gosubs'', ''subscripts'', ''mission scripts'', and ''streamed scripts''. These files can be included more times because they are actually processed once.
  
 
===Main file===
 
===Main file===
 
----
 
----
The ''main file'' is the most significant part of the whole source. It can include many script files and/or embedded ''gosubs'', ''scripts'' or ''functions''. Originally, it is characterized by the absence of the [[#Local|local]] [[#Scope|scope]]. It must be put outside the directory, having the same name as the main script file, where all other foreign scripts must be. R* compiler will search into subfolders too:
+
The ''main file'' is the most significant part of the whole source. It can include many script files and/or embedded ''gosubs'', ''scripts'' or ''functions''. Originally, it is characterized by the absence of the [[#Local|local]] [[#Scope|scope]]. It must be put outside the directory, having the same name as the main script file, where all other foreign scripts must be:
  
 
  <directory>
 
  <directory>
Line 558: Line 675:
 
  |  \- mission.sc
 
  |  \- mission.sc
 
  \- main.sc
 
  \- main.sc
 +
 +
;Note
 +
:R* compiler will scan subfolders too.
  
 
===Foreign gosubs===
 
===Foreign gosubs===
 
----
 
----
''Foreign gosubs'' (also called ''subroutines'') are ''main extension files''. They are called using the '''GOSUB_FILE''' [[#Commands|command]] which jumps to a specific [[#Labels|label]] and executes some code that returns back to the place where it has been called with '''RETURN'''. You are able to specify the gosub label to start jumping at aswell:
+
''Foreign gosubs'' (also called ''subroutines'') are ''main extension files''. They are called using the '''GOSUB_FILE''' [[#Commands|command]] which jumps to a specific [[#Labels|label]] and executes some code that returns back to the place where it has been called with '''RETURN'''. You are able to specify the gosub label to start jumping at as well:
  
 
  // File: main.sc
 
  // File: main.sc
 
   
 
   
  GOSUB_FILE gosub0 gosub.sc
+
  GOSUB_FILE gosub_ref foreign_gosub.sc
  
  // File: gosub.sc
+
  // File: foreign_gosub.sc
 
   
 
   
  gosub0:
+
  gosub_ref:
 
  {
 
  {
 
     [...]
 
     [...]
Line 584: Line 704:
 
  // File: any.sc
 
  // File: any.sc
 
   
 
   
  GOSUB gosub0
+
  GOSUB gosub_ref
  
 
  // File: any.sc
 
  // File: any.sc
 
   
 
   
  gosub0:
+
  gosub_ref:
 
  {
 
  {
 
     [...]
 
     [...]
Line 599: Line 719:
 
===Subscripts===
 
===Subscripts===
 
----
 
----
''Subscripts'' are code blocks which take part of a ''queue of other scripts''. They are denoted by the presence of '''MISSION_START''' at the very top of the mission file. As long as they aren't ended with '''MISSION_END''', their execution never expires till the end of the game process. Each one works independently, even though they are able to share [[#Global|global]] [[#Variables|variables]]:
+
''Subscripts'' are code blocks which take part of a ''queue of other scripts'' and are allocated over the memory by '''LAUNCH_MISSION'''. They are denoted by the presence of '''MISSION_START''' at the very top of the mission file. As long as they aren't ended with '''MISSION_END''', their execution never expires till the end of the game process. Each one works independently, even though they are able to share [[#Global|global]] [[#Variables|variables]]:
  
 
  // File: main.sc
 
  // File: main.sc
Line 609: Line 729:
 
  MISSION_START
 
  MISSION_START
 
   
 
   
  [VAR_{vartype} {varname0}[,] [... {varnameN}]]
+
  [VAR_* {varname0}[,] [... {varnameN}]]
 
   
 
   
 
  SCRIPT_NAME main
 
  SCRIPT_NAME main
Line 615: Line 735:
 
  subscript_loop:
 
  subscript_loop:
 
  {
 
  {
     [LVAR_{vartype} {varname0}[,] [... {varnameN}]]
+
     [LVAR_* {varname0}[,] [... {varnameN}]]
 
   
 
   
 
     [...]
 
     [...]
Line 622: Line 742:
 
  MISSION_END
 
  MISSION_END
  
;Note
+
;Notes
:'''MISSION_START''' is a special and fake directive that isn't assigned to any [[#Commands|command]].
+
:'''MISSION_START''' is a special and fake directive that isn't assigned to any [[#Commands|command]]. R* compiler will notify an error if it isn't placed at the first line of a subscript or a [[#Mission scripts|mission script]];
 +
:'''MISSION_END''' is an alias of '''TERMINATE_THIS_SCRIPT'''.
  
 
====Scripts====
 
====Scripts====
  
As for [[#Gosubs|gosubs]], ''scripts'' can be embedded everywhere in a script file. They are started by '''START_NEW_SCRIPT''' which has an undefined amount of [[#Arguments|arguments]], whose type must match with those of each [[#Local|local]] variable of the starting script in order to be passed, else the compilation will interrupt. Unlike subscripts, they get terminated by '''TERMINATE_THIS_SCRIPT''' or '''TERMINATE_ALL_SCRIPTS_WITH_THIS_NAME''' (elsewhere in another script):
+
As for [[#Gosubs|gosubs]], ''scripts'' can be embedded everywhere in a script file. They are started by '''START_NEW_SCRIPT''' which has an undefined amount of arguments, whose type must match with those of each [[#Local|local]] variable of the starting script in order to be passed, else the compilation will interrupt. Unlike subscripts, they get terminated by '''TERMINATE_THIS_SCRIPT''' or '''TERMINATE_ALL_SCRIPTS_WITH_THIS_NAME''' (elsewhere in another script):
  
 
  // File: any.sc
 
  // File: any.sc
Line 641: Line 762:
 
  script_loop:
 
  script_loop:
 
   
 
   
     [LVAR_{vartype} {varname0}[,] [... {varnameN}]]
+
     [LVAR_* {varname0}[,] [... {varnameN}]]
 
   
 
   
 
     [...]
 
     [...]
Line 650: Line 771:
  
 
;Notes
 
;Notes
:Scripts must have a local [[#Scope|scope]].
+
:Scripts must have a local [[#Scope|scope]];
:Script commands must be inserted within or after the local scope.
+
:Script commands must be inserted within or after the local scope;
 
:Since {{icon|vc}}, the ''opening curly bracket'' must be put before the script [[#Labels|label]] when more arguments are passed.
 
:Since {{icon|vc}}, the ''opening curly bracket'' must be put before the script [[#Labels|label]] when more arguments are passed.
  
Line 660: Line 781:
 
===Mission scripts===
 
===Mission scripts===
 
----
 
----
''Mission scripts'' are [[#Subscripts|subscripts]] which take part of the ''mission block'', which is basically a subscript started once. When they are launched with '''LOAD_AND_LAUNCH_MISSION''', the pointer is moved to the corresponding mission [[#Offsets|offset]] located somewhere in the mission block. Do not forget to begin a mission with '''MISSION_START''' and end it with '''MISSION_END''':
+
''Mission scripts'' are those [[#Subscripts|subscripts]] which are responsible for the presence of a storyline in the game. When they are launched with '''LOAD_AND_LAUNCH_MISSION''', the mission is loaded in the mission block, allocated over the memory and the script pointer is moved to the corresponding mission [[#Offsets|offset]]. Do not forget to begin a mission script with '''MISSION_START''' and end it with '''MISSION_END''':
  
 
  // File: main.sc
 
  // File: main.sc
Line 680: Line 801:
 
  MISSION_END
 
  MISSION_END
 
   
 
   
  [VAR_{vartype} {varname0}[,] [... {varnameN}]]
+
  [VAR_* {varname0}[,] [... {varnameN}]]
 
   
 
   
 
  mission_start:
 
  mission_start:
Line 690: Line 811:
 
   
 
   
 
  {
 
  {
     [LVAR_{vartype} {varname0}[,] [... {varnameN}]]
+
     [LVAR_* {varname0}[,] [... {varnameN}]]
 
   
 
   
 
     [...]
 
     [...]
Line 705: Line 826:
 
  [...]
 
  [...]
 
  RETURN
 
  RETURN
 +
 +
// Mark everything as no longer needed
 
   
 
   
 
  mission_cleanup:
 
  mission_cleanup:
  // Mark everything as no longer needed
+
  //MISSION_HAS_FINISHED
 
  [...]
 
  [...]
 
  RETURN
 
  RETURN
  
===Triggers===
+
Some missions doesn't need to be executed multiple times because they may just initialize some [[#Global|global]] [[#Variables|variables]] defined in the [[#Main file|main]] script or launch the intro mission. For this matter, here comes the usage of '''LOAD_AND_LAUNCH_MISSION_EXCLUSIVE''':
 +
 
 +
// File: main.sc
 +
 +
LOAD_AND_LAUNCH_MISSION_EXCLUSIVE initial.sc
 +
LOAD_AND_LAUNCH_MISSION_EXCLUSIVE intro.sc
 +
 
 +
;Note
 +
:Exclusive missions are never launched in the source code. It's likely, it was an idea not came to the end successfully or rather they were useful for debugging purposes.
 +
 
 +
;Limits
 +
:'''LOAD_AND_LAUNCH_MISSION_EXCLUSIVE''' is available only in {{icon|vc}} and {{icon|sa}};
 +
:Only 2 exclusive missions in {{icon|vc}} and 3 in {{icon|sa}} are handled, plus they must be launched before any of the counterpart.
 +
 
 +
===Streamed scripts===
 
----
 
----
 
{{incomplete}}
 
{{incomplete}}
  
==Statements==
+
==Control flow==
  
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''. However, you are still able to build your own control flows:
+
As usual, the evolution of something implies its development over the years. Alongside, the ''control flows'' implementation has been distributed equally into every chapter. Their definitions are similar to those used in ''pseudocodes'' resulting in a ''raw source code''. However, you are still able to build your own control flows:
  
 
  ANDOR {value}
 
  ANDOR {value}
  [NOT] {condition0}
+
    [NOT] {condition0}
  [[NOT] {condition8}]
+
    [[NOT] {condition8}]
 
  GOTO_IF_FALSE ELSE
 
  GOTO_IF_FALSE ELSE
 
     {consequence}
 
     {consequence}
Line 729: Line 866:
 
  ENDIF:]
 
  ENDIF:]
  
===IF===
+
;Note
 +
:It's likely, user-made control flows weren't intended to be usable because R* compiler cannot recognize an [[#Comparison|equal to]] rather than an [[#Arithmetic|assignment]] operator.
  
'''IF''' is one of the most widespread ''conditional statements'' which executes some codes by evaluating a boolean flag, the returning value of one or more conditions. According to the returning value, either the ''consequence'' or the ''alternative'' will be performed. The condition result can be inverted by appending the '''NOT''' [[#Logical|logical operator]] before. More conditions require the use of the remaining logical operators, they are '''AND''', when verifying if all ''checks'' are true, and '''OR''', while testing if one of all checks is true. The syntax below summarize the whole explanation:
+
===If===
 +
<code>IF</code> is the most common conditional statement. It executes one block of code if a boolean condition is <code>true</code>, and (optionally) another if the condition is <code>false</code>. The condition may be made of multiple conditions combined using the [[#Logical|logical operators]] <code>AND</code> or <code>OR</code>, or it may just be a single condition. <code>AND</code> makes the final condition <code>true</code> only if ''all'' of the input conditions are <code>true</code>, whereas <code>OR</code> only requires ''one'' input condition to be <code>true</code>. The condition may be inverted with <code>NOT</code>, another logical operator. Syntax:
  
IF [NOT] {condition0}
+
<syntaxhighlight>
[AND|OR [NOT] {condition8}]
+
IF [NOT] {condition0}
    {consequence}
+
[AND|OR [NOT] {condition8}]
[ELSE
+
    {consequence}
    {alternative}]
+
[ELSE
ENDIF
+
    {alternative}]
 +
ENDIF
 +
</syntaxhighlight>
  
;Limit
+
;Limitations
:More than ''9 conditions'' per statement are't allowed.
+
*There is a maximum of '''8 conditions'''.
  
===IFNOT===
+
===If-not===
 +
<code>IFNOT</code> works in the same way as <code>IF</code> except that the condition is always inverted.
  
'''IFNOT''' is a variation of the '''IF''' statement as already stated. As opposed to its closest relative, the conditions evaluetion is reversed, that is the ''consequence'' is perfomed when the boolean flag is false, else the ''alternative'' is executed:
+
<syntaxhighlight>
 +
IFNOT [NOT] {condition0}
 +
[AND|OR [NOT] {condition8}]
 +
    {consequence}
 +
[ELSE
 +
    {alternative}]
 +
ENDIF
 +
</syntaxhighlight>
  
IFNOT [NOT] {condition0}
+
;Limitations
[AND|OR [NOT] {condition8}]
+
*<code>IFNOT</code> is only supported in games that have <code>GOTO_IF_TRUE</code>: {{icon|3}}, {{icon|lcs}} and {{icon|vcs}}.
    {consequence}
 
[ELSE
 
    {alternative}]
 
ENDIF
 
  
;Limit
+
===While===
:It is supported since {{icon|lcs}}.
+
<code>WHILE</code> is similar to <code>IF</code>, but it continues executing the body until the condition is <code>false</code>.
  
===WHILE===
+
<syntaxhighlight>
 +
WHILE [NOT] {condition0}
 +
[AND|OR [NOT] {condition8}]
 +
    {consequence}
 +
ENDWHILE
 +
</syntaxhighlight>
  
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===
 +
<code>WHILENOT</code> is to <code>WHILE</code> as <code>IFNOT</code> is to <code>IF</code>: it loops until the condition is <code>true</code>.
  
WHILE [NOT] {condition0}
+
<syntaxhighlight>
[AND|OR [NOT] {condition8}]
+
WHILENOT [NOT] {condition0}
    {consequence}
+
[AND|OR [NOT] {condition8}]
ENDWHILE
+
    {consequence}
 +
ENDWHILE
 +
</syntaxhighlight>
  
===WHILENOT===
+
;Limitations
 +
*Like <code>IFNOT</code>, <code>WHILENOT</code> is only supported in games that have <code>GOTO_IF_TRUE</code>: {{icon|3}}, {{icon|lcs}} and {{icon|vcs}}.
  
'''WHILENOT''' acts seemingly like the '''WHILE''' statement, as all condition truths are inverted and therefore the ''consequence'' is performed over and over again until the boolean flag becomes true:
+
===Repeat===
 +
<code>REPEAT</code> acts as a range-based loop (generally a ''for-loop'' in modern programming languages). It executes the body and increments a certain [[#Variables|variable]] until it reaches a target value, at which point the loop stops.
  
WHILENOT [NOT] {condition0}
+
<syntaxhighlight>
[AND|OR [NOT] {condition8}]
+
REPEAT {target} {varname}
    {consequence}
+
    {consequence}
ENDWHILE
+
ENDREPEAT
 +
</syntaxhighlight>
  
;Limit
+
;Limitations
:It is supported since {{icon|lcs}}.
+
*<code>REPEAT</code> is supported in games from {{icon|vc}};
 +
*The target value must be positive;
 +
*The body will be read at least once in any case.
  
===REPEAT===
+
===Switch===
 +
A <code>SWITCH</code> statement is functionally equivalent to multiple nested <code>IF...ELSE</code> statements. It takes a single value and executes a block of code that is specific to that value (a <code>CASE</code>) until it finds a <code>BREAK</code>, which moves execution to the end of the construct. If no matching case is found, the <code>DEFAULT</code> clause is executed.
  
Similar to the '''WHILE''' construct, '''REPEAT''' ''iterates'' the ''consequence'' repeatedly depending on a 0-value incremental [[#Variables|variable]] which rises till the times specified:
+
<syntaxhighlight>
 +
SWITCH {varname}
 +
    CASE {value0}
 +
        {consequence}
 +
        BREAK
 +
    [CASE {valueN}
 +
        {consequence}
 +
        BREAK]
 +
    [DEFAULT
 +
        {alternative}
 +
        BREAK]
 +
ENDSWITCH
 +
</syntaxhighlight>
  
REPEAT {times} {varname}
+
;Limitations
    {consequence}
+
*It is supported from {{icon|sa}};
ENDREPEAT
+
*<code>CASE</code> allows the use of [[#INT|INT]] and [[#CONST (pseudo)|CONST]] values only;
 +
*In {{icon|sa}}, the <code>CASE</code> values should be sorted (R*'s compiler should do it implicitly);
 +
*Every <code>CASE</code>, including <code>DEFAULT</code>, must end with a <code>BREAK</code>.
  
;Limits
+
=Decompiling=
:It is supported since {{icon|vc}}.
 
:The times must be positive.
 
:The code will be read at least once in any case.
 
  
===CASE===
+
==Structure==
  
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:
+
For further information about the SCM file format, read [[Mission_Scripting (Overview)|this]] article. Take into account the compiling order of each ''SC'' file is [[#Main file|main file]] » [[#Foreign gosubs|foreign gosubs]] » [[#Subscripts|subscripts]] » [[#Mission scripts|mission scripts]] apart from the reading order of the commands used to include them. [[#Streamed scripts|Streamed scripts]] are compiled individually into the ''script.img'' file. On the other hand, [[#Functions|functions]] are compiled like [[#Gosubs|gosubs]].
  
CASE {varname}
+
==Identifiers==
    WHEN {value0}
 
        {consequence}
 
    [WHEN {valueN}
 
        {consequence}]
 
    [ELSE
 
        {alternative}]
 
ENDCASE
 
  
;Limits
+
''Undefined [[#Constants|constants]]'' of model identifiers, whose name refers to a [[DFF]] which is presumably archived into any of the [[IMG]]<nowiki>s</nowiki>, 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''. Those of [[#Mission scripts|mission scripts]] and [[#Streamed scripts|streamed scripts]] respect the same rule except the fact they are turned into a zero-based growing identifier, while exclusive mission scripts are launched by a negative identifier resulting from the bits inversion (bitwise complement).
:It is supported since {{icon|sa}}.
 
:The '''WHEN''' clause allows the use of integer values only.
 
:In {{icon|sa}}, values must be sorted.
 
:Multiple cases per ''consequence'' aren't allowed.
 
 
 
=Decompiling=
 
 
 
==Structure==
 
 
 
For further information about the SCM file format, read [[Mission_Scripting (Overview)|this]] article. Take into account the compiling order of each ''SC'' file is [[#Main file|main file]] - [[#Foreign gosubs|foreign gosubs]] - [[#Subscripts|subscripts]] - [[#Mission scripts|mission scripts]] apart from the reading order of the commands used to include them. [[#Triggers|triggers]] are compiled individually into the ''script.img'' file. On the other hand, [[#Functions|functions]] are compiled like [[#Gosubs|gosubs]].
 
 
 
==Identifiers==
 
 
 
''Undefined [[#Constants|constants]]'' of model identifiers, whose name refers to a [[DFF]] which is presumably archived into any of the [[IMG]]s, 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''. Those of [[#Mission scripts|mission scripts]] and [[#Triggers|triggers]] respect the same rule except the fact they are turned into a 0-based growing identifier.
 
  
 
==Offsets==
 
==Offsets==
  
An ''offset'' is a ''32-bit signed integer'' which points to a location of the source code. Those within the [[#Main file|main file]], [[#Foreign gosubs|foreign gosubs]] and [[#Subscripts|subscripts]] are ''absolute offsets'' that start from the beginning of the main script, while the ones inside [[#Mission scripts|mission scripts]] and [[#Triggers|triggers]] are ''relative offsets'' starting from their beginning. The offset is related to [[#Global|global]] [[#Variables|variables]] aswell, whose interval goes from ''8'' and ends to ''FFFC'', each one is aligned to the nearest 4 bytes.
+
An ''offset'' is a ''32-bit signed integer'' which points to a location of the script file. Those within the [[#Main file|main file]], [[#Foreign gosubs|foreign gosubs]] and [[#Subscripts|subscripts]] are ''absolute offsets'' that start from the beginning of the main script, while the ones inside [[#Mission scripts|mission scripts]] and [[#Streamed scripts|streamed scripts]] are ''relative and negative offsets'' starting from their beginning. The offset is related to [[#Global|global]] [[#Variables|variables]] as well, whose interval goes from ''8'' and ends to ''65532'' (''0xFFFC''), each one is aligned to the nearest 4 bytes.
  
==Variables==
+
==Variables range==
  
 
The following table shows the [[#Variables|variables]] range of the [[#Local|local]] [[#Scope|scope]] for each game version:
 
The following table shows the [[#Variables|variables]] range of the [[#Local|local]] [[#Scope|scope]] for each game version:
  
 
{|class=wikitable style=text-align:center
 
{|class=wikitable style=text-align:center
!width=125px|Context
+
!Context
 
!width=50px|{{icon|3}}
 
!width=50px|{{icon|3}}
 
!width=50px|{{icon|vc}}
 
!width=50px|{{icon|vc}}
Line 840: Line 989:
 
|align=left|[[#Subscripts|Subscript]]/[[#Scripts|Script]]||0-15||0-15||0-31||0-95||0-95
 
|align=left|[[#Subscripts|Subscript]]/[[#Scripts|Script]]||0-15||0-15||0-31||0-95||0-95
 
|-
 
|-
|align=left|[[#Mission scripts|Mission script]]{{ref|mblock|[*]}}||0-15||0-15||0-1023||0-95||0-95
+
|align=left|[[#Mission scripts|Mission script]]||0-15||0-15||0-1023||0-95||0-95
 
|-
 
|-
|align=left|[[#Triggers|Trigger]]||n/a||n/a||0-31||n/a||n/a
+
|align=left|[[#Streamed scripts|Streamed script]]||n/a||n/a||0-31||n/a||n/a
 
|-
 
|-
 
|align=left|[[#Functions|Function]]||n/a||n/a||n/a||0-95||0-95
 
|align=left|[[#Functions|Function]]||n/a||n/a||n/a||0-95||0-95
Line 848: Line 997:
 
!colspan=6|
 
!colspan=6|
 
|-
 
|-
|align=left|[[#Timers|Timer]]||16-17||16-17||32-33||10-11?||254-255
+
|align=left|[[#Timers|Timer]]||16-17||16-17||32-33||t0-t1||t0-t1
 
|}
 
|}
  
;Note
+
==Compiled operators==
:{{note|mblock}} Although the mission block is allocated as an ''unique subscript'', locals point to the same storage location, therefore they are some kind of [[#Globals|globals]] for missions uniquely.
+
As in most compiled programming languages, SCM's [[#Operators|operators]] are always compiled with two operands, regardless of how they appear within the source code.
  
==Operators composition==
+
This means that operators that seem to have only one operand will have two, and operators that seem to have more than two are actually compiled as multiple instructions.
  
As far as you wouldn't know, SCM's [[#Operators|operators]] always take two operands to compute an operation. Their composition is listed below:
+
{|class="mw-collapsible wikitable"
 
+
!width=70px|Operator
{|class=wikitable
 
!width=70px|Operator/s
 
 
!width=200px colspan=2|Name
 
!width=200px colspan=2|Name
!width=200px|Syntax
+
!width=200px|Written
!width=180px|Composition
+
!width=180px|Compiled
 
|-
 
|-
 
!rowspan=2|<code>++</code>
 
!rowspan=2|<code>++</code>
 
|align=center rowspan=2|Increment
 
|align=center rowspan=2|Increment
 
|align=center|Pre
 
|align=center|Pre
|align=center|<code>'''++''' expr0</code>
+
|align=center|<code>++a</code>
|align=center rowspan=2|<code>expr0 '''+=''' 1</code>
+
|align=center rowspan=2|<code>a += 1</code>
 
|-
 
|-
 
|align=center|Post
 
|align=center|Post
|align=center|<code>expr0 '''++'''</code>
+
|align=center|<code>a++</code>
 
|-
 
|-
 
!rowspan=2|<code>--</code>
 
!rowspan=2|<code>--</code>
 
|align=center rowspan=2|Decrement
 
|align=center rowspan=2|Decrement
 
|align=center|Pre
 
|align=center|Pre
|align=center|<code>'''--''' expr0</code>
+
|align=center|<code>--a</code>
|align=center rowspan=2|<code>expr0 '''-=''' 1</code>
+
|align=center rowspan=2|<code>a -= 1</code>
 
|-
 
|-
 
|align=center|Post
 
|align=center|Post
|align=center|<code>expr0 '''--'''</code>
+
|align=center|<code>a--</code>
 
|-
 
|-
!<code>= +</code>
+
!<code>+=</code>
 
|align=center colspan=2|Addition and assignment
 
|align=center colspan=2|Addition and assignment
|align=center|<code>expr0 '''=''' expr1 '''+''' expr2</code>
+
|align=center|<code>a = b + c</code>
|align=center|<code>expr0 '''=''' expr1<br/>expr0 '''+=''' expr2</code>
+
|align=center|<code>a = b</code><br/><code>a += c</code>
 
|-
 
|-
!<code>= -</code>
+
!<code>-=</code>
 
|align=center colspan=2|Subtraction and assignment
 
|align=center colspan=2|Subtraction and assignment
|align=center|<code>expr0 '''=''' expr1 '''-''' expr2</code>
+
|align=center|<code>a = b - c</code>
|align=center|<code>expr0 '''=''' expr1<br/>expr0 '''-=''' expr2</code>
+
|align=center|<code>a = b</code><br/><code>a -= c</code>
 
|-
 
|-
!<code>= *</code>
+
!<code>*=</code>
 
|align=center colspan=2|Multiplication and assignment
 
|align=center colspan=2|Multiplication and assignment
|align=center|<code>expr0 '''=''' expr1 '''*''' expr2</code>
+
|align=center|<code>a = b * c</code>
|align=center|<code>expr0 '''=''' expr1<br/>expr0 '''*=''' expr2</code>
+
|align=center|<code>a = b</code><br/><code>a *= c</code>
 
|-
 
|-
!<code>= /</code>
+
!<code>/=</code>
 
|align=center colspan=2|Division and assignment
 
|align=center colspan=2|Division and assignment
|align=center|<code>expr0 '''=''' expr1 '''/''' expr2</code>
+
|align=center|<code>a = b / c</code>
|align=center|<code>expr0 '''=''' expr1<br/>expr0 '''/=''' expr2</code>
+
|align=center|<code>a = b</code><br/><code>a /= c</code>
 
|-
 
|-
!<code>= +@</code>
+
!<code>+=@</code>
 
|align=center colspan=2|Timed addition and assignment
 
|align=center colspan=2|Timed addition and assignment
|align=center|<code>expr0 '''=''' expr1 '''+@''' expr2</code>
+
|align=center|<code>a = b +@ c</code>
|align=center|<code>expr0 '''=''' expr1<br/>expr0 '''+=@''' expr2</code>
+
|align=center|<code>a = b</code><br/><code>a +=@ c</code>
 
|-
 
|-
!<code>= -@</code>
+
!<code>-=@</code>
 
|align=center colspan=2|Timed subtraction and assignment
 
|align=center colspan=2|Timed subtraction and assignment
|align=center|<code>expr0 '''=''' expr1 '''-@''' expr2</code>
+
|align=center|<code>a = b -@ c</code>
|align=center|<code>expr0 '''=''' expr1<br/>expr0 '''-=@''' expr2</code>
+
|align=center|<code>a = b</code><br/><code>a -=@ c</code>
 
|}
 
|}
  
==Opcodes==
+
==Opcode==
 +
A command's ''opcode'' is a ''16-bit signed integer'' identifier which the game uses to find the implementation for the command. The maximum number of opcodes possible is 32,767 (<code>0x7FFF</code>), because the most significant bit (<code>0x8000</code>) is the ''sign bit'', which is only set when the associated command's return value is inverted (e.g. <code>not x()</code>).
 +
 
 +
There are no commands with negative opcodes; the game takes the absolute value (<code>|opcode|</code>) before finding the implementation, after noting whether it is inverted.
  
An ''opcode'' is a ''16-bit unsigned integer'' 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 opcodes is ''0x7FFF'', since the last bit (''0x8000'') is set whenever they are used as ''negative conditions'' (those with the '''NOT''' [[#Logical|logical operator]]).
+
==Command arguments==
  
===Arguments===
+
The limitation of the amount of arguments a [http://en.wikipedia.org/wiki/Variadic_function variadic] command can pass is game specific:
  
An ''argument'' is some data given as input to an opcode. Normally, opcodes 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|variables]] are, except [[#Timers|timers]]. This limitation is game specific.
+
* 16 for {{icon|3}} and {{icon|vc}};
 +
* 32 for {{icon|sa}};
 +
* 96 for {{icon|lcs}} and {{icon|vcs}}.
  
===Internal===
+
==Managed commands==
  
Here is the list of all [[#Commands|commands]] handled arbitrarily by the R* compiler:
+
Here is the list of all managed [[#Commands|commands]] and their relative specifications:
  
 
'''Legend:'''
 
'''Legend:'''
* '''Variable:'''<code>
+
 
** V, [[#Value|VALUE]]
+
* '''Prefix:'''
** G, [[#Global|GLOBAL]]
+
** V, [[#Global|VAR]];
** L, [[#Local|LOCAL]]
+
** L, [[#Local|LVAR]];
</code>
+
** A, ANY ([[#Value|VALUE]], VAR, LVAR).
* '''Type:'''<code>
+
 
** I, [[#INT|INT]]
+
* '''Specifier:'''
** F, [[#FLOAT|FLOAT]]
+
** R, [[#LABEL|LABEL]];
** T, [[#TEXT_LABEL|TEXT_LABEL]]
+
** I, [[#INT|INT]];
** S, [[#STRING|STRING]]
+
** F, [[#FLOAT|FLOAT]];
** O, [[#OFFSET|OFFSET]]
+
** T, [[#TEXT_LABEL|TEXT_LABEL]];
** N, [[#NUMBER|NUMBER]]
+
** T16, [[#TEXT_LABEL16|TEXT_LABEL16]];
** C, [[#CONSTANT|CONSTANT]]
+
** T32, [[#TEXT_LABEL32|TEXT_LABEL32]];
** B, [[#BUFFER|BUFFER]]
+
** T[N], [[#TEXT|TEXT]];
** V, [[#VARLEN|VARLEN]]
+
** C, [[#CONST (pseudo)|CONST]];
</code>
+
** M, [[#MULTI (pseudo)|MULTI]].
'''List:'''
+
 
{|class=wikitable style=text-align:center
+
* '''Suffix:'''
!rowspan=2 colspan=2|Command
+
** O, OPTIONAL.
!rowspan=2|Opcode
+
 
!rowspan=2|Args<br/>count
+
'''List:'''
!colspan=20|Arguments
+
 
 +
Be aware, the argument data types of the commands below are just informative:
 +
 
 +
<div width=100% style="overflow: auto; margin: -8px auto 8px">
 +
{|class="mw-collapsible mw-collapsed wikitable" style=text-align:center
 +
|-
 +
!rowspan=3 colspan=2|Command
 +
!rowspan=3|ID
 +
!colspan=9|Arguments
 +
|-
 +
!width=45px rowspan=2|#
 +
!width=45px rowspan=2|1
 +
!width=45px rowspan=2|2
 +
!width=45px rowspan=2|3
 +
!width=45px rowspan=2|4
 +
!width=45px rowspan=2|...
 +
!width=45px rowspan=2|18
 +
!width=45px rowspan=2|...
 +
!width=45px|n+l
 
|-
 
|-
!width=20px|1
+
!n+i+o
!width=20px|2
 
!width=20px|3
 
!width=20px|4
 
!width=20px|5
 
!width=20px|6
 
!width=20px|7
 
!width=20px|8
 
!width=20px|9
 
!width=20px|10
 
!width=20px|11
 
!width=20px|12
 
!width=20px|13
 
!width=20px|14
 
!width=20px|15
 
!width=20px|16
 
!width=20px|17
 
!width=20px|18
 
!width=20px|...
 
!width=20px|19
 
 
|-
 
|-
|colspan=25|{{icon|3}} {{icon|vc}} {{icon|sa}} {{icon|lcs}} {{icon|vcs}}
+
|colspan=12|{{icon|t}} {{icon|lcs}} {{icon|vcs}}
 
|-
 
|-
 
!colspan=2|MISSION_START{{ref|misdef|[*]}}
 
!colspan=2|MISSION_START{{ref|misdef|[*]}}
 
|
 
|
 
!0
 
!0
|colspan=20|
+
|colspan=8|
 
|-
 
|-
 
!colspan=2|GOTO{{ref|statem|[*]}}
 
!colspan=2|GOTO{{ref|statem|[*]}}
|0002
+
|[[0002|2]]
 
!1
 
!1
|VO||colspan=19|
+
|R||colspan=7|
 
|-
 
|-
|colspan=25|{{icon|3}} {{icon|vc}} {{icon|sa}} {{icon|lcs}}
+
|colspan=12|{{icon|t}} {{icon|lcs}}
 
|-
 
|-
!rowspan=4|=!!SET_VAR_INT
+
!rowspan=12|=<br/>SET!!SET_VAR_INT
|0004
+
|[[0004|4]]
!rowspan=4|2
+
!rowspan=12|2
|GI||VI||colspan=18|
+
|VI||I||colspan=6|
 
|-
 
|-
 
!SET_VAR_FLOAT
 
!SET_VAR_FLOAT
|0005||GF||VF||colspan=18|
+
|[[0005|5]]||VF||F||colspan=6|
 
|-
 
|-
 
!SET_LVAR_INT
 
!SET_LVAR_INT
|0006||LI||VI||colspan=18|
+
|[[0006|6]]||LI||I||colspan=6|
 
|-
 
|-
 
!SET_LVAR_FLOAT
 
!SET_LVAR_FLOAT
|0007||LF||VF||colspan=18|
+
|[[0007|7]]||LF||F||colspan=6|
 
|-
 
|-
!rowspan=4|+=!!ADD_VAL_TO_INT_VAR
+
!SET_VAR_INT_TO_VAR_INT
|0008
+
|[[0084|132]]||VI||VI||colspan=6|
!rowspan=4|2
 
|GI||VI||colspan=18|
 
 
|-
 
|-
!ADD_VAL_TO_FLOAT_VAR
+
!SET_LVAR_INT_TO_LVAR_INT
|0009||GF||VF||colspan=18|
+
|[[0085|133]]||LI||LI||colspan=6|
 
|-
 
|-
!ADD_VAL_TO_INT_LVAR
+
!SET_VAR_FLOAT_TO_VAR_FLOAT
|000A||LI||VI||colspan=18|
+
|[[0086|134]]||VF||VF||colspan=6|
 
|-
 
|-
!ADD_VAL_TO_FLOAT_LVAR
+
!SET_LVAR_FLOAT_TO_LVAR_FLOAT
|000B||LF||VF||colspan=18|
+
|[[0087|135]]||LF||LF||colspan=6|
 
|-
 
|-
!rowspan=4|-=!!SUB_VAL_FROM_INT_VAR
+
!SET_VAR_FLOAT_TO_LVAR_FLOAT
|000C
+
|[[0088|136]]||VF||LF||colspan=6|
!rowspan=4|2
 
|GI||VI||colspan=18|
 
 
|-
 
|-
!SUB_VAL_FROM_FLOAT_VAR
+
!SET_LVAR_FLOAT_TO_VAR_FLOAT
|000D||GF||VF||colspan=18|
+
|[[0089|137]]||LF||VF||colspan=6|
 
|-
 
|-
!SUB_VAL_FROM_INT_LVAR
+
!SET_VAR_INT_TO_LVAR_INT
|000E||LI||VI||colspan=18|
+
|[[008A|138]]||VI||LI||colspan=6|
 
|-
 
|-
!SUB_VAL_FROM_FLOAT_LVAR
+
!SET_LVAR_INT_TO_VAR_INT
|000F||LF||VF||colspan=18|
+
|[[008B|139]]||LI||VI||colspan=6|
 
|-
 
|-
!rowspan=4|*=!!MULT_INT_VAR_BY_VAL
+
!rowspan=12|+=<br/>+<br/>ADD_THING_TO_THING!!ADD_VAL_TO_INT_VAR
|0010
+
|[[0008|8]]
!rowspan=4|2
+
!rowspan=12|2
|GI||VI||colspan=18|
+
|VI||I||colspan=6|
 
|-
 
|-
!MULT_FLOAT_VAR_BY_VAL
+
!ADD_VAL_TO_FLOAT_VAR
|0011||GF||VF||colspan=18|
+
|[[0009|9]]||VF||F||colspan=6|
 
|-
 
|-
!MULT_INT_LVAR_BY_VAL
+
!ADD_VAL_TO_INT_LVAR
|0012||LI||VI||colspan=18|
+
|[[000A|10]]||LI||I||colspan=6|
 
|-
 
|-
!MULT_FLOAT_LVAR_BY_VAL
+
!ADD_VAL_TO_FLOAT_LVAR
|0013||LF||VF||colspan=18|
+
|[[000B|11]]||LF||F||colspan=6|
 
|-
 
|-
!rowspan=4|/=!!DIV_INT_ANY_BY_VAL
+
!ADD_INT_VAR_TO_INT_VAR
|0014
+
|[[0058|88]]||VI||VI||colspan=6|
!rowspan=4|2
 
|GI||VI||colspan=18|
 
 
|-
 
|-
!DIV_FLOAT_VAR_BY_VAL
+
!ADD_FLOAT_VAR_TO_FLOAT_VAR
|0015||GF||VF||colspan=18|
+
|[[0059|89]]||VF||VF||colspan=6|
 
|-
 
|-
!DIV_INT_LVAR_BY_VAL
+
!ADD_INT_LVAR_TO_INT_LVAR
|0016||LI||VI||colspan=18|
+
|[[005A|90]]||LI||LI||colspan=6|
 
|-
 
|-
!DIV_FLOAT_LVAR_BY_VAL
+
!ADD_FLOAT_LVAR_TO_FLOAT_LVAR
|0017||LF||VF||colspan=18|
+
|[[005B|91]]||LF||LF||colspan=6|
 
|-
 
|-
!rowspan=16|>!!IS_INT_VAR_GREATER_THAN_NUMBER
+
!ADD_INT_VAR_TO_INT_LVAR
|0018
+
|[[005C|92]]||LI||VI||colspan=6|
!rowspan=16|2
 
|GI||VN||colspan=18|
 
 
|-
 
|-
!IS_INT_LVAR_GREATER_THAN_NUMBER
+
!ADD_FLOAT_VAR_TO_FLOAT_LVAR
|0019||LI||VN||colspan=18|
+
|[[005D|93]]||LF||VF||colspan=6|
 
|-
 
|-
!IS_NUMBER_GREATER_THAN_INT_VAR
+
!ADD_INT_LVAR_TO_INT_VAR
|001A||VN||GI||colspan=18|
+
|[[005E|94]]||VI||LI||colspan=6|
 
|-
 
|-
!IS_NUMBER_GREATER_THAN_INT_LVAR
+
!ADD_FLOAT_LVAR_TO_FLOAT_VAR
|001B||VN||LI||colspan=18|
+
|[[005F|95]]||VF||LF||colspan=6|
 
|-
 
|-
!IS_INT_VAR_GREATER_THAN_INT_VAR
+
!rowspan=12|-=<br/>-<br/>SUB_THING_FROM_THING!!SUB_VAL_FROM_INT_VAR
|001C||GI||GI||colspan=18|
+
|[[000C|12]]
 +
!rowspan=12|2
 +
|VI||I||colspan=6|
 
|-
 
|-
!IS_INT_LVAR_GREATER_THAN_INT_LVAR
+
!SUB_VAL_FROM_FLOAT_VAR
|001D||LI||LI||colspan=18|
+
|[[000D|13]]||VF||F||colspan=6|
 
|-
 
|-
!IS_INT_VAR_GREATER_THAN_INT_LVAR
+
!SUB_VAL_FROM_INT_LVAR
|001E||GI||LI||colspan=18|
+
|[[000E|14]]||LI||I||colspan=6|
 
|-
 
|-
!IS_INT_LVAR_GREATER_THAN_INT_VAR
+
!SUB_VAL_FROM_FLOAT_LVAR
|001F||LI||GI||colspan=18|
+
|[[000F|15]]||LF||F||colspan=6|
 
|-
 
|-
!IS_FLOAT_VAR_GREATER_THAN_NUMBER
+
!SUB_INT_VAR_FROM_INT_VAR
|0020||GF||VN||colspan=18|
+
|[[0060|96]]||VI||VI||colspan=6|
 
|-
 
|-
!IS_FLOAT_LVAR_GREATER_THAN_NUMBER
+
!SUB_FLOAT_VAR_FROM_FLOAT_VAR
|0021||LF||VN||colspan=18|
+
|[[0061|97]]||VF||VF||colspan=6|
 
|-
 
|-
!IS_NUMBER_GREATER_THAN_FLOAT_VAR
+
!SUB_INT_LVAR_FROM_INT_LVAR
|0022||VN||GF||colspan=18|
+
|[[0062|98]]||LI||LI||colspan=6|
 
|-
 
|-
!IS_NUMBER_GREATER_THAN_FLOAT_LVAR
+
!SUB_FLOAT_LVAR_FROM_FLOAT_LVAR
|0023||VN||LF||colspan=18|
+
|[[0063|99]]||LF||LF||colspan=6|
 
|-
 
|-
!IS_FLOAT_VAR_GREATER_THAN_FLOAT_VAR
+
!SUB_INT_VAR_FROM_INT_LVAR
|0024||GF||GF||colspan=18|
+
|[[0064|100]]||LI||VI||colspan=6|
 
|-
 
|-
!IS_FLOAT_LVAR_GREATER_THAN_FLOAT_LVAR
+
!SUB_FLOAT_VAR_FROM_FLOAT_LVAR
|0025||LF||LF||colspan=18|
+
|[[0065|101]]||LF||VF||colspan=6|
 
|-
 
|-
!IS_FLOAT_VAR_GREATER_THAN_FLOAT_LVAR
+
!SUB_INT_LVAR_FROM_INT_VAR
|0026||GF||LF||colspan=18|
+
|[[0066|102]]||VI||LI||colspan=6|
 
|-
 
|-
!IS_FLOAT_LVAR_GREATER_THAN_FLOAT_VAR
+
!SUB_FLOAT_LVAR_FROM_FLOAT_VAR
|0027||LF||GF||colspan=18|
+
|[[0067|103]]||VF||LF||colspan=6|
 
|-
 
|-
!rowspan=16|>=!!IS_INT_VAR_GREATER_OR_EQUAL_TO_NUMBER
+
!rowspan=12|*=<br/>*<br/>MULT_THING_BY_THING!!MULT_INT_VAR_BY_VAL
|0028
+
|[[0010|16]]
!rowspan=16|2
+
!rowspan=12|2
|GI||VN||colspan=18|
+
|VI||I||colspan=6|
 
|-
 
|-
!IS_INT_LVAR_GREATER_OR_EQUAL_TO_NUMBER
+
!MULT_FLOAT_VAR_BY_VAL
|0029||LI||VN||colspan=18|
+
|[[0011|17]]||VF||F||colspan=6|
 
|-
 
|-
!IS_NUMBER_GREATER_OR_EQUAL_TO_INT_VAR
+
!MULT_INT_LVAR_BY_VAL
|002A||VN||GI||colspan=18|
+
|[[0012|18]]||LI||I||colspan=6|
 
|-
 
|-
!IS_NUMBER_GREATER_OR_EQUAL_TO_INT_LVAR
+
!MULT_FLOAT_LVAR_BY_VAL
|002B||VN||LI||colspan=18|
+
|[[0013|19]]||LF||F||colspan=6|
 
|-
 
|-
!IS_INT_VAR_GREATER_OR_EQUAL_TO_INT_VAR
+
!MULT_INT_VAR_BY_INT_VAR
|002C||GI||GI||colspan=18|
+
|[[0068|104]]||VI||VI||colspan=6|
 
|-
 
|-
!IS_INT_LVAR_GREATER_OR_EQUAL_TO_INT_LVAR
+
!MULT_FLOAT_VAR_BY_FLOAT_VAR
|002D||LI||LI||colspan=18|
+
|[[0069|105]]||VF||VF||colspan=6|
 
|-
 
|-
!IS_INT_VAR_GREATER_OR_EQUAL_TO_INT_LVAR
+
!MULT_INT_LVAR_BY_INT_LVAR
|002E||GI||LI||colspan=18|
+
|[[006A|106]]||LI||LI||colspan=6|
 
|-
 
|-
!IS_INT_LVAR_GREATER_OR_EQUAL_TO_INT_VAR
+
!MULT_FLOAT_LVAR_BY_FLOAT_LVAR
|002F||LI||GI||colspan=18|
+
|[[006B|107]]||LF||LF||colspan=6|
 
|-
 
|-
!IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_NUMBER
+
!MULT_INT_VAR_BY_INT_LVAR
|0030||GF||VN||colspan=18|
+
|[[006C|108]]||VI||LI||colspan=6|
 
|-
 
|-
!IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_NUMBER
+
!MULT_FLOAT_VAR_BY_FLOAT_LVAR
|0031||LF||VN||colspan=18|
+
|[[006D|109]]||VF||LF||colspan=6|
 
|-
 
|-
!IS_NUMBER_GREATER_OR_EQUAL_TO_FLOAT_VAR
+
!MULT_INT_LVAR_BY_INT_VAR
|0032||VN||GF||colspan=18|
+
|[[006E|110]]||LI||VI||colspan=6|
 
|-
 
|-
!IS_NUMBER_GREATER_OR_EQUAL_TO_FLOAT_LVAR
+
!MULT_FLOAT_LVAR_BY_FLOAT_VAR
|0033||VN||LF||colspan=18|
+
|[[006F|111]]||LF||VF||colspan=6|
 
|-
 
|-
!IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_FLOAT_VAR
+
!rowspan=12|/=<br/>/<br/>DIV_THING_BY_THING!!DIV_INT_BY_VAL
|0034||GF||GF||colspan=18|
+
|[[0014|20]]
 +
!rowspan=12|2
 +
|VI||I||colspan=6|
 
|-
 
|-
!IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_FLOAT_LVAR
+
!DIV_FLOAT_VAR_BY_VAL
|0035||LF||LF||colspan=18|
+
|[[0015|21]]||VF||F||colspan=6|
 
|-
 
|-
!IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_FLOAT_LVAR
+
!DIV_INT_LVAR_BY_VAL
|0036||GF||LF||colspan=18|
+
|[[0016|22]]||LI||I||colspan=6|
 
|-
 
|-
!IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_FLOAT_VAR
+
!DIV_FLOAT_LVAR_BY_VAL
|0037||LF||GF||colspan=18|
+
|[[0017|23]]||LF||F||colspan=6|
 
|-
 
|-
!rowspan=10|=!!IS_INT_VAR_EQUAL_TO_NUMBER
+
!DIV_INT_VAR_BY_INT_VAR
|0038
+
|[[0070|112]]||VI||VI||colspan=6|
!rowspan=10|2
 
|GI||VN||colspan=18|
 
 
|-
 
|-
!IS_INT_LVAR_EQUAL_TO_NUMBER
+
!DIV_FLOAT_VAR_BY_FLOAT_VAR
|0039||LI||VN||colspan=18|
+
|[[0071|113]]||VF||VF||colspan=6|
 
|-
 
|-
!IS_INT_VAR_EQUAL_TO_INT_VAR
+
!DIV_INT_LVAR_BY_INT_LVAR
|003A||GI||GI||colspan=18|
+
|[[0072|114]]||LI||LI||colspan=6|
 
|-
 
|-
!IS_INT_LVAR_EQUAL_TO_INT_LVAR
+
!DIV_FLOAT_LVAR_BY_FLOAT_LVAR
|003B||LI||LI||colspan=18|
+
|[[0073|115]]||LF||LF||colspan=6|
 
|-
 
|-
!IS_INT_VAR_EQUAL_TO_INT_LVAR
+
!DIV_INT_VAR_BY_INT_LVAR
|003C||GI||LI||colspan=18|
+
|[[0074|116]]||VI||LI||colspan=6|
 
|-
 
|-
!IS_FLOAT_VAR_EQUAL_TO_NUMBER
+
!DIV_FLOAT_VAR_BY_FLOAT_LVAR
|0042||GF||VN||colspan=18|
+
|[[0075|117]]||VF||LF||colspan=6|
 
|-
 
|-
!IS_FLOAT_LVAR_EQUAL_TO_NUMBER
+
!DIV_INT_LVAR_BY_INT_VAR
|0043||LF||VN||colspan=18|
+
|[[0076|118]]||LI||VI||colspan=6|
 
|-
 
|-
!IS_FLOAT_VAR_EQUAL_TO_FLOAT_VAR
+
!DIV_FLOAT_LVAR_BY_FLOAT_VAR
|0044||GF||GF||colspan=18|
+
|[[0077|119]]||LF||VF||colspan=6|
 
|-
 
|-
!IS_FLOAT_LVAR_EQUAL_TO_FLOAT_LVAR
+
!rowspan=16|><br/><=<br/>IS_THING_GREATER_THAN_THING!!IS_INT_VAR_GREATER_THAN_NUMBER
|0045||LF||LF||colspan=18|
+
|[[0018|24]]
 +
!rowspan=16|2
 +
|VI||I||colspan=6|
 
|-
 
|-
!IS_FLOAT_VAR_EQUAL_TO_FLOAT_LVAR
+
!IS_INT_LVAR_GREATER_THAN_NUMBER
|0046||GF||LF||colspan=18|
+
|[[0019|25]]||LI||I||colspan=6|
 
|-
 
|-
!colspan=2|GOTO_IF_FALSE{{ref|statem|[*]}}
+
!IS_NUMBER_GREATER_THAN_INT_VAR
|004D
+
|[[001A|26]]||I||VI||colspan=6|
!1
 
|VO||colspan=19|
 
 
|-
 
|-
!colspan=2|TERMINATE_THIS_SCRIPT
+
!IS_NUMBER_GREATER_THAN_INT_LVAR
|rowspan=2|004E
+
|[[001B|27]]||I||LI||colspan=6|
!rowspan=2|0
 
|rowspan=2 colspan=20|
 
 
|-
 
|-
!colspan=2|MISSION_END
+
!IS_INT_VAR_GREATER_THAN_INT_VAR
 +
|[[001C|28]]||VI||VI||colspan=6|
 
|-
 
|-
!colspan=2|START_NEW_SCRIPT{{ref|undefa|[*]}}
+
!IS_INT_LVAR_GREATER_THAN_INT_LVAR
|004F
+
|[[001D|29]]||LI||LI||colspan=6|
!1
 
|VO||colspan=19|_ _ _
 
 
|-
 
|-
!colspan=2|GOSUB
+
!IS_INT_VAR_GREATER_THAN_INT_LVAR
|0050
+
|[[001E|30]]||VI||LI||colspan=6|
!1
 
|VO||colspan=19|
 
 
|-
 
|-
!colspan=2|RETURN
+
!IS_INT_LVAR_GREATER_THAN_INT_VAR
|0051
+
|[[001F|31]]||LI||VI||colspan=6|
!0
 
|colspan=20|
 
 
|-
 
|-
!rowspan=8|+=!!ADD_INT_VAR_TO_INT_VAR
+
!IS_FLOAT_VAR_GREATER_THAN_NUMBER
|0058
+
|[[0020|32]]||VF||F||colspan=6|
!rowspan=8|2
 
|GI||GI||colspan=18|
 
 
|-
 
|-
!ADD_FLOAT_VAR_TO_FLOAT_VAR
+
!IS_FLOAT_LVAR_GREATER_THAN_NUMBER
|0059||GF||GF||colspan=18|
+
|[[0021|33]]||LF||F||colspan=6|
 
|-
 
|-
!ADD_INT_LVAR_TO_INT_LVAR
+
!IS_NUMBER_GREATER_THAN_FLOAT_VAR
|005A||LI||LI||colspan=18|
+
|[[0022|34]]||F||VF||colspan=6|
 
|-
 
|-
!ADD_FLOAT_LVAR_TO_FLOAT_LVAR
+
!IS_NUMBER_GREATER_THAN_FLOAT_LVAR
|005B||LF||LF||colspan=18|
+
|[[0023|35]]||F||LF||colspan=6|
 
|-
 
|-
!ADD_INT_VAR_TO_INT_LVAR
+
!IS_FLOAT_VAR_GREATER_THAN_FLOAT_VAR
|005C||LI||GI||colspan=18|
+
|[[0024|36]]||VF||VF||colspan=6|
 
|-
 
|-
!ADD_FLOAT_VAR_TO_FLOAT_LVAR
+
!IS_FLOAT_LVAR_GREATER_THAN_FLOAT_LVAR
|005D||LF||GF||colspan=18|
+
|[[0025|37]]||LF||LF||colspan=6|
 
|-
 
|-
!ADD_INT_LVAR_TO_INT_VAR
+
!IS_FLOAT_VAR_GREATER_THAN_FLOAT_LVAR
|005E||GI||LI||colspan=18|
+
|[[0026|38]]||VF||LF||colspan=6|
 
|-
 
|-
!ADD_FLOAT_LVAR_TO_FLOAT_VAR
+
!IS_FLOAT_LVAR_GREATER_THAN_FLOAT_VAR
|005F||GF||LF||colspan=18|
+
|[[0027|39]]||LF||VF||colspan=6|
 
|-
 
|-
!rowspan=8|-=!!SUB_INT_VAR_FROM_INT_VAR
+
!rowspan=16|>=<br/><<br/>IS_THING_GREATER_OR_EQUAL_TO_THING!!IS_INT_VAR_GREATER_OR_EQUAL_TO_NUMBER
|0060|
+
|[[0028|40]]
!rowspan=8|2
+
!rowspan=16|2
|GI||GI||colspan=18|
+
|VI||I||colspan=6|
 
|-
 
|-
!SUB_FLOAT_VAR_FROM_FLOAT_VAR
+
!IS_INT_LVAR_GREATER_OR_EQUAL_TO_NUMBER
|0061||GF||GF||colspan=18|
+
|[[0029|41]]||LI||I||colspan=6|
 
|-
 
|-
!SUB_INT_LVAR_FROM_INT_LVAR
+
!IS_NUMBER_GREATER_OR_EQUAL_TO_INT_VAR
|0062||LI||LI||colspan=18|
+
|[[002A|42]]||I||VI||colspan=6|
 
|-
 
|-
!SUB_FLOAT_LVAR_FROM_FLOAT_LVAR
+
!IS_NUMBER_GREATER_OR_EQUAL_TO_INT_LVAR
|0063||LF||LF||colspan=18|
+
|[[002B|43]]||I||LI||colspan=6|
 
|-
 
|-
!SUB_INT_VAR_FROM_INT_LVAR
+
!IS_INT_VAR_GREATER_OR_EQUAL_TO_INT_VAR
|0064||LI||GI||colspan=18|
+
|[[002C|44]]||VI||VI||colspan=6|
 
|-
 
|-
!SUB_FLOAT_VAR_FROM_FLOAT_LVAR
+
!IS_INT_LVAR_GREATER_OR_EQUAL_TO_INT_LVAR
|0065||LF||GF||colspan=18|
+
|[[002D|45]]||LI||LI||colspan=6|
 
|-
 
|-
!SUB_INT_LVAR_FROM_INT_VAR
+
!IS_INT_VAR_GREATER_OR_EQUAL_TO_INT_LVAR
|0066||GI||LI||colspan=18|
+
|[[002E|46]]||VI||LI||colspan=6|
 
|-
 
|-
!SUB_FLOAT_LVAR_FROM_FLOAT_VAR
+
!IS_INT_LVAR_GREATER_OR_EQUAL_TO_INT_VAR
|0067||GF||LF||colspan=18|
+
|[[002F|47]]||LI||VI||colspan=6|
 
|-
 
|-
!rowspan=8|*=!!MULT_INT_VAR_BY_INT_VAR
+
!IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_NUMBER
|0068
+
|[[0030|48]]||VF||F||colspan=6|
!rowspan=8|2
 
|GI||GI||colspan=18|
 
 
|-
 
|-
!MULT_FLOAT_VAR_BY_FLOAT_VAR
+
!IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_NUMBER
|0069||GF||GF||colspan=18|
+
|[[0031|49]]||LF||F||colspan=6|
 
|-
 
|-
!MULT_INT_LVAR_BY_INT_LVAR
+
!IS_NUMBER_GREATER_OR_EQUAL_TO_FLOAT_VAR
|006A||LI||LI||colspan=18|
+
|[[0032|50]]||F||VF||colspan=6|
 
|-
 
|-
!MULT_FLOAT_LVAR_BY_FLOAT_LVAR
+
!IS_NUMBER_GREATER_OR_EQUAL_TO_FLOAT_LVAR
|006B||LF||LF||colspan=18|
+
|[[0033|51]]||F||LF||colspan=6|
 
|-
 
|-
!MULT_INT_VAR_BY_INT_LVAR
+
!IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_FLOAT_VAR
|006C||GI||LI||colspan=18|
+
|[[0034|52]]||VF||VF||colspan=6|
 
|-
 
|-
!MULT_FLOAT_VAR_BY_FLOAT_LVAR
+
!IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_FLOAT_LVAR
|006D||GF||LF||colspan=18|
+
|[[0035|53]]||LF||LF||colspan=6|
 
|-
 
|-
!MULT_INT_LVAR_BY_INT_VAR
+
!IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_FLOAT_LVAR
|006E||LI||GI||colspan=18|
+
|[[0036|54]]||VF||LF||colspan=6|
 
|-
 
|-
!MULT_FLOAT_LVAR_BY_FLOAT_VAR
+
!IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_FLOAT_VAR
|006F||LF||GF||colspan=18|
+
|[[0037|55]]||LF||VF||colspan=6|
 
|-
 
|-
!rowspan=8|/=!!DIV_INT_VAR_BY_INT_VAR
+
!rowspan=10|=<br/>IS_THING_EQUAL_TO_THING!!IS_INT_VAR_EQUAL_TO_NUMBER
|0070
+
|[[0038|56]]
!rowspan=8|2
+
!rowspan=10|2
|GI||GI||colspan=18|
+
|VI||I||colspan=6|
 
|-
 
|-
!DIV_FLOAT_VAR_BY_FLOAT_VAR
+
!IS_INT_LVAR_EQUAL_TO_NUMBER
|0071||GF||GF||colspan=18|
+
|[[0039|57]]||LI||I||colspan=6|
 
|-
 
|-
!DIV_INT_LVAR_BY_INT_LVAR
+
!IS_INT_VAR_EQUAL_TO_INT_VAR
|0072||LI||LI||colspan=18|
+
|[[003A|58]]||VI||VI||colspan=6|
 
|-
 
|-
!DIV_FLOAT_LVAR_BY_FLOAT_LVAR
+
!IS_INT_LVAR_EQUAL_TO_INT_LVAR
|0073||LF||LF||colspan=18|
+
|[[003B|59]]||LI||LI||colspan=6|
 
|-
 
|-
!DIV_INT_VAR_BY_INT_LVAR
+
!IS_INT_VAR_EQUAL_TO_INT_LVAR
|0074||GI||LI||colspan=18|
+
|[[003C|60]]||VI||LI||colspan=6|
 
|-
 
|-
!DIV_FLOAT_VAR_BY_FLOAT_LVAR
+
!IS_FLOAT_VAR_EQUAL_TO_NUMBER
|0075||GF||LF||colspan=18|
+
|[[0042|66]]||VF||F||colspan=6|
 
|-
 
|-
!DIV_INT_LVAR_BY_INT_VAR
+
!IS_FLOAT_LVAR_EQUAL_TO_NUMBER
|0076||LI||GI||colspan=18|
+
|[[0043|67]]||LF||F||colspan=6|
 
|-
 
|-
!DIV_FLOAT_LVAR_BY_FLOAT_VAR
+
!IS_FLOAT_VAR_EQUAL_TO_FLOAT_VAR
|0077||LF||GF||colspan=18|
+
|[[0044|68]]||VF||VF||colspan=6|
 
|-
 
|-
!rowspan=6|+=@!!ADD_TIMED_VAL_TO_FLOAT_VAR
+
!IS_FLOAT_LVAR_EQUAL_TO_FLOAT_LVAR
|0078
+
|[[0045|69]]||LF||LF||colspan=6|
!rowspan=6|2
 
|GF||FV||colspan=18|
 
 
|-
 
|-
!ADD_TIMED_VAL_TO_FLOAT_LVAR
+
!IS_FLOAT_VAR_EQUAL_TO_FLOAT_LVAR
|0079||LF||FV||colspan=18|
+
|[[0046|70]]||VF||LF||colspan=6|
 
|-
 
|-
!ADD_TIMED_FLOAT_VAR_TO_FLOAT_VAR
+
!rowspan=10|NOT =<br/>IS_THING_NOT_EQUAL_TO_THING!!IS_INT_VAR_NOT_EQUAL_TO_NUMBER
|007A||GF||GF||colspan=18|
+
|[[003D|61]]
 +
!rowspan=10|2
 +
|VI||I||colspan=6|
 
|-
 
|-
!ADD_TIMED_FLOAT_LVAR_TO_FLOAT_LVAR
+
!IS_INT_LVAR_NOT_EQUAL_TO_NUMBER
|007B||LF||LF||colspan=18|
+
|[[003E|62]]||LI||I||colspan=6|
 
|-
 
|-
!ADD_TIMED_FLOAT_LVAR_TO_FLOAT_VAR
+
!IS_INT_VAR_NOT_EQUAL_TO_INT_VAR
|007C||LF||GF||colspan=18|
+
|[[003F|63]]||VI||VI||colspan=6|
 +
 
 
|-
 
|-
!ADD_TIMED_FLOAT_VAR_TO_FLOAT_LVAR
+
!IS_INT_LVAR_NOT_EQUAL_TO_INT_LVAR
|007D||GF||LF||colspan=18|
+
|[[0040|64]]||LI||LI||colspan=6|
 
|-
 
|-
!rowspan=6|-=@!!SUB_TIMED_VAL_FROM_FLOAT_VAR
+
!IS_INT_VAR_NOT_EQUAL_TO_INT_LVAR
|007E
+
|[[0041|65]]||VI||LI||colspan=6|
!rowspan=6|2
 
|GF||FV||colspan=18|
 
 
|-
 
|-
!SUB_TIMED_VAL_FROM_FLOAT_LVAR
+
!IS_FLOAT_VAR_NOT_EQUAL_TO_NUMBER
|007F||LF||FV||colspan=18|
+
|[[0047|71]]||VF||F||colspan=6|
 
|-
 
|-
!SUB_TIMED_FLOAT_VAR_FROM_FLOAT_VAR
+
!IS_FLOAT_LVAR_NOT_EQUAL_TO_NUMBER
|0080||GF||GF||colspan=18|
+
|[[0048|72]]||LF||F||colspan=6|
 
|-
 
|-
!SUB_TIMED_FLOAT_LVAR_FROM_FLOAT_LVAR
+
!IS_FLOAT_VAR_NOT_EQUAL_TO_FLOAT_VAR
|0081||LF||LF||colspan=18|
+
|[[0049|73]]||VF||VF||colspan=6|
 
|-
 
|-
!SUB_TIMED_FLOAT_LVAR_FROM_FLOAT_VAR
+
!IS_FLOAT_LVAR_NOT_EQUAL_TO_FLOAT_LVAR
|0082||LF||GF||colspan=18|
+
|[[004A|74]]||LF||LF||colspan=6|
 
|-
 
|-
!SUB_TIMED_FLOAT_VAR_FROM_FLOAT_LVAR
+
!IS_FLOAT_VAR_NOT_EQUAL_TO_FLOAT_LVAR
|0083||GF||LF||colspan=18|
+
|[[004B|75]]||VF||LF||colspan=6|
 
|-
 
|-
!rowspan=8|=!!SET_VAR_INT_TO_VAR_INT
+
!colspan=2|GOTO_IF_FALSE{{ref|statem|[*]}}
|0084|
+
|[[004D|77]]
!rowspan=8|2
+
!1
|GI||GI||colspan=18|
+
|R||colspan=7|
 
|-
 
|-
!SET_LVAR_INT_TO_LVAR_INT
+
!colspan=2|TERMINATE_THIS_SCRIPT
|0085||LI||LI||colspan=18|
+
|rowspan=2|[[004E|78]]
 +
!rowspan=2|0
 +
|rowspan=2 colspan=8|
 
|-
 
|-
!SET_VAR_FLOAT_TO_VAR_FLOAT
+
!colspan=2|MISSION_END
|0086||GF||GF||colspan=18|
 
 
|-
 
|-
!SET_LVAR_FLOAT_TO_LVAR_FLOAT
+
!colspan=2|START_NEW_SCRIPT{{ref|undarg|[*]}}
|0087||LF||LF||colspan=18|
+
|[[004F|79]]
 +
!1+l
 +
|R||colspan=7|AM
 
|-
 
|-
!SET_VAR_FLOAT_TO_LVAR_FLOAT
+
|colspan=2|GOSUB
|0088||GF||LF||colspan=18|
+
|[[0050|80]]
 +
!1
 +
|R||colspan=7|
 
|-
 
|-
!SET_LVAR_FLOAT_TO_VAR_FLOAT
+
|colspan=2|RETURN
|0089||LF||GF||colspan=18|
+
|[[0051|81]]
 +
!0
 +
|colspan=8|
 
|-
 
|-
!SET_VAR_INT_TO_LVAR_INT
+
!rowspan=6|+=@<br/>+@<br/>ADD_THING_TO_THING_TIMED!!ADD_TIMED_VAL_TO_FLOAT_VAR
|008A||GI||LI||colspan=18|
+
|[[0078|120]]
 +
!rowspan=6|2
 +
|VF||F||colspan=6|
 
|-
 
|-
!SET_LVAR_INT_TO_VAR_INT
+
!ADD_TIMED_VAL_TO_FLOAT_LVAR
|008B||LI||GI||colspan=18|
+
|[[0079|121]]||LF||F||colspan=6|
 
|-
 
|-
!rowspan=8|=#!!CSET_VAR_INT_TO_VAR_FLOAT
+
!ADD_TIMED_FLOAT_VAR_TO_FLOAT_VAR
|008C|
+
|[[007A|122]]||VF||VF||colspan=6|
!rowspan=8|2
 
|GI||GF||colspan=18|
 
 
|-
 
|-
!CSET_VAR_FLOAT_TO_VAR_INT
+
!ADD_TIMED_FLOAT_LVAR_TO_FLOAT_LVAR
|008D||GF||GI||colspan=18|
+
|[[007B|123]]||LF||LF||colspan=6|
 
|-
 
|-
!CSET_LVAR_INT_TO_VAR_FLOAT
+
!ADD_TIMED_FLOAT_LVAR_TO_FLOAT_VAR
|008E||LI||GF||colspan=18|
+
|[[007C|124]]||LF||VF||colspan=6|
 
|-
 
|-
!CSET_LVAR_FLOAT_TO_VAR_INT
+
!ADD_TIMED_FLOAT_VAR_TO_FLOAT_LVAR
|008F||LF||GI||colspan=18|
+
|[[007D|125]]||VF||LF||colspan=6|
 
|-
 
|-
!CSET_VAR_INT_TO_LVAR_FLOAT
+
!rowspan=6|-=@<br/>-@<br/>SUB_THING_FROM_THING_TIMED!!SUB_TIMED_VAL_FROM_FLOAT_VAR
|0090||GI||LF||colspan=18|
+
|[[007E|126]]
 +
!rowspan=6|2
 +
|VF||F||colspan=6|
 +
|-
 +
!SUB_TIMED_VAL_FROM_FLOAT_LVAR
 +
|[[007F|127]]||LF||F||colspan=6|
 +
|-
 +
!SUB_TIMED_FLOAT_VAR_FROM_FLOAT_VAR
 +
|[[0080|128]]||VF||VF||colspan=6|
 +
|-
 +
!SUB_TIMED_FLOAT_LVAR_FROM_FLOAT_LVAR
 +
|[[0081|129]]||LF||LF||colspan=6|
 +
|-
 +
!SUB_TIMED_FLOAT_LVAR_FROM_FLOAT_VAR
 +
|[[0082|130]]||LF||VF||colspan=6|
 +
|-
 +
!SUB_TIMED_FLOAT_VAR_FROM_FLOAT_LVAR
 +
|[[0083|131]]||VF||LF||colspan=6|
 +
|-
 +
!rowspan=8|=#<br/>CSET<br/>!!CSET_VAR_INT_TO_VAR_FLOAT
 +
|[[008C|140]]
 +
!rowspan=8|2
 +
|VI||VF||colspan=6|
 +
|-
 +
!CSET_VAR_FLOAT_TO_VAR_INT
 +
|[[008D|141]]||VF||VI||colspan=6|
 +
|-
 +
!CSET_LVAR_INT_TO_VAR_FLOAT
 +
|[[008E|142]]||LI||VF||colspan=6|
 +
|-
 +
!CSET_LVAR_FLOAT_TO_VAR_INT
 +
|[[008F|143]]||LF||VI||colspan=6|
 +
|-
 +
!CSET_VAR_INT_TO_LVAR_FLOAT
 +
|[[0090|144]]||VI||LF||colspan=6|
 
|-
 
|-
 
!CSET_VAR_FLOAT_TO_LVAR_INT
 
!CSET_VAR_FLOAT_TO_LVAR_INT
|0091||GF||LI||colspan=18|
+
|[[0091|145]]||VF||LI||colspan=6|
 
|-
 
|-
 
!CSET_LVAR_INT_TO_LVAR_FLOAT
 
!CSET_LVAR_INT_TO_LVAR_FLOAT
|0092||LI||LF||colspan=18|
+
|[[0092|146]]||LI||LF||colspan=6|
 
|-
 
|-
 
!CSET_LVAR_FLOAT_TO_LVAR_INT
 
!CSET_LVAR_FLOAT_TO_LVAR_INT
|0093||LF||LI||colspan=18|
+
|[[0093|147]]||LF||LI||colspan=6|
 
|-
 
|-
 
!rowspan=4|ABS!!ABS_VAR_INT
 
!rowspan=4|ABS!!ABS_VAR_INT
|0094
+
|[[0094|148]]
 
!rowspan=4|1
 
!rowspan=4|1
|GI||colspan=19|
+
|VI||colspan=7|
 
|-
 
|-
 
!ABS_LVAR_INT
 
!ABS_LVAR_INT
|0095||LI||colspan=19|
+
|[[0095|149]]||LI||colspan=7|
 
|-
 
|-
 
!ABS_VAR_FLOAT
 
!ABS_VAR_FLOAT
|0096||GF||colspan=19|
+
|[[0096|150]]||VF||colspan=7|
 
|-
 
|-
 
!ABS_LVAR_FLOAT
 
!ABS_LVAR_FLOAT
|0097||LF||colspan=19|
+
|[[0097|151]]||LF||colspan=7|
 
|-
 
|-
!colspan=2|ANDOR{{ref|statem|[*]}}
+
!colspan=2|VAR_INT{{ref|defvar|[*]}}
|00D6
+
|[[00C7|199]]
!1
+
!n
|VI||colspan=19|
+
|VI||colspan=7|VIO
 
|-
 
|-
!colspan=2|LAUNCH_MISSION
+
!colspan=2|VAR_FLOAT{{ref|defvar|[*]}}
|00D7
+
|[[00C8|200]]
!1
+
!n
|VO||colspan=19|
+
|VF||colspan=7|VFO
 
|-
 
|-
|colspan=25|{{icon|3}} {{icon|vc}} {{icon|sa}}
+
!colspan=2|LVAR_INT{{ref|defvar|[*]}}
 +
|[[00C9|201]]
 +
!n
 +
|LI||colspan=7|LIO
 
|-
 
|-
!colspan=2|LOAD_AND_LAUNCH_MISSION
+
!colspan=2|LVAR_FLOAT{{ref|defvar|[*]}}
|0417
+
|[[00CA|202]]
!1
+
!n
|VO||colspan=19|
+
|LF||colspan=7|LFO
 
|-
 
|-
|colspan=25|{{icon|3}} {{icon|vc}}
+
!colspan=2|{{{ref|embdsc|[*]}}
 +
|[[00CB|203]]
 +
!0
 +
|colspan=8|
 
|-
 
|-
!colspan=2|GOSUB_FILE
+
!colspan=2|}{{ref|embdsc|[*]}}
|02CD
+
|[[00CC|204]]
!2
+
!0
|VO||VO||colspan=18|
+
|colspan=8|
 
|-
 
|-
|colspan=25|{{icon|vc}} {{icon|sa}}
+
!colspan=2|IF{{ref|statem|[*]}}
 +
|[[00CF|207]]
 +
!1
 +
|I||colspan=7|
 
|-
 
|-
!rowspan=4|=!!IS_INT_VAR_EQUAL_TO_CONSTANT
+
!colspan=2|ELSE{{ref|statem|[*]}}
|04A3
+
|[[00D1|209]]
!rowspan=4|2
+
!0
|GC||VC||colspan=18|
+
|colspan=8|
 
|-
 
|-
!IS_INT_LVAR_EQUAL_TO_CONSTANT
+
!colspan=2|ENDIF{{ref|statem|[*]}}
|04A4||LC||VC||colspan=18|
+
|[[00D2|210]]
 +
!0
 +
|colspan=8|
 
|-
 
|-
!SET_VAR_INT_TO_CONSTANT
+
!colspan=2|WHILE{{ref|statem|[*]}}
|04AE||GC||VC||colspan=18|
+
|[[00D3|211]]
 +
!1
 +
|I||colspan=7|
 
|-
 
|-
!SET_LVAR_INT_TO_CONSTANT
+
!colspan=2|ENDWHILE{{ref|statem|[*]}}
|04AF||LC||VC||colspan=18|
+
|[[00D5|213]]
 +
!0
 +
|colspan=8|
 
|-
 
|-
!rowspan=4|>!!IS_INT_VAR_GREATER_THAN_CONSTANT
+
|colspan=12|{{icon|t}}
|04B0
 
!rowspan=4|2
 
|GC||VC||colspan=18|
 
 
|-
 
|-
!IS_INT_LVAR_GREATER_THAN_CONSTANT
+
!colspan=2|ANDOR{{ref|statem|[*]}}
|04B1||LC||VC||colspan=18|
+
|[[00D6|214]]
 +
!1
 +
|I||colspan=7|
 
|-
 
|-
!IS_CONSTANT_GREATER_THAN_INT_VAR
+
!colspan=2|LAUNCH_MISSION
|04B2
+
|[[00D7|215]]
|VC||GC||colspan=18|
+
!1
 +
|R||colspan=7|
 
|-
 
|-
!IS_CONSTANT_GREATER_THAN_INT_LVAR
+
|colspan=2|START_CUTSCENE
|04B3||VC||LC||colspan=18|
+
|[[02E7|743]]
 +
!0
 +
|colspan=8|
 
|-
 
|-
!rowspan=4|>=!!IS_INT_VAR_GREATER_OR_EQUAL_TO_CONSTANT
+
!colspan=2|PLAYER_MADE_PROGRESS
|04B4
+
|[[030C|780]]
!rowspan=4|2
+
!1
|GC||VC||colspan=18|
+
|I||colspan=7|
 
|-
 
|-
!IS_INT_LVAR_GREATER_OR_EQUAL_TO_CONSTANT
+
!colspan=2|SET_PROGRESS_TOTAL
|04B5||LC||VC||colspan=18|
+
|[[030D|781]]
 +
!1
 +
|I||colspan=7|
 
|-
 
|-
!IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_VAR
+
|colspan=2|REGISTER_MISSION_GIVEN
|04B6
+
|[[0317|791]]
|VC||GV||colspan=18|
+
!0
 +
|colspan=8|
 
|-
 
|-
!IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_LVAR
+
!colspan=2|REGISTER_MISSION_PASSED
|04B7||VC||LC||colspan=18|
+
|[[0318|792]]
 +
!1
 +
|T||colspan=7|
 
|-
 
|-
|colspan=25|{{icon|sa}}
+
!colspan=2|SCRIPT_NAME
 +
|[[03A4|932]]
 +
!1
 +
|T||colspan=7|
 
|-
 
|-
!rowspan=20|=!!rowspan=3|SET_ANY_TEXT_LABEL_TO_VAR_TEXT_LABEL{{ref|likely|[*]}}
+
!colspan=2|LOAD_AND_LAUNCH_MISSION
|rowspan=3|05A9
+
|[[0416|1046]]
!rowspan=20|2
+
!1
|GT||VT||colspan=18|
+
|R||colspan=7|
 
|-
 
|-
|GT||GT||colspan=18|
+
!colspan=2|LOAD_AND_LAUNCH_MISSION_INTERNAL
 +
|[[0417|1047]]
 +
!1
 +
|I||colspan=7|
 
|-
 
|-
|GT||LT||colspan=18|
+
!colspan=2|SET_TOTAL_NUMBER_OF_MISSIONS
 +
|[[042C|1068]]
 +
!1
 +
|I||colspan=7|
 
|-
 
|-
!rowspan=3|SET_ANY_TEXT_LABEL_TO_LVAR_TEXT_LABEL{{ref|likely|[*]}}
+
!colspan=2|REGISTER_ODDJOB_MISSION_PASSED
|rowspan=3|05AA
+
|[[0595|1429]]
|LT||VT||colspan=18|
+
!0
 +
|colspan=8|
 
|-
 
|-
|LT||GT||colspan=18|
+
|colspan=12|{{icon|vc}} {{icon|sa}} {{icon|lcs}}
 
|-
 
|-
|LT||LT||colspan=18|
+
!colspan=2|REPEAT{{ref|statem|[*]}}
 +
|[[00CD|205]]
 +
!2
 +
|I||VLI||colspan=6|
 
|-
 
|-
!rowspan=3|IS_TEXT_LABEL_VAR_EQUAL_TO_TEXT_LABEL_ANY{{ref|likely|[*]}}
+
!colspan=2|ENDREPEAT{{ref|statem|[*]}}
|rowspan=3|05AD
+
|[[00CE|206]]
|GT||VT||colspan=18|
+
!0
 +
|colspan=8|
 
|-
 
|-
|GT||GT||colspan=18|
+
|colspan=12|{{icon|3}} {{icon|vc}}
 
|-
 
|-
|GT||LT||colspan=18|
+
!colspan=2|CREATE_COLLECTABLE1
 +
|[[02EC|748]]
 +
!1
 +
|I||colspan=7|
 
|-
 
|-
!rowspan=3|IS_TEXT_LABEL_LVAR_EQUAL_TO_TEXT_LABEL_ANY{{ref|likely|[*]}}
+
!colspan=2|SET_COLLECTABLE1_TOTAL
|rowspan=3|05AE
+
|[[02ED|749]]
|LT||VT||colspan=18|
+
!1
 +
|I||colspan=7|
 
|-
 
|-
|LT||GT||colspan=18|
+
|colspan=12|{{icon|3}} {{icon|lcs}}
 
|-
 
|-
|LT||LT||colspan=18|
+
!colspan=2|GOTO_IF_TRUE{{ref|statem|[*]}}
 +
|[[004C|76]]
 +
!1
 +
|R||colspan=7|
 
|-
 
|-
!rowspan=3|SET_ANY_STRING_TO_VAR_STRING{{ref|likely|[*]}}
+
|colspan=12|{{icon|vc}} {{icon|sa}}
|rowspan=3|06D1
 
|GS||VS||colspan=18|
 
 
|-
 
|-
|GS||GS||colspan=18|
+
!rowspan=2|=<br/>IS_THING_EQUAL_TO_THING!!IS_INT_VAR_EQUAL_TO_CONSTANT
 +
|[[04A3|1187]]
 +
!rowspan=2|2
 +
|VI||C||colspan=6|
 
|-
 
|-
|GS||LS||colspan=18|
+
!IS_INT_LVAR_EQUAL_TO_CONSTANT
 +
|[[04A4|1188]]||LI||C||colspan=6|
 
|-
 
|-
!rowspan=3|SET_ANY_STRING_TO_LVAR_STRING{{ref|likely|[*]}}
+
!rowspan=2|=<br/>SET!!SET_VAR_INT_TO_CONSTANT
|rowspan=3|06D2
+
|[[04AE|1198]]
|LS||VS||colspan=18|
+
!rowspan=2|2
 +
|VI||C||colspan=6|
 
|-
 
|-
|LS||GS||colspan=18|
+
!SET_LVAR_INT_TO_CONSTANT
 +
|[[04AF|1199]]||LI||C||colspan=6|
 
|-
 
|-
|LS||LS||colspan=18|
+
!rowspan=4|><br/><=<br/>IS_THING_GREATER_THAN_THING!!IS_INT_VAR_GREATER_THAN_CONSTANT
 +
|[[04B0|1200]]
 +
!rowspan=4|2
 +
|VI||C||colspan=6|
 
|-
 
|-
!IS_INT_LVAR_EQUAL_TO_INT_VAR
+
!IS_INT_LVAR_GREATER_THAN_CONSTANT
|07D6||LI||GI||colspan=18|
+
|[[04B1|1201]]||LI||C||colspan=6|
 
|-
 
|-
!IS_FLOAT_LVAR_EQUAL_TO_FLOAT_VAR
+
!IS_CONSTANT_GREATER_THAN_INT_VAR
|07D7||LF||GF||colspan=18|
+
|[[04B2|1202]]||C||VI||colspan=6|
 
|-
 
|-
!rowspan=2|IS_TEXT_LABEL_NULL!!IS_TEXT_LABEL_NULL_VAR_TEXT_LABEL{{ref|likely|[*]}}
+
!IS_CONSTANT_GREATER_THAN_INT_LVAR
|0844
+
|[[04B3|1203]]||C||LI||colspan=6|
!rowspan=2|1
 
|GT||colspan=19|
 
 
|-
 
|-
!IS_TEXT_LABEL_NULL_LVAR_TEXT_LABEL{{ref|likely|[*]}}
+
!rowspan=4|>=<br/><<br/>IS_THING_GREATER_OR_EQUAL_TO_THING!!IS_INT_VAR_GREATER_OR_EQUAL_TO_CONSTANT
|0845||LT||colspan=19|
+
|[[04B4|1204]]
 +
!rowspan=4|2
 +
|VI||C||colspan=6|
 
|-
 
|-
!rowspan=2|IS_STRING_NULL!!IS_STRING_NULL_VAR_STRING{{ref|likely|[*]}}
+
!IS_INT_LVAR_GREATER_OR_EQUAL_TO_CONSTANT
|0846
+
|[[04B5|1205]]||LI||C||colspan=6|
!rowspan=2|1
 
|GS||colspan=19|
 
 
|-
 
|-
!IS_STRING_NULL_LVAR_STRING{{ref|likely|[*]}}
+
!IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_VAR
|0847||LS||colspan=19|
+
|[[04B6|1206]]||C||VI||colspan=6|
 
|-
 
|-
!rowspan=2 colspan=2|INIT_TABLE_OF_GOTO{{ref|statem|[*]}}{{ref|likely|[*]}}
+
!IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_LVAR
|rowspan=2|0871
+
|[[04B7|1207]]||C||LI||colspan=6|
!rowspan=2|18
 
|GI||VI||VI||VO||VI||VO||VI||VO||VI||V0||VI||VO||VI||VO||VI||VO||VI||VO||colspan=2|
 
 
|-
 
|-
|LI||VI||VI||VO||VI||VO||VI||VO||VI||VO||VI||VO||VI||VO||VI||VO||VI||VO||colspan=2|
+
!colspan=2|LOAD_AND_LAUNCH_MISSION_EXCLUSIVE
 +
|[[0515|1301]]
 +
!1
 +
|R||colspan=7|
 
|-
 
|-
!colspan=2|APPEND_GOTO_TO_TABLE{{ref|statem|[*]}}{{ref|likely|[*]}}
+
|colspan=12|{{icon|3}}
|0872
 
!18
 
|VI||VO||VI||VO||VI||VO||VI||VO||VI||VO||VI||VO||VI||VO||VI||VO||VI||VO||colspan=2|
 
 
|-
 
|-
!rowspan=6|IS_BIT_SET!!IS_BIT_SET_VAR_INT_NUMBER{{ref|likely|[*]}}
+
!colspan=2|IFNOT{{ref|statem|[*]}}
|08B4
+
|[[00D0|208]]
!rowspan=6|2
+
!1
|GI||VN||colspan=18|
+
|I||colspan=7|
 
|-
 
|-
!IS_BIT_SET_VAR_INT_VAR_INT{{ref|likely|[*]}}
+
!colspan=2|WHILENOT{{ref|statem|[*]}}
|08B5||GI||GI||colspan=18|
+
|[[00D4|212]]
 +
!1
 +
|I||colspan=7|
 
|-
 
|-
!IS_BIT_SET_VAR_INT_LVAR_INT{{ref|likely|[*]}}
+
!colspan=2|GOSUB_FILE
|08B6||GI||LI||colspan=18|
+
|[[02CD|717]]
|-
+
!2
!IS_BIT_SET_LVAR_INT_NUMBER{{ref|likely|[*]}}
+
|R||R||colspan=6|
|08B7||LI||VN||colspan=18|
 
 
|-
 
|-
!IS_BIT_SET_LVAR_INT_VAR_INT{{ref|likely|[*]}}
+
|colspan=12|{{icon|sa}}
|08B8||LI||GI||colspan=18|
 
 
|-
 
|-
!IS_BIT_SET_LVAR_INT_LVAR_INT{{ref|likely|[*]}}
+
!rowspan=2|=<br/>SET!!SET_VAR_TEXT_LABEL
|08B9||LI||LI||colspan=18|
+
|[[05A9|1449]]
 +
!rowspan=2|2
 +
|VT||AT||colspan=6|
 
|-
 
|-
!rowspan=6|SET_BIT_SET!!SET_BIT_VAR_INT_NUMBER{{ref|likely|[*]}}
+
!SET_LVAR_TEXT_LABEL
|08BA
+
|[[05AA|1450]]||LT||AT||colspan=6|
!rowspan=6|2
 
|GI||VN||colspan=18|
 
 
|-
 
|-
!SET_BIT_VAR_INT_VAR_INT{{ref|likely|[*]}}
+
!colspan=2|VAR_TEXT_LABEL{{ref|defvar|[*]}}
|08BB||GI||GI||colspan=18|
+
|[[05AB|1451]]
 +
!n
 +
|VT||colspan=7|VTO
 
|-
 
|-
!SET_BIT_VAR_INT_LVAR_INT{{ref|likely|[*]}}
+
!colspan=2|LVAR_TEXT_LABEL{{ref|defvar|[*]}}
|08BC||GI||LI||colspan=18|
+
|[[05AC|1452]]
 +
!n
 +
|LT||colspan=7|LTO
 
|-
 
|-
!SET_BIT_LVAR_INT_NUMBER{{ref|likely|[*]}}
+
!rowspan=2|=<br/>IS_THING_EQUAL_TO_THING!!IS_VAR_TEXT_LABEL_EQUAL_TO_TEXT_LABEL
|08BD||LI||VN||colspan=18|
+
|[[05AD|1453]]
 +
!rowspan=2|2
 +
|VT||AT||colspan=6|
 
|-
 
|-
!SET_BIT_LVAR_INT_VAR_INT{{ref|likely|[*]}}
+
!IS_LVAR_TEXT_LABEL_EQUAL_TO_TEXT_LABEL
|08BE||LI||GI||colspan=18|
+
|[[05AE|1454]]||LT||AT||colspan=6|
 
|-
 
|-
!SET_BIT_LVAR_INT_LVAR_INT{{ref|likely|[*]}}
+
!rowspan=2|=<br/>SET!!SET_VAR_TEXT_LABEL16
|08BF||LI||LI||colspan=18|
+
|[[06D1|1745]]
 +
!rowspan=2|2
 +
|VT16||AT16||colspan=6|
 
|-
 
|-
!rowspan=6|CLEAR_BIT_SET!!CLEAR_BIT_VAR_INT_NUMBER{{ref|likely|[*]}}
+
!SET_LVAR_TEXT_LABEL16
|08C0
+
|[[06D2|1476]]||LT16||AT16||colspan=6|
!rowspan=6|2
 
|GI||VN||colspan=18|
 
 
|-
 
|-
!CLEAR_BIT_VAR_INT_VAR_INT{{ref|likely|[*]}}
+
!colspan=2|VAR_TEXT_LABEL16{{ref|defvar|[*]}}
|08C1||GI||GI||colspan=18|
+
|[[06D3|1477]]
 +
!n
 +
|VT16||colspan=7|VT16O
 
|-
 
|-
!CLEAR_BIT_VAR_INT_LVAR_INT{{ref|likely|[*]}}
+
!colspan=2|LVAR_TEXT_LABEL16{{ref|defvar|[*]}}
|08C2||GI||LI||colspan=18|
+
|[[06D4|1478]]
 +
!n
 +
|LT16||colspan=7|LT16O
 
|-
 
|-
!CLEAR_BIT_LVAR_INT_NUMBER{{ref|likely|[*]}}
+
!rowspan=2|=<br/>IS_THING_EQUAL_TO_THING!!IS_INT_LVAR_EQUAL_TO_INT_VAR
|08C3||LI||VN||colspan=18|
+
|[[07D6|2006]]
 +
!rowspan=2|2
 +
|LI||VI||colspan=6|
 
|-
 
|-
!CLEAR_BIT_LVAR_INT_VAR_INT{{ref|likely|[*]}}
+
!IS_FLOAT_LVAR_EQUAL_TO_FLOAT_VAR
|08C4||LI||GI||colspan=18|
+
|[[07D7|2007]]||LF||VF||colspan=6|
 
|-
 
|-
!CLEAR_BIT_LVAR_INT_LVAR_INT{{ref|likely|[*]}}
+
!rowspan=4|IS_EMPTY{{ref|likely|[*]}}!!IS_VAR_TEXT_LABEL_EMPTY
|08C5||LI||LI||colspan=18|
+
|[[0844|2116]]
 +
!rowspan=4|1
 +
|VT||colspan=7|
 
|-
 
|-
!rowspan=6|=<br/>COMPARE_STRING{{ref|likely|[*]}}!!rowspan=3|IS_STRING_VAR_EQUAL_TO_STRING_ANY{{ref|likely|[*]}}<br/>COMPARE_STRING_VAR_STRING_ANY_STRING{{ref|likely|[*]}}
+
!IS_LVAR_TEXT_LABEL_EMPTY
|rowspan=3|08F9
+
|[[0845|2117]]||LT||colspan=7|
!rowspan=6|2
 
|GS||VS||colspan=18|
 
 
|-
 
|-
|GS||GS||colspan=18|
+
!IS_VAR_TEXT_LABEL16_EMPTY
 +
|[[0846|2118]]||VT16||colspan=7|
 
|-
 
|-
|GS||LS||colspan=18|
+
!IS_LVAR_TEXT_LABEL16_EMPTY
 +
|[[0847|2119]]||LT16||colspan=7|
 
|-
 
|-
!rowspan=3|IS_STRING_LVAR_EQUAL_TO_STRING_ANY{{ref|likely|[*]}}<br/>COMPARE_STRING_LVAR_STRING_ANY_STRING{{ref|likely|[*]}}
+
!colspan=2|SWITCH{{ref|statem|[*]}}
|rowspan=3|08FA
+
|[[0848|2120]]
|LS||VS||colspan=18|
+
!1
 +
|VLI||colspan=7|
 
|-
 
|-
|LS||GS||colspan=18|
+
!colspan=2|ENDSWITCH{{ref|statem|[*]}}
 +
|[[0849|2121]]
 +
!0
 +
|colspan=8|
 
|-
 
|-
|LS||LS||colspan=18|
+
!colspan=2|CASE{{ref|statem|[*]}}
|-
+
|[[084A|2122]]
|colspan=25|{{icon|lcs}}
 
|-
 
!colspan=2|GOTO_IF_TRUE{{ref|statem|[*]}}
 
|004C
 
 
!1
 
!1
|VI||colspan=19|
+
|I||colspan=7|
 
|-
 
|-
!colspan=2|RETURN_TRUE
+
!colspan=2|DEFAULT{{ref|statem|[*]}}
|00C5
+
|[[084B|2123]]
 
!0
 
!0
|colspan=20|
+
|colspan=8|
 
|-
 
|-
!colspan=2|RETURN_FALSE
+
!colspan=2|BREAK{{ref|statem|[*]}}
|00C6
+
|[[084C|2124]]
 
!0
 
!0
|colspan=20|
+
|colspan=8|
 
|-
 
|-
!colspan=2|ANDOR{{ref|statem|[*]}}
+
!rowspan=4 colspan=2|SWITCH_START{{ref|statem|[*]}}
|00DB
+
|rowspan=4|[[0871|2161]]
!1
+
!rowspan=4|18
|VI||colspan=19|
+
|rowspan=2|VI
 +
|rowspan=2|I
 +
|rowspan=2|I
 +
|rowspan=2|R
 +
|colspan=2|I||colspan=2|
 
|-
 
|-
!colspan=2|LAUNCH_MISSION
+
|colspan=2|R||colspan=2|
|00DC
 
!1
 
|VO||colspan=19|
 
 
|-
 
|-
!colspan=2|GOSUB_FILE
+
|rowspan=2|LI
|02D2
+
|rowspan=2|I
!2
+
|rowspan=2|I
|VO||VO||colspan=18|
+
|rowspan=2|R
 +
|colspan=2|I||colspan=2|
 
|-
 
|-
!colspan=2|LOAD_AND_LAUNCH_MISSION
+
|colspan=2|R||colspan=2|
|041C
 
!1
 
|VO||colspan=19|
 
 
|-
 
|-
!rowspan=4|=!!IS_INT_VAR_EQUAL_TO_CONSTANT
+
!rowspan=2 colspan=2|SWITCH_CONTINUED{{ref|statem|[*]}}
|04A8
+
|rowspan=2|[[0872|2162]]
!rowspan=4|2
+
!rowspan=2|18
|GC||VC||colspan=18|
+
|colspan=6|I
 +
|colspan=2|
 
|-
 
|-
!IS_INT_LVAR_EQUAL_TO_CONSTANT
+
|colspan=6|R
|04A9||LC||VC||colspan=18|
+
|colspan=2|
 
|-
 
|-
!SET_VAR_INT_TO_CONSTANT
+
!rowspan=6|IS_BIT_SET{{ref|likely|[*]}}!!IS_GLOBAL_VAR_BIT_SET_CONST
|04B3||GC||VC||colspan=18|
+
|[[08B4|2228]]
 +
!rowspan=6|2
 +
|VI||C||colspan=6|
 
|-
 
|-
!SET_LVAR_INT_TO_CONSTANT
+
!IS_GLOBAL_VAR_BIT_SET_VAR
|04B4||LC||VC||colspan=18|
+
|[[08B5|2229]]||VI||VI||colspan=6|
 
|-
 
|-
!rowspan=4|>!!IS_INT_VAR_GREATER_THAN_CONSTANT
+
!IS_GLOBAL_VAR_BIT_SET_LVAR
|04B5
+
|[[08B6|2230]]||VI||LI||colspan=6|
!rowspan=4|2
 
|GC||VC||colspan=18|
 
 
|-
 
|-
!IS_INT_LVAR_GREATER_THAN_CONSTANT
+
!IS_LOCAL_VAR_BIT_SET_CONST
|04B6||LC||VC||colspan=18|
+
|[[08B7|2231]]||LI||C||colspan=6|
|-
 
!IS_CONSTANT_GREATER_THAN_INT_VAR
 
|04B7||VC||GC||colspan=18|
 
 
|-
 
|-
!IS_CONSTANT_GREATER_THAN_INT_LVAR
+
!IS_LOCAL_VAR_BIT_SET_VAR
|04B8||VC||LC||colspan=18|
+
|[[08B8|2232]]||LI||VI||colspan=6|
 
|-
 
|-
!rowspan=4|>=!!IS_INT_VAR_GREATER_OR_EQUAL_TO_CONSTANT
+
!IS_LOCAL_VAR_BIT_SET_LVAR
|04B9
+
|[[08B9|2233]]||LI||LI||colspan=6|
!rowspan=4|2
 
|GC||VC||colspan=18|
 
 
|-
 
|-
!IS_INT_LVAR_GREATER_OR_EQUAL_TO_CONSTANT
+
!rowspan=6|SET_BIT{{ref|likely|[*]}}!!SET_GLOBAL_VAR_BIT_CONST
|04BA||LC||VC||colspan=18|
+
|[[08BA|2234]]
 +
!rowspan=6|2
 +
|VI||C||colspan=6|
 
|-
 
|-
!IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_VAR
+
!SET_GLOBAL_VAR_BIT_VAR
|04BB||VC||GV||colspan=18|
+
|[[08BB|2235]]||VI||VI||colspan=6|
 
|-
 
|-
!IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_LVAR
+
!SET_GLOBAL_VAR_BIT_LVAR
|04BC||VC||LC||colspan=18|
+
|[[08BC|2236]]||VI||LI||colspan=6|
 
|-
 
|-
!rowspan=2|CALL{{ref|undefa|[*]}}{{ref|argvar|[*]}}!!CALL_05AE
+
!SET_LOCAL_VAR_BIT_CONST
|05AE
+
|[[08BD|2237]]||LI||C||colspan=6|
!rowspan=2|1
 
|rowspan=2|VO
 
|rowspan=2 colspan=19|_ _ _
 
 
|-
 
|-
!CALL_05AF
+
!SET_LOCAL_VAR_BIT_VAR
|05AF
+
|[[08BE|2238]]||LI||VI||colspan=6|
 
|-
 
|-
|colspan=25|{{icon|vcs}}
+
!SET_LOCAL_VAR_BIT_LVAR
 +
|[[08BF|2239]]||LI||LI||colspan=6|
 
|-
 
|-
!rowspan=6|=!!rowspan=2|SET_ANY_INT
+
!rowspan=6|CLEAR_BIT{{ref|likely|[*]}}!!CLEAR_GLOBAL_VAR_BIT_CONST
|rowspan=2|0004
+
|[[08C0|2240]]
 
!rowspan=6|2
 
!rowspan=6|2
|GI||VI||colspan=18|
+
|VI||C||colspan=6|
 
|-
 
|-
|LI||VI||colspan=18|
+
!CLEAR_GLOBAL_VAR_BIT_VAR
 +
|[[08C1|2241]]||VI||VI||colspan=6|
 
|-
 
|-
!rowspan=2|SET_ANY_FLOAT
+
!CLEAR_GLOBAL_VAR_BIT_LVAR
|rowspan=2|0005
+
|[[08C2|2242]]||VI||LI||colspan=6|
|GF||VF||colspan=18|
 
 
|-
 
|-
|LF||VF||colspan=18|
+
!CLEAR_LOCAL_VAR_BIT_CONST
 +
|[[08C3|2243]]||LI||C||colspan=6|
 
|-
 
|-
!rowspan=2|SET_ANY_TEXT_LABEL
+
!CLEAR_LOCAL_VAR_BIT_VAR
|rowspan=2|0006
+
|[[08C4|2244]]||LI||VI||colspan=6|
|GT||VT||colspan=18|
 
 
|-
 
|-
|LT||VT||colspan=18|
+
!CLEAR_LOCAL_VAR_BIT_LVAR
 +
|[[08C5|2245]]||LI||LI||colspan=6|
 
|-
 
|-
!rowspan=4|+=!!rowspan=2|ADD_VAL_TO_INT_ANY
+
!rowspan=2|=<br/>IS_THING_EQUAL_TO_THING!!IS_VAR_TEXT_LABEL16_EQUAL_TO_TEXT_LABEL
|rowspan=2|0007
+
|[[08F9|2297]]
!rowspan=4|2
+
!rowspan=2|2
|GI||VI||colspan=18|
+
|VT16||AT16||colspan=6|
 
|-
 
|-
|LI||VI||colspan=18|
+
!IS_LVAR_TEXT_LABEL16_EQUAL_TO_TEXT_LABEL
 +
|[[08FA|2298]]||LT16||AT16||colspan=6|
 
|-
 
|-
!rowspan=2|ADD_VAL_TO_FLOAT_ANY
+
!rowspan=2|STRING_CAT{{ref|likely|[*]}}!!STRING_CAT16
|rowspan=2|0008
+
|[[098B|2443]]
|GF||VF||colspan=18|
+
!rowspan=2|3
 +
|VT16||VT16||VT16||colspan=5|
 
|-
 
|-
|LF||VF||colspan=18|
+
!STRING_CAT8
 +
|[[098C|2444]]||VT||VT||VT||colspan=5|
 
|-
 
|-
!rowspan=4|-=!!rowspan=2|SUB_VAL_FROM_INT_ANY
+
|colspan=12|{{icon|lcs}}
|rowspan=2|0009
 
!rowspan=4|2
 
|GI||VI||colspan=18|
 
 
|-
 
|-
|LI||VI||colspan=18|
+
|colspan=2|RETURN_TRUE
 +
|[[00C5|197]]
 +
!0
 +
|colspan=8|
 
|-
 
|-
!rowspan=2|SUB_VAL_FROM_FLOAT_ANY
+
|colspan=2|RETURN_FALSE
|rowspan=2|000A
+
|[[00C6|198]]
|GF||VF||colspan=18|
+
!0
 +
|colspan=8|
 
|-
 
|-
|LF||VF||colspan=18|
+
!colspan=2|SWITCH{{ref|statem|[*]}}{{ref|posngs|[*]}}
 +
|214
 +
!1
 +
|VLI||colspan=7|
 
|-
 
|-
!rowspan=4|*=!!rowspan=2|MULT_INT_ANY_BY_VAL
+
!colspan=2|ENDSWITCH{{ref|statem|[*]}}{{ref|posngs|[*]}}
|rowspan=2|000B
+
|215
!rowspan=4|2
+
!0
|GI||VI||colspan=18|
+
|colspan=8|
 
|-
 
|-
|LI||VI||colspan=18|
+
!colspan=2|CASE{{ref|statem|[*]}}{{ref|posngs|[*]}}
 +
|216
 +
!1
 +
|I||colspan=7|
 
|-
 
|-
!rowspan=2|MULT_FLOAT_ANY_BY_VAL
+
!colspan=2|DEFAULT{{ref|statem|[*]}}{{ref|posngs|[*]}}
|rowspan=2|000C
+
|217
|GF||VF||colspan=18|
+
!0
 +
|colspan=8|
 
|-
 
|-
|LF||VF||colspan=18|
+
!colspan=2|BREAK{{ref|statem|[*]}}{{ref|posngs|[*]}}
 +
|218
 +
!0
 +
|colspan=8|
 
|-
 
|-
!rowspan=4|/=!!rowspan=2|DIV_INT_ANY_BY_VAL
+
!colspan=2|ANDOR{{ref|statem|[*]}}
|rowspan=2|000D
+
|219
!rowspan=4|2
+
!1
|GI||VI||colspan=18|
+
|I||colspan=7|
 
|-
 
|-
|LI||VI||colspan=18|
+
!colspan=2|LAUNCH_MISSION
 +
|220
 +
!1
 +
|R||colspan=7|
 
|-
 
|-
!rowspan=2|DIV_FLOAT_ANY_BY_VAL
+
!colspan=2|SAVE_VAR_INT{{ref|defvar|[*]}}
|rowspan=2|000E
+
|502
|GF||VF||colspan=18|
+
!l
 +
|VI||colspan=7|VIO
 
|-
 
|-
|LF||VF||colspan=18|
+
!colspan=2|SAVE_VAR_FLOAT{{ref|defvar|[*]}}
 +
|503
 +
!l
 +
|VF||colspan=7|VFO
 
|-
 
|-
!rowspan=16|>!!rowspan=2|IS_INT_ANY_GREATER_THAN_NUMBER
+
!colspan=2|GOSUB_FILE
|rowspan=2|000F
+
|722
!rowspan=16|2
+
!2
|GI||VN||colspan=18|
+
|R||R||colspan=6|
 
|-
 
|-
|LI||VN||colspan=18|
+
|colspan=2|START_CUTSCENE
 +
|748
 +
!0
 +
|colspan=8|
 
|-
 
|-
!rowspan=2|IS_NUMBER_GREATER_THAN_INT_ANY
+
!colspan=2|PLAYER_MADE_PROGRESS
|rowspan=2|0010
+
|785
|VN||GI||colspan=18|
+
!1
 +
|I||colspan=7|
 
|-
 
|-
|VN||LI||colspan=18|
+
!colspan=2|SET_PROGRESS_TOTAL
 +
|786
 +
!1
 +
|I||colspan=7|
 
|-
 
|-
!rowspan=4|IS_INT_ANY_GREATER_THAN_INT_ANY
+
|colspan=2|REGISTER_MISSION_GIVEN
|rowspan=4|0011
+
|796
|GI||GI||colspan=18|
+
!0
 +
|colspan=8|
 
|-
 
|-
|GI||LI||colspan=18|
+
!colspan=2|REGISTER_MISSION_PASSED
 +
|797
 +
!1
 +
|T||colspan=7|
 
|-
 
|-
|LI||GI||colspan=18|
+
!colspan=2|SCRIPT_NAME
 +
|937
 +
!1
 +
|T||colspan=7|
 
|-
 
|-
|LI||LI||colspan=18|
+
!colspan=2|LOAD_AND_LAUNCH_MISSION
 +
|1051
 +
!1
 +
|R||colspan=7|
 
|-
 
|-
!rowspan=2|IS_FLOAT_ANY_GREATER_THAN_NUMBER
+
!colspan=2|LOAD_AND_LAUNCH_MISSION_INTERNAL
|rowspan=2|0012
+
|1052
|GF||VN||colspan=18|
+
!1
 +
|I||colspan=7|
 
|-
 
|-
|LF||VN||colspan=18|
+
!colspan=2|SET_TOTAL_NUMBER_OF_MISSIONS
 +
|1073
 +
!1
 +
|I||colspan=7|
 
|-
 
|-
!rowspan=2|IS_NUMBER_GREATER_THAN_FLOAT_ANY
+
!rowspan=2|=<br/>IS_THING_EQUAL_TO_THING!!IS_INT_VAR_EQUAL_TO_CONSTANT
|rowspan=2|0013
+
|1192
|VN||GF||colspan=18|
+
!rowspan=2|2
 +
|VI||C||colspan=6|
 
|-
 
|-
|VN||LF||colspan=18|
+
!IS_INT_LVAR_EQUAL_TO_CONSTANT
 +
|1193||LI||C||colspan=6|
 
|-
 
|-
!rowspan=4|IS_FLOAT_ANY_GREATER_THAN_FLOAT_ANY
+
!rowspan=2|=<br/>SET!!SET_VAR_INT_TO_CONSTANT
|rowspan=4|0014
+
|1203
|GF||GF||colspan=18|
+
!rowspan=2|2
 +
|VI||C||colspan=6|
 
|-
 
|-
|GF||LF||colspan=18|
+
!SET_LVAR_INT_TO_CONSTANT
 +
|1204||LI||C||colspan=6|
 
|-
 
|-
|LF||GF||colspan=18|
+
!rowspan=4|><br/><=<br/>IS_THING_GREATER_THAN_THING!!IS_INT_VAR_GREATER_THAN_CONSTANT
 +
|1205
 +
!rowspan=4|2
 +
|VI||C||colspan=6|
 
|-
 
|-
|LF||LF||colspan=18|
+
!IS_INT_LVAR_GREATER_THAN_CONSTANT
 +
|1206||LI||C||colspan=6|
 
|-
 
|-
!rowspan=16|>=!!rowspan=2|IS_INT_ANY_GREATER_OR_EQUAL_TO_NUMBER
+
!IS_CONSTANT_GREATER_THAN_INT_VAR
|rowspan=2|0015
+
|1207||C||VI||colspan=6|
!rowspan=16|2
 
|GI||VN||colspan=18|
 
 
|-
 
|-
|LI||VN||colspan=18|
+
!IS_CONSTANT_GREATER_THAN_INT_LVAR
 +
|1208||C||LI||colspan=6|
 
|-
 
|-
!rowspan=2|IS_NUMBER_GREATER_OR_EQUAL_TO_INT_ANY
+
!rowspan=4|>=<br/><<br/>IS_THING_GREATER_OR_EQUAL_TO_THING!!IS_INT_VAR_GREATER_OR_EQUAL_TO_CONSTANT
|rowspan=2|0016
+
|1209
|VN||GI||colspan=18|
+
!rowspan=4|2
 +
|VI||C||colspan=6|
 
|-
 
|-
|VN||LI||colspan=18|
+
!IS_INT_LVAR_GREATER_OR_EQUAL_TO_CONSTANT
 +
|1210||LI||C||colspan=6|
 
|-
 
|-
!rowspan=4|IS_INT_ANY_GREATER_OR_EQUAL_TO_INT_ANY
+
!IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_VAR
|rowspan=4|0017
+
|1211||C||VI||colspan=6|
|GI||GI||colspan=18|
 
 
|-
 
|-
|GI||LI||colspan=18|
+
!IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_LVAR
 +
|1212||C||LI||colspan=6|
 
|-
 
|-
|LI||GI||colspan=18|
+
!colspan=2|REGISTER_ODDJOB_MISSION_PASSED
 +
|1434
 +
!0
 +
|colspan=8|
 
|-
 
|-
|LI||LI||colspan=18|
+
!rowspan=2 colspan=2|CALL{{ref|undarg|[*]}}{{ref|argvar|[*]}}{{ref|likely|[*]}}
 +
|rowspan=2|1454
 +
!rowspan=2|1+i+o
 +
|rowspan=2|R
 +
|colspan=7|AM
 
|-
 
|-
!rowspan=2|IS_FLOAT_ANY_GREATER_OR_EQUAL_TO_NUMBER
+
|colspan=7|VLM
|rowspan=2|0018
 
|GF||VN||colspan=18|
 
 
|-
 
|-
|LF||VN||colspan=18|
+
!rowspan=2 colspan=2|CALLNOT{{ref|undarg|[*]}}{{ref|argvar|[*]}}{{ref|likely|[*]}}
 +
|rowspan=2|1455
 +
!rowspan=2|1+i+o
 +
|rowspan=2|R
 +
|colspan=7|AM
 
|-
 
|-
!rowspan=2|IS_NUMBER_GREATER_OR_EQUAL_TO_FLOAT_ANY
+
|colspan=7|VLM
|rowspan=2|0019
 
|VN||GF||colspan=18|
 
 
|-
 
|-
|VN||LF||colspan=18|
+
|colspan=12|{{icon|vcs}}
 
|-
 
|-
!rowspan=4|IS_FLOAT_ANY_GREATER_OR_EQUAL_TO_FLOAT_ANY
+
!rowspan=7|=<br/>SET!!SET_INT{{ref|likely|[*]}}
|rowspan=4|001A
+
|4
|GF||GF||colspan=18|
+
 
 +
!rowspan=7|2
 +
|VLI||I||colspan=6|
 
|-
 
|-
|GF||LF||colspan=18|
+
!SET_FLOAT{{ref|likely|[*]}}
 +
|5||VLF||F||colspan=6|
 
|-
 
|-
|LF||GF||colspan=18|
+
!SET_TEXT_LABEL{{ref|likely|[*]}}
 +
|6||VLT||T||colspan=6|
 
|-
 
|-
|LF||LF||colspan=18|
+
!SET_INT_TO_INT{{ref|likely|[*]}}
 +
|53||VLI||VLI||colspan=6|
 
|-
 
|-
!rowspan=12|=!!rowspan=2|IS_INT_ANY_EQUAL_TO_NUMBER
+
!SET_FLOAT_TO_FLOAT{{ref|likely|[*]}}
|rowspan=2|001B
+
|54||VLF||VLF||colspan=6|
!rowspan=12|2
 
|GI||VN||colspan=18|
 
 
|-
 
|-
|LI||VN||colspan=18|
+
!SET_TEXT_LABEL_TO_TEXT_LABEL{{ref|likely|[*]}}
 +
|55||VLT||VLT||colspan=6|
 
|-
 
|-
!rowspan=4|IS_INT_ANY_EQUAL_TO_INT_ANY
+
!SET_INT_TO_CONSTANT{{ref|likely|[*]}}
|rowspan=4|001C
+
|738||VLI||C||colspan=6|
|GI||GI||colspan=18|
 
 
|-
 
|-
|GI||LI||colspan=18|
+
!rowspan=4|+=<br/>+<br/>ADD_THING_TO_THING!!ADD_VAL_TO_INT{{ref|likely|[*]}}
 +
|7
 +
!rowspan=4|2
 +
|VLI||I||colspan=6|
 
|-
 
|-
|LI||GI||colspan=18|
+
!ADD_VAL_TO_FLOAT{{ref|likely|[*]}}
 +
|8||VLF||F||colspan=6|
 
|-
 
|-
|LI||LI||colspan=18|
+
!ADD_INT_TO_INT{{ref|likely|[*]}}
 +
|41||VLI||VLI||colspan=6|
 
|-
 
|-
!rowspan=2|IS_FLOAT_ANY_EQUAL_TO_NUMBER
+
!ADD_FLOAT_TO_FLOAT{{ref|likely|[*]}}
|rowspan=2|001D
+
|42||VLF||VLF||colspan=6|
|GF||VN||colspan=18|
 
 
|-
 
|-
|LF||VN||colspan=18|
+
!rowspan=4|-=<br/>-<br/>SUB_THING_FROM_THING!!SUB_VAL_FROM_INT{{ref|likely|[*]}}
 +
|9
 +
!rowspan=4|2
 +
|VLI||I||colspan=6|
 
|-
 
|-
!rowspan=4|IS_FLOAT_ANY_EQUAL_TO_FLOAT_ANY
+
!SUB_VAL_FROM_FLOAT{{ref|likely|[*]}}
|rowspan=4|001E
+
|10||VLF||F||colspan=6|
|GF||GF||colspan=18|
 
 
|-
 
|-
|GF||LF||colspan=18|
+
!SUB_INT_FROM_INT{{ref|likely|[*]}}
 +
|43||VLI||VLI||colspan=6|
 
|-
 
|-
|LF||GF||colspan=18|
+
!SUB_FLOAT_FROM_FLOAT{{ref|likely|[*]}}
 +
|44||VLF||VLF||colspan=6|
 
|-
 
|-
|LF||LF||colspan=18|
+
!rowspan=4|*=<br/>*<br/>MULT_THING_BY_THING!!MULT_INT_BY_VAL{{ref|likely|[*]}}
 +
|11
 +
!rowspan=4|2
 +
|VLI||I||colspan=6|
 
|-
 
|-
!rowspan=6|=!!rowspan=2|IS_TEXT_LABEL_ANY_EQUAL_TO_TEXT_LABEL
+
!MULT_FLOAT_BY_VAL{{ref|likely|[*]}}
|rowspan=2|001F
+
|12||VLF||F||colspan=6|
!rowspan=6|2
 
|GT||VT||colspan=18|
 
 
|-
 
|-
|LT||VT||colspan=18|
+
!MULT_INT_BY_INT{{ref|likely|[*]}}
 +
|45||VLI||VLI||colspan=6|
 
|-
 
|-
!rowspan=4|IS_ANY_TEXT_LABEL_EQUAL_TO_TEXT_LABEL_ANY
+
!|MULT_FLOAT_BY_FLOAT{{ref|likely|[*]}}
|rowspan=4|0020
+
|46||VLF||VLF||colspan=6|
|GT||GT||colspan=18|
 
 
|-
 
|-
|GT||LT||colspan=18|
+
!rowspan=4|/=<br/>/<br/>DIV_THING_BY_THING!!DIV_INT_BY_VAL{{ref|likely|[*]}}
 +
|13
 +
!rowspan=4|2
 +
|VLI||I||colspan=6|
 
|-
 
|-
|LT||GT||colspan=18|
+
!DIV_FLOAT_BY_VAL{{ref|likely|[*]}}
 +
|14||VLF||F||colspan=6|
 
|-
 
|-
|LT||LT||colspan=18|
+
!DIV_INT_BY_INT{{ref|likely|[*]}}
 +
|47||VLI||VLI||colspan=6|
 
|-
 
|-
!colspan=2|GOTO_IF_TRUE{{ref|statem|[*]}}
+
!DIV_FLOAT_BY_FLOAT{{ref|likely|[*]}}
|0021
+
|48||VLF||VLF||colspan=6|
!1
 
|VO||colspan=19|
 
 
|-
 
|-
!colspan=2|GOTO_IF_FALSE{{ref|statem|[*]}}
+
!rowspan=8|><br/><=<br/>IS_THING_GREATER_THAN_THING!!IS_INT_GREATER_THAN_NUMBER{{ref|likely|[*]}}
|0022
+
|15
!1
 
|VO||colspan=19|
 
|-
 
!colspan=2|TERMINATE_THIS_SCRIPT
 
|rowspan=2|0023
 
!rowspan=2|0
 
|rowspan=2 colspan=20|
 
|-
 
!colspan=2|MISSION_END
 
|-
 
!colspan=2|START_NEW_SCRIPT{{ref|undefa|[*]}}
 
|0024
 
!1
 
|VO||colspan=20|_ _ _
 
|-
 
!colspan=2|GOSUB
 
|0025
 
!1
 
|VO||colspan=20|
 
|-
 
!colspan=2|RETURN
 
|0026
 
!0
 
|colspan=20|
 
|-
 
!rowspan=8|+=!!rowspan=4|ADD_INT_ANY_TO_INT_ANY
 
|rowspan=4|0029
 
 
!rowspan=8|2
 
!rowspan=8|2
|GI||GI||colspan=18|
+
|VLI||I||colspan=6|
 
|-
 
|-
|GI||LI||colspan=18|
+
!IS_NUMBER_GREATER_THAN_INT{{ref|likely|[*]}}
 +
|16||I||VLI||colspan=6|
 
|-
 
|-
|LI||GI||colspan=18|
+
!IS_INT_GREATER_THAN_INT{{ref|likely|[*]}}
 +
|17||VLI||VLI||colspan=6|
 
|-
 
|-
|LI||LI||colspan=18|
+
!IS_FLOAT_GREATER_THAN_NUMBER{{ref|likely|[*]}}
 +
|18||VLF||F||colspan=6|
 
|-
 
|-
!rowspan=4|ADD_FLOAT_ANY_FLOAT_ANY
+
!IS_NUMBER_GREATER_THAN_FLOAT{{ref|likely|[*]}}
|rowspan=4|002A
+
|19||F||VLF||colspan=6|
|GF||GF||colspan=18|
 
 
|-
 
|-
|GF||LF||colspan=18|
+
!IS_FLOAT_GREATER_THAN_FLOAT{{ref|likely|[*]}}
 +
|20||VLF||VLF||colspan=6|
 
|-
 
|-
|LF||GF||colspan=18|
+
!IS_INT_GREATER_THAN_CONSTANT{{ref|likely|[*]}}
 +
|739||VLI||C||colspan=6|
 
|-
 
|-
|LF||LF||colspan=18|
+
!IS_CONSTANT_GREATER_THAN_INT{{ref|likely|[*]}}
 +
|740||C||VLI||colspan=6|
 
|-
 
|-
!rowspan=8|-=!!rowspan=4|SUB_INT_ANY_FROM_INT_ANY
+
!rowspan=8|>=<br/><<br/>IS_THING_GREATER_OR_EQUAL_TO_THING!!IS_INT_GREATER_OR_EQUAL_TO_NUMBER{{ref|likely|[*]}}
|rowspan=4|002B
+
|21
 
!rowspan=8|2
 
!rowspan=8|2
|GI||GI||colspan=18|
+
|VLI||I||colspan=6|
 
|-
 
|-
|GI||LI||colspan=18|
+
!IS_NUMBER_GREATER_OR_EQUAL_TO_INT{{ref|likely|[*]}}
 +
|22||I||VLI||colspan=6|
 
|-
 
|-
|LI||GI||colspan=18|
+
!IS_INT_GREATER_OR_EQUAL_TO_INT{{ref|likely|[*]}}
 +
|23||VLI||VLI||colspan=6|
 
|-
 
|-
|LI||LI||colspan=18|
+
!IS_FLOAT_GREATER_OR_EQUAL_TO_NUMBER{{ref|likely|[*]}}
 +
|24||VLF||F||colspan=6|
 
|-
 
|-
!rowspan=4|SUB_FLOAT_ANY_FROM_FLOAT_ANY
+
!IS_NUMBER_GREATER_OR_EQUAL_TO_FLOAT{{ref|likely|[*]}}
|rowspan=4|002C
+
|25||F||VLF||colspan=6|
|GF||GF||colspan=18|
 
 
|-
 
|-
|GF||LF||colspan=18|
+
!IS_FLOAT_GREATER_OR_EQUAL_TO_FLOAT{{ref|likely|[*]}}
 +
|26||VLF||VLF||colspan=6|
 
|-
 
|-
|LF||GF||colspan=18|
+
!IS_INT_GREATER_OR_EQUAL_TO_CONSTANT{{ref|likely|[*]}}
 +
|741||VLI||C||colspan=6|
 
|-
 
|-
|LF||LF||colspan=18|
+
!IS_CONSTANT_GREATER_OR_EQUAL_TO_INT{{ref|likely|[*]}}
 +
|742||C||VLI||colspan=6|
 
|-
 
|-
!rowspan=8|*=!!rowspan=4|MULT_INT_ANY_BY_INT_ANY
+
!rowspan=7|=<br/>IS_THING_EQUAL_TO_THING!!IS_INT_EQUAL_TO_NUMBER{{ref|likely|[*]}}
|rowspan=4|002D
+
|27
!rowspan=8|2
+
!rowspan=7|2
|GI||GI||colspan=18|
+
|VLI||I||colspan=6|
 
|-
 
|-
|GI||LI||colspan=18|
+
!IS_INT_EQUAL_TO_INT{{ref|likely|[*]}}
 +
|28||VLI||VLI||colspan=6|
 
|-
 
|-
|LI||GI||colspan=18|
+
!IS_FLOAT_EQUAL_TO_NUMBER{{ref|likely|[*]}}
 +
|29||VLF||F||colspan=6|
 
|-
 
|-
|LI||LI||colspan=18|
+
!IS_FLOAT_EQUAL_TO_FLOAT{{ref|likely|[*]}}
 +
|30||VLF||VLF||colspan=6|
 
|-
 
|-
!rowspan=4|MULT_FLOAT_ANY_BY_FLOAT_ANY
+
!IS_TEXT_LABEL_EQUAL_TO_STRING{{ref|likely|[*]}}
|rowspan=4|002E
+
|31||VLT||T||colspan=6|
|GF||GF||colspan=18|
 
 
|-
 
|-
|GF||LF||colspan=18|
+
!IS_TEXT_LABEL_EQUAL_TO_TEXT_LABEL{{ref|likely|[*]}}
 +
|32||VLT||VLT||colspan=6|
 
|-
 
|-
|LF||GF||colspan=18|
+
!IS_INT_EQUAL_TO_CONSTANT{{ref|likely|[*]}}
 +
|731||VLI||C||colspan=6|
 
|-
 
|-
|LF||LF||colspan=18|
+
!colspan=2|GOTO_IF_TRUE{{ref|statem|[*]}}
 +
|33
 +
!1
 +
|R||colspan=7|
 
|-
 
|-
!rowspan=8|/=!!rowspan=4|DIV_INT_ANY_BY_INT_ANY
+
!colspan=2|GOTO_IF_FALSE{{ref|statem|[*]}}
|rowspan=4|002F
+
|34
!rowspan=8|2
+
!1
|GI||GI||colspan=18|
+
|R||colspan=7|
 
|-
 
|-
|GI||LI||colspan=18|
+
!colspan=2|TERMINATE_THIS_SCRIPT
 +
|rowspan=2|35
 +
!rowspan=2|0
 +
|rowspan=2 colspan=8|
 
|-
 
|-
|LI||GI||colspan=18|
+
!colspan=2|MISSION_END
 
|-
 
|-
|LI||LI||colspan=18|
+
!colspan=2|START_NEW_SCRIPT{{ref|undarg|[*]}}
 +
|36
 +
!1+l
 +
|R||colspan=7|AM
 
|-
 
|-
!rowspan=4|DIV_FLOAT_ANY_BY_FLOAT_ANY
+
|colspan=2|GOSUB
|rowspan=4|0030
+
|37
|GF||GF||colspan=18|
+
!1
 +
|R||colspan=7|
 
|-
 
|-
|GF||LF||colspan=18|
+
|colspan=2|RETURN
 +
|38
 +
!0
 +
|colspan=8|
 
|-
 
|-
|LF||GF||colspan=18|
+
!rowspan=2|+=@<br/>+@<br/>ADD_THING_TO_THING_TIMED!!ADD_TIMED_VAL_TO_FLOAT{{ref|likely|[*]}}
 +
|49
 +
!rowspan=2|2
 +
|VLF||F||colspan=6|
 
|-
 
|-
|LF||LF||colspan=18|
+
!ADD_TIMED_FLOAT_TO_FLOAT{{ref|likely|[*]}}
 +
|50||VLF||VLF||colspan=6|
 
|-
 
|-
!rowspan=6|+=@!!rowspan=2|ADD_TIMED_VAL_TO_FLOAT_ANY
+
!rowspan=2|-=@<br/>-@<br/>SUB_THING_FROM_THING_TIMED!!SUB_TIMED_VAL_FROM_FLOAT{{ref|likely|[*]}}
|rowspan=2|0031
+
|51
!rowspan=6|2
+
!rowspan=2|2
|GF||VF||colspan=18|
+
|VLF||F||colspan=6|
 
|-
 
|-
|LF||VF||colspan=18|
+
!SUB_TIMED_FLOAT_FROM_FLOAT{{ref|likely|[*]}}
 +
|52||VLF||VLF||colspan=6|
 
|-
 
|-
!rowspan=4|ADD_TIMED_FLOAT_ANY_TO_FLOAT_ANY
+
!rowspan=2|=#<br/>CSET!!CSET_INT_TO_FLOAT{{ref|likely|[*]}}
|rowspan=4|0032
+
|56
|GF||GF||colspan=18|
+
!rowspan=2|2
 +
|VLI||VLF||colspan=6|
 
|-
 
|-
|GF||LF||colspan=18|
+
!CSET_FLOAT_TO_INT{{ref|likely|[*]}}
 +
|57||VLF||VLI||colspan=6|
 
|-
 
|-
|LF||GF||colspan=18|
+
!rowspan=2|ABS!!ABS_INT{{ref|likely|[*]}}
 +
|58
 +
!rowspan=2|1
 +
|VLI||colspan=7|
 
|-
 
|-
|LF||LF||colspan=18|
+
!ABS_FLOAT{{ref|likely|[*]}}
 +
|59||VLF||colspan=7|
 
|-
 
|-
!rowspan=6|-=@!!rowspan=2|SUB_TIMED_VAL_FROM_FLOAT_ANY
+
|colspan=2|RETURN_TRUE
|rowspan=2|0033
+
|94
!rowspan=6|2
+
!0
|GF||VF||colspan=18|
+
|colspan=8|
 
|-
 
|-
|LF||VF||colspan=18|
+
|colspan=2|RETURN_FALSE
 +
|95
 +
!0
 +
|colspan=8|
 
|-
 
|-
!rowspan=4|SUB_TIMED_FLOAT_ANY_FROM_FLOAT_ANY
+
!colspan=2|VAR_INT{{ref|defvar|[*]}}{{ref|posngs|[*]}}
|rowspan=4|0034
+
|96
|GF||GF||colspan=18|
+
!n
 +
|VI||colspan=7|VIO
 
|-
 
|-
|GF||LF||colspan=18|
+
!colspan=2|VAR_FLOAT{{ref|defvar|[*]}}{{ref|posngs|[*]}}
 +
|97
 +
!n
 +
|VF||colspan=7|VFO
 
|-
 
|-
|LF||GF||colspan=18|
+
!colspan=2|LVAR_INT{{ref|defvar|[*]}}{{ref|posngs|[*]}}
 +
|98
 +
!n
 +
|LI||colspan=7|LIO
 
|-
 
|-
|LF||LF||colspan=18|
+
!colspan=2|LVAR_FLOAT{{ref|defvar|[*]}}{{ref|posngs|[*]}}
 +
|99
 +
!n
 +
|LF||colspan=7|LFO
 
|-
 
|-
!rowspan=12|=!!rowspan=4|SET_ANY_INT_TO_ANY_INT
+
!colspan=2|VAR_TEXT_LABEL{{ref|defvar|[*]}}{{ref|posngs|[*]}}
|rowspan=4|0035
+
|100
!rowspan=12|2
+
!n
|GI||GI||colspan=18|
+
|VT||colspan=7|VTO
 
|-
 
|-
|GI||LI||colspan=18|
+
!colspan=2|LVAR_TEXT_LABEL{{ref|defvar|[*]}}{{ref|posngs|[*]}}
 +
|101
 +
!n
 +
|LT||colspan=7|LTO
 
|-
 
|-
|LI||GI||colspan=18|
+
!colspan=2|{{{ref|embdsc|[*]}}{{ref|posngs|[*]}}
 +
|102
 +
!0
 +
|colspan=8|
 
|-
 
|-
|LI||LI||colspan=18|
+
!colspan=2|}{{ref|embdsc|[*]}}{{ref|posngs|[*]}}
 +
|103
 +
!0
 +
|colspan=8|
 
|-
 
|-
!rowspan=4|SET_ANY_FLOAT_TO_ANY_FLOAT
+
!colspan=2|IF{{ref|statem|[*]}}{{ref|posngs|[*]}}
|rowspan=4|0036
+
|104
|GF||GF||colspan=18|
+
!1
 +
|I||colspan=7|
 
|-
 
|-
|GF||LF||colspan=18|
+
!colspan=2|IFNOT{{ref|statem|[*]}}{{ref|posngs|[*]}}
 +
|105
 +
!1
 +
|I||colspan=7|
 
|-
 
|-
|LF||GF||colspan=18|
+
!colspan=2|ELSE{{ref|statem|[*]}}{{ref|posngs|[*]}}
 +
|106
 +
!0
 +
|colspan=8|
 
|-
 
|-
|LF||LF||colspan=18|
+
!colspan=2|ENDIF{{ref|statem|[*]}}{{ref|posngs|[*]}}
 +
|107
 +
!0
 +
|colspan=8|
 
|-
 
|-
!rowspan=4|SET_ANY_TEXT_LABEL_TO_ANY_TEXT_LABEL
+
!colspan=2|WHILE{{ref|statem|[*]}}{{ref|posngs|[*]}}
|rowspan=4|0037
+
|108
|GT||GT||colspan=18|
+
!1
 +
|I||colspan=7|
 
|-
 
|-
|GT||LT||colspan=18|
+
!colspan=2|WHILENOT{{ref|statem|[*]}}{{ref|posngs|[*]}}
 +
|109
 +
!1
 +
|I||colspan=7|
 
|-
 
|-
|LT||GT||colspan=18|
+
!colspan=2|ENDWHILE{{ref|statem|[*]}}{{ref|posngs|[*]}}
 +
|110
 +
!0
 +
|colspan=8|
 
|-
 
|-
|LT||LT||colspan=18|
+
!colspan=2|REPEAT{{ref|statem|[*]}}{{ref|posngs|[*]}}
 +
|111
 +
!2
 +
|I||VLI||colspan=6|
 
|-
 
|-
!rowspan=8|=#!!rowspan=4|CSET_ANY_INT_TO_ANY_FLOAT
+
!colspan=2|ENDREPEAT{{ref|statem|[*]}}{{ref|posngs|[*]}}
|rowspan=4|0038
+
|112
!rowspan=8|2
+
!0
|GI||GF||colspan=18|
+
|colspan=8|
 
|-
 
|-
|GI||LF||colspan=18|
+
!colspan=2|SWITCH{{ref|statem|[*]}}{{ref|posngs|[*]}}
 +
|113
 +
!1
 +
|VLI||colspan=7|
 
|-
 
|-
|LI||GF||colspan=18|
+
!colspan=2|ENDSWITCH{{ref|statem|[*]}}{{ref|posngs|[*]}}
 +
|114
 +
!0
 +
|colspan=8|
 
|-
 
|-
|LI||LF||colspan=18|
+
!colspan=2|CASE{{ref|statem|[*]}}{{ref|posngs|[*]}}
|-
+
|115
!rowspan=4|CSET_ANY_FLOAT_TO_ANY_INT
+
!1
|rowspan=4|0039
+
|I||colspan=7|
|GF||GI||colspan=18|
 
|-
 
|GF||LI||colspan=18|
 
 
|-
 
|-
|LF||GI||colspan=18|
+
!colspan=2|DEFAULT{{ref|statem|[*]}}{{ref|posngs|[*]}}
|-
+
|116
|LF||LI||colspan=18|
 
|-
 
!rowspan=4|ABS!!rowspan=2|ABS_ANY_INT
 
|rowspan=2|003A
 
!rowspan=4|1
 
|GI||colspan=19|
 
|-
 
|LI||colspan=19|
 
|-
 
!rowspan=2|ABS_ANY_FLOAT
 
|rowspan=2|003B
 
|GF||colspan=19|
 
|-
 
|LF||colspan=19|
 
|-
 
!colspan=2|RETURN_TRUE
 
|005E
 
 
!0
 
!0
|colspan=20|
+
|colspan=8|
 
|-
 
|-
!colspan=2|RETURN_FALSE
+
!colspan=2|BREAK{{ref|statem|[*]}}{{ref|posngs|[*]}}
|005F
+
|117
 
!0
 
!0
|colspan=20|
+
|colspan=8|
 
|-
 
|-
 
!colspan=2|ANDOR{{ref|statem|[*]}}
 
!colspan=2|ANDOR{{ref|statem|[*]}}
|0078
+
|120
 
!1
 
!1
|VI||colspan=19|
+
|I||colspan=7|
 
|-
 
|-
 
!colspan=2|LAUNCH_MISSION
 
!colspan=2|LAUNCH_MISSION
|0079
+
|121
 
!1
 
!1
|VI||colspan=19|
+
|R||colspan=7|
 +
|-
 +
!colspan=2|SAVE_VAR_INT{{ref|defvar|[*]}}
 +
|297
 +
!l
 +
|VI||colspan=7|VIO
 +
|-
 +
!colspan=2|SAVE_VAR_FLOAT{{ref|defvar|[*]}}
 +
|298
 +
!l
 +
|VF||colspan=7|VFO
 +
|-
 +
!colspan=2|SAVE_VAR_TEXT_LABEL{{ref|defvar|[*]}}
 +
|299
 +
!l
 +
|VT||colspan=7|VTO
 
|-
 
|-
 
!colspan=2|GOSUB_FILE
 
!colspan=2|GOSUB_FILE
|01BA
+
|442
 
!2
 
!2
|VO||VO||colspan=18|
+
|R||R||colspan=6|
 
|-
 
|-
!colspan=2|LOAD_AND_LAUNCH_MISSION
+
!colspan=2|PLAYER_MADE_PROGRESS
|0289
+
|479
 
!1
 
!1
|IV||colspan=19|
+
|I||colspan=7|
 
|-
 
|-
!rowspan=4|=!!rowspan=2|IS_INT_ANY_EQUAL_TO_CONSTANT
+
!colspan=2|SET_PROGRESS_TOTAL
|rowspan=2|02DB
+
|480
!rowspan=4|2
+
!1
|GC||VC||colspan=18|
+
|I||colspan=7|
 
|-
 
|-
|LC||VC||colspan=18|
+
|colspan=2|REGISTER_MISSION_GIVEN
 +
|490
 +
!0
 +
|colspan=8|
 
|-
 
|-
!rowspan=2|SET_ANY_INT_TO_CONSTANT
+
!colspan=2|REGISTER_MISSION_PASSED
|rowspan=2|02E2
+
|491
|GC||VC||colspan=18|
+
!1
 +
|T||colspan=7|
 
|-
 
|-
|LC||VC||colspan=18|
+
!colspan=2|SCRIPT_NAME
 +
|568
 +
!1
 +
|T||colspan=7|
 
|-
 
|-
!rowspan=4|>!!rowspan=2|IS_INT_ANY_GREATER_THAN_CONSTANT
+
!colspan=2|LOAD_AND_LAUNCH_MISSION
|rowspan=2|02E3
+
|648
!rowspan=4|2
+
!1
|GC||VC||colspan=18|
+
|R||colspan=7|
 
|-
 
|-
|LC||VC||colspan=18|
+
!colspan=2|LOAD_AND_LAUNCH_MISSION_INTERNAL
 +
|649
 +
!1
 +
|I||colspan=7|
 
|-
 
|-
!rowspan=2|IS_CONSTANT_GREATER_THAN_INT_ANY
+
!colspan=2|SET_TOTAL_NUMBER_OF_MISSIONS
|rowspan=2|02E4
+
|662
|VC||GC||colspan=18|
+
!1
 +
|I||colspan=7|
 
|-
 
|-
|VC||LC||colspan=18|
+
!colspan=2|REGISTER_ODDJOB_MISSION_PASSED
|-
+
|874
!rowspan=4|>=!!rowspan=2|IS_INT_ANY_GREATER_OR_EQUAL_TO_CONSTANT
+
!0
|rowspan=2|02E5
+
|colspan=8|
!rowspan=4|2
 
|GC||VC||colspan=18|
 
 
|-
 
|-
|LC||VC||colspan=18|
+
!rowspan=2 colspan=2|CALL{{ref|undarg|[*]}}{{ref|argvar|[*]}}{{ref|likely|[*]}}
 +
|rowspan=2|890
 +
!rowspan=2|1+i+o
 +
|rowspan=2|R
 +
|colspan=7|AM
 
|-
 
|-
!rowspan=2|IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_ANY
+
|colspan=7|VLM
|rowspan=2|02E6
 
|VC||GV||colspan=18|
 
 
|-
 
|-
|VC||LC||colspan=18|
+
!rowspan=2 colspan=2|CALLNOT{{ref|undarg|[*]}}{{ref|argvar|[*]}}{{ref|likely|[*]}}
 +
|rowspan=2|891
 +
!rowspan=2|1+i+o
 +
|rowspan=2|R
 +
|colspan=7|AM
 
|-
 
|-
!rowspan=2|CALL{{ref|undefa|[*]}}{{ref|argvar|[*]}}!!CALL_037A
+
|colspan=7|VLM
|037A
 
!rowspan=2|1
 
|rowspan=2|VO
 
|rowspan=2 colspan=19|_ _ _
 
 
|-
 
|-
!CALL_037B
+
!colspan=2|SET_COLLECTABLE2_TOTAL
|037B
+
|1242
 +
!1
 +
|I||colspan=7|
 
|}
 
|}
 +
</div>
  
 
;Notes
 
;Notes
:{{note|misdef}} A special [[#Mission scripts|mission]] directive which is never compiled.
+
:{{note|misdef}} A special [[#Mission scripts|mission]] directive which is never compiled;
:{{note|statem}} It is used also to build [[#Statements|statements]] internally.
+
:{{note|statem}} It is used to build the various [[#Control flows|control flows]] internally;
:{{note|undefa}} It has an undefined amount of [[#Arguments|arguments]].
+
:{{note|defvar}} It is used to declare one or more variables;
:{{note|likely}} It is a likely definition of the standard command.
+
:{{note|embdsc}} It embeds a variable scope;
 +
:{{note|undarg}} It has an undefined amount of arguments;
 +
:{{note|likely}} It is a likely definition of the standard command;
 +
:{{note|posngs}} It should exist but its position is purely guessed;
 
:{{note|argvar}} Arguments amount varies when compiling.
 
:{{note|argvar}} Arguments amount varies when compiling.
  
 
{{incomplete}}
 
{{incomplete}}
  
===Uncommon===
+
==Uncommon values==
  
[[#Arguments|Arguments]] of some commands keep uncommon [[#Value|values]] which look familiar after encoding:
+
Arguments of some commands keep uncommon [[#Value|values]] which look familiar after encoding:
  
{|class=wikitable style=text-align:center  
+
<div width=100% style="overflow: auto; margin: -8px auto 8px">
 +
{|class="mw-collapsible mw-collapsed wikitable" style=text-align:center
 +
|-
 
!rowspan=2|Command
 
!rowspan=2|Command
!rowspan=2|Arg ID
+
!rowspan=2|Arg.<br/>ID
!rowspan=2|Syntax
+
!rowspan=2|Value
!colspan=2|Encoded
+
!colspan=4|Encoded
 
|-
 
|-
!Value!!Type
+
!Command!!Arg.<br/>ID!!Value!!Type
 
|-
 
|-
|colspan=5|{{icon|3}} {{icon|vc}} {{icon|sa}} {{icon|lcs}} {{icon|vcs}}
+
|colspan=7|{{icon|t}} {{icon|lcs}} {{icon|vcs}}
 
|-
 
|-
 
!GOTO
 
!GOTO
|1||Any [[#Labels|label]]||[[#Offsets|Offset]]||INT
+
|1||Generic [[#Labels|label]]
 +
!GOTO
 +
|1||Positive/Negative [[#Offsets|offset]]||INT
 
|-
 
|-
 
!GOTO_IF_FALSE
 
!GOTO_IF_FALSE
|1||Any label||Offset||INT
+
|1||Generic label
 +
!GOTO_IF_FALSE
 +
|1||Positive/Negative offset||INT
 
|-
 
|-
 
!GOSUB
 
!GOSUB
|1||[[#Gosubs|Gosub]] label||Offset||INT
+
|1||[[#Gosubs|Gosub]] label
 +
!GOSUB
 +
|1||Positive/Negative offset||INT
 
|-
 
|-
!rowspan=2|GOSUB_FILE
+
!rowspan=4|GOSUB_FILE
|1||Gosub label||rowspan=2|0-based offset||rowspan=2|INT
+
|1||Gosub label
 +
!rowspan=4|GOSUB_FILE
 +
|1||rowspan=2|Zero-based offset||rowspan=4|INT
 
|-
 
|-
|2||[[#Foreign gosubs|Foreign gosub]] file
+
|2||[[#Foreign gosubs|Foreign gosub]] file||2
 
|-
 
|-
!START_NEW_SCRIPT
+
|1||Gosub label||1||rowspan=2|Positive/Negative offset
|1||[[#Scripts|Script]] label||0-based offset||INT
 
 
|-
 
|-
!LAUNCH_MISSION
+
|2||Foreign gosub label||2
|1||[[#Subscripts|Subscript]] file||0-based offset||INT
 
 
|-
 
|-
 +
!rowspan=2|START_NEW_SCRIPT
 +
|1||[[#Scripts|Script]] label
 +
!rowspan=2|START_NEW_SCRIPT
 +
|1||Positive/Negative offset||INT
 +
|-
 +
|l||Passed [[#Local|locals]]||l||Passed locals||ANY_MULTI
 +
|-
 +
!rowspan=2|LAUNCH_MISSION
 +
|rowspan=2|1||[[#Subscripts|Subscript]] file
 +
!rowspan=2|LAUNCH_MISSION
 +
|rowspan=2|1||Zero-based offset||rowspan=2|INT
 +
|-
 +
|Subscript label||Positive/Negative offset
 +
|-
 +
!rowspan=2|LOAD_AND_LAUNCH_MISSION
 +
|rowspan=2|1||[[#Mission scripts|Mission script]] file
 +
!LOAD_AND_LAUNCH_MISSION_INTERNAL
 +
|rowspan=2|1||Mission [[#Identifiers|identifier]]||rowspan=2|INT
 +
|-
 +
|Mission script label
 
!LOAD_AND_LAUNCH_MISSION
 
!LOAD_AND_LAUNCH_MISSION
|1||[[#Mission scripts|Mission script]] file||Mission [[#Identifiers|identifier]]||INT
+
|Positive/Negative offset
 
|-
 
|-
|colspan=5|{{icon|lcs}} {{icon|vcs}}
+
|colspan=7|{{icon|3}} {{icon|lcs}} {{icon|vcs}}
 
|-
 
|-
 
!GOTO_IF_TRUE
 
!GOTO_IF_TRUE
|1||Any label||Offset||INT
+
|1||Generic label
 +
!GOTO_IF_TRUE
 +
|1||Positive/Negative offset||INT
 +
|-
 +
|colspan=7|{{icon|vc}} {{icon|sa}}
 +
|-
 +
!rowspan=2|LOAD_AND_LAUNCH_MISSION_EXCLUSIVE
 +
|rowspan=2|1||Mission script file
 +
!LOAD_AND_LAUNCH_MISSION_INTERNAL
 +
|rowspan=2|1||Negative mission identifier||rowspan=2|INT
 +
|-
 +
|Mission script label
 +
!LOAD_AND_LAUNCH_MISSION_EXCLUSIVE
 +
|Positive/Negative offset
 
|-
 
|-
!rowspan=4|CALL
+
|colspan=7|{{icon|lcs}} {{icon|vcs}}
|1||rowspan=4|[[#Functions|Function]] label||Function arguments||rowspan=4|INT
 
 
|-
 
|-
|2||Returning arguments
+
!rowspan=6|CALL<br/>CALLNOT
 +
|rowspan=4|1||rowspan=4|[[#Functions|Function]] label
 +
!rowspan=6|CALL<br/>CALLNOT
 +
|1||# of input arguments||rowspan=4|INT
 
|-
 
|-
|3||Parent script [[#Local|locals]]
+
|2||# of output arguments
 
|-
 
|-
|4||Offset
+
|3||# of script locals
 +
|-
 +
|4||Positive/Negative offset
 +
|-
 +
|i||Input arguments||i||Input arguments||ANY_MULTI
 +
|-
 +
|o||Output arguments||o||Output arguments||HOLD_MULTI
 
|}
 
|}
 +
</div>
  
 
{{incomplete}}
 
{{incomplete}}
  
===Comparing rule===
+
==Compare flag==
  
The ''comparing rule'' can handle up to ''9 checks'' per construct. ''006D'' ({{icon|3}}, {{icon|vc}}, {{icon|sa}}), ''00DB'' ({{icon|lcs}}) and ''0078'' ({{icon|vcs}}) indicate you are verifying a single check (0) or multiple checks with either '''AND''' (1 to 8) or '''OR''' (21 to 28) [[#Logical|logical operators]] (see also [[#ANDOR|ANDOR]]).
+
The ''compare flag'' is an internal script-dependent flag which makes conditional '''GOTO'''s such as [[#GOTO_IF_TRUE|GOTO_IF_TRUE]] (unavailable in {{icon|t}}) and [[#GOTO_IF_FALSE|GOTO_IF_FALSE]] deciding whether to jump otherwise. It can handle up to ''8 checks'' per conditional statement and indicates you are verifying a single condition (0, see also [[#Optimization|Optimization]]) or multiple conditions with either '''AND''' (1 to 8) or '''OR''' (21 to 28) [[#Logical|logical operators]] (see also [[#ANDOR|ANDOR]]).
  
==Analysis==
+
==Control flows analysis==
  
As an overview of the compiled source, [[#Statements|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.
+
As an overview of the compiled source, [[#Control flows|control flows]] 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===
 
===IF===
  
As regards the [[#IF|IF]] statement, if the whole check is true the ''consequence'' is performed and the code jumps to the end of the construct, otherwise it skips to the ''alternative'' (see also [[#Comparing rule|Comparing rule]]):
+
As regards the [[#IF|IF]] control flow, if the whole check is true the ''consequence'' is performed and the code jumps to the end of the construct, otherwise it skips to the ''alternative'' (see also [[#Compare flag|Compare flag]]):
  
 
{|width=100%
 
{|width=100%
 
!width=50%|Decompiled
 
!width=50%|Decompiled
!width=1px|{{icon|3}} {{icon|vc}} {{icon|sa}}
+
!width=1px|{{icon|t}}
 
!width=1px|{{icon|lcs}}
 
!width=1px|{{icon|lcs}}
 
!width=1px|{{icon|vcs}}
 
!width=1px|{{icon|vcs}}
Line 2,340: Line 2,764:
 
  ENDIF
 
  ENDIF
 
|
 
|
  {006D}
+
  {..214}
  {....}
+
  {.....}
  {....}
+
  {.....}
  {004D}
+
  {...77}
  {....}
+
  {.....}
  {0002}
+
  {....2}
   ----  
+
   -----  
  {....}
+
  {.....}
   ----  
+
   -----  
 
|
 
|
  {00DB}
+
  {..219}
  {....}
+
  {.....}
  {....}
+
  {.....}
  {004D}
+
  {...77}
  {....}
+
  {.....}
  {0002}
+
  {....2}
   ----  
+
   -----  
  {....}
+
  {.....}
   ----  
+
   -----  
 
|
 
|
  {0078}
+
  {..120}
  {....}
+
  {.....}
  {....}
+
  {.....}
  {0022}
+
  {...34}
  {....}
+
  {.....}
  {0002}
+
  {....2}
   ----  
+
   -----  
  {....}
+
  {.....}
   ----  
+
   -----  
 
|
 
|
 
  ANDOR {value}
 
  ANDOR {value}
Line 2,383: Line 2,807:
 
===IFNOT===
 
===IFNOT===
  
Not that much to say more than the preceding construct, the [[#IFNOT|IFNOT]] statement is built nearly in the same way. In fact, the '''ELSE''' clause points to the ''alternative'', whereas the [[#GOTO|GOTO]] jumps to its end. The substantial difference consists in the substitution of [[#GOTO_IF_FALSE|GOTO_IF_FALSE]] with [[#GOTO_IF_TRUE|GOTO_IF_TRUE]]:
+
Not that much to say more than the preceding construct, the [[#IFNOT|IFNOT]] control flow is built nearly in the same way. In fact, the '''ELSE''' clause points to the ''alternative'', whereas the [[#GOTO|GOTO]] jumps to its end. The substantial difference consists in the substitution of [[#GOTO_IF_FALSE|GOTO_IF_FALSE]] with [[#GOTO_IF_TRUE|GOTO_IF_TRUE]]:
  
 
{|width=100%
 
{|width=100%
 
!width=50%|Decompiled
 
!width=50%|Decompiled
 +
!width=1px|{{icon|3}}
 
!width=1px|{{icon|lcs}}
 
!width=1px|{{icon|lcs}}
 
!width=1px|{{icon|vcs}}
 
!width=1px|{{icon|vcs}}
Line 2,399: Line 2,824:
 
  ENDIF
 
  ENDIF
 
|
 
|
  {00DB}
+
  {..214}
  {....}
+
  {.....}
  {....}
+
  {.....}
  {004C}
+
  {...76}
  {....}
+
  {.....}
  {0002}
+
  {....2}
   ----  
+
   -----  
  {....}
+
  {.....}
   ----  
+
   -----  
 
|
 
|
  {0078}
+
  {..219}
  {....}
+
  {.....}
  {....}
+
  {.....}
  {0021}
+
  {...76}
  {....}
+
  {.....}
  {0002}
+
  {....2}
   ----  
+
   -----  
  {....}
+
  {.....}
   ----  
+
   -----
 +
|
 +
{..120}
 +
{.....}
 +
{.....}
 +
{...33}
 +
{.....}
 +
{....2}
 +
  -----
 +
{.....}
 +
  -----  
 
|
 
|
 
  ANDOR {value}
 
  ANDOR {value}
Line 2,432: Line 2,867:
 
===WHILE===
 
===WHILE===
  
The [[#WHILE|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:
+
The [[#WHILE|WHILE]] control flow is built pretty much similarly to the previous, even though when the ''consequence'' is read the code is moved to the beginning of the construct:
  
 
{|width=100%
 
{|width=100%
 
!width=50%|Decompiled
 
!width=50%|Decompiled
!width=1px|{{icon|3}} {{icon|vc}} {{icon|sa}}
+
!width=1px|{{icon|t}}
 
!width=1px|{{icon|lcs}}
 
!width=1px|{{icon|lcs}}
 
!width=1px|{{icon|vcs}}
 
!width=1px|{{icon|vcs}}
Line 2,447: Line 2,882:
 
  ENDWHILE
 
  ENDWHILE
 
|
 
|
   ----  
+
   -----  
  {006D}
+
  {..214}
  {....}
+
  {.....}
  {....}
+
  {.....}
  {004D}
+
  {...77}
  {....}
+
  {.....}
  {0002}
+
  {....2}
   ----  
+
   -----  
 
|
 
|
   ----  
+
   -----  
  {00DB}
+
  {..219}
  {....}
+
  {.....}
  {....}
+
  {.....}
  {004D}
+
  {...77}
  {....}
+
  {.....}
  {0002}
+
  {....2}
   ----  
+
   -----  
 
|
 
|
   ----  
+
   -----  
  {0078}
+
  {..120}
  {....}
+
  {.....}
  {....}
+
  {.....}
  {0022}
+
  {...34}
  {....}
+
  {.....}
  {0002}
+
  {....2}
   ----  
+
   -----  
 
|
 
|
 
  WHILE:
 
  WHILE:
Line 2,486: Line 2,921:
 
===WHILENOT===
 
===WHILENOT===
  
To say the least, [[#WHILENOT|WHILENOT]] statement follows the same constitution of both [[#WHILE|WHILE]] and [[#IFNOT|IFNOT]] constructs, by exchanging [[#GOTO_IF_FALSE|GOTO_IF_FALSE]] with [[#GOTO_IF_TRUE|GOTO_IF_TRUE]]:
+
To say the least, [[#WHILENOT|WHILENOT]] control flow follows the same constitution of both [[#WHILE|WHILE]] and [[#IFNOT|IFNOT]] constructs, by exchanging [[#GOTO_IF_FALSE|GOTO_IF_FALSE]] with [[#GOTO_IF_TRUE|GOTO_IF_TRUE]]:
  
 
{|width=100%
 
{|width=100%
 
!width=50%|Decompiled
 
!width=50%|Decompiled
 +
!width=1px|{{icon|3}}
 
!width=1px|{{icon|lcs}}
 
!width=1px|{{icon|lcs}}
 
!width=1px|{{icon|vcs}}
 
!width=1px|{{icon|vcs}}
Line 2,500: Line 2,936:
 
  ENDWHILE
 
  ENDWHILE
 
|
 
|
   ----  
+
   -----  
  {00DB}
+
  {..214}
  {....}
+
  {.....}
  {....}
+
  {.....}
  {004C}
+
  {...76}
  {....}
+
  {.....}
  {0002}
+
  {....2}
   ----  
+
   -----  
 
|
 
|
   ----  
+
   -----  
  {0078}
+
  {..219}
  {....}
+
  {.....}
  {....}
+
  {.....}
  {0021}
+
  {...76}
  {....}
+
  {.....}
  {0002}
+
  {....2}
   ----  
+
  -----
 +
|
 +
  -----
 +
{..120}
 +
{.....}
 +
{.....}
 +
{...33}
 +
{.....}
 +
{....2}
 +
   -----  
 
|
 
|
 
  WHILENOT:
 
  WHILENOT:
Line 2,530: Line 2,975:
 
===REPEAT===
 
===REPEAT===
  
Seemingly, the [[#REPEAT|REPEAT]] 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* programmers, that is iterating at least once else the construct is useless. However, there are few chance they decide to use such structure to avoid some conflict with some other constructs:
+
Seemingly, the [[#REPEAT|REPEAT]] control flow 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* programmers, that is iterating at least once else the construct is useless. However, there are few chance they decide to use such structure to avoid some conflict with some other constructs:
  
 
{|width=100%
 
{|width=100%
Line 2,543: Line 2,988:
 
  ENDREPEAT
 
  ENDREPEAT
 
|width=1px|
 
|width=1px|
  {0004}
+
  {....4}
   ----  
+
   -----  
  {....}
+
  {.....}
  {0008}
+
  {....8}
  {0028}
+
  {...40}
  {004D}
+
  {...77}
 
|width=1px|
 
|width=1px|
  {0005}
+
  {....5}
   ----  
+
   -----  
  {....}
+
  {.....}
  {0009}
+
  {....9}
  {0029}
+
  {...41}
  {004D}
+
  {...77}
 
|
 
|
  {0004}
+
  {....4}
   ----  
+
   -----  
  {....}
+
  {.....}
  {0007}
+
  {....7}
  {0015}
+
  {...21}
  {0022}
+
  {...34}
 
|
 
|
 
  {varname} = {value0}
 
  {varname} = {value0}
Line 2,572: Line 3,017:
 
|}
 
|}
  
===CASE===
+
===SWITCH===
  
In {{icon|sa}}, the [[#CASE|CASE]] statement is more complex and efficient because the game uses internally a [[Wikipedia:Binary_search_algorithm|binary search algorithm]] to jump at the [[#Labels|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|GOTO]] of the last case is still compiled even though its label points to the end of the jump itself:
+
In {{icon|sa}}, the [[#SWITCH|SWITCH]] control flow is more complex and efficient because the game uses internally a [[Wikipedia:Binary_search_algorithm|binary search algorithm]] to jump at the [[#Labels|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|GOTO]] of the last case is still compiled even though its label points right after the command mentioned earlier:
  
 
{|width=100%
 
{|width=100%
Line 2,582: Line 3,027:
 
|-
 
|-
 
|
 
|
  CASE {varname}
+
  SWITCH {varname}
     WHEN {value0}
+
     CASE {value0}
 
         {consequence}
 
         {consequence}
     [WHEN {valueN}
+
        BREAK
         {consequence}]
+
     [CASE {valueN}
     [ELSE
+
         {consequence}
         {alternative}]
+
        BREAK]
  ENDCASE
+
     [DEFAULT
 +
         {alternative}
 +
        BREAK]
 +
  ENDSWITCH
 
|
 
|
  {0871}
+
  {.2161}
  {0872}
+
  {.2162}
   ----  
+
   -----  
  {....}
+
  {.....}
  {0002}
+
  {....2}
   ----  
+
   -----  
  {....}
+
  {.....}
  {0002}
+
  {....2}
   ----  
+
   -----  
  {....}
+
  {.....}
  {0002}
+
  {....2}
   ----  
+
   -----  
 
|
 
|
  {varname} {cases} {iselse} ELSE {value0} WHEN0 {valueN} WHENN -1 ENDCASE -1 ENDCASE -1 ENDCASE -1 ENDCASE -1 ENDCASE
+
  SWITCH_START {varname} {numcases} {isdefault} DEFAULT {value0} CASE0 ...
[-1 ENDCASE -1 ENDCASE -1 ENDCASE -1 ENDCASE -1 ENDCASE -1 ENDCASE -1 ENDCASE -1 ENDCASE -1 ENDCASE]
+
[SWITCH_CONTINUED ... {valueN} CASEN [-1 ENDSWITCH]]
  WHEN0:
+
  CASE0:
 
     {consequence}
 
     {consequence}
     GOTO ENDCASE
+
     GOTO ENDSWITCH
  [WHENN:
+
  [CASEN:
 
     {consequence}
 
     {consequence}
     GOTO ENDCASE]
+
     GOTO ENDSWITCH]
  [ELSE:
+
  [DEFAULT:
 
     {alternative}
 
     {alternative}
     GOTO ENDCASE]
+
     GOTO ENDSWITCH]
  ENDCASE:
+
  ENDSWITCH:
 
|}
 
|}
  
In {{icon|lcs}} and {{icon|vcs}}, such statement is a set of nested [[#IF|IF]] constructs which causes a very slight loss of performance by considering that ''00DB'' ({{icon|lcs}}) and ''0078'' ({{icon|vcs}} aren't compiled:
+
In {{icon|lcs}} and {{icon|vcs}}, such control flow is a set of nested [[#IF|IF]] constructs which causes a very slight loss of performance by considering that [[#ANDOR|ANDOR]] isn't compiled:
  
 
{|width=100%
 
{|width=100%
Line 2,627: Line 3,075:
 
|-
 
|-
 
|
 
|
  CASE {varname}
+
  SWITCH {varname}
     WHEN {value0}
+
     CASE {value0}
 +
        {consequence}
 +
        BREAK]
 +
    [CASE {valueN}
 
         {consequence}
 
         {consequence}
    [WHEN {valueN}
+
         BREAK]
         {consequence}]
+
     [DEFAULT
     [ELSE
+
         {alternative}
         {alternative}]
+
        BREAK]
  ENDCASE
+
  ENDSWITCH
 
|width=1px|
 
|width=1px|
   ----  
+
   -----  
  {0038}
+
  {...56}
  {004D}
+
  {...77}
  {....}
+
  {.....}
  {0002}
+
  {....2}
   ----  
+
   -----  
  {0038}
+
  {...56}
  {004D}
+
  {...77}
  {....}
+
  {.....}
  {0002}
+
  {....2}
   ----  
+
   -----  
  {....}
+
  {.....}
   ----  
+
   -----  
   ----  
+
   -----  
 
|width=1px|
 
|width=1px|
   ----  
+
   -----  
  {0039}
+
  {...57}
  {004D}
+
  {...77}
  {....}
+
  {.....}
  {0002}
+
  {....2}
   ----  
+
   -----  
  {0039}
+
  {...57}
  {004D}
+
  {...77}
  {....}
+
  {.....}
  {0002}
+
  {....2}
   ----  
+
   -----  
  {....}
+
  {.....}
   ----  
+
   -----  
   ----  
+
   -----  
 
|
 
|
   ----  
+
   -----  
  {001B}
+
  {...27}
  {0022}
+
  {...34}
  {....}
+
  {.....}
  {0002}
+
  {....2}
   ----  
+
   -----  
  {001B}
+
  {...27}
  {0022}
+
  {...34}
  {....}
+
  {.....}
  {0002}
+
  {....2}
   ----  
+
   -----  
  {....}
+
  {.....}
   ----  
+
   -----  
   ----  
+
   -----  
 
|
 
|
  WHEN0:
+
  CASE0:
 
     {varname} = {value0}
 
     {varname} = {value0}
  GOTO_IF_FALSE WHENN
+
  GOTO_IF_FALSE CASEN
 
     {consequence}
 
     {consequence}
     [GOTO ENDCASE0]
+
     GOTO ENDSWITCH0
  WHENN:
+
  CASEN:
 
         [{varname} = {valueN}
 
         [{varname} = {valueN}
     GOTO_IF_FALSE ELSE
+
     GOTO_IF_FALSE DEFAULT
 
         {consequence}
 
         {consequence}
         [GOTO ENDCASEN]
+
         GOTO ENDSWITCHN
     ELSE:
+
     DEFAULT:
 
         [{alternative}
 
         [{alternative}
     ENDCASEN:]]
+
     ENDSWITCHN:]]
  ENDCASE0:
+
  ENDSWITCH0:
 
|}
 
|}
  
 
==Optimization==
 
==Optimization==
  
In {{icon|lcs}} and {{icon|vcs}}, whenever a ''single condition'' is checked ''00DB'' ({{icon|lcs}}) and ''0078'' ({{icon|vcs}}) don't get compiled cause no [[#Logical|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|IF]] statement which points to the end of the construct is still compiled after a [[#GOTO|GOTO]]. Furthermore, ''Stories Games'' come with an improved data type managing which causes a considerable decrease of the compiled file size.
+
In {{icon|lcs}} and {{icon|vcs}}, whenever a ''single condition'' is checked [[#ANDOR|ANDOR]] doesn't get compiled cause no [[#Logical|logical operator]] ('''AND''', '''OR''') is used and so they become really useless. Its lack increases the script efficiency a lot. However, the jump of the '''ELSE''' clause of an [[#IF|IF]] statement which points to the end of the construct is still compiled after a [[#GOTO|GOTO]]. Furthermore, ''Stories Games'' come with an improved data type managing which causes a considerable decrease of the compiled file size.
 +
 
 +
=Tools=
 +
 
 +
* [[SCRambl]] - an open-source tool provided by {{U|Deji}}
 +
* [[Mission Scripting Tools]]
 +
 
 +
=See also=
 +
* [[SCM language III/VC definitions]]
  
 
=External links=
 
=External links=
  
*{{icon|2}} [http://projectcerbera.com/gta/2/tutorials/scripting DMA's GBHScript information]
+
*{{icon|2}} [http://gtamp.com/GTA2/gta2script.7z DMA's official GTA2script Compiler V9.6], [http://projectcerbera.com/gta/2/tutorials/scripting DMA's official GTA2script information] - found into the game copy
*{{icon|3}} [http://alexander.sannybuilder.com/?category=various&altname=gta_3_script_sources SC source files (no main.sc)]
+
*{{icon|3}} [https://www.dropbox.com/s/bwxqe33c8ownfc8/gta3ta_source.rar GTA III 10th Anniversary source] - found into the ''iOS'' game copy
 +
*{{icon|3}} [http://pastebin.com/Pfwscpeh GTA III unofficial main.sc] - Reconstruction of main.sc, missing from the iOS source code, by {{U|Link2012}}
 +
*{{icon|3}} {{icon|vc}} [http://pastebin.com/raw.php?i=T73rCdDd GTA III/VC unavailable script commands (possibly NOP'd)] - some sort of information by {{U|Wesser}} as a result of the reverse-engineering applied to the [http://www.rockstargames.com/ Rockstar Games]' official '''GTA3 Script Compiler V413'''
 +
*{{icon|3}} {{icon|vc}} [https://www.dropbox.com/s/7xgvqo8b9u1qw02/gta3sc_v413.rar Official GTA3 Script Compiler V413] - found into the ''GTA VC 10th Anniversary'' copy
 +
*{{icon|3}} {{icon|vc}} [http://pastebin.com/raw.php?i=Pjb0Ezkx GTA3 Script Compiler V413 Compilation Strings] - a list by {{U|Wesser}} of all the error messages the compiler can throw and more
 +
*{{icon|sa}} [http://pastebin.com/raw.php?i=Ra9JLLeN GTA SA PC/PS2/XBOX script commands], [http://pastebin.com/raw.php?i=kCwS6rdG GTA SA Mobile script commands] - taken directly from the ''Android'' application and rearranged by {{U|Wesser}}
 +
*{{GTAF|441362|Reconstructing the III .sc language}} &ndash; a post by {{U|NTAuthority}}
  
 
{{N|SA|VC|3}}
 
{{N|SA|VC|3}}
  
 
[[Category:Mission Script]]
 
[[Category:Mission Script]]

Revision as of 11:34, 3 October 2020

Announcement: This article is currently being reworked. Check out the progresses by visiting this link from time to time. Contact Wesser for any suggestion.
This section deals with the native SCM syntax of GTA 3 series, nothing other than III, VC, SA, LCS and VCS.
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 syntax, 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 abbreviation is one of countless proofs of this inconvenience, which may stand for Script Multifile. Other doubts come with source files, whose SC extension appears to be very close to Mission SCript. Although we have enough information to suppose the currently unknown mysteries of the used language, we still have no safe clue about which was its original denomination. Furthermore, it is a matter of fact that R* developers have been left untouched the miss2 executable name of the GTA 3 series compiler since the chapter 2. In this connection, we could imagine the new language is a variant or an evolution of the GTA2script. The ancient documentation by DMA (at present Rockstar North), mentions GTA2script as a successor to GBHscript - a language used in GTA 1 (GBH was a planned name for GTA). Therefore, the language used in GTA 3 series should've been called GTA3script. It was influenced by both BASIC and C programming languages.


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

Comments are notes left in the code to aid readability or to explain a part of code that may be confusing otherwise. Comments are ignored by the compiler. R*'s compiler supports C++ style comments – single-line comments and multiline comments.

A single line comment only affects a single line. They are prefixed with // (two slashes). Anything between these slashes and the end of the line is a comment. Single line comments may appear at the end of a line of code as well as on their own line.

[...] // This comment is at the end of a line.

// This comment is on its own line.

Multiline comments appear between /* and */. They do not actually have to span multiple lines, and anything outside of the opening and closing tokens is not ignored (i.e. these comments may appear with code on either side on the same line).

[...]
/*
  This comment spans
  multiple lines.
*/
[...]

[...] /* This comment is within a line */ [...] /* As is this one */ [...]

R*'s compiler allows multiline comments to be nested.

Highlighters

Highlighters behaviour sounds trivial, that's to say they simply highlight one or more arguments per command within round brackets, individually or together. In GTA III, 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
Limits
Opening and closing round brakets are treated as blank spaces;
An optional comma can be used as well to distinguish each argument, processed as a space.

Scopes

Scopes are delimited by curly brackets (or multiline brackets) which 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:

{
    [...]
}
Limits
Scopes cannot be nested;
Opening and closing curly brakets are real commands.

Labels

A label is a sequence of characters which identify the reference of a location of the source code useful for gotoes. It can be accessed by any part of the source code. 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 memory address that is given a name. Variables are used to reference values that are stored in the game's memory and that can change (hence the name "variable"). Instructions may read the variable's memory or write to it. They act in the same way as pointers in other programming languages.

There are several words related to variables that are important to know:

  • The value of the variable is the data that lies at the variable's memory address.
  • The type is what kind of value the variable stores.
  • The scope is the region of code in which the variable may be used (and in which it is declared). There are two types:
    • The global scope is shared between all game scripts. Global variables have the same value everywhere. They are declared with the VAR prefix.
    • The local scope is a region of code within a script. Locals are only visible to other code inside the same pair of curly braces. They are declared with the LVAR prefix.
  • A timer is a unique local variable whose value rises automatically. They start counting when the script starts executing, and continue counting indefinitely. There are two such timers, TIMERA and TIMERB which are always defined, so do not need to be declared.

Data types


Among the available data types, some are equivalent to those of the most known programming languages. Their length is up to 4, 8 and 16 bytes. Each type is appended as a suffix in the variable declaration.

For an in-depth description of different data types, see the SCM instruction page.

LABEL

The LABEL type handles variable-length strings. It can refer to either a label name or a file name.

Notes
While inside a script file, R* compiler treats it unambiguously as a label;
R* compiler allocates 32 bytes per label.
Limit
LABEL variables aren't available.

INT

The INT type handles 32-bit signed integers. It is also used to store values with less bytes, such as a bool, a char and a short int.

FLOAT

The FLOAT type handles 32-bit floating-points. As it normally does, decimal precision of a float is usually stuck to 6-7 digits beyond which it may get lost.

Notes
R* compiler also accepts f and F suffixes for the immediate value.

TEXT_LABEL

The TEXT_LABEL type handles 8-byte strings. Generally, a string is an array of 1-byte characters. It 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) script names or any short string. Literal only TEXT_LABEL* strings are probably marked by single quotation marks to distinguish them from variable and constant identifiers:

PRINT_BIG 'GXT_KEY'
Limit
TEXT_LABEL variables are supported in San Andreas and Vice City Stories.

TEXT_LABEL16

The TEXT_LABEL16 type handles 16-byte strings. Like the previous, this type holds 15 characters plus the null-terminator. It is used to store model and texture names of player clothes, animation names or any long string.

Limit
TEXT_LABEL16 variables and values are supported only in San Andreas.

TEXT_LABEL32

The TEXT_LABEL32 type handles 32-byte strings or larger, depending on how many continuous parameters of the same type there are, each of which occupies 32 bytes. It can hold up to 127 characters plus the null-terminator, after which another TEXT_LABEL32 argument may begin. Strings of such type must be put within double quotation marks:

SAVE_STRING_TO_DEBUG_FILE "32B-128B TEXT"
Limits
TEXT_LABEL32 values are supported since Vice City;
TEXT_LABEL32 variables aren't available.

TEXT

The TEXT type handles N-byte strings. It holds N characters plus the null-terminator. Strings of this type mustn't exceed 255 characters (including the null-byte).

Limits
TEXT values are supported since San Andreas;
TEXT variables aren't available.

CONST (pseudo)

The CONST type handles 32-bit signed integers. It is used only to assign and compare constants to INT variables regarding model identifiers, task statuses, ped or audio events and such. It is a pseudo type of INT.

Limit
The assignment and comparison of CONST values are supported since Vice City.

MULTI (pseudo)

The MULTI type handles a group of few data types acceptable per argument. It is used only for commands featuring optional arguments, those whose type is unpredictable before the compilation. It can be a pseudo type of INT, FLOAT and TEXT_LABEL.

Notes
INT and FLOAT can be used interchangeably in GTA III, Vice City, San Andreas, Liberty City Stories and Vice City Stories;
Vice City Stories also admits TEXT_LABEL arguments.

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:

VAR_* {varname0}[,] [... {varnameN}]
LVAR_* {varname0}[,] [... {varnameN}]

As mentioned in the sections above, local variables have to be put within curly brackets:

{
    VAR_* {varname0}[,] [... {varnameN}]
    LVAR_* {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.

Limits
Whereas the variable buffer is limited, you can declare a certain amount of globals and locals. INT and FLOAT types take 1 variable, while TEXT_LABEL and TEXT_LABEL16 types occupy respectively 2 and 4 variables to store their data (have a look here for further details);
Vice City Stories isn't affected by what said above;
Global and local variable names must not collide.

Arrays

A array is a collection of variables having the same type which can be accessed by an index, an INT lesser than or equal to the size specified, enclosed by square brackets:

{
    VAR_* {varname0}{[arrsize0]}[,] [... {varnameN}{[arrsizeN]}]
    LVAR_* {varname0}{[arrsize0]}[,] [... {varnameN}{[arrsizeN]}]

    [...]
}
Limits
The usage of arrays is allowed since Vice City;
Variable indices are quite buggy in Vice City and therefore unrecommended, but they are fully supported since San Andreas;
The aforesaid indices are one-based, possibly zero-based since San Andreas;
Multidimensional arrays are not supported.

Handles

A handle is an univocal identifier assigned to a game entity. It is given by the following statement:

short nHandle = (iEntityIndexInPool << 8) | ucEntityFlag;
Note
R* compiler won't let you assign different entity types to the same variable or using a variable which hasn't been passed to any command designated to the creation of an entity.

Operators

In general, an operator is a token string that represents a math calculation or an operation of any other kind, in order to make the code understanding clearer at a glance.

Arithmetic

Arithmetic operators compute some of the most common algebric calculations between either a variable and a value or two variables. As well as in some programming language happens, CONST, TEXT_LABEL and TEXT_LABEL16 types are free from these operators, except for the basic assignment (see also Operators composition):

Operator Name Syntax Description
= Assignment expr0 = expr1 Store expr1 to expr0
+ Addition expr0 + expr1 Add expr1 to expr0
- Subtraction expr0 - expr1 Subtract expr1 from expr0
* Multiplication expr0 * expr1 Multiply expr0 by expr1
/ Division expr0 / expr1 Divide expr0 by expr1
+@ Timed addition expr0 +@ expr1 Multiply expr2 by delta time and add the result to expr1
-@ Timed subtraction expr0 -@ expr1 Multiply expr2 by delta time and subtract the result from expr1
++ Increment Pre[*] ++ expr0 Increment expr0 by 1 and store the result to expr0
Post expr0 ++
-- Decrement Pre[*] -- expr0 Decrement expr0 by 1 and store the result to expr0
Post expr0 --
Note
^ Pre and post increments have no difference unlike what you would expect.

Yet, you can put the assignment and algebric operators together inline as follows:

Operators Name Syntax Description
= + Addition and assignment expr0 = expr1[*] + expr2 Add expr2 to expr1 and store the result to expr0
= - Subtraction and assignment expr0 = expr1[*] - expr2 Subtract expr2 from expr1 and store the result to expr0
= * Multiplication and assignment expr0 = expr1[*] * expr2 Multiply expr1 by expr2 and store the result to expr0
= / Division and assignment expr0 = expr1[*] / expr2 Divide expr1 by expr2 and store the result to expr0
= +@ Timed addition and assignment expr0 = expr1[*] +@ expr2 Multiply expr2 by delta time, add the result to expr1 and store everything to expr0
= -@ Timed subtraction and assignment expr0 = expr1[*] -@ expr2 Multiply expr2 by delta time, subtract the result from expr1 and store everything to expr0
Note
^ expr1 can represent expr0 too.
Limit
Multiple algebric operators per line are not allowed.

Compound assignment

Compound assignment operators store values or variable content to other variables having a particular type afterwards the computation of an arithmetic operation, to squeeze the code and clear it up from granted repetitions:

Operator Name Syntax Description
+= Addition assignment expr0 += expr1 Add expr1 to expr0 and store the result to expr0
-= Subtraction assignment expr0 -= expr1 Subtract expr1 from expr0 and store the result to expr0
*= Multiplication assignment expr0 *= expr1 Multiply expr0 by expr1 and store the result to expr0
/= Division assignment expr0 /= expr1 Divide expr0 by expr1 and store the result to expr0
+=@ Timed addition assignment expr0 +=@ expr1 Multiply expr1 by delta time, add the result to expr0 and store everything to expr0
-=@ Timed subtraction assignment expr0 -=@ expr1 Multiply expr1 by delta time, subtract the result from expr0 and store everything to expr0

Uncompounded assignment

Uncompounded assignment operators are those on their own, or rather they are neither derivable nor decomposable similarly as those compounds:

Operator Name Syntax Description
=# Cast assignment expr0 =# expr1 Cast expr1 to any other type and store the result to expr0
Limit
Supported conversions are FLOAT to INT and INT to FLOAT.

Logical

Logical operators influence the way conditions are evalueted and enable to test more of them at a time. More than anything, they are built-in statements:

Operator Name Syntax Description
NOT Logical negation IF NOT condition0 Test if condition0 is false
AND Logical conjunction IF condition0
AND condition8
Test if both condition0 and conditionN are true
OR Logical disjunction IF condition0
OR condition8
Test if either condition0 or conditionN is true

Comparison

Comparison operators test the truth or falsity of the relation between either a variable and a value, a value and a variable or two variables:

Operator Name Syntax Description
= Equal to IF expr0 = expr1 Test if expr0 and expr1 are equal
> Greater than IF expr0 > expr1 Test if expr0 is greater than expr1
<[*] Lesser than IF expr0 < expr1 Test if expr0 is lesser than expr1
>= Greater than or equal to IF expr0 >= expr1 Test if expr0 is greater than or equal to expr1
<=[*] Lesser than or equal to IF expr0 <= expr1 Test if expr0 is lesser than or equal to expr1
Note
^ As a result of a critical bug, R* compiler mistakenly applies the operator inversion.

Commands

A command is a symbolic name associated to an identifier which executes a portion of code that specifies the operation to be performed by passing zero or more arguments. An argument is in turn some data given as input to a command. Normally, commands have a defined amount of arguments and those not, such as START_NEW_SCRIPT, can pass as many arguments as the available local variables are, except timers. Being a procedure, a command does not return values that can be assigned to a variable, even though the boolean flag is kept whenever it is used as a condition. It follows the common programming syntax adopted for function calls:

{commandname} [{anyvalue0|varname0} ... {anyvalueN|varnameN}]

Alternators

An alternator is an abstract operation that is implemented with a set of commands, each of which takes differently typed arguments.

Alternators are used because there are often multiple different combinations of argument types that one might wish to use for an operation. While 1 + 2 and 1 + 2.0 are equivalent to a human, they are not to a computer, so they must be implemented differently.

Each command has the same arity as the other commands implementing the same operation. They differ only the in combination and order of their parameters' types.

Common alternators

  • GTA III Vice City San Andreas Liberty City Stories Vice City Stories
    • SET (=)
    • CSET (=#)
    • ADD_THING_TO_THING (+=)
    • SUB_THING_FROM_THING (-=)
    • MULT_THING_BY_THING (*=)
    • DIV_THING_BY_THING (/=)
    • IS_THING_EQUAL_TO_THING (=)
    • IS_THING_NOT_EQUAL_TO_THING (NOT =)
    • IS_THING_GREATER_THAN_THING (>, <=)
    • IS_THING_GREATER_OR_EQUAL_TO_THING (>=, <)
    • ADD_THING_TO_THING_TIMED (+=@)
    • SUB_THING_FROM_THING_TIMED (-=@)
    • ABS
  • San Andreas
    • IS_EMPTY
    • IS_BIT_SET
    • SET_BIT
    • CLEAR_BIT
    • STRING_CAT

This section is incomplete. You can help by fixing and expanding it.

Hardcoded

Hardcoded commands are those which have unique characteristics and are handled internally:

List of hardcoded commands

  • GTA III Vice City San Andreas Liberty City Stories Vice City Stories:
    • GOTO
    • GOTO_IF_FALSE
    • TERMINATE_THIS_SCRIPT
    • START_NEW_SCRIPT
    • VAR_INT
    • VAR_FLOAT
    • LVAR_INT
    • LVAR_FLOAT
    • {
    • }
    • REPEAT
    • ENDREPEAT
    • IF
    • IFNOT
    • ELSE
    • ENDIF
    • WHILE
    • WHILENOT
    • ENDWHILE
    • ANDOR
    • LAUNCH_MISSION
    • SAVE_VAR_INT
    • SAVE_VAR_FLOAT
    • START_CUTSCENE[*]
    • PLAYER_MADE_PROGRESS
    • SET_PROGRESS_TOTAL[*]
    • REGISTER_MISSION_GIVEN[*]
    • REGISTER_MISSION_PASSED
    • SCRIPT_NAME
    • LOAD_AND_LAUNCH_MISSION
    • LOAD_AND_LAUNCH_MISSION_INTERNAL
    • SET_TOTAL_NUMBER_OF_MISSIONS[*]
    • VAR_TEXT_LABEL
    • LVAR_TEXT_LABEL
  • Vice City San Andreas Liberty City Stories Vice City Stories:
    • REGISTER_ODDJOB_MISSION_PASSED
  • GTA III Liberty City Stories Vice City Stories:
    • GOTO_IF_TRUE
    • GOSUB_FILE
  • GTA III Vice City:
    • CREATE_COLLECTABLE1
    • SET_COLLECTABLE1_TOTAL[*]
  • Vice City San Andreas:
    • LOAD_AND_LAUNCH_MISSION_EXCLUSIVE
  • Liberty City Stories Vice City Stories:
    • CALL
    • CALLNOT
  • San Andreas:
    • VAR_TEXT_LABEL16
    • LVAR_TEXT_LABEL16
    • SWITCH
    • ENDSWITCH
    • CASE
    • DEFAULT
    • BREAK
    • SWITCH_START
    • SWITCH_CONTINUED
  • Vice City Stories:
    • SAVE_VAR_TEXT_LABEL[*]
    • SET_COLLECTABLE2_TOTAL
Notes
^ The argument of these commands must be set respectively according to:
  • The sum of PLAYER_MADE_PROGRESS values;
  • The amount of REGISTER_MISSION_PASSED (those that don't have an immediate value are excluded) and REGISTER_ODDJOB_MISSION_PASSED;
  • The amount of CREATE_COLLECTABLE1.
If the argument of the listed commands differs from what expected, a 0-value must be passed;
^ This command was intended to be counted originally but its counter got deprecated.

This section is incomplete. You can help by fixing and expanding it.

WAIT

WAIT stops 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 may or may not break after more than one frame, such as the WHILE control flow. In this case, a INT equal to 0 is passed.

GOTO

GOTO jumps to the label of any location of the source code but conceptually it should never point off the current context. It is also used internally to build the control flows offered by the scripting language:

// File: any.sc

goto_ref0:
GOTO goto_refN
// File: any.sc

goto_refN:
GOTO goto_ref0

ANDOR

ANDOR sets out the way the comparison among more conditions have to occur (see also Compare flag).

GOTO_IF_TRUE

GOTO_IF_TRUE operates in conjunction with ANDOR and jumps to a label if the returned boolean flag is true.

GOTO_IF_FALSE

Unlike GOTO_IF_TRUE, GOTO_IF_FALSE jumps to the desired label only if the comparison returns false.

SCRIPT_NAME

SCRIPT_NAME simply associates an unique name to the current working script.

Note
R* compiler doesn't enable you to associate a name previously used for another script.

SAVE_STRING_TO_DEBUG_FILE

SAVE_STRING_TO_DEBUG_FILE accepts an argument which can admit up to 127 characters plus the null-terminator. In the compiling process, the argument is skipped but its string is copied to a predefined 128-bytes buffer, compiled afterwards. Since Vice City, these are the seemingly predetermined bytes of a random empty string block which are actually the result of uninitialized data:

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

The split of such bytes into 4 blocks of 32-bytes each is quite noticeable.

Constants

A constant is a symbolic name associated to a specific value. When compiling, their caption is converted to the assigned value. Since Vice City, names and identifiers of objects within OBJS and TOBJ blocks are loaded from every IDE file defined into gta_vc.dat, then those of vehicles and pedestrians within PEDS and CARS blocks are retrieved from default.ide. In San Andreas, they are listed into TXT files, whose name follows the Pascal Case (eg. AudioEvents.txt). These files respect the syntax 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 also Identifiers). Keep in mind arguments of some commands having the CONST type accept only constant values of a single namespace.

Notes
Constants don't collide even though they belong to different namespaces;
In GTA III and Vice City, they are hardcoded as everything inside R* compiler;
In San Andreas, the subdivision of constant namespaces in files might be just a listing of hardcoded constants useful for developers. The same would apply to Liberty City Stories and Vice City Stories.

Formatting

Everything is case-insensitive, that means the uppercase and lowercase letters have no dissimilarities when taken. Usually, the source code is conform to the same formatting according to:

Compiling

Structure

The source code is split up into several SC files which comprehend main file, foreign gosubs, subscripts, mission scripts, and streamed scripts. These files can be included more times because they are actually processed once.

Main file


The main file is the most significant part of the whole source. It can include many script files and/or embedded gosubs, scripts or functions. Originally, it is characterized by the absence of the local scope. It must be put outside the directory, having the same name as the main script file, where all other foreign scripts must be:

<directory>
| main
|  | gosub
|  |  |- gosub1.sc
|  |  \- gosubN.sc
|  | subscript
|  |  |- subscript1.sc
|  |  \- subscriptN.sc
|  | mission_guy
|  |  |- mission_guy1.sc
|  |  \- mission_guyN.sc
|  |- gosub.sc
|  |- subscript.sc
|  \- mission.sc
\- main.sc
Note
R* compiler will scan subfolders too.

Foreign gosubs


Foreign gosubs (also called subroutines) are main extension files. They are called using the GOSUB_FILE command which jumps to a specific label and executes some code that returns back to the place where it has been called with RETURN. You are able to specify the gosub label to start jumping at as well:

// File: main.sc

GOSUB_FILE gosub_ref foreign_gosub.sc
// File: foreign_gosub.sc

gosub_ref:
{
    [...]
}
RETURN
Limit
Foreign gosubs were introduced since GTA III. They were unused in Vice City and got removed in San Andreas, but then they were reimplemented in Liberty City Stories and Vice City Stories.

Gosubs

As mentioned, gosubs are also embedded in any script file. They follow almost the same rules, except they are called by GOSUB and can actually inehrit the local scope of the parent script:

// File: any.sc

GOSUB gosub_ref
// File: any.sc

gosub_ref:
{
    [...]
}
RETURN
Note
R* compiler doesn't take care if the code within a scope jumps to a gosub inside which another scope is declared. It is strongly recommended to pay attention at this issue or you will fall down into an irreparable local variable mismatch.

Subscripts


Subscripts are code blocks which take part of a queue of other scripts and are allocated over the memory by LAUNCH_MISSION. They are denoted by the presence of MISSION_START at the very top of the mission file. As long as they aren't ended with MISSION_END, their execution never expires till the end of the game process. Each one works independently, even though they are able to share global variables:

// File: main.sc

LAUNCH_MISSION subscript.sc
// File: subscript.sc

MISSION_START

[VAR_* {varname0}[,] [... {varnameN}]]

SCRIPT_NAME main

subscript_loop:
{
    [LVAR_* {varname0}[,] [... {varnameN}]]

    [...]
}
//GOTO subscript_loop
MISSION_END
Notes
MISSION_START is a special and fake directive that isn't assigned to any command. R* compiler will notify an error if it isn't placed at the first line of a subscript or a mission script;
MISSION_END is an alias of TERMINATE_THIS_SCRIPT.

Scripts

As for gosubs, scripts can be embedded everywhere in a script file. They are started by START_NEW_SCRIPT which has an undefined amount of arguments, whose type must match with those of each local variable of the starting script in order to be passed, else the compilation will interrupt. Unlike subscripts, they get terminated by TERMINATE_THIS_SCRIPT or TERMINATE_ALL_SCRIPTS_WITH_THIS_NAME (elsewhere in another script):

// File: any.sc

START_NEW_SCRIPT script [{anyvalue0|varname0} ... {anyvalueN|varnameN}]
// File: any.sc

script:
{
    SCRIPT_NAME script

script_loop:

    [LVAR_* {varname0}[,] [... {varnameN}]]

    [...]

    //GOTO script_loop
    TERMINATE_THIS_SCRIPT
}
Notes
Scripts must have a local scope;
Script commands must be inserted within or after the local scope;
Since Vice City, the opening curly bracket must be put before the script label when more arguments are passed.

Functions

This section is incomplete. You can help by fixing and expanding it.

Mission scripts


Mission scripts are those subscripts which are responsible for the presence of a storyline in the game. When they are launched with LOAD_AND_LAUNCH_MISSION, the mission is loaded in the mission block, allocated over the memory and the script pointer is moved to the corresponding mission offset. Do not forget to begin a mission script with MISSION_START and end it with MISSION_END:

// File: main.sc

LOAD_AND_LAUNCH_MISSION mission.sc
// File: mission.sc

MISSION_START

GOSUB mission_start

IF HAS_DEATHARREST_BEEN_EXECUTED
    GOSUB mission_failed
ENDIF

GOSUB mission_cleanup

MISSION_END

[VAR_* {varname0}[,] [... {varnameN}]]

mission_start:

REGISTER_MISSION_GIVEN
SCRIPT_NAME mission

// Variables initialization

{
    [LVAR_* {varname0}[,] [... {varnameN}]]

    [...]
}
GOTO mission_passed

mission_failed:
[...]
RETURN

mission_passed:
REGISTER_MISSION_PASSED mission
//PLAYER_MADE_PROGRESS 1
[...]
RETURN

// Mark everything as no longer needed

mission_cleanup:
//MISSION_HAS_FINISHED
[...]
RETURN

Some missions doesn't need to be executed multiple times because they may just initialize some global variables defined in the main script or launch the intro mission. For this matter, here comes the usage of LOAD_AND_LAUNCH_MISSION_EXCLUSIVE:

// File: main.sc

LOAD_AND_LAUNCH_MISSION_EXCLUSIVE initial.sc
LOAD_AND_LAUNCH_MISSION_EXCLUSIVE intro.sc
Note
Exclusive missions are never launched in the source code. It's likely, it was an idea not came to the end successfully or rather they were useful for debugging purposes.
Limits
LOAD_AND_LAUNCH_MISSION_EXCLUSIVE is available only in Vice City and San Andreas;
Only 2 exclusive missions in Vice City and 3 in San Andreas are handled, plus they must be launched before any of the counterpart.

Streamed scripts


This section is incomplete. You can help by fixing and expanding it.

Control flow

As usual, the evolution of something implies its development over the years. Alongside, the control flows implementation has been distributed equally into every chapter. Their definitions are similar to those used in pseudocodes resulting in a raw source code. However, you are still able to build your own control flows:

ANDOR {value}
    [NOT] {condition0}
    [[NOT] {condition8}]
GOTO_IF_FALSE ELSE
    {consequence}
    [GOTO ENDIF]
ELSE:
    [{alternative}
ENDIF:]
Note
It's likely, user-made control flows weren't intended to be usable because R* compiler cannot recognize an equal to rather than an assignment operator.

If

IF is the most common conditional statement. It executes one block of code if a boolean condition is true, and (optionally) another if the condition is false. The condition may be made of multiple conditions combined using the logical operators AND or OR, or it may just be a single condition. AND makes the final condition true only if all of the input conditions are true, whereas OR only requires one input condition to be true. The condition may be inverted with NOT, another logical operator. Syntax:

IF [NOT] {condition0}
[AND|OR [NOT] {condition8}]
    {consequence}
[ELSE
    {alternative}]
ENDIF
Limitations
  • There is a maximum of 8 conditions.

If-not

IFNOT works in the same way as IF except that the condition is always inverted.

IFNOT [NOT] {condition0}
[AND|OR [NOT] {condition8}]
    {consequence}
[ELSE
    {alternative}]
ENDIF
Limitations
  • IFNOT is only supported in games that have GOTO_IF_TRUE: GTA III, Liberty City Stories and Vice City Stories.

While

WHILE is similar to IF, but it continues executing the body until the condition is false.

WHILE [NOT] {condition0}
[AND|OR [NOT] {condition8}]
    {consequence}
ENDWHILE

While-not

WHILENOT is to WHILE as IFNOT is to IF: it loops until the condition is true.

WHILENOT [NOT] {condition0}
[AND|OR [NOT] {condition8}]
    {consequence}
ENDWHILE
Limitations
  • Like IFNOT, WHILENOT is only supported in games that have GOTO_IF_TRUE: GTA III, Liberty City Stories and Vice City Stories.

Repeat

REPEAT acts as a range-based loop (generally a for-loop in modern programming languages). It executes the body and increments a certain variable until it reaches a target value, at which point the loop stops.

REPEAT {target} {varname}
    {consequence}
ENDREPEAT
Limitations
  • REPEAT is supported in games from Vice City;
  • The target value must be positive;
  • The body will be read at least once in any case.

Switch

A SWITCH statement is functionally equivalent to multiple nested IF...ELSE statements. It takes a single value and executes a block of code that is specific to that value (a CASE) until it finds a BREAK, which moves execution to the end of the construct. If no matching case is found, the DEFAULT clause is executed.

SWITCH {varname}
    CASE {value0}
        {consequence}
        BREAK
    [CASE {valueN}
        {consequence}
        BREAK]
    [DEFAULT
        {alternative}
        BREAK]
ENDSWITCH
Limitations
  • It is supported from San Andreas;
  • CASE allows the use of INT and CONST values only;
  • In San Andreas, the CASE values should be sorted (R*'s compiler should do it implicitly);
  • Every CASE, including DEFAULT, must end with a BREAK.

Decompiling

Structure

For further information about the SCM file format, read this article. Take into account the compiling order of each SC file is main file » foreign gosubs » subscripts » mission scripts apart from the reading order of the commands used to include them. Streamed scripts are compiled individually into the script.img file. On the other hand, functions are compiled like gosubs.

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. Those of mission scripts and streamed scripts respect the same rule except the fact they are turned into a zero-based growing identifier, while exclusive mission scripts are launched by a negative identifier resulting from the bits inversion (bitwise complement).

Offsets

An offset is a 32-bit signed integer which points to a location of the script file. Those within the main file, foreign gosubs and subscripts are absolute offsets that start from the beginning of the main script, while the ones inside mission scripts and streamed scripts are relative and negative offsets starting from their beginning. The offset is related to global variables as well, whose interval goes from 8 and ends to 65532 (0xFFFC), each one is aligned to the nearest 4 bytes.

Variables range

The following table shows the variables range of the local scope for each game version:

Context GTA III Vice City San Andreas Liberty City Stories Vice City Stories
Foreign gosub/Gosub 0-15 0-15 n/a 0-95 0-95
Subscript/Script 0-15 0-15 0-31 0-95 0-95
Mission script 0-15 0-15 0-1023 0-95 0-95
Streamed script n/a n/a 0-31 n/a n/a
Function n/a n/a n/a 0-95 0-95
Timer 16-17 16-17 32-33 t0-t1 t0-t1

Compiled operators

As in most compiled programming languages, SCM's operators are always compiled with two operands, regardless of how they appear within the source code.

This means that operators that seem to have only one operand will have two, and operators that seem to have more than two are actually compiled as multiple instructions.

Operator Name Written Compiled
++ Increment Pre ++a a += 1
Post a++
-- Decrement Pre --a a -= 1
Post a--
+= Addition and assignment a = b + c a = b
a += c
-= Subtraction and assignment a = b - c a = b
a -= c
*= Multiplication and assignment a = b * c a = b
a *= c
/= Division and assignment a = b / c a = b
a /= c
+=@ Timed addition and assignment a = b +@ c a = b
a +=@ c
-=@ Timed subtraction and assignment a = b -@ c a = b
a -=@ c

Opcode

A command's opcode is a 16-bit signed integer identifier which the game uses to find the implementation for the command. The maximum number of opcodes possible is 32,767 (0x7FFF), because the most significant bit (0x8000) is the sign bit, which is only set when the associated command's return value is inverted (e.g. not x()).

There are no commands with negative opcodes; the game takes the absolute value (|opcode|) before finding the implementation, after noting whether it is inverted.

Command arguments

The limitation of the amount of arguments a variadic command can pass is game specific:

  • 16 for GTA III and Vice City;
  • 32 for San Andreas;
  • 96 for Liberty City Stories and Vice City Stories.

Managed commands

Here is the list of all managed commands and their relative specifications:

Legend:

  • Suffix:
    • O, OPTIONAL.

List:

Be aware, the argument data types of the commands below are just informative:

Command ID Arguments
# 1 2 3 4 ... 18 ... n+l
n+i+o
GTA III Vice City San Andreas Liberty City Stories Vice City Stories
MISSION_START[*] 0
GOTO[*] 2 1 R
GTA III Vice City San Andreas Liberty City Stories
=
SET
SET_VAR_INT 4 2 VI I
SET_VAR_FLOAT 5 VF F
SET_LVAR_INT 6 LI I
SET_LVAR_FLOAT 7 LF F
SET_VAR_INT_TO_VAR_INT 132 VI VI
SET_LVAR_INT_TO_LVAR_INT 133 LI LI
SET_VAR_FLOAT_TO_VAR_FLOAT 134 VF VF
SET_LVAR_FLOAT_TO_LVAR_FLOAT 135 LF LF
SET_VAR_FLOAT_TO_LVAR_FLOAT 136 VF LF
SET_LVAR_FLOAT_TO_VAR_FLOAT 137 LF VF
SET_VAR_INT_TO_LVAR_INT 138 VI LI
SET_LVAR_INT_TO_VAR_INT 139 LI VI
+=
+
ADD_THING_TO_THING
ADD_VAL_TO_INT_VAR 8 2 VI I
ADD_VAL_TO_FLOAT_VAR 9 VF F
ADD_VAL_TO_INT_LVAR 10 LI I
ADD_VAL_TO_FLOAT_LVAR 11 LF F
ADD_INT_VAR_TO_INT_VAR 88 VI VI
ADD_FLOAT_VAR_TO_FLOAT_VAR 89 VF VF
ADD_INT_LVAR_TO_INT_LVAR 90 LI LI
ADD_FLOAT_LVAR_TO_FLOAT_LVAR 91 LF LF
ADD_INT_VAR_TO_INT_LVAR 92 LI VI
ADD_FLOAT_VAR_TO_FLOAT_LVAR 93 LF VF
ADD_INT_LVAR_TO_INT_VAR 94 VI LI
ADD_FLOAT_LVAR_TO_FLOAT_VAR 95 VF LF
-=
-
SUB_THING_FROM_THING
SUB_VAL_FROM_INT_VAR 12 2 VI I
SUB_VAL_FROM_FLOAT_VAR 13 VF F
SUB_VAL_FROM_INT_LVAR 14 LI I
SUB_VAL_FROM_FLOAT_LVAR 15 LF F
SUB_INT_VAR_FROM_INT_VAR 96 VI VI
SUB_FLOAT_VAR_FROM_FLOAT_VAR 97 VF VF
SUB_INT_LVAR_FROM_INT_LVAR 98 LI LI
SUB_FLOAT_LVAR_FROM_FLOAT_LVAR 99 LF LF
SUB_INT_VAR_FROM_INT_LVAR 100 LI VI
SUB_FLOAT_VAR_FROM_FLOAT_LVAR 101 LF VF
SUB_INT_LVAR_FROM_INT_VAR 102 VI LI
SUB_FLOAT_LVAR_FROM_FLOAT_VAR 103 VF LF
*=
*
MULT_THING_BY_THING
MULT_INT_VAR_BY_VAL 16 2 VI I
MULT_FLOAT_VAR_BY_VAL 17 VF F
MULT_INT_LVAR_BY_VAL 18 LI I
MULT_FLOAT_LVAR_BY_VAL 19 LF F
MULT_INT_VAR_BY_INT_VAR 104 VI VI
MULT_FLOAT_VAR_BY_FLOAT_VAR 105 VF VF
MULT_INT_LVAR_BY_INT_LVAR 106 LI LI
MULT_FLOAT_LVAR_BY_FLOAT_LVAR 107 LF LF
MULT_INT_VAR_BY_INT_LVAR 108 VI LI
MULT_FLOAT_VAR_BY_FLOAT_LVAR 109 VF LF
MULT_INT_LVAR_BY_INT_VAR 110 LI VI
MULT_FLOAT_LVAR_BY_FLOAT_VAR 111 LF VF
/=
/
DIV_THING_BY_THING
DIV_INT_BY_VAL 20 2 VI I
DIV_FLOAT_VAR_BY_VAL 21 VF F
DIV_INT_LVAR_BY_VAL 22 LI I
DIV_FLOAT_LVAR_BY_VAL 23 LF F
DIV_INT_VAR_BY_INT_VAR 112 VI VI
DIV_FLOAT_VAR_BY_FLOAT_VAR 113 VF VF
DIV_INT_LVAR_BY_INT_LVAR 114 LI LI
DIV_FLOAT_LVAR_BY_FLOAT_LVAR 115 LF LF
DIV_INT_VAR_BY_INT_LVAR 116 VI LI
DIV_FLOAT_VAR_BY_FLOAT_LVAR 117 VF LF
DIV_INT_LVAR_BY_INT_VAR 118 LI VI
DIV_FLOAT_LVAR_BY_FLOAT_VAR 119 LF VF
>
<=
IS_THING_GREATER_THAN_THING
IS_INT_VAR_GREATER_THAN_NUMBER 24 2 VI I
IS_INT_LVAR_GREATER_THAN_NUMBER 25 LI I
IS_NUMBER_GREATER_THAN_INT_VAR 26 I VI
IS_NUMBER_GREATER_THAN_INT_LVAR 27 I LI
IS_INT_VAR_GREATER_THAN_INT_VAR 28 VI VI
IS_INT_LVAR_GREATER_THAN_INT_LVAR 29 LI LI
IS_INT_VAR_GREATER_THAN_INT_LVAR 30 VI LI
IS_INT_LVAR_GREATER_THAN_INT_VAR 31 LI VI
IS_FLOAT_VAR_GREATER_THAN_NUMBER 32 VF F
IS_FLOAT_LVAR_GREATER_THAN_NUMBER 33 LF F
IS_NUMBER_GREATER_THAN_FLOAT_VAR 34 F VF
IS_NUMBER_GREATER_THAN_FLOAT_LVAR 35 F LF
IS_FLOAT_VAR_GREATER_THAN_FLOAT_VAR 36 VF VF
IS_FLOAT_LVAR_GREATER_THAN_FLOAT_LVAR 37 LF LF
IS_FLOAT_VAR_GREATER_THAN_FLOAT_LVAR 38 VF LF
IS_FLOAT_LVAR_GREATER_THAN_FLOAT_VAR 39 LF VF
>=
<
IS_THING_GREATER_OR_EQUAL_TO_THING
IS_INT_VAR_GREATER_OR_EQUAL_TO_NUMBER 40 2 VI I
IS_INT_LVAR_GREATER_OR_EQUAL_TO_NUMBER 41 LI I
IS_NUMBER_GREATER_OR_EQUAL_TO_INT_VAR 42 I VI
IS_NUMBER_GREATER_OR_EQUAL_TO_INT_LVAR 43 I LI
IS_INT_VAR_GREATER_OR_EQUAL_TO_INT_VAR 44 VI VI
IS_INT_LVAR_GREATER_OR_EQUAL_TO_INT_LVAR 45 LI LI
IS_INT_VAR_GREATER_OR_EQUAL_TO_INT_LVAR 46 VI LI
IS_INT_LVAR_GREATER_OR_EQUAL_TO_INT_VAR 47 LI VI
IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_NUMBER 48 VF F
IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_NUMBER 49 LF F
IS_NUMBER_GREATER_OR_EQUAL_TO_FLOAT_VAR 50 F VF
IS_NUMBER_GREATER_OR_EQUAL_TO_FLOAT_LVAR 51 F LF
IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_FLOAT_VAR 52 VF VF
IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_FLOAT_LVAR 53 LF LF
IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_FLOAT_LVAR 54 VF LF
IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_FLOAT_VAR 55 LF VF
=
IS_THING_EQUAL_TO_THING
IS_INT_VAR_EQUAL_TO_NUMBER 56 2 VI I
IS_INT_LVAR_EQUAL_TO_NUMBER 57 LI I
IS_INT_VAR_EQUAL_TO_INT_VAR 58 VI VI
IS_INT_LVAR_EQUAL_TO_INT_LVAR 59 LI LI
IS_INT_VAR_EQUAL_TO_INT_LVAR 60 VI LI
IS_FLOAT_VAR_EQUAL_TO_NUMBER 66 VF F
IS_FLOAT_LVAR_EQUAL_TO_NUMBER 67 LF F
IS_FLOAT_VAR_EQUAL_TO_FLOAT_VAR 68 VF VF
IS_FLOAT_LVAR_EQUAL_TO_FLOAT_LVAR 69 LF LF
IS_FLOAT_VAR_EQUAL_TO_FLOAT_LVAR 70 VF LF
NOT =
IS_THING_NOT_EQUAL_TO_THING
IS_INT_VAR_NOT_EQUAL_TO_NUMBER 61 2 VI I
IS_INT_LVAR_NOT_EQUAL_TO_NUMBER 62 LI I
IS_INT_VAR_NOT_EQUAL_TO_INT_VAR 63 VI VI
IS_INT_LVAR_NOT_EQUAL_TO_INT_LVAR 64 LI LI
IS_INT_VAR_NOT_EQUAL_TO_INT_LVAR 65 VI LI
IS_FLOAT_VAR_NOT_EQUAL_TO_NUMBER 71 VF F
IS_FLOAT_LVAR_NOT_EQUAL_TO_NUMBER 72 LF F
IS_FLOAT_VAR_NOT_EQUAL_TO_FLOAT_VAR 73 VF VF
IS_FLOAT_LVAR_NOT_EQUAL_TO_FLOAT_LVAR 74 LF LF
IS_FLOAT_VAR_NOT_EQUAL_TO_FLOAT_LVAR 75 VF LF
GOTO_IF_FALSE[*] 77 1 R
TERMINATE_THIS_SCRIPT 78 0
MISSION_END
START_NEW_SCRIPT[*] 79 1+l R AM
GOSUB 80 1 R
RETURN 81 0
+=@
+@
ADD_THING_TO_THING_TIMED
ADD_TIMED_VAL_TO_FLOAT_VAR 120 2 VF F
ADD_TIMED_VAL_TO_FLOAT_LVAR 121 LF F
ADD_TIMED_FLOAT_VAR_TO_FLOAT_VAR 122 VF VF
ADD_TIMED_FLOAT_LVAR_TO_FLOAT_LVAR 123 LF LF
ADD_TIMED_FLOAT_LVAR_TO_FLOAT_VAR 124 LF VF
ADD_TIMED_FLOAT_VAR_TO_FLOAT_LVAR 125 VF LF
-=@
-@
SUB_THING_FROM_THING_TIMED
SUB_TIMED_VAL_FROM_FLOAT_VAR 126 2 VF F
SUB_TIMED_VAL_FROM_FLOAT_LVAR 127 LF F
SUB_TIMED_FLOAT_VAR_FROM_FLOAT_VAR 128 VF VF
SUB_TIMED_FLOAT_LVAR_FROM_FLOAT_LVAR 129 LF LF
SUB_TIMED_FLOAT_LVAR_FROM_FLOAT_VAR 130 LF VF
SUB_TIMED_FLOAT_VAR_FROM_FLOAT_LVAR 131 VF LF
=#
CSET
CSET_VAR_INT_TO_VAR_FLOAT 140 2 VI VF
CSET_VAR_FLOAT_TO_VAR_INT 141 VF VI
CSET_LVAR_INT_TO_VAR_FLOAT 142 LI VF
CSET_LVAR_FLOAT_TO_VAR_INT 143 LF VI
CSET_VAR_INT_TO_LVAR_FLOAT 144 VI LF
CSET_VAR_FLOAT_TO_LVAR_INT 145 VF LI
CSET_LVAR_INT_TO_LVAR_FLOAT 146 LI LF
CSET_LVAR_FLOAT_TO_LVAR_INT 147 LF LI
ABS ABS_VAR_INT 148 1 VI
ABS_LVAR_INT 149 LI
ABS_VAR_FLOAT 150 VF
ABS_LVAR_FLOAT 151 LF
VAR_INT[*] 199 n VI VIO
VAR_FLOAT[*] 200 n VF VFO
LVAR_INT[*] 201 n LI LIO
LVAR_FLOAT[*] 202 n LF LFO
{[*] 203 0
}[*] 204 0
IF[*] 207 1 I
ELSE[*] 209 0
ENDIF[*] 210 0
WHILE[*] 211 1 I
ENDWHILE[*] 213 0
GTA III Vice City San Andreas
ANDOR[*] 214 1 I
LAUNCH_MISSION 215 1 R
START_CUTSCENE 743 0
PLAYER_MADE_PROGRESS 780 1 I
SET_PROGRESS_TOTAL 781 1 I
REGISTER_MISSION_GIVEN 791 0
REGISTER_MISSION_PASSED 792 1 T
SCRIPT_NAME 932 1 T
LOAD_AND_LAUNCH_MISSION 1046 1 R
LOAD_AND_LAUNCH_MISSION_INTERNAL 1047 1 I
SET_TOTAL_NUMBER_OF_MISSIONS 1068 1 I
REGISTER_ODDJOB_MISSION_PASSED 1429 0
Vice City San Andreas Liberty City Stories
REPEAT[*] 205 2 I VLI
ENDREPEAT[*] 206 0
GTA III Vice City
CREATE_COLLECTABLE1 748 1 I
SET_COLLECTABLE1_TOTAL 749 1 I
GTA III Liberty City Stories
GOTO_IF_TRUE[*] 76 1 R
Vice City San Andreas
=
IS_THING_EQUAL_TO_THING
IS_INT_VAR_EQUAL_TO_CONSTANT 1187 2 VI C
IS_INT_LVAR_EQUAL_TO_CONSTANT 1188 LI C
=
SET
SET_VAR_INT_TO_CONSTANT 1198 2 VI C
SET_LVAR_INT_TO_CONSTANT 1199 LI C
>
<=
IS_THING_GREATER_THAN_THING
IS_INT_VAR_GREATER_THAN_CONSTANT 1200 2 VI C
IS_INT_LVAR_GREATER_THAN_CONSTANT 1201 LI C
IS_CONSTANT_GREATER_THAN_INT_VAR 1202 C VI
IS_CONSTANT_GREATER_THAN_INT_LVAR 1203 C LI
>=
<
IS_THING_GREATER_OR_EQUAL_TO_THING
IS_INT_VAR_GREATER_OR_EQUAL_TO_CONSTANT 1204 2 VI C
IS_INT_LVAR_GREATER_OR_EQUAL_TO_CONSTANT 1205 LI C
IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_VAR 1206 C VI
IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_LVAR 1207 C LI
LOAD_AND_LAUNCH_MISSION_EXCLUSIVE 1301 1 R
GTA III
IFNOT[*] 208 1 I
WHILENOT[*] 212 1 I
GOSUB_FILE 717 2 R R
San Andreas
=
SET
SET_VAR_TEXT_LABEL 1449 2 VT AT
SET_LVAR_TEXT_LABEL 1450 LT AT
VAR_TEXT_LABEL[*] 1451 n VT VTO
LVAR_TEXT_LABEL[*] 1452 n LT LTO
=
IS_THING_EQUAL_TO_THING
IS_VAR_TEXT_LABEL_EQUAL_TO_TEXT_LABEL 1453 2 VT AT
IS_LVAR_TEXT_LABEL_EQUAL_TO_TEXT_LABEL 1454 LT AT
=
SET
SET_VAR_TEXT_LABEL16 1745 2 VT16 AT16
SET_LVAR_TEXT_LABEL16 1476 LT16 AT16
VAR_TEXT_LABEL16[*] 1477 n VT16 VT16O
LVAR_TEXT_LABEL16[*] 1478 n LT16 LT16O
=
IS_THING_EQUAL_TO_THING
IS_INT_LVAR_EQUAL_TO_INT_VAR 2006 2 LI VI
IS_FLOAT_LVAR_EQUAL_TO_FLOAT_VAR 2007 LF VF
IS_EMPTY[*] IS_VAR_TEXT_LABEL_EMPTY 2116 1 VT
IS_LVAR_TEXT_LABEL_EMPTY 2117 LT
IS_VAR_TEXT_LABEL16_EMPTY 2118 VT16
IS_LVAR_TEXT_LABEL16_EMPTY 2119 LT16
SWITCH[*] 2120 1 VLI
ENDSWITCH[*] 2121 0
CASE[*] 2122 1 I
DEFAULT[*] 2123 0
BREAK[*] 2124 0
SWITCH_START[*] 2161 18 VI I I R I
R
LI I I R I
R
SWITCH_CONTINUED[*] 2162 18 I
R
IS_BIT_SET[*] IS_GLOBAL_VAR_BIT_SET_CONST 2228 2 VI C
IS_GLOBAL_VAR_BIT_SET_VAR 2229 VI VI
IS_GLOBAL_VAR_BIT_SET_LVAR 2230 VI LI
IS_LOCAL_VAR_BIT_SET_CONST 2231 LI C
IS_LOCAL_VAR_BIT_SET_VAR 2232 LI VI
IS_LOCAL_VAR_BIT_SET_LVAR 2233 LI LI
SET_BIT[*] SET_GLOBAL_VAR_BIT_CONST 2234 2 VI C
SET_GLOBAL_VAR_BIT_VAR 2235 VI VI
SET_GLOBAL_VAR_BIT_LVAR 2236 VI LI
SET_LOCAL_VAR_BIT_CONST 2237 LI C
SET_LOCAL_VAR_BIT_VAR 2238 LI VI
SET_LOCAL_VAR_BIT_LVAR 2239 LI LI
CLEAR_BIT[*] CLEAR_GLOBAL_VAR_BIT_CONST 2240 2 VI C
CLEAR_GLOBAL_VAR_BIT_VAR 2241 VI VI
CLEAR_GLOBAL_VAR_BIT_LVAR 2242 VI LI
CLEAR_LOCAL_VAR_BIT_CONST 2243 LI C
CLEAR_LOCAL_VAR_BIT_VAR 2244 LI VI
CLEAR_LOCAL_VAR_BIT_LVAR 2245 LI LI
=
IS_THING_EQUAL_TO_THING
IS_VAR_TEXT_LABEL16_EQUAL_TO_TEXT_LABEL 2297 2 VT16 AT16
IS_LVAR_TEXT_LABEL16_EQUAL_TO_TEXT_LABEL 2298 LT16 AT16
STRING_CAT[*] STRING_CAT16 2443 3 VT16 VT16 VT16
STRING_CAT8 2444 VT VT VT
Liberty City Stories
RETURN_TRUE 197 0
RETURN_FALSE 198 0
SWITCH[*][*] 214 1 VLI
ENDSWITCH[*][*] 215 0
CASE[*][*] 216 1 I
DEFAULT[*][*] 217 0
BREAK[*][*] 218 0
ANDOR[*] 219 1 I
LAUNCH_MISSION 220 1 R
SAVE_VAR_INT[*] 502 l VI VIO
SAVE_VAR_FLOAT[*] 503 l VF VFO
GOSUB_FILE 722 2 R R
START_CUTSCENE 748 0
PLAYER_MADE_PROGRESS 785 1 I
SET_PROGRESS_TOTAL 786 1 I
REGISTER_MISSION_GIVEN 796 0
REGISTER_MISSION_PASSED 797 1 T
SCRIPT_NAME 937 1 T
LOAD_AND_LAUNCH_MISSION 1051 1 R
LOAD_AND_LAUNCH_MISSION_INTERNAL 1052 1 I
SET_TOTAL_NUMBER_OF_MISSIONS 1073 1 I
=
IS_THING_EQUAL_TO_THING
IS_INT_VAR_EQUAL_TO_CONSTANT 1192 2 VI C
IS_INT_LVAR_EQUAL_TO_CONSTANT 1193 LI C
=
SET
SET_VAR_INT_TO_CONSTANT 1203 2 VI C
SET_LVAR_INT_TO_CONSTANT 1204 LI C
>
<=
IS_THING_GREATER_THAN_THING
IS_INT_VAR_GREATER_THAN_CONSTANT 1205 2 VI C
IS_INT_LVAR_GREATER_THAN_CONSTANT 1206 LI C
IS_CONSTANT_GREATER_THAN_INT_VAR 1207 C VI
IS_CONSTANT_GREATER_THAN_INT_LVAR 1208 C LI
>=
<
IS_THING_GREATER_OR_EQUAL_TO_THING
IS_INT_VAR_GREATER_OR_EQUAL_TO_CONSTANT 1209 2 VI C
IS_INT_LVAR_GREATER_OR_EQUAL_TO_CONSTANT 1210 LI C
IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_VAR 1211 C VI
IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_LVAR 1212 C LI
REGISTER_ODDJOB_MISSION_PASSED 1434 0
CALL[*][*][*] 1454 1+i+o R AM
VLM
CALLNOT[*][*][*] 1455 1+i+o R AM
VLM
Vice City Stories
=
SET
SET_INT[*] 4 2 VLI I
SET_FLOAT[*] 5 VLF F
SET_TEXT_LABEL[*] 6 VLT T
SET_INT_TO_INT[*] 53 VLI VLI
SET_FLOAT_TO_FLOAT[*] 54 VLF VLF
SET_TEXT_LABEL_TO_TEXT_LABEL[*] 55 VLT VLT
SET_INT_TO_CONSTANT[*] 738 VLI C
+=
+
ADD_THING_TO_THING
ADD_VAL_TO_INT[*] 7 2 VLI I
ADD_VAL_TO_FLOAT[*] 8 VLF F
ADD_INT_TO_INT[*] 41 VLI VLI
ADD_FLOAT_TO_FLOAT[*] 42 VLF VLF
-=
-
SUB_THING_FROM_THING
SUB_VAL_FROM_INT[*] 9 2 VLI I
SUB_VAL_FROM_FLOAT[*] 10 VLF F
SUB_INT_FROM_INT[*] 43 VLI VLI
SUB_FLOAT_FROM_FLOAT[*] 44 VLF VLF
*=
*
MULT_THING_BY_THING
MULT_INT_BY_VAL[*] 11 2 VLI I
MULT_FLOAT_BY_VAL[*] 12 VLF F
MULT_INT_BY_INT[*] 45 VLI VLI
MULT_FLOAT_BY_FLOAT[*] 46 VLF VLF
/=
/
DIV_THING_BY_THING
DIV_INT_BY_VAL[*] 13 2 VLI I
DIV_FLOAT_BY_VAL[*] 14 VLF F
DIV_INT_BY_INT[*] 47 VLI VLI
DIV_FLOAT_BY_FLOAT[*] 48 VLF VLF
>
<=
IS_THING_GREATER_THAN_THING
IS_INT_GREATER_THAN_NUMBER[*] 15 2 VLI I
IS_NUMBER_GREATER_THAN_INT[*] 16 I VLI
IS_INT_GREATER_THAN_INT[*] 17 VLI VLI
IS_FLOAT_GREATER_THAN_NUMBER[*] 18 VLF F
IS_NUMBER_GREATER_THAN_FLOAT[*] 19 F VLF
IS_FLOAT_GREATER_THAN_FLOAT[*] 20 VLF VLF
IS_INT_GREATER_THAN_CONSTANT[*] 739 VLI C
IS_CONSTANT_GREATER_THAN_INT[*] 740 C VLI
>=
<
IS_THING_GREATER_OR_EQUAL_TO_THING
IS_INT_GREATER_OR_EQUAL_TO_NUMBER[*] 21 2 VLI I
IS_NUMBER_GREATER_OR_EQUAL_TO_INT[*] 22 I VLI
IS_INT_GREATER_OR_EQUAL_TO_INT[*] 23 VLI VLI
IS_FLOAT_GREATER_OR_EQUAL_TO_NUMBER[*] 24 VLF F
IS_NUMBER_GREATER_OR_EQUAL_TO_FLOAT[*] 25 F VLF
IS_FLOAT_GREATER_OR_EQUAL_TO_FLOAT[*] 26 VLF VLF
IS_INT_GREATER_OR_EQUAL_TO_CONSTANT[*] 741 VLI C
IS_CONSTANT_GREATER_OR_EQUAL_TO_INT[*] 742 C VLI
=
IS_THING_EQUAL_TO_THING
IS_INT_EQUAL_TO_NUMBER[*] 27 2 VLI I
IS_INT_EQUAL_TO_INT[*] 28 VLI VLI
IS_FLOAT_EQUAL_TO_NUMBER[*] 29 VLF F
IS_FLOAT_EQUAL_TO_FLOAT[*] 30 VLF VLF
IS_TEXT_LABEL_EQUAL_TO_STRING[*] 31 VLT T
IS_TEXT_LABEL_EQUAL_TO_TEXT_LABEL[*] 32 VLT VLT
IS_INT_EQUAL_TO_CONSTANT[*] 731 VLI C
GOTO_IF_TRUE[*] 33 1 R
GOTO_IF_FALSE[*] 34 1 R
TERMINATE_THIS_SCRIPT 35 0
MISSION_END
START_NEW_SCRIPT[*] 36 1+l R AM
GOSUB 37 1 R
RETURN 38 0
+=@
+@
ADD_THING_TO_THING_TIMED
ADD_TIMED_VAL_TO_FLOAT[*] 49 2 VLF F
ADD_TIMED_FLOAT_TO_FLOAT[*] 50 VLF VLF
-=@
-@
SUB_THING_FROM_THING_TIMED
SUB_TIMED_VAL_FROM_FLOAT[*] 51 2 VLF F
SUB_TIMED_FLOAT_FROM_FLOAT[*] 52 VLF VLF
=#
CSET
CSET_INT_TO_FLOAT[*] 56 2 VLI VLF
CSET_FLOAT_TO_INT[*] 57 VLF VLI
ABS ABS_INT[*] 58 1 VLI
ABS_FLOAT[*] 59 VLF
RETURN_TRUE 94 0
RETURN_FALSE 95 0
VAR_INT[*][*] 96 n VI VIO
VAR_FLOAT[*][*] 97 n VF VFO
LVAR_INT[*][*] 98 n LI LIO
LVAR_FLOAT[*][*] 99 n LF LFO
VAR_TEXT_LABEL[*][*] 100 n VT VTO
LVAR_TEXT_LABEL[*][*] 101 n LT LTO
{[*][*] 102 0
}[*][*] 103 0
IF[*][*] 104 1 I
IFNOT[*][*] 105 1 I
ELSE[*][*] 106 0
ENDIF[*][*] 107 0
WHILE[*][*] 108 1 I
WHILENOT[*][*] 109 1 I
ENDWHILE[*][*] 110 0
REPEAT[*][*] 111 2 I VLI
ENDREPEAT[*][*] 112 0
SWITCH[*][*] 113 1 VLI
ENDSWITCH[*][*] 114 0
CASE[*][*] 115 1 I
DEFAULT[*][*] 116 0
BREAK[*][*] 117 0
ANDOR[*] 120 1 I
LAUNCH_MISSION 121 1 R
SAVE_VAR_INT[*] 297 l VI VIO
SAVE_VAR_FLOAT[*] 298 l VF VFO
SAVE_VAR_TEXT_LABEL[*] 299 l VT VTO
GOSUB_FILE 442 2 R R
PLAYER_MADE_PROGRESS 479 1 I
SET_PROGRESS_TOTAL 480 1 I
REGISTER_MISSION_GIVEN 490 0
REGISTER_MISSION_PASSED 491 1 T
SCRIPT_NAME 568 1 T
LOAD_AND_LAUNCH_MISSION 648 1 R
LOAD_AND_LAUNCH_MISSION_INTERNAL 649 1 I
SET_TOTAL_NUMBER_OF_MISSIONS 662 1 I
REGISTER_ODDJOB_MISSION_PASSED 874 0
CALL[*][*][*] 890 1+i+o R AM
VLM
CALLNOT[*][*][*] 891 1+i+o R AM
VLM
SET_COLLECTABLE2_TOTAL 1242 1 I
Notes
^ A special mission directive which is never compiled;
^ It is used to build the various control flows internally;
^ It is used to declare one or more variables;
^ It embeds a variable scope;
^ It has an undefined amount of arguments;
^ It is a likely definition of the standard command;
^ It should exist but its position is purely guessed;
^ Arguments amount varies when compiling.

This section is incomplete. You can help by fixing and expanding it.

Uncommon values

Arguments of some commands keep uncommon values which look familiar after encoding:

Command Arg.
ID
Value Encoded
Command Arg.
ID
Value Type
GTA III Vice City San Andreas Liberty City Stories Vice City Stories
GOTO 1 Generic label GOTO 1 Positive/Negative offset INT
GOTO_IF_FALSE 1 Generic label GOTO_IF_FALSE 1 Positive/Negative offset INT
GOSUB 1 Gosub label GOSUB 1 Positive/Negative offset INT
GOSUB_FILE 1 Gosub label GOSUB_FILE 1 Zero-based offset INT
2 Foreign gosub file 2
1 Gosub label 1 Positive/Negative offset
2 Foreign gosub label 2
START_NEW_SCRIPT 1 Script label START_NEW_SCRIPT 1 Positive/Negative offset INT
l Passed locals l Passed locals ANY_MULTI
LAUNCH_MISSION 1 Subscript file LAUNCH_MISSION 1 Zero-based offset INT
Subscript label Positive/Negative offset
LOAD_AND_LAUNCH_MISSION 1 Mission script file LOAD_AND_LAUNCH_MISSION_INTERNAL 1 Mission identifier INT
Mission script label LOAD_AND_LAUNCH_MISSION Positive/Negative offset
GTA III Liberty City Stories Vice City Stories
GOTO_IF_TRUE 1 Generic label GOTO_IF_TRUE 1 Positive/Negative offset INT
Vice City San Andreas
LOAD_AND_LAUNCH_MISSION_EXCLUSIVE 1 Mission script file LOAD_AND_LAUNCH_MISSION_INTERNAL 1 Negative mission identifier INT
Mission script label LOAD_AND_LAUNCH_MISSION_EXCLUSIVE Positive/Negative offset
Liberty City Stories Vice City Stories
CALL
CALLNOT
1 Function label CALL
CALLNOT
1 # of input arguments INT
2 # of output arguments
3 # of script locals
4 Positive/Negative offset
i Input arguments i Input arguments ANY_MULTI
o Output arguments o Output arguments HOLD_MULTI

This section is incomplete. You can help by fixing and expanding it.

Compare flag

The compare flag is an internal script-dependent flag which makes conditional GOTOs such as GOTO_IF_TRUE (unavailable in GTA III Vice City San Andreas) and GOTO_IF_FALSE deciding whether to jump otherwise. It can handle up to 8 checks per conditional statement and indicates you are verifying a single condition (0, see also Optimization) or multiple conditions with either AND (1 to 8) or OR (21 to 28) logical operators (see also ANDOR).

Control flows analysis

As an overview of the compiled source, control flows 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

As regards the IF control flow, if the whole check is true the consequence is performed and the code jumps to the end of the construct, otherwise it skips to the alternative (see also Compare flag):

Decompiled GTA III Vice City San Andreas Liberty City Stories Vice City Stories Compiled
IF [NOT] {condition0}
[AND|OR [NOT] {condition8}]
    {consequence}
[ELSE
    {alternative}]
ENDIF
{..214}
{.....}
{.....}
{...77}
{.....}
{....2}
 ----- 
{.....}
 ----- 
{..219}
{.....}
{.....}
{...77}
{.....}
{....2}
 ----- 
{.....}
 ----- 
{..120}
{.....}
{.....}
{...34}
{.....}
{....2}
 ----- 
{.....}
 ----- 
ANDOR {value}
    [NOT] {condition0}
    [[NOT] {condition8}]
GOTO_IF_FALSE ELSE
    {consequence}
    [GOTO ENDIF]
ELSE:
    [{alternative}
ENDIF:]

IFNOT

Not that much to say more than the preceding construct, the IFNOT control flow is built nearly in the same way. In fact, the ELSE clause points to the alternative, whereas the GOTO jumps to its end. The substantial difference consists in the substitution of GOTO_IF_FALSE with GOTO_IF_TRUE:

Decompiled GTA III Liberty City Stories Vice City Stories Compiled
IFNOT [NOT] {condition0}
[AND|OR [NOT] {condition8}]
    {consequence}
[ELSE
    {alternative}]
ENDIF
{..214}
{.....}
{.....}
{...76}
{.....}
{....2}
 ----- 
{.....}
 ----- 
{..219}
{.....}
{.....}
{...76}
{.....}
{....2}
 ----- 
{.....}
 ----- 
{..120}
{.....}
{.....}
{...33}
{.....}
{....2}
 ----- 
{.....}
 ----- 
ANDOR {value}
    [NOT] {condition0}
    [[NOT] {condition8}]
GOTO_IF_TRUE ELSE
    {consequence}
    [GOTO ENDIF]
ELSE:
    [{alternative}
ENDIF:]

WHILE

The WHILE control flow is built pretty much similarly to the previous, even though when the consequence is read the code is moved to the beginning of the construct:

Decompiled GTA III Vice City San Andreas Liberty City Stories Vice City Stories Compiled
WHILE [NOT] {condition0}
[AND|OR [NOT] {condition8}]
    {consequence}
ENDWHILE
 ----- 
{..214}
{.....}
{.....}
{...77}
{.....}
{....2}
 ----- 
 ----- 
{..219}
{.....}
{.....}
{...77}
{.....}
{....2}
 ----- 
 ----- 
{..120}
{.....}
{.....}
{...34}
{.....}
{....2}
 ----- 
WHILE:
ANDOR {value}
    [NOT] {condition0}
    [[NOT] {condition8}]
GOTO_IF_FALSE ENDWHILE
    {consequence}
    GOTO WHILE
ENDWHILE:

WHILENOT

To say the least, WHILENOT control flow follows the same constitution of both WHILE and IFNOT constructs, by exchanging GOTO_IF_FALSE with GOTO_IF_TRUE:

Decompiled GTA III Liberty City Stories Vice City Stories Compiled
WHILENOT [NOT] {condition0}
[AND|OR [NOT] {condition8}]
    {consequence}
ENDWHILE
 ----- 
{..214}
{.....}
{.....}
{...76}
{.....}
{....2}
 ----- 
 ----- 
{..219}
{.....}
{.....}
{...76}
{.....}
{....2}
 ----- 
 ----- 
{..120}
{.....}
{.....}
{...33}
{.....}
{....2}
 ----- 
WHILENOT:
ANDOR {value}
    [NOT] {condition0}
    [[NOT] {condition8}]
GOTO_IF_TRUE ENDWHILE
    {consequence}
    GOTO WHILENOT
ENDWHILE:

REPEAT

Seemingly, the REPEAT control flow 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* programmers, that is iterating at least once else the construct is useless. However, there are few chance they decide to use such structure to avoid some conflict with some other constructs:

Decompiled G/L Vice City San Andreas Liberty City Stories G/L Vice City Stories Compiled
REPEAT {times} {varname}
    {consequence}
ENDREPEAT
{....4}
 ----- 
{.....}
{....8}
{...40}
{...77}
{....5}
 ----- 
{.....}
{....9}
{...41}
{...77}
{....4}
 ----- 
{.....}
{....7}
{...21}
{...34}
{varname} = {value0}
LOOP:
{consequence}
++ {varname}
    {varname} >= {valueN}
GOTO_IF_FALSE LOOP

SWITCH

In San Andreas, the SWITCH control flow 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 right after the command mentioned earlier:

Decompiled San Andreas Compiled
SWITCH {varname}
    CASE {value0}
        {consequence}
        BREAK
    [CASE {valueN}
        {consequence}
        BREAK]
    [DEFAULT
        {alternative}
        BREAK]
ENDSWITCH
{.2161}
{.2162}
 ----- 
{.....}
{....2}
 ----- 
{.....}
{....2}
 ----- 
{.....}
{....2}
 ----- 
SWITCH_START {varname} {numcases} {isdefault} DEFAULT {value0} CASE0 ...
[SWITCH_CONTINUED ... {valueN} CASEN [-1 ENDSWITCH]]
CASE0:
    {consequence}
    GOTO ENDSWITCH
[CASEN:
    {consequence}
    GOTO ENDSWITCH]
[DEFAULT:
    {alternative}
    GOTO ENDSWITCH]
ENDSWITCH:

In Liberty City Stories and Vice City Stories, such control flow is a set of nested IF constructs which causes a very slight loss of performance by considering that ANDOR isn't compiled:

Decompiled G/L Liberty City Stories G/L Vice City Stories Compiled
SWITCH {varname}
    CASE {value0}
        {consequence}
        BREAK]
    [CASE {valueN}
        {consequence}
        BREAK]
    [DEFAULT
        {alternative}
        BREAK]
ENDSWITCH
 ----- 
{...56}
{...77}
{.....}
{....2}
 ----- 
{...56}
{...77}
{.....}
{....2}
 ----- 
{.....}
 ----- 
 ----- 
 ----- 
{...57}
{...77}
{.....}
{....2}
 ----- 
{...57}
{...77}
{.....}
{....2}
 ----- 
{.....}
 ----- 
 ----- 
 ----- 
{...27}
{...34}
{.....}
{....2}
 ----- 
{...27}
{...34}
{.....}
{....2}
 ----- 
{.....}
 ----- 
 ----- 
CASE0:
    {varname} = {value0}
GOTO_IF_FALSE CASEN
    {consequence}
    GOTO ENDSWITCH0
CASEN:
        [{varname} = {valueN}
    GOTO_IF_FALSE DEFAULT
        {consequence}
        GOTO ENDSWITCHN
    DEFAULT:
        [{alternative}
    ENDSWITCHN:]]
ENDSWITCH0:

Optimization

In Liberty City Stories and Vice City Stories, whenever a single condition is checked ANDOR doesn't get compiled cause no logical operator (AND, OR) is used and so they become really useless. Its lack increases 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. Furthermore, Stories Games come with an improved data type managing which causes a considerable decrease of the compiled file size.

Tools

See also

External links