dark mode light mode Search Menu
Search

Lua

Hey everyone and welcome back to our series highlighting different programming languages. This issue we’re going to discuss a language that’s useful in a lot of different gaming contexts: Lua.

Lua has actually been around for over twenty years but is still going strong. It’s the scripting language for Roblox Studio and for most of the “fantasy computers” on the market right now, like the TIC-80 system described elsewhere in this issue.

Lua is a language that’s designed to be easy to use that also can integrate into projects written in C/C++. That’s why it’s so commonly seen as a scripting language in things like Roblox, TIC-80, or even something as nerdy as a typesetting system for books.

If I were to compare Lua to any other language I’d probably say it’s closest to JavaScript but with Ruby and Python’s aesthetic.

For example, a simple loop through an array that doubles each element looks like:

arr = {2,4,6,8}
for k,v in ipairs(arr) do
   arr[k] = 2*v
end

There are some unique parts to Lua, though. Most of them have to do with how you use collections of data. You see, there’s only one real type of data in Lua beyond the basic numbers, strings, and booleans: tables.

Tables in Lua are arrays, dictionaries, and lists. They’re like JavaScript’s objects but pull even harder double-duty.

So if you want to use a table as an array, you can just put items into it like in the previous code sample and they’ll automatically be numbered just like in C or JavaScript arrays.

There’s one weird little quirk, though: tables as arrays or lists start being numbered at 1 not 0. You could argue that this is the right thing to do because, well, who other than long-time programmers actually points at the first object in a line and calls it “zeroth”?

Tables as dictionaries or JavaScript objects, on the other hand, are made with the following syntax:

arr = {x="stuff",
       y="things"}
 
for k,v in pairs(arr) do
   print("The key: "..k.." The value: "..v)
end

Which, when run, prints out the following:


The key: y The value: things
The key: x The value: stuff

The only real difference in how we iterate over something that’s like a dictionary or something that’s like a list. If it’s a list or array with numeric indices then you want to use the function ipairs to get the elements in order. If it’s an object or dictionary, you want to use the function pairs to get all of the key/value pairs but they won’t necessarily be in a reliable order.

Otherwise, tables in Lua deliberately have a familiar syntax. If you’re using them like arrays or lists you use the tab[3] syntax to access the third item in the list, and if you’re using them like objects or dictionaries then you can use the “dot” syntax like tab.x = “chicken”.

Functions in Lua are most similar to functions in JavaScript: they’re declared with the function keyword and can either have names or not.

This means you can either declare a function as either:

function (x,y)
   return x*y
end

or

function add(x,y)
   return x+y
end

Functions in Lua are more flexible than most programming languages because you can both take an arbitrary number of arguments into a function and you can get multiple values out of a function.

function returnsMultiple(x,y,z)
   return 2*x,3*y,4*z
end
 
local a,b,c =returnsMultiple(10,20,30)
--this should print out 20 60 120
print(a.." "..b.." "..c)
 
-- This function will multiply all the arguments it's given
function multMany(...)
   local prod = 1
   -- We use the syntax {...} to make a list out of all the arguments
   for _, v in ipairs{...} do
      prod = v * prod
   end
   return prod
end
-- should print 120
print(multMany(1,2,3,4,5))

The last thing that’s a little unusual to Lua is the local keyword you can see above. In Lua, you declare variables by assigning them a value for the first time. But what if in our function above we just wrote prod = 1. Should prod = 1 try to assign a value to a global variable that’s visible to the whole program ? Or should it create a new local variable that’s only visible inside the function?

Putting local in front of the variable when you first assign it resolves the ambiguity and tells Lua that you really do want to create a new variable and not that you meant to reference an already existing global one.

That’s pretty much it for our little overview of Lua. If you want a ton of examples to work with and play with you can either dig into Roblox Studio or read the article in this very issue on the TIC-80 fantasy computer for making retro games.

Learn More

Programming in Lua, the official book by the creators of the language

https://www.lua.org/pil/

The official Lua reference manual

http://www.lua.org/manual/5.3/

Description of Lua in a Backus-Naur Form (BNF)

BNF is like a compact cheatsheet for the syntax of a programming language
http://www.lua.org/manual/5.3/manual.html#9

Backus-Naur Form tutorial

http://www.garshol.priv.no/download/text/bnf.html

Related Posts