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.
(Lua - wikipedia)
Before you start with this tutorial,
please complete the steps of installing development environment to item creation and execution in Create your first VCI.
This page doesn’t explain the basic steps to configure environments and other basics.
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 VCI Script Reference and find out the wide possibility of what VCI can do.
-- 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.
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.
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)
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.
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
--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”.
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).
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 Relational Operators and Logical Operators for conditions.
You can utilize these operators to describe conditions of moderate complexity.
Control Structures
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.
For 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.
Control Structures
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 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.
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 Event Functions.
In VCI scripts, you run your own functions via event functions.
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…
--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 Lua 5.2 Reference Manual.
For details on VCI's library, you can get the information on VCI Script Reference as well as on “template.lua” inside “EmbeddedScriptWorkspace” folder.
(1) There is some restriction on the library you can use.
From Available libraries in VCI TOP, download help file.
(You can also check the library of Lua itself)
You can check the VCI's library in VCI script reference.
You can also use 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.