Luawe the Wayfarer Engine's scripting language All pages

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")
end

It prints

game over

elseif 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")
end

It prints

silver

Remember 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")
end

While

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

128

Repeat

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 rolls

For, counting

for with numbers counts from one number to another:

for i = 1, 3 do
    print("round " .. i)
end

It prints

round 1
round 2
round 3

A third number is the step. It can go down, and it need not be whole:

for i = 10, 1, -3 do
    print(i)
end

It prints

10
7
4
1

The 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)
end

It prints

1 red
2 green
3 blue

A 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

35

For 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)
end

It prints

name gate
open false

pairs(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)
end

It prints

1
3
5
7

Loops 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)
end

wait(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 gone

It prints

42

Next: functions.