Squirrel

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.
Contents
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
|
To do: Possibly unavailable in VScript |
Userdata
|
Opaque data used by the game. |
Thread
|
To do: 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.[...]
To do: Get a better example.
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