Difference between revisions of "Mission Scripting (Overview)"

From GTAMods Wiki
Jump to navigation Jump to search
(Special opcodes)
 
(108 intermediate revisions by 10 users not shown)
Line 1: Line 1:
 +
{{This|This article deals with the general overview on the mission scripting in GTA 3D series (including [[GTA LCS]] and [[GTA VCS]]). It does not cover [[GTA IV]].<br>
 +
For more information about the GTA IV script read the article about the [[SCO|SCO format]].}}
 +
{{Cleanup-rewrite}}
 +
 +
'''Mission scripting''' is the process of writing scripts: small codes that control many aspects of gameplay. Although most of the game features are [[hardcoded]], still much things could be done via scripting. In fact, every single mission in Grand Theft Auto series comes from the scripts. That is, knowing the format of scripts and having a [[Mission Scripting Tools|proper tool]], it is possible to change the original missions or even create an absoletely new story plot (although scripts is [[Design Your Own Mission|not the only option]] for the latter).
 +
__TOC__
 
== Introduction ==
 
== Introduction ==
 
+
The original mission script is looked like this{{ref|src|[*]}} (taken from Vice City debug.sc file):
The original Mission Script looked something like this (taken from Vice City debug.sc file):
 
  
 
  IF IS_BUTTON_PRESSED PAD2 RIGHTSHOULDER1
 
  IF IS_BUTTON_PRESSED PAD2 RIGHTSHOULDER1
Line 20: Line 25:
 
  ENDIF
 
  ENDIF
  
Easy to read and understand, and fairly basic, so anyone with an idea of basic coding (or even English) can understand it.  However, very little code came with the game like that, the majority of the mission script comes in a file called main.scm (although in San Andreas there are alternate mains and external scripts, but they all follow the same basic format - hex codes).  Example, for the code:
+
Easy to read and understand, it is fairly basic so anyone with an idea of basic coding (or maybe even English) can understand it.  However, very little code came with the game like that. The majority of the mission script comes in a file called [[main.scm]] (although in San Andreas there are [[Mission Pack|alternate mains]] and [[external script]]s, but they all follow the same basic format - hex codes).  Example, for the code:
  
 
  IF IS_CAR_DEAD magic_car
 
  IF IS_CAR_DEAD magic_car
Line 29: Line 34:
 
  D6 00 04 00 19 01 02 45 0E 4D 00 01 FE 3D 87 02 A6 00 02 45 0E
 
  D6 00 04 00 19 01 02 45 0E 4D 00 01 FE 3D 87 02 A6 00 02 45 0E
  
As you can see, this is nowhere near as easy to understand (infact, its pretty hard to understand, even for someone who knows the SCM format), the original code (which is easy for us to understand) is compiled into this format which is easy for the game to understand.  Mission script, when compiled, is an opcode based language, this basically means all the commands are represented by (hex (base 16)) numbers, e.g. the command to tell the engine to wait is command 0001.  In the original script, all you would need to do to make the game wait is type wait, and the length (in millseconds) you want the game to wait for, just with a simple 'WAIT 0' command.  This is then compiled into commands the game can understand:
+
This is how the beginning of the [[SA SCM|San Andreas mission script]] looks like:
 
+
{| class="wikitable"
{|  
+
!width="250px"|Byte data
| style="background:red; color:white" | 01
+
!width="250px"|Decompiled data
| style="background:green; color:white" | 00
+
!width="250px"|Decompiled data with description
| style="background:blue; color:white" | 04
+
|-
| style="background:orange; color:black" | 00
+
| {{hint|A4 03|opcode}}&nbsp;&nbsp;&nbsp;{{hint|09|Data type}}&nbsp;&nbsp;&nbsp;{{hint|4D 41 49 4E 00 00 00 00|Parameter value}}||03A4: 'MAIN'||[[03A4]]: name_thread 'MAIN'
|}
+
|-
 
+
| {{hint|6A 01|opcode}}&nbsp;&nbsp;&nbsp;{{hint|04|Data type}}&nbsp;&nbsp;&nbsp;{{hint|00|Parameter value}}&nbsp;&nbsp;&nbsp;{{hint|04|Data type}}&nbsp;&nbsp;&nbsp;{{hint|00|Parameter value}}||016A: 0 0||[[016A]]: fade 0 time 0
 
+
|-
{|  
+
| {{hint|2C 04|opcode}}&nbsp;&nbsp;&nbsp;{{hint|05|Data type}}&nbsp;&nbsp;&nbsp;{{hint|93 00|Parameter value}}||042C: 147||[[042C]]: set_total_missions_to 147
| style="background:red; color:white" | The first number is the SECOND HALF of the opcode
+
|-
| style="background:green; color:white" | the second is the FIRST HALF of the opcode,
+
| {{hint|0D 03|opcode}}&nbsp;&nbsp;&nbsp;{{hint|05|Data type}}&nbsp;&nbsp;&nbsp;{{hint|BB 00|Parameter value}}||030D: 187||[[030D]]: set_max_progress 187
| style="background:blue; color:white" | the third is the data type (more on these later)
 
| style="background:orange; color:black" | and the fourth is the amount of time (in milliseconds in hex - this is a parameter,
 
|} any additional data to define the usage of an OpCode is a parameter) for the game to wait, but for anything but the most advanced editing (very few people can directly edit the SCM in its raw form), no knowledge of the compiled version is required. The third and fourth numbers can repeat up to 16 times, depending on amout of parameter that the function takes.
 
 
 
== Special opcodes ==
 
 
 
There are special opcodes, which do not follow the usual parttype structure such as: <br>
 
004F - create thread and 0913 - run external script have variable amout of parameters, maximum 16 parameters, they are ended with a parttype of $00.<br>
 
05B6 - defines a table (stream of data, 4 * 32 bytes long strings)<br>
 
 
 
== Data types ==
 
Data types describe what kind of data is stored in that parameter and the size of data:
 
 
 
{|style="backgroundwhite"
 
|- style="background:lightgrey;"
 
| '''data type''' || '''size (bytes)''' || '''description'''
 
|- style="background:lightgrey;"
 
| 01 || || immediate 32 bit signed int
 
|- style="background:lightgrey;"
 
| 02  || || global int/float var
 
|- style="background:lightgrey;"
 
| 03  || 2  || local int/float var
 
|- style="background:lightgrey;"
 
| 04 || 1  || immediate 8 bit signed int
 
|- style="background:lightgrey;"
 
| 05 || 2  || immediate 16 bit signed int
 
|- style="background:lightgrey;"
 
| 06  || 4  || immediate 32 bit float
 
|- style="background:lightgrey;"
 
| 07  || 6  || global int/float var array
 
|- style="background:lightgrey;"
 
| 08  || 6  || local int/float var array
 
|- style="background:lightgrey;"
 
| 09  || 8  || immediate 8 byte string
 
|- style="background:lightgrey;"
 
| 10  || 2  || global 8 byte string var
 
|- style="background:lightgrey;"
 
| 11  || 2  || local 8 byte string var
 
|- style="background:lightgrey;"
 
| 12  || 6  || global 8 byte string var array
 
|- style="background:lightgrey;"
 
| 13  || 6  || local 8 byte string var array
 
|- style="background:lightgrey;"
 
| 14  || 1+x || immediate varlen string - first you read 1 byte which gives you length of the rest which is text
 
|- style="background:lightgrey;"
 
| 15  || 0  || ????????
 
|- style="background:lightgrey;"
 
| 16  || 2  || global varlen string var
 
|- style="background:lightgrey;"
 
| 17  || 2  || local varlen string var
 
|- style="background:lightgrey;"
 
| 18  || 6  || global varlen string var array
 
|- style="background:lightgrey;"
 
| 19  || 6  || local varlen string var array
 
 
|}
 
|}
  
 
== Cracking the SCM ==
 
== Cracking the SCM ==
 +
The original SCM format was cracked shortly after the release of GTA 3 (the first game to use this mission coding method), with people having to first figure out what all the sections did (there are 5 segments is an SCM - memory, objects, mission defines, MAIN and missions (GTA SA has more), where they started/ended etc, figuring out how many parameters each [[opcode]] had and a lot more. Once this was done, they knew where each opcode began and ended, so they could split them up to make it more readable, but the data on what each one does was lost in the compiling, so they still only had something that looked like this:
  
As has been said, very little of the code was supplied with the game in an uncompiled state (only two small files, both test scripts), so how, as asked, do we create our own scripts based on the original?  With a decompiler - but how do these work (no decompilers have been provided by rockstar).
+
<source lang="scm">0001: 0
 +
00D6: 0
 +
0256: 4
 +
004D: 52000</source>
  
The original SCM format was cracked shortly after the release of GTA 3 (the first game to use this mission coding method), with people having to first figure out what all the sections did (there are 5 segments is an SCM - memory, objects, mission defines, MAIN and missions (SA has more, but only one of these (global variables) has had its use determined), where they started/ended etc, figuring out how many parameters each OpCode had and alot more.  Once this was done, they knew where each OpCode began and ended, so they could split them up to make it more readable, but the data on what each one does was lost in the compiling, so they still only had something that looked like this:
+
So the next step was to find out what each opcode does. Some were easy, the very first line of a decompiled script (besides decompiler headers) looks something like:
  
:label035F78
+
<source lang="scm">0002: @label0034B2</source>
0001: 0?
 
00D6: 0?
 
0256: 4??
 
004D: ££label67B3A7
 
  
That doesn't still doesn't mean alot though, so people had to try figure out what the different OpCodes meant.
+
The only parameter this command has is an offset within the file, so this is most likely (and in fact is) a GOTO statement, so we know all [[0002]]s are GOTOs. With trials and errors people discovered meanings of many opcodes. With the release of the mobile version of GTA San Andreas, the complete [[list of opcodes]] names became available.
  
(Note: this code is in early mission builder format:
+
Once the mission script had been cracked, people could write programs to read through it and output it in a form we could understand (based on a format of opcodes, text to say what they do and a list of parameter values - nothing like the original - the opcodes are needed to determine which opcode it is, the describing text is completely ignored).  Originally there were two main decompilers, [[Mission Builder|BWME]] ({{U|Barton Waterduck}}'s Mission Editor) and {{U|CyQ}}'s disassembler, each with their own compilers (to compile the decompiled code back into an SCM file). BWME quickly became the most commonly used, especially among newer coders, probably due to the fact that the parameters were inter-mixed with the code, so you had something like:
  
:labelxxxxxx means this code was originally at this offset in the mission script (the 'label' is added in by the decompiler)
+
<source lang="scm">00B1: is_car $car in_cube $lowerx $lowery $lowerz $upperx $uppery $upperz 0</source>
x? means a one byte number
 
x?? means a variable stored at this offset from the start
 
££labelxxxxxx is a reference to a label (i.e. for if we wanted to 'jump' to a label))
 
 
 
Some were easy, the very first line of a decompiled script (besides decompiler headers) looks something like:
 
 
 
0002: ££label0034B2
 
 
 
The only parameter this command has is a reference to a label, so this is most likely (and infact is) a jump statement, so we know all 0002's are jumps.  Of course, finding what OpCodes do (and infact finding the original number of parameters took a while to confirm) takes time, you have to have an idea first and then have to test your theory - over half the OpCodes ave still not been named, so we still dont know exactly what a huge part of the mission script does.
 
 
 
Once the mission script had been cracked, people could write programs to read through it and output it in a form we could understand (based on a format of opcodes, text to say what they do and a list of parameter values - nothing like the original - the opcodes are needed to determine which opcode it is, the describing text is completely ignored).  Originally there were two main decompilers, BWME (Barton Waterducks Mission Editor) and CyQ's disassembler, each with their own compilers (to compile the decompiled code back into an SCM file).  BWME quickly became the most commonly used, especially among newer coders, probably due to the fact that the parameters were inter-mixed with the code, so you had something like:
 
 
 
00B1: is_car $car in_cube $lowerx $lowery $lowerz $upperx $uppery $upperz 0
 
  
 
As opposed to the gtaMa/DisAsm format:
 
As opposed to the gtaMa/DisAsm format:
  
is_car_in_cube $car, $lowerx, $lowery, $lowerz, $upperx, $uppery, $upperz, 0
+
<source lang="scm">is_car_in_cube $car, $lowerx, $lowery, $lowerz, $upperx, $uppery, $upperz, 0</source>
 
 
(also note the lack of OpCode in the second example, this builder uses a lookup to find the opcode (if the function is known) instead of just quoting it)
 
 
 
Although you can't see much difference with that example, it can make a lot of difference.
 
 
 
= The Tools =
 
 
As previoulsy stated, there are two main builders for GTA 3 and VC, and a few under development for SA.
 
 
 
== Mission Builder ==
 
''(BWME - note: although BWME was a slightly different tool, I shall be referring to this as that):''
 
 
 
This tool uses only OpCodes to compile the code, all the text on the line is ignored.  Traditionally, it decompiles to a file called main.scm.txt, which is just a big text file with all the code in it, expanded to be readable.  This tool is used by the vast majority of mission coders as it is the most abundant and as most source code online is written for it, most people use it, the more people use it, the more code there is for it, so the more people use it.
 
 
 
===Code format:===
 
 
 
Early builders used data type identifiers on all numbers, these were
 
 
 
;: ? - small int (data type 04)<br>& - medium int (data type 05)<br>&& - big int (data type 01)<br>££ - global jump (data type 01)<br>£ - mission jump (data type 01 - negative addressing)<br>! - integer (data type 06)<br>$ - global variable (data type 02)<br>@ - local variable (data type 03)<br>?? - DMA global variable (like a global variable, only its memory position is its name, not assigned to it - data type 02)<br><nowiki>: - label (text directly after used to reference this label in jumps)</nowiki><br>"" - string (no data type, first 8 bytes after opcode when compiled)<br><nowiki># - model identifier (means you can enter the id name of a model rather than the number - data type 05 for the compiled number)</nowiki>
 
 
 
Later versions of the builder got rid of number type definitions, assigning types based on the size of the number.  Integers were made integers by being not a whole number (e.g. 10.5 or 10.0 if you want a whole number defined as an integer).  They also replaced DMA variables with global variables where the name was the hex address in decimal divided by 4 (each variable uses 4 bytes of memory).
 
 
 
===Advantages: === Widely used.<br>Commands related to the parameters.<br>Macros and program execution facilities inbuilt.
 
 
 
===Disadvantages:=== Creator retired (no future updates / bug fixes).<br>Decompilation bugs (especially in certain advanced jumps).<br>Many unofficially usable SCM features uncatered for (although these are mostly advanced problems never experienced by the average coder).<br>Inconvenient syntax.
 
 
 
===Other notes:=== GUI.<br>Compiler inbuilt.
 
 
 
== Point ==
 
 
 
This is still very much in the development stages, it is the first user made high-level scripting tool (infact, first high-level at all, even rockstars compiler is only an advanced parser) made for coding GTA.  Originally developed for VC/III, this tool has been expanded to work for all three 3D games.  One major disadvantage to this is that the file headers it writes, while readable by the game, are unrecognised by any line by line decompilers.  So once a file has been compiled in Point, it cannot be decompiled again by another tool to see the exact generated code.
 
 
 
== Sanny Builder ==
 
 
 
Another new tool.  This is being developed for SA initially (although porting to other games may be an option) and is loosely based on BWME code.  It was originally created using the SAscm.ini file from BWME 0.33 SA but has since been expanded to include many different features, some taken from Gtama, some new (such as a basic class system and direct HEX input (as requested by Y_Less)).  This tool is still being developed and has now introduced a basic class system so you can do things such as "player.health += 5", this system is also being adapted for point.
 
 
 
The code format is based on a combination of both Gtama and BWME formats, although you can't force data types as you could in early Mission Builders (e.g. 0004: $var = 0&& which would normally be assigned one byte, not four).
 
 
 
===Code format === (note these are for SA, not VC as the others listed are):
 
 
 
;: $ - global variable<br>s$ - global string variable<br>v$ - global long string variable<br>@ - label (text directly AFTER used to reference this label in jumps)<br>@ - local variable (number BEFORE denotes variable)<br>@s - local string variable (number BEFORE denotes variable)<br>@v - local long string variable (number BEFORE denotes variable)<br><nowiki>'...'</nowiki> - string (first 8 bytes after opcode when compiled)<br>"..." - debug string text<br># - model identifier (means you can enter the id name of a model rather than the number)
 
 
 
== Disassembler/Assembler ==
 
''(GTA Mission Assembler - gtaMa, Vice City Disassembler - DisAsm):''
 
 
 
These tools use one word commands (although these words may be multiple words conocated together by a '_' e.g. is_player_defined.  They still compile each line as-is (i.e. no interpretation or code generation) so the game will execute exactly the commands you enter (this is similar to programming in ASM memonics, whereas BWME is more similar to machine code).  The decompiled file is split up into a number of .gsr files, each one containing the code to one mission.  This reduces file sizes considerably as BWME generated files are huge (around 6mb .txt files), containing the whole code.  The code is in the format of a command, with a list commands after, separated by tabed spaces - this can make named variables easy to distiguish from commands.
 
 
 
The disassembler (DisAsm) is written by CyQ and the assembler (gtaMa) is written by Dan Strandberg.  These two tools work together to de and re-compile the code.
 
  
===Code format:===
+
(also note the lack of opcode in the second example, this builder uses a lookup to find the opcode (if the function is known) instead of just quoting it)
  
;: $ - global variable (data type 02)<br>! - local variable (data type 03)<br>@ - label (text directly after used to reference this label in jumps)<br>"" - string (no data type, first 8 bytes after opcode when compiled)<br>% - model identifier (means you can enter the id name of a model rather than the number - data type 05 for the compiled number)
+
Although you can't see much difference with that example, it can make a lot of difference. Since Barton left the modding community, {{U|Seemann}} created an even more versatile decompiler, [[Sanny Builder]]. It has become the most popular scripting tool.
  
===Advantages:=== Small files sizes.<br>Clearer code - data and commands separated.<br>Active creator (although no longer developing).<br>More support for advanced features (supports memory hacking methods not widely used).<br>Open source.<br>Online updateable ini.<br>Format used on custom error handler for VC.
+
==See also==
 +
* [[Opcode]]
 +
* [[SCM language]]
 +
* [[SCM language III/VC definitions]]
 +
* [[Mission Scripting Tools]]
 +
* [[List of opcodes]]
 +
* {{Icon|SA}} [[Design Your Own Mission]]
  
===Disadvantages:=== Not widely used.<br>Code spread across multiple files - harder for searching.<br>Data not easily related to code.
+
== External links ==
 +
* {{Icon|trilogy}} {{GTAF|section|317|Coding Forum}}
 +
* {{GTAF|section|326|Mission Mods Showroom}}
 +
* {{note|src}} [http://gtamodding.ru/wiki/%D0%9A%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F:%D0%98%D1%81%D1%85%D0%BE%D0%B4%D0%BD%D0%B8%D0%BA%D0%B8 Sources of the GTA 3 missions at GTAModding.ru]
 +
* [http://public.sannybuilder.com/sources/gta3scmsrc.zip GTA 3 Script (scm) Rockstar's original sources found in the iPad version]
  
===Other notes: === Command line based.<br>
+
{{N|SA|VC|3}}
  
[[Category:Mission Scripting]][[Category:GTA 3]][[Category:GTA VC]][[Category:GTA SA]]
+
[[Category:Mission Scripting]]

Latest revision as of 16:08, 30 October 2016

This article deals with the general overview on the mission scripting in GTA 3D series (including GTA LCS and GTA VCS). It does not cover GTA IV.
For more information about the GTA IV script read the article about the SCO format.
40px-Ambox rewrite orange.svg.png This article may need to be rewritten.
Please help improve this article. The discussion page may contain suggestions.

Mission scripting is the process of writing scripts: small codes that control many aspects of gameplay. Although most of the game features are hardcoded, still much things could be done via scripting. In fact, every single mission in Grand Theft Auto series comes from the scripts. That is, knowing the format of scripts and having a proper tool, it is possible to change the original missions or even create an absoletely new story plot (although scripts is not the only option for the latter).

Introduction

The original mission script is looked like this[*] (taken from Vice City debug.sc file):

IF IS_BUTTON_PRESSED PAD2 RIGHTSHOULDER1
AND flag_create_car = 1
AND button_press_flag = 0
	IF IS_CAR_DEAD magic_car
		DELETE_CAR magic_car
	ELSE
		IF NOT IS_PLAYER_IN_CAR player magic_car
			DELETE_CAR magic_car
		ELSE
			MARK_CAR_AS_NO_LONGER_NEEDED magic_car
		ENDIF
	ENDIF 
	flag_create_car = 0
	initial_car_selected = 0
	button_press_flag = 1
ENDIF

Easy to read and understand, it is fairly basic so anyone with an idea of basic coding (or maybe even English) can understand it. However, very little code came with the game like that. The majority of the mission script comes in a file called main.scm (although in San Andreas there are alternate mains and external scripts, but they all follow the same basic format - hex codes). Example, for the code:

IF IS_CAR_DEAD magic_car
	DELETE_CAR magic_car

The equivalent in the main.scm would look something like this:

D6 00 04 00 19 01 02 45 0E 4D 00 01 FE 3D 87 02 A6 00 02 45 0E

This is how the beginning of the San Andreas mission script looks like:

Byte data Decompiled data Decompiled data with description
A4 03   09   4D 41 49 4E 00 00 00 00 03A4: 'MAIN' 03A4: name_thread 'MAIN'
6A 01   04   00   04   00 016A: 0 0 016A: fade 0 time 0
2C 04   05   93 00 042C: 147 042C: set_total_missions_to 147
0D 03   05   BB 00 030D: 187 030D: set_max_progress 187

Cracking the SCM

The original SCM format was cracked shortly after the release of GTA 3 (the first game to use this mission coding method), with people having to first figure out what all the sections did (there are 5 segments is an SCM - memory, objects, mission defines, MAIN and missions (GTA SA has more), where they started/ended etc, figuring out how many parameters each opcode had and a lot more. Once this was done, they knew where each opcode began and ended, so they could split them up to make it more readable, but the data on what each one does was lost in the compiling, so they still only had something that looked like this:

0001: 0
00D6: 0
0256: 4
004D: 52000

So the next step was to find out what each opcode does. Some were easy, the very first line of a decompiled script (besides decompiler headers) looks something like:

0002: @label0034B2

The only parameter this command has is an offset within the file, so this is most likely (and in fact is) a GOTO statement, so we know all 0002s are GOTOs. With trials and errors people discovered meanings of many opcodes. With the release of the mobile version of GTA San Andreas, the complete list of opcodes names became available.

Once the mission script had been cracked, people could write programs to read through it and output it in a form we could understand (based on a format of opcodes, text to say what they do and a list of parameter values - nothing like the original - the opcodes are needed to determine which opcode it is, the describing text is completely ignored). Originally there were two main decompilers, BWME (Barton Waterduck's Mission Editor) and CyQ's disassembler, each with their own compilers (to compile the decompiled code back into an SCM file). BWME quickly became the most commonly used, especially among newer coders, probably due to the fact that the parameters were inter-mixed with the code, so you had something like:

00B1: is_car $car in_cube $lowerx $lowery $lowerz $upperx $uppery $upperz 0

As opposed to the gtaMa/DisAsm format:

is_car_in_cube $car, $lowerx, $lowery, $lowerz, $upperx, $uppery, $upperz, 0

(also note the lack of opcode in the second example, this builder uses a lookup to find the opcode (if the function is known) instead of just quoting it)

Although you can't see much difference with that example, it can make a lot of difference. Since Barton left the modding community, Seemann created an even more versatile decompiler, Sanny Builder. It has become the most popular scripting tool.

See also

External links