I’ve been working with various languages over the years, from C to Objective‑C, Swift and even Assembly, and one thing I’ve learned is that the best way to get comfortable with a new language is to build something small but complete.

Lua is one of those languages that surprises you with simple syntax, yet incredibly powerful under the hood. Whether you want to embed it in your own apps, mod a game like Roblox, or just learn something lightweight and fast, this guide will help you get up and running quickly.
This post is structured so you can actually follow along in your own terminal or editor. Save the snippets as learnlua.lua and run them with:
lua learnlua.lua
Code language: Lua (lua)
If you don’t have Lua installed yet, check https://www.lua.org/download.html. You can also use JDoodle’s LUA Compiler directly in browser.
Getting Started with Lua
In Lua, everything begins with simple expressions. You can open the REPL (just type lua in your terminal) and start typing.
print('Hello from GeoSn0w!')
Code language: Lua (lua)
Everything is case sensitive, and semicolons are optional.
Variables are dynamically typed. You don’t declare them – Lua figures it out.
number = 365
language = 'Lua'
print('I am learning', language, 'with version', _VERSION)
Code language: Lua (lua)
Local variables exist only inside a block or function:
local day = 'Saturday'
print(day)
Code language: Lua (lua)
If you use a variable without declaring it as local, it becomes global by default.
Conditional Logic in Lua
Lua uses straightforward keywords for flow control.
local temp = 22
if temp > 30 then
print('Too hot')
elseif temp < 10 then
print('Too cold')
else
print('Just right')
end
Code language: Lua (lua)
Only false and nil count as false. Even 0 and empty strings are true.
Loops and Ranges in Lua
Counting up or down is simple.
for i = 1, 5 do
print('Count:', i)
end
for j = 10, 1, -2 do
print('Countdown:', j)
end
Code language: Lua (lua)
While loops also exist:
local n = 0
while n < 3 do
print('n =', n)
n = n + 1
end
Code language: Lua (lua)
Or repeat‑until, which always runs at least once:
repeat
print('Repeating once')
until true
Code language: Lua (lua)
Functions in Lua
Functions in Lua are first‑class, which means you can store them in variables or pass them around like data.
function greet(name)
return 'Hello, ' .. name
end
print(greet('Lua'))
Code language: Lua (lua)
Anonymous functions are useful for short callbacks:
local shout = function(msg)
print(string.upper(msg))
end
shout('lua is nice')
Code language: Lua (lua)
Functions can return multiple values:
function divide(a, b)
local q = math.floor(a / b)
local r = a % b
return q, r
end
local q, r = divide(17, 5)
print('quotient:', q, 'remainder:', r)
Code language: Lua (lua)
Tables: Lua’s Core Data Structure
Tables are everything in Lua – arrays, dictionaries, and objects.
Array‑style table
local numbers = {10, 20, 30}
for i = 1, #numbers do
print(numbers[i])
end
Code language: Lua (lua)
Dictionary‑style table
local phone = {model = 'iPhone', os = 'iOS', version = 18}
print('OS:', phone.os)
phone.year = 2025
for key, val in pairs(phone) do
print(key, '=', val)
end
Code language: Lua (lua)
You can remove keys by setting them to nil.
Metatables – Operator Overloading in Lua
You can make Lua behave like an object system by using metatables.
Vector = {}
Vector.__index = Vector
function Vector:new(x, y)
return setmetatable({x = x, y = y}, self)
end
function Vector.__add(a, b)
return Vector:new(a.x + b.x, a.y + b.y)
end
function Vector:__tostring()
return '(' .. self.x .. ', ' .. self.y .. ')'
end
local v1 = Vector:new(3, 4)
local v2 = Vector:new(5, 6)
print(v1 + v2)
Code language: Lua (lua)
Simulating Classes in Lua
There’s no class keyword in Lua. In fact, there are no classes at all so we cheat. We use the metatables in our favour.
Dog = {}
Dog.__index = Dog
function Dog:new(name)
local d = setmetatable({}, Dog)
d.name = name or 'Doggo'
return d
end
function Dog:bark()
print(self.name .. ' says Woof!')
end
local rex = Dog:new('Rex')
rex:bark()
Code language: Lua (lua)
Inheritance is easy to simulate too in Lua.
LoudDog = setmetatable({}, {__index = Dog})
function LoudDog:bark()
print(string.upper(self.name .. ' BARKS LOUDLY'))
end
local max = LoudDog:new('Max')
max:bark()
Code language: Lua (lua)
Modules and Files in Lua
Create a file named mathutils.lua:
local M = {}
function M.square(n)
return n * n
end
function M.cube(n)
return n * n * n
end
return M
Code language: Lua (lua)
Then import it:
local mathutils = require('mathutils')
print(mathutils.square(4))
print(mathutils.cube(3))
Code language: Lua (lua)
The require keyword runs the module once and caches it.
Error Handling in Lua
Use pcall to catch errors safely:
local ok, err = pcall(function()
error('Something went wrong')
end)
if not ok then
print('Caught error:', err)
end
Code language: Lua (lua)
Where do I go from here?
You’ve now got the fundamentals: variables, tables, loops, functions, and basic OOP. From here, you can:
- Use Lua with LÖVE for 2D game development.
- Embed Lua in your own C or C++ apps.
- Get into Roblox scripting and game dev.
- Explore LuaJIT for performance‑critical work.
- Dive into
Programming in Lua(official book).
Lua’s simplicity is its greatest strength. You can learn it in a day but spend years mastering its patterns.
My first contact with it was back in the PSP (PlayStation Portable) modding era! Who remembers those?
Final thoughts
When I first got into Lua, I used it to make PSP mods back in 2012. Over time, I started to appreciate how elegant it is for tooling and prototyping. If you’re new to programming, Lua teaches you how to think about data, not just syntax.
Of course, Roblox also uses Luau which is a fork of Lua so if you’re into making Roblox scripts and games / mods, this is absolutely a must.
So open your editor, run a few snippets, and tweak them. The best way to learn Lua is to break it, fix it, and make something fun with it.
Peace!