====== Lua tutorial (VCIScript) ====== This page is a basic tutorial for programming with Lua.\\ This tutorial is written for users who have already completed the steps of creating VCI item and embedding VCI scripts. Please take a look at them first. Note: VCI uses a programing language called VCI.\\ ([[https://en.wikipedia.org/wiki/Lua|Lua - wikipedia]]) ===== Prepare for this tutorial ===== Before you start with this tutorial,\\ please complete the steps of **installing development environment to item creation and execution** in [[en:vci:beginner|Create your first VCI]]. This page doesn’t explain the basic steps to configure environments and other basics. ===== About this tutorial ===== This is a basic tutorial of Lua to get the general idea of programming in Lua.\\ After you have grasped the basics of Lua, refer to [[en:vci:script:reference|VCI Script Reference]] and find out the wide possibility of what VCI can do. ==== 1. About commenting in Lua ==== -- a single line of comment --[[ Multiple lines of comment ]] This is not a comment, thus resulting in an error Comments are texts not included in the program itself.\\ On the first line, the text that comes after the two hyphens become a comment.\\ Texts enclosed by brackets are considered to be multiple-line comments. ==== 2. Printing on console ==== print("string, or text, are enclosed in double quotation marks") message = "You don’t need to declare types for variables, as they are changed dynamically in Lua" print(message) -- To combine strings, connect them with ".." name = "Alicia Solid" print("Hello "..name..", how are you?") num = 1234 print("You have "..num.." left") The result string, or text, are enclosed in double quotation marks You don’t need to declare types for variables, as they are changed dynamically in Lua Hello Alicia Solid, how are you? You have 1234 left You can display a string on the console by including a string in between the parentheses of print().\\ **To use string, enclose the string with "" (double quotation marks). (1)**\\ Also, a variable that contains numbers are automatically converted into a string and printed.\\ (1). Double quotation marks allow the Lua to distinguish between strings and variables. ==== 3. Variables and types ==== name = "Alicia Solid" forever = true age = 17 object = nil -- type() will determine the type of variable and return the result as string print(type(name)) print(type(forever)) print(type(age)) print(type(object)) The result string boolean number nil Basic types available in Lua are number, string, boolean, nil, table (array), function, etc.\\ **Variable type is determined dynamically depending on what you assign to it. **\\ Therefore, you do not need to declare a type at the time of variable declaration. You can simply declare a variable and assign a data directly into it.\\ If you want to see all types available, refer to Lua official documentation. ([[http://www.lua.org/manual/5.2/manual.html#2.1|]]) ==== 4. Scope of a variable ==== GranCount = 0 function onGrab() GranCount = GranCount + 1 print("Grab : "..GranCount) --Determine whether the number of times grabbed is a multiple of 3 local num = GranCount % 3 if num == 0 then print("Multiple of 3") end end function onUngrab() --Accessible print(GranCount) --Inaccessible print(num) end The result Grab : 1 Grab : 2 Grab : 3 Multiple of 3 In Lua, variables declared without "local" can be called from anywhere.\\ (Variables without "local" declaration is handled as global variables)\\ In the example above, "GranCount" can be called from anywhere. When you declared a variable with "local," the variable can only be accessed within the function which the variable was declared in.\\ In the example above, "num" is accessible only from within "onGrab()" function. ==== 5. Handling of number type and its concatenation==== GrabCount = 0 function onGrab() GrabCount = GrabCount + 1 --You can print without converting type. print(GrabCount) --Concatenation of string and number types print("Grab: "..GrabCount) --If an integer is assigned, it is a number type print("GrabCount is "..type(GrabCount).." type") -- Even if you run a computation with decimal, it will remain as a number type local num = GrabCount * 3.14159265 print(num) print("num is "..type(num).." type") --Declare as a string local char = "1234" print("char is "..type(char).." type") --Type conversion from string to number local conversion = tonumber(char) print("conversion is "..type(conversion).." type") end The result 1 Grab : 1 GrabCount is number type 3.14159265 num is number type char is string type conversion is number type Currently in Lua, there is no distinction between int type and float type. Both values are handled as number type.\\ (To be exact, there are no integer values, all numbers are handled as floating-point numerals)\\ Also, when you use "print()" to display a number type, the value can be displayed straight onto console without type conversion.\\ It is also possible to concatenate a string and a number without type conversion. For concatenation use two consecutive periods (..).\\ To convert from a string to a number, use "tonumber()". a = 2 b = 5 num = a + b --Addition print("Addition"..num) num = a - b --Subtraction print("Subtraction"..num) num = a * b --Multiplication print("Multiplication"..num) num = a / b --Division print("Division"..num) num = a % b --Modulo print("Modulo"..num) num = a ^ b --Exponentiation print("Exponentiation"..num) The result Addition7 Subtraction-3 Multiplication10 Division0.4 Modulo2 Exponentiation32 ==== 6. Table type ==== --A table type is declared with ={} table = { 3, 6, 9, 12, 15 } function onGrab() --declare with for statement local t = {} for i = 1, 5 do t[i] = i end --display the table at once print(t[1]..t[2]..t[3]..t[4]..t[5]) --display it with for statement --#table will return the element count (length) of the table for i = 1, #table do print("The value for table "..i.." is "..table[i]) end end The result 12345 The value for table 1 is 3 The value for table 2 is 6 The value for table 3 is 9 The value for table 4 is 12 The value for table 5 is 15 In Lua, an array is handled in the type of table. The table type is useful to handle multiple data as a group.\\ To use tables, you use "for" statement to manipulate all data at once.\\ To declare a table type, you enclose elements with curly brackets {}, like "c = {1, 2, 3, 4, 5}".\\ To access an element, place an index of the element in [], like "c[1]".\\ To get the length of the table, use "#TableName". === Associative array === people = {name = "babiko", age = 17} print(people["name"]) print(people.age) The result babiko 17 You can use a table as an associative array by making it hold pairs of a key and a value.\\ To do this, declare pairs of "key = value" and separate each pairs with colon.\\ You can access the elements by specifying the key string within brackets, or by using a period separator in the form of "Table.Key" (as you can see in the example above). ==== 7. if statement ==== function onGrab(subitem) --The if statement is written in form of "if(Condition) then" if subitem == "bell" then print("ring ring") else print("This is not a bell") end end The example above prints "ring ring" if the subitem was a bell, and if the subitem was not a bell, it would print "This is not a bell".\\ Set the condition in form of "variable = value", and write the process after "then".\\ You can use [[http://www.lua.org/manual/5.2/manual.html#3.4.3|Relational Operators]] and [[http://www.lua.org/manual/5.2/manual.html#3.4.4|Logical Operators]] for conditions.\\ You can utilize these operators to describe conditions of moderate complexity.\\ [[http://www.lua.org/manual/5.2/manual.html#3.3.4|Control Structures]] ==== 8.For Statement and While Statement ==== ==== For Statement ==== num = {2, 4, 6, 8, 10} for i = 1, 5 do print(num[i]) end The result 2 4 6 8 10 Stating "for //i's initial value//, //number of times to repeat// do" will repeat the process enclosed by "for ~ end" for a specified number of times.\\ By default, the i is incremented by one with each repeat.\\ "for //i's initial value//, //number of times to repeat// //incrementation value for i// do" \\ Combining this with the table will allow you to process multiple elements at once, which is convenient for batch processing. [[http://www.lua.org/manual/5.2/manual.html#3.3.5|For Statement]] ==== While Statement ==== i = 0 while i < 5 do i = i +1 print(i) end The result 1 2 3 4 5 Start by writing "while //condition// do", followed by process and the closure "end".\\ It repeats the process inside the while loop until the condition is met.\\ Be careful, as not having a process to exit the while statement will result in an infinite loop.\\ [[http://www.lua.org/manual/5.3/manual.html#3.3.4|Control Structures]] ==== 9. Using Event Functions ==== function onGrab(target) print("Grabbed "..target) end function onUngrab(target) print("Released "..target) end function onUse(use) print("A grip button was pressed while grabbing "..use) end function onTriggerEnter(item, hit) print(item.." and "..hit.." overlapped") end function onTriggerExit(item, hit) print(item.." and "..hit.." exited the overlapped state") end function onCollisionEnter(item, hit) print(item.." and "..hit.." collided") end function onCollisionExit(item, hit) print(item.." and "..hit.." exited the overlapped state") end When VCI is grabbed and released, when a grip button is pressed, when VCI is touched and released...\\ Functions that runs based on the VCI's usage state is called [[en:vci:script:reference:eventfunction|event functions]]. You can also specify **arguments** on event functions.\\ An argument is a mechanism for a function to receive information.** For event functions, *the game object name of SubItem is passed to the argument**.\\ What is the point of receiving SubItem's name? Well, on an event function like ''function onGrab(target)'', by looking at the string in "target", you can tell **which SubItem is being grabbed**.\\ By knowing the name of the grabbed item, you can perform a process against that item. (Argument: For instance, say that there is a function to calculate how many cans of drink you can buy with the money you have. In order to calculate this, you need to tell the function the amount of money you have. The amount of money, in this case, is the argument.) You can also see a list of event functions in "template.lua" inside "EmbeddedScriptWorkspace" folder. ==== 10. Writing your own functions ==== function hello() print("hello") end function onGrab() hello() end The result hello You can create your own functions.\\ To create a function, declare it with "function //AnyName()//", followed by function's process and close it with "end".\\ To run a function, write "YourFunctionName()" inside one of [[en:vci:script:reference:eventfunction:Event Functions|Event Functions]].\\ In VCI scripts, you run your own functions via event functions. ==== 11.Arguments to function and return value ==== {{:en:vci:script:arg_method_return.jpg?direct&200|}} A function perform certain process against inputs and return the result. function onGrab(target) print(ShowPosition(target)) end function ShowPosition(target) local pos = vci.assets.GetSubItem(target).GetPosition() local posc = tostring(pos) local message = target.."'s current position is "..posc.." return message end The result Subitem's current position is (0.0, 0.5, 0.1) You can specify **arguments** and **return value** when declaring functions.\\ An argument is **a mechanism for a function to receive information**. On the other hand, a return value is **a mechanism to return the result of the function's calculation**.\\ Arguments are declared in form of "function //FunctionName//(//Argument//)" and return value is declared in form of "return //ReturnValue//".\\ In the example above, the function "ShowPosition()" uses "target" as the argument, and the return value is "message".\\ By passing the name of a SubItem as the argument "target," current position of the SubItem will be assigned to the "message." As a result, you can retrieve the current position of the SubItem. The benefits of creating functions like this are...\\ * Even if you don't know what's going on inside the function, you can get the results by just knowing the arguments and a return value.\\ * When you need to use a similar process repeatedly, you just call a function and that will do the job.\\ (reusability)\\ * You can improve the readability of the program. ==== 12. Use the Library in Lua ==== --Show date and time print(os.date()) --Display date and time in the specified format print(os.date("%d/%m/%Y")) --Random value print(math.random()) -- Random value in specified range print(math.random(1, 100)) --Circumference ratio print(math.pi) --sin function print(math.sin(vci.me.FrameCount)) The result February 27, 2019 14:20 08/03/2019 0.152287599235907 25 3.14159265358979 0.97997642695433 A library is a group of programs that contains various features (functions).\\ In VCI, you can use the library for VCI as well as **the standard library that comes with Lua itself. (1)**\\ By using all these features in combination, you can implement various features.\\ For example, if you want to make an analog clock, you can use the values from "os.date()" to change the angles of the needles.\\ You can make fortune cookies by using random function. For details on Lua library, see [[http://www.lua.org/manual/5.2/manual.html|Lua 5.2 Reference Manual]].\\ For details on VCI's library, you can get the information on [[en:vci:script:reference|VCI Script Reference]] as well as on "template.lua" inside "EmbeddedScriptWorkspace" folder. (1) There is some restriction on the library you can use. ==== 13. List of available libraries ==== From **Available libraries** in [[en:vci:top|VCI TOP]], download help file.\\ (You can also check the library of Lua itself) You can check the VCI's library in [[en:vci:script:reference|VCI script reference]]. You can also use [[http://codepad.org/|codepad]] to quickly check the behavior of **Lua script by itself**.\\ Of course, this site doesn't support the functions of VCI. It can only be used to program pure Lua.