Fandom

Foldit Wiki

Lua Scripting Tutorial (Advanced)

1,448pages on
this wiki
Add New Page
Comment1 Share

Introduction Edit

This tutorial is for more experienced programmers, giving some information about functions and tables.
Have a look at the contents section for details.

Most of the grey boxes have full functional script code in it,
you can copy and paste it into FoldIt's Script editor.
Only some boxes contain code parts or output window text, but then, it is mentioned before.

Sorry that I couldn't give them other colors, I don't know if or how this is possible here.
If anyone does know it, let me know how.

On most systems,

Functions Edit

If you already did a shake, wiggle or just printed out a text by script, you have already used (called) a function.
But in addition to just using them, you can even create your own functions.

Using and declaring Edit

Using a function (and declaring it later), you need two things:

print("Hello")

Here, we call the function named print with only one argument - the constant expression "Hello".
The function name is: print
The function argument is: "Hello"

Let's now feed a variable into the function print:

outputtext="Hello"

print(outputtext)

In this example, our print-function gets the variable outputtext as argument.

Since now, we just used a defined function. It is time to create our own one:

function print2(a,b)
 print("A contents:",a)
 print("B is:",b)
end

a="Hello"
b="World"

print2(a,b)

Here, we defined the function print2 with two arguments, a and b.
Inside our function, we call the function print twice, to show the content of our arguments.
You can also see, that the print function also accepts more than one argument, and that we can use functions within functions.

To remember, we could also call our function with constants:

function print2(a,b)
 print("A contents:",a)
 print("B is:",b)
end

print2("Hello","World")

This would give the same result.

Alias-names of variables Edit

By using arguments, you don't need the same names for you variables within functions:

function print2(c,d)
 print("A contents:",c)
 print("B is:",d)
end

a="Hello"
b="World"

print2(a,b)

Compare the code with the second one before.
It does the same job, but we changed variable names in the function section.

We still feed the variables a and b as arguments into the function in this code section:

a="Hello"
b="World"

print2(a,b)


But in our function declaration, what was called a before is now called c, b is called d.
In the function,
a has the alias-name c,
b has the alias-name d.

The text to print is still the same in this part of the code:

function print2(c,d)
 print("A contents:",c)
 print("B is:",d)
end


The possibility of using alias-names has some advantages:
You don't need to change variable names in any function sections, when you:
But take care! Aliasing only works on variables,
if they are submitted as arguments in a function call by their initial names
and in the argument list of the function declaration by their alias-names!

Scope of global and local variables inside and outside Edit

If a variable name within a function is not mentioned as argument at function begin, it is a global variable.
If the keyword local is even put before it, it is a local variable.

The expressions global and local describe the scope (the visibility) of variables.

In our example before, you can say that c has a local content of a, and d has a local content of b.
Local, because the values of c and d only exist within the function, outside those variables don't have these values.
Outside the function the values are still stored in the variables a and b.

Let's see this in a more slim example, at first with a local variable.
Slim, because now, we won't be using any arguments to submit values:

function test()
 local a=5
 print ("A at function call is:",a)
end

print("A before function call is:",a)

test ()

print("A after function call is:",a)

This should result:

A before function call is:  nil
A at function call is:  5
A after function call is:  nil

You can see, that outside the function a is nil, as we didn't set a value there for it.
Inside the function, using the keyword local, another variable (also called a) is created, we set this to 5.
When leaving the function, the other (older) variable a is used again which still has nil information.

The local variable a within the function is not visible outside the function,
the local variable a outside the function is not visible inside the function.

Let's see what happens if we remove the expression local, so we will now use a global variable:

function test()
 a=5
 print ("A at function call is:",a)
end

print("A before function call is:",a)

test ()

print("A after function call is:",a)

This should result:

A before function call is:  nil
A at function call is:  5
A after function call is:  5

At start, a hasn't got any value again, as it is not mentioned before function call.
But inside the function, the keyword local is missing this time, so no new variable a is created.
Variable a inside the function is the same as outside and set to 5.
So, when the function is left, it still has the value of 5.

Here, one global variable a is visible inside and outside the function.

It is up to you to decide, if you want to use global (so you needn't submit them as arguments) or local variables.
But as you can imagine, this can cause problems:

function count3()
 local i=0
 while i<3 do
  i=i+1
  print("And i inside function is:",i)
 end
end

local i=0
while i<2 do
 i=i+1
 print("I outside function is:",i)
 count3()
end

This should result:

I outside function is:  1
And i inside function is:  1
And i inside function is:  2
And i inside function is:  3
I outside function is:  2
And i inside function is:  1
And i inside function is:  2
And i inside function is:  3

We have got two loops:
One is counting from 1 to 2 and calling a function named count3,
and in this function, we have a loop counting from 1 to 3.
Both loops (outside and inside the function) are using variable i to count.
No problem so far.

But let's see what happens, if we remove the keyword local:

function count3()
 i=0
 while i<3 do
  i=i+1
  print("And i inside function is:",i)
 end
end

i=0
while i<2 do
 i=i+1
 print("I outside function is:",i)
 count3()
end

Now, we only have:

I outside function is:  1
And i inside function is:  1
And i inside function is:  2
And i inside function is:  3

This happens, because variable i is overwritten inside the function, and when the loop inside the function is finished, i has the value 3.
As the function is left, i still has value 3, because it is a global variable and the old value for the outer loop isn't fetched.
But the loop outside the function is programmed to count to 2, and i is already over this value!
So, the outer loop finishes earlier as planned.

I tried this also with loops using the for-command with and without using the expression local, it didn't make a difference.
Both versions gave the same result as the first example.
I guess, for-loops create their own local variables in memory when using functions, but I wouldn't bet on it in a complex program.

My advice is:
Whenever you use temporary variables (in loops or for intermediate result values for example), write local before them!
You can use global variables for basic information, which should be available everywhere,
like Puzzle Score, Number of Segments, information about bands or saveslots.
When you use arguments, you are always on the safe side, as you can quickly see which variables are feeded into the function and (if necessary) which values of them are changed.

Accidentally created new variables and debugging Edit

With this information you have now, at this point a tip for debugging:
Maybe sometimes you accidentally create and use global variables without knowing it.

Why? Because of a typical behavior of most scripting languages (as Lua is):
You don't need to declare variables before, you can directly use them.

If their name appears the first time, the scripting language automatically assigns:

  • Control-c is for copying
  • and Control-v for pasting.
    1. A function name.
      This will allow us to call the function in the main program (or another function) by it's name when we need it.
    2. Function parameters (arguments).
      These are the variables, values (constants) or tables the function has to work with.
      In the declaration, they are put in braces after the function's name.
      When using several arguments in a function, they are separated by comma.
      If arguments are not needed, you still have to write the braces, so Lua can see that this is a function, and not a variable.
    1. write a new program and decide to use other variable names than before in the code which is calling the function
    2. copy a function from a user who works with other variable names
    3. call the function more than one time in a code, working on different variables each call

    If you use a variable outside, but inside your function (or anywhere else) you don't write it exactly the same as it is written the first time it is used,
    Lua will create a new global variable with your "new spelling" having nil (Lua's default) value!
    With this variable containing nil, computing with it won't work anymore,
    you just will be able to compare it with other variables/values and check if both of them are equal or unequal.

    Let's prove this with an example:

    function PlusOne()
     print ("A+1 is:",a+1)
    end
    a=1
    PlusOne()
    

    The result is:

    A+1 is:  2
    

    The content of the global variable a is also visible in the function, so we can add 1 to it in the print-command.

    Let's suppose, in the function we accidentally typed a as capital, not as small letter:

    function PlusOne()
     print ("A+1 is:",A+1)
    end
    a=1
    PlusOne()
    

    This gives the following error:

    ERROR: [string "function PlusOne()..."]:2: attempt to perform arithmetic on global 'A' (a nil value)
    

    For Lua, a is not the same as A, Lua is case-sensitive.

    So, in addition to the existing variable a already having some value,
    it created a new variable A with the default value nil.
    But to nil, we can't add 1.

    This means, if you get an error that a variable is nil, but you did use it before, you maybe misspelled it or wrote a letter in the wrong case.

    And now you know, what is happening internally and why.

    Returning values Edit

    So, we submitted values into a function as constant expressions or by using local/global variables,
    we've read the variables' values or manipulated them, but only inside the function.
    But if we don't use global variables and we want to make changes which are permanent,
    visible even outside the function (so that we are really creating new values),
    we have to tell the function, that the values must not only be used (and changed), but also returned:

    function increase(x)
     local x=x+1
     return x
    end
    a=1
    print("A before increasing is: "..a)
    a=increase(a)
    print("A after increasing is: "..a)
    


    A shorter form is:

    function increase(x)
     return x+1
    end
    a=1
    print("A before increasing is: "..a)
    a=increase(a)
    print("A after increasing is: "..a)
    

    The difference is, that in the first example, we create a new temporal variable in the function,
    do something with it, then return the temporal value.
    Then, outside the function, our variable gets the temporal value from inside.
    In the second example, we do directly change the variable's value,
    then allow this change to be made by returning it.
    Both ways do work, but my advice is, if you do multiple changes on a variable (or table),
    copy it at the beginning of the function by using the expression local like it is done in the first version.

    ... to be continued ...

    Tables Edit

    Tables are like drawers of a cupboard.
    They can contain a set of variables, values or other tables, you can even mix these different contents.

  • To start tables are set up like this: [Table Name] = {[Information]}
  • Ex. AdminPlayers = {"stickmasterluke", "builderman", "ROBLOX"} We will soon be introducing how to manipulate tables...


  • Reference Edit

    For the original source of information and other examples, go to this address:
    Lua 5.1 Reference Manual

    Search for:


    <ul type="square>

  • a type (information if this variable is a number or a string (text))
  • and a default value to them.

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.