Appendices: Projects, Interview Questions, Cheat Sheet & Resources
Capstone projects, interview questions, a Lua cheat sheet, Lua for developers coming from other languages, and resources with a study plan.
Appendix A: Capstone Projects
Beginner: Text Adventure Game. Tables for rooms and items, a command parser with string patterns, game state, save/load to a file.
Beginner: To-Do CLI. Read and write a Lua-table or JSON file, arg parsing, sorting, and filtering.
Intermediate: Word Frequency and Text Stats Tool. io.lines, gmatch, UTF-8 handling, sorted output, unit tests with busted.
Intermediate: Class Library + Data Structures. Implement class(), Stack, Queue, Heap, LinkedList, and Set with metamethods (__add for union, __tostring), with full tests.
Intermediate: Expression Evaluator. A tokenizer with patterns, a recursive-descent parser, an AST evaluator, variables, and a REPL; then rewrite the parser with LPeg.
Intermediate: Coroutine Task Scheduler. Sleep/wait primitives, channels, timeouts, an event system; simulate concurrent "processes".
Advanced: 2D Game in LÖVE. Game states, sprites/animation, collisions (bump.lua), audio, saved high scores, packaged .love distribution.
Advanced: Neovim Plugin. A plugin with commands, keymaps, autocmds, async jobs (vim.system/vim.uv), configuration via setup(), published on GitHub.
Advanced: API Gateway Plugin with OpenResty. JWT authentication, rate limiting with lua_shared_dict or Redis, request logging, tests with Test::Nginx.
Advanced: Embedded Scripting Engine. A C/C++ (or Rust with mlua) host application exposing a userdata API to sandboxed Lua scripts, with instruction and memory limits and hot reload.
Advanced: Native Module. A C module (or LuaJIT FFI binding) wrapping a C library (e.g., zlib or SQLite), with userdata, __gc, and a rockspec.
Open Source: Publish a Rock. A well-documented library with busted tests, luacheck, StyLua, CI across Lua 5.1/5.4/LuaJIT, and a LuaRocks release.
Appendix B: Interview Questions
What are Lua's eight types? What are integer and float subtypes?
Which values are falsy in Lua?
local vs global variables: how are globals stored, and why prefer locals?
Why do Lua arrays start at 1? What does #t return for tables with holes?
What's the difference between . and : when calling functions?
pairs vs ipairs?
How does and/or evaluation work? What's wrong with a and b or c?
How do you concatenate strings efficiently?
How do multiple return values and varargs work? What does select('#', ...) do?
How do you write continue in Lua?
What are closures and upvalues? Give a counter example.
How does the generic for work? Write a stateless and a stateful iterator.
How do Lua patterns differ from regular expressions? What do %b and %f do?
What are metatables? Explain __index (table vs function) and __newindex.
How do you implement classes and inheritance? Why must metamethods be copied to subclasses?
What are rawget/rawset for?
How does require find and cache modules?
pcall vs xpcall vs error levels? When do you return nil, err instead of raising?
What are weak tables and ephemerons? Give use cases.
What is _ENV (5.2+) vs setfenv (5.1)?
Explain coroutines: create, resume, yield, wrap, status. Are they threads?
How do you implement generators, pipelines, and async/await with coroutines?
What are <const> and <close> variables in Lua 5.4?
How does Lua's garbage collector work? Incremental vs generational?
How do you build a secure sandbox for untrusted Lua code?
Explain the Lua C API stack. How do you call Lua from C and C from Lua?
What is userdata? Full vs light userdata? How do you attach methods?
What is the registry, and what are luaL_ref/luaL_unref for?
What is LuaJIT? How does the FFI work? What are its compatibility limitations?
What are Luau, Teal, MoonScript, and Fennel?
How do you optimize Lua code?
What changed between Lua 5.1, 5.2, 5.3, and 5.4?
Implement split(str, sep) that handles empty fields and special characters.
Write a deep copy that handles cycles and metatables.
Implement a class() function with inheritance and super calls.
Write an LRU cache using a table and a doubly linked list.
Implement a read-only proxy table.
Write a coroutine-based producer/consumer pipeline.
Implement memoization with a weak-valued cache.
Write a C function callable from Lua that sums a table of numbers.
Appendix C: Lua Cheat Sheet
-- ===== Variables & types =====
local x = 10; local s = "str"; local t = {}; local f = function() end
type(x); math.type(x); tostring(x); tonumber("42"); local a, b = 1, 2; a, b = b, a
local PI <const> = 3.14159 -- 5.4
-- ===== Strings =====
"a" .. "b"; #s; s:upper(); s:sub(2, 4); s:find("x", 1, true); s:match("(%d+)"); s:gsub("a", "b")
for w in s:gmatch("%a+") do end; string.format("%5.2f %s %d", 1.5, "x", 3); s:rep(3); [[long]]
-- ===== Tables =====
local arr = {1, 2, 3}; local dict = {k = "v", ["key with space"] = 1}
arr[#arr + 1] = 4; table.insert(arr, 1, 0); table.remove(arr); table.sort(arr, function(p, q) return p < q end)
table.concat(arr, ","); table.unpack(arr); table.pack(...); next(t) == nil -- empty check
-- ===== Control flow =====
if c then elseif d then else end
for i = 1, 10, 2 do end; for i, v in ipairs(arr) do end; for k, v in pairs(dict) do end
while c do end; repeat until c; break; goto continue; ::continue::
-- ===== Functions =====
local function add(p, q) return p + q end
local function va(...) local n = select("#", ...); local args = {...} end
local function multi() return 1, 2 end; local m1, m2 = multi()
obj:method(args) --
…lua script.lua lua -i lua -e "print(1)" luac -l file.lua luarocks install pkg busted luacheck . stylua .Appendix D: Lua for Other Developers
0, '', [], None, False 0, '', null, undefined, NaN, false only nil and false then/do... end local (globals are the default!) -- and --[[ ]] Key gotchas:
Variables are global by default: always write local.
1-based indexing, and # is unreliable with nil holes.
0 and "" are true.
~= for inequality; .. for concatenation.
No continue (use goto), no += (except Luau), no ternary (use and/or carefully).
obj:method() vs obj.method(): forgetting the colon is a common bug ("attempt to index a nil value (local 'self')").
Appendix E: Resources and Study Plan
lua.org: the reference manual (5.4, 5.3, 5.2, 5.1), source code, mailing list (lua-l), Lua Workshop talks
Programming in Lua (PiL) by Roberto Ierusalimschy: the definitive book (4th edition covers 5.3; the 1st edition, for 5.0, is free online)
Lua Programming Gems (edited by de Figueiredo, Celes, Ierusalimschy)
luajit.org, luau.org (Luau docs), love2d.org/wiki, neovim.io/doc (:help lua-guide), openresty.org Books and Guides
*Programming in Lua*, 4th ed. (Ierusalimschy) *Lua Quick Start Guide* (Gabor Szauer)
*Coding Roblox Games Made Easy* (Zander Brumbaugh) *Game Development with LÖVE* resources: Sheepolution's "How to LÖVE" (free), the LÖVE wiki
*Learn X in Y minutes: Lua*, the lua-users wiki (lua-users.org/wiki), *Lua Style Guide* (Olivine Labs) lua-l mailing list, r/lua, r/love2d, r/neovim, Roblox DevForum, LÖVE forums and Discord, Stack Overflow [lua], the Lua Workshop (annual), awesome-lua (curated list on GitHub) 11-Week Study Plan Setup, types, numbers, strings
Operators, control flow, tables, functions Closures, tables in depth, iterators, data structures String patterns, LPeg, UTF-8
Metatables, OOP, inheritance, _ENV, GC and weak tables Modules, errors, coroutines and patterns, <const>/<close>
Standard library, load and sandboxing, debug library C API (embedding, extending, userdata), LuaJIT FFI, dialects, bindings
LuaRocks, LÖVE, Roblox/Luau, other engines, Neovim OpenResty, Redis, infrastructure, embedded/IoT, DSLs 47–52 + Capstone
Testing, linting, profiling, performance, security, internals
Final tip: Master tables, closures, and metatables and you've mastered Lua: everything else is built from them. Always use local, remember that indices start at 1, and pick a target (a LÖVE game, a Neovim plugin, an OpenResty service, or an embedded engine) to put your skills to work. Happy coding! 🌙