Author Topic: [VC] Basic Mission Scripting Tutorial  (Read 14540 times)

0 Members and 1 Guest are viewing this topic.

Offline Dannye

  • Veteran Member
  • Posts: 3580
    • View Profile
[VC] Basic Mission Scripting Tutorial
« Reply #15 on: April 20, 2008, 04:24:27 PM »
I think this is it...  

Getting started

This is a guide to basic mission scripting. I'm no expert, but I've learnt a bit here and there about some of the basic principles when mission coding. A huge amount of people with a huge amount of talent have guided me (whether they knew it or not) in my coding, so tremendous thanks to them all. My coding is fairly primitive, but it works for the most part. Mission coding involves a lot of trial and error, a lot of game crashing, frustration and some improvisation. But it can get some great results if you have the patience to get what you want right.

To get started, you should do the following:

- Download Barton Waterducks Mission Builder (v0.22 is probably the best of the editor's in this    class)
- Make a backup copy of Vice City in your Rockstar Games directory, and use that as your mission    editing copy
- Make a backup copy of the data/main.scm in this copy of VC so that you have a default main to    go back to, should things go awry



Extract the Mission Builder to a created directory and use the VSETTINGS.EXE to tell the Mission Builder where your copy of VC is. Make sure your text/american.gxt is not altered to a great degree. Having the REPLAY text removed is okay, but the rest of the gxt tables should be complete. You should also take the time to read any and all help files that come with the Mission Builder to help give you a grounding in how it works.

Start the mission builder, and open your data/main.scm file. The script will decompile and you will be able to read the contents. Take a few minutes to peruse the script and familiarise yourself with it's structure. It will all appear somewhat daunting, but you'll certainly see a discernable structure within the script.

Upon decompiling of the mission script, the Mission Builder will have written the contents to a txt file which will be found in the data directory under the filename 'main.txt'. This is now what you will use to script your own stuff, rather than decompiling the actual script every time. You can open the script in Windows text editor also and make changes that way, but because changes require a re-compile of the script, it's easier to use the mission builder to edit. Recompiling of the script will write a new text file companion, while also creating the new main.scm, complete with whatever changes you've made.

NOTE **MANY CHANGES TO THE MISSION SCRIPT WILL REQUIRE A NEW GAME TO FUNCTION PROPERLY. ALTHOUGH THIS ISN'T ALWAYS THE CASE, IT'S ALWAYS BEST TO START A NEW GAME TO TEST YOUR CUSTOM CODES OR MISSION ALTERATIONS**

------------------------------------------------------------------------------------------------

Terms to familiarise yourself with

-MISSION SCRIPT

The mission script is the blueprint for the game. All missions and mission data are stored within the mission script (main.scm).


-OPCODE

An opcode is a line with the mission script designed to perform a designated function. Most opcodes cannot function properly without supporting code to verify it and/or designate it specific parameters within which to function. An example of an opcode is as follows:

Code: [Select]
0224: set_car  104?? health_to  2000&
If we break it down:

0224: (opcode call number - every opcode has one of these, and they are all exclusive to the particular opcode)
set_car (designates a nominated car as the target for the remainder of the code's functions)
104?? (integer value assigned to particular car/actor - in this case, a car)
health_to (directs health toward the integer's target car/actor)
2000& (health amount to be assigned to target, & is used as a global variable)

Essentially this opcode will assign 2000 health to the target vehicle, using the integer value to recognise the target vehicle. The code needs supporting opcodes to make it function correctly.


-THREAD

A thread is a series of opcodes strung together to perform a specific function, or series of functions. A thread can consist of a single group of opcodes, or several subthreads working together. Threads are basically a way of keeping code from conflicting, and making the code easy to reference when using jump instructions (see below). A simple thread can be like this:

Code: [Select]
004F: create_thread テつ」テつ」niceday

:niceday
0001: wait 0? ms
01B6: set_weather  0?
0002: jump テつ」テつ」niceday

The entire thread is separated above into the create_thread opcode, and the thread itself. Breaking down both:

004F: (call number)
create_thread (command used to let the script know the thread exists, and allows it to function)
テつ」テつ」niceday (jump instruction referencing the name of the thread in the script)

and then:

:niceday (thread title - this can be anything, really)
0001: wait  0? ms (the wait state designated before the function is performed - in this case it's 0)
01B6: set_weather  0? (the primary function of the thread)
0002: jump テつ」テつ」niceday (jump instruction to repeat the entire thread)

The purpose of the above thread is to repeat the function set_weather  0? - thus keeping the weather clear. All threads need a create_thread opcode in the "Main" section of the script (normally at the end of the entire "Main" thread), with an accompanying jump instruction. The jump instruction and the thread title must be identical.

Here is an example of a group of threads all acting to perform the one task (subthreads):

Code: [Select]
004F: create_thread テつ」テつ」phone

:phone
0001: wait  50? ms
00D6: if  0?
0256:   player $PLAYER_CHAR defined
004D: jump_if_false テつ」テつ」phone
0001: wait 0? ms
00D6: if  1?
00E1:   key_pressed  0?  16?
004D: jump_if_false テつ」テつ」phone
018C: play_sound  1? at  0!  0!  0!
0247: request_model #CELLPHONE

:phone2
00D6: if  0?
8248:   NOT   model #CELLPHONE available
004D: jump_if_false テつ」テつ」phone3
0001: wait  0? ms
0002: jump テつ」テつ」phone2

:phone3
00D6: if  0?
0038:    4716?? ==  2?  \\ integer values
004D: jump_if_false テつ」テつ」phone4
0249: release_model #CELLPHONE
0051: return

:phone4
052B: actor $PLAYER_ACTOR hold_cellphone  1?
0006:  16@ =  0?  \\ integer values
0002: jump テつ」テつ」phone

I won't break this one down. But you can see within the threads, there are references (jump instructions) to other subthreads (either above or below). Each thread relies upon the others to function properly. The above threads allow the player to use the phone (simulated, of course) when the 'sprint' button is pressed. In most cases, a previous thread will automatically jump to the next thread in the script. However in some cases it is necessary to use a jump instruction for the function to proceed.
 

-INTEGER VALUE

An integer value is essentially a series of digits that are used to either reference a repeated function, or as a reference to a solitary game element (car, actor, etc). An example of an integer value is as follows:

Code: [Select]
024A:  1168?? = create_phone_at  36.90385! -1023.3!
Breaking it down:

024A: (call number)
1168?? (integer value)
= create_phone_at  36.90385! -1023.3! (the function of the integer value)

What this line creates is a function for the integer value 1168?? to create a phone at the designated co-ordinates in the game environment. Therefore, any time in the script that the creation of this phone is needed, the integer 1168?? can be used as a quick method of reference.

Conversely, in the line:

Code: [Select]
01F4:   car  348?? flipped
The integer 348?? is a reference to a single vehicle. Because a player could be driving any number of vehicles, the integer value is an easier and more universal method of reference.

**INTEGER VALUES MUST ALWAYS BE DIVISIBLE BY FOUR - 4  8  16  20 - ETC**


-FLOATING POINT VALUE

A floating point value works much like an integer value, referencing a specific co-ord. An example of a floating point value is:

Code: [Select]
0005:  2256?? =  487.2!  \\ floating-point values
Breaking this down:

0005: (call number)
2256?? (integer value)
=  487.2! (floating point)

The floating integers are used for quick setting up of co-ords. If, for instance, you wanted to set a vehicle position to the X co-ordinate 487.2 - you could use the floating integer value of 2256??, instead of 487.2.

**FLOATING POINT VALUES MUST ALWAYS BE DIVISIBLE BY FOUR - 4  8  16  20 - ETC**


-WAIT STATE

A wait state is used in a thread to determine the delay (if any) before a particular function is carried out. The most common example of a wait state is:

Code: [Select]
0001: wait  0? ms
Breaking it down:

0001: (call number)
wait  0? ms (the wait function, coupled with the desired time in milliseconds)

The wait state function can be very handy in choreographing several functions (particularly with actors) to be played out according to a desired timeline.

-ANIM WAIT STATES
I'm still a little unsure of anim wait states and how they work. Will update as I learn more.  


------------------------------------------------------------------------------------------------

Basic editing

Basic editing of the mission script involves alterations to existing code, rather than incorporation of completely new code. Basic editing is normally subtle changes to make certain elements of the game easier or less time consuming. Letテ「竄ャ邃「s start by
taking a look at one of the fundamental portions of the default mission script for Vice City.


Code: [Select]
;-------------MAIN---------------


:Label009AE4
03A4: name_thread "MAIN"
016A: fade  0? ()  0? ms
042C: set_total_missions_to  88?
030D: set_total_mission_points_to  154&
01F0: set_max_wanted_level_to  4?
02ED: set_total_hidden_packages_to  100?
0111: set_wasted_busted_check_to  0? (disabled)
00C0: set_current_time  22?  0?
04E4: unknown_refresh_game_renderer_at  83! -849.8!
03CB: set_camera  83! -849.8!  9.3!
0053: $PLAYER_CHAR = create_player #NULL at  83! -849.8!  9.3!
01F5: $PLAYER_ACTOR = create_emulated_actor_from_player $PLAYER_CHAR
0417: start_mission  0?

This is an abridged version of the main, showing only the more recognizable elements. The entire main is much longer, but most of the information isn't relevant at the moment. Lines such as:

Code: [Select]
01F0: set_max_wanted_level_to  4?
02ED: set_total_hidden_packages_to  100?
00C0: set_current_time  22?  0?

are fairly self-explanatory, and changes to them are equally so. For example, the line:

Code: [Select]
01F0: set_max_wanted_level_to  4?
determines your maximum possible wanted level at the beginning of a new game. However, a change such as this:

Code: [Select]
01F0: set_max_wanted_level_to  0?
will render you immune to the police at the start of a new game. However, further scouring down the mission script reveals this line:

Code: [Select]
01F0: set_max_wanted_level_to  6?
This will reset your max level back to 6, but can be easily countered by either changing the latter line of code (above) or creating a repeating thread, or button operated thread. But for now, just the simple change from 6 to 0 is sufficient.

You can also change the current time in-game when starting a new game. This is, of course, somewhat redundant. But it's a good way to practice subtle changes in the script and gain confidence. The line:

Code: [Select]
00C0: set_current_time  22?  0?
designates the current in-game time to be 22:00 (or 10:00pm). The number 22? in this line assigns the hour, and 0? assigns the minutes. So changing the line to this:

Code: [Select]
00C0: set_current_time  04? 32?
will designate the time to 04:32 (or 4:32am).

*NOTE - THIS ONLY REALLY WORKS IN A STRIPPED SCM. YOU CAN CHANGE THE TIME FOR WHEN THE INTRO ENDS AT LINE 30667, BUT CHANGING ONLY THE MAIN THREAD'S TIME SETTING WILL HAVE NO EFFECT ON A DEFAULT SCRIPT. THIS IS BECAUSE THE INTRO ALSO SETS A TIME THAT SUPERCEDES THE MAIN THREAD'S TIME SETTINGS*

Other lines in the main section of the mission script that can be changed are:

Code: [Select]
01B6: set_weather  0?
(current weather - any number between 0 and 5)

*NOTE - AGAIN, ONLY APPLICABLE TO A STRIPPED SCM. WEATHER IS DYNAMIC IN VICE CITY AND MANY MISSIONS BRING ABOUT WEATHER CHANGES, SO THIS OPERATION IS SOMEWHAT A MOOT ONE, BUT IS GOOD FOR BEGINNERS TESTING WITH A STRIPPED SCRIPT*

Most of the changes above can be checked quickly by starting a new game, but will be available in a save game also, with the exception of the current time and weather, which are recorded in a save game. Because you are not adding in new codes (simply changing existing code) it is not imperative that you start a new game.

-----------------------------------------------------------------------------------------------

Now onto more advanced alteration of existing code. GTA Vice City incorporates Taxi missions which require you to deliver 100 passengers to their destinations successfully before unlocking the taxi boost ability. The mission coding for the taxi submission can be found in the lower portions of the default script (Line 164312). Further down (Line 165406) you'll see the line:

Code: [Select]
0572: set_taxi_boost_jump  1?
which tells the game that the missions have been completed, and the boost is now unlocked. The script references the amount of fairs needed to activate the above line with this opcode (Line 165402):

Code: [Select]
0018:    1476?? >  99?  \\ integer values
The 1476?? is an integer value that equals 0 (but is used by the script as a way of saying 'fares amount'). The 99 is a normal reference to 99, this is because any number of fares over the amount 99 will unlock the boost. The > is the mathematical representation of 'greater than'. So essentially the line (in plain english) actually reads:

Code: [Select]
0018:   if fares completed?? is greater than  99?  \\ integer values
The opcode to enable the boost follows shortly after in this thread of code, and is triggered by the above opcode when the amount of fares completed is 100 or more. However, if you can't be bothered to drive whining passengers around for three hours to enable the boost, you can simply alter the reference to the amount of fares needed. If you change the integer opcode to read:

Code: [Select]
0018:    1476?? >  0?  \\ integer values
it will mean the boost will be enabled after the first fare has been completed. The line:  

Code: [Select]
0572: set_taxi_boost_jump  1?
can also be inserted into the "Main" thread of the mission script, enabling the cab boost from the start. However, this does not complete the taxi sub-mission, and the boost will be DISABLED if you choose to do the fares. So in the interest of completing the game 100%, it's better to drop the amount of fares needed, rather than attempt to have the mission completed without even starting it.

The same principle can be applied to the Pizzaboy, Paramedic, and Vigilante submissions. The lines that need to be changed are as follows:

VIGILANTE (Line 170492):

Code: [Select]
0038:    27568?? ==  12?  \\ integer values
The integer value 27568?? this time refers to 'vigilante level required to complete', and 12? refers to that level. Changing the line to this:

Code: [Select]
0038:    27568?? ==  1?  \\ integer values
will mean that only one level will be required. Unfortunately this level cannot be changed to 0. The result of completion of Vigilante is this (Line 170496):

Code: [Select]
055F: set_player $PLAYER_CHAR max_armor +=  50?
giving the player an extra 50 on their maximum allowable armor.


PARAMEDIC (Line 166831):

Code: [Select]
0038:    27024?? ==  13?  \\ integer values
(Line 166829)

Code: [Select]
0008:  27024?? +=  1?  \\ integer values

The integer value in the first line is much the same as it is for the Vigilante sub-mission, however the second value (13?) is not set at 12? simply because the Paramedic sub-mission can continue beyond the 12th level. The second line is basically a representation of how many levels will be incrimented as the patients are successfully dropped off, and is also a way for the game to know that in order to complete level 12, you must pass onto level 13. So, changing the first line to:

Code: [Select]
0038:    27024?? ==  1?  \\ integer values
and the second line to:

Code: [Select]
0008:  27024?? +=  0?  \\ integer values
will complete the sub-mission (although not end it) after the first level is reached (1 patient delivered). The reward for this sub-mission is (Line 166836):

Code: [Select]
0330: set_player $PLAYER_CHAR infinite_run_to  1? (true)
Giving the player infinite run. This can also be put into the main section of the code - unlocking it from the start. But again, it will not add to your percentage of the game completed, and the Paramedic missions will go uncompleted.


PIZZABOY (Line 190037):

Code: [Select]
0038:    31976?? ==  10?  \\ integer values
The integer value 31976?? again pretains to level reached, and 10? is the level required to complete the sub-mission. So changing the line to read:

Code: [Select]
0038:    31976?? ==  1?  \\ integer values
will once again mean that only the first level is required for completion. The reward for completion is as follows (Line 190092):

Code: [Select]
055E: set_player $PLAYER_CHAR max_health +=  50?
giving you an extra 50 on your maximum health.


As yet, I have been unable to find a way to fudge the figures for the firefighter sub-mission, but I will update this tutorial as I learn more.

-----------------------------------------------------------------------------------------------

Changing elements such as these in the game serve to make it quicker to complete the sub-missions, which will come in handy when adding new code into the script (which requires a new game to be started). Although your stats will record that you have only completed one stage of each sub-mission, you will get the standard percentage added to your completion record, and you will have officially completed the sub-mission(s).

Changes such as these do not weigh heavily on the game, and if done right, will not harm your game in any way. It is definately not recommended that you toy with any of the games story missions.

------------------------------------------------------------------------------------------------

Another alteration that can be made to the game is changing the location of spawned pick-ups. Unlike the above alterations, these WILL require that you start a new game. Something simple as an example (Line 339):

Code: [Select]
0213:  440?? = create_pickup -4? (BRIBE) type  15? at  393.9! -60.2!  11.5!
This opcode creates a bribe pick-up at the designated co-ordinates. However, simple changing of the three co-ordinate references can allow you to move the bribe to whatever location you desire. Co-ords can be attained by using any number of trainers (DevConsole, Spooshdemo, VCTeleport), or by using the CodeCreator included with Mission Builder.

Loading a saved game after making a change such as this will not crash your game, but the bribe will not appear in it's new location. Only by starting a new game will the change take effect. With this method you can change the location of hidden packages, weapon pick-ups and parked cars.


Look through the mission script and see what changes you think you could make for the better. You could group all the hidden packages into one area, move weapon pick-ups to more convenient locations, or even move parked cars to areas outside your safehouses. Be sure to make the changes correctly, and do not try to alter the code outside of it's existing parameters (ie: do not change a weapon pick-up into a bribe pick-up). It can be time consuming, and often frustrating work, but it can help to make the game more diverse and more enjoyable in the long run.


That's basically all I can really say about basic mission script alterations. When you feel you're ready to move on to more advanced techniques of adding in new code, check out the advanced tutorial.

ADVANCED TUT COMING SOON

Offline Flat Face

  • With power comes lulz
  • Administrator
  • Posts: 9243
    • View Profile
[VC] Basic Mission Scripting Tutorial
« Reply #16 on: April 20, 2008, 11:28:25 PM »
omfg  @ you when im done with 3ds later ima give this a shot

Offline Dannye

  • Veteran Member
  • Posts: 3580
    • View Profile
[VC] Basic Mission Scripting Tutorial
« Reply #17 on: April 21, 2008, 12:34:57 AM »
You should  Kan instead, not only did he write it, he was smart enough to make a backup post of it over at the batcave.

Offline Flat Face

  • With power comes lulz
  • Administrator
  • Posts: 9243
    • View Profile
[VC] Basic Mission Scripting Tutorial
« Reply #18 on: April 21, 2008, 01:05:21 AM »
Quote from: Dannye
You should  Kan instead, not only did he write it, he was smart enough to make a backup post of it over at the batcave.


 @ you all then .. sept BJ who also knows this stuff but left us in the dark  .. *cough* if anyone has his msn please abuse him(mention NNY) *cough*

also stick this in your 1st post lol
« Last Edit: April 21, 2008, 01:06:14 AM by Flat Face »

Offline Dannye

  • Veteran Member
  • Posts: 3580
    • View Profile
[VC] Basic Mission Scripting Tutorial
« Reply #19 on: April 21, 2008, 01:34:47 AM »
Ah yes, good idea. *First post edited*.

Offline jessrocked

  • Veteran Member
  • Posts: 3360
  • Victory Loves Preparation
    • View Profile
    • http://www.friendster.com/jessrocked
[VC] Basic Mission Scripting Tutorial
« Reply #20 on: May 06, 2008, 09:42:19 PM »
too many words :blow:

 

SimplePortal 2.3.7 © 2008-2024, SimplePortal