Script: Difference between revisions
|  (update notes/tips) | No edit summary | ||
| (14 intermediate revisions by 3 users not shown) | |||
| Line 1: | Line 1: | ||
| {{ | {{LanguageBar}} | ||
| {{This is a|console command|name=script|notext=1|since=Left 4 Dead 2}} | |||
| It is available in all games that have a {{sq|4}} implementation of [[VScript]], namely [[VScript#Squirrel|these]]. | It is available in all games that have a {{sq|4}} implementation of [[VScript]], namely [[VScript#Squirrel|these]]. | ||
| == Syntax == | |||
| <pre>script <code></pre> | |||
| == Description == | == Description == | ||
| It executes Squirrel code from the root table. The code can contain spaces without quotation marks used | It executes Squirrel code from the root table. The code can contain spaces even without using quotation marks {{code2|"}}. | ||
| == Limitations == | |||
| === Semicolons === | |||
| Semicolons {{code2|;}} can be used for scripting needs only inside of quotes because the [[Developer Console|developer console]] otherwise treats them as a delimiter for console commands. | |||
| * First way to use them is by enclosing whole code in quotes. In which case those 2 quotes are the only quote symbols allowed because the command is searching for the ending quote and it cannot be escaped in console | |||
| :<syntaxhighlight lang=js>script "local a = 666; for(local i; i < 10; i++) { printl(i + a) }"</syntaxhighlight> | |||
| * Other way to use them is possible if they are within quotes in a string. | |||
| :<syntaxhighlight lang=js>script printl("I can print ; but now I need a way to execute a string")</syntaxhighlight> | |||
| * Utilizing <code>compilestring</code> which compiles a string into a function it's possible to use <code>for</code> or <code>local</code> keywords while also using quote symbols for strings | |||
| :<syntaxhighlight lang=js>script compilestring("for(local i = 0; i < 10; i++) {printl(\"I can now do this: \" + i)} printl(\"My only limit now is max 255 characters in a console prompt, and the up arrow to get previously run command will only give 253 characters!\")")()</syntaxhighlight> | |||
| * Separating non-statements without semicolons and methods above can be done using {{code2|,}} comma.  | |||
| :<syntaxhighlight lang=js>script printl("i = 0"), i<-666, printl("i = " + i)</syntaxhighlight> | |||
| * Separating statements can be somewhat done using statement blocks.  | |||
| :<syntaxhighlight lang=js>script function f() { {i<-0} while(i++<10) printl(i) }</syntaxhighlight> | |||
| === Command parsing === | |||
| When script command is issued all the text from start of the command (including spaces) up to the ending semicolon is taken, first 6 characters from it are cut and the rest is run as a script. This in result means that if there is any space before script command it will cause errors.  | |||
| The following example shows script command issued with 3 spaces before it. <code>]</code> represents start of the console line. | |||
| :<syntaxhighlight lang=js>]   script printl(666)</syntaxhighlight>  | |||
| :Command above will run the script {{code2|ipt printl(666)}} resulting in error. | |||
| :The same applies to multiple script commands separated by {{code2|;}}. There must be no space between the ending semicolon and the start of next script command i.e. {{code2|script printl("print1"); script printl("print2")}} will throw a script error, but {{code2|script printl("print1");script printl("print2")}} will not. | |||
| === Finding command issuer === | |||
| * {{code2|activator}} or {{code2|caller}}, which are automatically created during [[Inputs and Outputs|I/O]] operations on entities with a script scope, wouldn't make much sense in this context and aren't created by script command. Neither is {{code2|self}}, which one could reasonably expect to contain the player issuing the script command. Getting the handle of a player running the command is not possible with a single "apply to all situations" method and {{tf2branch|2}} based games only allow the server to use the <code>script</code> command in which case it could be issued by clients only via {{cmd|rcon}}. | |||
| * If a client is connected to a server and has the ability to issue this command, they can figure out their player entity by checking {{cmd|status}} and using the <code>GetPlayerFromUserID(userid)</code> function if it's available. In the case of {{l4d2}} or {{portal2}}, unique [[Targetname#Those_evaluated_by_other_means|special targetnames]] are available and usable for example <code>Entities.FindByName(null, "!bill")</code>. | |||
| * If the player is a host of the server, they can find themselves using <code>Entities.FindByName(null, "!player")</code>. | |||
| {{ | |||
| * Other means include using {{cmd|ent_fire}} and the <tt>RunScriptCode</tt> input in which case the issuer of the command is set as the activator and caller. A player can target themselves for example using <code>ent_fire !activator RunScriptCode "::storing_my_handle_as_global <- self"</code>. See also: [[Generic Keyvalues, Inputs and Outputs/Inputs#VScript]]. | |||
| == Examples == | == Examples == | ||
Latest revision as of 00:33, 30 June 2025
script  is a   console command  available in all  Source games since
 Source games since  Left 4 Dead 2.
 Left 4 Dead 2.
It is available in all games that have a  Squirrel implementation of VScript, namely these.
 Squirrel implementation of VScript, namely these.
Syntax
script <code>
Description
It executes Squirrel code from the root table. The code can contain spaces even without using quotation marks ".
Limitations
Semicolons
Semicolons ; can be used for scripting needs only inside of quotes because the developer console otherwise treats them as a delimiter for console commands.
- First way to use them is by enclosing whole code in quotes. In which case those 2 quotes are the only quote symbols allowed because the command is searching for the ending quote and it cannot be escaped in console
- script "local a = 666; for(local i; i < 10; i++) { printl(i + a) }" 
- Other way to use them is possible if they are within quotes in a string.
- script printl("I can print ; but now I need a way to execute a string") 
- Utilizing compilestringwhich compiles a string into a function it's possible to usefororlocalkeywords while also using quote symbols for strings
- script compilestring("for(local i = 0; i < 10; i++) {printl(\"I can now do this: \" + i)} printl(\"My only limit now is max 255 characters in a console prompt, and the up arrow to get previously run command will only give 253 characters!\")")() 
- Separating non-statements without semicolons and methods above can be done using ,comma.
- script printl("i = 0"), i<-666, printl("i = " + i) 
- Separating statements can be somewhat done using statement blocks.
- script function f() { {i<-0} while(i++<10) printl(i) } 
Command parsing
When script command is issued all the text from start of the command (including spaces) up to the ending semicolon is taken, first 6 characters from it are cut and the rest is run as a script. This in result means that if there is any space before script command it will cause errors.
The following example shows script command issued with 3 spaces before it. ] represents start of the console line.
- ] script printl(666) 
- Command above will run the script ipt printl(666)resulting in error.
- The same applies to multiple script commands separated by ;. There must be no space between the ending semicolon and the start of next script command i.e.script printl("print1"); script printl("print2")will throw a script error, butscript printl("print1");script printl("print2")will not.
Finding command issuer
- activatoror- caller, which are automatically created during I/O operations on entities with a script scope, wouldn't make much sense in this context and aren't created by script command. Neither is- self, which one could reasonably expect to contain the player issuing the script command. Getting the handle of a player running the command is not possible with a single "apply to all situations" method and Team Fortress 2 branch based games only allow the server to use the Team Fortress 2 branch based games only allow the server to use the- scriptcommand in which case it could be issued by clients only via- rcon.
- If a client is connected to a server and has the ability to issue this command, they can figure out their player entity by checking statusand using theGetPlayerFromUserID(userid)function if it's available. In the case of or or , unique special targetnames are available and usable for example , unique special targetnames are available and usable for exampleEntities.FindByName(null, "!bill").
- If the player is a host of the server, they can find themselves using Entities.FindByName(null, "!player").
- Other means include using ent_fireand the RunScriptCode input in which case the issuer of the command is set as the activator and caller. A player can target themselves for example usingent_fire !activator RunScriptCode "::storing_my_handle_as_global <- self". See also: Generic Keyvalues, Inputs and Outputs/Inputs#VScript.
Examples
script printl( GetMapName() )
Prints the name of the current map in the console.
script player <- Entities.FindByClassname(null, "player"); script player.SetMaxHealth( 200 )
Using a variable, find the player with the lowest entity index then set their max health to 200.
script { player <- Entities.FindByClassname(null, "player") } { player.SetMaxHealth(200) }
The same code, but as a single console command, achieved by using curly braces to bypass semicolons. Note that in this example, one pair of curly braces would suffice; if there is no nesting, putting every other statement in curly braces is sufficient. Note also that the statement player <- ... despite the curly braces, creates a table slot in the root table that persists after the closing brace. If the player variable should be a local variable, its assignment statement must not stand alone inside curly braces, since its scope ends with the closing curly brace. 
When executing multiple complicated commands repeatedly using the up ↑ and down ↓ arrow keys in the console it may even be useful to add a comment in the command, for example the following.
script /* SET MAX HEALTH 200 */ { player <- Entities.FindByClassname(null, "player") } { player.SetMaxHealth(200) } // SET MAX HEALTH 200
Squirrel will never see line comments starting with // because the developer console sees and removes them first.
Block comments /* */ can also be used because Squirrel supports them!


























