Modding:Tutorial/Basic Syntax and Definitions

From DoomRL Wiki

Revision as of 20:38, 11 March 2012 by Game Hunter (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

The following is a very quick explanation of general programming syntax in lua. If you know even a little about programming, you do not likely need to read any of this.

Variables

Writing in a computer language is very brief and exact, and never involves any connotations or implications. In fact, with the exception of particular inputs and outputs, all of the language is entirely internal, purposed to communicate with the computer in order to perform calculations. Rather than directly using numbers, which do not allow for changes, you will want to assign any values you use to a variable. In lua, declaring a variable can be done by preceding it with the word "local", and assigning the variable a value is done using the equal sign.

local yes = 1
local no = 0

With this code, whenever you would use the variable 'yes', it will be read as a true value, and whenever you would use the variable 'no', it will be read as a false value. (Note that the parameters are not always "local": this will be covered in detail elsewhere.) Variables can be reassigned as much as you want unless they are read-only on the engine side (this comes up in a few places for our purposes).

Variables in lua can be of a variety of different types. Typically you will use the following:

local var_void = nil          --singular value, used mostly to be a placeholder
local var_boolean = true      --double value, true/false meant for satisfying conditions
local var_number = 3.14159    --double-precision floating-point value, pretty much any number you could possibly want
local var_string = 'awesome'  --sequence of characters, must have single- or double-quotes around them
local var_function = print    --subroutine, used to reference pieces of code over an entire file
local var_table = {1 = 'a'}   --associative array of fields, holds a lot of information in a single place (explained later)

For the purpose of modding, you are often restricted by what type you can use based on what is allowed by the API. If an input was expecting a string and you use a boolean value, you will almost certainly get an error. Note that the left side could be just about anything you want: use whatever naming scheme works for you. There are, however, some exceptions (found here) and you should be aware of them.

Operators

Calculations themselves are based on a variety of operators. The most basic operators are arithmetic, involving simple mathematical calculations (such as addition), and relational, which compare two values on either side of the operator. Logical operators first check the true/false values that are attached to the operator, then determine the true/false value of the whole statement, depending on which operator is used.

--Arithmetic operators
2 + 4   --gives a value of 6 (addition)
10 - 6  --gives a value of 4 (subtraction)
3 * 7   --gives a value of 21 (multiplication)
16 / 2  --gives a value of 8 (division)
-8      --gives a value of negative 8 (unary)
 
--Relational operators
3 == 3  --true (note that equality relations are understood with ==)
12 ~= 1 --true (not equal to)
6 > 2   --false (greater than)
6 < 9   --true (less than)
2 >= 2  --true (greater than or equal to)
5 <= 4  --false (less than or equal to)
 
--Logical operators
0 or 1  --returns true; either value must be true
0 and 1 --returns false; both values must be true
not 0   --returns true; negates the value that it operates on

Using parentheses to determine the order of operations is usually the best way to write code, although generally arthemetic operations are performed before relational ones, and relational operators are performed before logical ones. (The notable exception are the unary arithmetic and the "not" logical operators, which take precendence over everything.) Finally, for cases of equal priority, the left side is calculated before the right side.

If you want to add variables or line-breaks in a string, end the string, include a double-dot syntax (".."), and add the variable or start a new line. This is known as concatenation.

--displays "Hello world"
print("Hello " .. "world")
 
local var = 300
--displays "There are 300 bullets in the room."
print("There are " .. var .. " bullets in the room.")
 
--displays "This is just a single line of text."
print("This is just " ..
      "a single line " ..
      "of text.")

Conditional Syntax

Trying to determine how your code will run is primarily executed through conditional statements. These include:

if condition    --check to see if condition is true
    then result --if condition was true, do result
end             --conditional statements must always finish with this line
 
if condition1     --check to see if condition1 is true
    then result1  --if condition1 was true, do result1
elseif condition2 --if condition1 was false, check to see if condition2 is true
    then result2  --if condition2 was true, do result2
else
    result3       --if condition2 (and condition1) was false, do result3
end
 
while condition --check if condition is true
   do task      --if condition was true, task is executed; if it was false, skip
end             --if condition was true, repeat the statement; if it was false, end statement
 
repeat          --repeat the following lines indefinitely
   task         --task executes (always executes at least once)
until condition --if condition is true, end statement
 
for var=val1,val2,val3 --iterate following lines based on vals
    do task            --task is executed a number of times equal to the number of vals
end
 
for var=first,last,step --iterate following lines from first to last, using step as iterator
    do task             --task is executed (last-first+1)/step times (rounded down)
end
 
for var,iter in ipairs(array) --iterate following lines for all fields in array, iter acts as index (if necessary)
    do task                   --task is executed for as many fields as there are in the array
end
 
for var,iter in pairs(table) --same as above but with a table
    do task                  --task is executed for as many keys as there are in the table
end

If a lot of these are confusing, don't worry as we'll eventually manage to find ways to include them in the tutorial as we go.

Finally, we have two miscellaneous statements: break and return. Break will prematurely exit a conditional statement, and could be used to, for instance, exit a "while true" loop (although this should probably be avoided). The following example would print the index number of the first true value in binary_array (which should be a 7) and then exit the loop.

binary_array = {0,0,0,0,0,0,1,0,0,0,1,0,0,1}
 
for v,i in ipairs(binary_array) do
    if i
        print(i)
        break
    end
end

Return is used with functions. Calling return in a function ends execution of that function immediately and can be used to return data to whatever called it. Using the previous example, we can instead return the index number rather than printing it:

index = local function findTrueValue(binary_array)
    for v,i in ipairs(binary_array) do
    if i
        return(i)
    end
end

This brief lesson in lua scripting should be all you need in order to understand the various examples found in the tutorial.

Personal tools