Squirrel: Difference between revisions
m (Plese -> Please) |
(Section Functions, section Classes, some this, some that) |
||
Line 4: | Line 4: | ||
==Variables== | ==Variables== | ||
Squirrel has two kinds of variables | Squirrel has two kinds of variables: '''table slots''' and '''<code>local</code>''' variables. | ||
Since the execution scope is always a table, any variables declared outside functions will always be table slots. | |||
* Table slots have to be declared using the <code><-</code> operator. | |||
* Variables local to functions can be declared using the <code>local</code> keyword. These should be used for temporary values or as helpers. | |||
* Global variables are slots in the root table, and can be declared using the <code>::</code> scoping operator. | |||
Here are examples illustrating the declaration and use of variables. | |||
{| | |||
|- style="vertical-align:top;" | |||
| <source lang=cpp> | |||
<source lang=cpp> | |||
// Variable declaration. | // Variable declaration. | ||
a <- 5 | a <- 5 | ||
Line 18: | Line 20: | ||
// Modifying the variable. | // Modifying the variable. | ||
b = "New string" | b = "New string" | ||
</source> | |||
| <source lang=cpp> | |||
function MultiplyWithTwo(inValue) | function MultiplyWithTwo(inValue) | ||
{ | { | ||
Line 26: | Line 29: | ||
return inValue * factor | return inValue * factor | ||
} | } | ||
</source> | |||
| <source lang=cpp> | |||
// Global variable declaration. Sets x to 10. | // Global variable declaration. Sets x to 10. | ||
::x <- MultiplyWithTwo(a) | ::x <- MultiplyWithTwo(a) | ||
</source> | </source> | ||
|} | |||
==Data Types== | ==Data Types== | ||
Squirrel is a dynamically typed language. Any variable can be assigned a value of any type. | Squirrel is a dynamically typed language. Any variable can be assigned a value of any type. | ||
{{note| The VScript API functions are bindings to the Source C++ code, so while it may seem possible to pass values of any type to them, they only accept specific types.}} | {{note| The VScript API functions are bindings to the Source C++ code, so while it may seem possible to pass values of any type to them, they only accept specific types.}} | ||
The built-in function <code>typeof</code> returns the type of an input value as a string in lower case, e.g. <code>typeof(5) == "integer"</code>. | |||
{| class="standard-table" | {| class="standard-table" | ||
Line 41: | Line 47: | ||
|- | |- | ||
|<code>Integer</code> | |<code>Integer</code> | ||
| | | The integers <code>-2147483648</code> to <code>2147483647</code>. | ||
|- | |- | ||
|<code>Float</code> | |<code>Float</code> | ||
| | | <code>-3.4028235e38</code> to <code>3.4028235e38</code>, which equal -3.4028235 × 10<sup>38</sup> to 3.4028235 × 10<sup>38</sup>. | ||
|- | |- | ||
|<code>String</code> | |<code>String</code> | ||
Line 81: | Line 87: | ||
|<code>Weak reference</code> | |<code>Weak reference</code> | ||
| | | | ||
|} | |} | ||
Line 89: | Line 94: | ||
===Arrays=== | ===Arrays=== | ||
Arrays are sequences of objects that are numerically indexed starting from 0. Syntactically they function similarly to C arrays, but unlike C arrays, they are mutable and values can be inserted and removed using a set of [http://squirrel-lang.org/doc/squirrel3.html#d0e3058 built in functions]. | Arrays are sequences of objects that are numerically indexed starting from 0. Syntactically they function similarly to C arrays, but unlike C arrays, they are mutable and values can be inserted and removed using a set of [http://squirrel-lang.org/doc/squirrel3.html#d0e3058 built in functions]. | ||
Arrays are defined using square brackets. | Arrays are defined using square brackets. | ||
<source lang=cpp> | {| | ||
|- style="vertical-align:top;" | |||
| <source lang=cpp> | |||
// Array definition. | // Array definition. | ||
myArray <- | myArray <- | ||
Line 102: | Line 110: | ||
1 | 1 | ||
] | ] | ||
</source> | |||
| <source lang=cpp> | |||
// Prints "7" | // Prints "7" | ||
printl(myArray[0]) | printl(myArray[0]) | ||
Line 111: | Line 120: | ||
printl(myArray[0]) | printl(myArray[0]) | ||
</source> | </source> | ||
|} | |||
===Tables=== | |||
Tables are associative arrays, meaning that they contain a collection of key-value pairs, called slots. A table can be indexed into using the key, returning the associated value. The keys and values can be of any data type (except <code>null</code> for the key), including other tables, allowing the creation of more complex data structures. | Tables are associative arrays, meaning that they contain a collection of key-value pairs, called slots. A table can be indexed into using the key, returning the associated value. The keys and values can be of any data type (except <code>null</code> for the key), including other tables, allowing the creation of more complex data structures. | ||
Line 120: | Line 130: | ||
Using the <code>.</code> operator to index a key only works when the key is a string or numerical literal. Array style indexing <code>table[keyVariable]</code> can be used to index any kind of key. | Using the <code>.</code> operator to index a key only works when the key is a string or numerical literal. Array style indexing <code>table[keyVariable]</code> can be used to index any kind of key. | ||
<source lang=cpp> | {| | ||
|- style="vertical-align:top;" | |||
| <source lang=cpp> | |||
// Table defintion. | // Table defintion. | ||
myTable <- | myTable <- | ||
Line 133: | Line 145: | ||
} | } | ||
} | } | ||
</source> | |||
| <source lang=cpp> | |||
// Adding non-string keys | // Adding non-string keys | ||
a <- "0" | a <- "0" | ||
Line 144: | Line 157: | ||
// Prints "11" | // Prints "11" | ||
printl(myTable[a]) | printl(myTable[a]) | ||
</source> | |||
| <source lang=cpp> | |||
// Prints all the key-value pairs in the table. | // Prints all the key-value pairs in the table. | ||
foreach(key, value in myTable) | foreach(key, value in myTable) | ||
Line 154: | Line 168: | ||
printl(myTable.nestedTable.z) | printl(myTable.nestedTable.z) | ||
</source> | </source> | ||
| | |||
|} | |||
==Functions== | ==Functions== | ||
Functions in Squirrel work similarly to their C counterparts. Second order functions are supported, so functions can be directly manipulated like other values, including it being possible to store them in variables and table slots. Default parameter values and variable numbers of parameters are also supported. | Functions in Squirrel work similarly to their C counterparts. Second order functions are supported, so functions can be directly manipulated like other values, including it being possible to store them in variables and table slots. Default parameter values and variable numbers of parameters are also supported. | ||
{{ | For more details, see the [http://www.squirrel-lang.org/squirreldoc/reference/language/functions.html Squirrel API about functions]. | ||
===Declaration and Definition=== | |||
It is an idea to choose function names so that they begin with a capital letter. | |||
{| | |||
|- style="vertical-align:top;" | |||
| <source lang=cpp> | |||
// declares and (re)defines "Greet" | |||
function Greet() | |||
{ | |||
printl("Hello!") | |||
} | |||
Greet() // prints "Hello!" | |||
</source> | |||
| <source lang=cpp> | |||
// declares and (re)defines "Greet" | |||
Greet <- function() | |||
{ | |||
printl("Hello!") | |||
} | |||
Greet() // prints "Hello!" | |||
</source> | |||
| <source lang=cpp> | |||
// (re)defines "Greet"; exception if "Greet" not declared! | |||
Greet = function() | |||
{ | |||
printl("Hello!") | |||
} | |||
Greet() // prints "Hello!" | |||
</source> | |||
|} | |||
===Parameters=== | |||
When a function is called, it can be made so that it can or must receive input values that determine the function's side effects and/or its return value. | |||
* Multiple parameters must be comma delimited: <code>function Test( a , b , c , d=4, e=5) {...}</code> | |||
* All parameters with no default value must be the first. | |||
* To avoid exceptions, it is often a good idea to check if a parameter is not <code>null</code>. The statements <code>if (object != null) {...}</code> and <code>if (object) {...}</code> are equivalent. | |||
* As parameters are not restricted to a type, the <code>typeof</code> function can be used to handle different types differently. | |||
{| | |||
|- style="vertical-align:top;" | |||
| <source lang=cpp> | |||
// normal parameter | |||
function Greet(name) | |||
{ | |||
printl("Hello, " + name + "!") | |||
} | |||
Greet() // exception | |||
Greet("Gabe") // prints "Hello, Gabe!" | |||
</source> | |||
| <source lang=cpp> | |||
// parameter with default value | |||
function Greet(name="Gordon") | |||
{ | |||
printl("Hello, " + name + "!") | |||
} | |||
Greet() // prints "Hello, Gordon!" | |||
Greet("Gabe") // prints "Hello, Gabe!" | |||
</source> | |||
|} | |||
===Return Value=== | |||
A function is ended with the optional <code>return</code> statement, where it is also possible to ''return'' a value. | |||
It can be imagined that this value will be inserted to where the function was called. | |||
* If a function ends without a <code>return</code> statement, it returns the value <code>null</code>. | |||
{| | |||
| <source lang=cpp> | |||
function IsEven(n) | |||
{ | |||
if (n % 2 == 0) | |||
return true | |||
else | |||
return false | |||
} | |||
if (IsEven(42)) // (42 % 2 == 0) == true | |||
{ | |||
printl("42 is even!") | |||
} | |||
</source> | |||
|} | |||
==Classes== | ==Classes== | ||
{{ | The following is just an example of some basic class syntax. For details, see [http://www.squirrel-lang.org/squirreldoc/reference/language/classes.html Squirrel API about classes]. | ||
<source lang=cpp> | |||
class Weapon | |||
{ | |||
static prefix = "weapon_" // static variables are read-only! | |||
// For instance-individual variables it's best to declare them with anything and overwritte them on construction. | |||
name = null | |||
primMax = null | |||
secMax = null | |||
count = [0] // Containers and instances are not copied per instance, just the reference. count[0] is the same for all of instances. | |||
constructor(name0, prim, sec) | |||
{ | |||
name = prefix + name0 | |||
primMax = prim | |||
secMax = sec | |||
count[0]++ | |||
} | |||
function GetAll() | |||
{ | |||
local list = [] | |||
local wep = null | |||
while ( wep = Entities.FindByClassname(wep, name) ) | |||
{ | |||
list.append(wep) | |||
} | |||
return list | |||
} | |||
// ... more useful functions ... | |||
} | |||
awp <- Weapon("awp", 10, 30) | |||
ak47 <- Weapon("ak47", 30, 90) | |||
// can access class variables and class functions with awp.[...] | |||
</source> | |||
{{Todo | Get a better example.}} | |||
==Scripting== | ==Scripting== | ||
'''Please see [[ | '''Please see [[VScript Fundamentals]] for more information.''' | ||
With the Source VScript system, scripts are stored in the <code>''game''\scripts\vscripts\</code> directory. Squirrel scripts use the <code>.nut</code> file extension, and the <code>.nuc</code> extension for [[ICE]] encrypted files. | With the Source VScript system, scripts are stored in the <code>''game''\scripts\vscripts\</code> directory. Squirrel scripts use the <code>.nut</code> file extension, and the <code>.nuc</code> extension for [[ICE]] encrypted files. | ||
Line 177: | Line 317: | ||
==See Also== | ==See Also== | ||
* [[VScript]] | * [[VScript]] | ||
* [[ | * [[VScript Fundamentals]] | ||
* [[L4D2 Vscripts|Scripting in L4D2]] | * {{l4d2}} [[L4D2 Vscripts|Scripting in L4D2]] | ||
* {{csgo}} [[List of Counter-Strike: Global Offensive Script Functions]] | |||
==External links== | ==External links== |
Revision as of 16:16, 7 May 2021
Squirrel is a programming language similar to Lua, but uses a C like syntax. In Source Squirrel is used as one of the scripting languages in the VScript scripting system. The official Squirrel documentation can be found here
Squirrel heavily uses an associative array data structure called a table. Both the keys and values of a table can contain almost any kind of variable. The scripting environment consists of nested tables, and when a script is executed its variables and functions are added as table slots.
Variables
Squirrel has two kinds of variables: table slots and local
variables.
Since the execution scope is always a table, any variables declared outside functions will always be table slots.
- Table slots have to be declared using the
<-
operator. - Variables local to functions can be declared using the
local
keyword. These should be used for temporary values or as helpers. - Global variables are slots in the root table, and can be declared using the
::
scoping operator.
Here are examples illustrating the declaration and use of variables.
// Variable declaration.
a <- 5
b <- "A text string"
// Modifying the variable.
b = "New string"
|
function MultiplyWithTwo(inValue)
{
// Local variable declaration.
local factor = 2
return inValue * factor
}
|
// Global variable declaration. Sets x to 10.
::x <- MultiplyWithTwo(a)
|
Data Types
Squirrel is a dynamically typed language. Any variable can be assigned a value of any type.

The built-in function typeof
returns the type of an input value as a string in lower case, e.g. typeof(5) == "integer"
.
Type | Description |
---|---|
Integer
|
The integers -2147483648 to 2147483647 .
|
Float
|
-3.4028235e38 to 3.4028235e38 , which equal -3.4028235 × 1038 to 3.4028235 × 1038.
|
String
|
An immutable string. They behave like C strings, and support escape sequences (\t,\a,\b,\n,\r,\v,\f,\\,\",\',\0,\xhhhh ).
|
Null
|
|
Bool
|
Boolean data type that can be true or false .
|
Table
|
Associative array. |
Array
|
Mutable C style array. |
Function
|
Second order functions are supported, so functions can assigned as values to variables. |
Class
|
Object oriented class. Implementation similar to tables. |
Class Instance
|
Object instances of classes. Script handles generated by the game also identify as instances. |
Generator
|
Todo: Possibly unavailable in VScript
|
Userdata
|
Opaque data used by the game. |
Thread
|
Todo: Possibly unavailable in VScript
|
Weak reference
|
Data Structures
Squirrel has built-in support for two different data structures, arrays and tables.
Arrays
Arrays are sequences of objects that are numerically indexed starting from 0. Syntactically they function similarly to C arrays, but unlike C arrays, they are mutable and values can be inserted and removed using a set of built in functions.
Arrays are defined using square brackets.
// Array definition.
myArray <-
[
7,
"more text",
null,
1
]
|
// Prints "7"
printl(myArray[0])
myArray.remove(0)
// Prints "more text"
printl(myArray[0])
|
Tables
Tables are associative arrays, meaning that they contain a collection of key-value pairs, called slots. A table can be indexed into using the key, returning the associated value. The keys and values can be of any data type (except null
for the key), including other tables, allowing the creation of more complex data structures.
Tables are defined using curly brackets. Inside a table definition slots can be defined using the key = value
pattern. Outside of the definition, new slots can be added to existing tables using the table.key <- value
pattern.
Using the .
operator to index a key only works when the key is a string or numerical literal. Array style indexing table[keyVariable]
can be used to index any kind of key.
// Table defintion.
myTable <-
{
a = 3,
b = 7,
x = "example text",
nestedTable =
{
z = "another string"
}
}
|
// Adding non-string keys
a <- "0"
myTable[a] <- 11
myTable[["u", "v", "w"]] <- null
// Prints "3"
printl(myTable.a)
// Prints "11"
printl(myTable[a])
|
// Prints all the key-value pairs in the table.
foreach(key, value in myTable)
{
printl(key + ": " + value)
}
// Prints the value of the key in the nested table.
printl(myTable.nestedTable.z)
|
Functions
Functions in Squirrel work similarly to their C counterparts. Second order functions are supported, so functions can be directly manipulated like other values, including it being possible to store them in variables and table slots. Default parameter values and variable numbers of parameters are also supported.
For more details, see the Squirrel API about functions.
Declaration and Definition
It is an idea to choose function names so that they begin with a capital letter.
// declares and (re)defines "Greet"
function Greet()
{
printl("Hello!")
}
Greet() // prints "Hello!"
|
// declares and (re)defines "Greet"
Greet <- function()
{
printl("Hello!")
}
Greet() // prints "Hello!"
|
// (re)defines "Greet"; exception if "Greet" not declared!
Greet = function()
{
printl("Hello!")
}
Greet() // prints "Hello!"
|
Parameters
When a function is called, it can be made so that it can or must receive input values that determine the function's side effects and/or its return value.
- Multiple parameters must be comma delimited:
function Test( a , b , c , d=4, e=5) {...}
- All parameters with no default value must be the first.
- To avoid exceptions, it is often a good idea to check if a parameter is not
null
. The statementsif (object != null) {...}
andif (object) {...}
are equivalent. - As parameters are not restricted to a type, the
typeof
function can be used to handle different types differently.
// normal parameter
function Greet(name)
{
printl("Hello, " + name + "!")
}
Greet() // exception
Greet("Gabe") // prints "Hello, Gabe!"
|
// parameter with default value
function Greet(name="Gordon")
{
printl("Hello, " + name + "!")
}
Greet() // prints "Hello, Gordon!"
Greet("Gabe") // prints "Hello, Gabe!"
|
Return Value
A function is ended with the optional return
statement, where it is also possible to return a value.
It can be imagined that this value will be inserted to where the function was called.
- If a function ends without a
return
statement, it returns the valuenull
.
function IsEven(n)
{
if (n % 2 == 0)
return true
else
return false
}
if (IsEven(42)) // (42 % 2 == 0) == true
{
printl("42 is even!")
}
|
Classes
The following is just an example of some basic class syntax. For details, see Squirrel API about classes.
class Weapon
{
static prefix = "weapon_" // static variables are read-only!
// For instance-individual variables it's best to declare them with anything and overwritte them on construction.
name = null
primMax = null
secMax = null
count = [0] // Containers and instances are not copied per instance, just the reference. count[0] is the same for all of instances.
constructor(name0, prim, sec)
{
name = prefix + name0
primMax = prim
secMax = sec
count[0]++
}
function GetAll()
{
local list = []
local wep = null
while ( wep = Entities.FindByClassname(wep, name) )
{
list.append(wep)
}
return list
}
// ... more useful functions ...
}
awp <- Weapon("awp", 10, 30)
ak47 <- Weapon("ak47", 30, 90)
// can access class variables and class functions with awp.[...]
Scripting
Please see VScript Fundamentals for more information.
With the Source VScript system, scripts are stored in the game\scripts\vscripts\
directory. Squirrel scripts use the .nut
file extension, and the .nuc
extension for ICE encrypted files.
Common to all Squirrel using games, scripts can be associated to a game entity as an entity script that is executed then the entity spawns, and has access to the script handle of its entity through the self
variable. Specific games can also have other methosds of executing scripts.
Script files can also be executed from the Developer Console using the script_execute
command. Lines of code can even be executed in-line with the script
command.
See Also
- VScript
- VScript Fundamentals
Scripting in L4D2
List of Counter-Strike: Global Offensive Script Functions
External links
- Squirrel (programming language) - Wikipedia Article on Squirrel
- Squirrel Official Website
- Notepad++ syntax highlighting
- Squirrel Binary for Windows