Like2D Logo Like2D
← Back to Docs

Luau Guide

What is Luau?

Luau is a fast, small, safe, gradually typed embeddable scripting language derived from Lua. It's developed by Roblox and used in Like2D for game scripting.

Getting Started with Luau

Hello World

print("Hello, Like2D!")

Variables

-- Local variable (recommended)
local x = 10

-- Global variable
y = 20

-- Multiple assignment
local a, b = 1, 2

-- Type annotations (Luau feature)
local name: string = "Player"
local health: number = 100
local isAlive: boolean = true

Data Types

Tables

Tables are the only data structure in Luau. They can be used as arrays, dictionaries, or objects:

Array-style tables

local fruits = {"apple", "banana", "cherry"}
print(fruits[1])  -- apple (indices start at 1!)

Dictionary-style tables

local player = {
    name = "John",
    health = 100,
    x = 400,
    y = 300
}
print(player.name)  -- John
print(player.health)  -- 100

Object-oriented style

local Player = {}
Player.__index = Player

function Player.new(name, x, y)
    local self = setmetatable({}, Player)
    self.name = name
    self.x = x
    self.y = y
    self.health = 100
    return self
end

function Player:move(dx, dy)
    self.x = self.x + dx
    self.y = self.y + dy
end

function Player:takeDamage(amount)
    self.health = self.health - amount
end

-- Usage
local player1 = Player.new("Player1", 400, 300)
player1:move(10, 0)
player1:takeDamage(20)
print(player1.health)  -- 80

Functions

-- Basic function
function add(a, b)
    return a + b
end

-- Local function (recommended)
local function multiply(a, b)
    return a * b
end

-- Multiple return values
local function getNameAndAge()
    return "Alice", 30
end
local name, age = getNameAndAge()

-- Variable arguments
local function sum(...)
    local total = 0
    for i, v in ipairs({...}) do
        total = total + v
    end
    return total
end
print(sum(1, 2, 3, 4))  -- 10

Control Flow

If statements

local x = 10

if x > 0 then
    print("x is positive")
elseif x < 0 then
    print("x is negative")
else
    print("x is zero")
end

For loops

-- Numeric for
for i = 1, 10 do
    print(i)
end

-- Numeric for with step
for i = 10, 1, -1 do
    print(i)
end

-- Generic for (ipairs for arrays)
local fruits = {"apple", "banana", "cherry"}
for i, fruit in ipairs(fruits) do
    print(i, fruit)
end

-- Generic for (pairs for dictionaries)
local player = {name = "John", health = 100}
for key, value in pairs(player) do
    print(key, value)
end

While loops

local i = 1
while i <= 10 do
    print(i)
    i = i + 1
end

Repeat-until loops

local i = 1
repeat
    print(i)
    i = i + 1
until i > 10

String Manipulation

local str = "Hello, Like2D!"

-- Length
print(#str)  -- 14

-- Concatenation
local greeting = str .. " How are you?"

-- String functions
print(string.upper(str))  -- HELLO, LIKE2D!
print(string.lower(str))  -- hello, like2d!
print(string.sub(str, 1, 5))  -- Hello
print(string.find(str, "Like2D"))  -- 8

Math Library

print(math.pi)  -- 3.14159...
print(math.abs(-5))  -- 5
print(math.floor(3.7))  -- 3
print(math.ceil(3.2))  -- 4
print(math.sqrt(16))  -- 4
print(math.random())  -- Random number between 0 and 1
print(math.random(1, 10))  -- Random integer between 1 and 10

-- Set random seed
math.randomseed(os.time())

Table Library

local t = {3, 1, 4, 1, 5}

-- Insert
table.insert(t, 6)  -- t becomes {3, 1, 4, 1, 5, 6}
table.insert(t, 2, 9)  -- t becomes {3, 9, 1, 4, 1, 5, 6}

-- Remove
table.remove(t, 2)  -- t becomes {3, 1, 4, 1, 5, 6}

-- Sort
table.sort(t)  -- t becomes {1, 1, 3, 4, 5, 6}

-- Get length
print(#t)  -- 6

Luau in Like2D

In Like2D, you write your game logic in Luau. The framework provides callback functions that you implement and a special function for including other files:

Including Other Files (dofile)

To keep your project organized, you can split your code into multiple .luau files and include them using dofile() at the top of your main.luau:

-- main.luau
dofile("anim.luau")
dofile("scripts/utils.luau")

Note: This is much better than having a single 5,000-line file!

Callback Functions

Like2D calls these global functions automatically. Implement them in your main.luau:

-- Called once at startup — load assets and set up state
function onInit()
    setWindowTitle("My Game")
    setWindowSize(800, 600)
    loadImage("assets/player.png")
    loadSound("bgm", "assets/music.mp3")
    playSound("bgm", true)
end

-- Called every frame BEFORE onDraw() — game logic, input, physics
function onUpdate(dt)
    -- dt = seconds since last frame (~0.016 at 60 FPS)
    if isKeyDown("Right") then
        playerX = playerX + 200 * dt
    end
end

-- Called every frame for rendering — draw everything here
function onDraw()
    clearScreen(20, 20, 30)
    renderImage("assets/player.png", playerX, playerY, 64, 64)
    drawTextDirect("Score: " .. score, 10, 10, 24, 255, 255, 255, 255)
end

-- Called once when closing — cleanup and save
function onCleanup()
    unloadSound("bgm")
    print("Game ended")
end

Best Practices

Learning More