Luau

Introduction

BBOC integrates the Luau programming language, a derivative of the original Lua programming language. Luau adds new features and improvements such as typing or new operators.

Integration

The engine itself lightly wraps the Luau C API implemented in C++ around (thus being a C++ wrapper wrapping a C API implemented in C++). That is, we only have simplified some methods of the API to be more C+±esque (notably with templates), without being too far apart from the original API.

We thus strongly recommend you to read the Lua 5.1 Reference Manual to understand how Lua (and Luau by extension) works at its core; we won’t cover the basics of either the end user language or the C API in this documentation since the aforementioned link would be a better source for that anyway.

We do not sandbox the environment in any way as of now, since we trust the end developer to not do anything malicious with the API. This is partly due to the Class System we provide, but also how the API integrates and interacts with native Luau classes and objects in general.

Class System

Our integration provides a built-in system to support an object oriented programming style, complete with metamethods and inheritance similar to what Python would provide to its end users, but adapted for Luau and its type system.

Class Prototype

Declaration

Declaring a new class is pretty straightforward. Starting from the base class Class, you can create a new class like so:

-- Create a new class named `MyClass`
MyClass = Class:extend()

You can then provide a constructor to that class:

-- Exclusive 'self' parameter version
function MyClass.__init__(self, value)
    self.value = value
end

-- Inclusive 'self' parameter version
function MyClass:__init__(value)
    self.value = value
end

Note

The two versions of the constructor are equivalent. The inclusive version is just a shorthand for the exclusive version. You can choose either of the two, but we recommend that you stick consistently to one of them in your code.

From now on, we will use the inclusive version for the sake of brevity.

This then allows you to create a new instance of MyClass, with the constructor being mapped internally to the __call metamethod:

local myInstance = MyClass(42)
print(myInstance.value) -- 42

Warning

Omitting the __init__ method prevents the class from being instantiated. If you want an object with no constructor parameters, you can simply provide an empty __init__ method.

Other metamethods may be available in the future, but for now, only __init__ is supported.

Members

Just like with the constructor, new member methods can be added as well:

function MyClass:printValue()
    print(self.value)
end

function MyClass:printSelf()
    print(self)
end

These member methods can then be accessed from an instance of the class:

local myInstance = MyClass(42)
myInstance:printValue() -- 42
myInstance:printSelf() -- table: 0x1234567890

Any primitive Lua/Luau type can be stored in the class prototype, including functions, tables, numbers, etc:

MyClass.MY_CONSTANT = 42

function MyClass:__init__(value)
    self.value = value
    self.somethingElse = { 1, 2, 3 }
end

Inheritance

A class can inherit from another class by calling the extend method on the parent class, the same as you would do when creating regular classes:

MySubClass = MyClass:extend()

function MySubClass:amIInherited()
    print("Yes, you are!")
end

local mySubInstance = MySubClass(42)
mySubInstance:printValue() -- 42
mySubInstance:amIInherited() -- Yes, you are!

Type Checking

Once you are done declaring the prototype of a class, you can use the built-in Luau typeof keyword to make the type available to the environment:

export type MyClass = typeof(MyClass)
export type MySubClass = typeof(MySubClass)