Luawe the Wayfarer Engine's scripting language All pages

Scripts working together

A level can have many scripts (up to 64). Splitting a level's logic over a few of them, each with one job, keeps every one short enough to read: one for the doors, one for the score, one for the boss.

Each script is on its own

Every script starts when the level starts, as a task of its own, and runs beside the others. They start in the order of their names.

A script's variables are its own. That goes for its globals too: a name given a value without local is seen everywhere in that script, and nowhere else. So two scripts can both have a count and never mix them up.

Sharing on purpose

Every script has a table called shared. Whatever it puts in there, the other scripts can read, under scripts. and the script's name.

Say a script named score keeps the points:

-- the script "score"
shared.points = 0

function shared.add(amount)
    shared.points += amount
    print("points: " .. shared.points)
end

Another script, coins, uses it:

-- the script "coins"
for _, coin in things.all("coin") do
    coin.touched:once(function()
        coin:destroy()
        scripts.score.add(10)
    end)
end

scripts.score is the shared table of the script called score. scripts.score.add(10) calls the function that script put there, and scripts.score.points reads its number.

A script's own name is script.name.

Who is first?

Scripts start one after the other, by name, and each runs until it first waits. A script that starts early cannot yet see what a later one will put in its shared:

-- the script "alpha" starts before "score"
print(scripts.score.points) -- nil: "score" has not run yet

Two habits avoid the problem:

  • Use the other script later, not at the very start: inside a function connected to an event, or after a first wait(). By then every script has had its start.
  • Or have scripts tell each other things with an event, as below.

Talking through events

An event in shared lets one script announce something without knowing who cares:

-- the script "score"
shared.points = 0
shared.changed = signal.new()

function shared.add(amount)
    shared.points += amount
    shared.changed:fire(shared.points)
end
-- the script "hud"
local label = things.find("score text")

wait() -- let every script start first
scripts.score.changed:connect(function(points)
    label.text = `Score: {points}`
end)

Now score knows nothing about texts, and hud nothing about coins. Either can change without the other noticing.

Scripts and nodes

The nodes of the Logic tab and the scripts run side by side, and they meet in the level's variables: vars.coins in a script is the variable coins of the Logic tab. A node can set what a script reads, and the other way round. See the level's variables.

Next: limits and safety.