Skip to content

Lexical structure

Compiles

This page covers the building blocks the rest of the language is made of: how to write a comment, a name, a number or a piece of text, and where one statement ends and the next begins.

// A line comment runs to the end of the line.
/* A block comment runs until it is closed,
and may span several lines. */
let answer = 42 // Comments can follow code, too.

Use comments to say why. The code already says what.

Names of fields, functions and variables are made of letters, digits and underscores, and may not start with a digit. They are case-sensitive: score and Score are different names.

The convention everywhere in the game is snake_case: lowercase words joined by underscores (cooldown_seconds, find_player_entity). Engine types are the exception and are capitalised: Entity, Component, User, Reference.

These words are keywords and can’t be used as names:

fn let mut if else while for in switch break continue return enum event virtual override export const controlled super as true false null

A literal is a value written directly in the code.

Kind Examples Notes
Whole number (int) 0, 42, -7, 0xFF 0x starts a hexadecimal number.
Decimal number (float) 1.5, 0.25, -3.0 Needs a digit on both sides of the dot: write 0.5, not .5.
Text (string) "hello", "line\nbreak" Always double quotes.
True or false (bool) true, false
Nothing null “No entity”, “no component”, “no value”.
List [], [1, 2, 3], [name, score] See Lists and strings.
Vector vec3(0, 0, 100) Numbers only; see Types.

Inside a string, a backslash starts an escape: \n new line, \t tab, \" a quote, \\ a backslash. Any other character after a backslash is an error.

let message = "She said \"catch!\"\nand threw."

A statement ends at the end of its line. You may put a ; there, but you don’t have to: the language inserts one for you. Both of these are the same:

let a = 1;
let b = 2;
let c = 3
let d = 4

A line break does not end a statement when the statement obviously continues:

  • inside ( … ) or [ … ], because an argument list or a list can spread over many lines;
  • when the next line starts with something that can only continue: an operator like +, && or ==, a ., a ,, {, else, => or as.
let total = 100
+ 20
+ 3
let names = [
"plaza",
"garage",
]
✗ Doesn't work
let health = 100
- damage
✓ Works
let health = 100 -
damage

Two statements on one line need a ; between them: let a = 1; let b = 2.

For programmers

The rule is Go’s automatic semicolon insertion, extended so a line starting with a binary operator (other than -), ., ,, {, else, =>, as, :: or : continues the previous one, and never inserted while ( or [ is open. Braces do not suppress it; the parser tolerates the extra ; after a }.