en:vci:script:luatutorial

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

main.lua
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

main.lua
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

main.lua
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

main.lua
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()”.

main.lua
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

main.lua
--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

main.lua
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

main.lua
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

8.For Statement and While Statement

For Statement

main.lua
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

While Statement

main.lua
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

9. Using Event Functions

main.lua
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.

10. Writing your own functions

main.lua
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.

11.Arguments to function and return value

A function perform certain process against inputs and return the result.

main.lua
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

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

13. List of available libraries

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.

en/vci/script/luatutorial.txt · Last modified: 2021/06/29 19:26 by t-daihisa

Page Tools