spaceeinstein Posted November 30, 2008 Share Posted November 30, 2008 (edited) A Guide to Understanding the Basics of Coding (My interpretations) See final notes for more useful links. This is going to sync with the articles in GTAModding. Note that starting a new game is a requirement. With the advent of CLEO, you can insert scripts and missions without the need to start a new game, but the basic concepts of coding it remains the same. Opcodes Sanny Builder has the latest compiled list of opcodes. It is located in the program's Opcode Search Tool feature. These opcodes have many, many functions so it's best to look through the entire list to get the feel of what is available to you. You can do so much with scripting with what you have already. To understand how each opcode does, either look at documentations of them littered throughout the web or test the opcodes yourself through trial and error. This is the best way to learn how to use opcodes. You can check the game's original script (main.scm) and see how the developers use the opcodes in their scripts. Create a Script Creating a simple script is one of the first steps in understanding how to code. This article will show you the basic steps on how to create the simplest script using Sanny Builder. It should work for GTA III, Vice City, and San Andreas. Start your script Prior to the advent of CLEO, this section was one of the first steps in understanding how to create scripts. First make sure you are working with a decompiled main.scm file. If you don't have a decompiled file, go to Sanny Builder and press F5. Find and open the main.scm file for decompiling. The program will create the main.txt file in the same directory. That is the file you will be working with. Now we need a command to start your first script by using opcode 004F (or create_thread command). Find: create_thread Insert before it 004F: create_thread @simple_script simple_script is an arbitrary but unique name for a label. It helps the game locate your script. Insert your code Next create your script by inserting it in the appropriate place. Find: //-------------Mission 0--------------- That is where the MAIN section ends and the first mission begins. Insert your script between it. The simplest scripts have this format: :simple_script // Insert your code here 004E: end_thread Your script can include a series of opcodes like creating a ped and creating a vehicle. Loops The example above shows you a script that ends immediately. If you want your script to run continuously, you have insert a loop. For most cases, looping requires opcode 0001 (or wait command) to be placed somewhere within the loop or else the game will crash. There are exceptions but it is safer to have it. The simplest loop has this format: :simple_script while true 0001: wait 0 ms // Insert your code here end This script will repeat itself indefinitely so be careful what you put in it. Conditions Conditional opcodes are used to check whether the action is performed rather than to perform the action. If the condition is satisfied, it returns true, otherwise it returns false. In Sanny Builder, conditional opcodes are noted by spaces between the opcode and the description of the opcode. Conditions start with IF statements that checks if an action is performed. :simple_script while true 0001: wait 100 ms if // Conditional opcode, e.g. 00E1: player 0 pressed_key 13 then // Command if the condition returns true, e.g. if the key is being pressed, then add $2000 0109: player $PLAYER_CHAR money += 2000 else // Command if the condition returns false, e.g. if the key is not being pressed, then subtract $10 0109: player $PLAYER_CHAR money += -10 end end For IF statements with more than one conditions, you need to either add and or or after if. if and means if all of the conditions are met, then perform the command. // ... if and 00E1: player 0 pressed_key 4 // first condition 00E1: player 0 pressed_key 19 // second condition then // command end // ... This shows that if all conditions (if both keys 4 and 19 are pressed in this example) are met, the command will be performed. Otherwise, the code will skip the command and continue onwards. if or means if any one of these conditions are met, then perform the command. // ... if or 00E1: player 0 pressed_key 4 // first condition 00E1: player 0 pressed_key 19 // second condition then // command end // ... This shows that if either condition (if either key 4 or key 19 is pressed in this example) is met, the command will be performed. Otherwise, the code will skip the command and continue onwards. Opcodes normally starts with the number 0, but conditional opcodes can start with the number 8. This checks if the condition is not performed. 00E1: player 0 pressed_key 4 // IS pressed 80E1: not player 0 pressed_key 4 // is NOT pressed Final Notes Using this format requires you to start a new game. If you do not understand what is being said here, try looking into the Mission Coding Forum on how to understand this. A more in-depth look into how the script works is located here. Create a Mission Creating a mission is tough. The style is no different than creating a script so it is recommended that you start practicing with simple scripts and work your way up instead of attempting to create a mission right away. There are many ways to create a mission so to simplify this for beginners, the rest of the article will show the basic structure of creating a working mission. The format uses Sanny Builder. It should work for GTA III, Vice City, and San Andreas. Define your mission First define your mission. Find: DEFINE MISSIONS Increment that number by one. Scroll down until you see the last defined mission. Define your mission below it. DEFINE MISSION {xxx} AT @simple_mission where {xxx} is the mission index, one more from the previous mission. Insert your trigger Next create a script that will trigger your mission to start. Find: create_thread Insert before it 004F: create_thread @mission_trigger Find //-------------Mission 0--------------- That is where the MAIN section ends and the first mission begins. Insert your trigger code between that: :mission_trigger while true 0001: wait 0 if 0256: player $PLAYER_CHAR defined then if $ONMISSION == 0 then if // Condition to start your mission then 0417: start_mission {xxx} $ONMISSION = 1 end end end end where {xxx} is your mission index or the label of your mission. Insert your mission Lastly insert your mission. If you are using GTA III or Vice City, scroll all the way to the end of the file to insert your mission. If you are using San Andreas, find: //-------------External script 0 (PLAYER_PARACHUTE)--------------- That is where the last mission ends and the first external script starts. Insert your mission between that. :simple_mission 03A4: name_thread 'MISSA' 0050: gosub @simple_mission_begin if 0112: wasted_or_busted then 0050: gosub @simple_mission_failed end 0050: gosub @simple_mission_cleanup 004E: end_thread :simple_mission_begin // Place the contents of your mission 0051: return :simple_mission_failed // Died or got busted during your mission 0051: return :simple_mission_cleanup // Clean up the contents of your mission so you can end it $ONMISSION = 0 00D8: mission_cleanup 0051: return Final note Following this tutorial requires you to start a new game. CLEO is a newer and better way to insert scripts and missions into the game. If you do not understand what is being said here, try laboriously searching through the Mission Coding forum for more information. GTAModding Article If there are any errors, misunderstandings, or suggestions, post here. Edited June 16, 2018 by spaceeinstein Link to comment Share on other sites More sharing options...
spaceeinstein Posted December 11, 2008 Author Share Posted December 11, 2008 (edited) The first step is to create simple scripts. This tutorial is intended for those who already know how to make simple scripts. I'll try to make a tutorial on that later on. This is a tutorial though, I'll be only showing the basics of what you need to know so you can build on top of that. Since this thread is here, I'll post links that can help putting contents into the threads/missions. Coding Bible I Coding Bible II Too bad he didn't come back. He was on a roll with all those tutorials. Edited December 11, 2008 by spaceeinstein Link to comment Share on other sites More sharing options...
spaceeinstein Posted December 23, 2008 Author Share Posted December 23, 2008 I can't give examples to every opcodes that is available in the game. It's best for you to search for them and copy what they did or do trial and error. There are already successful mission scripts out there in the web and usually the user-made scripts are simpler to understand. My GTA2 Missions mod has the basic stuff for a working mission. I've updated the first post with more contents. Link to comment Share on other sites More sharing options...
grim666 Posted December 24, 2008 Share Posted December 24, 2008 i don't know where to put this but does anyone know how to put the wall climbing sa script in a cleo file? i just complains that i don't have label 1 (using sanny builder) Link to comment Share on other sites More sharing options...
ThaGTAGamer Posted April 5, 2009 Share Posted April 5, 2009 Yo, thanks for tutorial, it is great, but, I don't understand so much in coding.. you know... This helps ,e just a little bit. Link to comment Share on other sites More sharing options...
ali amroo Posted April 6, 2010 Share Posted April 6, 2010 thank you for this tutorial but is complicated. ------------ ali amroo Link to comment Share on other sites More sharing options...
Udra Posted May 27, 2010 Share Posted May 27, 2010 Thanks for the info :] Link to comment Share on other sites More sharing options...
Rameez_Iqbal Posted October 20, 2012 Share Posted October 20, 2012 How to edit cheat codes????? Link to comment Share on other sites More sharing options...
𝓦𝓸𝓵𝓯 Posted March 4, 2018 Share Posted March 4, 2018 thank you so much Link to comment Share on other sites More sharing options...
KszychU Posted August 22, 2020 Share Posted August 22, 2020 (edited) Hello there. I'm studying main.scm of Vice City and I can't understand one thing. When we have cell phone conversations code, between displaying texts there is something strange. I mean CELL_15595() for example. It's occurs in many variants and not only refer to cell phone conversations because it also applies for cutscenes or ammunation stores. My experience with C# tell me that it's functions (my guess by brackets) but where is the body of them? Maybe am i wrong? Please someone explain this to me! Example pieces of code in main.scm: ... :CELL_568 if $1156 == 0 // $ == int else_jump @CELL_1005 03E5: text_box 'ANSWER' // Press the ~h~~k~~PED_ANSWER_PHONE~~w~ to answer your cell phone. CELL_15111() if $1179 == 1 // $ == int else_jump @CELL_966 $1177 = 1 // $ = int 03CF: load_wav 'MOB_52A' as $1177 CELL_15595() 00BC: text_highpriority 'MOB52_A' time 10000 1 // Hey Leo, I think we got a buyer for Diaz's merchandise. CELL_15747() 03CF: load_wav 'MOB_52B' as $1177 CELL_15595() 00BC: text_highpriority 'MOB52_B' time 10000 1 // You gotta give him a ring, man, set up the deal, you know? CELL_15747() 03CF: load_wav 'MOB_52C' as $1177 CELL_15595() 00BC: text_highpriority 'MOB52_C' time 10000 1 // Where are you now? CELL_15747() 03CF: load_wav 'MOB_52D' as $1177 CELL_15595() 00BC: text_highpriority 'MOB52_D' time 10000 1 // You ok Leo? You sound kinda different. CELL_15747() 03CF: load_wav 'MOB_52E' as $1177 CELL_15595() 00BC: text_highpriority 'MOB52_E' time 10000 1 // Just tell me where you are. CELL_15747() 03CF: load_wav 'MOB_52F' as $1177 CELL_15595() 00BC: text_highpriority 'MOB52_F' time 10000 1 // Who the hell is this? Put Leo on, man! CELL_15747() 03CF: load_wav 'MOB_52G' as $1177 CELL_15595() 00BC: text_highpriority 'MOB52_G' time 10000 1 // Leo's gone away for a while, he left me in charge. CELL_15747() 03CF: load_wav 'MOB_52H' as $1177 CELL_15595() 00BC: text_highpriority 'MOB52_H' time 10000 1 // Screw you, man! CELL_15747() 00BE: text_clear_all :CELL_966 ... ... :INTRO_295 if or 823D: not special_actor 1 loaded 823D: not special_actor 2 loaded 823D: not special_actor 3 loaded 823D: not special_actor 4 loaded 823D: not special_actor 5 loaded else_jump @INTRO_369 wait 0 INTRO_14443() if $13 == 2 // $ == int else_jump @INTRO_362 jump @INTRO_11542 :INTRO_362 jump @INTRO_295 :INTRO_369 if or not Model.Available(#CUTOBJ01) not Model.Available(#CUTOBJ02) not Model.Available(#CUTOBJ03) not Model.Available(#CUTOBJ04) else_jump @INTRO_443 wait 0 INTRO_14443() if $13 == 2 // $ == int else_jump @INTRO_436 jump @INTRO_11542 ... Edited August 23, 2020 by KszychU spelling error Link to comment Share on other sites More sharing options...
KszychU Posted August 23, 2020 Share Posted August 23, 2020 (edited) Oh God. I found this. These are functions exactly as i thought. We can show up the list of functions by pressing CTRL + SPACE BAR. The body of CELL_15595() is declared by :CELL_15595 :CELL_15595 if 83D0: not wav $1177 loaded jf @CELL_15740 wait 0 if not Player.Defined($PLAYER_CHAR) jf @CELL_15647 $1179 = 2 // $ = int return jump @CELL_15733 Could someone tell me why after "return" is "jump @CELL_15733". Is RETURN moving back cursor to place where function was called? Is the "jump" useless in this case? Edited August 23, 2020 by KszychU minor mistake Link to comment Share on other sites More sharing options...
ZAZ Posted August 30, 2020 Share Posted August 30, 2020 (edited) On 8/22/2020 at 10:15 PM, KszychU said: Hello there. I'm studying main.scm of Vice City and I can't understand one thing. When we have cell phone conversations code, between displaying texts there is something strange. I mean CELL_15595() for example. It's occurs in many variants and not only refer to cell phone conversations because it also applies for cutscenes or ammunation stores. My experience with C# tell me that it's functions (my guess by brackets) but where is the body of them? Maybe am i wrong? Please someone explain this to me! Example pieces of code in main.scm: Spoiler ... :CELL_568 if $1156 == 0 // $ == int else_jump @CELL_1005 03E5: text_box 'ANSWER' // Press the ~h~~k~~PED_ANSWER_PHONE~~w~ to answer your cell phone. CELL_15111() if $1179 == 1 // $ == int else_jump @CELL_966 $1177 = 1 // $ = int 03CF: load_wav 'MOB_52A' as $1177 CELL_15595() 00BC: text_highpriority 'MOB52_A' time 10000 1 // Hey Leo, I think we got a buyer for Diaz's merchandise. CELL_15747() 03CF: load_wav 'MOB_52B' as $1177 CELL_15595() 00BC: text_highpriority 'MOB52_B' time 10000 1 // You gotta give him a ring, man, set up the deal, you know? CELL_15747() 03CF: load_wav 'MOB_52C' as $1177 CELL_15595() 00BC: text_highpriority 'MOB52_C' time 10000 1 // Where are you now? CELL_15747() 03CF: load_wav 'MOB_52D' as $1177 CELL_15595() 00BC: text_highpriority 'MOB52_D' time 10000 1 // You ok Leo? You sound kinda different. CELL_15747() 03CF: load_wav 'MOB_52E' as $1177 CELL_15595() 00BC: text_highpriority 'MOB52_E' time 10000 1 // Just tell me where you are. CELL_15747() 03CF: load_wav 'MOB_52F' as $1177 CELL_15595() 00BC: text_highpriority 'MOB52_F' time 10000 1 // Who the hell is this? Put Leo on, man! CELL_15747() 03CF: load_wav 'MOB_52G' as $1177 CELL_15595() 00BC: text_highpriority 'MOB52_G' time 10000 1 // Leo's gone away for a while, he left me in charge. CELL_15747() 03CF: load_wav 'MOB_52H' as $1177 CELL_15595() 00BC: text_highpriority 'MOB52_H' time 10000 1 // Screw you, man! CELL_15747() 00BE: text_clear_all :CELL_966 ... ... :INTRO_295 if or 823D: not special_actor 1 loaded 823D: not special_actor 2 loaded 823D: not special_actor 3 loaded 823D: not special_actor 4 loaded 823D: not special_actor 5 loaded else_jump @INTRO_369 wait 0 INTRO_14443() if $13 == 2 // $ == int else_jump @INTRO_362 jump @INTRO_11542 :INTRO_362 jump @INTRO_295 :INTRO_369 if or not Model.Available(#CUTOBJ01) not Model.Available(#CUTOBJ02) not Model.Available(#CUTOBJ03) not Model.Available(#CUTOBJ04) else_jump @INTRO_443 wait 0 INTRO_14443() if $13 == 2 // $ == int else_jump @INTRO_436 jump @INTRO_11542 ... It's new syntax for gosub command of sannybuilder 3.4.0 (meanwhile 3.5.1) When decompiling "without opcodes" (check tickbox at options) then 0050: gosub @CELL_15595 will be written in that way: CELL_15595() On 8/23/2020 at 6:28 PM, KszychU said: Oh God. I found this. These are functions exactly as i thought. We can show up the list of functions by pressing CTRL + SPACE BAR. The body of CELL_15595() is declared by :CELL_15595 :CELL_15595 if 83D0: not wav $1177 loaded jf @CELL_15740 wait 0 if not Player.Defined($PLAYER_CHAR) jf @CELL_15647 $1179 = 2 // $ = int return jump @CELL_15733 Could someone tell me why after "return" is "jump @CELL_15733". Is RETURN moving back cursor to place where function was called? Is the "jump" useless in this case? Yes, "jump" is useless in this case, it's a leftover from script author Let's say, later the author decided to exclude several code blocks from script and make it as "subscript" gosub @subscript ...... :subscript <code> return and maybe he thought to keep the jump, because maybe he will change it back READ HERE MORE ABOUT MAIN.SCM MODDING Edited August 31, 2020 by ZAZ KszychU and RyanDri3957V 2 CLEO MODS CLEO Script Tutorial Link to comment Share on other sites More sharing options...
cl55684 Posted September 27, 2020 Share Posted September 27, 2020 How to add deleted impound mission to the game used by ttdisa source? Link to comment Share on other sites More sharing options...
ZAZ Posted September 27, 2020 Share Posted September 27, 2020 impound script is still available in ttdisa main.scm CLEO MODS CLEO Script Tutorial Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now