-
Notifications
You must be signed in to change notification settings - Fork 0
Type System
ffredyk edited this page Jul 23, 2026
·
1 revision
SQ# uses a tagged union (SqValue) with explicit runtime types. Every value carries its type — no implicit coercion, no silent failures.
| Type | C# Storage | Description | Example |
|---|---|---|---|
Nothing |
— | Type of nil. "No value." |
nil |
Boolean |
double (0.0/1.0) |
True or false |
true, false
|
Number |
double (IEEE 754) |
Floating-point number |
42, 3.14, -2.5e10
|
String |
string (interned) |
Text, immutable |
"hello", 'hello'
|
Array |
SqArray |
Dynamic, mutable, by-reference | [1, 2, 3] |
Code |
SqCode |
Compiled bytecode chunk | { _x * 2 } |
HashMap |
SqHashMap |
Key-value dictionary | createHashMap |
Namespace |
SqNamespace |
Named global variable store | missionNamespace |
ScriptHandle |
SqScriptHandle |
Async operation handle (promise) | spawn { ... } |
Error |
SqError |
Caught error object | from try/catch
|
Shared |
SqSharedValue |
CAS-based atomic variable | shared _counter = 0 |
FrozenArray |
Immutable array | Read-only snapshot | freeze _arr |
Host applications can register custom types:
host.RegisterObjectType("Entity", id => new SqValue((double)id));| Host Type | Description |
|---|---|
Object |
Game entity (unit, vehicle, etc.) |
Group |
Group of entities |
Side |
Side/faction enum |
Config |
Configuration path reference |
Control |
UI control |
Display |
UI display |
Location |
Map location |
StructuredText |
Rich XML text |
nil — nular operator, returns Nothing value
Nothing — type of nil. "No value."
Void — state of undefined variable. NOT same as nil.
// nil DELETES variables (SQF behavior):
_myVar = nil; // _myVar becomes Void — DELETED
isNil "_myVar"; // true
// nil is still a valid VALUE in arrays and comparisons:
private _arr = [1, nil, 3];
if (_arr select 1 == nil) then { ... }; // truetypeName 42; // "number"
typeName "hello"; // "string"
typeName [1, 2, 3]; // "array"
typeName nil; // "nothing"
typeName { sleep 1; }; // "code"
typeName true; // "boolean"
typeName createHashMap; // "hashmap"switch (typeName _value) do {
case "number": { processNumber(_value); };
case "string": { processString(_value); };
case "array": { processArray(_value); };
default { print "Unknown type"; };
};// Compile-time type assertion:
_arr params [["_hp", "number"], ["_name", "string"]];
// Throws if types don't match at runtimeFor conditionals (if, while, &&, ||):
-
Falsy:
false,nil,0 - Truthy: everything else (non-zero numbers, non-empty strings, arrays, code, etc.)
if (42) { ... }; // truthy — runs
if (0) { ... }; // falsy — doesn't run
if ("") { ... }; // falsy — doesn't run
if ([]) { ... }; // truthy — runs (non-nil array)SQ# does NOT coerce types implicitly. Unlike SQF:
// SQF: "123" == 123 might work (inconsistently)
// SQ#: strict comparison — "123" == 123 is false
"123" == 123; // false (string ≠ number)
// Explicit conversion:
parseNumber "123"; // 123 (string → number)
str 42; // "42" (number → string)All values in SQ# are represented by SqValue:
public readonly struct SqValue
{
public SqType Type { get; }
public bool AsBool();
public double AsNumber();
public string AsString();
public SqArray AsArray();
public SqCode AsCode();
// ...
}Valid HashMap key types and their hashing:
| Key Type | Hashing |
|---|---|
| Number, Boolean, String | Value hashing |
| NaN | Hashable sentinel |
| Code, Config, Namespace, Side | Identity hashing (reference equality) |
| Array | Must be frozen to be a key |
_map set [42, "answer"]; // OK
_map set [mutableArray, 2]; // THROWS
_map set [freeze mutableArray, 1]; // OK- Language Guide — syntax and operators
- Arrays & Collections — arrays, hashmaps, namespaces
- Functions & Code — code blocks as values
- isNil — nil check command
- typeName — get type name
- str — value to string conversion
- Getting Started
- Language Guide
- Type System
- Control Flow
- Functions & Code
- Strings & Text
- Arrays & Collections
- Concurrency
- Promise System
- Thread Safety
- Host API & Embedding
- CLI Tool
- Bytecode Reference
- Multiplayer
- Syntax Sugar
- Optimization Guide
- Benchmarks
- count
- select
- pushBack
- append
- deleteAt
- deleteRange
- resize
- reverse
- sort
- find
- in
- forEach
- freeze
- thaw
- isFrozen
- currentScheduler
- clientOwner
- allSchedulers
- schedulerName
- schedulerExists
- schedulerBudget
- setSchedulerBudget
- fiberCount
- readyFiberCount
- waitingFiberCount
- schedulerLoad
- sendTo