Sanny Builder

Sanny Builder is a fast and powerful tool designed for the GTA 3D game series (GTA3, VC, SA, LCS; partially VCS).

It includes a disassembler, permitting the end-user to transform the game scripts into text. The compiler feature offers a convenient editor with a large number of useful functions such as syntax highlighting, error checking, advanced search tools, player coordinates reading, fast movement through code and much more.

Sanny offers an advanced code syntax which is similar to existing programming languages. This syntax includes changeable classes, keywords and high-level statements. We recommend you continue reading and fully explore the help section to learn more about SB and its capabilities. We provide a wealth of information that will help you get started in mission coding.

Supported Games

 | Decompiling | Compiling
GTA III | + | +
GTA VC | + | +
GTA SA | + | +
GTA LCS | + | +
GTA VCS | + | -

Installation and Updates

Run the installer and follow its instructions. During installation you could optionally select the game directory you plan to work with, associate files with the .SCM extension with Sanny Builder and install the CLEO library. All these settings you always can change in the program options.

To unistall the program, run the file unins000.exe located in its root folder.

Latest versions and updates are always available at sannybuilder.com

Command line usage

\sa - run as SA editor (default)
\vc - run as VC editor
\gta3 - run as GTA3 editor
\lcs - run as LCS editor
\vcs - run as VCS editor
\sa_mobile - run as SA Mobile editor.

You can change the current edit mode in run-time.

\debug - enables the debug options
\compile input_file_path [output_file_path] - run compilation in hidden mode at the program startup

Example: \compile C:\myscm.txt C:\myscm.scm
An output_file_path parameter is optional. If there is no path specified for an output file, the compiler uses name formats. Pay attention that the source file must have no errors. If at compilation there will be errors, they will be logged in the file compile.log. When compilation ends, the program shuts down.

\nosplash - run the program without the startup screen

Credits

Delphi 7.0 Ent. © Borland Software Corp
http://www.borland.com

SynEdit © SynEdit Team
http://synedit.sourceforge.net

CHM file made with help of yelmi and Xieon.

Sanny Builder on the web:
sannybuilder.com
Sanny Builder @ Twitter
Sanny Builder @ Facebook
Sanny Builder @ GTAForums.com

For any questions contact by e-mail mail@sannybuilder.com

Use it at your own risk. In Backup We Trust.

Best regards, Seemann.

Copyright © 2005-2019 Seemann


Version History

  • v. 3.3.2 - 19.10.2019
  • v. 3.3.1 - 14.09.2019
  • v. 3.3.0 - 08.09.2019
  • v. 3.2.4 - 04.08.2019
  • v. 3.2.3 - 07.07.2019
  • v. 3.2.2 - 05.07.2014
  • v. 3.2.1 - 04.05.2014
  • v. 3.2.0 - 22.03.2014
  • v. 3.1.4 - 22.02.2014
  • v. 3.1.3 - 22.12.2013
  • v. 3.1.2 - 06.10.2013
  • v. 3.1.1 - 22.09.2013
  • v. 3.1.0 - 14.09.2013
  • v. 3.09 - 28.07.2013
  • v. 3.08 - 05.07.2013
  • v. 3.06 - 17.06.2013
  • v. 3.05 - 05.06.2013
  • v. 3.04 - 04.08.2008
  • v. 3.03 - 17.11.2007
  • v. 3.02 - 16.11.2007
  • v. 3.01 - 06.08.2007
  • v. 3.00 - 04.08.2007
  • v. 2.99e - 01.01.2007
  • v. 2.99d - 03.12.2006
  • v. 2.99c - 30.11.2006
  • v. 2.99 - 27.09.2006
  • v. 2.98 - 04.08.2006
  • v. 2.97 - 11.06.2006
  • v. 2.96 - 01.04.2006
  • v. 2.9f - 18.02.2006
  • v. 2.9 - 15.12.2005
  • v. 2.6 - 05.11.2005
  • v. 2.5 - 10.10.2005
  • v. 2.0 - 18.09.2005
  • v. 1.1 - 07.09.2005
  • v. 1.0 - 04.09.2005
  • v. 0.8 - 20.08.2005
  • v. 0.7 - 10.08.2005
  • v. 0.6 - 04.08.2005

Current Version: 3.3.3

Version changes:

  • fixed bug causing incorrect external scripts compilation

v. 3.3.2 - 19.10.2019

  • fixed bugs #0036, #0050
  • fixed opcode 059C in Vice City mode

v. 3.3.1 - 14.09.2019

  • fixed bug #0048
  • included constants.txt missing in GTA SA mode

v. 3.3.0 - 08.09.2019

  • added compiler support for Liberty City Stories SCM format
  • added aliases for the timer variables: TIMERA and TIMERB
  • changed the Ranges check option to apply to the global variables

v. 3.2.4 - 04.08.2019

  • fixed bugs #0031, #0032, #0033, #0040, #0044
  • fixed regression defect when a CHM help file can not open
  • updated opcode definitions for GTA 3 and Vice City
  • added IDE support for CLEO 2.0 for III and VC

v. 3.2.3 - 07.07.2019

  • improved support of the version of GTA San Andreas for Wi﻿nStore, Xbox 360, and P﻿S3
  • fixed an issue with opcodes 09A4 and 0A18 not being properly decompiled in SA_Mobile mode

v. 3.2.2 - 05.07.2014

  • added translation into Korean language (thanks to MINE)
  • improved HEX..END construct processing
  • fixed bug #0000028

v. 3.2.1 - 04.05.2014

  • added translation into Indonesian language (thanks to IMasterFX)
  • CLEO for GTA III and CLEO for Vice City updated (thanks to Silent)
  • fixed bugs #0000026, #0000027

v. 3.2.0 - 22.03.2014

  • adding custom edit modes by editing the games.xml file is now possible
  • new edit mode - GTA SA SCR
  • variables can be quickly declared using a type name prefix
  • CLEO updated to the version 4.3.16
  • added the InstaSearch feature (formerly 'jump to label' function)
  • mission names can be changed by editing appropriate missions.txt files
  • improved association of the script file extensions with Sanny Builder
  • Sanny Builder only checks if the game directory path is not empty, no checks for specific files (such as an .exe)
  • minor improvements in the SB updating feature
  • changed the Sanny Builder icon and the menu icons
  • fixed bug #0000024

v. 3.1.4 - 22.02.2014

  • CLEO updated to the version 4.3.14
  • fixed minor interface glitches for hi-res displays
  • updated German, Polish, Chinese, Ukrainian translations

v. 3.1.3 - 22.12.2013

  • added support for iOS and Android versions of GTA: San Andreas
  • a looking depth value is now used when making a list of constants
  • updated Chinese and German translations

v. 3.1.2 - 06.10.2013

  • added Czech translation
  • added options to associate file extensions .cs and .cm with Sanny Builder
  • fixed bugs #0000011, #0000020

v. 3.1.1 - 22.09.2013

  • added a new directive $OPCODE to register a new opcode in the script
  • corrected behaviour of the directive $INCLUDE while scanning directories for the file
  • fixed bugs #0000005, #0000019

v. 3.1.0 - 14.09.2013

  • VCSCM.ini is updated to include opcodes for the GTA VC mobile version and unsupported opcodes
  • when the option Add extra info to SCM is enabled, Sanny Builder remembers the game a script is compiled for, to use the proper edit mode when decompiling
  • when the option Add extra info to SCM is enabled, Sanny Builder adds a source code into a script file (only when the directive $EXTERNAL or $CLEO is present)
  • added a new directive $NOSOURCE to prohibit including a source code into a compiled script
  • some hotkeys are now customizable in the options
  • added a feature to check automatically if an update exists at the program startup
  • directives $VERSION and $VERSION_RESTORE are deprecated
  • updated Spanish and Chinese translations
  • The Coords manager is now able to change the player's angle in GTA VC
  • The Sanny Builder installation now includes the SCRLog CLEO plugin by LINK/2012 (can be found in the 'tools' folder)
  • fixed bugs #0000010, #0000014, #0000015, #0000016

v. 3.09 - 28.07.2013

  • Sanny Builder is licensed under the Sanny Builder Freeware/Donationware License Agreement
  • added a feature to report found bugs via the official bug tracker
  • added a feature to check if an update is available
  • The Coords manager is upgraded to work with all known versions of GTA3, VC and SA (thanks to Silent)
  • added an updated Chinese translation
  • fixed bugs #0000002, #0000003, #0000004, #0000006, #0000009
  • minor design changes

v. 3.08 - 05.07.2013

  • added Silent's ASI Loader v1.1 as a default ASI loader for CLEO 3 and CLEO 4
  • added Chinese translation
  • added classes File and Audiostream for backward compatibility with CLEO 4 by Alien*
  • the compiler now accepts a literal string as a parameter in a class property**
  • the compiler is no more allowed to compile a string like text1"text2" or text1'text2' (without a leading quotation mark)
  • the compiler is allowed to compile the comment characters within a string ("{text1}text2")
  • the semicolon (;) can not be used to comment out a line of the code
  • changed syntax of the \debug parameter
  • added flag icons for the available languages in the options
  • fixed some issues in VCS decompiling

    • * File.Open, Audiostream.Load, Audiostream.Load3D were methods in CLEO 4. Now they are properties. It means, if you get an error when compiling old sources with these commands, change their syntax to:
    var = File.Open(file_name, mode)
    var = Audiostream.Load(file_name)
    var = Audiostream.Load3D(file_name)

    ** There is a limit on using space characters in such parameter.

v. 3.06 - 17.06.2013

  • added new operators ++ and --
  • added support for block comments /* */
  • SASCM.INI is updated with help of the GTAG Database
  • properties Actor.Armour and Actor.Car are replaced with their correct versions Actor.AddArmour and Actor.MissionCar
  • added new property Actor.CurrentCar for the opcode 03C0 in the SA and VC classes.
  • added new hotkeys Ctrl+Num+ and Ctrl+Num- to quickly change the text size
  • Sanny Builder now remembers a number of closed files for the option Load all closed files
  • fixed bug when the compiler failed to compile numerous hex..end constructs
  • fixed bug of version 3.05 when the program hung on startup trying to open a file passed as a parameter

v. 3.05 - 05.06.2013

  • added new translations for the following languages: finnish, polish, hungarian, turkish, ukrainian
  • the CLEO library updated to version 4.1.1.30f (CLEO 4 by Alien)
  • added possibility to install CLEO for GTA III and Vice City (made by Alien)
  • the opcode files (**SCM.ini, opcodes.txt) replaced with the ones from the CLEO 4 library installation
  • new command line parameter \nosplash

v. 3.04 - 17.08.2008

  • the editor got abilities to convert hexadimal numbers to decimal ones and vice versa (Ctrl+H), and convert the model names to their IDs (Ctrl+Alt+H)
  • removed the complaining message about the script.img being used by the game when compiling a CLEO script
  • the compiling report displays size of a CLEO script (as Largest script)
  • fixed bug when compiling an array with constant numeric indexes
  • the installer no longer requered the system administrator rights

v. 3.03 - 17.11.2007

  • the previous version of CLEO had a bug
  • minor changes (the toolbar position wasn't saved)

v. 3.02 - 16.11.2007

  • new version of the CLEO library
  • main toolbar is movable
  • F7 while compiling SCM with no header (with $E, $CLEO directives) does not make a copy of the output file
  • while compiling a source file with directive $CLEO by pressing F6, the output file is created at the same directory; if by pressing F7 a copy of the output is created at the CLEO directory (like with common SCM files)
  • new translations: italian, portuguese

v. 3.01- 06.08.2007

  • bug-fixes update

v. 3.00 - 04.08.2007

  • the CLEO 3 library is integrated into Sanny Builder
  • VCS SCM format support (decompiling only)
  • constants support
  • new directives $INCLUDE,$EXTERNAL,$CLEO
  • writing of the additional info in the end of the main.scm
  • custom arrays support
  • possibility to decompile the files having no header
  • ability to create an external script named AAA
  • new command line parameter \compile
  • possibility to use the floating-point values as a counter value in FOR..END loop
  • the commands WriteMem and ReadMem are not supported anymore
  • possibility to use the regular expressions when searching
  • possibility to save a source file in the RTF or HTML formats
  • ability to skip the splashes at SA startup
  • new key combo Ctrl+Enter
  • updated SASCM.INI

v. 2.99e - 01.01.2007

  • fixed bug when parts of the code within the HEX..END contruction disappeared in the debug_mode decompiling
  • a hex..end statement could accept the aDMA type
  • a FOR statement could accept the model identifiers as the counter values
  • a hex..end statement could accept the strings

v. 2.99d - 03.12.2006

  • Memory Hacker became a separate tool. Now downloadable at: http://sannybuilder.com/downloads
  • fixed a decompiler bug

v. 2.99c - 30.11.2006

  • added the Memory Hacker plug-in
  • possibility to decompile the main.scm of Liberty City Stories
  • support for numbers as indexes of global arrays
  • global variables are decompiled with the type aDMA (&) if are not dividable by 4
  • at compilation the default values for the segments are used when the file header is not present
  • possibility to Drag&Drop a file into the editor to open it
  • new preprocessor directives: {$VERSION}, {$VERSION_RESTORE}

If you get a compiler error message like "Unknown directive xxxx" when compiling the sources from v2.99, replace the line {$VERSION xxxx} to any place after the header, for instance before the comment //-------------MAIN---------------

v. 2.99 - 27.09.2006

  • added new commands WriteMem and ReadMem
  • support for hexadimal numbers
  • HEX..END statement can accept labels and global variables
  • full support for the ADMA datatype
  • opportunity to give custom names to labels
  • opportunity to choose a different case for custom names and strings (Options->Format)
  • added the console in order to switch the special options of SB
  • decompiler supports the GXT-files of GTA III & GTA VC
  • added special symbol constants in the long strings
  • information about an INI file (version, author, date)
  • classes support an original order of the parameters (like in SASCM.INI from PLPynton). In order to support such order there should be a line {$VERSION x.0.xxxx}, see comments in the INI about this
  • added option to confirm exit program
  • quick switching of the Edit Mode
  • converting of the selected piece of code
  • opportunity to pass the current file name to the external tool
  • corrected some mistakes in the configuration files
  • removed auto-casting of an integer number to a float one when the variable was declared as Float. Now the compiler chooses an opcode depending on the number type only (in math expressions without opcodes)
  • reading/writing of the player's z_angle in Coord Manager; quick insertion of this one in a script by pressing Ctrl+Shift+E (for SA)

Other notes:
The following opcodes were changed in SASCM.INI: 0181, 00c3, 00c4 in order to support the commands WriteMem and ReadMem. In original files these opcodes are not used and the games do not support them so there should be no problem.

The class member Car.SetSpeedInstantly was named incorrectly (with wrong opcode) in the file classes.db for SA. If you get the error message about this method at compilation, rename it in Actor.DrivingPlane manually. We apologize.

v. 2.98 - 04.08.2006

  • Sanny Builder became multilingual
  • added menu for external applications
  • the special version of Opcode Search Tool is built in SB Details in a file 'OST Readme.txt'
  • checking of the math expressions while decompiling when the option "Write opcodes" is disabled (to sure that all the opcodes were used correctly)
  • an opportunity to choose an IMG-file manually if the last one is not found in a folder with the SCM-file (an option "Manual IMG opening")
  • an opportunity to add new macros directly from the editor; added macros descriptions
  • the list of models can be sorted alphabetically/by value (Alt+S when the list is active)
  • minor corrections and changes

v. 2.97 - 11.06.2006

  • new data type: & that denotes direct byte address (ADMA).
  • minor updates

v. 2.96 - 01.04.2006

  • improved the option jump to label
  • added an opportunity to call macros list of macros
  • added an option of replacement of mission numbers with their names
  • fixed some bugs

v. 2.9f - 18.02.2006

  • model names is added to the DEFINE OBJECT list by the compiler (this list may be not presented in the source file at all)
  • block comments support {}
  • macrorecording
  • minor changes

v. 2.9 - 15.12.2005

  • additional commands (see by item 2.5) are added
  • operator IN is added
  • construction IF..THEN..ELSE..END is added
  • loops WHILE, REPEAT are added
  • the opportunity of use of the enclosed loops is added.
  • function alloc() is added, allowing to specify for a variable the specific address in memory
  • new comment style: //
  • positions of markers and the cursor are remembered for the closed files

v. 2.6 - 05.11.2005

  • full support of formats of Vice City and GTA3 is added
  • the opportunity of initialization of variables and files as members of a class is added
  • display of the list of variables and labels is added
  • support of loops (FOR operator) is added
  • minor changes:
  • missions can be started on their name (start_mission MYMISSION), where MYMISSION is a name of a starting label (DEFINE MISSION 100 at @MYMISSION)
  • the list of imported models (defined objects) on Ctrl+Space is accessible
  • new operator <>
  • if at decompiling it is not found script.img, it is used original
  • for arrays the type handle is added
  • an opportunity of switching-off of the warning of use IMG by game

v. 2.5 - 10.10.2005

  • added "properties" support
  • added macroes support
  • added construction VAR...END for variables management
  • all math commands can be used without opcodes [0004..008B]
  • new operators < and <=
  • added a capability that the compiler itself set necessary value for IF command
  • added "extended" parameters support
  • added models list showing
  • minor changes and fixes

v. 2.0 - 18.09.2005

  • added classes support
  • added keywords support
  • added a capability to write some math commands without opcodes (now such capability exists for opcodes 0004,0005,0006,0007,0038,0039,0042,0043)
  • for opcode 00D6 the default parameter is 0 (if = if 0)
  • added the option of a choice of various kinds of labels (Formats-> Labels Format)
  • added keywords True and False which designate 1 and 0 accordingly
  • added construction HEX...END for writing hexadecimal values directly in SCM

v. 1.1 - 07.09.2005

  • added coords manager
  • some bugs fixed

v. 1.0 - 04.09.2005

  • new format of labels
  • added convertor from BW''s SA Mission Builder syntax
  • at decompiling names of models and texts from american.gxt are added in source
  • added new options
  • some bugs fixed

v. 0.8 - 20.08.2005

  • added the capability to associate SCM-files with the program
  • after decompilling the output file get an addition index if a file with same name already exists. (e.g, if main.scm.txt already exists, a new file will be main.scm[0].txt
  • error messages becames more informative
  • added check of label redeclaring
  • some bugs fixed

v. 0.7 - 10.08.2005

  • added new options for the text editing
  • added a capability to work with several files simultaneously
  • added a function to auto-complete a line with the F1 button (beta)

v. 0.6 - 04.08.2005

  • full decompiling of GTA SA SCM files
  • compiling of the source files into a SA SCM file and an IMG file
  • some options for the text editing


Sanny Builder Help: Coding

  • Data types
  • Variables
  • Constants
  • Arrays
  • Conditions
  • Loops
  • Classes
  • Keywords
  • Additional commands
  • HEX..END
  • Directives


Data types

$ - global variables.

0004: $MyVar = 100

@ - (in the beginning): of a label. The text directly after is used to reference the label in jumps

0002: jump @MyLabel

(in the end): a local variable. Number BEFORE denotes a variable

0006: 100@ = 10

'...' - short string (15 chars max).

03A4: name_thread 'MAIN'

Empty string is also allowed: ' '

"..." - long string (maximum length is determined by the opcode it uses)

Single quotes do not need anything special, but to use double quotes you must specify slash char \ before a quote.

Empty string is also allowed: " "

0662: write_debug_message "Hello, \"world\"! \n 'Here we go!'"

s$ - global string variable

05A9: s$MyString = 'GLOBAL'

@s - local string variable

05AA: 1@s = 'LOCAL'

v$ - global long string variable

06D1: v$MyString = "LONG_GLOBAL"

@v - local long string variable

06D2: 1@v = "LONG_LOCAL"

# - model identifier from '.ide' files

0247: request_model #CELLPHONE

& - ADMA (Advanced Direct Memory Access).
Reads/writes the values within the SCM even not in the variables block.
Does not affect the second segment size.

ADMA can be used the same as a global variable.

&57 += &120(&231,4i)

0x - a hexadimal number
-0x - a negative hexadimal number

0004: $var = -0xBB08

A number has to be within -80000000..7FFFFFFF range.


Variables

A variable (var) is a named storage location that contains a value and can be read/rewrite many times. There are two types of variables:

Global variables

Global variables are denoted by the $ character put before the name identifier. A global variable name is any combination of letters, underscores, and digits:

$variable1 $100 $____

Their values are available from any place of a code.

Saved Variables

A saved variable is a special global variable available only in LCS and VCS modes. It is denoted by a combination of the dollar and the underscore put before the name identifier: $_var. The value of this variable persists across saved games. Values of global variables denoted by the dollar sign only ($var) are not saved and they get blank values when the LCS or VCS game loads.

Local variables

Local variables are denoted by the @ characher put after the name identifier. A local variable name can only include digits:

0@ 999@ 56@

Their values are available only within the current thread or mission.

Threads, external scripts and CLEO scripts have a limited amount of local variables. Refer to the limits documentation to find out exact ranges.

Timer Variables

Each script or mission have 2 special local variables called TIMERA and TIMERB. The value of a timer variable is increased automatically when the game clock advances, so they are commonly used to measure elapsed time in the script.

0006: TIMERA = 0

:WAIT_2S
0001: wait 0 ms
00D6: if
0019:   TIMERA > 2000
004D: jump_if_false @WAIT_2S
0662: printstring "2 seconds has passed"

Note that TIMERA and TIMERB names are only available starting with Sanny Builder v3.3.0. Older scripts have these timers as numeric variables 16@, 17@ (GTA3, VC) or 32@, 33@ (SA).

VAR..END construct

Variables are commonly used in expressions. If the right operand is a number constant, the opcode is not needed:

$var = 0
$myarray($index, 10i) >= 150

If both operands in the expression are variables, the compiler can not find a correct opcode, because types of the variables are unknown.

For example, there are two opcodes to increment a variable value: 0058 for the integer values and 0059 for the floating-point values.

0058: $Var1 += $Var2 // (int)
0059: $Var1 += $Var2 // (float)
Assuming there is no opcode, which one to use?
$Var1 += $Var2 // ??

To communicate the compiler a variable type use the VAR..END construct.

VAR..END construct allows to declare variables and their types for the advanced use.

Syntax:
var
<var name>: <type>
end

For example, if both variables are declared, the compiler is able to process the expression without opcodes:

var
$Var1 : Integer
$Var2 : Integer
end
$Var1 += $Var2 // opcode 0058

The following types of variables are supported:

  • Integer, Int - integer values
  • Float - floating-points values
  • String, ShortString - a variable containing a string literal with the fixed length (only for arrays, use s$, @s for variables)
  • LongString - a variable containing a string literal with the variable length (only for arrays, use v$, @v for variables)
  • <Class name> - any available class name

Types of local variables can be declared too.

Take a note that once the type of the variable is declared it is used for all the code following the declaration. You can redeclare variables to set a new type:

thread 'Food'
var
10@ : Float
$Var : Float
end
$var = 1
10@ = $Var
end_thread

thread 'Loop'
var
10@ : Int
$Var : Int
end
$var = 1
10@ = $Var
end_thread

In the thread named "Food" 10@ is the floating-point variable. In the one named "Loop" 10@ is the integer variable.

You can redeclare variables as many times as you need.

Short form of Declaration

Since v3.2.0 it's possible to declare a variable of a built-in type (Int, Float, String, LongString) shortly using the type name.

Syntax:
<type> <variable name>

int 0@ // 0@ declared as an integer variable.

Variable Initialization

Also you can set an initial value for the variable when declaring it. Write symbol = and then the initial value:

var
$fVar: float = 1.0
end
or
float $fVar = 1.0

Variable $fVar declared as Float and also the compiler will add an opcode in the script:

0005: $fVar = 1.0

Initialization is allowed for the variables only, not for arrays.


Constants

A constant is an identifier with a predefined value. As against a variable the value of the constant can’t be changed in run-time. At compilation the name of the constant is replaced with the value set to it. The constants can be numeric (numerals) and string (string literals), and contain an expression.

To define new constant use the construct CONST..END. It syntax looks like this:

CONST
<constant name> = <constant value>
END

The constant name is any allowed identifier (letters, numbers and “_”). There are reserved names that can’t be used, as Continue, True, And and so on.
The constant value may be a number (a model identifier, a label); a string; an expression (for example class or variable); another constant.

Example:

Copy to Clipboard
const
MoneyRequired = 30
PlayerMoney = $PLAYER_CHAR.Money
end

if
PlayerMoney > MoneyRequired
then
PlayerMoney += -1
end

At compilation the constant MoneyRequired will be replaced with a number 30 and PlayerMoney with $PLAYER_CHAR.Money.

The compiler also uses 2 internal constants True and False which values are equals to 1 and 0 accordingly.

You can use the constant elsewhere except the case:

Copy to Clipboard
const
VarName = $Var
IndexName = 25
end

VarName[IndexName] = 0

To compile such expression, you must write the opcode, for example:

0004: VarName[IndexName] = 0

Also there are the limits with using of a complex expression as a constant.

The list of the constants could be called at any place of the code by pressing Ctrl + [space].


Arrays

An array represents an indexed collection of elements of the same type (called the base type). You can work with any element directly via its index. An index numeration begins with a zero.
These arrays are supported by SA and LCS, VCS.

Syntax:

San Andreas:
<array name>(<index var name>,<size><type>)

Liberty City Stories, Vice City Stories:
<array name>(<index var name>,<size>)

<array name>: local or global variable.

<index var name>: any variable containing an index value.

<size>: any value greater than 0.

<type>: chars i f s v denote one of the array types:

i: integer 4 bytes
f: float, 4 bytes
s: shortstring, 8 bytes
v: longstring, 16 bytes

In LCS, VCS, the array elements are only 4 bytes in length. Therefore, there is no need for declaring its type.

An array could contain the elements of same type only.

Example:

Copy to Clipboard
$index = 0
$array($index,10i) = 1

Sanny Builder can work with the arrays in two easier ways:

1) declare an array using VAR..END construct

The following syntax is used:

var
<array name>: array <size> of <type>
end

e.g.:

Copy to Clipboard
var
$FloatArray: array 10 of Float
end

You can operate this array without specifying its type and size:

Copy to Clipboard
$FloatArray[$RndIndex] += 100.0

2) use a constant number as an index

For instance, you have the array $strings, containing 10 elements of type s. You can use a constant number to work with the specified element:

Copy to Clipboard
s$strings[0] = 'str1'
s$strings[1] = 'str2'
    ...
s$strings[9] = 'str10'

These variables could be used as the class name when declared:

Copy to Clipboard
$players[0].Build

By default in SA mode, the array elements decompile with the number of indexes. You can turn this feature off through the Console using the command toggle constant_indexes off. The possibility of decompiling with the number of indexes is allowed in LCS, VCS but is disabled by default. You can enable this through the Console.


Conditions

There is the operator IF to evaluate the condition. Two kinds of syntax of this statement are permitted:

  1. low-level
  2. high-level.

1. The following syntax is used:

00d6: if <N>
... <condition 1>
... <condition 2>
...
... <condition n+1>
004d: jump_if_false <label>

<N> - the parameter means total number of conditions.
0 - 1 condition
1..7 - 2 and more conditions (8 max) connected by logic operator AND.
The check returns true if ALL conditions within this return true.
21..27 - 2 and more conditions (8 max), connected by logic operator OR.
The check returns true, if even ONE condition within this return true.

<label> - a name of a label where script jumps if the check is false.

Sanny Builder allows not to use parameter for single conditions. (meaning, if is the same as if 0)

Also you can use keywords AND or OR instead of the condition's number*.
The compiler will calculate the necessary value itself.

For example:

Copy to Clipboard
if and
$var > 0
$var2 == 10.0
jf @anywhere

The compiler will write number 1 instead of 'and'.

* Option 'Conditions check' has to be enabled.
IF AND - conditions connected with the logic operator AND (1..7)
IF OR - conditions connected with the logic operator OR (21..27)

2. Sanny Builder supports high-level constructions
IF..THEN..END
IF..THEN..ELSE..END*

A condition is created by the rules described above.
After the word THEN, you have to specify the command(-s) that are executed if the condition is true.
After the word ELSE, you have to specify the command(-s) that are executed if the condition is false.

The IF statement is closed by word End.

Copy to Clipboard
if $var == 5

then
Inc($var)
else
Dec($var)
end

* Option 'Conditions check' has to be enabled.
** Nested IF statements are supported.

You can use the following relational operators*:

a == b a is equal to b
a >= b a is greater than or equal to b
a > b a is greater than b
a < b a is less than b
a <= b a is less than or equal to b
a <> b a is inequal to b

*If there is no opcode in the line. Otherwise these sign will be ignores like any other words.


Loops

A loop is a statement which allows code to be repeatedly executed. Sanny Builder supports three kinds of controls loops: repeat, while, for.

FOR loop

The FOR loop has a strictly certain number of iterations (repetitions).

Syntax:
FOR <loop variable> = <initial value> TO/DOWNTO <final value> [step = 1]
<the loop body>
END

<loop variable> - a variable used as a counter for iterations

<initial value> - a starting value of the loop variable (any value including a model identifier)

TO/DOWNTO- increment or decrement the loop variable between iterations

<final value> - a final value of the loop variable when finished (any value including a model identifier)

<step> - an optional value the loop variable will be incremented or decremented with between iterations. By default its value is equal to 1.

Example:

var
$value: int = 0
$final: int = 100
end

FOR $MyCounter = 1 to $final step 2
$value += $mycounter
end

If the starting/final values or a step value contained in variables, these variables will get the same type the loop variable has. If the loop variable is not declared with any type before using in a loop it gets an integer type. In order to use the floating-point values as the FOR loop ranges, declare the loop variable with the float type.

Example:

var
$MyCounter: float
end

FOR $MyCounter = 1.0 to $final step 2.0
end

Variables $MyCounter and $final both have the Float type after the loop.

WHILE loop

Syntax:
WHILE <loop condition>
<the loop body>
END

Example:

while not #AK47.Available
wait 0
end

The WHILE loop is working until the loop condition returns true. The condition is evaluated before the loop iterations. Hence, if the condition is false, the statement sequence is never executed.

$var = 10

while $var > 11
inc($var)
end

As the condition $var > 11 is false, the command inc($var) will never be executed.

Constants true and false are valid for the use as the loop condition.

while true
<the loop body>
end

This loop's body executes infinitely until the loop stopped with the command Break.

while false
<the loop body>
end

This loop is ignored by the compiler as the condition is never evaluated.

Currently the compiler accepts only one condition to be checked in the loop condition, but you can check more conditions within the loop body and use the commands Break and Continue.

REPEAT..UNTIL loop

Syntax:
REPEAT
<the loop body>
UNTIL <loop condition>

The repeat..until loop executes until the loop condition returns False. The condition is evaluated after iteration therefore the loop is guaranteed to be executed at least once.

Constants true and false are valid for the use as the loop condition.

repeat..until true - the loop has the only iteration.

repeat..until false - the loop executes infinitely until it's stopped with the Break command.

Currently the compiler accepts only one condition to be checked in the loop condition, but you can check more conditions within the loop body and use the commands Break and Continue.

Continue and Break

If you want to skip the current iteration and proceed to the next one, use the Continue command. The Break command causes the loop immediately to stop and proceed to the command after the loop body.

They can be used as an opcode parameter (for example, jf continue) or a separate single command.

Example:

if
    $currentactor.dead
jf Break // exit from the loop

if
    not $currentactor.dead
then
   Continue // goes next iteration
end


Classes
Basic Concepts

Sanny Builder allows you to use classes in the code. Class is a group of opcodes applied to in-game objects: player, actor, object, etc.

Each class has a set of commands (class members). They can be split into the following groups:

  • conditional opcodes
  • regular opcodes (methods)
  • properties
Conditional Commands

Conditional commands are marked with the word 'Check' in the resizable window that is displayed when you press Ctrl+Space. Many of these have only the parameter: the class owner handle (name).

Example:

Copy to Clipboard
if
Player.Defined($PLAYER_CHAR)
jf @anywhere

Player - class name
Defined - class member
$PLAYER_CHAR - class owner

Regular Commands (methods)

Regular (procedural) commands are used to complete a single in-game action: move an object, destroy this one and so on. A special kind of these commands is the constructor that creates an object (an actor, a car) and stores its handle to a variable.

In SB the constructor can be used either as method or property:

Copy to Clipboard
Player.Create($PLAYER_CHAR, #NULL, 2488.5601, -1666.84, 13.38) - procedure
$PLAYER_CHAR = Player.Create(#NULL, 2488.5601, -1666.84, 13.38) - constructor

These create the same effect.

Properties

Property allows you to read/write values to the class fields.

Example:
Property 'Money' of the class 'Player' allows to operate with the following opcodes:

Copy to Clipboard
0109: player $PLAYER_CHAR money += 1000000
010A:   player $PLAYER_CHAR money > 461@
010B: 4@ = player $PLAYER_CHAR money

With the property you can use the following commands without any opcodes:

Copy to Clipboard
player($PLAYER_CHAR).Money += 1000000
player($PLAYER_CHAR).Money > 461@
4@ = player($PLAYER_CHAR).Money

Note: that you make DIFFERENT actions using the ONLY command.

In the current version there is a limit on using space characters in the string literals used as a parameter in a property. The compiler ignores these characters. For example, the command

0@ = File.Open("file name","wb")

will be compiled as

0@ = File.Open("filename","wb")
Class Members

There is a possibility of initializing the variables as class members to use them instead of class names.

Example:

Copy to Clipboard
var
$PLAYER_CHAR: Player
end

It declares the variable $PLAYER_CHAR as member of the class 'Player'.
So, the variable can be used instead of the class name Player:

Copy to Clipboard
if
$PLAYER_CHAR.Defined
jf @anywhere

Pay attention that such variables are compiled as the first parameter and therefore, do not duplicate them.

Copy to Clipboard
Player.SetClothes($PLAYER_CHAR, "PLAYER_FACE", "HEAD", Head)
=
$PLAYER_CHAR.SetClothes("PLAYER_FACE", "HEAD", Head))

These variables can be redeclared with another type.

'Model' Class

The model identifiers are always the members of the 'Model' class.
You can reference this class using their names:

Copy to Clipboard
#AK47.Load

:loop
wait 0
if
#AK47.Available
jf @loop

It is the same as:

Copy to Clipboard
Model.Load(#AK47)

:loop
wait 0
if

Model.Available(#AK47)
jf @loop

Extended Parameters (class constants)

Some classes use parameters with special names. This possibility makes the source code more readable.

Example:

Copy to Clipboard
Player.SetClothes($PLAYER_CHAR, "VEST", "VEST", Torso)

Last parameter (Torso) is the class constant that will be replaced with the number 0 at compilation.

These parameters are defined in the file 'classes.db'.

For convenience, a list of extended parameters are displayed when you press Ctrl+Space. Simply place the cursor where there should be an extended parameter, press ctrl+space and the parameters list will be displayed.
You can then select a name from it and insert this into your code.


Keywords

A keyword is a single word that replaces the opcode for simple commands.
For example, the keyword WAIT can be used instead of opcode 0001.

To demonstrate:

wait 0

instead of

0001: wait 0

The keywords list can be displayed by pressing Ctrl+Space.


Additional commands

INC

Increments the first parameter by the second one. First parameter is a variable.

Copy to Clipboard
Inc($IntVariable, $Value)
=
$IntVariable += $Value

Second parameter is equal to 1 if isn't specified.

Copy to Clipboard
Inc(1@)
=
1@ += 1

Since version 3.06 it's possible to use a C++-like operator ++ that can be applied to variables and increments the value they hold by one.

Copy to Clipboard
$var++
=
$var += 1

DEC

Decreases the first parameter by the second one. First parameter is a variable.

Copy to Clipboard
Dec($IntVariable, $Value)
=
$IntVariable -= $Value

Second parameter is equal to 1 if isn't specified.

Copy to Clipboard
Dec(1@)
=
1@ -= 1

Since version 3.06 it's possible to use a C++-like operator -- that can be applied to variables and decrements the value they hold by one.

Copy to Clipboard
$var--
=
$var -= 1

MUL

Multiplies the first parameter by the second one. First parameter is a variable.

Copy to Clipboard
Mul($IntVariable, $Value)
=
$IntVariable = $IntVariable * $Value

Second parameter is equal to 2 if isn't specified.

Copy to Clipboard
Mul(1@)
=
1@ = 1@ * 2

DIV

Divides the first parameter by the second one. First parameter is a variable.

Copy to Clipboard
Div($IntVariable, $Value)
=
$IntVariable = $IntVariable / $Value

Second parameter is equal to 2 if isn't specified.

Copy to Clipboard
Div(1@)
=
1@ = 1@ / 2

(internal) ALLOC*
This function sets the memory address for the global variable. It has to be used only for the ones with custom names (i.e. $text). For others, the memory address is set by name: the variable $40 is always addressed at memory address #40.

Copy to Clipboard
Alloc($MyVar, 40) - the variable $MyVar will be compiled as $40

(!) See also 'help\examples\alloc.txt'

SQR

Calculates the square of a variable passed as a parameter*. It can be used as procedure only.

Copy to Clipboard
sqr($var)
=
$var *= $var

* variable type has to be defined. See item: (The multilingual interface)

RANDOM

This function generates a random number within a range specified by the parameters.

Copy to Clipboard
$rnd = random(1, $high)

This function can be used for both integers and floats. The opcode is chosen in accordance with the type of a result variable ($rnd in this case)


HEX..END

Sanny Builder supports writing a raw content in an output file. All values within this construct are written in an output file without any checks.

Use this feature only if you know what you're doing. Any mistakes will corrupt the script file making it unreadable by the game or a script editor.

Syntax:
hex
<any hexadimal numbers>
end

Example:

hex
04 00 02 0800 04 01
end

This sequence of bytes is a compiled opcode 0004: $2 = 1, so the game will correctly read it and set the value of the variable $2 to 1.

You must specify each byte you're going to write with two digits. All spaces are ignored. The compiler processes any two digits with a space between them as a single byte value. A single digit (0..F) is affixed with 0. So, for example, A B C is written as a number 0xAB0C.

The HEX..END construct also accepts string literals, labels, global variables identifiers, model names. They are compiled without a preceeding data type.

:get_offset
hex
04 00 02 $PLAYER_CHAR 01 @get_offset
end

This is an exact copy of the opcode 0004: $PLAYER_CHAR = @get_offset

String literals are compiled as a sequence of characters enclosed in double quotes.

hex
"This is a string"
end

The following escape sequences are supported within a string:

  • \0 - null - 0
  • \b - backspace - 8
  • \t - tab - 9
  • \n - line feed - 10
  • \r - carriage return - 13
  • \x<nn> - numeric escape sequence - nn
  • \<char> - escape char - <char>

Example:

hex
"\0\b\t\n\r\xDD"
end

It produces the following sequence of bytes: 00 08 09 0A 0D DD.

Currently multiple spaces in a string literal are converted into a single one. Thus a line "This is a string" is converted into "This is a string". Use an escape character \ to make multiple spaces in a string literal: "This \ \ \ is \ a \ \ \ \ string".

Also you can use the aDMA data type to write a numeric constant in an output file. The number after the & sign can be both positive or negative, decimal or hexadimal.

hex
&1000 &-0xA33500
end

This example produces the following sequence of bytes: E8 03 00 CB 5C FF.


Directives

Preprocessing directives are the special words that make the compiler function in different ways. They are denoted with the symbol $ and located between brackets {}.

List of available directives:

  1. $VERSION
  2. $VERSION_RESTORE
  3. $INCLUDE / $I
  4. $EXTERNAL / $O
  5. $CLEO
  6. $NOSOURCE
  7. $OPCODE / $O

$VERSION

This directive is deprecated since v3.1.0

This directive sets what version of opcodes should be used during compilation.

Syntax:
$VERSION x.y.zzzz

x - edit mode ID
y - parameters order.
0 - original, numeric
1 - custom order
zzzz - opcodes version

By default the compiler uses version current edit mode.1.0000.

$VERSION_RESTORE

This directive is deprecated since v3.1.0

This directive sets the version to its previous value prior to using $VERSION.

$INCLUDE

This directive allows to insert the content of an external text file in the current file. If the compiler finds this directive it opens the file by the path passing as the directive’s parameter and continues the compiling process from the code written in the included file. When it reaches the end of the file it returns back to the previous file.

Syntax:
{$INCLUDE file path}
or
{$I file path}

Example: {$I loadwav.txt} or {$I C:\dev\getarrayindex.txt}

If the file path is relative, the compiler searches the file in the following order:

  1. directory of the file with the directive*
  2. Sanny Builder\data\<game>
  3. Sanny Builder root directory
  4. game directory

It none of these directories contains a needed file the compiler throws an exception. You can use this directive unlimited number of times. The included files can contain this directive as well.

* All paths used in the $INCLUDE directive are relative to the directory of a currently processed file.

$EXTERNAL

This directive makes the compiler to process the file like external script. Meaning, the outputfile will be without header and with local label offsets, so it will be the same as an .scm file from the script.img. Using this directive requires that the file will contain only one thread (also without missions and other scripts).

The alternative way to get such file is a debug option SKIP_SCM_HEADER. This option could be enabled in the console or from the list on the main panel.

Syntax:
{$EXTERNAL}
or
{$E}

$CLEO

This directive is an analogue of the $E one, but the output file is copied into the ‘game\CLEO’ directory automatically. It also gets the file extension specified as a directive parameter.

Syntax:
{$CLEO <file extension>}
File extension is an optional parameter. If no extension is present, the compiler uses a default value .cs

Example: {$CLEO} // a file will get the default extension .cs

So this directive is the perfect solution to compile a CLEO script.

$NOSOURCE

This directive prohibits the compiler from including a source code of the script. By default, when the option Add extra info to SCM is enabled, Sanny Builder adds a source code into a script file (only when either the directive $EXTERNAL or $CLEO is present). This directive changes the default behaviour of the compiler, not allowing to include the source code into an output file.

Syntax:
{$NOSOURCE}

$OPCODE

This directive allows to register a custom opcode directly via the script. Commonly, all the opcodes definitions are contained in a special file, one for each supported game. But sometimes it's necessary to add a custom opcode for the current script. The directive $OPCODE makes it possible without editing an opcodes INI file.

Syntax:
{$OPCODE <opcode definition>}
or
{$OPCODE <file name>}
or
{$OPCODE}

It accepts an opcode definition in the same syntax as the INI file.

Example: {$OPCODE 0CCC=1,my_new_opcode %1d%}

This directive also accepts a file name as its parameter. This file must contain only opcodes definitions to be loaded. If no global path is specified for the file, the compiler searches it using same rules as for $INCLUDE.

Example: {$OPCODE additional_opcodes.ini}

When used without any parameter, this directive reloads the original opcodes definitions file, so all the changes made by previous using of this directive are gone.

Example: {$OPCODE}

The short variant of this directive is $O.


Sanny Builder Help: Editor/IDE

  • Options
    • General
    • Formats
    • Editor
    • Highlighter
    • Hotkeys
  • Features
  • Console
  • Hotkeys
  • Opcode Search Tool


Options

The options window is shown when you press F10. This window is divided into five pages, each of them contains certain kind of settings. By default the general settings page is open.


General

This page contains the (de)compiler options mostly.

Sanny Builder needs certain game files while working, so you have to choose a correct directory where the game is installed. You may input the path manually or by selecting the directory via the dialog appearing when you press the button.

The program also needs the INI file containing the opcodes list. You may set the path to this file here (manually or by selecting file dialog appearing when you press the button).

There is a list of available translations for Sanny Builder. The translation files are present in the folder \lang. Choose desired language for the program interface in this list. The translation instructions are contained in the file "How to translate.txt" in the folder \lang.

You may associate different file extensions with Sanny Builder. When a checkbox is selected, your Windows Registry is changed and you may open the files with this extension simply by clicking it. To cancel the association, unselect a proper checkbox.

Here you see common options of the (de)compiler.

Always overwrite output file

If this one checked, the decompiler writes decompiled data in the output file disregarding if it exists or not. If not, and the text file with such name already exists, the decompiler won’t rewrite it but create a new text file with index (for example, main[0].txt).

Show progress

While program executes (de)compiling process and if this box selected, there is a progress line in the status bar. Otherwise status bar have words: Please wait. Showing progress slightly slows the execution time.

Show warning

This option has the meaning only when San Andreas scripts are compiling. If the game is running during the compiling process, the file script.img containing the part of the scripts could not be rewrote as the game uses this file. The compiler shows a warning about it. You may disable this warning by checking this box.

Manual IMG opening

When the decompiling process started, the program searches for the file script.img containing some game scripts. If this file is not found in the same folder with the SCM file or in the San Andreas\data\scripts\ folder, the error message is shown. If this option toggled, you can select needed img file manually.

Quick game loading

Sanny Builder is able to skip SA startup splash screens (F8). If this ability causes an error in your game version, disable this option.

Check conditions

This option has two meanings. First, the program replaces the number of conditions in the IF opcode with AND or OR. Second, the program is able to compile the IF..END construct, and calculate needed IF parameter in the conditions with words AND or OR.

Ranges check

The number of local and global variables is limited. When this option is checked, the compiler checks if a variable fits the available range.

Write opcodes

This option turns the decompiling output from high-level to low-level and vice versa. If this option is unchecked, the decompiler uses available classes and keywords instead of opcodes. In addition, there are no opcodes for simple math expressions. If option checked, all opcodes are present in the output file.

Replace mission numbers

When this option checked, the decompiler replaces mission number in the opcode start_mission with mission name. The mission name is the label name defined in the file header.
This name also could be used for quick movement to the mission code.

Insert original mission names

When this option checked, the decompiler adds predefined original mission names as comments for the opcode start_mission and for the line DEFINE MISSION in the file header.

Add extra info to SCM

If this option is checked the compiler adds extra information to the end of the file main.scm. This info will be used later when this file is decompiled in order to bring it to maximum conformity with original source. The following data is added to the end of the main.scm: hex..end constructs offsets, global variables names and so on. Pay attention that the file compiled in such way cannot be decompiled in older SB versions (except the case when ignore_unknown option is enabled).


Formats

Here you can set up source file names, labels format, and identifiers case.

There the file name masks are present. The upper line contains path and name of the text file which is created at decompiling. Bottom lines contain paths and names of two binary files SCM and IMG which are created at compiling. All lines have the same syntax. It uses special words meaning part of full file name:

$dir – file path
$name – file name
$ext – file extension

Example, if you decompile the file C:\MyDir\main.scm, then

$dir = C:\MyDir;
$name = main
$ext - .scm
So, if the mask is $dir\$name.txt, the output file will be named C:\MyDir\main.txt

Here you may choose one of the various name formats for the labels used at decompiling.

Global Offset: all labels will have a numeric name, for example @12345. The number means this label’s offset in the file being decompiled.

Thread+Local Offset: label name will consist of two parts: a name of the thread where the label is (the name_thread opcode is used for this), and additionally offset from this thread’s beginning, for example @MAIN_12.

Thread + Global Offset: this option is similar to the previous one, except that after the thread name there will be not a local offset but the global one (as the first case), for example @HELP_34567.

If you want the offsets to be hexadimal, select the proper option. By default, all offsets are decimal.

These options make the decompiler use or not the custom names for various script literals.

The labels names are contained in the file CustomLabels.ini in the folder SB\data\<game>. This file contains the list of labels names and offsets (for main.scm version 1.0). If the first box checked, the decompiler names the label as defined.

The variables names are present in the file CustomVariables.ini for each game. It looks like the list of global variables addresses (DMA) and their textual representation. If this box checked, the decompiler gives to the global variable its custom name.

The arrays names list are present in the file CustomArrays.ini. Its syntax is as follows: the first number is the global variable name (DMA) which is the first element of the array (array name), the second – array size, the third – custom name. This option is used in order to decompiler adds an index to some global variables being an array. So, these variables become indexed ones.

This option has two meanings. The decompiler names global variables, labels, arrays using the selected letters case. The compiler writes the strings in the SCM using the selected letter case also.


Editor

Here you can change the IDE settings.

Colors

The following options allow to set up different colors for the editor.

Active line - color of the line where the cursor is

Gutter - color of the padding area on the left to the code area of the editor

Editor - color of the code area background

Common options

The looking depth value is used while searching constants, labels and variables through the code when you press the Ctrl + [space] combo. This value tells the editor how much lines to scan up and down from the active line. If you set a number of 0, the editor will scan the whole source file.

If the 'Auto list' option is checked, the list of available labels, models and variables appears automatically when you type symbols @, $, #.

Show main panel – toggle the main toolbar

Show opcode info – make the editor display important information in the status bar (number of expecting parameters for an opcode, model ID, variable type, etc)

Line numbers – show line numbers in the left padding area

Show gutter border – display the border line on the right side of the left padding area. Uncheck this option to increase the available space visually.

Load last closed file at startup – open the last closed file at startup

Load all closed files – open all closed files at startup. This option is only availabel when the Load last closed file at startup is checked.

Confirm when exit – confirm exit to prevent occasional program termination.

Fonts

Here you can choose the font and tune it. Sanny Builder supports only fixed-pitch fonts. The line AaBbCcDd reflects the chosen settings.


Highlighter

You may set various syntax highlighting schemes on this page. Each code element has 3 properties: Foreground, Background, and Style.
3 style elements are available: B – bold, I – italicize, U – underlined.

The selected highlighting scheme is also used at saving the code source in the RTF or HTML format.

Code elements:

Comments – the text after double-slash // or between braces {}.

Labels – the identifiers beginning with an @.

Variables – the identifiers having a dollar-sign $ in the beginning (global variables), or ending with an @ (local variables). Also the aDMA type (begins with an &) and the arrays are highlighted same as variables.

Keywords – the special words stored in the file keywords.ini (one for all games) and keywords.txt (separate file for each game).

Numbers – the integer and floating-point numbers

Strings – the text between “…” and ‘…’.

Models – the identifiers beginning with a #.

Classes – the part of the class command: the identifier before the point.

Commands – the part of the class commands: identifier after the point.

Directives – the comment containing a $ immediately after the opening {.


Hotkeys

Some hotkeys are customizable for your comfort. You may set up new keyboard shortcuts for the IDE tools, editor actions and some other features.


Features

Sanny Builder grants the end-user the following possibilities:

Syntax Highlighting

Sanny Builder highlights a code for easier understanding. The highlighting color scheme is changeable via the options.

Bookmarks / Quick jump

You can bookmark the line by pressing Ctrl+Shift+0..9 and then to pass to this one by pressing Ctrl+0..9. To delete all bookmarks, use option Edit -> Clear All Bookmarks. The second method is via an option 'Go To Line' invoked by pressing Ctrl+G. Enter a sequence number of the necessary line and the editor will move the cursor to it.

InstaSearch

The InstaSearch feature allows to find a word or a label directly in the editor without using the Find dialog box.

To find another occurrence of a word under the cursor, press Ctrl + Num6 to start searching it below in a code, or Ctrl + Num4 to search above. The cursor will immediately move to the line where such word is found. Keep pressing Ctrl + Num4/Num6 to find other occurrences of this word.

To jump to the line with a label (for example, :MyLabel), put the cursor on a label reference (@MyLabel) and press Ctrl + Num2. The editor will move the cursor to the line with this label.

If the cursor position remains the same, it means that the InstaSearch did not find the needed word in a code.

Before changing the cursor position the InstaSearch remembers where it is now, so if you want to return back press Ctrl + Num8.

Displaying Various Information About Opcode

SB displays a number of parameters for the opcode, a digital value of the model under the cursor in the statusbar when the option Show opcode info is enabled.

SA Mission Builder Source Code Converter

Sanny supports SAMB 0.33 syntax. To use the converter, open the source file in Sanny Builder and select menu item: 'Tools -> Code converter -> MB -> SB'. Note the convertor uses the file 'MB.ini' from the SB directory which contains the variables used by SAMB and their memory addresses. If you added your own variables in the file variables.ini (from the SAMB 0.33), copy them into the file MB.ini.

Opcode Search

Use a built-in Opcode Search tool to find an opcode you need.

Player Coordinates Management

Press F4 when SA is running and the Coords Manager window will appear. Here, you can set new player coords and copy the current ones. In the upper edit line, you can input all three coordinates XYZ, delimited by a single space or ",". Additionally, you can insert CJ's current coords in the text by pressing Ctrl+Shift+C. To insert the player's angle, press Ctrl+Shift+E.

Macros Support

A macro is the group of lines that are inserted in the editor when you type a macro name (for example, load) and press the F2 button. The editor will add the following piece of the code:

#.Load

while not #.Available

  wait 0

end

All macros are contained in the file 'macroes.txt'. Syntax of this file is that:
A macro name is written as a single line. The equals sign (=) should follow the macro name. After the equals sign you can also write a short description of the macro. The macro code lines follow its name, each line begins with the equals sign. The cursor position is marked with the | character

Additionally, it's possible to add a macro in the file macroes.txt directly from the editor. For this purpose, select the a piece of the code and click the "Service -> Add macros" menu. Type in the name of a new macro, the description (optionally) in the dialog window and press the OK buton. The macro is ready to be used.

To call the macros list, press Ctrl+J.

You can also record your key pressing sequence (macros) and reproduce it later. Consider the following code:

$Actor = Actor.Create(CivMale, #MALE01, 100.0, 100.0, 10.0)
$ActorWithGun = Actor.Create(CivMale, #MALE01, 110.0, 100.0, 20.0)
$Gang01 = Actor.Create(CivMale, #MALE01, 120.0, 100.0, 30.0)
$Gang02 = Actor.Create(CivMale, #MALE01, 130.0, 100.0, 40.0)
$Killer = Actor.Create(CivMale, #MALE01, 140.0, 100.0, 50.0)
$ActorWithoutGun = Actor.Create(CivMale, #MALE01, 150.0, 100.0, 60.0)

Say you need to exchange the actor's handles in each pair (i.e have $ActorWithGun instead of $Actor, and vice versa).

Put the cursor on the first line and press Ctrl+M. The editor immediately begins logging all keystrokes - so be careful!

- Press and hold Ctrl and press once [Right arrow]
- Now press Shift+Home and Ctrl+Ins.
- Press [Down arrow]. The cursor must be on the second line with the global variable on the clipboard
- Press Ctrl + [Right arrow] and Shift+Ins.
- Press Ctrl + [Left arrow], Shift+Home, Ctrl+Ins and Delete
- Press [Up arrow]
- Press Ctrl + Shift + [Right arrow] and Shift+Ins
- Press Home button.

Now the first two lines look like these:

$ActorWithGun = Actor.Create(CivMale, 100.0, 100.0, 10.0)
$Actor = Actor.Create(CivMale, 110.0, 100.0, 20.0)

and cursor is in the beginning of the first line. Now press Ctrl+M to stop recording.

Now you can repeat the recorded keystrokes by pressing Ctrl+P. Put the cursor on the third line, press Ctrl+P and the actors handles will be exchanged.

While processing, you can pause/unpause the recording by pressing Ctrl+P.

Replacing Mission Numbers With Their Names

Sanny Builder allows using a mission name in the opcode 'start_mission'. The mission name is the label defined with a DEFINE MISSION command. For example, you have:

DEFINE MISSION 10 AT @MYMISSION

Instead of start_mission 10 you can use start_mission MYMISSION.

There is also the Replace Mission Numbers option. When it's enabled, the decompiler automatically replaces all mission numbers with their names.

To call the mission names list, press Ctrl+Space. The cursor has to be directly after the start_mission command.

Additionally, you can use the InstaSearch to jump to the mission from its name.

Custom Mission Names

Since v3.2.0 Sanny supports custom mission names for each available edit mode. Mission names are commonly stored into a file missions.txt located in a data\<game> folder. This file is used by the decompiler to comment each mission entry with its title. If a main.scm file contains some custom missions you may edit this file to have proper titles after decompiling.

Multilingual Interface

Sanny Builder has fully multilingual interface translated into 15 languages. You can switch languages in the options (F10). The file 'lang\How to translate.txt' contains more information about creating your own translation.

External Tools/Plug-ins Menu

You can add up to 9 tools which can be executed whenever you need them. Every tool has its own hotkey for your convenience. You may also pass the parameters to your tool. To pass the name of the current opened file use a special word $SB_FileName.

Commenting Code

Comments are denoted by a double slash //, as seen in other scripting languages (php etc.). All text placed after // (within that same line) will be ignored by the compiler.

To comment out multiple lines or part of the line, use block comments {}:

0001: wait  {comments here} 0 ms

Since version 3.06 Sanny Builder also supports C++-like comments /* */.

0001: wait  /* comments here */ 0 ms

Also it is possible to comment out multiple lines by selecting them and pressing Ctrl+Q. To uncomment the lines repeat it once again.

Custom Labels

You can give labels custom names that are not dependent on decompiler options. The names are specified in the file CustomLabels.ini (separately for each game).

File syntax:
<label offset>=<custom name>

If the decompiler finds a label at the specified offset, it will get the custom name.

To find out the label offset set the labels format to "Global Offset" in the options. After decompiling, the number in a label name is its offset.

Checking for updates

Sanny Builder is able to check if a new version is available. To use this feature go to menu "Help->Check for update...". The editor will connect to the update servers and propose to download and install an update file if the latter exists. The editor can automatically check for an available update at startup if you enable this option in the updater window.


Edit Modes

An edit mode is a set of options determining behaviour of Sanny Builder when working with scripts of a particular game. Fact is, there is no game in the GTA series with the script format same to the others. So, each game requires special settings while editing scripts. That's the reason why the edit modes are introduced in Sanny Builder.

An edit mode includes (but not limited to) the following options:

  • Sanny Builder disassemble a script file in a specific way
  • Sanny Builder can compile a script for the given game
  • you may run the game or read/change the player coordinates

By default, there are 7 different modes:

  • GTA III
  • GTA VC
  • GTA SA (for custom named opcodes)
  • GTA LCS
  • GTA VCS
  • SA Mobile (for Android and iOS versions)
  • GTA SA SCR (for original R* names)

You may add a new mode by manual editing the file games.xml located in the <SB>\data\ directory.

To switch the edit mode, click at the right bottom corner of the Sanny Builder's main window. A list of the available modes will appear. Choose one and click it. Sanny Builder will reload all needed files and you may start working.

Before disassembling or compiling a script, make sure that the correct edit mode is active. Even if the script is compiled with no errors, the game will crash when trying to read a script in different format.

A compiled script file may have an information which game it is made for. So, if you decompile such a script in another edit mode being active, Sanny Builder will propose you to change the mode to the correct one. Declining this prompt may cause a crash of the disassembler, because the script format is unexpected for it.


Console

The console is intented to switch the advanced options of Sanny Builder. Mostly they relate to the decompiler features and you can see the changes when decompile a file. The console window is called by pressing Ctrl + ~. You may write the commands and the parameters in the edit line. After typing a command press Enter to process. The console will display a result.

All commands are case-insensitive.

The available commands are:

help – shows the help information about the console

clear – clears the console

list – shows in the console the list of all commands

The parameter (optional):

list options – after input list options the console will display all possible options to toggle.

toggle – the major command to enable or disable the program options

The parameter:

toggle <option name> [on/off]

The options list can be different in other version. To get all possible options, type list options.

The command line might be ended either with word ON (the option will be enabled) or word OFF (the option will be disabled), or nothing (the option will be toggled from ON to OFF or from OFF to ON).

Note: First of all the debug mode should be enabled with command toggle debug_mode

toggle CODE_OFFSETS | the decompiler will print offsets of each opcode
toggle VAR_COUNTER | after compiling the console will contain the list of the global variables used once in the code. It is very useful to search the useless variables.
toggle IGNORE_UNKNOWN | makes the decompiler work in advanced way, ignoring missing opcodes, incorrect parameters and so on. It may help you It allows to decompile almost every file to crack the protected files (or the files which were compiled incorrectly).
toggle CONSTANT_INDEXES | allows to decompile the arrays with the constant number index, if possible. It's available for San Andreas (enabled by default), LCS, VCS. For example,
 |  | before | after
 |  | $10 | $10[0]
 |  | $11 | $10[1]
 |  | $12 | $10[2]
toggle SKIP_SCM_HEADER | Makes the decompiler skip the scm header while processing. Allows to decompile the external scms from the script.img separately. Also makes the compiler not to compile the scm header.

Usage of the \debug parameter is an alternate way to switch the advanced options of Sanny Builder. Run Sanny with the parameter \debug=X, where X is a sequence of characters '0' and '1' (without quotes). The characters mean which debug option is enabled/disabled.

Example: \debug=11000

First digit 1 will enable "code_offsets" option, second digit will enable "ignore_unknown" mode. The '0's digits will disable all remaining options.

# | Sanny Builder Option | # | Sanny Builder Option
1 | toggle code offsets | 16 |
2 | toggle ignore_unknown | 17 |
3 | toggle var_counter | 18 |
4 | toggle constant_indexes | 19 |
5 | toggle skip_scm_header | 20 |
6 |  | 22 |
7 |  | 23 |
8 |  | 24 |
9 |  | 25 |
10 |  | 26 |
11 |  | 27 |
12 |  | 28 |
13 |  | 29 |
14 |  | 30 |
15 |  | 31 |


Hotkeys

Sanny Builder supports standard keyboard shortcuts for the file and text operations (Ctrl+N, Ctrl+Z, etc). In addition there are specific hotkeys to use in work with scripts. Some of them are customizable in the options

Menu

F5 | open file as a script and decompile
F6 | compile text to a script file
F7 | compile text to a script file and copy it to the directory for scripts for the current game
F8 | run the current game
F10 | open the options window
F12 | open the help file (this one)

Text

TAB , Shift+TAB | move the selected text to the left / right (tab)
Ctrl+Alt+A / D | move the selected text to the left / right (by one symbol)
Ctrl+Alt+B / N / M | different modes of text selection: Normal, Columnar (same as selection with pressed Alt), Lines
Ctrl+Shift+U / L | make word uppercase / lowercase
Ctrl+Num+ | increase the text size (zoom in)
Ctrl+Num- | decrease the text size (zoom out)
Ctrl+T | delete word
Ctrl+Y | delete line
Ctrl+Shift+Y | clear line
Ctrl+Q | comment / uncomment line

Cursor

Ctrl+Shift+B | jump between brackets: {}, (), <>, []
Ctrl+Shift+Num8 / Num2 | to scroll page on line up / down
Ctrl+Scroll Up / Down | page up / down
Ctrl+Shift+0..9 | toggle a bookmark
Ctrl+0..9 | jump at the bookmark
Ctrl+G | go to line
Ctrl+Num4 / Num6 | search the word under the cursor below/above in the code
Ctrl+Num2 | jump to the label under the cursor
Ctrl+Num8 | return the cursor back to the previous position (before InstaSearch)
Ctrl+Enter | open file which name is under the cursor (see also relative path priorities)

Code

Ctrl+[space] | show list of classes / class members / models / labels / variables / missions
Ctrl+Shift+[space] | show list of parameters for the current class command
Ctrl+Shift+C | insert the player's coords
Ctrl+Shift+E | insert the player's z_angle
F1 | search opcode with the word under the cursor (with ignoring of '_' and '.')
Ctrl+F1 | search opcode with the word under the cursor (without ignoring of '_' and '.')
F2 | use macro
Ctrl+J | show list of macros
Ctrl+M | start/stop recording of a macro (keystroke pressings sequence)
Ctrl+P | replay macro/pause while processing
Ctrl+H | convert a number under the cursor from decimal to hexadimal and vice versa
Ctrl+Alt+H | convert a model name under the cursor to its numeric ID and vice versa

Misc

Ctrl+~ | open console
Alt+S | (when the list of models is active) re-sort the list


Opcode Search Tool

You can call this function by pressing Ctrl + Alt + 2 or by selecting the menu item: Tools -> IDE Tools -> Opcode Search.

To find the needed opcode, type your search term(s) in the top field. For example: actor car. The tool displays opcodes that contain these words. You may also use the special search operators.

When OST is called, it checks if there is a selected word in the editor. If the selected word is found, it will be pasted into the search field.

Copying

After you've found the needed opcode, select it in the list and press ENTER. Now your selected opcode will be copied onto your clipboard. If you want to copy another opcode, press SHIFT + ENTER. The opcode will be ADDED to your clipboard content. F2 copies all opcodes from the results list.

Hotkeys

ENTER | copy selected opcode onto clipboard
SHIFT + ENTER | add selected opcode to the clipboard
SCROLL LOCK | switch on/off search (when param "extra_search" (in settings.ini) is equal to 1)
F1 | call help
F2 | copy all opcodes from the results list onto the clipboard
F3 | sort the list by opcodes
F4 | sort the list alphabetically
F11 | clean up the search edit, show all opcodes
ESC | close window

Search Operators:

LOGIC

AND operator

In the program this function is carried out with a SINGLE SPACE between the words.

Example: @ player

will show opcodes that have both symbol '@' and word 'player'

OR operator

In the program this function is carried out with a symbol | between the words.

Example: @ | player

will show opcodes that have EITHER symbol '@' OR word 'player'

If you write | as the FIRST char in the line, the program will connect all words by operator OR.

Example: | actor player car

will show opcodes that have EVEN ONE of these words.

NOT operator (NOT)

For all cases it is carried out with two minuses before of an excluded word

Example: car --car2

will show opcodes that HAVE a word 'car' AND HAVE NO word 'car2'

For words and symbols '$' and '@' it is possible to use one minus. This is to avoid mixing the exclusion during a search of negative numbers:

Example: -10 -@ -car -3

will show opcodes that have a number -10, NO symbol '@', word 'car' and number '3'

OTHER OPERATORS

^ | shows all conditions in the list
^word | finds the word in the conditional opcodes

Example: ^car ==

will show conditional opcodes that have a word 'car' and a sign '=='

-^ excludes all conditions from the list

Example: player -^

will show all non-conditional opcodes that have a word 'player'

-^word to exclude the conditions containing the word

Example: player -^actor

will show all opcodes that have a word 'player', except the conditional opcodes with a word 'actor'.

% searches in the given order

Example: % @ = @

will show all opcodes where these symbols go in the given order.


SCM Documentation

Sanny Builder Help: SCM Documentation

Contents:

Opcodes List (INI)

GTA Limits

GTA SA

GTA VC

GTA LCS

Help materials by:
Alexander aka Alexander Koryakin, Barton Waterduck, Bigun, DeeZire, Opius, pdescobar, San'OK aka Alexander Golovnev, Seemann, spaceeinstein, spinnie, Xieon, Wesser, http://www.lzfdownloads.de/


Opcodes List (INI)

The INI file is the major file providing the (de)compiling process. It contains a list of opcodes: its own for each game. These lists are located in the Sanny Builder’s folder data\’game’:

data\gta3 : SCM.INI
data\vc : VCSCM.INI
data\sa : SASCM.INI
data\lcs : LCSSCM.INI
data\vcs : VCSSCM.INI

All files have the same syntax. First, the special parameters could be written in the beginning of the INI. They are:
VERSION – this line defines a version of this INI. See $VERSION directive.
PUBLISHER – the person published this version.
DATE – the latest update date.
The decompiler inserts these values into the source files.
The list of opcodes goes right after those special parameters.

Each opcode line has the following syntax:

xxxx=N, yyyy

where XXXX is the opcode number, N – the number of parameters, YYYY – the opcode description.

First two values can’t be changed in any way, however the description can. Also take note of the part of the description denoted by the % sign - an opcode parameter is designed in this way.

For example,

0001=1,wait %1d% ms
this line makes the decompiler when it processing an opcode 0001 write the words ‘wait’ and ‘ms’ and the only parameter between them.

A parameter consists of two parts: a number and a type.

The number in parameter %1d% is its number itself. The point is that some opcodes can have their parameters to be arranged in the non-numerical order. It’s all to make a source code more readable and looking like the common programming languages. For instance,

0053=5,%5d% = create_player %1o% at %2d% %3d% %4d%

Pay attention, the decompiler writes the fifth parameter at first. If the parameters follow their numeric order, the opcode 0053 will look like:

0053: сreate_player #NULL at 2488.562 -1666.865 12.8757 $PLAYER_CHAR

It’s significant that the numeric order is typical for the gtama and PLPynton’s SASCM.INI.
The following letters denote the parameter type:
d = any values
p = label
o = model name
g = gxt-entry
x = external script ID

The type changes the decompiler behavior. For example, it adds a comment with the gxt-key content for the g-parameter; converts the p-one to the label, the o-parameter to the model name (like #NULL in the 0053), etc.
Attention! The parameters order can never be changed as it will cause the impossibility to compile your scripts correctly by the other users. The only way to do so is if you never going to publish your script.
You can freely change the description words and the parameters types, if it needed. The comments are marked with the semicolon at the beginning of the line.

If the INI contains few opcodes with the same number, the program uses that one located further.


GTA Limits

Sanny Builder Help: GTA Limits
 | GTA III | Vice City | San Andreas | LCS
main size | 131072 | 225512 | 200000 |
mission size | 32768 | 35000 | 69000 |
num missions | 120 | 120 | 200 |
Mission Cleanup List | 50 | 50 | 75 |
model names (2nd segment) | 200 | 220 | 395 |
running threads | 128 | 128 | 96 |
local variables | 16 + 2 timers | 16 + 2 timers | 32 + 2 timers 1024 total in missions | 96 + 2 timers
gosub levels | 4 | 6 | 8 |
Text_Draw | 2 | 48 | 96 |
Jump Table Labels | - | - | 75 | -
external threads | n/a | n/a | 82 | n/a
external thread attachments | n/a | n/a | 70 | n/a
car generators | 160 | 185 | 500 |
radar blips | 32 | 75 | 175 |
pickups | 336 | 336 | 620 |
last opcode | 0481 | 05a8 | 0a4e |
spheres | 16 | 16 | 16 |
car saving garagetypes | 16..18 | 16..18,24..32 | 16..18,24..32,39..45 |

Originally posted by CyQ on GTAForums.com


SCM Documentation: GTA SA

Sanny Builder Help: SCM Documentation: GTA SA

Contents:

Car variations

Garage names

Gang IDs

Clothes: TORSO

Clothes: LEGS

Clothes: SHOES, NECKLACES, WATCHES

Clothes: GLASSES, HATS, SPECIAL

GTA SA Interior

HairCuts

Keypress numbers

Particle effects

PedTypes

Player body parts

Radar icons

Special actors

Statistics ID

Tattos

Train types

Weapon numbers

Weather IDs

Zones


GTA SA Car Variations

Sanny Builder Help: GTA SA Car Variations

0506: set_vehicle_model #PONY next_variation 0 0

For most vehicles, only one extra can be added so both the second and third parameters should be set to the same wanted variant to avoid confusion. However, some vehicles can have 2 different extras active.

Variant -1 is the default model with no extras.
Variants 0 through 5 are possible extra variants which will fall back to the default if the model does not have that many extras, and variants greater than 5 will crash the game.

#MODEL_ID | ID | Changes | 0 | 1 | 2 | 3 | 4 | 5
#ambulan | 416 | Numbers: | 37 | 71 | x | x | x | x
#artict1 | 435 | Side Ads: | Cok-o-Pops | Munky Juice | Hinterland | Zip | RS Haul | Ranch
#artict2 | 450 | Contents: | Filled with gravel /coal /stone | x | x | x | x | x
#bagboxb | 607 | Contents: | Various distributions of loose baggage |  |  | x | x | x
#baggage | 485 | Rear Cargo Items: | Earmuffs | Small Case | Large Case | x | x | x
#barracks | 433 | Bed Covering: | Opaque Fabric | Camo Netting | x | x | x | x
#benson | 499 | Side Ads: | Shady Industries | LSD | The Uphill Gardener | Discount Furniture | x | x
#bf400 | 581 | Exhausts: Fairings (with Windshields): | Single Type1 | Single Type2 | Dual Type3 | Half-size | Full-size | x
#bfinject | 424 | Body: | Side Panels | x | x | x | x | x
#bloodra | 504 | Numbers/ Roof Color: | 328/ White | 464/ Check | 172/ Check | 100/ White | 284/ White | 505/ Check
#bobcat | 422 | Bed Items: | Spare Tire | Sprunk Cans |  |  |  |
#burrito | 482 | Roof Items: | Roof Lights + Spoiler | x | x | x | x | x
#caddy | 457 | Rear Cargo Driver Side: Rear Cargo Pass Side: | Golfbag1 | Satchel1 | Golfbag2 | Satchel2 | Golfbag3 | Golfbag4
#camper | 483 |  | Open Curtains & Second Bench Seat | Open Roof Vent Closed Curtains Bed in Back Peace Sign | x | x | x | x
#cheetah | 415 | Side Mirrors: | Single, Placed High | Dual, Placed Normally | x | x | x | x
#coach | 437 | Name on Side: | Big O Tours | Bikini Line | x | x | x | x
#coastg | 472 | Various Items: | Items all Over, | Items Grouped in Back | Items all Over +2 Oars in Front | x | x | x
#fcr900 | 521 | Exhausts: Fairings (with Windshields): | Single Type1 | Dual Type1 | Dual Type2 | Half-size | Full-size | x
#firetruk | 407 | Numbers: | 64 | 16 | 47 | x | x | x
#flatbed | 455 | Cargo: | Crates in Front | Crates in center under Tarp | Two Sets of crates (Front and Back) | x | x | x
#hotknife | 434 |  | Partial Engine Cover | x | x | x | x | x
#hotrina | 502 | Numbers: | 96 | 67 | 73 | 52 | 45 | 14
#hotrinb | 503 | Numbers: | 82 | 26 | 65 | 07 | 36 | 60
#kart | 571 | Body Panels: | Both Sides | Steering Column | x | x | x | x
#launch | 595 | Roofs: | Over passenger section | Over driver section | x | x | x | x
#marquis | 484 |  | Windshield over cabin Entrance | x | x | x | x | x
#mesa | 500 |  | Roof Over Back | Roll Bar in Back | x | x | x | x
#monstera | 556 |  | Roof Spoiler | Roof Lights | Roll Bar with Lights | x | x | x
#monsterb | 557 |  | x | Roof Lights | x | x | x | x
#mrwhoop | 423 | Rear Sign: | Cherry Popping Good, | Slow Children Ahead | x | x | x | x
#mule | 414 | Side Ads: | Toy Corner | Binco | Semi | Shafted Appliances | x | x
#nrg500 | 522 | Exhausts: Fairings (with Windshields): | Single Pair1 | Single Pair2 | Dual Pair2 | Smooth | With Side Cutouts | x
#patriot | 470 | Cargo Area: | Low Cover | Roof/High Cover | Roll Bar | x | x | x
#peren | 404 |  | Roof Rack | x | x | x | x | x
#picador | 600 | Items in Bed | Planks | Sprunk Cans | x | x | x | x
#pony | 413 |  | Sound System in Back | x | x | x | x | x
#reefer | 453 | Items in Back: | Boxes of Fish | Bench | x | x | x | x
#romero | 442 | Coffins: | Brown Style1 | Black Style2 | Brown Style3 | x | x | x
#rumpo | 440 | Side Ads: | Cok-o-Pops | Harry Plums | Dick Goblin's | Final Build | Transfender | Wheel Arch Angels
#sadler | 543 | Items in Bed | Two Propane Tanks & Crate | Two Barrels | Sprunk Cans | Open Crates | x | x
#sadlshit | 605 | Items in Bed | Two Propane Tanks & Crate | Two Barrels | Sprunk Cans | Open Crates | x | x
#securica | 428 | Side Logo: | Chuff | Lock&Load | x | x | x | x
#slamvan | 535 | Steering Wheel: | Normal | Chain | x | x | x | x
#stallion | 439 | Roof: | Hardtop | Softtop (up) | Softtop (folded) | x | x | x
#supergt | 506 |  | Full Roof | x | x | x | x | x
#swatvan | 601 | Number: | 1 | 9 | 6 | 7 | x | x
#topfun | 459 |  | Boxes of Toys in Back | x | x | x | x | x
#tram | 449 |  | ? | ? | ? | ? | ? | x
#trash | 408 |  | Some bits of trash sticking out of the back | x | x | x | x | x
#utility | 552 |  | Cones, Barrel in back, Cone lying on passenger | driver side rail |  | x | x | x | x
#walton | 478 | Items in Bed | Two Propane Tanks | Open Crates | Propane Tank and Barrel | x | x | x
#windsor | 555 |  | Roof |  |  |  |  |
#yankee | 456 | Side Ads: | Big Gas | RS Haul | Star Balls | Flower Power | x | x
#zr350 | 477 |  | Rear Spoiler | x | x | x | x | x


GTA SA Garage names

Sanny Builder Help: GTA SA Garage names

Garage.Activate('BODLAWN')

Los Santos
CJSAFE | (2502.31, -1699.36, 12.4323) | Ganton garage
CESAFE1 | (1352.58, -636.657, 108.135) | Muholland garage
MUL_LAN | (1640.37, -1520.07, 12.5118) | Downtown garage used in "Life's a Beach"
IMP_LA | (1523.92, -1653.23, 4.72837) | impound lot
DUF_LAS | (1873.97, -2096.55, 12.487) | El Corona garage used in "Los Desperados"
LASBOMB | (1843.91, -1858.8, 12.3645) | bomb shop
MODGLAS | (1809.46, -2150.67, 12.4283) | Cesar's garage
CARLAS1 | (1694.8, -2088.7, 12.3636) | El Corona garage
BURG_LK | (2738.4, -2012.55, 12.5759) | burglary garage
MODLAST | (2640.78, -2049.99, 12.543) | Loco Low Co
SPLAW2 | (491.103, -1747.55, 9.45516) | Verona Beach Pay n Spray
BEACSV | (319.326, -1768.93, 3.35686) | Santa Maria Beach garage
BODLAWN | (1038.24, -1025.67, 31.1027) | Transfender
+ |  |
; used twice
SPRLAE | (2056.6, -1835.9, 12.5443) | Idlewood Pay n Spray
SPRLAE | (1021.81 -1018.71 30.9081) | Temple Pay n Spray
San Fierro
FDORSFE | (-2171.43, 649.416, 49.8742) | Wu Zi's garage
MICHDR | (-1790.97, 1209.71, 23.763) | Michelle's garage
SAV1SFE | (-2108.92, 886.553, 75.566) | Windy road grg
IMP_SF | (-1652.78, 647.502, -6.04924) | impound lot
MDS1SFS | (-2728.53, 212.295, 3.45112) | "Wheels Arch Angel" garage
TBON | (-2735.46, 60.7331, 3.07005) | garage a block south of "Wheels Arch Angel"
SVGSFS1 | (-2454.02, -131.556, 25.0886) | Hashbury garage
MDSSFSE | (-1941.04, 251.714, 33.4274) | Transfender
SPRSFSE | (-1908.93, 292.353, 40.0413) | Downtown Pay n Spray
BRGSFSE | (-2112.48, -21.214, 34.303) | burglary garage
HBGDSFS | (-2057.35, 150.803, 27.8286) | Doherty garage #1 left
LCKSFSE | (-2043.1, 118.609, 27.821) | Doherty garage #2 right
SPRSFW | (-2430.13, 1013.71, 49.3413) | Juniper Hollow Pay n Spray
SAV1SFW | (2699.12, 821.489, 49.0042) | Paradiso garage
+ |  |
noname | (-1694.78 1033.15 44.1937) | Esplanade North garage (for "Yay Ka-Boom-Boom")
noname | (-1794.15 1429.69 4.37321) | Downtown garage (for stealing manana)
Las Venturas
VGELOCK | (2602.6, 1438.84, 9.8337) | burglary garage
VECMOD | (2382.28, 1044, 9.8337) | Transfender
VESVGRG | (2449.5, 695.018, 10.4742) | Rockshore West garage
IMP_LV | (2218.06, 2448.06, -8.43807) | impound lot
VGSHNGR | (1550.98, 1155.36, 8.97329) | AT 400 hangar
BLOB2 | (2002.96, 2303.72, 9.61706) | Welding and Wedding bomb shop
BLOB1 | (1968.23, 2157.88, 9.59696) | Redsands East Pay n Spray
BLOB6 | (1408.65, 1899.52, 10.115) | Redsands West garage
BLOB69 | (1269.2, 2525.14, 9.80013) | Prickle Pine garage
BLOB7 | (929.554, 2008.59, 10.115) | Whitewood Estates garage
+ |  |
TIMY1 | (2389.6, 1483.26, 9.81843) | unused Pay n Spray (the door doesn't work)
Countryside
CN2SPRY | (-103.636, 1112.42, 18.7017) | Fort Carson Pay n Spray
CN2GAR1 | (-364.439, 1194.37, 18.597) | Fort Carson garage
CN2GAR2 | (430.059, 2542.31, 15.166) | Verdant Meadows garage
GHOSTDR | (-397.297, 2223.17, 41.3824) | garage used in "Interdiction"
DHANGAR | (383.843, 2433.28, 15.166) | Verdant Meadows Hangar
CESPRAY | (715.806, -462.403, 14.9635) | Dillimore Pay n Spray
BURBDOO | (2227.6, 168.649, 26.4635) | Palomino Creek garage
BURBDO2 | (783.155, -492.75, 16.3361) | Dillimore garage
CNSPRAY | (-1424.11, 2576.61, 54.8156) | El Quebrados Pay n Spray
AMUMIS | (-2114.42, -2462.27, 29.4809) | Angel Pine Ammunation garage


GTA SA Gang IDs

Sanny Builder Help: GTA SA Gang IDs

0237: set_gang 1 weapons_to 24 29 4

Gang0 Ballas
Gang1 Grove Street Families
Gang2 Los Santos Vagos
Gang3 San Fierro Rifa
Gang4 Da Nang Boys
Gang5 Mafia
Gang6 Mountain Cloud Triad
Gang7 Varrio Los Aztecas
Gang8 (unused)
Gang9 (unused)


GTA SA Clothes: TORSO

Sanny Builder Help: GTA SA Clothes: TORSO

Player.SetClothes($PLAYER_CHAR, "TEXTURE", "MODEL", BODY_PART)
Player.Build($PLAYER_CHAR)

Also, see (BODY PART).

TEXTURE | MODEL | BODY PART | NAME
 |  | TORSO |
player_torso | torso | 0 | Torso ;(default)
vestblack | vest | 0 | Black Tank
vest | vest | 0 | White Tank
tshirt2horiz | tshirt2 | 0 | Striped T-Shirt
tshirtwhite | tshirt | 0 | White T-Shirt
tshirtilovels | tshirt | 0 | L.S. T-Shirt
tshirtblunts | tshirt | 0 | Sharps T-Shirt
shirtbplaid | shirtb | 0 | Plaid Shirt
shirtbcheck | shirtb | 0 | Checkered Shirt
field | field | 0 | Combat Jacket
tshirterisyell | tshirt | 0 | Eris T-Shirt
tshirterisorn | tshirt | 0 | Eris T-Shirt2
trackytop2eris | trackytop1 | 0 | Track Top
bbjackrim | bbjack | 0 | Rimmers Jacket
bballjackrstar | bbjack | 0 | R-Star Jacket
baskballdrib | baskball | 0 | Dribblers Vest
baskballrim | baskball | 0 | Saint's Shirt
sixtyniners | tshirt | 0 | 69ers T-Shirt
bandits | baseball | 0 | Bandits Top
tshirtprored | tshirt | 0 | ProLaps T-Shirt
tshirtproblk | tshirt | 0 | ProLaps Black T
trackytop1pro | trackytop1 | 0 | Track Top
hockeytop | sweat | 0 | Slappers Top
bbjersey | sleevt | 0 | Baseball T
shellsuit | trackytop1 | 0 | Leisure Top
tshirtheatwht | tshirt | 0 | White Heat T
tshirtbobomonk | tshirt | 0 | Bobo Ape T
tshirtbobored | tshirt | 0 | Red Bobo T
tshirtbase5 | tshirt | 0 | Base 5 T
tshirtsuburb | tshirt | 0 | Suburban T
hoodyamerc | hoodya | 0 | Mercury Hood
hoodyabase5 | hoodya | 0 | Base 5 Hood
hoodyarockstar | hoodya | 0 | Rockstar Hood
wcoatblue | wcoat | 0 | Vest & T-Shirt
coach | coach | 0 | Grn Windbreaker
coachsemi | coach | 0 | Blk Windbreaker
sweatrstar | sweat | 0 | Rockstar Sweat
hoodyAblue | hoodyA | 0 | Blue Hoody
hoodyAblack | hoodyA | 0 | Black Hoody
hoodyAgreen | hoodyA | 0 | Green Hoody
sleevtbrown | sleevt | 0 | Brown Shirt
shirtablue | shirta | 0 | Sky Blue Shirt
shirtayellow | shirta | 0 | Yellow Shirt
shirtagrey | shirta | 0 | Gray Shirt
shirtbgang | shirtb | 0 | Green Shirt
tshirtzipcrm | tshirt | 0 | Cream Logo T
tshirtzipgry | tshirt | 0 | Gray Logo T
denimfade | denim | 0 | Jean Jacket
bowling | hawaii | 0 | Bowling shirt
hoodjackbeige | hoodjack | 0 | Hooded Jacket
baskballloc | baskball | 0 | Loc-Down Vest
tshirtlocgrey | tshirt | 0 | Loc-Down T
tshirtmaddgrey | tshirt | 0 | Madd Tagg T
tshirtmaddgrn | tshirt | 0 | Green Tagg T
suit1grey | suit1 | 0 | Gray Jacket
suit1blk | suit1 | 0 | Black Jacket
leather | leather | 0 | Biker Jacket
painter | painter | 0 | Chore Coat
hawaiiwht | hawaii | 0 | Hawaiian Shirt
hawaiired | hawaii | 0 | Blue Hawaiian
sportjack | trackytop1 | 0 | Sports Jacket
suit1red | suit1 | 0 | Red Jacket
suit1blue | suit1 | 0 | Blue Jacket
suit1yellow | suit1 | 0 | Yellow Jacket
suit2grn | suit2 | 0 | Tweed Jacket
tuxedo | suit2 | 0 | Tuxedo Pants
suit1gang | suit1 | 0 | Green Jacket
letter | sleevt | 0 | Letterman Top


GTA SA Clothes: LEGS

Sanny Builder Help: GTA SA Clothes: LEGS

Player.SetClothes($PLAYER_CHAR, "TEXTURE", "MODEL", BODY_PART)
Player.Build($PLAYER_CHAR)

Also, see (BODY PART).

TEXTURE | MODEL | BODY PART | NAME
 |  | LEGS |
player_legs | legs | 2 | Legs ; (default)
worktrcamogrn | worktr | 2 | Woodland Camo
worktrcamogry | worktr | 2 | Urban Camo
worktrgrey | worktr | 2 | Gray Pants
worktrkhaki | worktr | 2 | Olive Pants
tracktr | tracktr | 2 | Sweat Pants
tracktreris | tracktr | 2 | Track Pants
jeansdenim | jeans | 2 | Blue Jeans
legsblack | legs | 2 | Black Boxers
legsheart | legs | 2 | Heart Boxers
biegetr | chinosb | 2 | Beige Pants
tracktrpro | tracktr | 2 | Track Pants
tracktrwhstr | tracktr | 2 | Black Track Pants
racktrblue | tracktr | 2 | Blue Track Pants
tracktrgang | tracktr | 2 | Green Track Pants
bbshortwht | boxingshort | 2 | Ball Shorts
boxshort | boxingshort | 2 | Boxing Shorts
bbshortred | boxingshort | 2 | Dribbler Shorts
shellsuittr | tracktr | 2 | Leisure Pants
shortsgrey | shorts | 2 | Gray Shorts
shortskhaki | shorts | 2 | Olive Shorts
chongergrey | chonger | 2 | Gray Chonglers
chongergang | chonger | 2 | Green Chonglers
chongerred | chonger | 2 | Red Chonglers
chongerblue | chonger | 2 | Blue Chonglers
shortsgang | shorts | 2 | Green Shorts
denimsgang | jeans | 2 | Green Jeans
denimsred | jeans | 2 | Red Jeans
chinosbiege | chinosb | 2 | Beige Khakis
chinoskhaki | chinosb | 2 | Olive Khakis
cutoffchinos | shorts | 2 | Beige Shorts
cutoffchinosblue | shorts | 2 | Blue Shorts
chinosblack | chinosb | 2 | Black Khakis
chinosblue | chinosb | 2 | Blue Khakis
leathertr | leathertr | 2 | Leather Pants
leathertrchaps | leathertr | 2 | Leather Chaps
suit1trgrey | suit1tr | 2 | Gray Pants
suit1trblk | suit1tr | 2 | Black Pants
cutoffdenims | shorts | 2 | Jean Shorts
suit1trred | suit1tr | 2 | Red Pants
suit1trblue | suit1tr | 2 | Blue Pants
suit1tryellow | suit1tr | 2 | Yellow Pants
suit1trgreen | suit1tr | 2 | Tweed Pants
suit1trblk2 | suit1tr | 2 | Tuxedo Pants
suit1trgang | suit1tr | 2 | Green Pants


GTA SA Clothes: SHOES, NECKLACES, WATCHES

Sanny Builder Help: GTA SA Clothes: SHOES, NECKLACES, WATCHES

Player.SetClothes($PLAYER_CHAR, "TEXTURE", "MODEL", BODY_PART)
Player.Build($PLAYER_CHAR)

Also, see (BODY PART).

TEXTURE | MODEL | BODY PART | NAME
 |  | SHOES |
foot | feet | 3 | Shoes ; (default)
cowboyboot2 | biker | 3 | Cowboy Boots
bask2semi | bask1 | 3 | Hi-Top Kicks
bask1eris | bask1 | 3 | Hi-Top Sneaks
sneakerbincgang | sneaker | 3 | Green Low-Tops
sneakerbincblu | sneaker | 3 | Blue Low-Tops
sneakerbincblk | sneaker | 3 | Black Low-Tops
sandal | flipflop | 3 | Sandals
sandalsock | flipflop | 3 | Sandal & Socks
flipflop | flipflop | 3 | Flip-Flops
hitop | bask1 | 3 | Mid-Top Sneaker
convproblk | conv | 3 | Black Hi-Tops
convproblu | conv | 3 | Blue Hi-Tops
convprogrn | conv | 3 | Green Hi-Tops
sneakerprored | sneaker | 3 | Red Sneakers
sneakerproblu | sneaker | 3 | Blue Sneakers
sneakerprowht | sneaker | 3 | White Sneakers
bask1prowht | bask1 | 3 | White Mid-Tops
bask1problk | bask1 | 3 | Black Mid-Tops
boxingshoe | biker | 3 | Boxing Shoes
convheatblk | conv | 3 | Black Hi-Tops
convheatred | conv | 3 | Red Hi-Tops
convheatorn | conv | 3 | Orange Hi-Tops
sneakerheatwht | sneaker | 3 | White Low-Tops
sneakerheatgry | sneaker | 3 | Gray Low-Tops
sneakerheatblk | sneaker | 3 | Black Low-Tops
bask2heatwht | bask1 | 3 | White Hi-Tops
bask2heatband | bask1 | 3 | Strap Sneakers
timbergrey | bask1 | 3 | Gray Boots
timberred | bask1 | 3 | Red Boots
timberfawn | bask1 | 3 | Brown Boots
timberhike | bask1 | 3 | Hiking Boots
cowboyboot | biker | 3 | Cowboy Boots
biker | biker | 3 | Biker Boots
snakeskin | biker | 3 | Snake Skin
shoedressblk | shoe | 3 | Black Shoes
shoedressbrn | shoe | 3 | Brown Shoes
shoespatz | shoe | 3 | Spats
 |  | NECKLACES |
dogtag | neck | 13 | Dogtags
neckafrica | neck | 13 | Africa Pendant
stopwatch | neck | 13 | Stop Watch
necksaints | neck | 13 | Saints Chain
neckhash | neck | 13 | Leaf Chain
necksilver | neck2 | 13 | Silver Cuban
neckgold | neck2 | 13 | Gold Cuban
neckropes | neck2 | 13 | Silver Chain
neckropeg | neck2 | 13 | Gold Chain
neckls | neck | 13 | L.S. Chain
neckdollar | neck | 13 | Dollar Chain
neckcross | neck | 13 | Cross Chain
 |  | WATCHES |
watchpink | watch | 14 | Pink Watch
watchyellow | watch | 14 | Yellow Watch
watchpro | watch | 14 | Pro-Laps White
watchpro2 | watch | 14 | Pro-Laps Black
watchsub1 | watch | 14 | Face Watch
watchsub2 | watch | 14 | Face Black
watchzip1 | watch | 14 | Zip Blue
watchzip2 | watch | 14 | Zip Gold
watchgno | watch | 14 | Gold Gnocchi
watchgno2 | watch | 14 | Silver Gnocchi
watchcro | watch | 14 | Gold Crowex
watchcro2 | watch | 14 | Silver Crowex


GTA SA Clothes: GLASSES, HATS, SPECIAL

Sanny Builder Help: GTA SA Clothes: GLASSES, HATS, SPECIAL

Player.SetClothes($PLAYER_CHAR, "TEXTURE", "MODEL", BODY_PART)
Player.Build($PLAYER_CHAR)

Also, see (BODY PART).

TEXTURE | MODEL | BODY PART | NAME
 |  | GLASSES |
groucho | grouchos | 15 | Joke Glasses
zorro | zorromask | 15 | Joke Mask
eyepatch | eyepatch | 15 | Eyepatch
glasses01 | glasses01 | 15 | Black Shades
glasses04 | glasses04 | 15 | Brown Shades
bandred3 | bandmask | 15 | Red Rag
bandblue3 | bandmask | 15 | Blue Rag
bandgang3 | bandmask | 15 | Green Rag
bandblack3 | bandmask | 15 | Black Rag
glasses01dark | glasses01 | 15 | Aviators
glasses04dark | glasses04 | 15 | Sun Glasses
glasses03 | glasses03 | 15 | Green Tint
glasses03red | glasses03 | 15 | Red Tint
glasses03blue | glasses03 | 15 | Blue Tint
glasses03dark | glasses03 | 15 | Black Shades
glasses05dark | glasses03 | 15 | Black Shades
glasses05 | glasses03 | 15 | Black Rim
 |  | HATS |
bandred | bandana | 16 | Red Rag Back
bandblue | bandana | 16 | Blue Rag Back
bandgang | bandana | 16 | Green Rag Back
bandblack | bandana | 16 | Black Rag Back
bandred2 | bandknots | 16 | Red Rag Front
bandblue2 | bandknots | 16 | Blue Rag Front
bandblack2 | bandknots | 16 | Black Rag Front
bandgang2 | bandknots | 16 | Green Rag Front
capknitgrn | capknit | 16 | Watch Cap
captruck | captruck | 16 | Trucker Hat
cowboy | cowboy | 16 | Cowboy Hat
hattiger | cowboy | 16 | Leopard Cowboy
helmet | helmet | 16 | Fullface Helmet
moto | moto | 16 | MotoX Helmet
boxingcap | boxingcap | 16 | Boxing Helmet
hockey | hockeymask | 16 | Hockey Mask
capgang | cap | 16 | Green Cap
capgangback | capback | 16 | Green Cap (Back)
capgangside | capside | 16 | Green Cap (Side)
capgangover | capovereye | 16 | Grn Cap (Tilt)
capgangup | caprimup | 16 | Grn Cap (Up)
bikerhelmet | bikerhelmet | 16 | Helmut
capred | cap | 16 | Red Cap
capredback | capback | 16 | Red Cap (Back)
capredside | capside | 16 | Red Cap (Side)
capredover | capovereye | 16 | Red Cap (Tilt)
capredup | caprimup | 16 | Red Cap (Up)
capblue | cap | 16 | Blue Cap
capblueback | capback | 16 | Blue Cap (Back)
capblueside | capside | 16 | Blue Cap (Side)
capblueover | capovereye | 16 | Blue Cap (Tilt)
capblueup | caprimup | 16 | Blue Cap (Up)
skullyblk | skullycap | 16 | Black Skully
skullygrn | skullycap | 16 | Green Skully
hatmancblk | hatmanc | 16 | Black Sun Hat
hatmancplaid | hatmanc | 16 | Plaid Sun Hat
capzip | cap | 16 | Cap
capzipback | capback | 16 | Cap (Back)
capzipside | capside | 16 | Cap (Side)
capzipover | capovereye | 16 | Cap Tilted
capzipup | caprimup | 16 | Cap Rim Up
beretred | beret | 16 | Red Beret
beretblk | beret | 16 | Black Beret
capblk | cap | 16 | Black Cap
capblkback | capback | 16 | Black Cap (Back)
capblkside | capside | 16 | Black Cap (Side)
capblkover | capovereye | 16 | Black Cap (Tilt)
capblkup | caprimup | 16 | Black Cap (Up)
trilbydrk | trilby | 16 | Dark Trilby
trilbylght | trilby | 16 | Light Trilby
bowler | bowler | 16 | Black Derby
bowlerred | bowler | 16 | Red Derby
bowlerblue | bowler | 16 | Blue Derby
bowleryellow | bowler | 16 | Yellow Derby
boater | boater | 16 | Gray Boater
bowlergang | bowler | 16 | Green Derby
boaterblk | boater | 16 | Black Boater
 |  | SPECIAL |
gimpleg | gimpleg | 17 | Gimp Suit
valet | valet | 17 | Valet Uniform
countrytr | countrytr | 17 | Rural Clothes
croupier | valet | 17 | Croupier
policetr | policetr | 17 | Cop
balaclava | balaclava | 17 | Ski Mask
pimptr | pimptr | 17 | Pimp Suit
garageleg | garagetr | 17 | Racing Suit
medictr | medictr | 17 | Medic Uniform


GTA SA Interior

Sanny Builder Help: GTA SA Interior
Number | Name | Description
1 | ABATOIR | Sindacco Abattoir
1 | AMMUN1 | Ammu-Nation
1 | CARMOD1 | TransFender
1 | FDREST1 | World of Coq
1 | GF1 | Denise's
1 | JETINT | Shamal interior
1 | LACS1 | Sub Urban
1 | LAHS1B | House
1 | MAFCAS | Caligulas Casino
1 | MAFCAS2 | Penthouse Suites
1 | - | Saint Mark's
1 | SMASHTV | Warehouse
1 | - | Stadium with wooden sandbox
1 | SVVGHO1 | Hotel Suite
1 | SWEETS | Sweet's House
1 | - | Trailer
1 | TSDINER | Truck Stop
1 | WUZIBET | Wu Zi Mu's
2 | BARBERS | Barber
2 | BDUPS1 | B Dup's Crack Palace
2 | CARMOD2 | Loco Low Co.
2 | CARTER | Smokes Crack Palace
2 | GF2 | Katie's
2 | LAHS1A | House
2 | LASTRIP | Strip Club
2 | RYDERS | Ryder's Place
2 | SVVGHO2 | Hotel Suite
2 | VGHSB1 | House
2 | VGHSB3 | House
3 | BARBER2 | Barber
3 | BDUPS | B Dup's apartment
3 | BIKESCH | Bike School
3 | BROTHL1 | Whore House
3 | CARLS | The Johnson House
3 | CARMOD3 | Wheel Arch Angels
3 | CHANGER | Wardrobe
3 | CSSPRT | Pro-Laps
3 | DRIVES | Driving School
3 | DRIVES2 | Driving School
3 | GENOTB | Inside Track Betting
3 | GF3 | Helena's
3 | LAHSB4 | House
3 | OGLOCS | OG Loc's
3 | PAPER | Planning Department
3 | PDOMES | The Pleasure Domes
3 | PDOMES2 | The Pleasure Domes
3 | POLICE3 | LVPD HQ
3 | SEXSHOP | Sex Shop
3 | S1TEST | Middle of nowhere
3 | STRIP2 | Strip Club
3 | STUDIO | Blastin' Fools Records studio
3 | TATTO3 | Tattoo Parlor
4 | AMMUN2 | Ammu-Nation
4 | DINER1 | Diner
4 | DIRBIKE | Dirt Stadium
4 | GF4 | Michelle's
4 | LAHS2A | House
4 | LAHSS6 | House
4 | SFHSM2 | House
4 | X711S2 | 24-7
5 | CSDESGN | Victim
5 | DINER2 | Diner
5 | FDPIZA | Pizza Stack
5 | GANG | Vagos Gang House
5 | GF5 | Barbara's
5 | GYM1 | Ganton Gym
5 | LACRAK | Crack Den
5 | LAHSB3 | House
5 | MADDOGS | Madd Dogg's Crib
5 | MDDOGS | Madd Dogg's Crib
5 | SFHSB1 | House
5 | SVHOT1 | Hotel Suite
5 | VGHSM2 | House
6 | AMMUN3 | Ammu-Nation
6 | AMMUN5 | Ammu-Nation
6 | BROTHEL | Whore House
6 | GF6 | Millie's
6 | GYM2 | Cobra Marital Arts
6 | LAHSB1 | House
6 | POLICE1 | LSPD HQ
6 | RCPLAY | Zero's RC Shop
6 | REST2 | Secret Valley
6 | SFHSB2 | House
6 | SFHSS2 | House
6 | SVCUNT | Safe House
6 | SVSFSM | Safe House
6 | X7_11S | 24-7
7 | 8TRACK | 8-Track Stadium
7 | AMMUN4 | Ammu-Nation
7 | GYM3 | Below the Belt Gym
7 | LAHSB2 | House
7 | OFTEST | Middle of nowhere
8 | BURHOUS | Colonel Fuhrberger's
8 | SFHSS1 | House
8 | SVLAMD | Safe House
9 | FDCHICK | Cluckin' Bell
9 | LAHS2B | House
9 | SFHSB3 | House
9 | SVGNMT2 | Motel room
9 | SVVGMD | Safe House
10 | DESHOUS | Abandoned AC tower
10 | FDBURG | Burger Shot
10 | POLICE2 | SFPD HQ
10 | SVGNMT1 | Motel room
10 | TRICAS | The Four Dragon's
10 | - | The Four Dragon's Casino's maintenance room
10 | SVSFMD | Safe House
10 | VGHSM3 | House
10 | X711S3 | 24-7
10 | - | Zero's No Man's Land
11 | BAR2 | Bar
11 | SVLASM | Safe House
12 | BARBER3 | Barber
12 | MOROOM | Motel room
12 | SVLABIG | Safe House
14 | CSEXL | Didier Sachs
14 | AIRPOR2 | Los Santos International Airport
14 | AIRPORT | Francis Intl. Airport
15 | CSCHP | Binco
15 | MOTEL1 | Jefferson Motel
15 | SFHSM1 | House
15 | VGHSS1 | House
15 | VGSHM2 | House
15 | VGSHM3 | House
15 | VGSHS2 | House
16 | - | Stadium with giant round circular raised platform in middle
16 | TATTOO | Tattoo Parlor
16 | X7_11C | 24-7
17 | BAR1 | Bar
17 | DAMIN | Generator Hall
17 | FDDONUT | Rusty Brown's
17 | TATTO2 | Tattoo Parlor
17 | X7_11D | 24-7
18 | ATRIUME | Atrium
18 | ATRIUMX | Attrium
18 | CLOTHGP | Zip
18 | GENWRHS | Warehouse
18 | UFOBAR | Lil' Probe Inn
18 | X7_11B | 24-7


GTA SA HairCuts

Sanny Builder Help: GTA SA HairCuts
Player.SetClothes($PLAYER_CHAR, "TEXTURE", "MODEL", BODY_PART)
Player.Build($PLAYER_CHAR)

Also, see (BODY PART).

TEXTURE | MODEL | BODY PART | Name
afro | afro | 1 | Afro
afrobeard | afro | 1 | Afro & Beard
afroblond | afro | 1 | Blonde Afro
afrogoatee | afro | 1 | Afro & Goatee
afrotash | afro | 1 | Afro & Stash
bald | head | 1 | Bald Head
baldbeard | head | 1 | Bald & Beard
baldgoatee | head | 1 | Bald & Goatee
baldtash | head | 1 | Bald & Stash
beard | head | 1 | Cesar & Beard
cornrows | cornrows | 1 | Cornrow
cornrowsb | cornrows | 1 | Blonde Cornrow
elvishair | elvishair | 1 | Elvis Hair
flattop | flattop | 1 | FlatTop
goatee | head | 1 | Cesar & Goatee
groovecut | groovecut | 1 | Groove Cut
hairblond | head | 1 | Blonde Hair
hairblue | head | 1 | Blue Hair
hairgreen | head | 1 | Green Hair
hairpink | head | 1 | Pink Hair
hairred | Head | 1 | Red Hair
highafro | highafro | 1 | High Afro
highfade | head | 1 | High Fade
jhericurl | jheri | 1 | Jheri Curl
mohawk | mohawk | 1 | Mowhawk
mohawkbeard | mohawk | 1 | Mohawk & Beard
mohawkblond | mohawk | 1 | Blonde Mowhawk
mohawkpink | mohawk | 1 | Pink Mowhawk
player_face | head | 1 | Cesar
slope | slope | 1 | Slope
tash | head | 1 | Cesar & Stash
tramline | tramline | 1 | Detail Cut
wedge | wedge | 1 | Wedge


GTA SA Keypress numbers

Sanny Builder Help: GTA SA Keypress numbers

ONFOOT CONTROLS |  |
# | CONTROL | GXT ENTRY VALUES
0 | left/right | ~k~~GO_LEFT~ / ~k~~GO_RIGHT~
1 | forward/backward | ~k~~GO_FORWARD~ / ~k~~GO_BACK~
2 | special ctrl left/right | ~k~~VEHICLE_LOOKLEFT~/~k~~VEHICLE_LOOKRIGHT~
3 | special ctrl up/down | -unknown-
4 | action/secondary fire | ~k~~PED_ANSWER_PHONE~/ ~k~~PED_FIREWEAPON_ALT~
5 | previous weapon/zoom in | ~k~~PED_CYCLE_WEAPON_LEFT~/ ~k~~PED_SNIPER_ZOOM_IN~
6 | aim weapon | ~k~~PED_LOCK_TARGET~
7 | next weapon/zoom out | ~k~~PED_CYCLE_WEAPON_RIGHT~/ ~k~~PED_SNIPER_ZOOM_OUT~
8 | group CTRL forward | ~k~~GROUP_CONTROL_FWD~
9 | group CTRL back | ~k~~GROUP_CONTROL_BWD~
10 | conversation - no | ~k~~CONVERSATION_NO~
11 | conversation - yes | ~k~~CONVERSATION_YES~
12 | (does not exist) | -- -- --
13 | change camera | ~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~
14 | jump | ~k~~PED_JUMPING~
15 | enter vehicle | ~k~~VEHICLE_ENTER_EXIT~
16 | sprint | ~k~~PED_SPRINT~
17 | fire | ~k~~PED_FIREWEAPON~
18 | crouch | ~k~~PED_DUCK~
19 | look behind | ~k~~PED_LOOKBEHIND~
LALT | sneak | ~k~~SNEAK_ABOUT~
VEHICLE CONTROLS |  |
# | CONTROL | GXT ENTRY VALUES
0 | left/right | ~k~~VEHICLE_STEERLEFT~/ ~k~~VEHICLE_STEERRIGHT~
1 | steer back/up | ~k~~VEHICLE_STEERUP~/ ~k~~VEHICLE_STEERDOWN~
2 | special ctrl left/right | ~k~~VEHICLE_TURRETLEFT~/ ~k~~VEHICLE_TURRETRIGHT~ (NUM6)
3 | special control up/down | ~k~~VEHICLE_TURRETUP~/ ~k~~VEHICLE_TURRETDOWN~
4 | secondary fire | ~k~~VEHICLE_FIREWEAPON_ALT~
5 | look left | ~k~~VEHICLE_LOOKLEFT~
6 | hand brake | ~k~~VEHICLE_HANDBRAKE~
7 | look right | ~k~~VEHICLE_LOOKRIGHT~
8 | next radio station | ~k~~VEHICLE_RADIO_STATION_UP~
9 | previous radio station | ~k~~VEHICLE_RADIO_STATION_DOWN~
10 | no | ~k~~CONVERSATION_NO~
11 | yes / trip skip | ~k~~CONVERSATION_YES~
12 | (does not exist) | -- -- --
13 | camera | ~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~
14 | brake/reserve | ~k~~VEHICLE_BRAKE~
15 | enter/exit | ~k~~VEHICLE_ENTER_EXIT~
16 | accelerate | ~k~~VEHICLE_ACCELERATE~
17 | fire | ~k~~VEHICLE_FIREWEAPON~
18 | horn | ~k~~VEHICLE_HORN~
19 | submission | ~k~~TOGGLE_SUBMISSIONS~
RMB | vehicle mouse look | ~k~~VEHICLE_MOUSELOOK~


GTA SA Particle effects

Sanny Builder Help: GTA SA Particle effects
"blood_heli" | bloody explosion
"boat_prop" | a surf
"camflash" | small flare
"carwashspray" | steam, as on a carwash
"cement" | cement
"cloudfast" | fast clouds
"coke_puff" | puff of a coke
"coke_trail" | a pouring water
"cigarette_smoke" | a smoke from a cigarette
"explosion_barrel" | explosion and splinters of a box
"explosion_crate" | explosion and splinters of the large box
"explosion_door" | a smoke with sparks
"exhale" | a small smoke
"explosion_fuel_car" | explosion, as from the machine
"explosion_large" | the large explosion
"explosion_medium" | average explosion
"explosion_molotov" | explosion, as from a movotov cocktail
"explosion_small" | small explosion
"explosion_tiny" | very small explosion
"extinguisher" | foam of the fire extinguisher
"flame" | small fire
"fire" | fire
"fire_med" | average fire
"fire_large" | large fire
"flamethrower" | fire of the flamethrower
"fire_bike" | fire, as from a burning motorcycle
"fire_car" | fire, as from the burning machine
"gunflash" | as the bullet from a trunk takes off
"gunsmoke" | a smoke from a gun
"insects" | insects
"heli_dust" | a dust, as from the helicopter
"jetpack" | a jetpack's fire
"jetthrust" | fire from the muffler of the machine, as during use of nitrogen
"nitro" | nitro
"molotov_flame" | fire from a Molotov Cocktail
"overheat_car" | smoke from damaged car
"overheat_car_electric" | wrecked electro-machine
"prt_boatsplash" | foam
"prt_cardebris" | splinters from a box
"prt_collisionsmoke" | a dense white smoke
"prt_glass" | a crashing glass
"prt_gunshell" | shells
"prt_sand" | sand, which was scattered
"prt_sand2" | there is less sand, than in previous animation
"prt_smokeII_3_expand" | - a grey smoke
"prt_smoke_huge" | there is a lot of grey smoke
"prt_spark" | of a spark
"prt_spark_2" | the large sparks
"prt_splash" | burst
"prt_wake" | a wave
"prt_watersplash" | sparks
"prt_wheeldirt" | sparks from wheels of the car
"petrolcan" | a jet
"puke" | belch
"riot_smoke" | there is a lot of smoke
"spraycan" | spray
"smoke30lit" | a smoke
"smoke30m" | a rich smoke
"smoke50lit" | more richer smoke
"shootlight" | fireworks
"smoke_flare" | fireworks
"tank_fire" | a shot from the tank
"teargas" | gas, as from gas grenade
"teargasAD" | gas, as from small gas grenade
"tree_hit_fir" | leaf falling
"tree_hit_palm" | falling of pair large leafs
"vent" | slowly dissipating a smoke
"vent2" | practically too most
"water_hydrant" | the large flow of water
"water_ripples" | circles on water
"water_speed" | the large sparks from water
"water_splash" | small sparks from water
"water_splash_big" | average sparks
"water_splsh_sml" | sparks, only them it is not visible almost
"water_swim" | small sparks at navigation
"waterfall_end" | there is a lot of pair
"water_fnt_tme" | the large flow of water
"water_fountain" | water of a fountain
"wallbust" | a disappearing heap pair
"WS_factorysmoke" | smoke


GTA SA PedTypes

Sanny Builder Help: GTA SA PedTypes

Here is available pedtypes, using in

009A: $Actor = create_actor INT(pedtype) #MODEL at X Y Z

0 | PLAYER1
1 | PLAYER2
2 | PLAYER_NETWORK
3 | PLAYER_UNUSED
4 | CIVMALE
5 | CIVFEMALE
6 | COP
7 | GANG1 (Ballas)
8 | GANG2 (Grove Street Families)
9 | GANG3 (Los Santos Vagos)
10 | GANG4 (San Fierro Rifa)
11 | GANG5 (Da Nang Boys)
12 | GANG6 (Mafia)
13 | GANG7 (Mountain Cloud Triad)
14 | GANG8 (Varrio Los Aztecas)
15 | GANG9 (unused)
16 | GANG10 (unused)
17 | DEALER
18 | MEDIC
19 | FIREMAN
20 | CRIMINAL
21 | BUM*
22 | PROSTITUTE
23 | SPECIAL
24 | MISSION1
25 | MISSION2
26 | MISSION3
27 | MISSION4
28 | MISSION5
29 | MISSION6
30 | MISSION7
31 | MISSION8


GTA SA Player body parts

Sanny Builder Help: GTA SA Player body parts

087B: set_player $PLAYER_CHAR texture "VEST" model "VEST" body_part 0
Player.SetClothes($PLAYER_CHAR, "VEST", "VEST", Torso)

 | BODY_PART
0 | Torso
1 | Head (haircuts)
2 | Legs
3 | Shoes
4 | Lower left arm
5 | Upper left arm
6 | Upper right arm
7 | Lower right arm
8 | Back top
9 | Left chest
10 | Right chest
11 | Stomach
12 | Lower back
13 | Necklace
14 | Bracelet/Watch
15 | Glasses
16 | Hats
17 | Special clothes as Valet, Gimp suit


GTA SA radar icons

Sanny Builder Help: GTA SA radar icons
0 | small yellow square
1 | white square
2 | Player position
3 | Arrow (Menu-card)
4 | North
5 | Airport
6 | Ammu Nation
7 | Barber
8 | Big Smoke
9 | Docks
10 | Burger Shot
11 | Bulldozer
12 | Catalina
13 | Cesar Viapando
14 | Chicken
15 | Carl Johnson
16 | Crash
17 | Dinner
18 | Emmet
19 | enemy attack
20 | Fire
21 | Girl Friend
22 | Hospital
23 | Loco Syndicate
24 | Maddog
25 | Mafia
26 | MC Strap
27 | Tuning Shop
28 | OG Loc
29 | Pizza
30 | Police
31 | Asset green
32 | Asset red
33 | Race
34 | Ryder
35 | Savepoint
36 | School
37 | Unknown
38 | Sweet
39 | Tattoo
40 | The Truth
41 | Player target
42 | Toreno Ranch
43 | Triads
44 | Triads Casino
45 | Clothes
46 | Woozie
47 | Zero
48 | Disco
49 | Bar
50 | Restaurant
51 | Truck
52 | Robbery
53 | Race
54 | Gym
55 | Car
56 | Light
57 | Run Way
58 | Varrios Los Aztecas Gang
59 | Ballas Gang
60 | Los Santos Vagos Gang
61 | San Fierro Rifa Gang
62 | Grove Gang
63 | Pay'n Spray


Sanny Builder Help: GTA SA Special actors

GTA SA / Special actors

Special Actor | Description
'ANDRE' | Andre
'BBTHIN' | Big Bear (thin)
'BB' | Big Bear (fat)
'CAT' | Catalina
'CESAR' | Cesar
'COPGRL1' | The naked girl 1
'COPGRL2' | Girl 1
'CLAUDE' | Claude from GTA3
'CROGRL1' | The naked girl 2
'CROGRL2' | Girl 2
'DWAYNE' | Dwayne
'EMMET' | Emmet
'FORELLI' | Forelli
'JANITOR' | mechanic
'JETHRO' | Jethro
'JIZZY' | Jizzy
'HERN' | Hernandes
'GANGRL1' | The naked girl 3
'GANGRL2' | Girl 3
'GUNGRL1' | The naked girl 4
'GUNGRL2' | Girl 4
'KENDL' | Kendel
'MACCER' | Maccer
'MADDOGG' | Mad Dog
'MECGRL1' | The naked girl 5
'MECGRL2' | Girl 5
'NURGRL1' | The naked nurse
'NURGRL2' | nurse
'NURGRL2' | nurse
'OGLOC' | OG Loc
'PAUL' | Kent Paul
'PULASKI' | Pulaski
'ROSE' | Ken Rosenberg
'RYDER1' | Ryder (1)
'RYDER2' | Ryder (2)
'RYDER3' | Ryder (3)
'SINDACO' | Sindaco
'SMOKE' | Big Smoke
'SMOKEV' | with body armour
'SUZIE' | Suzie
'SWEET' | Sweet
'TBONE' | T Bone
'TENPEN' | Tenpeni
'TORINO' | Torino
'TRUTH' | righteous man
'WUZIMU' | Wu Zi
'ZERO' | Zero


GTA SA Statistics ID

Sanny Builder Help: GTA SA Statistics ID
ID | Statistics ID
0-81 | - all floats
0 | Progress made
1 | Total progress
2 | Furthest Hoop
3 | Distance travelled on foot
4 | Distance travelled by car
5 | Distance travelled by motorbike
6 | Distance travelled by boat
7 | Distance travelled by golf cart
8 | Distance travelled by helicopter
9 | Distance travelled by plane
10 | Longest Wheelie distance
11 | Longest Stoppie distance
12 | Longest 2 wheels distance
13 | Weapon Budget
14 | Fashion Budget
15 | Property Budget
16 | Auto Repair and Painting Budget
17 | Longest Wheelie time
18 | Longest Stoppie time
19 | Longest 2 wheels time
20 | Food Budget
21 | Fat
22 | Stamina
23 | Muscle
24 | Max Health
25 | Sex appeal
26 | Distance travelled by swimming
27 | Distance travelled by bicycle
28 | Distance travelled on treadmill
29 | Distance travelled on exercise bike
30 | Tattoo budget
31 | Hairdressing budget
32 | Girlfriend budget
33 | Prostitute budget
34 | Furniture budget
35 | Money spent gambling
36 | Money made from pimping
37 | Money won gambling
38 | Biggest gambling win
39 | Biggest gambling loss
40 | Largest burglary swag
41 | Money made from burglary
42 | Money spent building property
43 | Unused
44 | Longest treadmill time
45 | Longest exercise bike time
46 | Heaviest weight on bench press
47 | Heaviest weight on dumbbells
48 | Best time in 8-Track
49 | BMX best time
50 | Lightest weight
51 | Longest chase time with 5 or more stars
52 | Last chase time with 5 or more stars
53 | Wage bill
54 | Strip club budget
55 | Car modification budget
56 | Time spent shopping
57 | Time spent gambling
58 | Time spent on longest mission
59 | Time spent on quickest mission
60 | Average mission time
61 | Drugs budget
62 | Total shopping budget
63 | Time spent underwater
64 | Total respect
65 | Girlfriend respect
66 | Clothes respect
67 | Fitness respect
68 | Respect
69 | Pistol Skill
70 | Silenced Pistol Skill
71 | Desert Eagle Skill
72 | Shotgun Skill
73 | Sawn-Off Shotgun Skill
74 | Combat Shotgun Skill
75 | Machine Pistol Skill
76 | SMG Skill
77 | AK-47 Skill
78 | M4 Skill
79 | Rifle Skill
80 | Appearance
81 | Gambling
82-119 | Unused
120-337 | - all integers
120 | People wasted by others
121 | People you've wasted
122 | Road Vehicles destroyed
123 | Boats destroyed
124 | Planes & Helicopters destroyed
125 | Cost of property damaged
126 | Bullets fired
127 | Kgs of explosives used
128 | Bullets that hit
129 | Tires popped with gunfire
130 | Number of headshots
131 | Total number of wanted stars attained
132 | Total number of wanted stars evaded
133 | Times busted
134 | Days passed in game
135 | Number of hospital visits
136 | Safehouse visits
137 | Times cheated
138 | Vehicle Resprays
139 | Maximum INSANE Jump distance
140 | Maximum INSANE Jump height
141 | Maximum INSANE Jump flips
142 | Maximum INSANE Jump rotation
143 | Best INSANE stunt awarded
144 | Unique Jumps found
145 | Unique Jumps done
146 | Mission attempts
147 | Missions passed
148 | Total number of missions in game
149 | Cash made in a Taxi
150 | Passengers dropped off
151 | People saved in an Ambulance
152 | Criminals killed on Vigilante Mission
153 | Total fires extinguished
154 | Packages Delivered
155 | Assassinations
156 | Last dance score
157 | Highest Vigilante Mission level
158 | Highest Paramedic Mission level
159 | Highest Firefighter Mission level
160 | Driving skill
161 | Number of Truck missions passed
162 | Money made in Truck
163 | Recruited gang members killed
164 | Armor
165 | Energy
166 | Photographs Taken
167 | Rampages attempted
168 | Rampages passed
169 | Flight time
170 | Times drowned
171 | Number of girls pimped
172 | Best position in 8-Track
173 | Time on jetpack
174 | Shooting range levels passed
175 | Most cars parked on 'Valet Parking'
176 | Kills since last checkpoint
177 | Total legitimate kills
178 | Number of 'Bloodring' kills
179 | Total time in bloodring
180 | No more hurricanes Flag
181 | City unlocked
182 | Number of Police bribes
183 | Number of cars stolen
184 | Current number of girlfriends
185 | Number of disastrous dates
186 | Number of girls dated
187 | Number of times scored with a girl
188 | Number of successful dates
189 | Number of girls dumped
190 | Number of prostitutes visited
191 | Number of houses burgled
192 | Number of safes cracked
193 | Burgular status
194 | Number of stolen items sold
195 | Number of eight balls in pool
196 | Total number of wins playing pool
197 | Total number of losses playing pool
198 | Times visited the gym
199 | Body type
200 | Number of meals eaten
201 | Money made in Quarry
202 | Time taken to Complete Quarry
203 | Number of furniture purchased
204 | Favorite console game
205 | Highest civilian peds killed on Rampage
206 | Highest police peds killed on Rampage
207 | Highest civilian vehicles destroyed on Rampage
208 | Highest police vehicles destroyed on Rampage
209 | Highest number of tanks destroyed on Rampage
210 | Pimping level
211 | Kickstart best score
212 | Best lap time in 8-Track
213 | Number of vehicles exported
214 | Number of vehicles imported
215 | Highest basketball score
216 | Fires started
217 | Amount of drugs sold
218 | Amount of drugs bought
219 | Best lap time in dirt track
220 | Best time in dirt track
221 | Best position in dirt track
222 | NRG-500 best time
223 | Flying skill
224 | Respect Mission
225 | Lung capacity
226 | Game gore rating
227 | Game sex rating
228 | Respect Mission Total
229 | Bike skill
230 | Cycling skill
231 | Snapshots taken
232 | Total snapshots
233 | Luck
234 | Territories taken over
235 | Territories lost
236 | Territories held
237 | Highest number of territories held
238 | Gang members recruited
239 | Enemy gang members killed
240 | Friendly gang members killed
241 | Horseshoes collected
242 | Total horseshoes
243 | Oysters collected
244 | Total oysters
245 | Calories
246 | 2 Player Rampage best time
247 | 2 Player Car Rampage best time
248 | 2 Player On Foot Rampage best time
249 | 2 Player Chopper Rampage best time
250 | 2 Player Bike Rampage best time
251 | 'Keepie Uppy' best time
252 | Progress with Denise
253 | Progress with Michelle
254 | Progress with Helena
255 | Progress with Barbara
256 | Progress with Katie
257 | Progress with Millie
258 | Best position in Lowrider Race
259 | Best time in Lowrider Race
260 | Best position in Little Loop
261 | Best time in Little Loop
262 | Best position in Backroad Wanderer
263 | Best time in Backroad Wanderer
264 | Best position in City Circuit
265 | Best time in City Circuit
266 | Best position in Vinewood
267 | Best time in Vinewood
268 | Best position in Freeway
269 | Best time in Freeway
270 | Best position in Into the Country
271 | Best time in Into the Country
272 | Best position in Badlands A
273 | Best time in Badlands A
274 | Best position in Badlands B
275 | Best time in Badlands B
276 | Best position in Dirtbike Danger
277 | Best time in Dirtbike Danger
278 | Best position in Bandito County
279 | Best time in Bandito County
280 | Best position in Go-Go-Kart
281 | Best time in Go-Go-Kart
282 | Best position in San Fierro Fastlane
283 | Best time in San Fierro Fastlane
284 | Best position in San Fierro Hills
285 | Best time in San Fierro Hills
286 | Best position in Country Endurance
287 | Best time in Country Endurance
288 | Best position in SF to LV
289 | Best time in SF to LV
290 | Best position in Dam Rider
291 | Best time in Dam Rider
292 | Best position in Desert Tricks
293 | Best time in Desert Tricks
294 | Best position in LV Ringroad
295 | Best time in LV Ringroad
296 | Best time in World War Aces
297 | Best time in Barnstorming
298 | Best time in Military Service
299 | Best time in Chopper Checkpoint
300 | Best time in Whirly Bird Waypoint
301 | Best time in Heli Hell
302 | Drive-thru mission accomplished
303 | Management Issues mission accomplished
304 | 555 WE TIP mission accomplished
305 | Yay Ka-Boom-Boom mission accomplished
306 | Fish in a Barrel mission accomplished
307 | Breaking the Bank at Caligula's mission accomplished
308 | A Home In The Hills mission accomplished
309 | maybe set riot mode
310 | Ryder's mission Robbing Uncle Sam accomplished
311 | Mike Toreno mission accomplished
312 | Architectural Espionage mission accomplished
313 | Jizzy mission accomplished
314 | Reuniting the Families mission accomplished
315 | Small Town Bank mission accomplished
316 | Photo Opportunity mission accomplished
317 | Don Peyote mission accomplished
318 | Local Liquor Store mission accomplished
319 | Badlands mission accomplished
320 | Playing time
321 | Hidden Packages found
322 | Tags sprayed
323 | Least favorite gang
324 | Gang members wasted
325 | Criminals wasted
326 | Most Favorite Radio Station
327 | Least Favorite Radio Station
328 | Current weapon skill
329 | Weapon skill levels
330 | Pilot ranking
331 | Strongest Gang
332 | 2nd strongest gang
333 | 3rd strongest gang
334 | Money lost gambling
336 | Gang strength
337 | Territory under control
338 | Are you going to San Fierro? mission accomplished
339 | High Noon mission accomplished
340 | The Green Sabre mission accomplished
341 | maybe Catalina meeting
342 | maybe Wu Zi meeting
343 - 344 | - Unused


GTA SA Tattos

Sanny Builder Help: GTA SA Tattos
Player.SetClothes($PLAYER_CHAR, "TEXTURE", "MODEL", BODY_PART)
Player.Build($PLAYER_CHAR)

Also, see (BODY PART).

TEXTURE | MODEL | BODY PART | NAME
4weed | 4WEED | 4 | Weed
4rip | 4RIP | 4 | Grave
4spider | 4SPIDER | 4 | Spider
5gun | 5GUN | 5 | Gun
5cross | 5CROSS | 5 | Cross
5cross2 | 5CROSS2 | 5 | Rose
5cross3 | 5CROSS3 | 5 | Clown
6aztec | 6AZTEC | 6 | Aztec
6crown | 6CROWN | 6 | Web
6clown | 6CLOWN | 6 | Clown
6africa | 6AFRICA | 6 | Africa
7cross | 7CROSS | 7 | Cross
7cross2 | 7CROSS2 | 7 | Cross
7cross3 | 7CROSS3 | 7 | Cross
7mary | 7MARY | 7 | Mary
8sa | 8SA | 8 | Grove St .
8sa2 | 8SA2 | 8 | San Andreas
8sa3 | 8SA3 | 8 | San Fierro
8westside | 8WESTSD | 8 | Westside
8santos | 8SANTOS | 8 | Los Santos
8poker | 8POKER | 8 | Card
8gun | 8GUN | 8 | Gun
9crown | 9CROWN | 9 | Crown
9gun | 9GUN | 9 | Gun
9gun2 | 9GUN2 | 9 | Gun
9homeboy | 9HOMBY | 9 | Homeboy
9bullet | 9BULLT | 9 | Bullet
9rasta | 9RASTA | 9 | Rasta
10ls | 10LS | 10 | Los Santos
10ls2 | 10LS2 | 10 | Los Santos
10ls3 | 10LS3 | 10 | Los Santos
10ls4 | 10LS4 | 10 | Los Santos
10ls5 | 10LS5 | 10 | Los Santos
10og | 10OG | 10 | O.G.
10weed | 10WEED | 10 | Grove
11grove | 11GROVE | 11 | Grove
11grove2 | 11GROV2 | 11 | Grove
11grove3 | 11GROV3 | 11 | Grove
11dice | 11DICE | 11 | Dice
11dice2 | 11DICE2 | 11 | Dice
11jail | 11JAIL | 11 | Jail
11godsgift | 11GGIFT | 11 | God's Gift
12angels | 12ANGEL | 12 | Angel
12mayabird | 12MAYBR | 12 | Mayan Bird
12dagger | 12DAGER | 12 | Dagger
12bandit | 12BNDIT | 12 | Masks
12cross7 | 12CROSS | 12 | Cross
12mayaface | 12MYFAC | 12 | Mayan Face


GTA SA Train types

Sanny Builder Help: GTA SA Train types

06D8: 1@ = create_train_at 2278.1771 -1144.8823 27.5108 TYPE 0 direction 1

(to change train carriages see SA Memory Handling)

Train types:

 | Train | Carriage1 | Carriage2 | Carriage3 | Carriage4 | Carriage5
0: | #FREIGHT | #FREIFLAT | #FREIFLAT | #FREIFLAT | #FREIFLAT | o
1,2,4,7,11: | #STREAK | #STREAKC | #STREAKC | o | o | o
3: | #FREIGHT | #FREIFLAT | #FREIFLAT | #FREIFLAT | o | o
5: | #STREAK | #STREAKC | #STREAKC | #STREAKC | o | o
6: | #FREIGHT | #FREIFLAT | #FREIFLAT | o | o | o
8: | #TRAM | #TRAM | o | o | o | o
9,14: | #TRAM | o | o | o | o | o
10: | #FREIGHT | #FREIFLAT | o | o | o | o
12: | #FREIGHT | #FREIFLAT | #FREIFLAT | #FREIFLAT | #FREIGHT | o
13: | #FREIGHT | #FREIFLAT | #FREIFLAT | #FREIFLAT | #FREIFLAT | #FREIFLAT
15: | #STREAK | o | o | o | o | o


GTA SA Weapon numbers

Sanny Builder Help: GTA SA Weapon numbers

Weapon numbers used with

01B2: give_actor $PLAYER_ACTOR weapon 28 ammo 60
01B9: set_actor $PLAYER_ACTOR armed_weapon_to 0

and similar opcodes

number | Weapon Group | Name | ModelID | Model name | Icon
gift
10 | 11 | Purple Dildo | 321 | #gun_dildo1 |
11 | 11 | White Dildo | 322 | #gun_dildo2 |
12 | 11 | Long White Dildo | 323 | #gun_vibe1 |
13 | 11 | White Dildo 2 | 324 | #gun_vibe2 |
14 | 11 | Flowers | 325 | #flowera |
15 | 11 | Cane | 326 | #gun_cane |
melee
0 | 1 | Unarmed |  |  |
1 | 1 | Brass Knuckles | 331 | #brassknuckle |
2 | 2 | Golf Club | 333 | #golfclub |
3 | 2 | Night Stick | 334 | #nitestick |
4 | 2 | Knife | 335 | #knifecur |
5 | 2 | Baseball Bat | 336 | #bat |
6 | 2 | Shovel | 337 | #shovel |
7 | 2 | Pool cue | 338 | #poolcue |
8 | 2 | Katana | 339 | #katana |
9 | 2 | Chainsaw | 341 | #chnsaw |
projectiles
16 | 9 | Grenades | 342 | #grenade |
17 | 9 | Tear Gas | 343 | #teargas |
18 | 9 | Molotovs | 344 | #molotov |
handguns
22 | 3 | Pistol | 346 | #colt45 |
23 | 3 | Silenced Pistol | 347 | #silenced |
24 | 3 | Desert Eagle | 348 | #desert_eagle |
shotguns
25 | 4 | Shotgun | 349 | #chromegun |
26 | 4 | Sawn Off Shotgun | 350 | #sawnoff |
27 | 4 | Combat Shotgun | 351 | #shotgspa |
sub-machineguns
28 | 5 | Micro Uzi (Mac 10) | 352 | #micro_uzi |
29 | 5 | MP5 | 353 | #mp5lng |
32 | 5 | Tec9 | 372 | #tec9 |
machineguns
30 | 6 | AK47 | 355 | #ak47 |
31 | 6 | M4 | 356 | #m4 |
rifles
33 | 7 | Rifle | 357 | #cuntgun |
34 | 7 | Sniper Rifle | 358 | #sniper |
specials
35 | 8 | RPG | 359 | #rocketla |
36 | 8 | Missile Launcher | 360 | #heatseek |
37 | 8 | Flame Thrower | 361 | #flame |
38 | 8 | Minigun | 362 | #minigun |
39 | 9 | Sachet Charges | 363 | #satchel |
40 | 13 | Detonator | 364 | #bomb |
41 | 10 | Spray Paint | 365 | #spraycan |
42 | 10 | Fire Extinguisher | 366 | #fire_ex |
43 | 10 | Camera | 367 | #camera |
44 | 12 | Nightvision Goggles | 368 | #nvgoggles |
45 | 12 | Thermal Goggles | 369 | #irgoggles |
46 | 12 | Parachute | 371 | #gun_para |
Other
 |  | jetpack | 370 | #jetpack |


GTA SA WEATHER IDs

Sanny Builder Help: GTA SA WEATHER IDs

01b6: set_weather 1

0 | Extra Sunny | Los Santos
1 | Sunny | Los Santos
2 | Extra Sunny Smog | Los Santos
3 | Sunny Smog | Los Santos
4 | Cloudy | Los Santos
5 | Sunny | San Fierro
6 | Extra Sunny | San Fierro
7 | Cloudy | San Fierro
8 | Rainy | San Fierro
9 | Foggy | San Fierro
10 | Sunny | Las Venturas
11 | Extra Sunny | Las Venturas
12 | Cloudy | Las Venturas
13 | Extra Sunny | Countryside
14 | Sunny | Countryside
15 | Cloudy | Countryside
16 | Rainy | Countryside
17 | Extra Sunny | Desert
18 | Sunny | Desert
19 | Sandstorm | Desert
20 | Underwater |
21 | Extracolours 1 |
22 | Extracolours 2 |


GTA SA ZONES

Sanny Builder Help: GTA SA ZONES

0767: set_zone 'CARSO' type 1 // Fort Carson

0 | BUSINESS
1 | DESERT
2 | ENTERTAINMENT
3 | COUNTRYSIDE
4 | RESIDENTIAL_RICH
5 | RESIDENTIAL_AVERAGE
6 | RESIDENTIAL_POOR
7 | GANGLAND
8 | BEACH
9 | SHOPPING
10 | PARK
11 | INDUSTRY
12 | ENTERTAINMENT_BUSY
13 | SHOPPING_BUSY
14 | SHOPPING_POSH
15 | RESIDENTIAL_RICH_SECLUDED
16 | AIRPORT
17 | GOLF_CLUB
18 | OUT_OF_TOWN_FACTORY
19 | AIRPORT_RUNWAY

NAME | GXT VALUE | GXT ENTRY
Los Santos
LA | Los Santos | LA
RIH1a | Richman | RIH
RIH1b | Richman | RIH
RIH2 | Richman | RIH
RIH3a | Richman | RIH
RIH3b | Richman | RIH
RIH4 | Richman | RIH
RIH5a | Richman | RIH
RIH5b | Richman | RIH
RIH6a | Richman | RIH
RIH6b | Richman | RIH
MUL1a | Mulholland | MUL
MUL1b | Mulholland | MUL
MUL1c | Mulholland | MUL
MUL2a | Mulholland | MUL
MUL2b | Mulholland | MUL
MUL3 | Mulholland | MUL
MUL4 | Mulholland | MUL
MUL5a | Mulholland | MUL
MUL5b | Mulholland | MUL
MUL5c | Mulholland | MUL
MUL6 | Mulholland | MUL
MUL7a | Mulholland | MUL
MUL7b | Mulholland | MUL
MULINT | Mulholland Intersection | MULINT
SUN1 | Temple | SUN
SUN2 | Temple | SUN
SUN3a | Temple | SUN
SUN3b | Temple | SUN
SUN3c | Temple | SUN
SUN4 | Temple | SUN
CHC1a | Las Colinas | CHC
CHC1b | Las Colinas | CHC
CHC2a | Las Colinas | CHC
CHC2b | Las Colinas | CHC
CHC3 | Las Colinas | CHC
CHC4a | Las Colinas | CHC
CHC4b | Las Colinas | CHC
VIN1a | Vinewood | VIN
VIN1b | Vinewood | VIN
VIN2 | Vinewood | VIN
VIN3 | Vinewood | VIN
LDT1a | Downtown Los Santos | LDT
LDT1b | Downtown Los Santos | LDT
LDT1c | Downtown Los Santos | LDT
LDT3 | Downtown Los Santos | LDT
LDT4 | Downtown Los Santos | LDT
LDT5 | Downtown Los Santos | LDT
LDT6 | Downtown Los Santos | LDT
LDT7 | Downtown Los Santos | LDT
LDT8 | Downtown Los Santos | LDT
GLN1 | Glen Park | GLN
GLN1b | Glen Park | GLN
GLN2a | Glen Park | GLN
LFL1a | Los Flores | LFL
LFL1b | Los Flores | LFL
MKT1 | Market | MKT
MKT2 | Market | MKT
MKT3 | Market | MKT
MKT4 | Market | MKT
MARKST | Market Station | MARKST
JEF1a | Jefferson | JEF
JEF1b | Jefferson | JEF
JEF2 | Jefferson | JEF
JEF3a | Jefferson | JEF
JEF3b | Jefferson | JEF
JEF3c | Jefferson | JEF
ROD1a | Rodeo | ROD
ROD1b | Rodeo | ROD
ROD1c | Rodeo | ROD
ROD2a | Rodeo | ROD
ROD2b | Rodeo | ROD
ROD3a | Rodeo | ROD
ROD3b | Rodeo | ROD
ROD4a | Rodeo | ROD
ROD4b | Rodeo | ROD
ROD4c | Rodeo | ROD
ROD5a | Rodeo | ROD
ROD5b | Rodeo | ROD
MAR1 | Marina | MAR
MAR2 | Marina | MAR
MAR3 | Marina | MAR
THALL1 | Commerce | COM
COM1a | Commerce | COM
COM1b | Commerce | COM
COM2 | Commerce | COM
COM3 | Commerce | COM
COM4 | Commerce | COM
ELS1a | East Los Santos | ELS
ELS1b | East Los Santos | ELS
ELS2 | East Los Santos | ELS
ELS3a | East Los Santos | ELS
ELS3b | East Los Santos | ELS
ELS3c | East Los Santos | ELS
ELS4 | East Los Santos | ELS
EBE1 | East Beach | EBE
EBE2a | East Beach | EBE
EBE2b | East Beach | EBE
EBE3c | East Beach | EBE
PER1 | Pershing Square | PER1
IWD1 | Idlewood | IWD
IWD2 | Idlewood | IWD
IWD3a | Idlewood | IWD
IWD3b | Idlewood | IWD
IWD4 | Idlewood | IWD
IWD5 | Idlewood | IWD
GAN1 | Ganton | GAN
GAN2 | Ganton | GAN
CONF1a | Conference Center | CONF
CONF1b | Conference Center | CONF
CITYS | City Hall | CITYS
LMEX1a | Little Mexico | LMEX
LMEX1b | Little Mexico | LMEX
UNITY | Unity Station | UNITY
SMB1 | Santa Maria Beach | SMB
SMB2 | Santa Maria Beach | SMB
VERO1 | Verona Beach | VERO
VERO2 | Verona Beach | VERO
VERO3 | Verona Beach | VERO
VERO4a | Verona Beach | VERO
VERO4b | Verona Beach | VERO
LIND1a | Willowfield | LIND
LIND1b | Willowfield | LIND
LIND2a | Willowfield | LIND
LIND2b | Willowfield | LIND
LIND3 | Willowfield | LIND
LIND4a | Willowfield | LIND
LIND4c | Willowfield | LIND
ELCO1 | El Corona | ELCO
ELCO2 | El Corona | ELCO
PLS | Playa del Seville | PLS
BLUF1a | Verdant Bluffs | BLUF
BLUF1b | Verdant Bluffs | BLUF
BLUF2 | Verdant Bluffs | BLUF
LAIR1 | Los Santos International | LAIR
LAIR2a | Los Santos International | LAIR
LAIR2b | Los Santos International | LAIR
LBAG1 | Los Santos International | LAIR
LBAG2 | Los Santos International | LAIR
LBAG3 | Los Santos International | LAIR
LDOC1a | Ocean Docks | LDOC
LDOC1b | Ocean Docks | LDOC
LDOC2 | Ocean Docks | LDOC
LDOC3a | Ocean Docks | LDOC
LDOC3b | Ocean Docks | LDOC
LDOC3c | Ocean Docks | LDOC
LDOC4 | Ocean Docks | LDOC
Red County
RED | Red County | RED
MONT | Montgomery | MONT
MONT1 | Montgomery | MONT
MONINT | Montgomery Intersection | MONINT
HBARNS | Hampton Barns | HBARNS
HANKY | Hankypanky Point | HANKY
BLUAC | Blueberry Acres | BLUAC
FERN | Fern Ridge | FERN
PANOP | The Panopticon | PANOP
PALO | Palomino Creek | PALO
BLUEB | Blueberry | BLUEB
BLUEB1 | Blueberry | BLUEB
TOPFA | Hilltop Farm | TOPFA
NROCK | North Rock | NROCK
DILLI | Dillimore | DILLI
San Fierro
SF | San Fierro | SF
BATTP | Battery Point | BATTP
ESPN1 | Esplanade North | ESPN
ESPN2 | Esplanade North | ESPN
ESPN3 | Esplanade North | ESPN
ESPE1 | Esplanade East | ESPE
ESPE2 | Esplanade East | ESPE
ESPE3 | Esplanade East | ESPE
JUNIHO | Juniper Hollow | JUNIHO
SFDWT1 | Downtown | SFDWT
SFDWT2 | Downtown | SFDWT
SFDWT3 | Downtown | SFDWT
SFDWT4 | Downtown | SFDWT
SFDWT5 | Downtown | SFDWT
SFDWT6 | Downtown | SFDWT
PARA | Paradiso | PARA
CALT | Calton Heights | CALT
FINA | Financial | FINA
BAYV | Palisades | BAYV
JUNIHI | Juniper Hill | JUNIHI
CHINA | Chinatown | CHINA
CIVI | Santa Flora | CIVI
WESTP1 | Queens | WESTP
WESTP2 | Queens | WESTP
WESTP3 | Queens | WESTP
CITYS | City Hall | CITYS
THEA1 | King's | THEA
THEA2 | King's | THEA
THEA3 | King's | THEA
EASB1 | Easter Basin | EASB
EASB2 | Easter Basin | EASB
GARC | Garcia | GARC
SFGLF3 | Garcia | GARC
CRANB | Cranberry Station | CRANB
OCEAF1 | Ocean Flats | OCEAF
OCEAF2 | Ocean Flats | OCEAF
OCEAF3 | Ocean Flats | OCEAF
HASH | Hashbury | HASH
DOH1 | Doherty | DOH
DOH2 | Doherty | DOH
SFBAG2 | Easter Bay Airport (English) | SFAIR
SFBAG3 | Easter Bay Airport (English) | SFAIR
SFBAG1 | Easter Bay Airport (English) | SFAIR
SFAIR1 | Easter Bay Airport (English) | SFAIR
SFAIR2 | Easter Bay Airport (English) | SFAIR
SFAIR3 | Easter Bay Airport (English) | SFAIR
SFAIR4 | Easter Bay Airport (English) | SFAIR
SFAIR5 | Easter Bay Airport (English) | SFAIR
Flint County
FLINTC | Flint County | FLINTC
CUNTC1 | Avispa Country Club | CUNTC
CUNTC2 | Avispa Country Club | CUNTC
CUNTC3 | Avispa Country Club | CUNTC
SFGLF1 | Avispa Country Club | CUNTC
SFGLF2 | Avispa Country Club | CUNTC
SFGLF4 | Avispa Country Club | CUNTC
HAUL | Fallen Tree | HAUL
HILLP | Missionary Hill | HILLP
EBAY | Easter Bay Chemical | EBAY
EBAY2 | Easter Bay Chemical | EBAY
ETUNN | Easter Tunnel | ETUNN
SILLY1 | Foster Valley | SILLY
SILLY2 | Foster Valley | SILLY
SILLY3 | Foster Valley | SILLY
SILLY4 | Foster Valley | SILLY
FARM | The Farm | FARM
BEACO | Beacon Hill | BEACO
FLINTI | Flint Intersection | FLINTI
FLINTR | Flint Range | FLINTR
LEAFY | Leafy Hollow | LEAFY
BACKO | Back o Beyond | BACKO
Whetstone
WHET | Whetstone | WHET
MTCHI1 | Mount Chiliad | MTCHI
MTCHI2 | Mount Chiliad | MTCHI
MTCHI3 | Mount Chiliad | MTCHI
MTCHI4 | Mount Chiliad | MTCHI
CREEK | Shady Creeks | CREEK
CREEK1 | Shady Creeks | CREEK
SHACA | Shady Cabin | SHACA
ANGPI | Angel Pine | ANGPI
Las Venturas
VE | Las Venturas | VE
YBELL1 | Yellow Bell Golf Course | YBELL
YBELL2 | Yellow Bell Golf Course | YBELL
SPIN | Spinybed | SPIN
KACC | K.A.C.C. Military Fuels | KACC
PRP1 | Prickle Pine | PRP
PRP2 | Prickle Pine | PRP
PRP3 | Prickle Pine | PRP
PRP4 | Prickle Pine | PRP
YELLOW | Yellow Bell Station | YELLOW
JTN1 | Julius Thruway North | JTN
JTN2 | Julius Thruway North | JTN
JTN3 | Julius Thruway North | JTN
JTN4 | Julius Thruway North | JTN
JTN5 | Julius Thruway North | JTN
JTN6 | Julius Thruway North | JTN
JTN7 | Julius Thruway North | JTN
JTN8 | Julius Thruway North | JTN
PINT | Pilson Intersection | PINT
ISLE | The Emerald Isle | ISLE
ROCE1 | Roca Escalante | ROCE
ROCE2 | Roca Escalante | ROCE
WWE | Whitewood Estates | WWE
WWE1 | Whitewood Estates | WWE
OVS | Old Venturas Strip | OVS
CREE | Creek | CREE
REDE1 | Redsands East | REDE
REDE2 | Redsands East | REDE
REDE3 | Redsands East | REDE
REDW1 | Redsands West | REDW
REDW2 | Redsands West | REDW
REDW3 | Redsands West | REDW
REDW4 | Redsands West | REDW
HGP | Harry Gold Parkway | HGP
STRIP1 | The Strip | STRIP
STRIP2 | The Strip | STRIP
JTW1 | Julius Thruway West | JTW
JTW2 | Julius Thruway West | JTW
VISA1 | The Visage | VISA
VISA2 | The Visage | VISA
STAR1 | Starfish Casino | STAR
STAR2 | Starfish Casino | STAR
CONST1 | Starfish Casino | STAR
RING | The Clown's Pocket | RING
SRY | Sobell Rail Yards | SRY
JTE1 | Julius Thruway East | JTE
JTE2 | Julius Thruway East | JTE
JTE3 | Julius Thruway East | JTE
JTE4 | Julius Thruway East | JTE
BFLD1 | Blackfield | BFLD
BFLD2 | Blackfield | BFLD
CALI1 | Caligula's Palace | CALI
CALI2 | Caligula's Palace | CALI
VAIR1 | Las Venturas Airport (English) | VAIR
VAIR2 | Las Venturas Airport (English) | VAIR
VAIR3 | Las Venturas Airport (English) | VAIR
LVBAG | Las Venturas Airport (English) | VAIR
PIRA | Pirates in Men's Pants | PIRA
ROY | Royal Casino | ROY
PILL1 | Pilgrim | PILL
PILL2 | Pilgrim | PILL
LST | Linden Station | LST
LINDEN | Linden Station | LINDEN
HIGH | The High Roller | HIGH
STRIP3 | The Strip | STRIP
STRIP4 | The Strip | STRIP
PINK | The Pink Swan | PINK
CAM | The Camel's Toe | CAM
GGC1 | Greenglass College | GGC
GGC2 | Greenglass College | GGC
LDS | Linden Side | LDS
LVA1 | LVA Freight Depot | LVA
LVA2 | LVA Freight Depot | LVA
LVA3 | LVA Freight Depot | LVA
LVA4 | LVA Freight Depot | LVA
LVA5 | LVA Freight Depot | LVA
DRAG | The Four Dragons Casino | DRAG
LOT | Come-A-Lot | LOT
BINT1 | Blackfield Intersection | BINT
BINT2 | Blackfield Intersection | BINT
BINT3 | Blackfield Intersection | BINT
BINT4 | Blackfield Intersection | BINT
JTS1 | Julius Thruway South | JTS
JTS2 | Julius Thruway South | JTS
BFC1 | Blackfield Chapel | BFC
BFC2 | Blackfield Chapel | BFC
RIE | Randolph Industrial Estate | RIE
LDM | Last Dime Motel | LDM
RSE | Rockshore East | RSE
RSW1 | Rockshore West | RSW
Tierra Robada
ROBAD | Tierra Robada | ROBAD
ROBAD1 | Tierra Robada | ROBAD
ELQUE | El Quebrados | ELQUE
SUNNN | Bayside | SUNNN
BYTUN | Bayside Tunnel | BYTUN
ALDEA | Aldea Malvada | ALDEA
SUNMA | Bayside Marina | SUNMA
BARRA | Las Barrancas | BARRA
ROBINT | Robada Intersection | ROBINT
Bone County
BONE | Bone County | BONE
PAYAS | Las Payasadas | PAYAS
VALLE | Valle Ocultado | VALLE
ELCA | El Castillo del Diablo | ELCA
ELCA1 | El Castillo del Diablo | ELCA
ELCA2 | El Castillo del Diablo | ELCA
ARCO | Arco del Oeste | ARCO
MEAD | Verdant Meadows | MEAD
BRUJA | Las Brujas | BRUJA
TOM | Regular Tom | TOM
REST | Restricted Area | REST
BIGE | 'The Big Ear' (English) | BIGE
PALMS | Green Palms | PALMS
OCTAN | Octane Springs | OCTAN
PROBE | Lil' Probe Inn | PROBE
CARSO | Fort Carson | CARSO
QUARY | Hunter Quarry | QUARY
Lakes
LSINL | Los Santos Inlet | LSINL
FLINW | Flint Water | FLINW
FISH | Fisher's Lagoon | FISH
SANB1 | San Fierro Bay | SANB
SANB2 | San Fierro Bay | SANB
SHERR | Sherman Reservoir | SHERR
SASO | San Andreas Sound | SASO
Bridges
GANTB | Gant Bridge | GANTB
GANTB1 | Gant Bridge | GANTB
*DAM | The Sherman Dam | DAM
GARV | Garver Bridge | GARV
GARV1 | Garver Bridge | GARV
GARV2 | Garver Bridge | GARV
KINC | Kincaid Bridge | KINC
KINC1 | Kincaid Bridge | KINC
KINC2 | Kincaid Bridge | KINC
FALLO | Fallow Bridge | FALLO
MART | Martin Bridge | MART
MAKO | The Mako Span | MAKO
FRED | Frederick Bridge | FRED


SCM Documentation: GTA VC

Sanny Builder Help: SCM Documentation: GTA VC

Contents:

Gang IDs

Garage ID

Interiours

Keypress numbers

PedTypes

Radar icons

Weapon numbers


GTA VC Gang IDs

Sanny Builder Help: GTA VC Gang IDs

0236: set_gang 4 car_to #BAGGAGE
0235: set_gang 2 models_to #ARMY #ARMY

Gang0 | Cubans
Gang1 | Haitians
Gang2 | Street wannabees
Gang3 | Columbians (Diaz's)
Gang4 | Renta Cops (PIGs)
Gang5 | Bikers
Gang6 | Vercetti (yours)
Gang7 | Golfers
Gang8 | Army (special gang)


GTA VC Garage ID

Sanny Builder Help: GTA VC Garage ID
Garage ID - Description
1 | Placeholder, DummyID. (doesn't do anything,
 | initial garages get 1, and change type when
 | a certain asset is bought)
3 | BombShop (8ball)
5 | Pay and Spray
7 | Car Eater, haven't got a clue what this is
 | suppose to be, not sunshine autos anyways...
8 | Sunshines Autos Carshop, List 1
9 | Sunshines Autos Carshop, List 2
10 | Sunshines Autos Carshop, List 3
13 | DO NOT USE, CORRUPTS SAVEGAMES!
16..18 | In use Saving Garages
19 | Garage where you beat the cops up during "Copland"
22 | Sunshines Autos Carshop, List 4
23 | Garage to park the tank in during "Sir, Yes Sir!"
24..31 | In use Saving Garages
32 | Unused Saving Garage


GTA VC interiours

Sanny Builder Help: GTA VC interiours
0 | outside
1 | hotel
2 | mansion
3 | bank
4 | mall
5 | stripclub
6 | lawyers
7 | cafe robina
8 | concert
9 | studio
10 | shooting range
11 | apartment/bikerbar
12 | policeHQ
14 | stadium1
15 | stadium2
16 | stadium3
17 | Malibu club
18 | Print Works


GTA VC keypress numbers

Sanny Builder Help: GTA VC keypress numbers

My tested key_press numbers in Vice. Returned by

00E1: key_pressed 0? <number tested>?

with standard controls setup. Made from ghost_master2000's list.

Number | On Foot | In Car
2 | turn left/right | Look left + turret L and Look right + turret
3 |  | turret up/down
4 | action key | Radio
5 | prev. weapon | look left/behind
6 | aim/target | handbrake
7 | next weapon | look right/behind
8 | forward |
9 | backward |
10 | strafe left | turn left
11 | strafe right | turn right
13 | camera | camera
14 | jump | brake/reverse
15 | enter vehicle | exit vehicle
16 | sprint | gas/forward
17 | shoot/attack | shoot
18 | crouch | horn
19 | look behind | sub-mission

With classic setup

Number | On Foot | In Car
3 | Look left and right | turret up/down

In certain situations like when then lock_actor code is used, keypress number 12 is used. I don't know how to set that key up.

Number | On Foot | In Car
12 | Used to exit certain modes


PedTypes
0 | player1
1 | player2
2 | player3
3 | player4
4 | civmale
5 | civfemale
6 | cop
7 | gang1
8 | gang2
9 | gang3
10 | gang4
11 | gang5
12 | gang6
13 | gang7
14 | gang8
15 | gang9
16 | emergency
17 | fireman
18 | criminal
19 | special


GTA VC radar icons

Sanny Builder Help: GTA VC radar icons

02A8: create_marker 236?? 28? at 396?? 400?? 404??

the 236?? is the marker ID

and got all the alternative marker 'types' the 28? in the above code, Just change it to one of the following:

0 | Small purple dot
1 | Large player type icon
2 | Small arrow
3 | North on the Map
4 | Avery
5 | radar_biker
6 | Colonel Cortez
7 | Diaz
8 | Kent
9 | Ken Rosenberg
10 | Phil
11 | Biker's Bar
12 | Docks
13 | Malibu Club
14 | Cuban missions
15 | P0rn Studios
16 | AmmuNation
17 | Haitian missions
18 | Toolshop
19 | Save Game Icon
20 | Pole Position Club Icon
21 | Cherry Poppers Icon
22 | Kauffman Cabs Icon
23 | lovefist - Love Fist
24 | Printworks Icon
25 | No Icon
26 | Sunshine Autos Icon
27 | Spray 'n' Pay
28 | Clothing pickup
29 | Tommy's Home Icon
30 | The Phone Icon
31 | Wildstyle station logo
32 | Flash station logo
33 | KChat station logo
34 | Fever station logo
35 | VRock station logo
36 | VCPR station logo
37 | Espantoso station logo)
38 | Emotion station logo
39 | Wave station logo


GTA VC weapon numbers

Sanny Builder Help: GTA VC weapon numbers

Tested and confirmed weapon numbers returned by

031D: actor <actor> hit_by_weapon <weapon number>

Number | Group | Name | Model name | Icon
0 |  | Unarmed |  |
1 |  | BrassKnuckle | #brassknuckle |
2 |  | ScrewDriver | #screwdriver |
3 |  | GolfClub | #golfclub |
4 |  | NightStick | #nitestick |
5 |  | Knife | #knifecur |
6 |  | BaseballBat | #bat |
7 |  | Hammer | #hammer |
8 |  | Cleaver | #cleaver |
9 |  | Machete | #machete |
10 |  | Katana | #katana |
11 |  | Chainsaw | #chnsaw |
12 | 2 | Grenade | #grenade |
13 | 2 | DetonateGrenade | #bomb |
14 | 2 | TearGas | #teargas |
15 | 2 | Molotov | #molotov |
16 | 2 | Rocket | #missile |
17 | 3 | Colt45 | #colt45 |
18 | 3 | Python | #python |
19 | 4 | Shotgun | #chromegun |
20 | 4 | Spas12Shotgun | #shotgspa |
21 | 4 | StubbyShotgun | #buddyshot |
22 | 5 | Tec9 | #tec9 |
23 | 5 | Uzi C | #uzi |
24 | 5 | SilencedIngram | #ingramsl |
25 | 5 | Mp5 | #mp5lng |
26 | 6 | m4 | #m4 |
27 | 6 | Ruger | #ruger |
30 | 7 | RocketLauncher | #rocketla |
31 | 7 | FlameThrower | #flame |
32 | 7 | M60 | #M60 |
33 | 7 | Minigun | #minigun |
35 | 7 | HeliCannon |  |
28 | 8 | SniperRifle | #sniper |
29 | 8 | LaserScope | #laser |
34 | 9 | Detonator |  |
36 | 9 | Camera | #camera |


SCM Documentation: GTA LCS

Sanny Builder Help: SCM Documentation: GTA LCS

Contents:

Gang IDs

Model IDs

Player Skins

Special Actors

Weapon numbers

Weather


GTA LCS Gang IDs

Sanny Builder Help: GTA LCS Gang IDs

023B: set_gang 0 car_to 172

GANG0 | Leone
GANG1 | Triad
GANG2 | Diablo
GANG3 | Yakuza
GANG4 | Yardie
GANG5 | Colombian
GANG6 | Hood
GANG7 | Forelli
GANG8 | Sindacco


GTA LCS model IDs

Sanny Builder Help: GTA LCS model IDs
Model ID | Model Name
0 | PLAYER
1 | COP
2 | SWAT
3 | FBI
4 | ARMY
5 | MEDIC
6 | FIREMAN
7 | MALE01
8 | <unknown>
9 | TAXI_D
10 | PIMP
11 | CRIMINAL01
12 | CRIMINAL02
13 | MALE02
14 | MALE03
15 | FATMALE01
16 | FATMALE02
17 | FEMALE01
18 | FEMALE02
19 | FEMALE03
20 | FATFEMALE01
21 | FATFEMALE02
22 | PROSTITUTE
23 | PROSTITUTE2
24 | P_MAN1
25 | P_MAN2
26 | P_WOM1
27 | P_WOM2
28 | CT_MAN1
29 | CT_MAN2
30 | CT_WOM1
31 | CT_WOM2
32 | LI_MAN1
33 | LI_MAN2
34 | LI_WOM1
35 | LI_WOM2
36 | DOCKER1
37 | DOCKER2
38 | SCUM_MAN
39 | SCUM_WOM
40 | WORKER1
41 | WORKER2
42 | B_MAN1
43 | B_MAN2
44 | B_MAN3
45 | B_WOM1
46 | B_WOM2
47 | B_WOM3
48 | MOD_MAN
49 | MOD_WOM
50 | ST_MAN
51 | ST_WOM
52 | FAN_MAN1
53 | FAN_MAN2
54 | FAN_WOM
55 | HOS_MAN
56 | HOS_WOM
57 | CONST1
58 | CONST2
59 | SHOPPER1
60 | SHOPPER2
61 | SHOPPER3
62 | STUD_MAN
63 | STUD_WOM
64 | CAS_MAN
65 | CAS_WOM
68 | HITMAN
79 | GANG01 LEONE_A
80 | GANG02 LEONE_B
81 | GANG03 TRIAD_A
82 | GANG04 TRIAD_B
83 | GANG05 DIABLO_A
84 | GANG06 DIABLO_B
85 | GANG07 YAKUZA_A
86 | GANG08 YAKUZA_B
87 | GANG09 YARDIE_A
88 | GANG10 YARDIE_B
89 | GANG11 COLOMBIAN_A
90 | GANG12 COLOMBIAN_B
91 | GANG13 HOOD_A
92 | GANG14 HOOD_B
93 | GANG15 Forelli thug1
94 | GANG16 Forelli thug2
95 | GANG17 Sindacco thug1
96 | GANG18 Sindacco


GTA LCS Player Skins

Sanny Builder Help: GTA LCS Player Skins

0357: set_actor $PLAYER_ACTOR skin_to 'PLR3'

'PLR' | Leone's suit
'PLR2' | Lawyer's suit
'PLR3' | Casual clothes
'PLR4' | Chauffeur's clothes
'PLR5' | Overalls
'PLR6' | Tuxedo
'PLR7' | Avenging Angel's fatigues
'PLR8' | 'The King' jumpsuit
'PLR9' | Cox Mascot suit
'PLR10' | Underwear
'PLR11' | Hero garb
'PLR12' | 'Dragon' jumpsuit
'PLR13' | Antonio
'PLR14' | Sweats
'PLR15' | Wiseguy
'PLR16' | Goodfella


GTA LCS Special Actors

Sanny Builder Help: GTA LCS Special Actors

0241: load_special_actor 1 'PLR6'

AVERY | Avery Carrington
BABY | Giovanni Casa (baby)
BIKER1 | Biker Dude 1
BIKER2 | Biker Dude 2
BODYBAG | BODYBAG
CAMP_MAN | Campaign Worker
CAMP_WOM | Campaign Worker 2
CASA | Giovanni Casa
CHAUFF | Chauffeur
DELIASS | Deli Assistant
DONOVAN | O'Donovan
EIGHT | 8Ball
FKENNY | Father Kenny (not used)
FRANFOR | Franco Forelli
GRDANG1 | Avenging Angel
GRDANG2 | Avenging Angel 2
GREASE | Grease Zuko
GUN_ASS | Gun assistant
HOBO_01 | Donald Love 2
HOLEJOG | Mayor RC Hole (Jogging outfit)
HOPPER | Jane Hopper
JD_SHOT | dead JD
JDMADE | JD O'Toole - Made Man
KAS_01 | Toshiko Kasen (kimono)
KAZUKI | Kazuki Kasen
LOVE_01 | Donald Love
M_HOLE | Mayor RC Hole
MAR_01 | Maria
MASTOR | Massimo Torrini (Assassin)
MCAFFRY | Det. Leon McAffrey
MICKEYH | Mickey H
MIGUEL | Miguel
NED_01 | Ned Burner (Reporter)
PAULIE | Paulie Sindacco
PHILC | Phil Cassidy
PLR10 | player (skin: boxer Shorts)
PLR11 | player (skin: bad super hero)
PLR12 | player (skin: dragon)
PLR2 | player (skin: lawyer)
PLR3 | player (skin: travel clothes)
PLR4 | player (skin: chauffeur)
PLR5 | player (skin: hockey mask)
PLR6 | player (skin: tuxedo)
PLR7 | player (skin: avenging angel)
PLR8 | player (skin: the King of Rock'n Roll)
PLR9 | player (skin: cock's mascot)
RAY_01 | Ray (Bad Cop)
SAL_01 | Salvatore (Mob Don)
SAL_CON | Sal CONVICT
THUG_01 | Sicilian Thug 1
THUG_02 | Sicilian Thug 2
TOOL_01 | JD O'Toole
VINC_01 | Vincenzo Cilli
WAYNE | Wayne (Biker Dude)
WKAS_01 | Toshiko Kasen (western)


GTA LCS Weapon numbers

Sanny Builder Help: GTA LCS Weapon numbers

!untested, incomplete

01B6: give_player $PLAYER_CHAR weapon 1 ammo 1

Weapon ID | Model ID | Name
0 | - | Unarmed
1 | 259 |
2 | 260 |
3 | 261 |
4 | 262 |
5 | 263 |
6 | 264 |
7 | 265 |
8 | 266 |
9 | 267 |
10 | 268 |
11 | 269 |
12 | 270 | Grenades
13 | 291 |
14 | 271 ? |
15 | 272 |
16 | 273 ? |
17 | 274 | Pistol
18 | 275 | .357
19 | 277 | Shotgun
20 | 278 |
21 | 279 |
22 | 281 |
23 | 282 | Micro-SMG
24 | 283 |
25 | 284 | SMG
26 | 280 | M4
27 | 276 | AK-47
28 | 285 | Sniper Rifle
29 | 286 |
30 | 287 | Rocket Launcher
31 | 288 | Flame-Thrower
32 | 289 |
33 | 290 | Minigun
34 | ? |
35 | ? |
36 | 292 | Name


GTA LCS weather

Sanny Builder Help: GTA LCS weather

01BB: set_weather 1

0 | SUNNY
1 | CLOUDY
2 | RAINY
3 | FOGGY
4 | EXTRA SUNNY
5 | HURRICANE
6 | EXTRA COLOURS
7 | SNOW


SCM Documentation: GTA VCS

Sanny Builder Help: SCM Documentation: GTA VCS


GTA VCS Clothes IDs

Sanny Builder Help: GTA VCS Clothes IDs.
OUT_F1 | Army Fatigues
OUT_F2 | Casuals
OUT_F3 | Leisure
OUT_F4 | Trailer Trash
OUT_F5 | Cuban Style
OUT_F6 | Pastel Suit
OUT_F7 | Tracksuit
OUT_F8 | Hood
OUT_F9 | Hired Muscle
OUT_F10 | Repo-Man
OUT_F11 | Smuggler
OUT_F12 | Smart Suit
OUT_F13 | Winner
OUT_F14 | Wet Suit


GTA VCS Gang IDs

Sanny Builder Help: GTA VCS Gang IDs
Gang0 | Umberto's guys
Gang1 | Cholos
Gang2 | Sharks
Gang3 | Army
Gang4 | Security
Gang5 | Bikers
Gang6 | Vance gang
Gang7 | Golfer
Gang8 | Marty's


GTA VCS Weather IDs

Sanny Builder Help: GTA VCS Weather IDs
0109: set_weather 7

0 | Sunny
1 | Cloudy
2 | Rainy
3 | Foggy
4 | Extra sunny
5 | Hurricane
6 | Extra colours
7 | Ultra sunny


Articles

  • Mission Coding with Sanny Builder Tutorial Part I
  • Mission Coding with Sanny Builder Tutorial Part II


Sanny Builder Help: About the program

Mission Coding with Sanny Builder Tutorial
Grand Theft Auto

San Andreas

Mission Coding with Sanny Builder Tutorial
Part I
Getting started

Introduction

Hi, since a long time I wanted to make a tutorial for newbies, it won't tell you what to do, it will helps you doing what you want to do. It can also be a good tutorial for Sanny builder. I tried to make a tutorial for anyone even if you don't know anything about programming. You might want jump straight to part II, if you think you know enough about coding to get started.

With Mission coding (or Mission scripting) you can make your own missions, your own mods or modificate existing ones (you can find many in this Mission Mods and this Mission Coding (and is where you can ask questions about coding) .

Mission coding is done with the files main.scm and script.img in data\script folder of San Andreas. Main.scm is a compiled file, so it's made in a language that the computer can understand it easily. If you open main.scm with hexadecimal editor it looks like that inside :
CODE
Copy to Clipboard
D6 00 04 00 19 01 02 45 0E 4D 00 01 FE 3D 87 02 A6 00 02 45 0E

So you need to uncompile it to have it in a human readable format, then we will be able to program in it. You don't need to do anything on the file script.img, the file is needed, so each main.scm will need his own script.img.

So to decompile main.scm you need Sanny Builder. There is many other decompiler but if you a beginer Sanny will be the best coding solution, because it's continuously update, has proper support, is fast, is colorfull [image] !!!!! And the tutorial is made with and for Sanny Builder.
Sanny Builder is close to Barton Waterduck's San Andreas Mission builder but because the syntax is different I highly advise to use Sanny Builder but if you want to disobey, here it is : Barton's Waterduck Mission Builder -Craig's version, thanks to him.

Something very important, to get informations, the Sanny Builder's Help, it' full of very useful information and always available (like offline).

Launch the executable follow usual installation process. Then go first to Tools\options (or press F10). In general tab check Show progress, Show report, Show warning, Quick game loading, Condition check, Ranges check, Writes opcodes, maybe Replace mission numbers, Insert Original mission names, Add extra info to SCM. I will explain later why we need those.

Like this :

Close Sanny Builder and reopen it.

There is many other good tutorials that should help you : YeTi's SA Coding Tutorial Part One, YeTi's SA Coding Tutorial Part Two, Y_less quick tuto, those are for San Andreas. Vice City tutorials can help you too : Alex "Y_Less" Cole's n00b guide to coding, littleguna's VC Coding Tutorial, YeTi's VC Coding Tutorial Part One, YeTi's VC Coding Tutorial Part Two. The GTAforums tutorial archive. You can find more in this forum here.
You can visit GTAmodding.com and particulary Mission scripting category.

1. Main.scm architecture :

So now copy original main.scm and script.img to a new coding working folder (or anywhere you want : desktop, My docs, recycle bin, your mum's docs [image] ....) you've created and open it (make backups !!!!! like doing right away a new folder for original main.scm and script.img) by clicking open and selecting SCM File (*.scm). You can see the progress bar filling up (That's why we've truned on the option "Show progress").

- Define section :

And you will get something like that :
CODE
Copy to Clipboard
// This file was decompiled using sascm.ini published by Seemann (http://sannybuilder.com/files/SASCM.rar) on 13.10.2007
DEFINE OBJECTS 389
DEFINE OBJECT SANNY BUILDER 3.03
DEFINE OBJECT INFO                     // Object number -1
DEFINE OBJECT KEYCARD                  // Object number -2
DEFINE OBJECT AD_FLATDOOR              // Object number -3
DEFINE OBJECT KB_BANDIT_U              // Object number -4
etc...

As you can see it defines the objects that will be used in the main.scm, there is 389 of them like said on top (DEFINE OBJECTS 389). To add an object just go to to last one and add yours.

Further down (much further down) you can find that :
CODE
Copy to Clipboard
DEFINE MISSIONS 135
DEFINE MISSION 0 AT @INITIAL
DEFINE MISSION 1 AT @INITIL2
DEFINE MISSION 2 AT @INTRO
DEFINE MISSION 3 AT @NONE
etc...

This defines the missions, there is 135 of them like said on top (DEFINE MISSIONS 135). If you use Xbox, Playstation 2, or jarjar 2-player mod files you can see that there is more missions which are 2 player console mission but that's another story...

CODE
Copy to Clipboard
DEFINE EXTERNAL_SCRIPTS 78 // Use -1 in order not to compile AAA script
DEFINE SCRIPT PLAYER_PARACHUTE AT @PLCHUTE // 0
DEFINE SCRIPT PARACHUTE AT @PARACH // 1
DEFINE SCRIPT BCESAR2 AT @BCESAR2 // 2
DEFINE SCRIPT BCESAR3 AT @COKEC // 3
DEFINE SCRIPT SLOT_MACHINE AT @BANDIT // 4
etc...

This defines the external scripts which are scripts (programs) that are triggered when needed, there is 78 of them like said on top. That's what handles the Parachute (player -PLAYER_PARACHUTE- and non-players -PARACHUTE-), Games at the casino (ROULETTE, VIDPOK -Video Poker-, BLACKJ -Black Jack-, WHEELO -Wheel Of Fortune-, etc...), Shops (AMMU, TATTOO, BARBER, JUNKFUD, CARMOD), and many other thing more or less weird (DEBT, STRIPW, GF_SEX, HOME_BRAINS...) More about those later on.

Then you get to those 2 lines : CODE
Copy to Clipboard
DEFINE UNKNOWN_EMPTY_SEGMENT 0

DEFINE UNKNOWN_THREADS_MEMORY 574
Which are undocumented and useless for me and you.

- Main section :

Now you can see something like this :
CODE
Copy to Clipboard

{$VERSION 3.1.0027}

//-------------MAIN---------------
03A4: name_thread 'MAIN'
016A: fade 0 time 0
042C: set_total_missions_to 147
030D: set_max_progress 187
0997: set_total_respect_points_to 1339
01F0: set_max_wanted_level_to 6
0111: set_wasted_busted_check_to 0
00C0: set_current_time_hours_to 8 current_time_minutes_to 0
04E4: unknown_refresh_game_renderer_at 2488.562 -1666.864
03CB: set_rendering_origin_at 2488.562 -1666.864 13.3757
062A: change_stat 165 to 800.0 // floating-point values
062A: change_stat 23 to 50.0 // floating-point values
062A: change_stat 21 to 200.0 // floating-point values
062A: change_stat 160 to 0.0 // floating-point values
0629: change_stat 181 to 4 // integer values
0629: change_stat 68 to 0 // integer values
0053: $PLAYER_CHAR = create_player #NULL at 2488.562 -1666.864 12.8757
etc...

Up to before there (use Sanny search tool and search "mission 0") :
CODE
Copy to Clipboard
//-------------Mission 0---------------
// Originally: Initial 1

:INITIAL
03A4: name_thread 'INITIAL'
06C8: enable_riot 0
0004: $1515 = 0
0005: $1500 = 5.0
etc...

It is called the main part or the main section (and sometimes with imprecision named the main thread). In this there is many little bit of scripts that for example create the red circles which start missions, the thing that handles the phone calls (CELLFON and other things), that handles grilfriends, from where everything is triggered (started), where many many mods are added, and that's where you will start coding. The main section is composed of many little threads, but it starts with the main thread. And the thread is (and is the only one) created by the engine itself, you don't have to use the opcode that create threads 004F (create_thread) like everyother ones to ingnite it. Don't worry, a whole part will be dedicated to threads later.

In the main part you can only use locals variables (<0@, 1@, 2@, etc...) up to 31@ included, 32@ and 33@ are internals local timers (counts the amount of time elapsed, we'll see it later) that you can use too. But any over 33@ will not work in the main part. Sanny won't be happy and will tell you that the local var. is out of range (that's why we've turned "Range check" option on). You can use any globals you want but their number is limited to 16383, it should be far enough.

- Now Mission section :

Then after :
CODE
Copy to Clipboard
//-------------Mission 0---------------
// Originally: Initial 1

:INITIAL
03A4: name_thread 'INITIAL'
06C8: enable_riot 0
0004: $1515 = 0
0005: $1500 = 5.0
etc...

It's the first mission (which actually ain't a mission because it's done during the first milliseconds of a new game before the cutscene and doesn't give any mission points). This mission actually create parked cars, some weapons pick up and other thing.

After will get to the mission 1 (search mission 1)
CODE
Copy to Clipboard
//-------------Mission 1---------------
// Originally: Initial 2

:INITIL2
03A4: name_thread 'INITIL2'
0004: $3407 = 25
0004: $3408 = 100
0004: $3409 = 250
etc...

Same as mission 0 it's not a mission, it only set some variables equal to number value, parked some cars again, activate some doors and lifts.

Then Mission 2
CODE
Copy to Clipboard
//-------------Mission 2---------------
// Originally: Intro

:INTRO
03A4: name_thread 'INTRO'
0050: gosub @INTRO_47
00D6: if
0112:   wasted_or_busted // mission only
004D: jump_if_false @INTRO_38
0050: gosub @INTRO_9715
etc...
This one is part of the intro cutscene and the mission ends when you got to the red circle at CJ's home (Jonhson House in Ganton).

After there is the arcades games (originally: Video game: They crawled from uranus; originally: Video game: Duality; originally: Video game: Go Go Space Monkey; originally: Video game: Let's get ready to BUMBLE; originally: Video game: poker) then other thing like pool (originally: Pool), dance (originally: Lowrider (bet and dance)) and Zero "hidden/bonus" mission (originally: Beefy Baron) and after those, the "Big smoke" Mission (mission 11) which is first mission of the game.

And then like that up to mission's 134 end.
If you want to add a mission add after that and define it in define mission section. (more later on).

- External script section (last section)

After the last mission you can see all the defined external script starting with the first one PLAYER_PARACHUTE:
CODE
Copy to Clipboard
//-------------External script 0 (PLAYER_PARACHUTE)---------------

:PLCHUTE
03A4: name_thread 'PLCHUTE'
0247: request_model #GUN_PARA

:PLCHUTE_16
etc...

and then CODE
Copy to Clipboard
//-------------External script 1 (PARACHUTE)---------------

:PARACH
03A4: name_thread 'PARACH'
0004: $8275 = 0
etc...

and so on till the 77th external scripts. Many things in external scripts, by looking at the name of the external, you can often figure out what it is used for.

What's most important for now is the main part.

But still about main.scm architecture, you need to know that some things are limited in main.scm look, here . As you can see the main size (the lenght of all 'main part' threads) is limited to 200 000 bytes. To know how long the 'main part' is compile and look the report it tells you "MAIN size : XXXXXX b." and then the biggest mission "Largest Mission : XXXX b." and the Largest external script :

That's why we've set on the option "Show report".

2. Stripped scm and Opcodes :

A. Stripped SCM :

For your first coding projects you need a main.scm that is small (orgininal one is just hudge), and doesn't have thing that is useless for scripting. You will gain time compiling and not having to wait for the first cutscene. And also because of the scm limits, read above.

So a stripped scm is a main.scm which don't contains any mission, any external script, any main threads. Contains almost nothing, it just creates the player.

You can find one in the folder \data\sa where you installed Sanny Builder under the name stripped.txt, it looks weird because it's written in Sanny Builder classes syntax, I won't tell much you about it, find more in Sanny Builder's Help. Not because it isn't good because I think it'll be easier to first learn with the "opcode method".

You should have something like that :

CODE
Copy to Clipboard
{
  use macro (Ctrl+J) "headsa"
  to insert a file header
}
{$VERSION 3.0.0000}
var
 $PLAYER_CHAR: Player
end // var
03A4: name_thread 'MAIN'
01F0: set_max_wanted_level_to 6
0111: toggle_wasted_busted_check 0
00C0: set_current_time_hours_to 8 minutes_to 0
04E4: unknown_refresh_game_renderer_at 2488.56 -1666.84
03CB: set_rendering_origin_at 2488.56 -1666.84 13.38
0053: $PLAYER_CHAR = create_player #NULL at 2488.56 -1666.84 13.38
01F5: $PLAYER_ACTOR = create_player_actor $PLAYER_CHAR
07AF: $PLAYER_GROUP = player $PLAYER_CHAR group
0373: set_camera_directly_behind_player
01B6: set_weather 0
0001: wait 0 ms
087B: set_player $PLAYER_CHAR clothes_texture "PLAYER_FACE" model "HEAD" body_part 1
087B: set_player $PLAYER_CHAR clothes_texture "JEANSDENIM" model "JEANS" body_part 2
087B: set_player $PLAYER_CHAR clothes_texture "SNEAKERBINCBLK" model "SNEAKER" body_part 3
087B: set_player $PLAYER_CHAR clothes_texture "VEST" model "VEST" body_part 0
070D: rebuild_player $PLAYER_CHAR
01B4: toggle_player $PLAYER_CHAR can_move 1
016A: fade 1 time 0
04BB: select_interior 0
0629: change_integer_stat 181 to 4
016C: restart_if_wasted_at 2027.77 -1420.52 15.99 angle 137.0 town_number 0
016D: restart_if_busted_at 1550.68 -1675.49 14.51 angle 90.0 town_number 0
0180: set_on_mission_flag_to $ONMISSION // Note: your missions have to use the variable defined here
0004: $DEFAULT_WAIT_TIME = 250
03E6: remove_text_box

// put your create_thread commands here

:MAIN_LOOP
0001: wait $DEFAULT_WAIT_TIME ms
00BF: $TIME_HOURS = current_time_hours, $TIME_MINS = current_time_minutes
0002: jump @MAIN_LOOP

// put your mods (threads) here

//-------------Mission 0---------------
// put your missions here

//-------------External script 0---------------
// put your external scripts here

You probably noticed that there isn't a Define section (DEFINE OBJECTS, DEFINE MISSIONS...) there is nothing to worry here because there isn't anything that needs to be defined here. As said in the file if you need an header (define section) press CTRL+J and select headsa. Like on the pic :

Then you'll get what you're missing :
CODE
Copy to Clipboard
DEFINE MISSIONS 0
//DEFINE MISSION {ID} 0 AT {LABEL} @
DEFINE EXTERNAL_SCRIPTS 0 // Use -1 in order not to compile AAA script
//DEFINE SCRIPT {NAME}  AT {LABEL} @
DEFINE UNKNOWN_EMPTY_SEGMENT 0
DEFINE UNKNOWN_THREADS_MEMORY 0

Now you can define your missions and external scripts.

To put mods in this stripped scm you need to put your create threads command (like 004F: create_thread @MYTHREAD) where it says : // put your create_thread commands here. And put your scripts after the MAIN_LOOP where it says // put your mods (threads) here.

B. Opcodes :

In begining of most lines there is a 4 digit number followed by two dots like 0001:, 087B:, 016A: or 004E: like this 0605: in Sanny Builder . Those are called opcodes !!!!!!! And that's why we've set on the "Write opcodes" option.

The opcode is the number of the command (action or operation) that the game engine will do with the parameters given, all opcodes (expect for a few) has a fixed number of parameters.

Parameters (also called Params, or just P1, P2, or %p ) are the input (numbers, actors, vehicles, text strings or any type of variables) of the command. Sanny builder on bottom left tells you how much parameters an opcode needs :

Here is two example :

simple
CODE
Copy to Clipboard
000A: 3@ += 1 // integer values

  • 000A : the opcode which does the operation add to integers
  • 3@ and 1 : are the parameters, this opcode has 2 parameters.
So this get the local variable (more later) 3@ and adds one to it, like if 3@ was equal to 1 now it will be equal to 2 !!!

more complex CODE
Copy to Clipboard
0605: actor $PLAYER_ACTOR perform_animation_sequence "ATM" from_file "PED" 4.0 loop 0 0 0 0 6000 ms
  • 0605: the opcode of the command
  • $PLAYER_ACTOR, "ATM", "PED", 4.0 , 0 , 0 , 0 , 0 , 6000 : are the parameters, this opcode has 9 parameters.
This command make an existing actor (character) $PLAYER_ACTOR perform the animation "ATM" in the animation file "PED" , 4.0 is the playback rate of the animation, loop 0 mean it won't do the anim again once finish if the integer is set to 1 the actor will do the again again and again (loop) until it's told to do something else (or destroy, or "free" -changing it to any others ped you see in the game, opcode 01C2), then there is other parameters that we will talk later about them. The last one is the time for how long the animation will be executed by the engine, act like a wait and will make the engine stop executing the code until that time.

Now to find the opcode you need you have many places :
  • Brilliant new "Opcode search tool" in Sanny Builder. In Tools menu, IDE tools, opcode search. Here just write what you're looking for and you'll get a chance to find it. There is a special section in Sanny Builder Help here at It tells you the keys to copy opcodes to clipboard (selected opcode = Enter), to sort opcodes, etc... It uses the opcodes.txt that is created by Sanny and that you have to recrate manually if you change sacm.ini.

  • Original main.scm uncompiled (the more trustable one most times -pretty good explanation and if used here it DOES work-) Thanks to R* for making the game !!!!! Thanks to Barton Waterduck, Sanny Builder authors, and many others who help decompiling the scm, they should recognize themselves (if they have time reading this).

  • GTA:SA Opcodes @ GTAforums the place for opcodes and is very good because it contains good description, explainations, and what the value of a parameter do.
    Thanks to everyone who posted in the topic and to opius for starting it.

  • http://sa-db.webtools4you.net/ THE interactive database, the best way to use it is to search "nothing" (just clic go) you'll have all opcodes, and then search with your internet browser "find in the page".
But the best way is to refer to all of them !!!

The opcode descriptions come from a file called sascm.ini which is located in data\sa of Sanny builder installation folder. Updating this file will make new descriptions or/and change the opcode parameters.
  • Original Sanny Builder sascm.ini is very good I advise you to keep it for the begining.

  • Unified opcode databse from PLPynton here, or the file here.. If you don't want to use the file you can still find some opcodes in the topic.

    This opcode "database" has two big advantage, because it's very complete and keeps original parameters order, and a disadvantage is that it use a completly different syntax for description.
    Thanks to PLPynton for creating it.

  • Spaceeinstein's sascm.ini here. Use the syntax which has always been used. Thanks to him.
To use the files sascm.ini that are given there you have to compile all the files you are working on close Sanny builder (if open) put the file in folder \data\sa in Sanny Builder installation folder (make backup), open Sanny and uncompile the files. Evrytime you change sascm.ini you have to do that.

!!!!!!!!!!!! Important !!!!!!!!!!!!

About sascm.ini, don't mess too much with them, choose one and stick to it for a while. Everytime you change it you have to convert all your files, or compile and uncompile, but you have to watch out for opcode parameters, they get sometimes mess up in changing sascm.ini and you'll get crashes and bugs (and they'll be very hard to find).

You will also have to recreate your opcodes.txt files otherwise completion with F1 or in the Opcode search. To do this go Tools and "Make opcodes.txt". My advise is to choose one of those, or keep the one that is given in Sanny Builder, and don't change it until you have a good reason to do so.
The tutorial is made with the sascm.ini given in Sanny Builder.

3. Parameters and variables :

There is different types of parameters :
  • integer (or int), also called whole numbers like 1 or -2 or 321 or any other.

  • Floats or floating point values, any decimal number like 1.2 or -2372.3845. More on floating point numbers

  • An actor like CJ (YOU) which is store in the global variable $PLAYER_ACTOR , or Ryder ingame character in $SA_RYDER , or the soldier who watch the gate of the army base in Ryder's mission is store in the local variable @102 . The variable gets called an handle when holding (keeping in memory) an actor (or a car), it will be the name of the object next, the handle form where you grab it.

  • A "car" (in coding every vehicle -flying, floating, choppering- is a car), like often the car you're driving $PLAYER_CAR , well like the actors they're stored in local or global variables. Same as actors when stocking a car in a variable it's then called an handle.

  • Model identifier like #CHEETAH, #ARMY, #PARACHUTE, the 3D model of a car, an actor, an object. It refers to the dff files that are store in gta3.img. And this model is needed to be loaded (put in memory) to create cars, actors or objects.

  • Short text strings (8 bytes long) like 'STRAP_4' or 'MTIME3' which are lettred words that the engine "reads" when passing through and look for the file -or the line a the file- named. They're always 7 character maximum. It refers to file names such as gxt, animation files, IPL files (interiors garage etc...) or threads names, text entries (from gxt file), animations (the animation in the animation file), and many other things. Don't worry much it's just a format for the parameter.

  • Long text strings (16 bytes or more long,) like "ATM" or "JEANSDENIM" . It's exactly the same as above it's just a format for the parameter, but this one can handle longer words (Sanny's ReadMe says up to 255 characters) and is used even if the word is shorter than 7 characters. You can find more explanations on strings (both short and long in this message from Seemann)

  • Labels like MAIN_4059which are used only in jumps (and gosubs) because those opcodes (0002: jump @; 004D: jump_if_false @; 0050: gosub @ ; or 004F: create_thread @ ) make the engine travels to (jump at) the label told. The label is represented with : before it.

    example :
    CODE
    Copy to Clipboard
    :label
0001: wait 0 ms
0002: jump @label

Variables are a little piece of memory where you store something in it. Once you've defined it the engine will remeber it until it's changed or cleared, even after saving the variable will still present (saving saves all the variable and reloads it when the game is loaded). Like when you create an actor you assign it a variable, which would be like it's name. In those you can put anything integer, floats, actors, vehicles, text strings (special format).

Then there is two big family of variables :
  • Global variables : which are represented by starting with $ . Globals can be use everywhere in the main.scm. If you set it to something in the main part in mission it will still be accessible and equal to something. Exemples : $ONMISSION , $PLAYER_ACTOR.

  • Local variables : Locals are represented by an @ at the end like 1@ , 2@ . Each thread ( created by 004F) has his own set of locals, like 0@ in :thread_A isn't the same as 0@ in :thread_B. In main part you cannot use over 33@ (which is a local timer see downer for more details). But in mission you can use up to 1024@ .
Locals timers : 32@ and 33@ , are internal locals timers, they count the number of milliseconds that have elapsed. Like if you set it to 0 , wait 10 seconds and look how much 32@ or 33@ worth you'll find 10 000. if you set it to 1 000 and wait 5 second before looking it will then be equal to 6 000 ms.

Short and long text strings : text strings are stored in special format of variables. Text string a highlighted in red in Sanny. There is 4 kind of text variables 2 for short (8 bytes, 'STRING' ) strings, 2 for long strings (16 bytes, "LONGSTRING" ) :

For short strings :

- a global text string like : s$1169 or s$ACTOR_SPEECH_GXT_REFERENCE which can always be accessible like other globals.

- a local text string like : 170@s or 5@s which are accessible only in their own thread.

For long strings :

- a global text string : v$1225 or v$MYLONGSTRING , same as short string but for long ones...

- a local long string : 28@v , same as short ones...

BUT watch out, for exemple0@s replace 0@ if existing and vice versa, it is the same variable but they're just in a different format.

And I want to remind (or tell) you that a integer and a float are different to game engine ( 1 isn't the same as 1.0 !!!!!). If the opcode needs a float and you give it a int (and vice versa) the game WILL crash.
You can convert an integer to a float with opcode 008D. And convert a float to an integer with 008C.

4. Threads and labels :

A thread is a "stand alone" (something that needs nothing but itself) piece of code. It's like a program by itself (like an opened window on your operating system -like Microsoft Windows-). So to use (play ingame with) your future mods (programs, windows) you'll need to create a new one. What you do with 004F like :
CODE
Copy to Clipboard
004F: create_thread @MYTHREAD

Threads are like fire in a world with matches (ligther, silex, well you cannot "make" fire you need to ingnite it from another fire -like the Olympic Flame never switched off between 2 olympic games). You must create a new one from an existing one. As I said before the main thread is created by the engine itself. The 'MAIN' thread will lite your fire. So if it's the only existing thread (like in a stripped main.scm) you'll need to create your thread in the main thread BEFORE it gets switched off by (before this line) :
CODE
Copy to Clipboard
004E: end_thread

If using a bigger file (like orignal main.scm) just create it where there is many others create_thread (004F) like this :

Don't worry about "00D7: create_thread_with_wasted_busted_check " because their real use is actually unknown yet. Use 004F, there is better ways to check if player is wasted or busted (like conditional opcode 0112). As Seeman tells us later in the topic 004f creates a thread with 0 to 32 extra-parameters, and 00d7 creates a thread with 0 extra-parameters. So don't worry at all about 00d7 because 004f does the same and as more functionalities. (Seemann's message)

Like I said before in each single thread you've create you have for each thread it's very own set of locals from 0@ to 33@ (32@ and 33@ being local timers). They're pretty usefull because not sucking up memory.

A label is a little piece of thread like :MAIN_4059. Think now the thread as a book (no more fire [image] ) and labels would be pages of this book. Then you can easily understand that a jump (or jump_if_false, or gosub) to a certain label would be like a report to a certain page.

I made an animated example for you to see how the game engine travels through the labels :

The red line represent the code (the engine is called sometimes simply the code, like the code reader) going through labels.

As you can see the thread label is created from another thread. You can see the code "seperating" in two one going to just created thread label one keeps doing the thread it use to do, and it gets ended (but could be continuing to do things if you don't end it).
It goes through :label to :label_100. In :label_100 you can see there is an "if" with a condition in it, followed by a jump_if_false, this means that if $PLAYER_ACTOR is near position in 3 dimension 2498.0 -1711.0 1015.0 the code can pass through and jump to :label_200.
So the code keeps looping in :label_100 until the condition is satisfied.
Then jumps to :label_200 without passing through :label_150, going straight to :label_200. Does what it needs to do in :label_200 (which is to put the 3D coordinates of actor $PLAYER_ACTOR into variables $X_COORD $Y_COORD $Z_COORD). Then jumps to :label_150, waits 1minute and jump back :label_100 and check again if player's near the point. And will do all over again and again and again. You don't have to end a thread if you don't need to, it can just keep check something to start. Don't forget you got to do something with your thread, keep it running or end it but don't let it free.

!!!!!!! Notice the wait (0001: wait 0 ms), because it's compulsory !!!!!!!!!!!!!
When looping you have to add a wait so the engine doesn't get itself stucked in it, and it won't even crash then it will just simply freeze. The only way to recover from it is to force resolution change (sometimes just impossible to do, and some laptops have a combo key) and end GTA:SA with task manager.

If you don't really know if you should add a wait or not just add "wait 0 ms", because most times you will not see the difference at all, and mostly anything under 500 ms you don't notice it.

5. "If"s and conditional opcodes :

What's called an "if" is a code strucutre that checks if something is happening. Like :
if
I die
if not then --> I will finish my mods
--> you give all my unfinished mods to the GTA community

In Sanny Builder it would look like

The engine will travel straight through if the something checked happens but jump to another label if it doesn't happend (004D: jump_if_false @ ). The something (which could or not happend) of the if is called a condition, for them you use conditionals opcode !!!!!!! And you can put up to seven conditions in one if !!!!!!! (I know you're like "Yes I'm so happy, that's really change my life !!!!!!...." but... )

Then there is two kind of multiple conditions ifs :

When you have multiple conditions you might want to have all conditions true (happens) or at least one of them true.
  • if and is when you want all the conditons to be true for passing through like :

    So here you can see that if all those external scripts are loaded it goes through but then if any of them isn't it will jump to label :INTMAN_1088. You can think it as if this and this and this is OK then go throught if not jump because it's false.

  • if or is when you only need one of those conditions to be go through like :

    Here it's if any of these door is open keep going but if not jump to :MAIN_4336. You can think it as if this or this or this or happens go througt but if there isn't any that is true jump because it's false.
And and or are called logic operators.

Notice how it wouldn't make sens to add an or or an and in a single condition if. Only one condition, you just cannot use them, only one element !!!!! And sanny builder won't like it neither it will tell you "hey don't do that".

On the other hand don't forget to put an or or an and to your multiples conditions ifs, becasue sanny won't say anything, the game might not crash, but I'm sure it won't work properly, either and or or, but you need to put something in multiple conditions ifs.

You can negate all conditional opcodes. Negate is like adding a not in the conditons. If actor not dead, or if actor not driving. Then it means that to pass through it, the condition needs to return false (don't happend). You can negate conditional opcodes in mutlpiple conditions ifs too. To negate a conditional opcode you have to put a 8 at the first digit instead of 0, like :

not negated

negated

You don't have to write not the compiler (sanny) will not look at it, and it will write it when re-uncompiling. But you still can write not if you want, it makes it clearer and easier to work with. But you really HAVE TO write the 8 in the opcode.

When you negate all conditions a 'multiple conditions if', you have to change around the logic operator.

Those two do the same :
  • the first one checks if player is agressive or aiming at actor 14@ or aiming at actor 15@ or aiming at actor 16@ or aiming at actor 17@ , if any of those is true the code passes through and jump to labelz.
  • the second one check if player is not agressive and not aiming at actor 14@ and not aiming at actor 15@ and not aiming at actor 16@ and not aiming at actor 17@ , if any of those is false (if player do aims) the code will jump because it's false to labelz.
Sometimes when look for some nice mods you might find :

CODE
Copy to Clipboard
00D6: if 0

or
CODE
Copy to Clipboard
00D6: if 5

or
CODE
Copy to Clipboard
00D6: if 21

or
CODE
Copy to Clipboard
00D6: if 25

Don't worry it's the same, compile, then decompile it and you'll have the logic operator written. And that's why we've enable "Conditions check", so we can use and & or and Sanny writes them when decompiling.

if 0 = if

if x = if and

if 2x = if or

Read Conditions in Sanny Builder's Help or/and here (It's for Vice City but is the same, just ignore "?") for more explanations.

You might want to do high-level conditions construction, read Conditions in Sanny Builder's Help, it explains it pretty well. Low level contructions can be good for now, and you can make high level with low level anyway.

BUT remember well when doing "if"s, add waits where you know the code is going to loop back. And a wait 0 is never a problem because it actually wait for 0 milisecond which is pretty short !!!!!!! but it will let time to the engine doing other things. Relook at the animated exemple for labels to understand where you'll absolutly need wait.

6. Request models, load them, create, then release them to free memory :

When creating actor (with opcode 009A), car (with op 00A5), object (with op 0107), give weapon to an actor you have to request the dff model before and load it, and check that is it loaded for real !!!!!!

Like :
CODE
Copy to Clipboard
:GSHAUTO_564
0001: wait 0 ms
0247: request_model #HFYBE
0247: request_model #POLICE_BARRIER
0247: request_model #BMYBOUN
0247: request_model #WMYBOUN
0247: request_model #DESERT_EAGLE
0247: request_model #MP5LNG 0247: request_model #CHEETAH
0247: request_model #TURISMO
038B: load_requested_models
00D6: if and
 0248: model #HFYBE available
 0248: model #BMYBOUN available
 0248: model #WMYBOUN available
 0248: model #DESERT_EAGLE available
 0248: model #MP5LNG available
004D: jump_if_false @GSHAUTO_564
00D6: if and
 0248: model #POLICE_BARRIER available
 0248: model #CHEETAH available
 0248: model #TURISMO available
004D: jump_if_false @GSHAUTO_564
009A: 11@ = create_actor 4 #WMYBOUN at 561.0 -1252.0 17.0
009A: 14@ = create_actor 4 #BMYBOUN at 552.0 -1257.0 17.0
009A: 15@ = create_actor 5 #HFYBE at 567.0 -1290.0 17.5
009A: 16@ = create_actor 4 #WMYBOUN at 561.0 -1255.0 17.0
009A: 17@ = create_actor 4 #BMYBOUN at 553.5 -1260.0 17.0
009A: 18@ = create_actor 4 #WMYBOUN at 569.0 -1292.0 17.5
009A: 19@ = create_actor 4 #BMYBOUN at 569.0 -1288.0 17.5
0107: 9@ = create_object #POLICE_BARRIER at 560.0 -1254.0 17.0
00A5: 0@ = create_car #TURISMO at 1793.4956 -1907.4233 12.3992
00A5: 1@ = create_car #CHEETAH at 1793.4956 -1907.4233 12.3992
01B2: give_actor 11@ weapon 29 ammo 900 // Load the weapon model before using this
01B2: give_actor 14@ weapon 29 ammo 900 // Load the weapon model before using this
01B2: give_actor 15@ weapon 24 ammo 300 // Load the weapon model before using this
01B2: give_actor 16@  weapon 29 ammo 900 // Load the weapon model before using this
01B2: give_actor 17@ weapon 29 ammo 900 // Load the weapon model before using this
01B2: give_actor 18@  weapon 29 ammo 900 // Load the weapon model before using this
01B2: give_actor 19@ weapon 29 ammo 900 // Load the weapon model before using this

Look how I first request the models (with 0247: request_model) then load them (with 038B: load_requested_models). Then checks if all models requested are available to use (with 0248). If any of them is load jumps back to top and re-request and reload them. If they all are then create the actor, the weapons and the object. You can see in the comment (after //) that 01B2 need the weapon model to be load before using it (for weapons numbers look in help here or at very good Generic SA SCM Documentaion.

Once you've finished doing what you need to with thoses (they're all dead, player is too far away, don't want them here, etc...) transform them into usuals peds and cars (like all the peds and cars you see in-game) or destroy them (the object must be destroyed) :

CODE
Copy to Clipboard
0108: destroy_object 9@
01C3: remove_references_to_car 1@ // Like turning a car into any random car
01C3: remove_references_to_car 0@ // Like turning a car into any random car
01C2: remove_references_to_actor 11@ // Like turning an actor into a random pedestrian
01C2: remove_references_to_actor 14@ // Like turning an actor into a random pedestrian
01C2: remove_references_to_actor 15@ // Like turning an actor into a random pedestrian
01C2: remove_references_to_actor 16@ // Like turning an actor into a random pedestrian
01C2: remove_references_to_actor 17@ // Like turning an actor into a random pedestrian
01C2: remove_references_to_actor 18@ // Like turning an actor into a random pedestrian
01C2: remove_references_to_actor 19@ // Like turning an actor into a random pedestrian

or CODE
Copy to Clipboard
0108: destroy_object 9@
00A6: destroy_car 0@
00A6: destroy_car 1@
009B: destroy_actor_instantly 11@
009B: destroy_actor_instantly 14@
009B: destroy_actor_instantly 15@
009B: destroy_actor_instantly 16@
009B: destroy_actor_instantly 17@
009B: destroy_actor_instantly 18@
009B: destroy_actor_instantly 19@

Don't apply those (01C2, 01C3, 0108, 00A6, 009B, etc...) to an actor, or a car that doesn't exist (or when the handle that should hold it -like 0@, $car, etc...- doesn't hold it), because the game will badly crash!!!!!!

Once you got rid of actors/cars/objects (So when you finished using them, and after you have delete them, and only after that), you can release the models you've used because you will no longer need them.

CODE
Copy to Clipboard
0249: release_model #WMYBOUN
0249: release_model #BMYBOUN
0249: release_model #HFYBE
0249: release_model #POLICE_BARRIER
0249: release_model #DESERT_EAGLE
0249: release_model #MP5LNG
0249: release_model #CHEETAH
0249: release_model #TURISMO

You actualy could have release those models earlier, you don't need them to be loaded after you have created the game object (object, actor or vehicle). But I advise you for a start to release the model only at the end of your script/mission when you sure won't need it anymore. It will prevent you from a few return to desktop.

Conclusion

Well, this part was mostly informations, there isn't much to do. But now you know that an opcode is a 4 digit number that do things in the game depending on the parameters you gave it. You know the different types of parameters, what's a local variable and what's a global one. Creating, naming and ending threads, and many other things that you need to know to keep going. Now we speak the same "language" we can get to real coding.
Let's get to part II...

Have fun


Mission Coding with Sanny Builder Tutorial Part II
Grand Theft Auto

San Andreas

Mission Coding with Sanny Builder Tutorial
Part II
Coding Basics

Introduction

Hi, in Part II we will get some basics of coding, create spheres, actors, cars, markers, texts, panels etc....

If you need to look at Part I it's here.

As in Part I, I recommend you to print the topic using Printable Version of Topic, by clicking print this topic on top right of the first message.

A lot of examples here use globals (variables that start with a $ like : $markerxx , $car00 , $actor00 , $myweaps00 ) but it doesn't mean you cannot use locals (varaiables that end with a @ like : 0@ , 1@ , 28@ , 1004@ ). I use gobals so I can name them for easier understading. But when you'll be coding you should use locals, for many reasons they are better. You only need to use gloabls when you need the varaible in two (or more) different threads (it's pretty rare, and it isn't usually much more than a few varaible).

Often I will give a four digit hexadecimal number (like 0103, 02a8, 00ec, 032b, etc...) they're opcodes, to have a description write the four digit number on a new line in Sanny Builder and press F1.

Most examples are given in a CODE tag like this :
CODE
Copy to Clipboard
CODE tag

So you can copy and past it in Sanny, I recommand you to do so often, it will help you understanding. And you won't have to write the opcode number and press F1 everytime.

1. Using Sanny :

This part is most repeat parts of Sanny's Help but sometimes explained differently. But you can still report to the Hotkeys page for more details.

Hotkeys :

- F1 : the magic hotkey !!!!! write an opcode like 004F and press F1 and ho magic appears :

CODE
Copy to Clipboard
004F: create_thread @ODDVE

or write thread and press it and press it again, Sanny will suggest you all those different lines :

CODE
Copy to Clipboard
004E: end_thread

004F: create_thread @ODDVEH

00D7: create_thread_with_wasted_busted_check @NONAME_2

03A4: name_thread 'MAIN'

0459: end_thread_named 'INT'

004F: create_thread @ODDVEH

F1 will be the key you'll use a lot, just think about what you want (car, actor, checkpoint, markers, weapon, money, paintjob, etc...) write it and press F1. It won't do what you want everytime but it will get you going.
F1 is kind of google for Sanny !!!!!!!

But notice that it only works for one and only one word.

Remember (or learn if you didn't know) that F1 gets it's suggestions from opcodes.txt so make sure you did what it's in part II introduction.

- Ctrl + Shift + <0..9> : make bookmark, at the line you are like :

They should be save when you save the file.

- Ctrl + <0..9> : go to bookmark number <0..9>, put you at the line of the bookmark (if it exist)

- Ctrl + Num2/Num8 : when you place your cusor (the blinky |) on a jump (or gosub or jf -jump_if_false-)and press it the editor will bring you the the label. Look animation to see that I've place on @PSAVE1_1498 and it bring me to the label it self :PSAVE1_1498 .

- F3 : find next

- Ctrl + F3 : find previous

- Ctrl + Alt holded : Rectangular selection :

- Ctrl + Alt + 1 : Coords Manager (game must be running)

- Ctrl + Alt + C : Insert player coordinates where you cursor is

- Ctrl + Alt + E : Insert z angle value where you cursor is

- Ctrl + T : delete word, remember things like end_thread will be considered as one word.

- Ctrl + Y : delete line

- Ctrl + Shift + Y : clear line, leave the line but delete what's written in it.

- Ctrl + Scroll Up/Down : page up / down

- Ctrl + Shift + U/L : make word UPPERCASE / lowercase.

- Ctrl + Q : comment out the line your cursor is (adds // at begining of the line), so the line will be ignored when compiling.

- Ctrl + G : go to line

- Ctrl + R : replace

- Ctrl + C : copy

- Ctrl + V : paste

- F7 : compile and copy to GTA SA folder main.scm and script.img

Editor completion :

Sanny can complete some thing for you like global variables, labels, model IDs, to use it just write first character ($, @, or #) and get what you need. Look the animation I think it explains well :

Those are the most used exemples, but you might find many use for this tool.

Notice that with models, the nudel number is shown, so it's a pretty easy way to find what number a model is.

Coords Manager :

Very usefull tool here which get the 3D position of the player. Of course the game muste be running....

The 3 dimension position is the value of each axis (x, y, z). The San Andreas map goes from -3000.0 to 3000.0 on x and y axis. The altitude (z) max of planes is about 800.0 units. Axis x is oriented west east, the x value increases when going east. Axis y is oriented south north, the y value increases when going north. Center of the map is located at 0.0 0.0 0.0 .
Well it looks like that :

This screenshot is from old Sanny Builder new coord manager is slightly different.

Copy will copy into clipboard the 3d pos like 747.756 -1809.0986 13.0234

Read will refresh the position of the player ingame.

Set will put player at the position you've written in the three dimensions.

In new Sanny Builder you get the Z angle value. This is the value of the angle around z axis which means what direction the player (CJ) is looking at. 0.0 is north, 180.0 is south, 90.0 is east, 270.0 is west.

2. Adding mission mods :

This isn't really coding but it is usefull for everyone to look/test/use/imitate parts of other's mods.

First thing to know when adding mods : FOLLOW INSTRUCTIONS !!!!!!!!!!!!!!!!!!!! Every mods is different so when adding a mod first follow the author instructions to add it, they're the best instructions. But sometimes there isn't much instruction.

Then, most of mods are main part (look part I, 1.Main.scm architecture) mods. So they're activated (create_thread) and executed in the main part. You probably want to add mods to original main.scm (or modded main.scm), then you'll will use 004F (create_thread) here :

CODE
Copy to Clipboard
004F: create_thread @ODDVEH
004F: create_thread @R3
004F: create_thread @GYM
004F: create_thread @SHOOT
004F: create_thread @BLOODR
004F: create_thread @HOTR
004F: create_thread @KICKS
004F: create_thread @PSAVE1
004F: create_thread @FLOW
004F: create_thread @HELP
004F: create_thread @COLLS
004F: create_thread @CRANES
004F: create_thread @BUY_PRO
004F: create_thread @VALET_L
004F: create_thread @ADPLANE
Between any of those lines you'll add :

CODE
Copy to Clipboard
004F: create_thread @modlabel
where it will be of course the mod's first label name instead of modlabel.

Then you've got the mod itself, you have to add it anywhere in main part. BUT it isn't really anywhere, it's more like anywhere after it's been created/activated, and not inside another thread. to simplify just put it at the very end of main part, so before :

CODE
Copy to Clipboard
//-------------Mission 0---------------
// Originally: Initial 1

Then compile and copy to San Andreas data\script (F7), launch the game, start a new game and.....

have fun

Hang on, if it really did work, you're like really very very lucky (and you did a good job apparently) !!!! Most of time first try simply doesn't work. So watch what you've done, look how the author of the mod did it, watch global variables (if only numbers you should change it to a custom name), the try again, and if you really can't get it working, ask the author how he did (do that after several tries and checks, don't disturb the author for a mistake you've done).

3. Weapon pickups and parked cars :

For me this part isn't real coding neither but it's usefull and asked very very very often, and it's a good opportunity to explain how it works.

Pickups and parked car are spaecial opcode because it telle the engine to create such car or such weapon if player is close enough to the point.

Well I'll take exemple to the cars/vehicles that you always find in one place (the skimmer near the dam, the AT400 at Vegas airport, the cropduster in the desert, these are the only one I can think of right now) everytime (actually not everytime) you come back it's here. Same for weapons (the heatseek rockets at the abandonned village, the gun behind Sweet's house...), life (red heart in gang wars), and armor.

Parked cars :

CODE
Copy to Clipboard
014B: $mycarx00 = init_parked_car_generator #CHEETAH 15 15 1 alarm 0 door_lock 0 0 0 at -1253.1 -348.0 13.9 angle 0.0
014C: set_parked_car_generator $mycarx00 cars_to_generate_to 101

- This will create a cheetah (#CHEETAH )

- at the 3d coordinate -1253.1 -348.0 13.9

- the car will be headed the z_angle 219.0 (z_angle is the angle around the axis z, 0.0 and 360.0 is north, 180.0 is south, 90.0 is east, 270.0 is west), so this car is
directed to south-west

- with color one number 15 (you can notice sometimes -1 which mean any)

- with color two number 15 (you can notice sometimes -1 which mean any)

- Car belongs to the player (the cops don't think you've stole it) becasue next parameters is set to 1 . If would set on 0 cops will give you a wanted level when you enter it

- Without alarm, because it's 0 . It's actaully percentage of chances of getting alarm. So if you want the alarm to go off everytime set it to 100 , if you want it once out of two time then 50 etc....

- Doors won't be lock. As you can read door_lock is set to 0 . If 1 doors will be lock. The two others parameters are unknown.

- This car generation (not the car itself) is set as handle $mycarx00

And you should be wondering how do I know all that (beside simply reading and thinking) ???????
Well go check http://sa-db.webtools4you.net/, clic go without writting anything, and with your internet browser (if you don't know what it is then it's Internet Explorer) go Edition\Find in the page, and search for 014B.

You'll then get 014B description. Wait till your internet browser brings you to 014 description (4 or 5 seconds), and it will be at top of th page highlighted in yellow.

The line after 014C just activates or unactivate the parked car generator for this car generation handle : 101 makes it spawn and 0 doesn't. It is needed don't forget one for each car generation, but they don't have to be together you can separate them.

There is other types of parked cars they're very close to this one and they ain't much usefull.

Weapon pickups :

There is two types of weapons pickups, one for weapons which doesn't need ammunitions (like dildos, katana, golf club, shovel, parachute....), and is actualy just a normal pickup.

Those both pickup opcodes like with parked cars opcode don't need to request and load the model before using.
  1. Melee (and gift) weapons

    CODE
    Copy to Clipboard
    0213: $myweaps00 = create_pickup #CHNSAW       type 15 at -2083.0 298.0 42.0
0213: $myweaps01 = create_pickup #BAT          type 15 at -2306.0  93.0 35.0
0213: $myweaps02 = create_pickup #SHOVEL       type 15 at -2796.4 123.6  6.8
0213: $myweaps03 = create_pickup #POOLCUE      type 15 at -2135.0 197.0 35.0
0213: $myweaps04 = create_pickup #KATANA       type 15 at -2208.0 696.0 50.0
0213: $myweaps05 = create_pickup #BRASSKNUCKLE type 15 at -2206.0 961.0 80.0

    You can use this opcode for other pickups like the keycard (what you get with the croupier girl- model : #KEYCARD ), armour (model : #BODYARMOUR ), life (model : #HEALTH ), bribe (model : #BRIBE ), save disks (only the pickup not the saving routine ! - model : #PICKUPSAVE ), briefcase (model : #BRIEFCASE ) etc...

    All the melee weapons (including parachute -#PARA_PACK - but not the goggles), and health, armour, bribes, are hardcoded that mean you don't have to check if the player picks up the so-called pickup, just go to the pickup and it automaticly gives the weapon/bribe/armour/health etc....

    For keycard, save disk, briefcase, but as well as all define objects models (if there ain't too big of course) because they can be use as a pickup, you have to check if the pickup has been pickup or not. You don't have to destroy it once it's been picked, because as soon as the player is on it it will automaticly disappear.
    For this you must use something like this :

    CODE
    Copy to Clipboard
    00D6: if
0214: pickup $pickupvar picked_up
004D: jump_if_false @

  2. Firearms (and all others)
    But for weapons which have ammunition, with an exeption for the night and infrared goggles, (models : #NVGOGGLES , and #IRGOGGLES ) you'll need to use the pickups which give ammunition with the weapon (doesn't it sound obvious ?) :

    CODE
    Copy to Clipboard
    032B: $myweaps06 = create_weapon_pickup #NVGOGGLES 15 ammo 1   at   299.5   -31.7 1001.0
032B: $myweaps07 = create_weapon_pickup #IRGOGGLES 15 ammo 1   at   299.6   -41.3 1001.0
032B: $myweaps08 = create_weapon_pickup #M4        15 ammo 60  at  2021.8  1001.4   10.3
032B: $myweaps09 = create_weapon_pickup #MP5LNG    15 ammo 120 at  2025.2  1001.4   10.3
032B: $myweaps10 = create_weapon_pickup #SHOTGSPA  15 ammo 120 at  2021.0  1013.3   10.3
032B: $myweaps11 = create_weapon_pickup #SATCHEL   15 ammo 20  at  2023.7  1013.5   10.5
032B: $myweaps12 = create_weapon_pickup #SNIPER    15 ammo 60  at -2035.7   139.4   28.3
032B: $myweaps13 = create_weapon_pickup #MICRO_UZI 15 ammo 120 at -2038.4   139.6   28.3
032B: $myweaps14 = create_weapon_pickup #CHROMEGUN 15 ammo 120 at -2038.6   137.4   28.3
032B: $myweaps15 = create_weapon_pickup #GRENADE   15 ammo 20  at -2035.4   137.2   28.3
032B: $myweaps16 = create_weapon_pickup #AK47      15 ammo 120 at  2499.3 -1707.4 1014.2
032B: $myweaps17 = create_weapon_pickup #TEC9      15 ammo 120 at  2499.5 -1709.6 1014.2
032B: $myweaps18 = create_weapon_pickup #SAWNOFF   15 ammo 60  at  2493.4 -1708.2 1014.9
032B: $myweaps19 = create_weapon_pickup #MOLOTOV   15 ammo 20  at  2493.5 -1706.8 1015.1
032B: $myweaps22 = create_weapon_pickup #COLT45    15 ammo 100 at  -365.4 -1422.4   25.5
032B: $myweaps23 = create_weapon_pickup #FLAME     15 ammo 200 at  -366.0 -1418.6   25.5

    Well for those ones, the number after ammo is the number of ammunition you'll have when you pick the weapon up.
For all pickups (both 0213 and 032B) :

type 1 disables the pickup (you can't pick it up)
type 3 make the pickup pickable only one time
type 15 make the pickup re-grows up everytime after you picked it up (probably what you want)

the three floats are the coordinates of the pickup like those :-366.0 -1418.6 25.5

$myweapsxx is the handle of the pickup, the variable that contains it.

and #GRENADE is the model.

One last thing is that you can find a weapon list right here.

There is some weapons like the jetpack, or the parachute where you can use either 0213 or 032B with ammo 1 it has the same result.

You can destroy pickups before it's been pickup, with 0215 :

CODE
Copy to Clipboard
0215: destroy_pickup $myweaps01

4. Threads :

There isn't much to say more than what's been told in Part I : 4. Threads and labels.

Just that you create them with 004F like that :
CODE
Copy to Clipboard
004F: create_thread @name_of_your_thread

You name it with 03A4 :
CODE
Copy to Clipboard
03A4: name_thread 'NAME'
No more than 7 letter.

You can end it with 004E from the thread itself :
CODE
Copy to Clipboard
004E: end_thread

Or from anywhere else with 0459 :
CODE
Copy to Clipboard
0459: end_thread_named 'NAME'

Sometime you can find weird 004F like :

Don't worry it's just how you can set local variable for the thread you create. Like on the example $ACTOR_RYDER will be 0@ , 0 (first one) will be 1@ , 0 (second one) will be 2@ , 2 will be 3@ , 1 will be 4@ in the thread :AUDIOL .

Like Sanny tells you you can set up to 32 locals there for the thread you create from 0@ to 31@ . It can be very usefull but if you don't really understend it doesn't really matter, it's just so you know about it.

5. Spheres and markers :

Spheres :
A sphere (also called POI cylinder) is the red round thingy that you walk in when you start a mission.

Even if you don't actually see the red circle, the game (and you while modding) uses many sphere all the time. Just to check if actor x is near a given coordinate within a certain radius.

To create thoses special spheres that checks if actor is near it you need a special type of opcodes that have a command and are conditional !!!! There rare but so usefull since GTA III. They are conditional because they check if the actor is near it and in the meanwhile they display the red sphere ingame.
  1. 2d opcodes
    from 00ec to 00f4.

    CODE
    Copy to Clipboard
    00EC: actor $PLAYER_ACTOR 0 near_point 1812.369 -1929.9215 radius 80.0 80.0
00ED: actor $PLAYER_ACTOR 0 near_point_on_foot 2043.6801 -1635.73 radius 4.0 4.0
00EE: actor $PLAYER_ACTOR 0 near_point_in_car 2067.3999 -1831.2 radius 15.0 15.0
00EF: actor $PLAYER_ACTOR stopped 0 near_point 2196.239 -1191.459 radius 2.0 2.0
00F0: actor $PLAYER_ACTOR stopped 0 near_point_on_foot 2175.29 -2259.22 radius 3.0 3.0
00F1: actor $PLAYER_ACTOR stopped 0 near_point_in_car -175.29 -59.22 radius 3.0 3.0
00F2: actor 67@ near_actor $PLAYER_ACTOR radius 20.0 20.0 0
00F3: actor $PLAYER_ACTOR near_actor_on_foot 15@ radius 2.0 2.0 0
00F4: actor 34@ near_actor_in_car $PLAYER_ACTOR radius 6.0 6.0 0

    Those opcodes shouldn't be used because they can lead to many bugs particulary in interiors.

  2. 3d opcodes
    from 00fe to 0106.

    CODE
    Copy to Clipboard
    00FE: actor $PLAYER_ACTOR 0 near_point_3d 658.0068 -1866.3127 4.4537 radius 15.0 15.0 15.0
00FF: actor $PLAYER_ACTOR 0 near_point_3d_on_foot $X_JOHNSON_HOUSE $Y_JOHNSON_HOUSE $Z_JOHNSON_HOUSE radius 1.0 1.0 2.0
0100: actor $PLAYER_ACTOR near_point_3d_in_car 1793.0676 -1904.2538 12.3989 radius 4.0 4.0 4.0 sphere 1
0101: actor $PLAYER_ACTOR stopped_near_point_3d 10@ 11@ 12@ radius 5.0 5.0 3.0 sphere 0
0103: actor $PLAYER_ACTOR stopped_near_point_3d_in_car -1577.9417 52.6333 16.3281 radius 4.0 4.0 6.0 sphere 0
0104: actor $PLAYER_ACTOR near_actor_3d 1@ radius 15.0 15.0 15.0 sphere 0
0105: actor $PLAYER_ACTOR near_actor_3d_on_foot 102@(42@,9i) radius 5.0 5.0 2.0 sphere 0
0106: actor $PLAYER_ACTOR near_actor_3d_in_car 71@ radius 15.0 15.0 15.0 0
    These opcodes are good use them !!!
For all of them opcodes :

Where ever it is placed the integer 0 or 1 tells the engine to show the red circle (1=show;0=don't show).

The first 2 or 3 (2 for 2D, 3 for 3D) floats like -366.066 -1418.683 25.5 are the position.

The second 2 or 3 (2 for 2D, 3 for 3D) floats like 4.0 4.0 6.0 are the radius of the sphere.

$PLAYER_ACTOR or 71@ , are the actor variables.

To have the sphere working (and then appearing) you need to place it in a loop :

CODE
Copy to Clipboard
:SPHERE_LOOP
0001: wait 0 ms
00D6: if
00EC: actor $PLAYER_ACTOR 0 near_point 1812.369 -1929.9215 radius 80.0 80.0
004D: jump_if_false @SPHERE_LOOP

The thread must be running on the loop for the condition to checked, and for the red circle to appear. The wait is needed don't make it too long otherwise it will be flickering, keep to 0 ms to have it nice.

Markers :
  • Marker icons
    Markers icons are the radar assets you go to to do a mission. Like [image], [image], or [image], etc...

    Thanks to LazioFreak for finding them. You can find a list of the icons and the numbers to use them on this page [SA] radar icons or in Sanny Builder's Help contents in SCM Documentation: GTA SA: radar icons.

    There is four opcodes to create them :

    Three without sphere (like it's said in the opcode description) 04ce and 0570 :
    CODE
    Copy to Clipboard
    04CE: $marker01 = create_icon_marker_without_sphere 12 at 2447.3643 -1974.4963 12.5469
0570: $marker02 = create_asset_radar_marker_with_icon 36 at 1837.3643 -1974.4963 12.5469
02A8: $marker03 = create_marker 23 at 658.0068 -1866.3127 4.4537

    02a8 will ALWAYS be visible on the radar.

    One with a sphere 02a7 :
    CODE
    Copy to Clipboard
    02A7: $marker00 = create_icon_marker_and_sphere 33 at 2514.5601 -1666.84 13.38

    Like 02a8, this one is pretty cool because it will be ALWAYS visible on the radar, where ever you go you'll see it.
    But watch out it's only a sphere (just the red circle) it doesn't check if the player is near it, just the radar marker and the sphere. To check if the player is near it use opcodes told upper in spheres.

    All of them are 5 parameters opcodes :
    • $markerxx is the handle of the marker
    • The integer like 12 , 36 , or 23 are the marker icons number you can find on SCM Documentation: GTA SA: radar icons
    • The three floats are the x y z coordinates
  • Color markers
    The color markers are that :

    And on the radar they are represented by a colored square like that :

    To create them on vehicle/actor/object/pickup :
    CODE
    Copy to Clipboard
    0186: $marker04 = create_marker_above_car $car00
0187: $marker05 = create_marker_above_actor $actor00
0188: $marker06 = create_marker_above_object $object00
03DC: $marker07 = create_marker_above_pickup $myweaps00

    Watch out the vehicle/actor/object/pickup must be existing and store in the hanlde otherwise you'll crash the game.
    With 03dc, the marker over the pickup will always be green what ever you do with it.
    • $markerxx is the handle of the marker
    • $car00 , $actor00 , $object00 , $myweaps00 are the handles of vehicle/actor/object/pickup
    You can change the color of the marker with :
    CODE
    Copy to Clipboard
    0165: set_marker $marker05 color_to 1
    • 0 = red
    • 1 = green
    • 2 = light blue
    • 3 = white
    • 4 = light yelow
    With 0168 you can change the size of the marker (unlike the description says) :
    CODE
    Copy to Clipboard
    0168: show_on_radar $marker04 1
    • < 3 : smaller the default size
    • = 3 : default size
    • > 3 : bigger
    You can set to enemy or friendly color (it only change the color):
    CODE
    Copy to Clipboard
    07E0: set_marker $marker02 type_to 1
    • 0 : enemy red
    • 1 : friendly blue
To hide and show them (both icons and colored markers) :
CODE
Copy to Clipboard
018B: show_on_radar $marker04 1
  • 0 = hide
  • 1 = hide
  • 2 = show
  • 3 = show
  • 4 = hide
  • 5 = hide
To destroy them (both icons an colored markers) :
CODE
Copy to Clipboard
0164: disable_marker $markerxx

Where of course $markerxx is the handle of the marker.

6. Actors, weapons and vehicles :

Now let's create some things to destroy them !!!!!

First when you create actors, vehicles, objects, or give weapons to an actor, you have to load the models and check they are loaded before creating them.

So you need to request the models with 0247 :
CODE
Copy to Clipboard
0247: request_model #CHEETAH
0247: request_model #DESERT_EAGLE

then load requested models with 038b :
CODE
Copy to Clipboard
038B: load_requested_models

After you need a check to confirm that the models are really loaded (available for the engine to use):
CODE
Copy to Clipboard
00D6: if and
0248: model #HEATSEEK available
0248: model #DESERT_EAGLE available
0248: model #MP5LNG available
0248: model #CR_AMMOBOX available
0248: model #CHEETAH available
0248: model #WFYSEX available
004D: jump_if_false @LOOP_RQ_10

The jump if false jumps to :LOOP_RQ_10 where the model will be requested again loaded again.

All in one it look like that :
CODE
Copy to Clipboard
:LOOP_RQ_10
0001: wait 0
0247: request_model #WFYSEX
0247: request_model #CR_AMMOBOX
0247: request_model #CHEETAH
0247: request_model #DESERT_EAGLE
0247: request_model #MP5LNG
0247: request_model #HEATSEEK
038B: load_requested_models
00D6: if and
0248: model #HEATSEEK available
0248: model #DESERT_EAGLE available
0248: model #MP5LNG available
0248: model #CR_AMMOBOX available
0248: model #CHEETAH available
0248: model #WFYSEX available
004D: jump_if_false @LOOP_RQ_10

Notice the wait because it's very important here you do a loop, you make the engine comes back to where it was before. You need this wait, wait 0 ms is far enough, you don't need more, but you DO need it.

Now that the models are available you can create your actors/vehicles/objects, and give weapons to the actors :

CODE
Copy to Clipboard
00A5: $car00 = create_car #CHEETAH at 2368.5601 -1666.84 13.38
009A: $actor00 = create_actor 22 #WFYSEX at 2490.56 -1666.84 14.38
009A: $actor01 = create_actor 22 #WFYSEX at 2495.56 -1666.84 14.38
009A: $actor02 = create_actor 22 #WFYSEX at 2490.56 -1660.84 14.38
009A: $actor03 = create_actor 22 #WFYSEX at 2495.56 -1660.84 14.38
0107: $object00 = create_object #CR_AMMOBOX at 2502.5601 -1566.84 24.38
01B2: give_actor $actor00 weapon 36 ammo 900 // Load the weapon model before using this
01B2: give_actor $actor01 weapon 29 ammo 900 // Load the weapon model before using this
01B2: give_actor $actor02 weapon 24 ammo 300 // Load the weapon model before using this
01B2: give_actor $actor03 weapon 29 ammo 900 // Load the weapon model before using this
  1. For creating a car with 00a5 :
    • $car00 is the car handle
    • #CHEETAH is the model. Use editor completion to have a list of models (watch out there is ALL models, cars, actors, objects).
    • 2490.56 -1666.84 14.38 are the coordinates.
  2. Create actor with 009a :
    • $actor00 is the actor handle
    • #WFYSEX is the model. Use editor completion to have a list of models.
    • The integer 22 is the ped type. The ped type is the temper, the way the actor will act by default (without any order given). You can find a list of ped types in Sanny Builder help contents in SCM Documentation: GTA SA: PedTypes. Here they don't like cops and will defend themself if they're attacked, among other things.
    • 2368.5601 -1666.84 13.38 are the coordinates.
  3. 0107 will create an object :
    • $object00 is the object handle
    • #CR_AMMOBOX is the model. Here you can use any objects defined in the map files (.ide files in GTA San Andreas\data\maps folder) as long as you defined the object in define object section in the scm. See Part I : 1. Main.scm architecture.
    • 2502.5601 -1566.84 24.38 are the coordinates.
  4. Finally 01b2 gives an actor a weapon :
    • $actor00 is the actor handle
    • The first integer 36 , 29 or 24 after weapon is the Weapon number. You can find a list of weapons their numbers and the correponding model in Sanny Builder help contents in SCM Documentation: GTA SA: Weapon numbers.
    • The second integer 300 or 900 after ammo is the number of ammunition given to the actor along with it's weapon. Here it's too much depends of how time the actor will live but I found that 150 is usualy far enough.
    Even if you might think that this opcode don't need the weapon model to be loaded, but it DO NEEDS the model to be loaded. To ensure you can look at the comment (after //) which says : "// Load the weapon model before using this "
Now they're ready to shoot away but they'll have to wait a bit !!!!

You might need to change the direction of the car (z angle), or its colors (there is up to four colors for cars) :
CODE
Copy to Clipboard
0175: set_car $car00 z_angle_to 90.0
0229: set_car $car00 color_to 11 0
0A11: set_car $car00 tertiary_color_to 6 quaternary_color_to 12

It's pretty easy so I'll be fast :
  • for all of them $car00 is the car handle as usual !!!!
  • In 0175 the float 90.0 is the z angle from -360.0 to 360.0 .
  • In 0229 the integers 11 is the primary color and 0 is the secondary color.
  • In 0a11 the integers 6 is the tertiary color and 12 is the quaternary color. Don't worry about the opcode description, by the time the sascm.ini used here (the one given with Sanny) was written the opcode wasn't known yet, but it will still work very well, and now that you know what the opcode does, there is nothing to stop you !!!
For infos, those were only "set" opcodes, but there is opposite opcodes for all thoses "get" opcodes. The "get" opcodes will get the color/angle of the car and stores it in variables :

CODE
Copy to Clipboard
0174: $carangle = car $car00 z_angle
03F3: get_car $car00 color $primcolor $scndcolor
0A12: get_car $car00 tertiary_color_to $tertcolor quaternary_color_to $quatcolor

Well, what can I say, it the same as before but the all way around, instead of saying the engine to put a color on the car or put the car in such direction, it finds what color the car is or what direction the car is and put the resulting integer in the variable.
The variable names should speak form themselves.

As much obvious as it is, you can't change the color of an actor !!!!!! But you can change the direction (s)he's looking at, and know where (s)he's looking :
CODE
Copy to Clipboard
0172: $actorangle = actor $actor00 z_angle
0173: set_actor $actor00 z_angle_to 262.0

Same for objects, here is just the angle, but there is more on objects just next :
CODE
Copy to Clipboard
0176: $objangle = object $object00 z_angle
0177: set_object $object00 z_angle_to 180.0

When you finished using those actor/vehicles/object you have two different ways to get rid of them :
  • First you can simply destroy them (they will just disappear straight away) :
    CODE
    Copy to Clipboard
    00A6: destroy_car $car00
0108: destroy_object $object00
009B: destroy_actor_instantly $actor01
034F: destroy_actor_with_fade $actor00 // The actor fades away like a ghost

    034f as the comment says "// The actor fades away like a ghost ". Is usualy what you see happening in original game when an actor is dead, it slowly disappear.
  • Secondly you can remove references from them, this will turn them into normal peds (just like every pedestrian/vehicle you see ingame). So the actor/vehicle/object will still be there but the handle $car00 /$actor00 /$object00 won't hold the actor/vehicle/object anymore :
    CODE
    Copy to Clipboard
    01C2: remove_references_to_actor $actor00 // Like turning an actor into a random pedestrian
01C3: remove_references_to_car $car00 // Like turning a car into any random car
01C4: remove_references_to_object $object00 //This object will now disappear when the player looks away

    The comments (after //) explain what the opcodes do pretty well again.
Now that the actors/vehicles/objects are destroyed the engine don't need the models any more. So to free some game memory you can release the models with 0249 :
CODE
Copy to Clipboard
0249: release_model #WFYSEX
0249: release_model #CR_AMMOBOX
0249: release_model #CHEETAH
0249: release_model #DESERT_EAGLE
0249: release_model #MP5LNG
0249: release_model #HEATSEEK

About special actors :

Actors like Ryder, BigSmoke, Sweet, Tenpeny, Pulaski, Toreno, Ceasar, Jethro etc... are called special actors, they're not like the usual ped you find on the street. Then, in scm coding, they're handled in a special way, with special opcodes those so special actors !!!!

It goes like this :
CODE
Copy to Clipboard
023C: request_special_actor 'TENPEN' as 1
023C: request_special_actor 'PULASKI' as 2
023C: request_special_actor 'HERN' as 3
023C: request_special_actor 'CESAR' as 4
023C: request_special_actor 'JETHRO' as 5
023C: request_special_actor 'MADDOGG' as 6

Here you have requested the models 'TENPEN' , 'PULASKI' and 'HERN' and define them as special actor models integers 1 , 2 and 3 .
You can find a special actor list in Sanny Builder help contents in SCM Documentation: GTA SA: Special actors. You can only define 9 special actor models at the same time (integers from 1 to 10 included).

Then you have to check if the special actors are loaded and create them either on foot or in a car with the usual create_actor opcodes :
CODE
Copy to Clipboard
wait 0
00D6: if and
023D:  special_actor 1 loaded
023D:  special_actor 2 loaded
023D:  special_actor 3 loaded
023D:  special_actor 4 loaded
023D:  special_actor 5 loaded
023D:  special_actor 6 loaded
0248:  model #COPCARLA available
004D: jump_if_false @check_1
00A5: 0@ = create_car #COPCARLA at 2431.609 -1254.061 22.8303
01C8: 1@ = create_actor 23 #SPECIAL01 in_car 0@ passenger_seat 0
0129: 2@ = create_actor 23 #SPECIAL02 in_car 0@ driverseat
01C8: 3@ = create_actor 23 #SPECIAL03 in_car 0@ passenger_seat 1
009A: 4@ = create_actor 23 #SPECIAL04 at 2436.609 -1254.061 22.8303
009A: 5@ = create_actor 23 #SPECIAL05 at 2437.609 -1254.061 22.8303
009A: 6@ = create_actor 23 #SPECIAL06 at 2438.609 -1254.061 22.8303

When creating actors, see how the model is named #SPECIAL01 and that it refers to the integer used in 023c(request_special_actor). Then special actors models are named from #SPECIAL01 to #SPECIAL10 .

If you need other special actors later (like in another mission) follow the same procedure with different models names but keeping 1 , 2 and 3 as special actor model integer, like :
CODE
Copy to Clipboard
023C: request_special_actor 'SMOKE' as 1
023C: request_special_actor 'TORINO' as 2
023C: request_special_actor 'SWEET' as 3
023C: request_special_actor 'TRUTH' as 4
023C: request_special_actor 'CESAR' as 5
023C: request_special_actor 'MADDOGG' as 6
023C: request_special_actor 'ZERO' as 4

To release the model simply use 0296 with the special actor integer model, and destroy the actor with usual 009b, 034f or 01c2 :
CODE
Copy to Clipboard
0296: unload_special_actor 1
0296: unload_special_actor 2
0296: unload_special_actor 3
0296: unload_special_actor 4
0296: unload_special_actor 5
0296: unload_special_actor 6
009B: destroy_actor_instantly 0@
009B: destroy_actor_instantly 1@
009B: destroy_actor_instantly 2@
009B: destroy_actor_instantly 4@
009B: destroy_actor_instantly 5@
009B: destroy_actor_instantly 6@
00A6: destroy_car 3@

7. Objects and moving them :

In Grand Theft Auto San Andreas there is many many things you can do with objects, but I won't (and I can't) tell you everything about it. I'll give you far enough to do nice and fun things with them.

I won't repeat (even if I do repeat a lot of things) how to request and load models to create objects, it's told upper. I won't repeat neither how to destroy/remove references and release objects for the same reason.

First some general (general because there is similar opcodes for vehicles and actors) things about coordinates and offsets. Sometime you need to know where the object is placed, and sometimes you need to know what are the coordinates just a bit away from the object (this is called an offset) :
CODE
Copy to Clipboard
01BB: store_object $object00 position_to $objpos_x $objpos_y $objpos_z

0400: create_coordinate $objpos_x $objpos_y $objpos_z from_object $object00 offset 1.0 2.0 3.0
  • 01bb will simply get the object $object00 x y z coordinates and store them into $objpos_x $objpos_y $objpos_z .
  • In 0400 it will store the coordinates at the offsets 1.0 2.0 3.0 of the object. It means that the coordinates that will be stored in $objpos_x $objpos_y $objpos_z will be 1.0 unit away from the object on the object's z axis, 2.0 unit away from the object on the object's y axis, and 3.0 unit away from the object on the object's z axis.

As I said there is similar opcodes for cars and actors, the explaination is the same as before just replace object by car or actor :
  • For vehicles :
    CODE
    Copy to Clipboard
    00AA: store_car $car00 position_to $carpos_x $carpos_y $carpos_z
0407: create_coordinate $carpos_x $carpos_y $carpos_z from_car $car00 offset 1.0 2.0 3.0
  • For actors :
    CODE
    Copy to Clipboard
    00A0: store_actor $actor00 position_to $actorpos_x $actorpos_y $actorpos_z
04C4: create_coordinate $actorpos_x $actorpos_y $actorpos_z from_actor $actor00 offset 1.0 2.0 3.0

Once the object is created you can move the object to new coordinates :
CODE
Copy to Clipboard
01BC: put_object $object00 at 2368.5601 -1666.84 13.38

For info similar opcodes for actors and cars are : 00a1 for actors and 00ab for cars.

You can use this to make the object move along, it's isn't the best way to do it but it's simple and works well. Here is an example :
CODE
Copy to Clipboard
:MOVE_10
0001: wait 3 ms
00D6: if
0031:  0@ >= 200.0 // floating-point values
004D: jump_if_false @MOVEND
01BC: put_object $object00 at 0@ 1@ 2@
000B: 0@ += 0.1 // floating-point values
0002: jump @MOVE_10

You can see here that the object will move along x axis, as every 3ms the object will go 0.1 distance unit further on the x axis until 0@ (which is here the x axis unit) reaches 200.0 . DON'T FORGET THE WAIT !!!!!!

The same way you can change the created object angles x y and z
CODE
Copy to Clipboard
0453: object $object00 set_rotation 0.0 0.0 180.0

Same as 01bc with a little loop you can make the object turn around. And as for 01bc there is better ways to do it, but this one is simple and works well. It also as the advantage of giving you the possibility to change any angle x y or z.

But you can as well use 034d so it will move around x axis :
CODE
Copy to Clipboard
034D: object $object00 at_angle 0.0 then_rotate_by_angle 360.0 flag 0

This is how Rockstar open many garage doors (not all).

But before using moving opcodes (like 034d or 0381) you need to give the object the ability to move (objects ain't able to move when you create them) :
CODE
Copy to Clipboard
0392: object $object00 toggle_in_moving_list 1
  • 0 = unable to move
  • 1 = able to move
You can aswell throw the object (just like throwing a ball) with 0381 :
CODE
Copy to Clipboard
0381: throw_object $object00 distance 20.0 10.0 5.0
  • 20 is the distance on x axis
  • 10 the distance on y axis
  • 5 the distance on z axis
You can attach object to cars, actors or other objects :
CODE
Copy to Clipboard
0681: attach_object $object00 to_car $car00 at_offset 0.5 0.3 0.3 rotation 0.0 0.0 0.0
069B: attach_object $object00 to_actor $actor00 at_offset 0.0 0.5 -1.0 rotation 0.0 0.0 0.0
069A: attach_object $object00 to_object $object01 at_offset 0.0 0.0 0.0 rotation 0.0 0.0 0.0

Those are pretty obvious, and as I already explained about offsets, so I'll just have to tell that the three floats after rotation are the x y and z angles that will be set, and that the object isn't solid whan attach to something else.

If you don't want the object to be solid you can turn off the collision detection
CODE
Copy to Clipboard
0382: set_object $object00 collision_detection 0
  • 0 not solid
  • 1 solid
You can make the object liftable like this :

with 08e9 :
CODE
Copy to Clipboard
08E9: set_object $object00 liftable 1

As usual 1 = on, 0 = off.

This is a very very very cool thing (thanks to DexX and PLPynton) :

You can attach object to body parts of the actor, actually you can attach 2 object to the actor and make the actor do an animation !!!!!!!
There will be more on animation later, but I'll explain those now :

CODE
Copy to Clipboard
070A: AS_actor $PLAYER_ACTOR attach_to_object $object00 offset 0.0 0.0 0.0 on_bone 6 16 perform_animation "NULL" IFP_file "NULL" time 0

attach the first object (object A)

CODE
Copy to Clipboard
09A0: actor $PLAYER_ACTOR attach_object $object01 with_offset 0.0 0.0 0.0 on_bone 5 16 perform_animation "NULL" IFP_file "NULL" time -1

attach the second object (object B)

For both of them :
  • $PLAYER_ACTOR is the actor handle (here it's you CJ)
  • the three floats 0.0 0.0 0.0 are the x y and z offsets from the normal bone coordinates
  • the first integer 5 or 6 is the bone number (it's not the same as player body parts numbers for clothes)
    • 0 - crashes the game
    • 1 - chest?
    • 2 - neck?
    • 3 - left shoulder
    • 4 - right shoulder
    • 5 - left hand
    • 6 - right hand
    • 7 - root?
    • 8 - ??
    • 9 - left foot
    • 10 - right foot
    • 11 - right knee
    • 12 - ??
    • 13 - left elbow
    • 14 - right elbow
    • 15 - left clavicle
    • 16 - right clavicle
    • 17 - back of neck
    • 18 - mouth or chin
    • 19 - crashes the game
  • the second integer 16 is unknown and is always 16
  • the first long string "NULL" is the animation file (more on them later, and IT HAS TO BE LOADED like models) where the engine will get the animation. Here "NULL" means that no animation will be done.
  • the second long string "NULL" is the animation itself within the animation file. Here "NULL" again means that no animation will be done.
  • Last integer 0 , 1 or -1 is unknown
To take theses objects off you have two opcodes :

CODE
Copy to Clipboard
070B: set_actor $PLAYER_ACTOR onbone_attached_object_operation 1 // drop or detaches object B automatically with object A
09A1: set_actor $PLAYER_ACTOR onbone_attached_objectB_operation 0 // drop or detaches object B only

070b detaches/drops object A and B if object B attached
09a1 detaches/drops object B
  • $PLAYER_ACTOR is still the actor handle (here it's you CJ)
  • the integer 1 or 0 tell if the object will be droped of just been detach.
    • 1 drops the object
    • 0 detaches the object
!!!!!!!!!!!!!!!!!!!!!!!!!!! watch out !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Attach object A fisrt because otherwise object B won't appear. When you hold object A you can't get in a car and your weapon won't be visible. If you hold two objects, object B will drop when you fall or shoot with a weapon. If you die both objects will drop.

As I said there is many things to do with objects in San Andreas but now you know the most important things you can do.

8. Animations and particules :

A. Animations :

Lets get to something very important in GTA : The actors animations !!!!!!!!!!!!!!
The animations topic in SA in unending but as with objects we will see most important things.

First lets say what are animation sequences, they are animations of an actor. Like when CJ is moving his arms while talking, when Ryder is smoking, when CJ is using the keycard, or when CJ is using the parachute...

More generally when an actor is making an action, when it's been animated !!

There is two types of animation sequences (AS), one which does one precise animation and another which make the animation you put as parameters in the opcode from the anims files (*.ifp in the anim.img file in anim folder of game directory). The second type need the animation to be loaded with 04ed, and as usual you need to check if the animation is loaded.

  • First type anims : one opcode does one animation

some examples :
CODE
Copy to Clipboard
05BA: AS_actor $actor00 chew_gum 10000 ms
05BB: AS_actor $actor00 fall_down 0 time_on_ground 500
05BC: AS_actor $actor00 jump 1
05C5: AS_actor $actor00 cower 3000 ms
05C7: AS_actor $actor00 use_atm
05C8: AS_actor $actor00 look_around
05C9: AS_actor $actor00 on_guard 2000 ms
05CD: AS_actor $actor00 exit_car $car00
05D3: AS_actor $actor00 go_to 81.42 1474.63 51.56 speed 4 3000 ms
05D4: AS_actor $actor00 rotate_angle 77.0
0639: AS_actor $actor00 rotate_to_actor $actor01
0672: AS_actor $actor00 attack_car $car00
0673: AS_actor $actor00 dive_to_offset 1.0 -3.0 time_on_ground 1000 ms
0676: AS_actor $actor00 in_car $car00 move_from_passengerseat_to_driverseat
0677: AS_actor $actor00 chat_with_actor $actor02 1 1
06A9: AS_actor $actor00 look_at_point 681.81 -474.15 15.53 5000 ms
06E3: AS_actor $actor00 roll_sideways 1

They are the easiest to use, just put the opcode, the right parameters (the first is the actor which will do the animation ($actor00 ), then there are like said in the description either an angle (77.0 ), a 3D position (681.81 -474.15 15.53 ), a car ($car00 ), another actor ($actor01 ), the time the animation will last (5000 ) etc....
They're easy simple and work very well don't hesitate to use a lot of them !!!!!!

  • Second type anims : one opcode does the anim you have put as parameters

some examples :
CODE
Copy to Clipboard
0829: actor $actor00 perform_animation "CRCKDETH3" IFP_file "CRACK" 4.0 time 0 and_dies
0605: actor $actor00 perform_animation_sequence "PASS_RIFLE_PED" IFP_file "MISC" 4.0 loop 0 0 0 0 time -1 // versionA
0812: AS_actor $actor00 perform_animation "LRGIRL_IDLELOOP" IFP_file "LOWRIDER" 4.0 loopA 0 lockX 0 lockY 0 lockF 0 time -1 // versionB
0A1A: actor $actor00 perform_animation "HIKER_POSE_L" IFP_file "MISC" 4.0 loopA 0 lockX 0 lockY 0 lockF 1 -1 ms // versionC
088A: actor $actor00 perform_animation "RAIL_FALL" IFP_file "SWAT" 8.0 loopA 0 lockX 0 lockY 0 lockF 1 limT -1 unknown 0 unknown 1
070A: AS_actor $actor00 attach_to_object $object00 offset 0.0 0.0 0.0 on_bone 6 16 perform_animation "NULL" IFP_file "NULL" time 1
09A0: actor $actor00 attach_object $object01 with_offset 0.0 0.0 0.0 on_bone 5 16 perform_animation "NULL" IFP_file "NULL" time -1

Or with very good PLPynton's sascm.ini descriptions they look like this :
CODE
Copy to Clipboard
0829: char $actor00 perform_animation "CRCKDETH3" group "CRACK" 4.0 limT 0 and_dies
0605: char $actor00 perform_animation "PASS_RIFLE_PED" group "MISC" 4.0 loopA 0 lockX 0 lockY 0 lockF 0 limT -1 //versionA
0812: char $actor00 perform_animation "EAT_VOMIT_P" group "FOOD" 4.0 loopA 0 lockX 0 lockY 0 lockF 0 limT -1 //versionB
0A1A: char $actor00 perform_animation "VEND_EAT1_P" group "VENDING" 4.0 loopA 0 lockX 0 lockY 0 lockF 0 limT -1 //versionC
088A: char $actor00 perform_animation "RAIL_FALL" group "SWAT" 8.0 loopA 0 lockX 0 lockY 0 lockF 1 limT -1 unknown 0 unknown 1
070A: set_char $actor00 attach_objectA $object00 with_offset 0.0 0.0 0.0 on_bone 6 16 perform_animation "NULL" group "NULL" time 1 //object no 1
09A0: set_char $actor00 attach_objectB $object00 with_offset 0.0 0.0 0.0 on_bone 5 16 perform_animation "NULL" group "NULL" time -1 //object no 2

First for those you have to load the animation file before using the animation opcode. It's aesy, it's just like we requested car and actors models before :
CODE
Copy to Clipboard
:ANIMLOAD
0001: wait 0 ms
04ED: load_animation "FOOD"
00D6: if
04EE: animation "FOOD" loaded
004D: jump_if_false @ANIMLOAD

As you have probably noticed it's just a bit diferent than with models, because here you directly load the anim, and with models, you request (with 0247) and then load the models (with 038b).

Don't forget after using it to release the anim with
CODE
Copy to Clipboard
04EF: release_animation "LOWRIDER"

Here to explain opcodes parameters I will use the PLPynton's sacsm.ini descriptions instead of using original Sanny Builder sascm.ini descriptions like I usually do, because it will be much easier for you to understand. But don't worry it is the same parameters order.

Parameters (thanks ceedj):
  1. The first word between quotation marks is the animation name ("CRCKDETH3" , "PASS_RIFLE_PED" , "HIKER_POSE_L" , etc...)
  2. The second is the library (animation file) where the anim is ("CRACK" , "SWAT" , "VENDING" , "FOOD" , etc...).
    In some cases, like for 09a0 and 070a "NULL" means that no animation will be done, they are both explained in chapter 7.Objects and moving them.
  3. 4.0 is playback rate. Default is 4.0, less than this slows it down, more speeds it up and may skip animation frames with higher numbers.
  4. loopA or loop It's the Loop flag, to make the animation start again once finished. 1 on/0 off, BUT if on, Timelimit (parameter 8.) MUST be set to -1 .
  5. lockX unlocks or locks actor in position on X axis. If 1 and if the actor is moving on the X axis from actor's origin (left to right), he will stay at those new coords. If 0 , the actor will return to the start position coords.
  6. lockY unlocks or locks actor in position on Y axis. If 1 and if the actor is moving on the Y axis from actor's origin (front to back), he will stay at those new coords. If 0 , the actor will return to the start position coords.
  7. lockF lock the actor in final postion. If 1 it will play the animation through once, then lock the actor into the final frame of the animation. This can NOT be stopped with opcode 0687 (clear_actor_task), but proceeding to another animation will.
  8. limT the Timelimit in milliseconds, is the time the actor will do the anim, set to 1000 ms for 1 second, 6000 ms for 6 seconds etc... If set to -1 it will play the entire animation, once through. With the Loop flag on (1 ), the animation will loop until interupted by either opcode 0687 (clear_actor_task) or another animation.

To find anims name and in which anim file they are you can look in the very good file wrtitten by ceedj : SAAnims.txt, but you can as well think of where this animation has been used in the original game, go in the mission or the external script in original main.scm it is used and search with Sanny Builder the anim you want in the mission/external you've seen it.

B.Particules :
 create particule
throw angle
particules on/off

9. Animating vehicles and car mods :
driver behaviour
follow path/road
"put at" methode
AS drving
for plane/cars/boats
carmods, request set, numbers
carparts, open/close break/repair
trailers attach
Tyres inflate deflate
10. Fire, explosions and interiors :
fire extinguish, destroy all fires,
explosion type
interiors:
player
actor/car/object
11. Cameras and directering scm cutscenes :
you're the director !!!!!
moving the camera
cam on vehicle/on actor looking to vehicle
in and out shot,
use anims
skip cutscenes
12. Texts and panels :
panels
textboxes
text draw
gxt
13. Maths, stats and timers :
variables and int and floats where a float or int can be used you can use a variable that contains the float or the int
+/-
* /
==
stats
internal timer 32@ 33@
14. Randoming and table jumps :
Random
table jumps
15. Arrays :
16. Missions and externals scripts :
starters mission/externals
One mission at a time, many external at the same time
locals range
Mission cleanup
Conclusion
opcode search ****
do experiments
try easy for beginning
Immitate existing code
use you brain !!!
multiply information sources
use search google in domain gta forum, or gtaforum search tool
ask question there is plenty of good guys (hi you guys [image] ), I was like you a while ago, and someone helped me (thank you again Dem), now I'm here writting a tutorial.
CREDITS: cns (I wouldn't be here without him), Demarest (idem), Seeman (he created Sanny Builder !!!!), PLPynton, ceedj, Y_less, PatrickW, Gangsta Killa, Bigun, SteaVor but as well as anyone who posted opcodes description (like Opius, spaceeinstein, Craig Kostelecky, DexX...), and anyone who helped me or will helped me for this, as well as people who point out mistakes I've done in the bible, and maybe YOU soon...

Have fun


CLEO 3 Code Library
CLEO 3
What is CLEO 3? -------

CLEO 3 is the next step in the CLEO project development that extends coding possibilities in San Andreas. After installing CLEO 3, you get everything that CLEO 2 can, plus some new features.

1. New opcodes.
CLEO 3 has 40 useful opcodes in store, such as file management, game memory handling, ability to call exe functions and much more. The third version adds such opcodes as a call of a SCM function, creating a thread or starting a mission from an external file and more.

2. Plugins.
Read more about them below.

3. Custom scripts.
CLEO 3 allows adding the custom scripts to the game written in Sanny Builder without need for starting of a new game. All you need is to write a script, place it in the CLEO folder and run the game (new or saved).

What game versions are supported? -------

CLEO 3 supports SA versions 1.0 and 1.01. It was tested with the US 1.0 and EUR 1.01 versions. If you have another version, please, let me know if CLEO 3 works or does not for you.

How to install CLEO 3? -------

To install CLEO 3 run Sanny Builder 3. You will see word CLEO in the status bar outlined in red. Click it, read the license agreement and press the button ‘Install’.
Physically, CLEO 3 uses 3 files in work: vorbisFile.dll, vorbishooked.dll, cleo.asi. You always can find latest versions of these files on the website cleo.sannybuilder.com.

If you used CLEO 2 or CLEO 1, delete it manually to avoid conflicts with new version. If you used the cleo.asi of version 2, replace it with the new one. If you used the cleo.dll running from the main.scm, you must delete the cleo.dll and remove its loading code from the main.scm.

The libraries CLEO 2 and CLEO 3 are fully compatible. All mods/plugins written for CLEO 2 should work with the new version.

Should I change my SASCM.INI? -------

Sanny Builder 3 has the files SASCM.INI and OPCODES.TXT already up to date. Future updates of the CLEO library may require some changes of these files. You will get all instructions along with the updates on cleo.sannybuilder.com.

What about plugins? -------

The plugins are the DLL files having an extension .CLEO. At startup, the CLEO library scans the folder GTASA\CLEO for the files with that extension and tries to load them. If successful, the plugin begins to work and complete the functions it was made for.

The plugin installation is very simple: just copy the plugin file to the folder GTASA\CLEO. TO cancel the plugin usage, delete proper file.

You may find the list of available plugins on cleo.sannybuilder.com.

Is CLEO 3 redistributable? -------

If you wrote a script using the CLEO library and (or) its plugins, you may distribute needed files along with that script. You also may direct the script users on cleo.sannybuilder.com to inform them how to use CLEO.

Credits? -------

The author of the CLEO library is Seemann. The author has no liability for any negative consequences caused by using this product. Use it at your own risk.

If you want to help in developing of the library or its plugins, contact me by forum or e-mail.

Also thanks to Stanislav Golovin (aka listener) for his support and useful information.


Virtual key codes (for 0AB0)
Character | Decimal | Hex
Backspace | 8 | 8
Tab | 9 | 9
Enter | 13 | D
Shift (both) | 16 | 10
Ctrl (both) | 17 | 11
Pause | 19 | 13
Caps Lock | 20 | 14
Esc | 27 | 1B
Spacebar | 32 | 20
Page Up | 33 | 21
Page Down | 34 | 22
End | 35 | 23
Home | 36 | 24
(left arrow) | 37 | 25
(up arrow) | 38 | 26
(right arrow) | 39 | 27
(down arrow) | 40 | 28
Insert | 45 | 2D
Delete | 46 | 2E
0 | 48 | 30
1 | 49 | 31
2 | 50 | 32
3 | 51 | 33
4 | 52 | 34
5 | 53 | 35
6 | 54 | 36
7 | 55 | 37
8 | 56 | 38
9 | 57 | 39
A or a | 65 | 41
B or b | 66 | 42
C or c | 67 | 43
D or d | 68 | 44
E or e | 69 | 45
F or f | 70 | 46
G or g | 71 | 47
H or h | 72 | 48
I or i | 73 | 49
J or j | 74 | 4A
K or k | 75 | 4B
L or l | 76 | 4C
M or m | 77 | 4D
N or n | 78 | 4E
O or o | 79 | 4F
P or p | 80 | 50
Q or q | 81 | 51
R or r | 82 | 52
S or s | 83 | 53
T or t | 84 | 54
U or u | 85 | 55
V or v | 86 | 56
W or w | 87 | 57
X or x | 88 | 58
Y or y | 89 | 59
Z or z | 90 | 5A
(left Windows key) | 91 | 5B
(right Windows key) | 92 | 5C
(application key - located between the right Windows and Ctrl keys on most keyboards) | 93 | 5D
0 (numpad with Num Lock on) | 96 | 60
1 (numpad with Num Lock on) | 97 | 61
2 (numpad with Num Lock on) | 98 | 62
3 (numpad with Num Lock on) | 99 | 63
4 (numpad with Num Lock on) | 100 | 64
5 (numpad with Num Lock on) | 101 | 65
6 (numpad with Num Lock on) | 102 | 66
7 (numpad with Num Lock on) | 103 | 67
8 (numpad with Num Lock on) | 104 | 68
9 (numpad with Num Lock on) | 105 | 69
* (numpad) | 106 | 6A
+ (numpad) | 107 | 6B
- (numpad) | 109 | 6D
. (numpad) | 110 | 6E
/ (numpad) | 111 | 6F
F1 | 112 | 70
F2 | 113 | 71
F3 | 114 | 72
F4 | 115 | 73
F5 | 116 | 74
F6 | 117 | 75
F7 | 118 | 76
F8 | 119 | 77
F9 | 120 | 78
F10 | 121 | 79
F11 | 122 | 7A
F12 | 123 | 7B
Num Lock | 144 | 90
Scroll Lock | 145 | 91
; | 186 | BA
= | 187 | BB
, | 188 | BC
- | 189 | BD
. | 190 | BE
/ | 191 | BF
` | 192 | C0
[ | 219 | DB
\ | 220 | DC
] | 221 | DD
' | 222 | DE


CLEO 3: opcodes

The using of the following opcodes is only possible at the CLEO 3 library installed. At compiling Sanny Builder checks if the library is installed and if not, warns that it’s necessary. If you write a script using these opcodes, you have to include the library files as well to guarantee its functionality to the end user

Opcode 0A8C | Opcode 0A99 | Opcode 0AA6 | Opcode 0AB3
Opcode 0A8D | Opcode 0A9A | Opcode 0AA7 | Opcode 0AB4
Opcode 0A8E | Opcode 0A9B | Opcode 0AA8 | Opcode 0AB5
Opcode 0A8F | Opcode 0A9C | Opcode 0AA9 | Opcode 0AB6
Opcode 0A90 | Opcode 0A9D | Opcode 0AAA | Opcode 0AB7
Opcode 0A91 | Opcode 0A9E | Opcode 0AAB | Opcode 0AB8
Opcode 0A92 | Opcode 0A9F | Opcode 0AAC | Opcode 0AB9
Opcode 0A93 | Opcode 0AA0 | Opcode 0AAD | Opcode 0ABA
Opcode 0A94 | Opcode 0AA1 | Opcode 0AAE | Opcode 0ABD
Opcode 0A95 | Opcode 0AA2 | Opcode 0AAF | Opcode 0ABE
Opcode 0A96 | Opcode 0AA3 | Opcode 0AB0 | Opcode 0ABF
Opcode 0A97 | Opcode 0AA4 | Opcode 0AB1 |
Opcode 0A98 | Opcode 0AA5 | Opcode 0AB2 |

CLEO 2 Opcodes

0A8C: write_memory 0xC0BC15 size 1 value 1 virtual_protect 0

0A8C writes a value to the game memory.

Parameters:
1 – memory address (any integer value)
2 – number of bytes to write: 1, 2 or 4 bytes
3 – value to write (any number)
4 – Virtual Protect: use 1 to write to the read-only address, 0 – if the address is rewritable.

0A8D: $result = read_memory 1@ size 4 virtual_protect 0

0A8D reads the game memory and stores the result to a variable.

Parameters:
1 – variable to store read result (any variable or array item)
2 – memory addressа to read (any integer value)
3 – number of bytes to read: 1, 2 or 4 bytes
4 – Virtual Protect: use 1 if the address is unreadable, 0 – if address is readable.

0A8E: 4@ = 5@ + 6@ // int

0A8E sums up two values and stores the result to a variable.

Parameters:
1 – variable to store sum (any variable or array item)
2 – first item (any integer value)
3 – second item (any integer value)

0A8F: $var = 0@(1@,2i) - 1 // int

0A8F subtracts one integer value from another and stores the result to a variable.

Parameters:
1 – variable to store difference (any variable or array item)
2 – minuend (any integer value)
3 – subtrahend (any integer value)

0A90: $var(0@,10i) = 100 * 1@ // int

0A90 multiplies one integer number by another and stores the result to a variable.

Parameters:
1 – variable to store product (any variable or array item)
2 – multiplier (any integer value)
3 – multiplier (any integer value)

0A91: $div = 1 / 5 // int

0A91 divides one integer number by another and stores the result to a variable without the remainder.

Parameters:
1 – variable to store result (any variable or array item)
2 – dividend (any integer value)
3 – divisor (any integer value)

0A96: $ActorStruct = actor $PLAYER_ACTOR struct

0A96 stores the pointer to the actor’s structure in the game memory. The structure is a set of different values such as health, coords, etc. Knowing the struct address it’s possible to read/rewrite these values using 0A8D/0A8C.

Parameters:
1 – variable to store the struct address
2 – actor handle obtained by the constructor opcode (009A and similar)

0A97: $CarStruct = car $MyCar struct

0A97 stores the pointer to the vehicle’s structure in the game memory.

Parameters:
1 – variable to store the struct address
2 – vehicle handle obtained by the constructor opcode (00A5 and similar)

0A98: $ObjectStruct = object 0@ struct

0A98 stores the pointer to the object’s structure in the game memory.

Parameters:
1 – variable to store the struct address
2 – object handle obtained by the constructor opcode (0107 and similar)

0A99: chdir 0

0A99 sets the current directory making it default.

Parameter:
0 – the game root folder becomes the default directory
1 – the user files folder becomes the default directory

0A9A: $hFILE = openfile "settings.ini" mode 0x72 // IF and SET

0A9A opens the file for reading and writing. This opcode can be used as a condition: if the file is was not open, it returns False, otherwise True.

Parameters:
1 – variable to store the file handle
2 – file name. If the path is relative, the file is open in accordance with the current directory (opcode 0A99).
3 – file open mode:
0x6272 – opens binary file for reading
0x72 – opens text file for reading
0x6277 – opens binary file for writing
0x77 – opens text file for reading

0A9B: closefile $hFILE

0A9B closes the file and frees the memory.

Parameter: a handle to the file

0A9C: 0@ = file $hFILE size

0A9C stores the file size in bytes to a variable.

Parameters:
1 – variable to store the result
2 – file handle

0A9D: readfile $hFILE size 2 to $150

0A9D reads the specified number of bytes from the opened file and writes them to the memory region starting from the address where the variable is.

Parameters:
1 – file handle
2 – number of bytes to read from the file
3 – variable to store the result. If the number of delivered bytes is more than four, the remainder will be written to the next variable ($151 in this case), and so on.

0A9E: writefile $hFILE size 128 from 0@

0A9E copies data starting from the address, where the variable (last parameter) is, to the file.

Parameters:
1 – file handle
2 – number of bytes to copy
3 – variable indicated the starting position of writing data. If the data size is more than 4 bytes, next variable’s value will be read and written to the file. In this example, the file will keep the dump of all local variables of a thread (32 variables with 4 bytes in length for each = 128 bytes to copy).

0A9F: 0@ = current_thread_pointer

0A9F stores the current thread pointer to a variable. Knowing this pointer it’s possible to work directly with any thread fields such as thread name, its local variables, base IP, etc.

0AA0: gosub_if_false @CREATE_NEW_ACTOR

0AA0 executes a gosub command if the condition result is false. Except this difference, this opcode is the same as 004D: jump_if_false and can be used instead of it.

Parameter: label where the thread is transfered

0AA1: return_if_false

0AA1 executes a return if the condition result is false. This one is similar to the 004D and can be used instead of.

0AA2: $hLIB = load_library "CLEO\version.dll" // IF and SET

0AA2 loads a DLL library and stores the handle to it to a varaible. This opcode can be used as a condition: if the library does not loaded, it returns False, otherwise it’s True.

Parameters:
1 – variable to store the handle to a library (any variable or array item)
2 – a library name. If the path is relative (without specifying of a disk name), the DLL file is searched relatively of the current active directory (opcode 0A99). If the file extension is not specified, the default extension will be used (.DLL).

0AA3: free_library $hLIB

0AA3 unloads the library and frees the memory.

Parameter: handle to the library

0AA4: $hPROC = get_proc_address "GetVersion" library $hLIB // IF and SET

0AA4 returns the address of the specified exported DLL function. This address can be used in the opcodes of the call type. This opcode can be used as a condition: if the function is not found it return False, otherwise it’s True.

Parameters:
1 – variable to store the function address.
2 – function name (a string or a string variable). Pay attention that the get_proc_address is sensitive to the letter case. If the function is exported having the name GetVersion, it means that, for example, get_proc_address “getversion” will not find such a function. You must specify exact name. Also remember that Sanny Builder compiles all strings in uppercase by default. It means that this example will be compiled as “GETVERSION”, so the function GetVersion won’t be found again. To avoid that, select the “As is” letter case in the program options.
3 – loaded library handle (0AA2)

0AA5: call $hPROC num_params 1 pop 1 $param

0AA5 and similar opcodes have variable number of parameters. This opcode has at least 3 parameters, and also additional ones (passed to the called proc), number and values of which depend on the called procedure. Total number of additional parameters must equal to the parameter num_params. Each passed parameter must be numerical (constant or variable fit), but not string.

Parameters:
1 – address of called proc. It may be the address inside the gta_sa.exe or inside a loaded dll.
2 – number of parameters to pass to the proc.
3 – number of parameters that must be removed from the stack after the proc execution. This value has to be within an interval from zero to num_params. The exact value depends on the calling convention of the procedure. Usually, the exe procedures do not clean the stack themselves, so the pop parameter mostly equals to the num_params (all passed parameters are removed from the stack after the proc execution).

0AA6: call_method $Destroy struct $CarStruct params 0 pop 0

0AA6 calls the proc for the class. Each class has a set of procedures called methods to operate with the class data (like SB classes for reference). We call the Destroy method of the CVehicle class in this example. With a proviso it’s possible to say that this example is the same as the Car.Destroy() command.

Parameters:
1 – address of called proc. It may be the address inside the gta_sa.exe or inside a loaded dll.
2 – pointer to the class structure (can be obtained by the opcodes 0A96 - 0A98).
3 – number of parameters to pass
4 – number of parameters to be removed from the stack after the method execution. Commonly, the methods clean the stack themselves, so the pop parameter must equal to 0.

0AA7: call_function 0x569660 num_params 2 pop 2 $COORD_X $COORD_Y $GROUND

0AA7 work similar to the 0AA5 except that additionally there is a variable to keep the result of called function. It means that the last parameter here is always a variable. Thus the num_params does not include this one. We call the function at address 0x569660 and pass two parameters X and Y to it in this example. The function result will be stored to the $GROUND.

Parameters:
1 – address of called function. It may be the address inside the gta_sa.exe or inside a loaded dll.
2 – number of parameters to pass to the function
3 – number of parameters that must be removed from the stack after the function execution. See the 0AA5 for explanation.

0AA8: call_function_method 0x4048E0 struct 0xB74494  num_params 1 pop 0 $MyCar 0@

0AA8 calls a function from the class and stores the result to a variable which is always the last parameter. The principle of operation is similar to the opcodes 0AA6 and 0AA7. We call the function at address 0x4048E0 and pass the vehicle handle as a parameter to it in this example. Struct 0xB74494 is a collection of all in-game vehicles. 0x4048E0 is a function that converts the vehicle handle to its struct pointer (analogue of opcode 0A97). This pointer will be stored to the variable 0@.

Parameters:
1 – address of called function. It may be the address inside the gta_sa.exe or inside a loaded dll.
2 – pointer to the class structure (can be obtained by the opcodes 0A96 - 0A98).
3 – number of parameters to pass
4 – number of parameters to be removed from the stack after the method execution. Commonly, the methods clean the stack themselves, so the pop parameter must equal to 0.

0AA9: is_game_version_original

This opcode is used as a condition. If you work with the original SA version 1.0 it returns True, otherwise False. The opcode is useful to write a multiversion script.

0AAB: file_exists "CLEO\version.dll"

0AAB tests if a specified file exists. This check is a part of opcodes 0A9A and 0AA2, so there is no need to duplicate it for them.

Parameter: file name. If the path is relative (without specifying of a disk name), it’s searched relatively of the current active directory (opcode 0A99).

0AAC: $hMP3 = load_mp3 "CLEO\playlist\01.mp3"

0AAC loads a mp3 file and stores a handle to it to a variable.

Parameters:
1 – variable to store the mp3 handle
2 – mp3 file name. If the path is relative (without specifying of a disk name), it’s searched relatively of the current active directory (opcode 0A99).

0AAD: set_mp3 $hMP3 perform_action 1

This opcode performs the pre-defined action with the loaded mp3.

Parameters:
1 – mp3 handle obtained by 0AAC
2 – a number to specify an action:
0: stop
1: play
2: pause
3: resume

0AAE: release_mp3 $hMP3

0AAE releases the mp3 file and frees the memory.

Parameter: mp3 handle obtained by 0AAC.

0AAF: 0@ = get_mp3_length $hMP3

This opcode stores the track length in seconds of the loaded mp3 to a variable.

Parameters:
1 – variable to store the result
2 – mp3 handle

0AB0: key_pressed 0x73

0AB0: key_pressed 0x73

0AB0 is used as a condition. This opcode tests if the key is pressed on keyboard. If the key with specified code is pressed, it returns True, otherwise False.

Parameter: virtual key code. See here the list of them.

CLEO 3 Opcodes

0A92: create_custom_thread "ShowTextBox.s"

0A92 creates a new thread from the file. If the file has an extension .cs the thread from it is created automatically at game startup. At creating a custom thread, you can pass up to 34 parameters to it, like in opcode 004F.

Parameter: file name. The name must be specified with an extension if it has one. The file is retrieved relatively of the directory ‘game\CLEO’ which is default path for any CLEO files.

0A93: end_custom_thread

0A93 ends the custom CLEO thread. This opcode must be used only in the CLEO threads (nor in CLEO-missions, nor in the main.scm). On the whole this opcode is an analogue of the 004E.
To stop a CLEO-mission, use opcode 004E.

0A94: start_custom_mission "missions\CustomMission1"

0A94 begins a CLEO mission from the specified file as the 0147 does. Look that the file extension is not needed to specify. In fact the opcode will search for the file with the extension .cm (Custom Mission). The mission starts from the file CLEO\missions\CustomMission1.cm in this example.

Parameter: file name without an extension. The file is retrieved relatively of the directory ‘game\CLEO’.

0A95: enable_thread_saving

0A95 enables the saving flag for the current thread. By default the CLEO threads status are not saved, and they execute from the very beginning each time the game started. To save the thread status, its local variables and such, add this opcode to the script.

0AAA: 0@ = thread 'OTB' pointer

This opcode tests if a thread with given name is active. If so, opcode will store the address of this thread to a variable. If a thread with given name is not found in the game memory, the variable's value will be 0.

Parameters:
1 - a variable to store search result
2 - a thread name to search

0AB1: call_scm_func @GetSQR 1 10 $result

This opcode calls a SCM function, passes the parameters to it and stores the result to a variable(s). The passed parameters values are copied to the local variables in series, then the thread execution is transferred to the label, it executes code there and returns after the opcode 0AB2.
Parameters:
1 – label (SCM function beginning)
2 – number of parameters to pass

Then there are the passed parameters, a number of 10 in our case. After that, there should be the variables to store the result of a SCM function (see 0AB2).

0AB2: ret 1 0@

This opcode transfers the thread execution back to the 0AB1 opcode and stores the returned values in its variables. Total number of returned values must equals to the number of variables storing the result in the 0AB1. In this example the 0AB2 returns one value, which is the value of the variable 0@, this value will be copied to the variable $result (see 0AB1 example). If the 0AB2 opcode does not return any values, it must have a 0 as the only parameter, and proper 0AB1 that calls such a function should have no variables to store.

Parameters:
1 – number of values to return
After that there are the returned values.

This is a simple example of SCM function calculating the square number.

0@ = 5
0AB1: call_scm_func @GetSQR 1 10 $result
end_thread

…..

: GetSQR
006A: 0@ *= 0@
0AB2: ret 1 0@

How it works. First of all, the game comes to the opcode 0AB1. The game reads the number of parameters to pass (1) and its values (10). The variable 0@ of the current thread equates to 10 (if there would more parameters to pass, the next one will be copied to the 1@, then 2@ and so on). After that the thread jumps to the label @GetSQR. Here the square number is calculated (of a value in the 0@). Again, if there would be more parameters, the values of 1@, 2@ etc may be taken in to account, if needed. After the calculation, the game comes to the opcode 0AB2. The value of 0@ equals to 10*10 = 100 at this moment. Then the following happens: the returned value(s) (0@) is copied to the variable(s) that is written in the opcode 0AB1 which called this function. In our example such variable is $result. After storing of the result, the thread returns back to the 0AB1 and comes to the command end_thread. The value of the $result equals to the 100 (which is square of 10) at this moment.
Finally say that 0AB2 could return not only the variables values, but also the number constants. For example, 0AB2: ret 1 1 will forever stores 1 to the result.

Also pay attention that the local variables are stayed unchanged after the function calling. In this example, the variable 0@ contains a value of 5 before 0AB1. Despite the fact that this variable was used in the function, after the calling it still equals to 5. This covers on all 32 local variables, so you can freely work with them within a function without fear to lose data.

0AB3: var 0 = 10

0AB3 sets a new value of the global CLEO variable. These variables can be used to data communication between CLEO threads, or between CLEO and the main.scm. The total number of such variables is 100. Their values are saved in the CLEO save.
This variables can be used in the main.scm as alternative to the common global variables.

Parameters:
1 – global variable ID. Should be in a range of 0..999
2 – new value for the variable. (any number).

0AB4: 0@= var 0

0AB4 stores to a variable the value of the global CLEO variable. In this example, the 0@ will be equal to 10 (see 0AB3).

Parameters:
1 – variable to store the global CLEO variable value
2 – global CLEO variable ID. Should be in range of 0..999.

0AB5: store_actor $PLAYER_ACTOR closest_vehicle_to 0@ closest_ped_to 1@

This opcode stores to the variables handles of a vehicle and ped being closest to the actor. If there’s no any vehicle or ped close to him, the proper variable will contain value of -1.

Parameters:
1 – actor handle
2 – variable to store a vehicle being closest to him
3 – variable to store a ped being closest to him

0AB6: store_target_marker_coords_to 0@ 1@ 2@ // IF and SET

This opcode stores to the variables coordinates of the place marked with red target point on the map (right-click on the map). If the target point does not exist, the variables do not change their values.

Parameters:
1,2,3 – variables to store XYZ coords

0AB7: get_vehicle $CAR number_of_gears_to 10@

Opcode 0AB7 stores to a variable total number of gears for specified vehicle. This number equals to the parameter TransmissionData.nNumberOfGears in the file handling.cfg.

Parameters:
1 – a vehicle handle
2 – variable to store number of gears

0AB8: get_vehicle $CAR current_gear_to 11@

This opcode stores to a variable number of current gear for specified vehicle.

Parameters:
1 – a vehicle handle
2 – variable to store current gear

0AB9: get_mp3 $hMP3 state_to 7@

This opcode stores to a variable a state of a MP3 file.

Parameters:
1 – handle of a loaded mp3-file (opcode 0AAC)
2 – variable to store mp3 file state:
1 – file is playing
2 – file paused
-1 – file is stopped

0ABA: end_custom_thread_named 'BENZIN'

0ABA ends a CLEO-thread with given name. A thread gets its name with the opcode 03A4. If the thread wasn't named with 03A4, the thread gets its name by first 7 letters of the file name. For example, the thread from the file test.cs will have name 'test.cs'; from the file myscript.cs - 'myscrip'. The opcode 0ABA immediately finishes the execution of a thread with given name. This opcode is the same as 0459, but is made for the CLEO scripts.

Parameters:
1 - name of the thread to end.

0ABD: vehicle 0@ siren_on

0ABD checks if the siren of the vehicle 0@ is on. If so, the condition will be true.

Parameters:
1 - handle of the vehicle

0ABE: vehicle 0@ engine_on

0ABE checks if the engine of the vehicle 0@ is on. If so, the condition will be true.

Parameters:
1 - handle of the vehicle

0ABF: set_vehicle 0@ engine_state_to 0

0ABF enables or disables the vehicle's engine.

Parameters:
1 - handle of the vehicle
2 - engine's new state:
0 - off
1 - on


CLEO3: scripts

CLEO 3 allows adding new scripts needlessly to start a new game. Strictly speaking, the main.scm state does not matter for these scripts as CLEO-scripts are run and functioned separately from it.

What does it give? You can add new script at any stage of the game or delete existing one. Even so, you do not need to edit the main.scm, so the need of starting a new game, the saves incompatibility, script limits – all these problems disappear right away.

The CLEO-script is an ordinary script written using the opcodes in Sanny Builder. Each script should be made as a single file with an extension .cs (Custom Script). The dominant requirement of writing such scripts is they must be compiled as the external scripts.

There are several ways of making of a CLEO-script being able to work correctly in the game. First: you add a new external script in the source file, compile it, and then extract that script from the file script.img. The extracted file will have the extension .scm, so you only need to change it on the .cs and copy to the folder ‘game\CLEO’.

The second way is easier. Create a new file in Sanny Builder, write the directive $E at the beginning of it, and compile. The compiled file will be the same as that one extracted from the script.img. You only need to change its extension on the .cs and copy to the ‘game\CLEO’.

Finally, the easiest one. Create a new file in Sanny Builder, write the directive $CLEO at the beginning of the file, and compile. The compiled file will be copied into the ‘game\CLEO’ directory and will have a file extension specified by the directive (.cs by default).

The CLEO-scripts could be used as missions. The compiling process is the same, but the output file must have the extension .cm (Custom Mission). To start this mission, use the opcode 0A94.

The rules you must follow using CLEO 3:
  1. One file – one thread. Each CLEO-script must be made as a single thread compiled in a single file. If you need more threads for your script, use the opcodes 004F or 0A92, depending of where is that additional thread located - in the main.scm or in a separate cs-file.
  2. Never use the opcode 004E in the CLEO-threads. They work separately from the common threads, so the using of this opcode will cause an error. Use the opcode 0A93, if you need to stop a CLEO-thread. Conversely, never use the opcode 0A93 in the CLEO-missions, but instead use the 004E to cancel a mission.
  3. Never use custom global variables in your CLEO-scripts ($car, $foo, $blahblah, etc), or your script will work incorrectly. You may use only a few global variables (read below).

To install the CLEO script it’s only necessary to copy the file with an extension .cs to the folder ‘game\CLEO’. The file name does not matter, but it uses at the thread initialization to name it. For example, the CLEO thread located in the file showsavescreen.cs has the name SHOWSAV.

To remove the script, just delete the proper file from the CLEO directory.

The CLEO thread status may be saved and loaded along with the common threads. It does not saved by default. The saves themselves are located in the folder CLEO\cleo_saves. The is an own save for each save slot. The save file stores only the CLEO threads having the saving flag enabled (0A95 opcode). The save file stores not only the active threads, but also the ones being forced to end (0A93 opcode), to prevent their rerun at loading. If at the loading one of saved thread is not found, there is no error. If you add a new script that is not present in the current save file, it will be loaded along with the others and to work from the very beginning.

The CLEO thread is the ordinary thread on the whole. It has 32 local variables and 2 timers incrementing constantly. You can pass up to 34 parameters at creation of that thread or a CLEO mission (by analogy with the opcode 004F).

An important thing concerns with data communication between a CLEO script and the main.scm. To use the SCM code, its variables, threads you have to compile the CLEO script as an external one (first way). But this method is not recommended, as such a script becomes very sensible to the any main.scm change. Implicitly, a CLEO script should be sufficient for itself and use minimum of the SCM data. However, you can freely use global variables names from the CustomVaribles.ini (for example, $PLAYER_CHAR, $PLAYER_ACTOR, $ONMISSION, etc).
Also, for the data communicate between the main.scm and CLEO, or between the CLEO scripts you may use the CLEO variables (see opcodes 0AB3, 0AB4).

The CLEO complete set includes the examples of simple scripts with sources.


Previous Releases

Version History

Previous Releases:

v. 2.99e - 01.01.2007
  • fixed disappearing code parts within the HEX..END contruction in the debug_mode decompiling
  • the hex..end statement could accept the aDMA type
  • the FOR statement could accept the model identifiers as the counter values
  • the hex..end statement could accept the strings
v. 2.99d - 03.12.2006
  • Memory Hacker became a separate tool. Now downloadable at: http://sannybuilder.com/downloads
  • fixed a decompiler bug
v. 2.99c - 30.11.2006
  • added the Memory Hacker plug-in
  • possibility to decompile the main.scm of Liberty City Stories
  • support the number of constants as the global array indexes
  • the global variables are decompiled with the type aDMA (&) if not a multiple to 4
  • at compilation the default values for the segments are used when the file header is not present
  • possibility to open a file using Drag&Drop
  • new preprocessor directives: {$VERSION}, {$VERSION_RESTORE}

(!) If you get a compiler error message like "Unknown directive xxxx"
when compiling the sources from v2.99, replace the line {$VERSION xxxx}
to any place after the header, for instance before the comment

//-------------MAIN---------------

v. 2.99 - 27.09.2006
    Major changes:
  • added new commands WriteMem and ReadMem
  • support hexadimal numbers
  • HEX..END statement can accept labels and global variables
  • full support of &-datatype (ADMA)
  • opportunity to give custom names to labels
  • opportunity to choose a different case for custom names and strings (Options->Format)
  • added the console in order to switch the special options of SB
  • decompiler supports the GXT-files of GTA III & GTA VC
  • added special symbol constants in the long strings
    Minor changes:
  • information about an INI file (version, author, date)
  • classes support an original order of the parameters (like in SASCM.INI from PLPynton).
    In order to support such order there should be a line {$VERSION x.0.xxxx},
    see comments in the INI about this
  • added option to confirm exit program
  • quick switching of the Edit Mode
  • converting of the selected piece of code
  • opportunity to pass the current file name to the external tool
  • corrected some mistakes in the configuration files
  • removed auto-casting of an integer number to a float one when the variable was declared as Float. Now the compiler chooses an opcode depending on the number type
    only (in math expressions without opcodes)
  • reading/writing of the player's z_angle in Coord Manager; quick insertion of this one in a script by pressing Ctrl+Shift+E (for SA)

Other notes:
(!) The following opcodes were changed in SASCM.INI: 0181, 00c3, 00c4 in order to support the commands WriteMem and ReadMem. In original files these opcodes are not used and the games do not support them so there should be no problem.

(!) The class member Car.SetSpeedInstantly was named incorrectly (with wrong opcode) in the file classes.db for SA. If you get the error message about this method at compilation, rename it in Actor.DrivingPlane manually. We apologize.

v. 2.98 - 04.08.2006
  • Sanny Builder became multilingual
  • added menu for external applications
  • the special version of Opcode Search Tool is built in SB Details in a file 'OST Readme.txt'
  • checking of the math expressions while decompiling when the option "Write opcodes" is disabled (to sure that all the opcodes were used correctly)
  • an opportunity to choose an IMG-file manually if the last one is not found in a folder with the SCM-file (an option "Manual IMG opening")
  • an opportunity to add new macros directly from the editor; added macros descriptions
  • the list of models can be sorted alphabetically/by value (Alt+S when the list is active)
  • minor corrections and changes
v. 2.97 - 11.06.2006
  • new data type: & that denotes direct byte address (ADMA).
  • minor updates
v. 2.96 - 01.04.2006
  • improved the option jump to label
  • added an opportunity to call macros list of macros
  • added an option of replacement of mission numbers with their names
  • fixed some bugs
v 2.9f - 18.02.2006
  • model names is added to the DEFINE OBJECT list by the compiler (this list may be not presented in the source file at all)
  • block comments support {}
  • macrorecording
  • minor changes
v 2.9 - 15.12.2005
  • additional commands (see by item 2.5) are added
  • operator IN is added
  • construction IF..THEN..ELSE..END is added
  • loops WHILE, REPEAT are added
  • the opportunity of use of the enclosed loops is added.
  • function alloc() is added, allowing to specify for a variable the specific address in memory
  • new comment style: //
  • positions of markers and the cursor are remembered for the closed files
v. 2.6 - 05.11.2005
  • full support of formats of Vice City and GTA3 is added
  • the opportunity of initialization of variables and files as members of a class is added
  • display of the list of variables and labels is added
  • support of loops (FOR operator) is added
  • minor changes:
  • missions can be started on their name (start_mission MYMISSION), where MYMISSION is a name of a starting label (DEFINE MISSION 100 at @MYMISSION)
  • the list of imported models (defined objects) on Ctrl+Space is accessible
  • the new pseudo-operator <>
  • if at decompiling it is not found script.img, it is used original
  • for arrays the type handle is added
  • an opportunity of switching-off of the warning of use IMG by game
v. 2.5 - 10.10.2005
  • added "properties" support
  • added macroes support
  • added construction VAR...END for variables management
  • all math commands can be used without opcodes [0004..008B]
  • new pseudo operators < and <=
  • added a capability that the compiler itself set necessary value for IF command
  • added "extended" parameters support
  • added models list showing
  • minor changes and fixes
v. 2.0 - 18.09.2005
  • added classes support
  • added keywords support
  • added a capability to write some math commands without opcodes (now such capability exists for opcodes 0004,0005,0006,0007,0038,0039,0042,0043)
  • for opcode 00D6 the default parameter is 0 (if = if 0)
  • added the option of a choice of various kinds of labels (Formats-> Labels Format)
  • added keywords True and False which designate 1 and 0 accordingly
  • added construction HEX...END for writing hexadecimal values directly in SCM
v. 1.1 - 07.09.2005
  • added coords manager
  • some bugs fixed
v. 1.0 - 04.09.2005
  • new format of labels
  • added convertor from BW''s SA Mission Builder syntax
  • at decompiling names of models and texts from american.gxt are added in source
  • added new options
  • some bugs fixed
v. 0.8 - 20.08.2005
  • added the capability to associate SCM-files with the program
  • after decompilling the outputfile name now changes if file with such name already exists. E.g, if already exists main.scm.txt, the new file will be main.scm[0].txt
  • error messages becames more informative
  • added check of label redeclaring
  • some bugs fixed
v. 0.7 - 10.08.2005
  • added new options for the text editing
  • added a capability to work with several files simultaneously
  • added a function to auto-complete a line with the F1 button (beta)
v. 0.6 - 04.08.2005
  • full decompiling of GTA SA *.scm-files
  • compiling of the source files into the SA .SCM file and .IMG file.
  • some options for the text editing


Sanny Builder Help: About the program

About The Program

About The Program

Version History
  • Current Version

  • Previous Releases
            •


CLEO library not found

Sanny Builder Error Messages

CLEO library not found

This error message is displayed, if you used an opcode that requires the CLEO library to be installed. The program either not found needed files or the existed files is outdated.

Possible solutions: install CLEO by clicking the word CLEO on the bottom panel.


INI file not found

Sanny Builder Error Messages

INI file not found

This warning message occurs when the program can’t find the INI file, containing the list of opcodes. The compiler work is impossible without it.

Possible solutions: either reinstall the program, or set the correct path to the INI file via options


Unknown array type

Sanny Builder Error Messages

Unknown array type

The arrays types are strictly limited. If the decompiler did not recognize the array type compiled in the SCM file, this error is issued. It may happen because of wrong compiling.

Possible solutions: toggle debug option ignore_unknown via console.


Невозможно Could not decompile script.img

Sanny Builder Error Messages

Could not decompile script.img

If this error message is given, it means the script.img file is broken or has unknown format. It may also happen if this img file was not compiled along with the main.scm, and the main.scm contains the external scripts data relating to another file. Check if both files are compiled at the same time.

Possible solutions: replace the script.img with the file suitable to the decompiled main.scm.


Unknown parameter type

Sanny Builder Error Messages

Unknown parameter type

An opcode parameter can be only one of the pre-defined types. The error occurs if the decompiler can not find out what this parameter is type of, or its ID is unknown. It also occurs if the file was compiled incorrectly, or the number of parameters for an opcode in SCM does not match the number in the INI.

Possible solutions: toggle debug option ignore_unknown via console.


Could not decompile this file

Sanny Builder Error Messages

Could not decompile this file

This error message is displayed if you’re trying to decompile the SCM file of GTA 3 or Vice City format while the current edit mode is San Andreas.

Possible solutions: switch the edit mode to needed.


Unknown file header

Sanny Builder Error Messages

Unknown file header

This error occurs if the header of decompiled file contains wrong or impossible data.

Possible solutions: turn off the header reading via console (command skip_scm_header)


Could not load file

Sanny Builder Error Messages

Could not load file

This error message is given because the program can’t find and load the needed file.

Possible solutions: check if the file name and path is correct, and the file exists.


Could not create opcodes table

Sanny Builder Error Messages

Could not create opcodes table

This message is displayed at the program startup if the INI file contains incorrect data.

Possible solutions: either reinstall the program, or update the INI file.


Missed INI file

Sanny Builder Error Messages

Missed INI file

This warning message is shown when you start compiling or decompiling process while the INI file is missed.

Possible solutions: check if the INI file exists and restart the program.


Unknown opcode

Sanny Builder Error Messages

Unknown opcode

This error occurs if the compiler found an opcode that not described in the INI file.

Possible solutions: edit the mentioned opcode. Probably you use incorrect value.


Unknown opcode at

Sanny Builder Error Messages

Unknown opcode at

If the decompiler found an opcode, that the INI file does not contain, it shows this error message. In most cases, it happens when the number of parameter of the previous opcode does not match the INI number.

Possible solutions: either add the mentioned opcode in the proper INI file, or toggle debug option ignore_unknown via console.


Incorrect jump instruction

Sanny Builder Error Messages

Incorrect jump instruction

This error message is displayed when the decompiler finds a label, offset of which is out of the code.

Possible solutions: decompiling is impossible.


Unknown directive

Sanny Builder Error Messages

Unknown directive

It is the common error message displayed when the compiler find a command being unknown or being placed incorrectly. It can be a word at the beginning of a line whereas the compiler expected to find an opcode there.

Possible solutions: edit the mentioned command, probably it’s misprinted.


Incorrect expression

Sanny Builder Error Messages

Incorrect expression

This error message is given, if you use a math expression without specifying an opcode, and the operands types are incompatible. The operands incompatibility is possible when you:

a) declared a variable of a type using VAR..END, but in fact used this variable with another type;
b) both of the variables weren’t declared through the VAR..END;
c) one of the expression operands is impossible. For example, you used a number as the left operand of an assignment statement. (5=6).

Possible solutions: check correctness of this math expression. Choose a solution depending on the kind of error:

a) re-declare the variable with needed type;
b) declare both variables, using VAR..END;
c) fix an expression using possible values.


Out of memory

Sanny Builder Error Messages

Out of memory

This error message occurs if the number of used labels in the file exceeds 65536.

Possible solutions: decompiling is impossible


Thread not found

Sanny Builder Error Messages

Thread not found

This error occurs when the decompiler can’t find the beginning of the mission or external script where the header defines them. More often, it happens when the script.img is used, internal offsets of which is turned out to be different from those written in the main.scm header.

Possible solutions: toggle debug option ignore_unknown via console.


Variable with unknown type

Sanny Builder Error Messages

Variable with unknown type

If the compiler can’t recognize the type of a variable. In most cases, it happens as the variable is not declared, or declared with another type.

Possible solutions: set the correct variable type name.


Could not get size of array

Sanny Builder Error Messages

Could not get size of array

This error message is displayed as you did not specify the array size at declaring it in the VAR..END construct, or wrote an incorrect value (for example, a string instead of a number).

Possible solutions: use the correct integer value


Unknown array type

Sanny Builder Error Messages

Unknown array type

This error message is displayed as you did not specify the array type, or wrote an incorrect value (for example, a number).

Possible solutions: use the acceptable value in accordance with this topic.


Variable is not declared as array

Sanny Builder Error Messages

Variable is not declared as array

You’re using the short array notation, but the array was not declared.

Possible solutions: declare an array of certain type and size using VAR..END.


Incorrect variable name

Sanny Builder Error Messages

Incorrect variable name

This error is given when you use a non-numeric value to name the local string variables (@s, s$)

Possible solutions: use correct integer number taking into account the local variables limitation of San Andreas.


Loop counter should be a variable

Sanny Builder Error Messages

Loop counter should be a variable

This message is displayed when a loop counter isn’t a variable, or it isn’t specified at all.

Possible solutions: use variable as the counter of the loop iterations.


Unexpected instruction

Sanny Builder Error Messages

Unexpected instruction

It’s a common error message displayed at incorrect syntax of the constructs FOR..END or VAR..END.

Possible solutions: consult with these topics to write the constructs correctly.


Integer value expected

Sanny Builder Error Messages

Integer value expected

It’s a common error message displayed when the compiler expected integer value (for example in an aDMA variable name), but found something different (a floating-point value, for example).

Possible solutions: consult with the help to write the acceptable value.


Incorrect counter range

Sanny Builder Error Messages

Incorrect counter range

You used incorrect values for a loop iterations counter. They are being considered as so, if

a) at a FOR..to construct – if the initial counter value is greater than the final one.
b) at a FOR..downto construct – if the final value is greater than the initial one.

Possible solutions: consult with this topic and set the correct values.


Could not get a float parameter

Sanny Builder Error Messages

Could not get a float parameter

This error message is displayed when you used an unacceptable floating-point number, for example with too high mantissa.

Possible solutions: use acceptable value


String too long

Sanny Builder Error Messages

String too long

The strings have certain limits of its length for each string type, so this error message is displayed if the limit is exceeded.

Possible solutions: either cut down the string to make it satisfy the limits, or use another string type (“…” instead of ‘…’).


Unterminated string

Sanny Builder Error Messages

Unterminated string

This error message occurs, as the compiler is unable to find the end of the string. The strings must be denoted by both opening and closing quotation marks (double or single, depending on the string type).

Possible solutions: fix a mentioned string


Could not recognize a debug script ID

Sanny Builder Error Messages

Could not recognize a debug script ID

This error message is given as the compiler can’t recognize the parameter of special opcode 05B6 which is compiler in-built. This opcode defines a number of debug string used by Rockstar Games in their San Andreas scripts. These strings are used only in order to produce the SCM files similarly to original files.

Possible solutions: use acceptable integer number, or remove this opcode at all.


The definition of amount expected

Sanny Builder Error Messages

The definition of amount expected

This error message is given if the compiler expected to find a definition of either missions or external scripts amount but did not find it. In most cases, it happens due to incorrect number of elements of the previous header segment of the main.scm.

Possible solutions: check if every header segment has correct number of defined elements.


Couldn't define amount

Sanny Builder Error Messages

Couldn't define amount

This error message occurs when either the compiler can’t recognize a number of objects, missions or external scripts, or the number is unacceptable.

Possible solutions: check the correctness of defined amount of elements in the given header segment.


Couldn't recognize value

Sanny Builder Error Messages

Couldn't recognize value

This error message is displayed if the compiler was unable to recognize the value of the forth (UNKNOWN_EMPTY_SEGMENT) or the fifth (UNKNOWN_THREADS_MEMORY) segment of the main.scm.

Possible solutions: set the acceptable integer number for this segment.


Couldn't get a local variable

Sanny Builder Error Messages

Couldn't get a local variable

This error message occurs if the compiler was unable to recognize the number of a local varaible being its name. It happens when you did not use an integer number, but, for example, a string or a floating-point value.

Possible solutions: set the correct number for a local variable name.


Local variable is out of range

Sanny Builder Error Messages

Local variable is out of range

This warning message is shown when you use a number for a local varaible name that exceeds the limit for the threads of this game.

Possible solutions: use acceptable integer number in accordance with the local variables limits, or turn off the ranges check via options.


The definition expected

Sanny Builder Error Messages

The definition expected

This error happens when the compiler expected to meet the certain element of the header, but obtained identifier does not appear to be it.

Possible solutions: check the correctness of the obtained element.


Local variable of a mission is out of range

Sanny Builder Error Messages

Local variable of a mission is out of range

This warning message is shown when you use a number for a local varaible name that exceeds the limit for the missions of this game.

Possible solutions: use acceptable integer number in accordance with the local variables limits, or turn off the ranges check via options.


Debug script not found

Sanny Builder Error Messages

Debug script not found

This error message is displayed when the compiler found the special opcode 05B6 with parameter being greater than the file debug.bin allows. This file contains the debug strings of 128-bytes in length used by Rockstar Games. These strings are used only in order to produce the SCM files similarly to original files.

Possible solutions: use an integer number being less than maximum allowed value of 211.


Unknown data type of array

Sanny Builder Error Messages

Unknown data type of array

This error message is given when you used an array type, being unknown to the compiler. The number of allowed array types is strictly limited.

Possible solutions: consult with the given help topic and use the acceptable type.


Couldn't recognize segment element

Sanny Builder Error Messages

Couldn't recognize segment element

This error occurs when the compiler can’t recognize one of the elements either of a mission segment or an external scripts segment: mission or script label, number of mission. It may happen if you used a string when an integer number is expected.

Possible solutions: use a correct element value.


Constant name or value not found

Sanny Builder Error Messages

Constant name or value not found

It happens if you did not specify the constant name or its value in the CONST..END construct.

Possible solutions: consult with the given help topic to assign a constant correctly.


Incorrect mission id

Sanny Builder Error Messages

Incorrect mission id

This error message occurs when a mission number is less than zero, or it exceeds the total missions’ number.

Possible solutions: correct the mentioned number to set an acceptable one.


External script already defined

Sanny Builder Error Messages

External script already defined

This error message is displayed when you used the same name for several external scripts. This is unacceptable.

Possible solutions: use different names for each external script.


Неверное имя индексной переменной массива

Sanny Builder Error Messages

Incorrect index name of an array

This error message occurs when you did not use a variable as an array index but instead used something else (for example, a number). There are the indexed variables for this purpose.

Possible solutions: use a global or a local variable containing an array index.


Incorrect array name

Sanny Builder Error Messages

Incorrect array name

This error message occurs when the compiler expected to find a variable for a name but failed.

Possible solutions: use a global or a local variable for an array name.


Identifier not found

Sanny Builder Error Messages

Identifier not found

This error happens when the compiler failed to find an array name or a variable containing its index.

Possible solutions: write the proper identifier.


String variable can not be used

Sanny Builder Error Messages

String variable can not be used

This error happens when you used a string variable (@s, s$) for an array name or its index.

Possible solutions: use a common global or local variable ($, @).


Array size can not be less than 1

Sanny Builder Error Messages

Array size can not be less than 1

This error message is displayed as you set an array size to zero or a negative number that is unacceptable.

Possible solutions: use correct positive number.


Couldn't get size of array

Sanny Builder Error Messages

Couldn't get size of array

This error happened due to you did not specify an array size, or specified an unacceptable value (for example, a string).

Possible solutions: use correct positive number.


Not enough actual parameters

Sanny Builder Error Messages

Not enough actual parameters

The compiler expected to find certain number of parameters but failed. Either the line may have parameters less than expected, or some of them are unacceptable. The expected number of parameters is set in the INI file and can be displayed in the status bar at the option Show opcode info being turned on.

Possible solutions: write the required number of parameters.


Not enough actual parameters

Sanny Builder Error Messages

Not enough actual parameters

This error occurs as the compiler failed to get needed number of parameters either for an additional command or directive. Either there are parameters less than needed, or some of them are unacceptable. You may know needed number of parameters at the proper help topic, and in the hint shown after Ctrl+Shift+Space are pressed.

Possible solutions: write the required number of parameters.


Couldn't write the IMG header

Sanny Builder Error Messages

Couldn't write the IMG header

This error is displayed if there is a failure during the compiling of the script.img header.

Possible solutions: try to recompile the script. If the error happens again, turn to the developers.


Couldn't write the IMG file

Sanny Builder Error Messages

Couldn't write the IMG file

This error is displayed if there is a failure during the compiling of the script.img content.

Possible solutions: make sure your hard drive has free space enough, and the file script.img can be rewritten.


Recursive include file

Sanny Builder Error Messages

Recursive include file

The $INCLUDE directive has been used to recursively include another file.

Possible solutions: make sure that all include files terminate without having cycles in them.


Label not found

Sanny Builder Error Messages

Label not found

This error message occurs as the compiler can’t find the mentioned label anywhere in a script.

Possible solutions: make sure you specify the existed label name (probably it’s mistyped), or put a label in the proper place.


Identifier not found

Sanny Builder Error Messages

Identifier not found

It’s a common error message displayed when the compiler can’t recognize the actual identifier (name of a variable, a constant value, etc) as it’s missed or has illegal length.

Possible solutions: write the correct identifier.


Label redeclared

Sanny Builder Error Messages

Label redeclared

This error message is given, if the script contains a few labels named the same, so the compiler can’t recognize which of them you are referring to.

Possible solutions: use a unique name for each label.


Couldn't complete jump to label. Internal label not found

Sanny Builder Error Messages

Couldn't complete jump to label. Internal label not found

This error message is displayed as one of the high-level statements (if..then..else..end, while..end, etc) has incorrect syntax. In most cases, it happens when you did not write a closing ‘end’ at the end of a statement.

Possible solutions: consult with the help and check out the correctness of every statement.


Illegal parameter

Sanny Builder Error Messages

Illegal parameter

The common error message displayed when you specify an illegal parameter. For example, it occurs, if you use a number as a result of the functions Sqr or Random, while the compiler expects to find a variable there.

Possible solutions: consult with the help and write an accessible parameter.


Incorrect number of parameters in a file

Sanny Builder Error Messages

Incorrect number of parameters in a file

This error message is given if the program found an incorrect parameters number while loading an INI file.

Possible solutions: update the INI file.


No source

Sanny Builder Error Messages

No source

This error may happen if the source file window was closed during the compiling process. Normally, it is impossible.

Possible solutions: re-open a source file and re-compile.


Empty source

Sanny Builder Error Messages

Empty source

This error may happen if you tried to compile an empty file. Normally, it is impossible.

Possible solutions: open a source file and re-compile.


IDE file not found

Sanny Builder Error Messages

IDE file not found

If the program failed to load a required IDE file in the game folder ‘data’, this message is displayed. The error may occur, for example, if the file default.dat (SA) contains a link to a non-existent IDE file.

Possible solutions: check out the existence of the mentioned file.


Ожидалась метка миссии

Sanny Builder Error Messages

Mission label expected

This error message occurs if the compiler found a mission label, which must not be placed there according to the file header. It may also happen if you insert an external script between the missions. The external scripts must follow all missions.

Possible solutions: check out if the mission’s layout in a source file corresponds to their declaration order in the header. One of the missions breaks that order.


Mission label not found

Sanny Builder Error Messages

Mission label not found

This error message is displayed, as the compiler can’t find a beginning of one of the declared mission.

Possible solutions: check if every mission declared in the header is present in a source file. Add the missed mission, or remove its declaration.


External script label not found

Sanny Builder Error Messages

External script label not found

This error message is displayed, as the compiler can’t find a beginning of one of the declared external scripts.

Possible solutions: check if every script declared in the header is present in a source file. Add the missed script, or remove its declaration.


Illegal char in the external script name

Sanny Builder Error Messages

Illegal char in the external script name

You are using an illegal character in the external script’s name. Allowable characters are digits, Latin letters and underscores.

Possible solutions: correct the name in accordance with the requirements.


Illegal char in the identifier

Sanny Builder Error Messages

Illegal char in the identifier

It’s a common error displaying if you use an illegal character in an identifier (variable name, label, etc). Allowable characters are digits, Latin letters and underscores.

Possible solutions: correct the name in accordance with the requirements.


Illegal char in the object name

Sanny Builder Error Messages

Illegal char in the object name

It’s a common error displaying if you use an illegal character in an object name. Allowable characters are digits, Latin letters and underscores.

Possible solutions: correct the object name in accordance with the requirements.


Incorrect number of the conditions

Sanny Builder Error Messages

Incorrect number of the conditions

This error message is displayed if you checked a number of conditions which is higher than maximum. The maximum number of conditions to be checked at once is 9.

Possible solutions: correct the number of conditions in accordance with the requirements.


Incorrect number of the conditions

Sanny Builder Error Messages

Incorrect number of the conditions

This error occurs in the IF..END statement, when you used several conditions at once without specifying a mode of checking: AND or OR.

Possible solutions: correct this statement: either use the only condition, or write the word AND or OR.


Incorrect number of the conditions

Sanny Builder Error Messages

Incorrect number of the conditions

This error message is displayed when you used only one condition in the IF..END statement but for all that there is a word AND or OR. These words are only acceptable in a case of checking the several conditions at same time.

Possible solutions: correct this statement: either use several conditions, or remove the word AND or OR.


Enable "Conditions check" option to use this feature

Sanny Builder Error Messages

Enable "Conditions check" option to use this feature

This error message occurs if you used an IF statement with words AND or OR with the option Conditions check being disabled. This compiler feature can work only when this option is enabled.

Possible solutions: turn on the option Condition check via options (F10).


Incorrect hexadimal value

Sanny Builder Error Messages

Incorrect hexadimal value

This error message occurs in a HEX..END statement if you used a non-hexadimal symbol. The hexadimal symbols are Latin letters from A to F, and digits (0..9).

Possible solutions: correct the mentioned value


Сondition expected

Sanny Builder Error Messages

Сondition expected

It’s a common error displayed if you did not specify a condition to check after words while or until. These constructs require at least one condition. You may use pre-defined constants True or False as a fake condition.

Possible solutions: write a condition to check


Only global variables can be allocated

Sanny Builder Error Messages

Only global variables can be allocated

This error message is given if you did not use a global variable in a command Alloc. This command only accepts a global variable as parameter.

Possible solutions: use a global variable


Use positive integer value

Sanny Builder Error Messages

Use positive integer value

It’s a common error occurred when you used a negative number or not a number at all (for example, a string) where the compiler expected to find a positive integer number (indexed variables, Alloc, etc).

Possible solutions: use acceptable positive integer number


Too many actual parameters

Sanny Builder Error Messages

Too many actual parameters

It is a common error occurred if you used more parameters than the current command required (for example, Sqr).

Possible solutions: consult with the help topics, and write the needed number of parameters.


Incorrect statement

Sanny Builder Error Messages

Incorrect statement

This error is displayed when the compiler has found a statement, which is not contained inside a major construct. For example, it happens, if you wrote a word ELSE outside of an IF..END construct.

Possible solutions: consult with the help topics, and write an acceptable construct.


Model name can not be used

Sanny Builder Error Messages

Model name can not be used

This error is happened when you try to use a model name in an SCM file without header, and the compiler does not know what numeric ID this model has. Most often this happens when you compile a CLEO script with a model name that was defined in the original main.scm in the DEFINE OBJECT list (for example, #KEYCARD). These #names unlike those ones defined in the vehicles.ide, peds.ide default.ide can not be compiled.

The most notably effect of this error is that in the game you will see an INFO pickup (#INFO) instead of expected model.

Possible solutions: use a numeric identifier (ID) instead of the model name. For example, for the #KEYCARD ID = 1581. You may find out needed ID in the game IDE files. Also you can use a a SB built-in function of converting the models names to their ID and vice versa (Ctrl+Alt+H).


A jump to zero offset found

Sanny Builder Error Messages

A jump to zero offset found

This error message occurs when your CLEO script has a jump to label placed right in the beginning of the script. The game has a relating bug that makes such jump cause an incorrect script’s work. The effect of this bug is that the game is reloaded (a new game is started again and again).

Possible solutions: add opcode 0000 in the beginning of the script (before any labels). It will be enough.

See also: http://www.gtaforums.com/index.php?showtopic=211077&st=380&#entry4492136


Sanny Builder

Only local variables can be used as array indexes in LCS and VCS modes

The script engine of Liberty City Stories and Vice City Stories games only allows local variables to be array indexes. The following code will throw an error: $array($index,1).

Possible solutions: replace the global variable with a local variable: $array(0@,1)


Sanny Builder

The aDMA variable can only be a multiple of 4 in LCS and VCS modes

The data type system of Liberty City Stories and Vice City Stories games limits addressing var space to offsets that are multiples of 4.

Possible solutions: change the ADMA variable to be a multiple of 4: e.g. &0, &4, &8, etc.


Sanny Builder

Global variable is out of range.

Starting from v3.3.0 Sanny Builder checks if global variables with numeric names are in the allowed range that varies from game to game. Commonly you can use any variable in range $2 to $3FFF, in LCS the maximum variable is $6655, in VCS it is $6399.

Possible solutions: change the number in the global variable name to be a positive integer value in the allowed range for the selected game. Alternatively you may disable the option "Ranges check" in the main options.