====== 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.