Decisions and loops
A script that only went from its first line to its last could not do much. This page is about choosing what to do, and doing things many times.
If
if does something only when a condition is true. It always ends with end.
local lives = 0
if lives > 0 then
print("still in the game")
else
print("game over")
endIt prints
game overelseif asks another question when the ones before were not true. The first part that fits is done, and the rest are skipped:
local coins = 7
if coins >= 10 then
print("gold")
elseif coins >= 5 then
print("silver")
elseif coins >= 1 then
print("bronze")
else
print("nothing yet")
endIt prints
silverRemember that only false and nil count as no. if thing then is a common way to ask "is there a thing at all?":
local door = things.find("door")
if door then
door.alpha = 0.5
else
warn("this level has no thing called door")
endWhile
while repeats its block as long as a condition is true. The condition is asked before each round.
local n = 1
while n < 100 do
n *= 2
end
print(n)It prints
128Repeat
repeat ... until is a while turned round: the block runs first, and the condition, asked after each round, says when to stop. So the block always runs at least once.
local dice = random.new(7)
local rolls = 0
repeat
rolls += 1
until dice:whole(1, 6) == 3
print(`a three after {rolls} rolls`)It prints
a three after 2 rollsFor, counting
for with numbers counts from one number to another:
for i = 1, 3 do
print("round " .. i)
endIt prints
round 1
round 2
round 3A third number is the step. It can go down, and it need not be whole:
for i = 10, 1, -3 do
print(i)
endIt prints
10
7
4
1The loop's variable (i here) belongs to the loop: it is new in every round, and gone after the loop.
For, through a table
The other for goes through a table and gives each key with its value. For a list the key is the place, counted from 1:
local colours = { "red", "green", "blue" }
for place, colour in colours do
print(place, colour)
endIt prints
1 red
2 green
3 blueA name you do not need is by habit called _:
local total = 0
for _, points in { 5, 10, 20 } do
total += points
end
print(total)It prints
35For a table with names as keys, the pairs come in the order they were put in:
local door = { name = "gate", open = false }
for key, value in door do
print(key, value)
endIt prints
name gate
open falsepairs(table) and ipairs(list) can be written after in as well; for k, v in t and for k, v in pairs(t) do the same. ipairs goes through a list's places 1, 2, 3... and stops at the first empty one.
Leaving a loop, skipping a round
break leaves the loop it is in. continue skips the rest of this round and goes on with the next.
for i = 1, 10 do
if i % 2 == 0 then
continue -- even numbers: skip
end
if i > 7 then
break -- enough
end
print(i)
endIt prints
1
3
5
7Loops that go on and on
A script often wants to do something for as long as the level is played. Such a loop must wait in every round. Waiting is what lets the level carry on; a loop that never waits would hold everything up, so the game stops it (and says so in the script output).
local lamp = things.find("lamp")
while true do
lamp.alpha = 1
wait(0.5)
lamp.alpha = 0.2
wait(0.5)
endwait(0.5) pauses for half a second. wait() with no number pauses until the next step of the level, which is the shortest pause there is. Waiting and tasks has the whole story.
Blocks of their own
do ... end is a block and nothing else. Its use is to keep a variable to a few lines:
do
local secret = 42
print(secret)
end
-- here, secret is goneIt prints
42Next: functions.