Limits and safety
Levels are shared, and a level's scripts run on the computer of whoever plays it. So Luawe is built around two promises to the player: a script cannot reach anything outside the level, and a script cannot freeze or fill up the game. This page says how those promises are kept, and what the limits mean for a script's writer.
What a script cannot do
A script works inside the level being played, and only there. Luawe has no way to:
- read, write, list or delete files
- use the internet or the network in any way
- start programs, or talk to other programs
- read the clipboard, the game's settings, or the player's progress and other levels
- load more code while it runs (there is no
require,loadordofile) - keep anything after the run: nothing a script does is saved anywhere
These are not switched off; they were never built. The whole list of what a script can use is the reference, and every entry in it is about the level: its things, its camera, its cube, its variables, its sounds, the keys the player holds.
Esc always pauses the game. Scripts never see that key, so a level cannot take the way out away.
A script cannot freeze the game
Every task has an allowance of work between two waits. A task that uses it up, which in practice means a loop that never waits, is stopped, and the script output says where:
It prints
door.luawe:14: this task ran for too long without waiting, so it was stopped: put a wait() in a loop that goes on and onOnly that task stops; the level plays on. pcall cannot catch this.
There is a second, smaller allowance for all of a level's scripts together in one step of the level. When it is used up, the scripts simply carry on in the next step. Nothing breaks, but a level that does very heavy work every step will find its scripts running a little behind.
For a script's writer this comes down to one habit: a loop that runs for a long time waits in every round.
The numbers
Most scripts never come near these.
| What | At most |
|---|---|
| Scripts in a level | 64 |
| One script's text | 256 KB |
| All of a level's scripts together | 2 MB |
| A script's name | 48 letters: letters, digits, _ and -, starting with a letter |
| Memory the scripts of a run keep | 16 MB |
| One string | 1 MB |
| Tasks and coroutines alive at once | 2000 |
| Functions calling functions, deep | 4000 |
| Lines kept in the script output | 400 (a line is cut at 1000 letters) |
| Things made by scripts and nodes, there at once | 2000 |
| Things made in one step of the level | 64 |
When memory runs out, the task that asked for more stops with an error, and what nothing uses any more is cleaned up. Tidying happens by itself: there is nothing to free by hand, and collectgarbage() only tells how much is kept.
The same on every computer
A level should play the same for everyone. So:
- Sums come out the same everywhere. (Only the very last digits of a sine or a power can differ between kinds of computer: never build a level on the fifteenth digit.)
- A table's keys come out of a
forloop in the order they were put in, always. - Scripts start in the order of their names, and tasks take their turns in a fixed order.
- A random generator made with a seed,
random.new(7), gives the same numbers on every computer. Without a seed, and forrandom.number()and its friends, the numbers are new at every try.
Tries and checkpoints
Nothing a script does changes the level itself. Every try starts with the level as it was built and with the scripts starting from their first lines.
A checkpoint keeps the run as it is at that moment, and the scripts are part of the run: their variables, their waiting tasks, their connections. A try that goes back to a checkpoint finds its scripts exactly as they were when it was set, in the middle of whatever they were doing.
Next: four scripts to learn from.