Collaborative Lua Tutorial

View previous topic View next topic Go down

Collaborative Lua Tutorial

Post by JHaskly on Fri Aug 20, 2010 7:04 pm

Here is the collaborative Lua tutorial made a while back for the old "new" forums.

Please feel free to suggest any corrections, additions, etc.




Introduction:

Lua (or RCLua, when used in RC), is a way to make your models do things on their own, react to there surroundings and themselves, and display information. It takes the form of a simple code, easy enough to learn. As with any code, programming or scripting language, it is useful to set it out neatly. A common way is to indent every level of code with [Tab]. If you are using RCD, then you can just start typing the Lua directly into the Lua section. Otherwise, Surround the Lua in Lua{ and }.

Functions:

The first thing you need to know about in RCLua are functions. In every model using Lua you need to have either function main() or the three On*() functions. In function main(), every line of code is executed once per frame. It is a more basic way to use RCLua.

The On*() functions consist of three different functions, but you need to use all of them for the script to run correctly.
The functions are:
function OnInit()
function OnReset()
function OnFrame()

function OnInit() is executed on the first frame after you load the model from file (via Open or [Ctrl+O] or [Ctrl+u]). This function is typically used to set variables.
function OnReset() is executed on the first frame after you reset (via [+U] or [+R]) the model. Usually, this is the same as function OnInit().
function OnFrame() is like function main() in that it is executed every frame.

To add extra functions, you must type:

Code:
function <NameOfTheFunction>()

Then, to execute this function, you must write [function]() in another executed function.

Code:
Lua{
   function example()
   end


   function main()
      example()
   end
}

Absolute Statements:

The simplest thing you can do in Lua is create an absolute statement, or something that happens no matter what, as long as the function it is in is executed. This is done by saying [Variable] = [value] {operator} [value]

Code:
   ELEVATOR = ROLL + PITCH

The operators are =
+ addition
- subtraction
* multiplication
/ division
^ power


As with general maths, surrounding something in brackets tells the Lua to perform that operation first.

Code:
   ELEVATOR = (ROLL + PITCH) * 2

is equivalent to

Code:
   ELEVATOR = ROLL * 2 + PITCH * 2

If Statements:

The next thing you can do is create a statement that only happens if something is happening, or a certain condition is met. The basic if statement is: if [logic statement] then [code to execute] end

Code:
   if MODE == 1 then
      ELEVATOR = ROLL + PITCH
   end

The logic comparison operators are:
== is equal to
=~ is unequal to
< is smaller than
> is greater than
<= is smaller than or equal to
>= is greater than or equal to

NOTE: "==" Checks equality, "=" forces it. In other words, "==" is used in logic statements, and "=" is used to alter variables. This is very important, as it may affect the operation of your model.

You can also combine logic statements, using {and} or {or}

Code:
   if MODE == 1 and GEAR > 0 then ... end

In this case, if MODE is one, and the gear value is larger than zero, it will execute the command.

Code:
   if MODE == 1 or GEAR > 0 then ... end

In this one, if MODE is one, or the gear value is larger than zero, or both, it will execute the command.

After the [if True statement]s, you can add in else, or elseif.

Code:
if <logic statement> then
   <code to execute if logic is true>
else
   <code to execute if logic is NOT true>
end

Code:
if <logic statement1> then
   <code to execute if logic1 is true>
elseif <logic statement2> then
   <code to execute if logic2 is true>
end

Code:
if [logic statement1] then
   >code to execute if logic is true>
elseif [logic statement2] then
   <code to execute if logic2 is true>
else
   <code to execute if ALL logic is NOT true>
end

NOTE: You can use "elseif" as many times as you want, but "else" can only be used once.

So, the if-else-elseif chain acts as kind of a set of stairs. If the first condition is not met, it goes on and checks the next step down, and so on. If none of the conditions are met, it looks for an "else" statement, and then operates that. If at any point the current condition is met, however, it will carry out those operations, and just jump off the staircase and go to the rest of your code (ignoring the rest of the if construct).

NOTE: if statements can be stacked multiple times ("nest"). Functions can also be executed in if statements.

While Loops: (And a whole lot of other stuff)

A while loop is another type of loop, controlled by a single logic comparison. The syntax is:

Code:
while <logic comparison> do
   ...
end

It is a pretty simple function to understand, as it does what you would expect.

Code:
Lua{
   local count = 0;
   local hiddenValue = 34;
   local found = 0;

   function count(max)
      while(count < max) do
         if(count == hiddenValue) then
            found = count;
         end

         count = count + 1;
      end

      if(count >= max) then
         count = 0;
      end
   end

   function main()
      count(100);
      out(0, "The hidden value found is "..found.."!");
   end
}

Don't be intimidated by this code, it's not as complicated as it looks!
First off, we start by creating a local variable. A variable is any sort of data that you can change within the code to whatever you want. They can be character strings (Such as "Hello World!"), numbers, functions, arrays, or Boolean values (Either true, or false).

We made a variable called count, which is created with a value of 0. Notice how We made it outside of the main function, because the main function is called every frame, therefore the value would be set to 0 every frame if it was in the main function! Then is our function called count(). It takes a single argument, in this case a number called "max". When a function takes an argument, you pass it that argument by calling the function like this:

Code:
foo(bar)

Where foo() is the function, and "bar" is the argument.

Inside that function, we have the while loop. Inside that while loop, we have the code to be executed if "count" is less than "max". What that code is doing is checking whether the count value is equal to this "hiddenValue". If it is, we set "found" to the value of "count", therefore the value of "hiddenValue"! Follow me? If not, we increment "count" by one so the loop can go back around and check again. Also in that function is a check to make sure count doesn't go above the max value we specified, in this case 100. If it does, it gets set back to 0.

Only thing to do after that is call the function inside main(). I do this by writing "count(100);". This calls count() and sets "max" to 100. Then I output the hidden value using out().

Code:
out(lineNumber, "text")

The main thing you need to know about while loops is that unlike an if construct, which runs once a frame, a while loop will repeat itself indefinately until the condition is False. Be careful here though, because if your While loop doesn't cause the condition to be False, the loop will run forever and crash your RC.

Simple, eh?

For Loops:

A very important ability in Lua is to call the same function multiple times per frame. This is especially useful in things like chainguns, radar and some other models.

Code:
   for <declaration>do <code here> end

The <declaration> usual looks like this:
<variable> = min,max,increment
The <variable> is a new local variable, that is created by the for loop and changes during each frame. It is only usable inside the loop.

Code:
   for i = 0,4 do
      out(i,i+2)
   end

#=> 2
#=> 3
#=> 4
#=> 5
#=> 6[/code]

The for loop will perform the code inside it multiple times per frame, (max-min)/increment times. The variable, in this case "i", changes each time the code is performed.
Basically:
  1. The variable starts as <min].
  2. The <code> is performed.
  3. <increment> is added to the variable (default is 1 if left blank)
  4. Repeats steps 2-3 until the ariable is over <max>.


Code:
   for j = 0,4,2 do
      out(i,i+2)
   end

#=> 2
#=>
#=> 4
#=>
#=> 6

As another example, we will try to script a 3D line contrail/cord.

Code:
Lua{
   timer = 0
   x,y,z = {},{},{}

   function cord()
      x[timer] = _X(0)
      y[timer] = _Y(0)
      z[timer] = _Z(0)

      _SETCOLOR(16711680)

      _MOVE3D(x[0],y[0],z[0])
      for tdisp = 1,timer do
         _LINE3D(x[tdisp],y[tdisp],z[tdisp])
      end

      timer = timer + 1
   end

   function main()
      cord()
   end
}

Im guessing some of this looks like nonsense to you. First off, tables. To create a table, you create a variable and instead of assigning a number, boolean or string to it, you assign a table value, or "{}". Then, to call or assign a specific value, you use the "[]" brackets. You contain the assigner in the curly brackets, this can be either a number or "string" value.

Code:
   table[<any_value>] = 6
   table[7465] = true
   table["a_string"] = table[7465]

NOTE: You can also call a string assigner a different way. For example, table["a_string"] could also be written as table.a_string

The next thing you may not know is 3D lines. They are pixel wide lines that are drawn in the RC world, often used as "targetting lasers".

Code:
   _SETCOLOR(col)
   _MOVE3D(x,y,z)
   _LINE3D(x,y,z)

_SETCOLOR() Takes the decimal version of a #****** 6 digit hex color code, and sets the color for all lines after it is called.
_MOVE3D() Sets the start position for the line.
_LINE3D() Sets the end position for the line and draws it. It also sets the start possition for the next 3D line. (can be overwritten with _MOVE3D)

function cord() works by setting up a table for the X,Y, and Z co-ordinates every frame. Then, the function stores the co-ordinates every frame in these tables. Then, it sets the color for the line to red. Then it sets the start of the line to wherever the model was in the first frame. Finally, it uses a for loop to draw a section of the line to where it was in the next frame. This repeats until the end of the line is reached.

Another function that works well with for loops is _G[]. _G[] is for calling a variable (or chipname). It takes "strings" and/or numerical values as its input. Writing "variable" is equivalent to writing _G["variable"].

Code:
   for i = 1,4 do
      local gunangle = {}
      gunangle[i] = _G["GANG"..i]
   end


Where GANG1, GANG2, GANG3, GANG4 are variables defined in the VAL section of RCD.
Seperate inputs are seperated with ".." (Which is used to concatenate (join together) strings).

One Last Word:

This is most of what you need to start scripting using Lua in RC! Have fun!

Made By: Juz30, Chris220, Fredsmith, Bwansy
Made For: http://www.rigid-chips.com/forums
irc://freenode/RigidChips

_________________
Previously (and currently) known as Juz.

Please do not write "LUA", beause it's "Lua". It's Moon in Portuguese, not a Limited User Account, Last Universal Ancestor, or the Lukla Airport in Nepal.

JHaskly
Admin

Posts : 235
Join date : 2010-07-16
Age : 21
Location : Brisbane

View user profile

Back to top Go down

View previous topic View next topic Back to top

- Similar topics

 
Permissions in this forum:
You cannot reply to topics in this forum