Jump to content

Mission Coding for Pro's!


Recommended Posts



Mission Coding for Pro's!


By PatrickW and Dutchy3010


This topic is a continuation of the Mission Coding for Dummies tutorial. We will explain the more advanced parts of SCM Coding. In this tutorial, you won't find how to create actors, or how to make a text ingame. In this tutorial, you will find advanced things, like how to write readable code and how to use the SCMLOG Cleo extension. So if you can't make an easy mission, or haven't coded at all, then you should start with the other topic (Mission coding for dummies). This topic is, just like the Mission Coding for Dummies tutorial, in continual update. SCM Coding is very wide, you can do all sort of things with it. That's why we are able to make many tutorials about it.


For this tutorials you need:

  • SannyBuilder (Download)
  • Grand Theft Auto: San Andreas
  • Experience in SCM Coding
Content:Links:The reactiontopic is the same as the one for Mission Coding for Dummies. You can ask questions about the content of this tutorial, but you can also suggest new subjects for tutorials. Edited by Dutchy3010
Link to comment
Share on other sites


The commandments of readable code.

The SCM en CLEO coding style-guide


user posted image


This guide asumes that you already know the concepts of SCM en CLEO programming and that you are able to write code that is understood by the compiler and that does what you want it to do. This guide presents you with a suloution to an additional challenge: Write code that people can understand.

How often have you looked at a piece of code that you wrote some time ago, and have difficulty to understand it again. How often have you tried to answer a question about a piece of code on the forums, but you have great difficulty to comprehend what the code is suppose to do in the first place.


The Commandments of SCM Coding

Thou shalt use Sannybuilder for thy SCM coding. Thou shalt use high-level constructs wherever possible.Thou shalt use object notation when available.Thou shalt not code without proper identation.Thou shalt comment thy code.Thou shalt minimize thy labels.Thou shalt declare thy variables.Thou shalt name thy locals.Thou shalt symbolize thy constants.Thou shalt not give thy identifyers meaningless names.Thou shalt describe the parameters of thy routines.



Thou shalt use Sannybuilder for thy SCM coding.

Although there are more tools available and everybody has their own reasons for using one or the other. But for readibility, sannybuilder offers the most support and many of the following commandments depend on these features.


Thou shalt use high-level constructs wherever possible.

The advantage of using these constructs is, that they immediatly reveal the structure of the code. Especially in combination with the next commandment, proper identation, this will reveal the overall structure of a piece of code at first glance.


Thou shalt use object notation when available.

The object notation that Sannybuilder provides, has a much more readable syntax than regular opcodes. Thus these should always be used where they are available as an alternative for normal opcodes.


Thou shalt not code without proper identation.

When code is properly idented, the structure becomes apparent immediatly. This is especially the case when using nested constructs, the identation will reveal where one constructs end, and where the other starts.


Thou shalt comment thy code.

Adding comments to your code offers you the option to state what each section of code is suppose to do, and how it contributes to the fuctionality ythat is implemented.


Thou shalt minimize thy labels.

Almost a direct result of the usage of high-level constructs, is the lack of need for using labels. Labels are especially cumbersome if you want to reuse a piece of code at another location in your file. Labels will conflict, and will have to be adapted. This also goes for all the references to the label, which might lead to some hard to find bugs if one is forgotten.


Thou shalt declare thy variables.

Using the VAR-END construct to declare the type of your variables has the advantage that it will enable you to use arithmetic and comparison commands without the need to prefix them with the numerical opcode. This will not onloy speed-up the coding, but will also make the code much more readable. Another advantage is that it gives you a central location where you van use comments to describe the meaning and usage of each variable.


Thou shalt name thy locals.

The usage of local variables has advantages in many cases, such as not taking up global memory space and is even mandatory for CLEO scripts. But the disadvantage is that using their numerical notation will deteriate the readibility, as the name bears no meaning. Therefor you should use the CONST-END construct to assign names to your locals, which will greatly improve the understandability of your code.


Thou shalt symbolize thy constants.

if you're using numerical or string constants in your code, it is adviseable to define them in a CONST-END construct, so that you can use the symbolic name in all places wehere the constant is used. This will not only better explain the mening of a specific constant value, but it is also very handy when after a while it turns out that a constant wasn;t that constant after all, and needs to be adapted. Now you can simply adapt the value at one position.


Thou shalt not give thy identifiers meaningless names.

A key method to improve the readibility of your code is to use meaningful names for all your identifiers: variables, constants and labels. The names of variables and constant should describe what they represent. If a label cannot be prevented, at least give it a name that accurately describes the functiuonality of the piece of code that follows.


Thou shalt describe the parameters of thy routines.

When defining Subroutines, not only add a comment that described the functionality, but also add comments with an exhaustive list of all variables that are used by the routine (input variables) and all variables that are adapted by the routine (output variables).





First we will show you an example of a code which is violating every commandment. After that, we will fix the code.



{$CLEO}:0003A4: name_thread "MODEL"0247: load_model #BFYST0247: load_model #rocketla0247: load_model #desert_eagle 0247: load_model #m4 038B: load_requested_models0002: jump @01:010001: wait 0 ms00D6: if or8248: not model #BFYST available8248: not model #rocketla available 8248: not model #desert_eagle available 8248: not model #m4 available 004D: jump_if_false @1010001: wait 0 ms0002: jump @01:1010001: wait 0 ms00D6: if 8256: not  player $PLAYER_CHAR defined 004D: jump_if_false @0100001: wait 200 ms0002: jump @101:010 0001: wait 0 ms009A: 10@ = create_actor_pedtype 5 model #BFYST at 2488.5601 -1680.84 13.3438 02E2: set_actor 10@ weapon_accuracy_to 90 0223: set_actor 10@ health_to 2000 01B2: give_actor $PLAYER_ACTOR weapon 24 ammo 3000001B2: give_actor 10@ weapon 31 ammo 300000350: toggle_actor 10@ maintain_position_when_attacked 1 05E2: AS_actor 10@ kill_actor $PLAYER_ACTOR 01B2: give_actor $PLAYER_ACTOR weapon 35 ammo 1001B9: set_actor $PLAYER_ACTOR armed_weapon_to 2401B9: set_actor 10@ armed_weapon_to 310002: jump @10:100001: wait 200 ms00D6: if 0118: actor 10@ dead 004D: jump_if_false @100002: jump @100:1000394: play_music 1 01E3: show_text_1number_styled GXT 'M_PASS' number 10000 time 5000 style 10109: player $PLAYER_CHAR money += 25000 0249: release_model #BFYST0249: release_model #rocketla0249: release_model #desert_eagle0249: release_model #m40A93: end_custom_thread



Fixed code:



{$CLEO}{ DEMO-SCRIPT by PatrickW and Dutchy3010 © 2009  This CLEO script executes as soon as a new game is started or a savefile is loaded. It spawns a woman with an M4 at Groove-street, who is determined to kill your player. To defend himself, tha player will receive a rocketlauncher and a desert_eagle. Killing the woman will be rewarded with $25000.  Note: This Script was created for the SCM and CLEO Coding Style Guide.  Feedback, please at <<< Topic URL >>>} :MODELthread "MODEL"Const // Mapping of local Variables ATTACKER=10@  // Id's used for weapon handling M4_ID=31 ROCKETLA_ID=35 DESERT_EAGLE_ID=24EndVar ATTACKER : Actor  // The Actor that needs to be killed to pass this missionEnd{ Load the required models.=================================================}model.Load(#BFYST)model.Load(#rocketla)model.Load(#desert_eagle)model.Load(#m4){                                                       Wait for the models to be available.=================================================}While True wait 0 ms if and    model.Available(#BFYST)   model.Available(#rocketla)   model.Available(#desert_eagle)   model.Available(#m4) jf Breakend{ Create Attacker, set properties and give her a M4.=================================================}ATTACKER = Actor.Create(CIVFEMALE, #BFYST, 2488.5601, -1680.84, 13.3438 )Actor.WeaponAccuracy(ATTACKER)= 90Actor.Health(ATTACKER) = 20000350: toggle_actor ATTACKER maintain_position_when_attacked 1 01B2: give_actor ATTACKER weapon M4_ID ammo 30000 01B9: set_actor ATTACKER armed_weapon_to M4_ID{ Wait for the player to be available.=================================================}repeat wait $DEFAULT_WAIT_TIME msuntil Player.Defined($PLAYER_CHAR)  { Give the player a desert-eagle and a rocketlauncher, and make the desert-eagle the active weapon.================================================}01B2: give_actor $PLAYER_ACTOR weapon ROCKETLA_ID ammo 10 01B2: give_actor $PLAYER_ACTOR weapon DESERT_EAGLE_ID ammo 3000001B9: set_actor $PLAYER_ACTOR armed_weapon_to DESERT_EAGLE_ID{Now order the attacker to attack the player and wait until the victim is killed. ================================================} 05E2: AS_actor ATTACKER kill_actor $PLAYER_ACTOR repeat wait $DEFAULT_WAIT_TIME ms until Actor.dead(ATTACKER)  {The Attacker is killed. The Mission is passed.================================================} 0394: play_music 1 01E3: show_text_1number_styled GXT 'M_PASS' number 10000 time 5000 style 1  // MISSION PASSED!~n~~w~$~1~Player.Money($PLAYER_CHAR) += 25000{Unload the loaded Models.================================================} model.Destroy(#BFYST)model.Destroy(#rocketla)model.Destroy(#desert_eagle)model.Destroy(#m4){Stop this CLEO-script.================================================}0A93: end_custom_thread



Of course this is a bit exaggerated for a short code like this, but when you make a large script, you will be thankful if you need to edit something afterwards, or need to show your code to somebody else to get some help.


This was the first tutorial in this topic about advanced scm coding. If you want to give any feedback, please go to our reaction topic.

Edited by PatrickW
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • 1 User Currently Viewing
    0 members, 0 Anonymous, 1 Guest

  • Create New...

Important Information

By using GTAForums.com, you agree to our Terms of Use and Privacy Policy.