Luau Guide

Overview

OVERDARE Studio uses Luau, a scripting language extended from Lua. While preserving most of Lua's syntax and functionality, Luau introduces a wide range of features, such as Type Annotations, Type Inference, Compound Assignment, and If Expressions.

These extensions allow developers to write safer and more flexible logic while maintaining high productivity and expressiveness.

Note

  • Type-based autocompletion is partially supported at the moment, and some information may not appear in the autocomplete list.

  • Type inference is partially supported at the moment, and some types may not be accurately recognized.

Type Annotations

Variables

When declaring local variables, you can specify their types as below (except when declaring global variables).

local Gold: number = 1

Functions

You can specify function parameters and return values' types as below (can be used for global functions).

local function Sum(a: number, b: number): number
    return a + b	
end
print(Sum(1, 2))

function AddScalarToVector3(v: Vector3, scalar: number): Vector3
    return Vector3.new(v.X + scalar, v.Y + scalar, v.Z + scalar)
end
local Pos = Vector3.new(50, 0, 10)
print(AddScalarToVector3(Pos, 100))

Variadic Functions

Even variadic functions such as (...) can be annotated with types.

Tables

Table types can be defined using {}, and you can specify the types for each field in braces to fix the types of values found in a table.

Table type can also define the types of key and values.

Instance

Objects such as Player, Part, and Instance can also be assigned with types.

Type Checking

Autocomplete Integration

By declaring types for variables or functions, the autocomplete function will also display type information while coding, preventing errors and improving code maintainability.

Inference Modes

You can specify the type inference modes such as --!nonstrict at the top of the script.

Inference Modes
Features

--!nocheck (default)

Completely disables type checking.

--!nonstrict

Checks only the explicitly specified types.

--!strict

Infers and checks types for every code.

--!nocheck

The default state where type checking does not function. (Type errors are ignored, and type inference or warnings do not occur.)

--!nonstrict

Checks only explicitly specified types, and skips variables or functions without specified types.

--!strict

Infers and checks types for every code. Even without specified types, it infers automatically to detect errors.

Flexible Type System

Optional Type

Appending ? after a type makes it optional. Optional types accept both the specified types and nil values.

Type Cast

An error may occur if you assign values to variables of different types. In such cases, you can explicitly cast the type using the :: operator to avoid type errors.

Literal Type Specification

Types such as string or boolean can be specified as literals, allowing them to be used like constants.

Unions and intersections

Using union and intersection types, you can allow a variable to accept multiple types or define a new composite type by combining multiple types.

Union types use the | operator to allow a variable to have a single value among multiple types.

Intersection types use the & operator to define a composite object type by combining multiple types. (Each type must be defined using the type keyword before combining.)

Syntax & Expressions

Compound Assignment

You can use compound assignment listed in the table below to combine operations and assignments into a single statement, which allows code to be written more concisely and efficiently.

However, unlike in other languages, compound assignments cannot be used in expressions such as print (a += 2). They must be written as separate statements like a += 2.

Operator
Features

+=

a = a + b

-=

a = a - b

*=

a = a * b

/=

a = a / b

//=

a = a // b

%=

a = a % b

^=

a = a ^ b

..=

a = a .. b

if Expressions

You can insert literal values within conditional branches to return values immediately based on the conditions.

continue Keyword

Within a loop statement such as for or while, the continue keyword can be used to skip the current loop and move on to the next.

String interpolation

You can use backticks (`) to dynamically insert variables or expressions within braces.

Loop Statement

Generic For Loops

Without explicitly using iterators like ipairs or pairs, you can directly traverse collections like tables using the for ... in syntax. This can also be applied to array or dictionary structures.

Generalized Iteration

By implementing the __iter metamethod, you can embed iterator logic directly within a table, enabling user-defined iteration behavior.

User-Defined Types

Type

You can declare user-defined types using the type keyword. This allows for safer and more efficient management of complex data structures such as monsters, skills, or tiles.

You can also use a function type across multiple functions, helping to maintain consistent function structures and enabling broader extensibility.

Type Exports

When you use the export type keyword, types defined in module scripts can be separated and managed for use outside the module.

Generic

Generics

By defining generic types using <T>, you can dynamically specify the input type. This makes it possible to express and reuse various forms of data structures flexibly through a single type definition.

Function Generics

By applying generics to a function's parameters, the type of the data being passed can be dynamically specified at the time of the function call, enabling both high code reusability and type safety.

Libraries

Some of Lua's standard libraries, such as io and package, have been removed, while libraries like table and string have been extended. (More details on the libraries will be provided in the future.)

Table Cloning Function

String Splitting Function

Exit Coroutine

Task

Learn More

Conveniently Managing Coroutine Using Task

Last updated