Difference between revisions of "Create a script"

From GTAMods Wiki
Jump to navigation Jump to search
m (See Also)
(Loops)
 
(10 intermediate revisions by 4 users not shown)
Line 1: Line 1:
'''Creating a simple thread''' is one of the first steps in understanding how to code. This article will show you the basic steps on how to create the simplest thread using [[Sanny Builder]]. It should work for [[GTA 3]], [[Vice City]], and [[San Andreas]].
+
This tutorial will show you the basic steps on how to '''create a simple script''' in the <code>[[main.scm]]</code> using the latest version of [[Sanny Builder]]. This tutorial applies to [[GTA III]], [[Vice City]], and [[San Andreas]].
  
== Create your thread ==
+
== Start your script ==
First create your thread using opcode [[004F]] (or ''create_thread'' command). Find
+
Prior to the advent of [[CLEO]], this section was one of the first steps in understanding how to create scripts. First make sure you are working with a decompiled <code>main.scm</code> file. If you don't have a decompiled file, go to Sanny Builder and press F5. Find and open the <code>main.scm</code> file for decompiling. The program will create the <code>main.txt</code> file in the same directory. That is the file you will be working with. Now we need a command to start your first script by using opcode [[004F]] (or ''create_thread'' command). Find:
<source lang="scm">create_thread</source>
+
<pre<includeonly></includeonly> class="sb-code"><span class="k">create_thread</span>
Insert before it
+
</pre>
<source lang="scm">004F: create_thread @mythread</source>
 
''mythread'' is an arbitrary [[label]]. You can name the label with anything.
 
  
== Insert your contents ==
+
Insert before it:
Next you have to insert the contents into your thread. Find
+
<pre<includeonly></includeonly> class="sb-code">004F: <span class="k">create_thread</span> <span class="nl">@simple_script</span>
<source lang="scm">//-------------Mission 0---------------</source>
+
</pre>
That is where the MAIN section ends and the first mission begins. Insert your contents between it. The simplest format of a thread have this format
 
<source lang="scm">:mythread
 
// Insert your contents here
 
004E: end_thread</source>
 
The contents can include simple [[opcode]]s or longer threads like in the examples of [[009A|creating a ped]] and [[00A5|creating a vehicle]].
 
  
== Thread names ==
+
''simple_script'' is an arbitrary but unique name for a [[label]]. It helps the game locate your script.
Your thread can have a name. Use opcode [[03A4]] to name your thread. It is essential if you need to end your thread from another part of the script with opcode [[0459]].
+
 
 +
== Create your script ==
 +
Next create your script by inserting it in the appropriate place. Find:
 +
<pre<includeonly></includeonly> class="sb-code"><span class="c1">//-------------Mission 0---------------</span>
 +
</pre>
 +
 
 +
That is where the MAIN section ends and the first mission begins. Insert your script between it. The simplest scripts have this format:
 +
<pre<includeonly></includeonly> class="sb-code"><span class="nl">:simple_script</span>
 +
<span class="c1">// Insert your code here</span>
 +
004E: <span class="k">end_thread</span>
 +
</pre>
 +
 
 +
Your script can include a series of [[List of opcodes|opcodes]] like [[0109|adding cash to you]] or [[010D|setting your wanted level]]:
 +
<pre<includeonly></includeonly> class="sb-code"><span class="nl">:simple_script</span>
 +
0109: player <span class="nv">$PLAYER_CHAR</span> money += <span class="m">1000</span>
 +
010D: set_player <span class="nv">$PLAYER_CHAR</span> wanted_level_to <span class="m">6</span>
 +
004E: <span class="k">end_thread</span>
 +
</pre>
 +
 
 +
More complex code can be placed there instead, including [[Spawn a ped#Full example|spawning a ped]], creating a [[clothes pickup]], or creating a [[moving gate]]. Check out the [[:Category:Code Snippets|Code Snippets category]] for some code that you can use.
 +
 
 +
Your script can have an optional name with which the game can identify by using opcode [[03A4]]. A maximum of 7 characters are allowed for the name. If needed, through different scripts you can end your script with opcode [[0459]].
 +
<pre<includeonly></includeonly> class="sb-code"><span class="nl">:simple_script</span>
 +
03A4: name_thread <span class="s1">'SCRIPTA'</span>
 +
 
 +
<span class="nl">:simple_script_start</span>
 +
<span class="c1">// Insert your code here</span>
 +
004E: <span class="k">end_thread</span>
 +
</pre>
  
 
== Loops ==
 
== Loops ==
The example above shows you a thread that ends straight away. If you want the thread to run continuously, you have to loop the thread. For the most part, looping the thread requires opcode [[0001]] (or ''wait'' command) to be placed somewhere within the loop or else the game will crash. There are exceptions but it is safer to have it. The simplest loop has this format
+
The example above shows you a script that ends immediately. If you want your script to run continuously, you have insert a loop. If the loop runs for indeterminate number of iterations depending on the player input or game functions (e.g. checking for the player to walk at coordinates, or the game clock to match some value) you have to place opcode [[0001]] (or ''wait'' command) somewhere within the loop or else the game will hang. If the number of iterations is finite (e.g. iterating over a list of items), you don't need to use 0001. The simplest loop has this format:
<source lang="scm">:mythread
+
<pre<includeonly></includeonly> class="sb-code"><span class="nl">:simple_script</span>
0001: wait 0 ms
+
<span class="k">while</span> <span class="k">true</span>
// Insert your contents here
+
    0001: <span class="k">wait</span> <span class="m">0</span> ms
0002: jump @mythread</source>
+
    <span class="c1">// Insert your code here</span>
This thread will repeat itself indefinitely so be careful what you put in it.
+
<span class="k">end</span>
 +
</pre>
 +
 
 +
This script will repeat itself indefinitely so be careful what you put in it. In older or decompiled scripts, you may see this format:
 +
<pre<includeonly></includeonly> class="sb-code"><span class="nl">:simple_script</span>
 +
0001: <span class="k">wait</span> <span class="m">0</span> ms
 +
<span class="c1">// Insert your code here</span>
 +
0002: <span class="k">jump</span> <span class="nl">@simple_script</span>
 +
</pre>
 +
 
 +
This style is lower level and behaves equivalently to the prior example script.
  
 
== Conditions ==
 
== Conditions ==
Conditional opcodes checks whether the action is performed rather than to perform the action. In Sanny Builder, they are noted by spaces between the opcode and the description of the opcode. Conditions start with IF statements that checks if an action is performed.
+
Conditional opcodes are used to check whether the action is performed rather than to perform the action. If the condition is satisfied, it returns true, otherwise it returns false. In Sanny Builder, conditional opcodes are noted by spaces between the opcode and the description of the opcode. Conditions start with IF statements that checks if an action is performed.
<source lang="scm">:Check
+
<pre<includeonly></includeonly> class="sb-code"><span class="nl">:simple_script</span>
0001: wait 0 ms
+
<span class="k">while</span> <span class="k">true</span>
00D6: if
+
    0001: <span class="k">wait</span> <span class="m">100</span> ms
// Conditional opcode
+
    <span class="k">if</span>
0256:  player $PLAYER_CHAR defined
+
        <span class="c1">// Conditional opcode, e.g.</span>
004D: jump_if_false @CheckEnd
+
        00E1:  player <span class="m">0</span> pressed_key <span class="m">13</span>
// Command
+
    <span class="k">then</span>
 
+
        <span class="c1">// Command if the condition returns true, e.g. if the key is being pressed, then add $2000</span>
:CheckEnd
+
        0109: player <span class="nv">$PLAYER_CHAR</span> money += <span class="m">2000</span>
0002: jump @Check</source>
+
    <span class="k">else</span>
For IF statements with more than one conditions, you need to either add ''and'' or ''or'' after ''00D6: if''.
+
        <span class="c1">// Command if the condition returns false, e.g. if the key is not being pressed, then subtract $10</span>
 +
        0109: player <span class="nv">$PLAYER_CHAR</span> money += -<span class="m">10</span>
 +
    <span class="k">end</span>
 +
<span class="k">end</span>
 +
</pre>
  
'''if and''' means if all of the conditions are met.
+
In older or decompiled scripts, you may see this format:
<source lang="scm">:Check
+
<pre<includeonly></includeonly> class="sb-code"><span class="nl">:simple_script</span>
0001: wait 0 ms
+
0001: <span class="k">wait</span> <span class="m">100</span> ms
00D6: if and
+
00D6: <span class="k">if</span>
// First condition
+
<span class="c1">// Conditional opcode, e.g.</span>
00E1:  player 0 pressed_key 4
+
00E1:  player <span class="m">0</span> pressed_key <span class="m">13</span>
// Second condition
+
004D: jump_if_false <span class="nl">@simple_script_check_failed</span>
00E1:  player 0 pressed_key 19
+
<span class="c1">// Command, if the condition returns true, e.g. if the key is being pressed, then add $2000</span>
004D: jump_if_false @CheckEnd
+
0109: player <span class="nv">$PLAYER_CHAR</span> money += <span class="m">2000</span>
// Command
+
0002: <span class="k">jump</span> <span class="nl">@simple_script_end</span>
 
 
:CheckEnd
 
0002: jump @Check</source>
 
This means if '''both''' the first '''and''' second conditions are met, perform the command. Else jump to label ''CheckEnd''.
 
  
'''if or''' means if either one of these conditions are met.
+
<span class="nl">:simple_script_check_failed</span>
<source lang="scm">:Check
+
<span class="c1">// Command, if the condition returns false, e.g. if the key is not being pressed, then subtract $10</span>
0001: wait 0 ms
+
0109: player <span class="nv">$PLAYER_CHAR</span> money += -<span class="m">10</span>
00D6: if or
 
// First condition
 
0118:  actor 0@ dead
 
// Second condition
 
0118:   actor 1@ dead
 
004D: jump_if_false @CheckEnd
 
// Command
 
 
 
:CheckEnd
 
0002: jump @Check</source>
 
This means if '''either''' the first '''or''' the second condition is met, perform the command. Else jump to label ''CheckEnd''.
 
  
Opcodes normally starts with the number ''0'', but conditional opcodes can start with the number ''8''. This checks if the condition is '''NOT''' performed.
+
<span class="nl">:simple_script_end</span>
<source lang="scm">
+
0002: <span class="k">jump</span> <span class="nl">@simple_script</span>
0214:   pickup 3@ picked_up // IS picked up
+
</pre>
8214:   not pickup 3@ picked_up // is NOT picked up</source>
 
  
== Final Notes ==
+
Again, this style is lower level and behaves equivalently to the prior example script. Both of the examples above show if '''one''' condition is met (the CAMERA key is pressed), the condition is true and the first command will be performed (add $2000). Otherwise, the condition would be false and reaches the alternate command (subtract $10). For IF statements with more than one conditions, you need to either add ''and'' or ''or'' after ''if''.
Using this format requires you to start a new game. If you do not understand what is being said here, try looking into the [http://www.gtaforums.com/?showforum=109 Tutorial Forum] for more in-depth tutorials or the [http://www.gtaforums.com/index.php?showforum=49 Mission Coding Forum] on how to understand this.
 
  
== See Also ==
+
'''if and''' means if all of the conditions are met, then perform the command.
 +
<pre<includeonly></includeonly> class="sb-code"><span class="c1">// ...</span>
 +
<span class="k">if</span> <span class="k">and</span>
 +
    00E1:  player <span class="m">0</span> pressed_key <span class="m">4</span>  <span class="c1">// first condition</span>
 +
    00E1:  player <span class="m">0</span> pressed_key <span class="m">19</span>  <span class="c1">// second condition</span>
 +
<span class="k">then</span>
 +
    <span class="c1">// command</span>
 +
<span class="k">end</span>
 +
<span class="c1">// ...</span>
 +
</pre>
 +
 
 +
This shows that if '''all''' conditions (if both keys 4 and 19 are pressed in this example) are met, the command will be performed. Otherwise, the code will skip the command and continue onwards.
 +
 
 +
'''if or''' means if any one of these conditions are met, then perform the command.
 +
<pre<includeonly></includeonly> class="sb-code"><span class="c1">// ...</span>
 +
<span class="k">if</span> <span class="k">or</span>
 +
    00E1:  player <span class="m">0</span> pressed_key <span class="m">4</span>  <span class="c1">// first condition</span>
 +
    00E1:  player <span class="m">0</span> pressed_key <span class="m">19</span>  <span class="c1">// second condition</span>
 +
<span class="k">then</span>
 +
    <span class="c1">// command</span>
 +
<span class="k">end</span>
 +
<span class="c1">// ...</span>
 +
</pre>
 +
 
 +
This shows that if '''either''' condition (if either key 4 or key 19 is pressed in this example) is met, the command will be performed. Otherwise, the code will skip the command and continue onwards.
 +
 
 +
Opcodes normally starts with the number ''0'', but conditional opcodes can start with the number ''8''. This checks if the condition is '''not''' performed.
 +
<pre<includeonly></includeonly> class="sb-code">00E1:  player <span class="m">0</span> pressed_key <span class="m">4</span> <span class="c1">// IS pressed</span>
 +
80E1:  <span class="k">not</span> player <span class="m">0</span> pressed_key <span class="m">4</span> <span class="c1">// is NOT pressed</span>
 +
</pre>
 +
 
 +
== Save your changes ==
 +
Finally, after you have finished all the necessary changes, you have to compile the file you are working on by pressing F6. The compilation is successful when a "Report" dialog box pops up and your <code>main.scm</code> file is successfully modified. In order to play the game with the modification, you must start a new game or else the game can crash. Check out the [http://gtaforums.com/forum/109-tutorials/ Tutorial Forum] for more in-depth tutorials or the [http://gtaforums.com/forum/317-coding/ Mission Coding Forum] for further help on coding.
 +
 
 +
== See also ==
 
* [[Mission Scripting (Overview)]]
 
* [[Mission Scripting (Overview)]]
* [Wikipedia:Thread_(computer_science) Multithreading theory (Wikipedia)]
+
* [[CLEO/Tutorial|CLEO tutorial]]
 
 
[[Category:Mission Scripting]][[Category:GTA 3]][[Category:GTA VC]]
 
  
{{SA-navi}}
+
{{N|SA|VC|3}}
 +
[[Category:Mission Scripting]][[Category:Code Snippets]][[Category:Tutorials]]

Latest revision as of 15:56, 27 May 2019

This tutorial will show you the basic steps on how to create a simple script in the main.scm using the latest version of Sanny Builder. This tutorial applies to GTA III, Vice City, and San Andreas.

Start your script

Prior to the advent of CLEO, this section was one of the first steps in understanding how to create scripts. First make sure you are working with a decompiled main.scm file. If you don't have a decompiled file, go to Sanny Builder and press F5. Find and open the main.scm file for decompiling. The program will create the main.txt file in the same directory. That is the file you will be working with. Now we need a command to start your first script by using opcode 004F (or create_thread command). Find:

create_thread

Insert before it:

004F: create_thread @simple_script

simple_script is an arbitrary but unique name for a label. It helps the game locate your script.

Create your script

Next create your script by inserting it in the appropriate place. Find:

//-------------Mission 0---------------

That is where the MAIN section ends and the first mission begins. Insert your script between it. The simplest scripts have this format:

:simple_script
// Insert your code here
004E: end_thread

Your script can include a series of opcodes like adding cash to you or setting your wanted level:

:simple_script
0109: player $PLAYER_CHAR money += 1000
010D: set_player $PLAYER_CHAR wanted_level_to 6
004E: end_thread

More complex code can be placed there instead, including spawning a ped, creating a clothes pickup, or creating a moving gate. Check out the Code Snippets category for some code that you can use.

Your script can have an optional name with which the game can identify by using opcode 03A4. A maximum of 7 characters are allowed for the name. If needed, through different scripts you can end your script with opcode 0459.

:simple_script
03A4: name_thread 'SCRIPTA'

:simple_script_start
// Insert your code here
004E: end_thread

Loops

The example above shows you a script that ends immediately. If you want your script to run continuously, you have insert a loop. If the loop runs for indeterminate number of iterations depending on the player input or game functions (e.g. checking for the player to walk at coordinates, or the game clock to match some value) you have to place opcode 0001 (or wait command) somewhere within the loop or else the game will hang. If the number of iterations is finite (e.g. iterating over a list of items), you don't need to use 0001. The simplest loop has this format:

:simple_script
while true
    0001: wait 0 ms
    // Insert your code here
end

This script will repeat itself indefinitely so be careful what you put in it. In older or decompiled scripts, you may see this format:

:simple_script
0001: wait 0 ms
// Insert your code here
0002: jump @simple_script

This style is lower level and behaves equivalently to the prior example script.

Conditions

Conditional opcodes are used to check whether the action is performed rather than to perform the action. If the condition is satisfied, it returns true, otherwise it returns false. In Sanny Builder, conditional opcodes are noted by spaces between the opcode and the description of the opcode. Conditions start with IF statements that checks if an action is performed.

:simple_script
while true
    0001: wait 100 ms
    if
        // Conditional opcode, e.g.
        00E1:   player 0 pressed_key 13
    then
        // Command if the condition returns true, e.g. if the key is being pressed, then add $2000
        0109: player $PLAYER_CHAR money += 2000
    else
        // Command if the condition returns false, e.g. if the key is not being pressed, then subtract $10
        0109: player $PLAYER_CHAR money += -10
    end
end

In older or decompiled scripts, you may see this format:

:simple_script
0001: wait 100 ms
00D6: if
// Conditional opcode, e.g.
00E1:   player 0 pressed_key 13
004D: jump_if_false @simple_script_check_failed
// Command, if the condition returns true, e.g. if the key is being pressed, then add $2000
0109: player $PLAYER_CHAR money += 2000
0002: jump @simple_script_end

:simple_script_check_failed
// Command, if the condition returns false, e.g. if the key is not being pressed, then subtract $10
0109: player $PLAYER_CHAR money += -10

:simple_script_end
0002: jump @simple_script

Again, this style is lower level and behaves equivalently to the prior example script. Both of the examples above show if one condition is met (the CAMERA key is pressed), the condition is true and the first command will be performed (add $2000). Otherwise, the condition would be false and reaches the alternate command (subtract $10). For IF statements with more than one conditions, you need to either add and or or after if.

if and means if all of the conditions are met, then perform the command.

// ...
if and
    00E1:   player 0 pressed_key 4  // first condition
    00E1:   player 0 pressed_key 19  // second condition
then
    // command
end
// ...

This shows that if all conditions (if both keys 4 and 19 are pressed in this example) are met, the command will be performed. Otherwise, the code will skip the command and continue onwards.

if or means if any one of these conditions are met, then perform the command.

// ...
if or
    00E1:   player 0 pressed_key 4  // first condition
    00E1:   player 0 pressed_key 19  // second condition
then
    // command
end
// ...

This shows that if either condition (if either key 4 or key 19 is pressed in this example) is met, the command will be performed. Otherwise, the code will skip the command and continue onwards.

Opcodes normally starts with the number 0, but conditional opcodes can start with the number 8. This checks if the condition is not performed.

00E1:   player 0 pressed_key 4 // IS pressed
80E1:   not player 0 pressed_key 4 // is NOT pressed

Save your changes

Finally, after you have finished all the necessary changes, you have to compile the file you are working on by pressing F6. The compilation is successful when a "Report" dialog box pops up and your main.scm file is successfully modified. In order to play the game with the modification, you must start a new game or else the game can crash. Check out the Tutorial Forum for more in-depth tutorials or the Mission Coding Forum for further help on coding.

See also