Beginner's Guide
This article is for people completely unfamiliar with Lua who want to jump right into Pluto.
For people already familiar with Lua, the rest of this documentation should be a good introduction to Pluto.
Your first program
Let's start simple by saying hello to the world.
print("Hello, world!")
Try It Yourself
Participation using the "try it yourself" links is recommended. Also feel free to modify the code and use the terminal to run it again (Arrow Key Up + Enter).
As you can see, this program prints "Hello, world!", and it does so by calling the builtin print
function from Lua.
Simple arithmetic
Of course, we want more than a glorified text file, so let's get a bit more programmatic with some arithmetics.
print($"2 + 2 is {2 + 2}")
Notice the $
before the string; this allows us to use curly brackets to embed expressions directly into the string. In this case, we embed the expression 2 + 2
, which evaluates to 4.
Try It Yourself
Variables
Variables in Lua/Pluto are global by default and are assigned trivially:
a = 2
print($"a is {a}")
a += 2
print($"I added 2 and now it's {a}")
Notice how we still have a $
before the strings but this time we're embedding the expression a
which simply evaluates to the value of a
at that particular moment.
Try It Yourself
Conditionals
Programming isn't just about arithmetics, tho, so let's get into the flow — or the "control flow", as computer scientists would call it.
a = 1
b = 2
if a + b == 4 then
print("The sum is 4!")
else
print("The sum is not 4. Could you change a or b to fix it?")
end
Try It Yourself
As you see, the message being printed changes based on whether the expression a + b == 4
is true or false.
Loops
We can't just change if code will run, but also how often. For example, we could make a script that counts from 1 to 10:
for i=1, 10 do
print(i)
end
Try It Yourself
We can also change the interval. For example, count from 0 to 100 in intervals of 10:
for i=0, 100, 10 do
print(i)
end
Try It Yourself
Tables
Alright, you know the basic control flow, and data types (numbers and string), so let's look at a more interesting data type: tables. These can store organised data, for example, scores for each player in a game:
players = {
["John"] = 15,
["Jane"] = 10,
["Bob"] = 12,
}
for name, score in players do
print($"{name} has a score of {score}.")
end
Try It Yourself
Notice how we're still using a for-loop, but this time we're iterating over the our players table instead of a range of numbers.
We can also store tables within tables, so we could have more data than just a single number for each player:
players = {
["John"] = {
["kills"] = 15,
["deaths"] = 5,
},
["Jane"] = {
["kills"] = 10,
["deaths"] = 8,
},
["Bob"] = {
["kills"] = 12,
["deaths"] = 8,
},
}
for name, data in players do
print($"{name} has {data.kills} kills and {data.deaths} deaths.")
end
Try It Yourself
Calculating K/D ratios
Let's put all of what we've learned so far to the test and make a program that actually does some work for us instead of the other way around.
players = {
["John"] = {
["kills"] = 15,
["deaths"] = 5,
},
["Jane"] = {
["kills"] = 10,
["deaths"] = 8,
},
["Bob"] = {
["kills"] = 12,
["deaths"] = 8,
},
}
-- Add "kd" field to each player
for players as player do
player.kd = player.kills / player.deaths
end
-- Print
for name, data in players do
print($"{name} has a K/D of {data.kd}.")
end
Try It Yourself
Notice another variant of the for-loop: The for-as loop. This is handy for calculating the K/D since we don't care about the name.
Encapsulation in functions
We've been using functions quite a bit — or at least, the print
function — so it's about time we make our own function.
function calculate_kd(plys: table)
for plys as ply do
ply.kd = ply.kills / ply.deaths
end
end
players = {
["John"] = {
["kills"] = 15,
["deaths"] = 5,
},
["Jane"] = {
["kills"] = 10,
["deaths"] = 8,
},
["Bob"] = {
["kills"] = 12,
["deaths"] = 8,
},
}
calculate_kd(players)
for name, data in players do
print($"{name} has a K/D of {data.kd}.")
end
Try It Yourself
And as you can see, the code behaves exactly the same as before! Perhaps not very interesting, but better than the alternative.
Let's break down what exactly is happening:
- On the first line, we declare a function with the name
calculate_kd
and a parameterplys
of typetable
. Note that the: table
part is optional, but it's always good to be explicit about assumptions! (Didn't think you'd find relationship advice here, did you?) - Then near the end of the script, we call
calculate_kd
with ourplayers
table as an argument.
Local variables
Next, I'd like to introduce local variables, but you've actually already seen them! In the example above, the calculate_kd
function's plys
argument is a local variable, because it is only available within that function's body.
However, other than having a local variable by virtue of it being a function parameter, we can also manually define one just like we've already defined variables except we put local
before it:
local a = 1
print(a)
Try It Yourself
Nil values
However, what happens when we use a variable we didn't define, or we don't give it a value?
local no_value_given
print(no_value_given)
print(never_defined)
Try It Yourself
As you can see, this prints "nil" two times, so that's the answer — we get nil
in both cases. nil
is a special type that is used as the result of valueless expressions.
Where to go from here
You should now have an understanding of the fundemantals of Pluto. If you want to learn more, the rest of this documentation is certainly a good place to learn more about Pluto.
You could start with some of the Pluto features we already made use of in this guide:
- String Interpolation (
$
-strings) - For-As Loop
- Type Hinting
If you want to understand the underpinnings of Pluto a bit better, the Lua manual would be a good place to look.