Voxel Game Maker

Docs Quick code

Lists and tables

Lists (numbered items), tables (named values), and the functions that work on them.

#Lists

A list holds items in order. The first item is number 0.

local loot = ["Coin", "Gem", "Key"]
local first = loot[0]    -- "Coin"
local last = loot[-1]    -- "Key" (negative counts from the end)
local n = #loot          -- 3
loot[1] = "Ruby"         -- change an item
loot[3] = "Map"          -- one past the end adds an item
loot:push("Rope")        -- adds at the end too

Reading past the end gives nil. Putting an item further past the end than the next free place is a mistake (it says how many items the list has).

{1, 2, 3} (Lua style) is the same list as [1, 2, 3].

#Working with lists

Each works as a function or as a method with a colon: push(list, x) or list:push(x).

Do Code
Add to the end / take the last l:push(x), l:pop()
Put in / take out at a place l:insert(i, x), l:remove_at(i)
Take out a value l:remove(x) (the first one equal to x)
Is it in there? Where? l:contains(x), l:index_of(x) (-1 if not)
First, last, one at random l:first(), l:last(), random_pick(l)
Sort l:sort() (numbers or texts), l:sort(function(a, b) return a.hp > b.hp end)
Turn around / mix up l:reverse(), l:shuffle()
A part of it l:slice(from, to) (from … up to, not including, to)
Each item changed l:map(function(x) return x * 2 end)
Only some items l:filter(function(e) return e.hp > 0 end)
Add up / smallest / biggest sum(l), min(l), max(l)
As one text join(l, ", ")
A list of numbers range(1, 5) → [1, 2, 3, 4, 5], range(10, 0, -5) → [10, 5, 0]
A separate copy copy(l)

sort, reverse, shuffle, push… change the list itself (and give it back, so they can be chained); map, filter and slice make new lists.

-- The three nearest enemies, weakest first.
local foes = objects("enemy"):filter(function(e) return e.distance(player) < 10 end)
foes:sort(function(a, b) return a.hp < b.hp end)
for e in foes:slice(0, 3) do
  e.say("!")
end

#Tables

A table holds values by name:

local stats = {hp = 10, speed = 2.5, name = "Rat"}
local hp = stats.hp           -- 10
stats.hp -= 3                 -- change one
stats.armor = 2               -- add one
local who = stats["name"]     -- "Rat" — the same as stats.name
stats.armor = nil             -- = nil takes it out
local count = #stats          -- how many values it has

Names with spaces or made in code go in brackets: {["long name"] = 1}, stats[key]. A key can be a number or text: tables make good grids and look-ups.

local grid = {}
grid["3,4"] = "tree"
if grid["3,4"] == "tree" then popup("A tree is there") end
Do Code
Its names / its values keys(t), values(t) (lists)
Does it have a name? t:has("hp") or has_key(t, "hp")
How many #t or t:count()
Take one out t:remove("hp") (gives its value)
A separate copy copy(t)

Going through one: for name, value in t do … end (a table's order is the order its values were added). With one name, for name in t do gives the names.

Tables can hold lists, other tables and functions — see methods.

local waves = [
  {enemy = "Slime", count = 3},
  {enemy = "Goblin", count = 5},
]
for w in waves do
  spawn(w.enemy, 8, 0, 8, w.count)
  wait(10)
end

#What gets saved

Game variables and objects' own values holding lists and tables are saved with the game, as long as everything inside is a number, text, true / false, or more lists and tables. (Functions, objects and vectors inside them aren't saved.)