A to Z Scripting: More scripting basics

From The DarkMod Wiki
Revision as of 10:02, 21 December 2020 by Dragofer (talk | contribs) (Created page with "== More scripting basics == === General === * Scripting is case-sensitive. * The scripting engine reads from top to bottom. That makes the order in which scripts and variables...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

More scripting basics

General

  • Scripting is case-sensitive.
  • The scripting engine reads from top to bottom. That makes the order in which scripts and variables are arranged quite important. You can't call a script or use a variable if the engine hasn't seen it defined yet.
  • The $ sign instructs the engine to look for an entity ingame with that name. If there's no $ sign, the engine will instead look for a variable with that name in the scripts.
  • Commenting can be done either by putting // in front of every line of comment, or by putting /* at the top and */ at the bottom. The latter is useful for multi-line comments or temporarily disabling a section of your script.
  • To make changes to a (map) script take effect, you need to reload the map. This can be sped up by binding the "map" command to a hotkey (note that this only works when youre already in a map). Entering the following into the console would bind opening a map called test_script.map to the p key:
bind "p" "map test_script"


Data types

Data type indicates whether something is a text (string), number (float), vector etc. You will always want to be aware of this, since i.e. a script designed to apply a force vector won't work if you give it a string instead of a vector as input.

String A string of letters/numbers, in other words plain text. It must always have double quotation marks. Example: “Text message 123”
Float A float is a single number, decimals are allowed. Example: 15.2
Vector A vector consists of 3 numbers, often used for 3D movements (x z y) or colors (red green blue). It must always have single quotation marks. Example: '0 90 0'
Boolean Can be true or false. Easily replaced by floats (0 or 1). Example: TRUE
Void No type. Commonly used for scripts or script events that have no direct output.
Entity Indicates an entity, usually using the name as seen in DR. If it's a specific entity, instead of a variable, then a $ sign is required. Example: $player1
Subcategories of “entity” You can be more specific and define an entity as, for example, an ai, light or tdm_elevator. These are names of scriptobjects, and by defining an entity like this you gain access to that scriptobject's internal variables and scripts. For an "ai", useful internal variables are i.e. whether the AI is alerted or knocked out. (see "AI flags" for more)


Variables

Variables are a key principle in scripting. They allow the same script to have different results depending on the input, rather than always doing the exact same thing. Another use is for storing data, allowing it to be used or modified by other script events.


Creating new variables

The first time the engine finds a variable in a script it needs to be given a data type. Afterwards you use just the name. Example:

float attempts;						//define "attempts" as a new float variable
attempts = attempts + 1;				//increase the number of attempts made by 1
sys.println("Player has " + attempts + " left.");	//print a console message with the number of attempts left

You may also want to assign an initial value. Otherwise, floats will default to 0, strings to "", vectors to '0 0 0' and entities to $null_entity. Example:

float attempts = 3;

Another option is to define a variable using the output of a script event. 3 Examples:

vector starting_origin = $func_static_1.getOrigin();

float can_see = $guard_westwing_1.canSee($player1);

float sound_duration = $entity1.startSound("snd_move", SND_CHANNEL_ANY, false);  //stores the sound duration of the sound being played

Where a variable is defined is important. If it's inside a script, the variable will only be visible to that script. If it's defined outside of a script, all later scripts will be able to use it.


Example: puzzle with max 3 attempts

Say you wanted to give a player 3 attempts to solve an optional puzzle, with an option to reset his number of attempts:

float attempts_left = 3;		//the starting number of attempts the player can make, defined as a float

void attempt_failed()			//called every time the player fails an attempt
{
	attempts_left	= attempts_left - 1; 			//reduce the number of attempts left by 1

	if (attempts_left == 0) $puzzle.setFrobable(0);		//if no more attempts, make the puzzle entity unfrobable
}

void reset_attempts()				//calling this resets the player's attempts
{
	attempts_left = 3;

	$puzzle.setFrobable(1);			//also make sure the puzzle entity is frobable
}



Using the TDM Script Reference

The TDM Script Reference is an essential wiki resource for scripting, listing all available script events for the current version of TDM. All script events are listed twice: the first time they're sorted alphabetically, the second time they're grouped based on which kinds of entities they can be called on. By far not all script events have received manual descriptions, so sometimes you may need to experiment with them to properly figure them out.

Here is an example entry:

scriptEvent float canSee(entity ent);

    no description

    Spawnclasses responding to this event: idAI

Interpretation:

  • the script event canSee() is suitable for being called on AIs.
  • an entity must be entered into its input bracket. The event calls this entity "ent", but this name doesn't matter to the scripter
  • the script event returns a float. This means you could for example store the result of this check in a float variable and use that elsewhere in your scripting.


It might take some experimentation to figure out which entity the script event should be called on and which entity should go into the input brackets. In the end it could look something like this:

$guard_westwing_1.canSee($player1);


Alternatively, if you want to store the result as a variable (that we name "guard_sees_player") for later use:

float	guard_sees_player = $guard_westwing_1.canSee($player1);		//if you haven't defined the "guard_sees_player" variable yet


Next / previous article