👑 Premium Sign in Sign up

Language lab · Beginner → Scripting

🌙 Lua

Concept → trace → write code → run tests → explain why → improve → mini-project. Start in the browser if you like; set up your own computer when you are ready.

💻 Runs on your computerOfficial download & docs ↗

📖 Topics with real code (13)

Every verified output below was produced by running the code with Lua 5.4.9 Copyright (C) 1994-2026 Lua.org, PUC-Rio on 6 Nov 2026. Open a topic to edit the code and run it right here in your browser.

🌱 Beginner (5)

Variables and types

Lua has nil, boolean, number (integer and float), string, table and function. local keeps a variable inside its block. type() shows the type; tonumber and tostring convert.

local age = 15
local height = 1.62
local student = true
local name = "Asha"
print(name, age, height, student)
print(type(age), type(height), type(student), type(name), type(nil), math.type(age), math.type(height))
print(tonumber("88") + 2, 7 // 2, 7 / 2, tostring(90) .. "!")

✅ Verified output

Asha	15	1.62	true
number	number	boolean	string	nil	integer	float
90	3	3.5	90!
Operators and boolean logic

.. joins strings, // is floor division, ~= means "not equal". and/or return one of their operands, which gives a handy default idiom.

local a, b = 17, 5
print(a + b, a - b, a * b, a / b, a // b, a % b, a ^ 2)
print(a == b, a ~= b, not true)
local nickname = nil
print(nickname or "no nickname", false and "x" or "default")

✅ Verified output

22	12	85	3.4	3	2	289.0
false	true	false
no nickname	default
Conditionals

if … then … elseif … else … end. Only nil and false are false: 0 and "" are true in Lua.

local marks = 78
local grade
if marks >= 90 then grade = "A+"
elseif marks >= 75 then grade = "A"
elseif marks >= 35 then grade = "Pass"
else grade = "Fail" end
print("Grade: " .. grade)
if 0 then print("0 is true in Lua") end

✅ Verified output

Grade: A
0 is true in Lua
Loops

Numeric for (start, stop, step), generic for with ipairs/pairs, while and repeat…until. goto continue is a common way to skip a turn.

for i = 1, 5 do
  if i == 3 then goto continue end
  print("for " .. i)
  ::continue::
end
local n = 10
while n > 0 do
  if n < 4 then break end
  print("while " .. n)
  n = n - 3
end
local k = 0
repeat k = k + 1 until k >= 3
print("repeat ran " .. k .. " times")

✅ Verified output

for 1
for 2
for 4
for 5
while 10
while 7
while 4
repeat ran 3 times
Functions

Functions are values. They can take a variable number of arguments (...) and return several results.

local function area(length, width)
  width = width or 1
  return length * width
end
local function stats(...)
  local t, sum = { ... }, 0
  for _, v in ipairs(t) do sum = sum + v end
  return math.min(...), math.max(...), sum / #t
end
print(area(5, 3), area(7))
print(stats(4, 9, 2, 7))

✅ Verified output

15	7
2	9	5.5

🌿 Intermediate (5)

Tables as arrays

Tables are Lua's only data structure. As arrays they are 1-based; # gives the length; table.insert, table.sort and table.concat help.

local marks = { 72, 95, 64, 88 }
table.insert(marks, 91)
table.sort(marks)
print(table.concat(marks, ", "), "first " .. marks[1], "last " .. marks[#marks])
local squares = {}
for x = 1, 5 do if x % 2 == 1 then squares[#squares + 1] = x * x end end
print(table.concat(squares, " "))

✅ Verified output

64, 72, 88, 91, 95	first 64	last 95
1 9 25
Tables as dictionaries

Tables also map keys to values. pairs walks all keys (in no fixed order, so sort keys to print).

local stock = { pen = 40, book = 12 }
stock.eraser = 25
stock.pen = stock.pen - 5
local keys = {}
for k in pairs(stock) do keys[#keys + 1] = k end
table.sort(keys)
for _, k in ipairs(keys) do print(k, stock[k]) end
local freq = {}
for w in ("the cat and the hat and the bat"):gmatch("%a+") do freq[w] = (freq[w] or 0) + 1 end
print("the=" .. freq.the, "and=" .. freq["and"])

✅ Verified output

book	12
eraser	25
pen	35
the=3	and=2
Strings and patterns

string functions can be called with : on any string. Lua patterns (%d digits, %a letters) power find, match and gsub.

local t = ("  GayaGnan learning  "):match("^%s*(.-)%s*$")
print(t:upper(), t:gsub("learning", "labs"), #t)
print(string.format("Total: %.2f for %d items", 49.5 * 3, 3))
print(("level"):reverse() == "level")
for num in ("a1b22c333"):gmatch("%d+") do io.write(num, " ") end
print()

✅ Verified output

GAYAGNAN LEARNING	GayaGnan labs	17
Total: 148.50 for 3 items
true
1 22 333
Objects with metatables

Lua has no classes, but metatables and __index give objects and inheritance. The : syntax passes self.

local Account = {}
Account.__index = Account
function Account.new(owner, balance) return setmetatable({ owner = owner, balance = balance or 0 }, Account) end
function Account:deposit(amount)
  assert(amount > 0, "amount must be positive")
  self.balance = self.balance + amount
  return self
end
local acc = Account.new("Asha", 500):deposit(250)
print(acc.owner, acc.balance)
local Savings = setmetatable({}, { __index = Account })
Savings.__index = Savings
function Savings:addInterest() return self:deposit(self.balance * 0.05) end
local s = setmetatable(Account.new("Ravi", 1000), Savings)
print(s:addInterest().balance)

✅ Verified output

Asha	750
1050.0
Errors with pcall

error() raises an error; pcall runs a function in protected mode and returns false plus the message instead of crashing.

local function withdraw(balance, amount)
  if amount > balance then error("need " .. (amount - balance) .. " more", 0) end
  return balance - amount
end
print(pcall(withdraw, 100, 30))
print(pcall(withdraw, 100, 150))
local ok, err = pcall(function() return nil + 1 end)
print(ok, (err:gsub("^.-:%d+: ", "")))

✅ Verified output

true	70
false	need 50 more
false	attempt to perform arithmetic on a nil value

🌳 Advanced (3)

Closures

An inner function keeps access to the outer function's local variables. Each counter below has its own count.

local function makeCounter(step)
  local count = 0
  return function() count = count + (step or 1); return count end
end
local byOne, byTen = makeCounter(), makeCounter(10)
byOne(); byOne()
print(byOne(), byTen(), byTen())
local function compose(f, g) return function(x) return f(g(x)) end end
print(compose(function(x) return x + 1 end, function(x) return x * 2 end)(5))

✅ Verified output

3	10	20
11
Recursion and memoization

A cache table makes recursive Fibonacci fast. Lua 5.4 integers are 64-bit.

local memo = {}
local function fib(n)
  if n < 2 then return n end
  if not memo[n] then memo[n] = fib(n - 1) + fib(n - 2) end
  return memo[n]
end
local out = {}
for i = 0, 9 do out[#out + 1] = fib(i) end
print(table.concat(out, " "), fib(80))

✅ Verified output

0 1 1 2 3 5 8 13 21 34	23416728348467685
Coroutines

Coroutines pause with yield and resume later: cooperative multitasking used by game engines and network servers.

local producer = coroutine.wrap(function()
  for i = 1, 3 do coroutine.yield("item " .. i) end
  return "done"
end)
print(producer()); print(producer()); print(producer()); print(producer())
local co = coroutine.create(function(a, b) local c = coroutine.yield(a + b); return c * 2 end)
print(coroutine.resume(co, 2, 3))
print(coroutine.resume(co, 10))
print(coroutine.status(co))

✅ Verified output

item 1
item 2
item 3
done
true	5
true	20
dead

🛠️ Set up and verify

  1. Install
    winget install DEVCOM.Lua
    brew install lua
    sudo apt install lua5.4
  2. Editor: Visual Studio Code with Lua (sumneko).
  3. Create hello.lua
    print('Hello, GayaGnan!')
  4. Run it and check the version
    hello.lua
    lua -v
  5. Health check: paste what your terminal printed.

Install one language at a time. These commands only install or print versions; nothing here deletes files. Versions change: check the official page and note the version you installed.

🧭 The 14-lab path

  • 00 · Setup and verify — install the runtime and editor, run hello world, print the version, fix PATH
  • 01 · Syntax and trace — follow each line and the value of every variable
  • 02 · Logic — conditionals and decision trees
  • 03 · Loops — trace tables and loop challenges
  • 04 · Functions — break problems down and test each piece
  • 05 · Data structures — lists, maps, stacks, queues and trees you can see
  • 06 · Debugging — bug cases with a hint ladder
  • 07 · Algorithms — search, sort and Big-O comparison
  • 08 · Files and data — read and write fixture files
  • 09 · API or database — talk to a mock API or a sandbox database
  • 10 · Testing — write tests and read failing assertions
  • 11 · Security — secure coding and dependency hygiene for this language
  • 12 · Project — one portfolio mini-project
  • 13 · Assessment — quiz, coding test, rubric and an explain-your-answer prompt

📚 Modules

  1. types
  2. operators
  3. conditionals
  4. loops
  5. functions
  6. tables as arrays
  7. tables as dictionaries
  8. strings and patterns
  9. metatables
  10. pcall
  11. closures
  12. memoization
  13. coroutines

🏗️ Mini-projects

  • Text adventure game
  • Config-file parser
  • Game-engine scripting (concepts)

Projects use synthetic data only.