Before you start reading my tutorial, I would like to name some scripting programs/tools that you could use to learn Lua scripting.
SciTE Included in Lua for Windows
Notepad++ A nice editor with multiple features and scripting languages
Cloud9 IDE A website that supports multiple scripting languages and collaborative scripting with other scripters.
ZeroBrane Studio (My favorite scripting editor)
You might have been taught on school some basic mathematics stuff where you use letters and numbers to make complex formulas, you can create them the same way as you do in mathematics.
Numbers
Everything that is related to numbers is used for mathematical formulas, this is how you define a number.
1
2
3
2
3
NumberA = 1 NumberB = 100 NumberC = -10
Strings
Strings, also known as sentences. It's a set of characters (numbers, words, etc) that makes a sentence. You always have to put quotes on the begining and at the end when you define them.
1
String = "Hello world!"
As you have noticed before, the = operator is used to assign variables, but there are more operators that do different things! You can multiply, divide, add, susbtract and even more. I'll show you some essential operators here.
Z = X + Y
Z is equal to X plus Y
Z = X - Y
Z is equal to X minus Y
Z = X / Y
Z is equal to X divided by Y
Z = X * Y
Z is equal to X multiplied by Y
This is how you use them
1
2
3
4
5
6
2
3
4
5
6
NumberA = 5 NumberB = 15 NumberC = NumberA + NumberB NumberD = NumberA - NumberB NumberE = NumberB / NumberA NumberF = NumberB * NumberA
What does the previous code mean?
NumberA is 5
NumberB is 15
NumberC is 5 plus 15, that means it's 20
NumberD is 5 minus 15, that means it's -10
NumberE is 15 divided by 5, that means it's 3
NumberF is 15 multiplied by 5, that means it's 75
The string operator (Concatenate)
Just as you have a + operator for numbers, there's a special operator that is used to mix two strings as one, this is what is called concatenating. This operator is written as two dots.
1
2
3
2
3
StringA = "I like" StringB = "Pie" StringC = StringA .. StringB
Wait what? Shouldn't there be a space between "like" and "Pie" ?
Yes, but you would have to add the space character when you get those strings together.
1
2
3
2
3
StringA = "I like" StringB = "Pie" StringC = StringA .. " " .. StringB
Functions are used to do more tasks and use less coding, functions have a number of arguments that are passed from the code that called it. This is how you call a function.
1
print("Hello world!")
How do I make my own function?
You have to write the keyword "function" and your function name, then you open a parenthesis/brackets () with the name of the arguments that are passed to the function, each argument must be separated by a comma.
1
2
3
4
5
6
7
2
3
4
5
6
7
function myFunctionName(ArgumentA, ArgumentB) 	print("The first argument is") 	print(ArgumentA) 	print("The second argument is") 	print(ArgumentB) end
What does ArgumentA and ArgumentB mean?
They're the name of the arguments used in this function, you can give it any name but you can only use word characters. When this function is called, ArgumentA will be replaced with the first value passed to the function and ArgumentB with the second one.
1
myFunctionName("Test", 123)
What does "end" mean?
The "function" keyword is used to start a new chunk of code, you have to use "end" to let the script know that there's where your function's code finishes.
What if you want certain code to be executed, but you don't want another part of your code to be executed?
You can use conditionals. They try to figure out if a condition is possible or impossible.
How do I make a condition?
Firstly, you have to write the keyword "if" and your condition.
Secondly, you have to write the keyword "then" and the code that will be processed when the condition is possible.
Finally, you have to write "end" to let your conditional know that there's where your condition ends.
1
2
3
4
2
3
4
A = 10 if A == 10 then 	print("A is 10") end
Why does that condition use "==" and not "="?
The "==" operator is a comparison operator, it is used to compare two variables. However "=" is just used to assign values. In the previous code we have assigned A to 10 and then we compared A with 10, it was a condition that is possible so it should print "A is 10" to our console.
What is a loop?
A loop is a script that gets executed a certain amount of times in a moment.
"for" loop
The "for" loop executes a script and gives it a variable that will have a different value for every execution. This is how you make a "for" loop.
1
2
3
2
3
for i = 1, 100 do 	print("i has a value of: "..i) end
1
2
3
2
3
for Value = From, To do 	-- Script here end
Here we go with another variables lesson, you will get used to booleans and to tables.
Booleans
Boolean is a data type with two possible values: true or false, in some other scripting languages true is 1 and false is 0. You can't compare a boolean with a number or a boolean with a string, but you can compare two booleans.
1
2
2
UnrealSoftwareRocks = true HacksRocks = false
Tables
The table is the most complex concept of Lua, you might want to imagine it as a list of elements. Imagine a list of the scores/places in a competition, you could imagine it as an excel table aswell.
What is the index/key?
The index or the key is the position of a value in our Lua table.
1
Table[Key] = Value
What types of values can I put in a table?
You can put any type of value; number, strings, booleans and even more tables!
Can the key/index be just a number?
No, the key can be any type of value too, but it's mostly used for strings and number than other types of values.
There are even more operators that you didn't know they existed.
X < Y
X is lower than Y
X > Y
X is higher than Y
X <= Y
X is lower or equal to Y
X >= Y
X is higher or equal to Y
X ~= Y
X is different to Y
How do I use those operators?
You can use them the same way you're using you use the comparison operator.
1
2
3
4
5
6
2
3
4
5
6
MinimumAgeForTheMovie = 18 YourAge = 17 if MinimumAgeForTheMovie >= YourAge then 	print("You can enter to the cinema sir") end
What does it mean that functions can return values?
Functions don't just do tasks, they also return values. That's why we have a "math" table with functions that we can use for mathematical operations.
1
Value = math.sqrt(4)
Can I make a function that returns something?
Yes, you just have to write the keyword "return" and the value that you want your function to return.
1
2
3
4
2
3
4
function add(x, y) 	return x + y end Value = add(10, 5)
What does "elseif" mean in a condition?
When the first condition did not succeed, we can put the keyword "elseif" with a condition, and if the "elseif" condition is not possible either we can put another one and so on.
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
A = 3 B = 2 if A + B == 6 then 	print("A + B is 6") elseif A / B == 6 then 	print("A / B is 6") elseif A * B == 6 then 	print("A * B is 6") end
What does "else" mean in a condition?
The keyword "else" is used when none of the previous conditions succeeded, so we put the keyword with the code that will be executed alternatively.
1
2
3
4
5
6
2
3
4
5
6
Value = "Test" if Value == "asd" then 	print("Value is asd") else 	print("Value is not asd, it's something else") end
"while" loop
The while loop works similar as the conditional, the difference is that it executes a script while the condition used is still possible.
1
2
3
4
5
6
2
3
4
5
6
A = 0 while A < 10 do 	A = A + 1 	print("A increased by 1") end print("A is "..A)
"repeat" loop
The repeat loop also works similar as the conditional and the while loop, but it works with a conditional that is NOT possible.
1
2
3
4
5
6
2
3
4
5
6
A = 0 repeat 	A = A + 1 	print("A increased by 1") until A >= 10 print("A is "..A)
And why don't we use the "while" loop instead of the "repeat" loop?
The repeat loop has slightly higher frequency of execution than the while loop, that means that its code is executed faster.
What does it mean that tables are pointers?
It means that if you modify a element in that table, any other object that has a copy of that table will be modified aswell.
1
2
3
4
2
3
4
Table = {} CopiedTable = Table Table.VAR = "This is a test" print(CopiedTable.VAR)
What does the RAM usage have to do with scripting?
The RAM memory is the memory that saves all your script variables, it is limited but on newer machines you won't have to worry about the RAM usage.
What is a nil value?
A nil value means a value that is empty, nothing in it. You can use the keyword "nil" to free some memory from your scripts.
1
2
2
Table = {1, 3, 12, 60, 43, 123, 12348, 12347} Table = nil
What is a logical operator?
We have two keyword logical operators, "and" and "or". You will see them most of the time appearing in conditionals like this.
1
2
3
4
5
6
2
3
4
5
6
CS2DRocks = true UnrealSoftwareRocks = true if CS2DRocks == true and UnrealSoftwareRocks == true then 	print("Our community rocks!") end
"len" operator (#)
Then "len" operator also known as length operator is just a character that is put before a variable's name to know what it's length is, it will only be available for use in tables and strings. Tables will tell you how many elements they have, and strings will tell you how many characters they have.
1
2
2
String = "This is a test string" StringLength = #String
1
2
2
Table = {1, 6, 3, 9, 8, 2, 4} TableLength = #Table
Modulus operator (%)
You might think that the modulus operator is a percent, but it actually is what remains from a division.
1
2
3
2
3
A = 10 B = 5 C = A % B
1
2
3
2
3
A = 9 B = 5 C = A % B
"pow" operator
The "pow" operator gets the result of a number multiplied by itself a certain amount of times.
1
A = 2 ^ 4
1
A = 2 * 2 * 2 * 2
Can I put a function inside a table?
Yes, just as you've been taught in the previouses lessons, you can define functions in different ways.
Some functions you might want to use for your scripts
tostring: The "tostring" fuction converts any type of value into a readable string. Normal strings are not affected by this function.
1
2
2
Number = 123 String = tostring(Number)
tonumber: The "tonumber" function converts certain type of values into numerical values, if it can't be converted then it results nil.
1
2
3
4
5
2
3
4
5
A = "0123" B = tonumber(A) C = "test" D = tonumber(C)
pcall: The "pcall" function calls a function with some arguments, the special part of it is that it catches Lua errors and doesn't throw them to the console, but you receive them as a string value.
1
2
3
4
5
2
3
4
5
function AFunctionThatTriggersAError() 	error("This is the error") end Success, Error = pcall(AFunctionThatTriggersAError)
Is there any other way to operate with booleans?
Yes, there's a very simple conditional that lets you to know if a value is not nil and not false
1
2
3
4
2
3
4
Value = true if Value then 	print("Value is not nil and not false") end
Does the previous method work just with booleans?
No, it works with any Lua type while it's not nil and not false.
1
2
3
4
5
2
3
4
5
Value = 12345 if Value then 	print("Value is not nil and not false") 	print("Value is "..Value) end
How can I know all the elements that a table has?
There are two methods. The first method is pairs, it loops through ALL elements with key and value and executes a script that you can give to it. The second method is ipairs, it loops numbers keys only and starts from 1 until it finds a empty value.
1
2
3
4
2
3
4
Table = {10, "test", ["keyname"] = "test2"} for Key, Value in pairs(Table) do 	print("KEY: "..Key.." Value: "..Value) end
Console has written
KEY: 1 Value: 10
KEY: 2 Value: test
KEY: keyname Value: test2
KEY: 2 Value: test
KEY: keyname Value: test2
1
2
3
4
2
3
4
Table = {10, "test", ["keyname"], [5] = 40, [6] = 70} for Key, Value in ipairs(Table) do 	print("KEY: "..Key.." Value: "..Value) end
Console has written
KEY: 1 Value: 10
KEY: 2 Value: test
KEY: 2 Value: test
ipairs will skip "keyname" because it is a string, and it will skip the 5th and the 6th element because the 3rd and the 4th elements are missing in the table.
What does it mean that everything is a variable?
It means that every single thing that you've defined in your Lua script's memory will act as a variable, even functions are variables. Using functions as variables will be quite useful if you try to trigger events.
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
Event = {} function SetEventFunction(EventType, Function) 	Event[EventType] = Function 	-- Let's test our function 	Function("this is a test") end function OnEvent(Argument1) 	print("Function called with input: "..Argument1) end SetEventFunction("Click", OnEvent)
Metatables
This topic isn't quite bound to variables but it needs to be explained now so I can continue with the following topics on the IV cathegory.
The metatables are tables that insert other functionalities into normal tables, it will give you the possibility to use tables as functions, numbers or strings. It does not sound logic but you'll be taught soon how that works.
1
2
3
2
3
Metatable = {} Table = {} setmetatable(Table, Metatable)
Note: setmetatable also returns the original table which is going to receive the metatable object.
Add: If you have two objects (ObjectA and Object), let's assume that ObjectA is a table, ObjectB could be anything.
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
Metatable = {} function Metatable.__add(ObjectA, ObjectB) 	if type(ObjectB) == "number" then 		return ObjectA.Value + ObjectB 	elseif type(ObjectB) == "table" then 		return ObjectA.Value + ObjectB.Value 	end end ObjectA = setmetatable({Value = 10}, Metatable) ObjectB = 35 ObjectC = {Value = 22} ObjectD = ObjectA + ObjectB
ObjectD results 10 + 22 = 32
Sub: Sub works the same way as Add, but the difference is that it uses the minus character (-).
1
2
2
function Metatable.__sub(ObjectA, ObjectB) end
Mul: Mul works the same way as Add, but the difference is that it uses the multiplication character (*).
1
2
2
function Metatable.__mul(ObjectA, ObjectB) end
Div: Div works the same way as Add, but the difference is that it uses the division character (/).
1
2
2
function Metatable.__div(ObjectA, ObjectB) end
Mod: Mod works the same way as Add, but the difference is that it uses the modulo character (%).
1
2
2
function Metatable.__mod(ObjectA, ObjectB) end
Pow: Pow works the same way as Add, but the difference is that it uses the exponentiation character (^).
1
2
2
function Metatable.__pow(ObjectA, ObjectB) end
Unm: Unm works the similar to Sub, but the difference is that it uses only one argument.
1
2
3
2
3
function Metatable.__unm(ObjectA) 	return -ObjectA.Value end
Concat: Concat works the same way as Add, but the difference is that it uses the concatenation characters (..).
1
2
3
2
3
function Metatable.__concat(ObjectA, ObjectB) 	return ObjectA.String .. ObjectB.String end
Len: Len works the same way as Unm, but the difference is that it uses the concatenation character (#).
1
2
2
function Metatable.__len(ObjectA) end
Eq: Eq works the same way as Add, but the difference is that it uses the comparison characters (==).
1
2
3
2
3
function Metatable.__eq(ObjectA, ObjectB) 	return ObjectA.Value == ObjectB.Value end
Function memory
Every function is bound to it's own memory, the memory is the amount of variables this function will have to loop through in order to find a value.
Upvalues
The function's upvalues are values that cannot be modified unless they're pointers (tables can be modified because they're pointers). I'll show you how to make a function with a upvalue on it's memory.
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
function GenerateFunctionWithUpValue(Value) 	-- This is a function that returns another function 	return function () 		-- Whatever is returned here will be able to access the arguments from the top 		print(Value) 	end end Function = GenerateFunctionWithUpValue("This text is an upvalue being printed") Function()
Function environment
The function environment is like the workspace of your function, _G is the default function environment. However you can create functions and modify their environments so they won't be able to access variables that you want to be locked.
1
2
3
4
5
2
3
4
5
function TestFunction(Message) 	print(Message) end setfenv(TestFunction, {print = print}) TestFunction("test message")
Hint: This is an optimization trick I use for my heavy functions, the less amount of variables it uses, the better it performs.
Tables as functions under metatables
Following the examples from Operators IV, you will be able to use the __call metamethod to make the tables act as functions.
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
Metatable = {} function Metatable.__call(Table, Arg1, Arg2, Arg3, ...) 	-- When we call our table, our first argument will be the table object 	-- The following arguments will be the arguments assigned to our call. end ObjectA = setmetatable({}, Metatable) ObjectA("test", 123, {Test = "Variable"} )
Conditions under metatables
Metatables can also support the "<" and "<=" operators, they've got their own metamethods which are called whenever you use any of the previouses operators.
Lt: Lt works the same way as Eq, but the difference is that it uses the lower than character (<).
1
2
3
2
3
function Metatable.__lt(ObjectA, ObjectB) 	return ObjectA.Value < ObjectB.Value end
1
2
2
ObjectA < ObjectB ObjectB > ObjectA
Le: Le works the similar to Lt, but the difference is that it uses the lower than character and the equal character (<=). Which means we're comparing a variable that could be lower or equal to another one.
1
2
3
2
3
function Metatable.__le(ObjectA, ObjectB) 	return ObjectA.Value <= ObjectB end
1
2
2
ObjectA <= ObjectB ObjectB >= ObjectA
Custom loops
Have you ever wondered how the pairs function works like in loops?
1
2
3
2
3
for Key, Value in pairs(Table) do 	print(tostring(Key).." = "..tostring(Value)) end
I'll show you the equivalent code in another way.
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
local PairsFunction = pairs(Table) while true do 	local Key, Value = PairsFunction() 	if Key and Value then 		print(tostring(Key).." = "..tostring(Value)) 	else 		break 	end end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function EachString(Table) 	local Index = next(Table) 	return function () 		while Index do 			-- Repeat this process until we find a string 			local Key, Value = Index, Table[Index] 			Index = next(Table, Index) 			if type(Value) == "string" then 				-- Return the index and the value 				return Key, Value 			end 		end 		Index = next(Table, Index) 	end end TestTable = {1, 5, "Cookies", 30, "Test", {}, print} for Key, Value in EachString(TestTable) do 	print(tostring(Key).." = "..tostring(Value)) end
As you might know, Lua doesn't support a native object oriented programming. For that, I've decided to create my own standard to object oriented programming.
Only few rules are required to do this.
1. The name of the class must be written with the UpperCamelCase style.
2. The name of the file must be the same as the name of the class you're going to make.
3. The name of the class must be initialized as a table at the begining of the code.
4. A '__index' attribute must be added to the table, and it's value must be the table itself.
5. A 'Type' attribute needs to be added, as a string (which is the name of the class) for identification.
6. The constructor & creator of the class must be 'Class:new()' where the 'Class' is the name of your class.
7. The constructor of the class must be added before the metamethods.
8. The methods must be added after the metamethods.
Example for 'MyClassName.lua'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
MyClassName = {} MyClassName.__index = MyClassName MyClassName.__type = "MyClassName" function MyClassName:new(constructor, arguments, etc, ...) 	 	local self = {} 	 	self.Value = constructor 	 	return setmetatable(self, MyClassName) end function MyClassName:__tostring() -- This is a metamethod 	 	return tostring( self.Value ) 	 end function MyClassName:__concat(what) -- This is a metamethod 	 	return tostring( self ) .. tostring( what ) 	 end function MyClassName:DoSomething() -- This is a method end function MyClassName:GetSomeValue() -- This is a method 	 	return self.Value 	 end function MyClassName:SetSomeValue(Value) -- This is a method 	 	self.Value = Value 	 end
edited 26×, last 13.11.17 03:43:56 pm