A variable is used to store and retrieve data. There are five types of values in HSL: integers, numbers, objects, hitboxes, and null. The type of a variable is inferred from the value it's assigned to, and a variable can be reassigned to a different type from what it was initialized with.
Variables can be declared using the var or const statements. Variables declared using var are mutable and may be initialized with an expression. If a var is not assigned to any value, it's initialized to null.
Variables declared with const are immutable and must be initialized with a constant expression.
The name of a variable is called an identifier. An identifier can start with an alphabetic letter, _, or $, and the remaining characters can be digits. Variable names are case sensitive: playerName, PlayerName, and PLAYERNAME are different variables. Examples of valid identifiers are: onMainMenu, top10, MAX_HIGH_SCORES, $total, and _average.
There are three types of variable scope:
When a variable is declared inside of a block, it's called a local variable. When a variable is declared outside of a block, it can be either a global variable a script variable. A global variable is any var or const declaration in top-level code, and a script variable is any local var or local const declaration in top-level code; since it's local to the script it's declared, it cannot be accessed from other scripts.
In script scope or block scope, a local variable cannot reuse the identifier of another local variable in the same scope.
A variable in block scope can be declared with the same identifier as another previously declared variable if the latter declaration is in a deeper block scope.
In global scope, a global variable can reuse the identifier of another global variable.
A variable in script or block scope can be declared with the same identifier as a variable in global scope, temporarily overriding the global variable, until it goes out of scope.
Finally, a variable declared in block scope can no longer be accessed once the block ends (that is, after the }.)
In HSL, all variable types are passed by value, except objects, which are passed by reference. The following are considered basic types:
| Type | Description | Examples |
|---|---|---|
| Integer | A whole number. Can be in hexadecimal. | 123, -456, 0x7F |
| Decimal | A floating point number. The integer or fractional part can be omitted. | 1.0, -0.25, .75, 3. |
| Object | A reference to an object. | new Car(), "Hello world", [ 10, 2.0, "omelette" ] |
| Hitbox | A rectangular shape, used for collision. | hitbox{-16, -16, 16, 16} |
| null | Absence of a value. | null |
A hitbox type can be constructed with integer literals, or integer variables. The values must be integers; they cannot be decimals. The order of the values are: left, top, right, and bottom.
The individual sides of a hitbox can be retrieved using the element-access syntax.
Despite being a keyword, hitbox can still be used as an identifier.
A hitbox is immutable.
While HSL doesn't natively have a boolean type, true and false are accepted and considered the same as 1 and 0 respectively.
The following are considered object types in HSL:
| Type | Description | Example |
|---|---|---|
| String | Text. | "Hello world" |
| Array | A resizable list of values. | [ 10, 2.0, "omelette" ] |
| Map | A collection of key-value pairs. Other languages also call this type a dictionary. Keys must be strings and are stored in order of insertion. | {"tankCapacity": 60.0, "color": "red"} |
| Class | Contains methods and (optionally) a constructor. Typically used to define entities. | class Car { ... } |
| Function | A callable that accepts arguments and optionally returns a value. When defined inside of a class, a function is called a "method". Some functions are defined natively and execute C++ code. | event IsVehicle() { return true; } |
| Bound method | A method with arguments bound to it. | IsVehicle.bind(car); |
| Instance | An instance of a class. | new Car() |
| Entity | A game object in a scene. | Instance.Create("Car", 200.0, 192.0); |