· 6 years ago · Mar 31, 2019, 06:12 AM
1______
2Basics
3______
4
5Since Lua is a language designed to be operated alongside other languages for scripting, it is not
6recommended to learn lua in of itself, rather to learn the language and operate it with other languages or
7API's. That being said, these notes aren't written for those who don't understand the basics of coding. In
8this chapter here, we're going to cover all of the baseline code in one go, so as to get straight to the
9point where we can use this language for game development.
10
11Comments:
12A single-line comment uses two dashes at the start of it, and a multi-line comment uses two brackets at the
13beginning and end of the comment.
14___________________________________________
15-- print("Hello, Adam") single-line comment
16--[[
17print("Hello, Adam")
18multi-line comment
19--]]
20___________________________________________
21
22Integers:
23All numbers in Lua are doubles; with all 64-bit doubles being stored in 52 bits. Precision isn't a problem
24for integers less than 52 bits.
25________
26x = 1
27print(x)
28________
29
30Strings:
31Strings in Lua are Immutable; meaning that while the string themselves can not be changed, their pointers
32can be. Lua also has capability for multi-line strings using brackets.
33___________
34a = 'Hello'
35b = "Adam"
36c = [[How
37are
38you?]]
39print(a)
40print(b)
41print(c)
42___________
43
44Strings can concatinate using the '..' operator.
45______________________________
46name = 'Adam'
47print ('My name is ' .. name)
48______________________________
49
50Clearing Memory:
51You can undefine an object using the nil keyword. Undefined objects will be outputted as nil.
52____________________
53name = 'Adam'
54print(name) -- Adam
55name = nil
56print(name) -- nil
57____________________
58
59While:
60While statements, also known as Blocks in Lua, are denoted using the 'do' and 'end' keywords.
61________________
62x = 0
63while x < 10 do
64 x = x + 1
65 print(x)
66end
67________________
68
69If:
70If statements operate similar to While, using the 'then' keyword instead of 'do'.
71____________________
72x = 0
73
74if x ~= 5 then
75 x = x + 1
76 print(x)
77else if x == 5 then
78 print('Five')
79end
80end
81____________________
82
83Conditional Operators:
84Conditional operators include less than, greater than, is, and isn't.
85____________________________________
86x = 10
87
88while x > 5 do
89 x = x - 1
90 print(x)
91end
92
93if x == 5 then
94 print('Five')
95 x = x + 1
96end
97
98while x < 10 do
99 x = x + 1
100 print(x)
101end
102
103if x ~= 0 then -- Isn't operator
104 print('Good job.')
105end
106____________________________________
107
108Read/Write:
109You can perform input with lua using io.read() after assigning a pointer to it. io.write() is very similar
110to print(), but allows us to perform actions alongside it similar to cout in C++.
111______________________________________
112print('Enter a number: ')
113n1 = io.read()
114print('Enter another number: ')
115n2 = io.read()
116io.write(n1, ' + ', n2, ' = ', n1+n2)
117______________________________________
118
119Length:
120You can determine the length of a variable by simply using the length operator #. In the example below, we
121output 4.
122_____________
123name = "Adam"
124print(#name)
125_____________
126
127Boolean Values:
1280, '', and 'true' are all boolean values for true while nil and 'false' are boolean values for false. The
129keywords 'not', 'and', and 'or' can be used in loops when operating with boolean values.
130___________________________________________
131boolTrue = 0
132boolTrue2 = ''
133boolTrue3 = true
134boolFalse = nil
135boolFalse2 = false
136
137if boolTrue then print('true') end
138if boolTrue2 then print('true') end
139if boolTrue3 then print('true') end
140if not boolFalse then print('false') end
141if not boolFalse2 then print('false') end
142___________________________________________
143
144The format bellow follows the Conditional Operator a?b:c from C++ where the value following and is
145representative of true, and the value following or is representative of false. Its a short way of writing an
146if-else statement.
147_________________________________________
148boolTrue = 0
149boolTrue2 = ''
150boolTrue3 = true
151boolFalse = nil
152boolFalse2 = false
153
154bool = boolTrue3 and 'true' or 'false'
155bool2 = boolFalse2 and 'true' or 'false'
156
157io.write(bool, ' ', bool2)
158_________________________________________
159
160We can check the validity of statements in a program by using the 'assert' function. This function checks to
161see if its argument is true, and if so, outputs "true" when called on. If the argument is false, then an
162error occurs.
163_____________________
164x = 1
165
166print(assert(x == 1))
167_____________________
168
169For:
170For statements operate similar to C++ with the implementation of Luas do and end operators. In the example
171below, the value x is our initial statement with 10 being our expression statement. The expression statement
172operates moreso as a target destination, so in the example below its no different then 'while (x < 10)'.
173________________
174for x = 1, 10 do
175 print(x)
176 x = x + 1
177end
178________________
179
180The end expression is optional in Lua. The example bellow increments x, just as the program above does.
181________________________________
182for x = 1, 10, 1 do print(x) end
183________________________________
184
185Scope:
186All variables are global by default. To make a variable local, simply use the 'local' keyword.
187________________
188x = 1
189
190if x == 1 then
191local y = x
192print(y) -- 1
193end
194
195print(y) -- nil
196_______________
197
198Repeat:
199Repeat is a loop type found in Lua. It simply uses the 'repeat' keyword to create the loop, and uses 'until'
200to define a stopping point. This is a safe and easy way to create loops in Lua, as the 'until' keyword is
201syntaxically required to create the loop.
202_____________
203x = 10
204
205repeat
206 print(x)
207 x = x - 1
208until x == 0
209_____________
210
211Functions:
212Functions work similar to that of C++, with the 'return' keyword operating in a similar manner. Since all
213variables in Lua are global unless stated otherwise, its very easy to transfer data across a program, however
214it's also easy to mix up said data in large programs.
215______________________________
216function add(number1, number2)
217 return number1 + number2
218end
219
220io.write(add(1, 2))
221______________________________
222
223Tables:
224The only compound data structure in Lua is tables. Tables allow us to create custom datasets. In the example
225bellow we create a custom table thats able to hold integers, strings, and boolean values. We can add new
226data entries to tables at any time, and remove values from the table by setting them to nil.
227________________________________________
228x = {int = 1, str = 'Adam', bool = true}
229x.bool = nil
230x.bool = false
231
232io.write(x.int + 2)
233print(x.str)
234if not x.bool then print('false') end
235________________________________________
236
237We can also iterate through a table by using the 'pairs' keyword. The following program will output each key
238and their current value associated with it. Keep in mind that on output the bool value is on the top of the
239list, this is because we change its value and it is now present on the top of the stack.
240________________________________________
241x = {int = 1, str = 'Adam', bool = true}
242x.bool = nil
243x.bool = false
244
245for key, val in pairs(x) do
246 print (key, val)
247end
248________________________________________
249
250Metatables:
251With tables in Lua we can add/substract values in a table, check values associated within a table, and
252iterate through all values within a table. With metatables we can change the behavior of a table. In order
253to change the behavior of a table, we need to set a metatable that corresponds with it. We can use the
254keyword 'setmetatable' to set or change the metatable.
255________________________________________
256x = {int = 1, str = 'Adam', bool = true}
257x1 = {}
258
259setmetatable(x, x1)
260________________________________________
261
262Any table can be a metatable, including the table itself (allowing it to define its own behaviors). We can
263use the 'getmetatable()' function to figure out if a metatable exists for a table. If one is found, then the
264address of the table is outputted, and if one isn't, than the compiler will output nil.
265________________________________________
266x = {int = 1, str = 'Adam', bool = true}
267x1 = {}
268
269setmetatable(x, x1)
270
271print(getmetatable(x))
272________________________________________
273
274Metamethods:
275When the metatable is ran, the system checks for any functions associated with it known as Metamethods. The
276first metamethod we will look at is called '__index' (keep in mind that ALL metamethods are preceded by TWO
277underscores). __index allows us to create a sub-list of items, allowing us to either add things that do not
278exist on our table, or that we want to have on our table but under lower priority.
279________________________________________
280x = {int = 1, str = 'Adam', bool = true}
281x1 = {
282 __index = {
283 num = 2
284 }
285}
286
287setmetatable(x, x1)
288
289print(x.num)
290________________________________________
291
292In the example above we're trying to output a value associated with the key 'num' but 'num' does not exist
293on our table 'x'. What the compiler will procede to do is search for a metatable associated with the table
294specified and to see if that metatable has an index. If so, the compiler will then search the index for the
295key specified. Since 'num' is located within our index, the compiler will output its value '2'. Now if num
296were to be located in both the table AND the metatable, then the table would take higher priority and it's
297value would be outputted instead of the one located in the index. If no key labeled 'num' existed in either
298the table or the index, then the compiler would output nil.
299
300An alternate choice to __index is __newindex, where we add a level of dynamicacy in subsitute of the
301structured dataflow that __index provides.
302_________________________________________________________________________
303local mt = {}
304local x = setmetatable({one = 1, two = 2, three = 3}, {__newindex = mt})
305
306print(x.one)
307x.four = 4
308print(mt.four)
309_________________________________________________________________________
310
311The example above is simple. We declare the metatable in the variable x itself, and direct all unlisted
312values as __newindex to the metatable. In this case we create a new key "four" and set its value to 4, which
313can be easilly called on.
314
315Using the __call metamethod, we can treat our metatables as functions, and call on our tables as if they
316were functions.
317_______________________________________________
318local mt = function(t, n)
319 if not t[n] then
320 t[n] = n*fact(n-1)
321 end
322 return t[n]
323end
324
325fact = setmetatable({[0] = 1}, {__call = mt})
326
327print(fact(7))
328______________________________________________
329
330In the above example we turn our metatable into a function that takes 7 and outputs its factorial value.
331We can then set the table to the metatable, while also allowing us to handle input as if it were a function,
332using the __call metamethod.
333
334Earlier we discussed how to determine the length of variables using the length operator #. Using the __len
335metamethod (as of Lua 5.2) we can determine the length or how many items exist within a table. The below
336example will output 2.
337_________________________________________
338local mt = function (op)
339 if type(op) == "string" then
340 return strlen(op)
341 else if type(op) == "table" then
342 return #op
343 end
344end
345end
346
347x = setmetatable({1, 3}, {__call = mt})
348
349print(x())
350_________________________________________
351
352Arithmetic Metamethods:
353There are many metamethods that allow us to perform standard mathmatical operations on items in a table.
354______________________________________
355x = {}
356
357mt = {
358 __add = function ()
359 a = io.read()
360 b = io.read()
361 print(a+b)
362 end
363}
364
365setmetatable(x, mt)
366
367local y = (getmetatable(x).__add())
368______________________________________
369
370The above example creates a variable y that requests the __add metamethod from x's metatable. The __add
371metamethod is then treated like a function, and gathers user input for two variables (a and b) and outputs
372the sum. The __add metamethod, like other metamethods we will cover, is not REQUIRED to perform the
373mathmatical operation, rather is a system that tells the metatable what to do when __add metamethod is
374requested.
375_____________________________________
376x = {}
377
378mt = {
379 __add = function ()
380 a = io.read()
381 b = io.read()
382 print(a-b)
383 end
384}
385
386setmetatable(x, mt)
387
388local y = (getmetatable(x).__add())
389____________________________________
390
391In the example above we recreated our program, but now it performs subtraction despite calling the __add
392metamethod. Here are the other standard arithmetic metamethods:
393___________________________________________
394x = {}
395mt = {}
396
397function mt.__add()
398 a = io.read()
399 b = io.read()
400 print(a + b)
401end
402
403function mt.__sub()
404 a = io.read()
405 b = io.read()
406 print(a - b)
407end
408
409function mt.__mul()
410 a = io.read()
411 b = io.read()
412 print(a * b)
413end
414
415function mt.__div()
416 a = io.read()
417 b = io.read()
418 print(a / b)
419end
420
421function mt.__pow()
422 a = io.read()
423 b = io.read()
424 print(a ^ b)
425end
426
427setmetatable(x, mt)
428
429local output1 = (getmetatable(x).__add())
430local output2 = (getmetatable(x).__sub())
431local output3 = (getmetatable(x).__mul())
432local output4 = (getmetatable(x).__div())
433local output5 = (getmetatable(x).__pow())
434___________________________________________
435
436The metamethod __unm is used for operating with negation. In the program below, we can input a positive
437number to get its negative value, or input a negative number to get its positive value.
438____________________________________________
439x = {}
440mt = {}
441
442function mt.__unm()
443 a = io.read()
444 print(-a)
445end
446
447setmetatable(x, mt)
448
449local output = (getmetatable(x).__unm())
450___________________________________________
451
452Comparison Metamethods:
453Lua offers a set of metamethods that allow us to compare data types and values. The first of which we will
454look at is the __eq metamethod for testing equality. The __eq metamethod is called on when the == operator is
455pushed.
456________________________________________
457x = {}
458mt = {}
459
460function mt.__eq()
461 a = io.read()
462 b = io.read()
463 if a == b then
464 print(true)
465 else
466 print(false)
467 end
468end
469
470setmetatable(x, mt)
471
472local output = (getmetatable(x).__eq())
473_______________________________________
474
475Our other comparison metamethods include __lt (less than) and __le (less than or equal to). There isn't a
476metamethod for greater than/greater than or equal to so you will have to structure your variables carefully
477when handling these comparisons with metamethods.
478________________________________________
479x = {}
480mt = {}
481
482function mt.__eq()
483 a = io.read()
484 b = io.read()
485 if a == b then
486 print(true)
487 else
488 print(false)
489 end
490end
491
492function mt.__lt()
493 a = io.read()
494 b = io.read()
495 if a < b then
496 print(true)
497 else
498 print(false)
499 end
500end
501
502function mt.__le()
503 a = io.read()
504 b = io.read()
505 if a <= b then
506 print(true)
507 else
508 print(false)
509 end
510end
511
512setmetatable(x, mt)
513
514local output1 = (getmetatable(x).__eq())
515local output2 = (getmetatable(x).__lt())
516local output3 = (getmetatable(x).__le())
517_________________________________________
518
519Modules:
520Modules allow us to have other files running inside our Lua program. To create a module, we simply create a
521program and save its file within our project. Here is an example:
522___________________________
523mod.lua
524
525x = {}
526local function printName()
527 print('Adam')
528end
529
530function x.printHello()
531 print('Hello, ')
532 printName()
533end
534
535return x
536___________________________
537
538We can then call on the module in our main file with the following:
539__________________________
540main.lua
541
542local mod = require('mod')
543
544mod.printHello()
545__________________________
546
547Note that we treat 'mod' as the function name when calling on its values, rather than by the name of its
548functions within itself.