| name | gmloop-gml-syntax-basics |
| description | Understand and work with GameMaker Language (GML), including its syntax differences from JavaScript, GML-specific language constructs, data accessors, keywords, constants, and formatting conventions. |
Correctly interpret, generate, refactor, lint, format, and reason about GameMaker Language (GML) code.
GML is syntactically similar to JavaScript ES3, but differs significantly in semantics, runtime behavior, data structures, syntax rules, and language features.
GameMaker Language (GML) is fully case-sensitive in modern versions (GMS2/2.3+).
Treat GML as a JavaScript-like language with the following important differences and extensions.
Editing GameMaker project files
Do not make changes to .yy or .yyp files yourself.
It's very hard to correctly edit these manually!
GML reserved names
Your own names must avoid clashing with these (not an exaustive list):
score, lives, health
- Position:
x, y
- Sprite:
sprite_index, image_index, image_speed, image_xscale, image_yscale, image_angle, image_alpha, image_blend
- Physics:
speed, direction, friction, gravity, gravity_direction
- Collision:
bbox_left, bbox_right, bbox_top, bbox_bottom
- Instance:
id, object_index, layer, depth, visible, persistent
Object Model & Types
- GML uses
self instead of this
- GML calls objects "structs"
- GML calls numbers "reals"
- GML uses
pointer_null instead of null
- GML uses lowercase
infinity instead of Infinity
GML Naming conventions
- Use
snake_case for variables and functions (including global variables and functions)
- Use
PascalCase for constructor functions (structs)
- Use
UPPER_SNAKE_CASE for macros
- Prefix local variables with
_ (e.g., var _temp_value, var _effect)
- Prefix resource names based on their type, e.g.
obj_player, spr_player_face, snd_squish, etc.
Type & Instance Checks
GML uses specific, built-in functions for type checking instead of operators:
instanceof(value)
is_instanceof(value, SomeConstructor)
Instead of:
typeof value
value instanceof SomeConstructor
Variable Declarations
GML supports:
var
global.
globalvar (DEPRECATED)
static
GML does NOT support:
Example:
var my_value = 10;
global.global_score = 0;
static static_counter = 0;
Constructor Functions ("Structs")
GML does not use ES6 classes. Instead, from version 2.3 and above, GML has constructor functions, which have the constructor keyword between the parameters and the body:
function MyStruct(_value) constructor {
self.value = _value;
}
Strings
GML strings must use double quotes only.
Valid:
var name = "Henry";
Invalid:
var name = 'Henry';
For string concatenation, use the + operator:
var full_name = "Henry" + " " + "Smith";
For string interpolation, use $ at the start of the string, and {} for embedded expressions. Prefer to use string interpolation for readability over concatenation. For example:
var last_name = "Smith";
var full_name = $"Henry {last_name}";
Naming Rules
Identifiers:
- may contain alphanumeric characters and underscores
- must not begin with a number
Valid:
my_variable
_player2
Invalid:
2variable
my-variable
Struct Accessors
my_struct[$ "field"]
my_struct.field
struct_get(my_struct, "field")
ds_list Accessor
my_list[| 0]
ds_map Accessor
my_map[? "name"]
ds_grid Accessor
my_grid[# 5, 8]
Array Accessors
my_array[0]
my_array[@ 0]
// 1D array
array_get(my_array, 0);
// 2D array
array_get(my_array[0], 0);
// 3D array
array_get(my_array[0][0], 0);
The array @ accessor bypasses Copy-on-Write and performs in-place mutation on the original array. Using the @ accessor bypasses the 'Copy on Write' behaviour and directly modifies the referenced array. This can be used to selectively disable 'Copy on Write' for specific statements while keeping the option enabled. This is not necessary if the setting 'Copy on Write' is disabled (which is the default and recommended option).
Arrays, Strings, and Functions
Arrays, strings, and functions do NOT expose methods or properties via . accessors.
Use standalone functions instead.
Correct:
array_length(my_array)
string_length(my_string)
Incorrect:
my_array.length
my_string.length
Macros
GML supports compile-time macros using #macro.
Example:
#macro PLAYER_SPEED 4
Multi-line macros use trailing \:
#macro LONG_MACRO \
"part1" + \
"part2"
Macro references are expanded at compile time.
Macros but can include semicolons at the end of lines in multi-line macros, for example:
#macro __SCRIBBLE_GEN_WORD_NEW __SCRIBBLE_GEN_WORD_END;\
_word_width = 0;\
_word_glyph_start = _i;\
_word_bidi = _glyph_bidi;\
__SCRIBBLE_GEN_WORD_START;
Macros can be used in expressions with or without semicolons:
var speed = PLAYER_SPEED;
Operators
GML supports both symbolic and keyword forms. GML supports the following expression operators.
| Category | Operators | Notes |
|---|
| Assignment | = | Assignment. Legacy code may use = for comparison, but prefer == for equality. |
| Logical | &&, ||, ^^ | Boolean AND, OR, XOR. Keyword forms: and, or, xor. |
| Nullish | ??, ??= | Nullish means undefined or pointer_null. RHS of ?? only runs when needed. |
| Comparison | <, <=, ==, !=, >, >= | Return boolean values. |
| Bitwise | |, &, ^, <<, >> | Bitwise OR, AND, XOR, shift left, shift right. |
| Bitwise assignment | |=, &=, ^= | Apply bitwise operation and assign result. |
| Arithmetic | +, -, *, / | Add, subtract, multiply, divide. |
| Arithmetic assignment | +=, -=, *=, /= | Apply arithmetic operation and assign result. |
| String concatenation | +, += | Both operands must be strings unless explicitly converted. |
| Increment/decrement | ++, -- | Prefix and postfix forms differ. Avoid complex mixed expressions. |
| Division/modulo | div, %, mod, %= | div is integer division. mod and % are equivalent modulo operators. |
| Unary | !, -, ~ | Logical NOT, numeric negation, bitwise negation. Note: The parser strictly rejects not when used as a logical operator (use ! instead). The name not is allowed as a user-defined identifier (e.g., variables, macros, or call expressions like not(value)). Invalid usages of not as a logical operator are repaired to ! by the linter's recovery pre-processor and operator alias normalization rule. |
| Conditional | <condition> ? <expression1 (if true)> : <expression2 (if false)> | Ternary conditional expression. Nested conditionals should be parenthesized. |
Binary Literals
var _six = 0b0010 | 0b0100; // produces 0b0110, or 6
Hexadecimal Literals
$abcd
0xabcd
Documentation Comments
GML JSDoc-style comments use triple slash syntax:
/// @desc This function does something important with the value.
/// @param {real} value
/// @returns {real}
Regions
Code-folding regions use:
#region My region
// ...many lines of code...
#endregion
#region My 2nd region
// ...many lines of code...
#endregion End of my 2nd region
Control Flow Keywords
if
then
else
switch
case
default
while
do
for
repeat
until
break
continue
exit
return
begin, end (legacy block delimiters, equivalent to braces)
Struct & Function Keywords
function
constructor
new
delete
enum
Exception Handling Keywords
Miscellaneous Keywords
#macro
#region
#endregion
Boolean & Numeric Constants
true
false
pi
NaN
infinity
Variable Scope Keywords
global
globalvar (DEPRECATED)
static
var
Instance & Scope Keywords
self
other
with
noone
all
Pointer & Undefined Values
undefined
pointer_invalid
pointer_null