Aprenda a: Programar na Roblox em Lua com o Desenvolvedor fly_san

Roblox Developer Relations
Roblox Developer Português
16 min readJun 17, 2020

--

Este é um dos tutoriais vencedores do Desafio Mestre do Conhecimento, o qual diversos desenvolvedores da comunidade da Roblox em Português competiram pelo melhor tutorial criado no Fórum dos Desenvolvedores.

O tutorial destacado neste artigo foi criado por fly_san. Tivemos uma breve entrevista com ele para entendermos como foi a sua experiência no desafio.

Fly_san está na plataforma a 7 anos e participa de diversas comunidades. Ele encontrou sua motivação para desenvolvimento enquanto explorava o Roblox Studio. Inicialmente desenvolvia para amigos e grupos que pediam a sua ajuda, e com o tempo foi aprimorando diversas habilidades, como construção, design e programação.

Também perguntamos como foi sua experiência no desafio:

fly_san

“Como alguns dizem, a melhor maneira de aprender é ensinando. Fazer um tutorial é uma oportunidade de revisitar conceitos e tentar explicá-los a outras pessoas de forma mais simples e resumida. Para mim, foi uma experiência muito divertida! Apesar de eu ter começado um pouco atrasado (três dias antes do prazo), foi uma experiência muito rica.

Pessoalmente, já fazia um tempo que eu queria fazer um tutorial mais descontraído, para iniciantes; o desafio do Mestre do Conhecimento foi a oportunidade perfeita para me motivar. Além disso, o feedback do pessoal foi incrível: as respostas, votos e likes me deixaram muito feliz!”

Ansiosos para aprender a programar em Lua? Confira esse tutorial de fly_san

Em um mundo cada vez mais digital, uma das ferramentas que vem crescentemente ganhando relevância é habilidade em programação.

Lua é uma linguagem de programação simples e direta, além de possuir uma série de aplicações, é utilizada em diversos jogos mundialmente conhecidos. Além disso, Lua foi desenvolvida na PUC-RJ, no Brasil!

Então, por que não começar a aprender Lua enquanto se diverte?

1. Vamos lá?!

Abrindo o Roblox Studio

Para começar, abra o Roblox Studio. Se ainda não o tem instalado, clique aqui para ler a respeito.

Programar é o processo de criar instruções para serem seguidas por um computador.

  • No Roblox Studio, essas instruções podem ser dadas através de scripts. Esses scripts dão ao jogo, uma série de instruções, que serão efetuadas durante a execução de uma partida/servidor.

Agora que estamos prontos, vamos inserir uma [ Script ] no seu jogo. Para isso, clique no botão de mais ao lado de ServerScriptService, pesquise por “Script” e tecle enter.

Clique duas vezes no novo objeto [ Script ] - se fez tudo como indicado, você deve estar vendo essa tela:

Esse é o Script Editor, ferramenta que nos permite editar e visualizar nosso código.

2. Output / Console

Debugging — análise de erros

Output é uma ferramenta que nos ajuda a entender melhor o que acontece durante a execução do nosso código.

Para abrí-la, clique em “View” e depois em “Output”, como a seguir:

a) Print

Podemos enviar mensagens para o Output usando uma função chamada de print(). Para isso, basta escrevê-la dentro do Script Editor!

print("Olá pessoal!")  
-- Para escrever um texto (string), colocamos ele entre aspas!
print(12345)
-- Mas, não precisamos colocar números entre aspas.

Atenção: A parte a seguir não deve estar no seu código! Aqui, ela apenas representa o que aconteceria em seu Output se executássemos a script acima

>>> OUTPUT: Olá pessoal! 
>>> OUTPUT: 12345

Quer tentar você mesmo? Onde está escrito print("Hello world!") na sua script, apague e escreva algo mais legal. Clique em “Run” e fique de olho no seu Output!

Além disso, você percebeu que o código foi executado na ordem em que você o escreveu?

Isso sempre irá acontecer, mas é possível fazer um código rodar sem que ele pare os outros; porém esse é um tutorial para iniciantes!

b) Strings e Números

i) Strings
Se nós quisermos escrever um texto, devemos colocá-lo sempre entre aspas!

-- Duas strings diferentes:
"Isso é uma string", 'Eu também sou uma string!'

Esse texto se chama string e há várias formas de manipulá-los:

  • Uma das ferramentas mais úteis é o concatenate ( .. ), que pode unir duas strings em uma só.
"O fptbb gosta de " .. "Suco de Laranja!"
-- Os dois pontos (..) representam a função concatenate,
-- ao colocá-los entre duas strings, elas serão lidas como uma!

ii) Numbers
Já, se precisarmos escrever apenas um número (como 123 ou 4.5), não é necessário colocá-lo entre aspas.

-- Três números diferentes:
123, 0.5, 9.99999

Também podemos manipular esses números. Para fazer isso, usamos operadores matemáticos fornecidos pelo Lua.

50 + 5 -- uau!

Também é possível concatenar uma string e um número

"Eu gosto do número " .. 1000

Além disso, podemos fazer operações aritméticas entre uma string e um número, desde que a string seja composta por apenas um número!

print("10" + 5) -- O resultado é 15

c) Error

Além de mostrar aquilo que escrevemos com print(), nós também podemos ver os erros que aconteceram durante a execução de nossa script!

print('Cem' + 25) 
-- Não podemos efetuar essa operação...
-- Ambos os termos da operação devem ser números, mas 'Cem' é uma string

d) Comentários

Você já deve ter percebido, mas quando escrevemos --, o que vem imediatamente depois, não é lido pela script! Esses são chamados de comments e podem te ajudar a se organizar durante a escrita de um código.

3. Agora é pra valer.

Conhecimentos Básicos

a) Variáveis

Variáveis são um dos construtores básicos da sua script.

i) Definindo variáveis:

Variáveis são, provavelmente, a coisa mais importante em qualquer linguagem de programação, principalmente porque elas nos permitem escrever menos!

Digamos que você precise escrever "Gu4rana e bri9adeiro são grandes amigos" várias vezes na sua Script.

Ao invés de repetir sempre essa frase enorme, podemos definí-la como uma variável:

local Frase = "Gu4rana e bri9adeiro são grandes amigos"

ii) Usando variáveis:

Muito bem, agora que nós sabemos usar print() e definir uma variável , vamos dar um passo adiante!

Outra forma de usar print() é colocando uma variável entre os parêntesis:

-- Primeiro, definimos a variável Frase:
local Frase = "Gu4rana e bri9adeiro são grandes amigos"
print(Frase)
>>> OUTPUT: "Gu4rana e bri9adeiro são grandes amigos"

Lembre-se: variáveis são apenas uma forma de fazer referência a algo mencionado anteriormente!

Assim, se o valor dado à variável for um número, também podemos realizar operações aritméticas com a variável.

Exercício 1

Entendeu? Então vamos fazer um exercício!

Defina a variável chamada Data, de modo que ela tenha o valor de 21/05/2020 - 20:55. Faça com que isso apareça no Output!

Resposta:

local Data = "21/05/2020 - 20:55"
print(Data)

Conseguiu?

Se você não conseguiu, releia mais uma vez e tente de novo! Tenho certeza que vai conseguir desta vez.

b) Manipulando objetos

No Roblox Studio, muitas vezes, nós iremos precisar manipular objetos e mudar suas propriedades. Vamos dar uma olhada?

i) Aba de propriedades

Não são apenas frases que podemos definir como variáveis! Também podemos definir funções, objetos, números inteiros e muito mais!

Um tipo básico de objeto que é importante saber manipular é uma “Part”. Vamos inserir uma em nosso ambiente de trabalho.

Agora, vamos examinar as propriedades desse objeto. Para isso, vamos abrir uma outra aba que se chama “Properties”:

Cada objeto possui propriedades diferentes que o definem. Além disso, podemos selecionar os objetos clicando neles ou os selecionando através da aba “Explorer”.

Por exemplo: vamos mudar o nome dessa Part para “Bloco”. Basta selecionar o objeto, ir na aba de propriedades e mudar seu nome para Bloco!

ii) Manipulação através de uma Script!

Mudar as propriedades de um objeto é legal, mas nós também podemos fazer isso através de uma script!

Para acessar objetos, sempre devemos ter o modelo a seguir em mente

Vamos visualizar isso com uma Representação resumida que nos mostre a relação de grau parental entre esses objetos:

v Workspace (Objeto Pai)
- Camera (Filho de workspace)
- Terrain (Filho de workspace)
- Baseplate (Filho de workspace)
- Bloco (Filho de workspace)

Nesse modelo, o objeto “Bloco” é Child/Filho do objeto “Workspace”, que é o Parent/Pai. Vale apontar que, na verdade, o que acontece é isso:

v game (Objeto pai de Workspace)
v Workspace (Objeto pai de Bloco e Filho de Workspace)
- Bloco (Filho de Workspace e Descendente de game)

Game é o objeto pai de Workspace, mas ele sempre fica oculto para nós, meros mortais.

Além disso, o objeto game já é uma variável embutida! Isso significa que nós não precisamos defini-la como uma variável.

Se você entendeu tudo, então vamos tentar mudar o nome do Bloco para Bloco_2. Primeiro, devemos definir os objetos no Explorer como variáveis:

local workspace = game.Workspace
-- Espere! Não precisamos fazer isso!
-- Além de game, outra variável já embutida é "workspace".
-- Assim, não precisamos definir workspace outra vez.

Agora sim, vamos lá! Lembre-se, nosso objetivo é fazer com que Bloco se torne Bloco_2

-- Primeiro, vamos definir o objeto "Bloco" com a variável "Tijolo":

local Tijolo = workspace.Bloco
Tijolo.Name = "Bloco_2" -- Aqui, mudamos o valor da propriedade Name

Podemos acessar todas as propriedades de um objeto assim!

Para testar nosso código, vamos clicar de novo em “Run”.

Mas atenção: essa mudança só ocorrerá enquanto você estiver no modo Play ou Run. Assim que você clicar em Stop, tudo voltará ao normal.

Exercício 2
Tudo certo? Vamos para mais um exercício!

Mude a transparência (Transparency) do objeto Bloco, filho de Workspace, para 0.5
Dessa vez, o nome da variável é por sua conta! Seja criativo

Resposta:

local parteLegal = workspace["Bloco"]
parteLegal.Transparency = 0.5 -- Como mencionado antes, números não precisam estar entre aspas

E aí, como foi? Acertou tudo?

Atenção:
Para definir a variável parteLegal, eu usei o código:

local parteLegal = workspace["Bloco"]

Mas, você também poderia ter usado workspace.Bloco. A sintaxe ["String"] é útil quando queremos selecionar uma Childque tem o mesmo nome de uma propriedade do objeto pai

Suponha que há uma parte dentro de Workspace que se chama “Name”.

local Part = workspace.Name 
print(Part)
>>> Output: "Workspace" -> Não queremos isso!

Para solucionar o problema, podemos usar a sintaxe de string:

local Part = workspace["Name"]
print(Part.Name)
>>> Output: "Name" -> Resultado desejado!

Atenção: Vamos fazer uma pausa?

Parece algo chato ou desnecessário, mas é importante descansar a mente depois de aprender tantas coisas novas!

Faça algo diferente por 5–10 minutos; Revise o que vimos até agora; Levante-se da sua cadeira, estique suas pernas; Já tomou água hoje? Hidratar-se faz bem!

Já fez tudo isso? Então vamos lá!

c) Condições

Outra parte importante de qualquer linguagem de programação são “condições”. Elas agem como portas, que permitem a passagem ou não de pessoas, baseado em uma condição.

Condição de existência verdadeira (if then else)

Nós podemos estabelecer condições com o método if x then y end. O código y apenas funcionará se x não for falso ou nulo!

if <[Pudim é bom] == true> then print("Fly gosta de pudim") end

Esse é um pseudocódigo! Ele não funciona de verdade, pois deve servir apenas como exemplo! Vamos analisá-lo:

  • A parte entre as chaves (< >) é o argumento da condição.
    Se a igualdade Pudim é bom e true for verdadeira, prosseguimos para a próxima parte: a execução do código. No nosso exemplo, é a função print()

Note que em condições if, para verificar igualdade entre dois termos, devemos usar o operador lógico para comparações (==).

Já, quando estamos declarando variáveis, usamos apenas um operador binário de atribuição (=), lembrou?

Exemplo:

local x = 10 -- Usamos = para atribuir o valor 10 à variável 'x'
local y = 10 -- Atribuimos o mesmo valor a 'y'
-- Com o sinal == podemos verificar se aquilo
-- que está à direita do sinal é igual ao que está à esquerda
if x == y then -- Se x é igual a y, então...
print("Isso também é verdade!")
end

Portanto, atenção:
Não podemos usar o operador = para comparação, apenas para atribuição de valor à uma variável! Da mesma forma, não é possível usar o operador == para definir uma variável.

Veja:

Como esperado, ao tentar verificar igualdade com apenas um sinal de igual (=), o Output nos mostrou um erro!

Ao trocá-lo por dois sinais (==), a script foi executada! Mas, como a condição 5 == 3 não é verdadeira, o Output não mostrou nenhum resultado!

Vale apontar que também é possível omitir a comparação de igualdade verdadeira (if x == true).

local verdade = true
if verdade then
print("é verdade isso")
end

E também podemos declarar omitir uma condição de igualdade falsa (if x == false)

local verdade = false
if not verdade then
print("Mentira!")
end

Como já foi mencionado, podemos fazer comparações entre dois objetos para ver se eles são iguais! Então, agora vamos tentar verificar se o objeto Pai de Bloco é o workspace.

local Bloco = workspace.Blocoif Bloco.Parent == workspace then -- Workspace é pai de Bloco?
-- Se sim, então execute:
print(Bloco.Parent.Name)
end
>>> OUTPUT: Workspace

Perceba que, se Bloco não for filho de workspace, nada acontecerá! Para mudar isso, podemos adicionar as condições elseif ou else.

  • elseif - Funciona como um if, mas seu código só passará por aqui se a primeira condição não for verdadeira!
  • else - Caso nenhuma das condições anteriores sejam verdadeiras, seu código irá executar o que você definir depois de else

Exemplo: Vamos verificar se o nome do Bloco é “Gato” ou “Cão”, e se não for um desses, iremos printar “Não sou gato nem cão, sou um bloco!”

local Bloco = workspace.Blocoif Bloco.Name == "Gato"  then -- O nome do bloco é Gato?
print("Miau")
elseif Bloco.Name == "Cão" then -- Se não for gato, então é Cão?
print("Au au, sou um cão!")
else
print("Não sou gato nem cão, sou um bloco!")
end
>>> OUTPUT: Não sou gato nem cão, sou um bloco!

Operadores de inequação

Além disso, podemos usar os operadores > (maior que), < (menor que), <= (maior ou igual a), >= (menor ou igual a) para avaliar expressões númericas.

Para nosso exemplo, vamos tornar o Bloco totalmente transparente se ele tiver transparência menor que 1:

local Bloco = workspace.Bloco
if Bloco.Transparency < 1 then
Bloco.Transparency = 1
end

Operador de negação

Também é possível formular uma condição negativa, que so executará o código se seu resultado não for true (verdadeira).

Vamos tentar mudar a Transparency do bloco para 0.5, caso ele não seja transparente!

local Bloco = workspace.Bloco
if Bloco.Transparency ~= 1 then -- O operador ~= representa desigualdade
Bloco.Transparency = 1
end

d) Loops

Bem, o que vimos foi bem legal…
Mas, e se nós pudessemos fazer o Bloco lentamente desaparecer?

Isso é beeeeem mais legal que simplesmente fazê-lo desaparecer do nada! Para isso, nós podemos usar o seguinte código:

local Bloco = workspace.Bloco -- Definimos a variável como sempreBloco.Transparency = 0.1
wait(0.1) -- Espere 0.1 segundos antes de continuar!
Bloco.Transparency = 0.3
wait(0.1)
Bloco.Transparency = 0.6
wait(0.1)
Bloco.Transparency = 0.9
wait(0.1)
Bloco.Transparency = 1

Mas isso não parece muito prático não é? Afinal, escrever a mesma coisa várias vezes é chato! Para resolver isso, vamos usar um loop.

i) While loop

Um loop do tipo while x do y end é um loop que ocorrerá para sempre, desde que a condição x não seja nula/nil ou falsa/false

local Bloco = workspace.Bloco-- Visto que true nunca será falso, o loop irá acontecer para sempre:
while true do
Bloco.Transparency = Bloco.Transparency + 0.1
wait(0.1)
end

Porém, temos um problema com esse código! Como dito, esse loop rodará para sempre, o que é desnecessário e ineficiente!

ii) For Loop
Há outra forma de fazer com que o loop apenas funcione até que ele atinja um objetivo. Um for loop tem a forma de: for <i> = <início, fim, taxa> do <x> end

São muitas variáveis novas! Para explicar melhor, um exemplo: vamos fazer nosso código contar de 1 até 5.

for i = 1, 5, 1 do
print(i)
wait(0.1)
end
  • i é uma variável que varia de acordo com o indíce atual no número de repetições
  • 1 é o número de onde partimos
  • 5 é o número máximo
  • 1 é a taxa a qual iremos somar ao i a cada repetição

Resultado:

Vamos ver o que acontece a cada loop:

-- Nosso loop é definido por i + 1
-- Dessa forma, a cada iteração (ciclo) no loop,
-- adicionamos 1 ao valor de i

i = 0 + 1 --> i = 1
i = 1 + 1 --> i = 2
i = 2 + 1 --> i = 3
i = 3 + 1 --> i = 4
i = 4 + 1 --> i = 5

Agora, podemos voltar ao nosso problema original: como fazer o nosso Bloco lentamente se tornar transparente?

  • Sabemos que uma [ Part ] é transparente se sua propriedade Transparency for igual a 1, e que ela é opaca se for 0.
  • Portanto, nosso início deve ser 0 e o final 1.
  • Vamos colocar uma taxa de acréscimo arbitrária de 0.1
  • Também vamos esperar 0.1 segundos entre cada iteração.
local Bloco = workspace.Bloco
for i = 0, 1, 0.1 do -- A cada iteração, adicionar + 0.1 ao valor de i
Bloco.Transparency = i
print(i)
wait(0.1)
end

Exercício 3
Mais um exercício para vocês!

Faça com que o Bloco gradualmente fique transparente, e então mude seu Material para Neon e volte a ser Opaco lentamente!

Resposta:

local Bloco = workspace.Bloco

for i = 0, 1, 0.1 do
Bloco.Transparency = i
wait(0.1)
end

Bloco.Material = "Neon"

for i = 1, 0, -0.1 do
Bloco.Transparency = i
wait(0.1)
end

c) Tables

Introdução às Tables

Tables são outra parte importante do seu aprendizado de Lua. Tables são objetos que podem ser utilizados para guardar informações. É comum referir-se a elas como “dictionaries” ou “arrays”, em outras linguagens.

Definindo uma table

Uma table tem o seguinte formato:

local  Leaders = {"fptbb", "Streeteenk", "davness"}

Acessando uma table

Podemos acessar “keys” ou “values” através do seguinte método: Table[índice], sendo índice a posição do termo que você deseja selecionar na tabela.

local Leaders = {"fptbb", "Streeteenk", "davness"} 
print(Leaders[1])
print(Leaders[#Leaders])
-- #Table, te dará a quantidade de itens dentro de Table

Resultado:

>>> OUTPUT: fptbb
>>> OUTPUT: davness

Mas, e se eu quisesse colocar um Table dentro de uma Table? Também é possível! Chamamos isso, em geral, de “dicionário”.

local Staff = {
DET = {"Gu4rana", "bri9adeiro"},
LCL = {"davness", "fptbb", "Streeteenk"}
}

No exemplo acima, Staff é a table principal, na qual estão inseridas as tables DET e LCL.

Abaixo, temos uma Table chamada de Dados_Espionagem. Dentro dela, temos outras três tables: fptbb, fly_san e ["Gu4rana"].

local Dados_Espionagem = {
fptbb = {
["Bebida preferida"] = "Suco de laranja uwu";
["Nome completo"] = 'Fp "Raposo" Tbb';
["Profissão"] = {
Cozinha = "Assistente de Ajudante de Auxiliar de Cozinha"
}
};
fly_san = {
["Bebida preferida"] = {"Chá", "Café"};
["Nome completo"] = 'Senhor fly';
["Profissão"] = {
Cozinha = "Sub-Auxiliar de Chefe dos Assistentes"
}
};
["Gu4rana"] = {
["Bebida preferida"] = "????????";
["Nome completo"] = 'Gu1234rana';
["Profissão"] = {
["Roblox DET"] = "Portuguese and Brazilian Team",
Cozinha = "Gerente Superintendente Geral de Chefe de Cozinha"
}
}
}

Porém, perceba que para acessar fly_san ou fptbb, usamos Table.Key:

local fptbb = Dados_Espionagem.fptbb -- fptbb não é string
local fly_san = Dados_Espionagem.fly_san -- fly_san não é string

Mas, para acessar ["Gu4rana"] usamos Table["KeyName"]

local Gu4rana = Dados_Espionagem["Gu4rana"] -- "Gu4rana" é string

Dessa forma, podemos descobrir qual a bebida preferida do @fptbb com o código:

local bebidaPreferida = Dados_Espionagem.fptbb["Bebida preferida"]
print(bebidaPreferida)

Lendo Tables

Voltando à table “Dados_Espionagem”, percebemos que não é possível descobrir a minha bebida preferida usando o mesmo método que para o fptbb. Isso acontece pois eu gosto tanto de café quanto de chá, então eu tenho duas bebidas preferidas!

local bebidaPreferida = Dados_Espionagem.fly_san["Bebida preferida"]
print(bebidaPreferida)

Para descobrir as minhas bebidas favoritas, temos três opções:

i) Table[i]
Podemos usar o primeiro método que aprendemos para acessar valores:

local BebidaPreferida = Dados_Espionagem.fly_san["Bebida preferida"]
print(BebidaPreferida[1])
print(BebidaPreferida[2])
>>> OUTPUT: Chá
>>> OUTPUT: Café

ii) for i,v in loop
Há outras formas de usar o for loop, que nos permitem ler tables.

for i,v in ipairs(Table) do
print(v)
end
>>> OUTPUT: Chá
>>> OUTPUT: Café

iii) table.unpack()
O último método usando table.unpack() é o mais prático e rápido se você apenas desejar ver os resultados no Output

Manipulando keys e valores

Você também pode inserir ou editar informações em uma table!

Editando um valor

local Table = {"a"}
Table[1] = "A" -- Estamos mudando a key 1 de "a" para "A"
print(table.unpack(Table))>>> Output: A

Adicionando um valor

local Table = {"a", "b"}
Table[3] = "c" -- Estamos adicionando a key "c" na posição 3
print(table.unpack(Table))>>> Output: a b c

Também podemos adicionar um valor sempre ao final de uma table! Lembrando que o operador #pode ser usado para nos informar a quantidade de itens da table.

local Table = {"a", "b", "c", "d", "e", "f"}
Table[#Table] = "g" -- Estamos adicionando a key "g" na posição #Table
print(table.unpack(Table))>>> Output: a b c d e f g

4. Conclusão

Aprender uma nova linguagem não é fácil! Se você conseguiu chegar até aqui, parabéns. Com esse tutorial, você aprendeu várias coisas novas.

  • Como utilizar o Output e a função print()
  • Como declarar variáveis e usá-las dentro de uma função
  • Como manipular objetos e suas propriedades
  • Condições if
  • Loops while e for
  • Tables

Eu acredito que essas sejam as ferramentas básicas para a construção de ainda mais aprendizagens futuras. Com esses conhecimentos, agora você conseguirá navegar pelo wiki de desenvolvimento sem grandes dificuldades!

Muito obrigado por ler esse simples tutorial. Por favor, não hesite em me contatar ou deixar uma pergunta caso tenha alguma dúvida sobre o tutorial.

Você pode ler também a versão original desse tutorial no Fórum de Desenvolvedores.

Caso queira saber mais sobre o desenvolvedor, você pode segui-lo no Twitter: @ComradeFly. Também não esqueça de nos seguir! @robloxdevrelptb.

--

--

Roblox Developer Relations
Roblox Developer Português

Empowering Roblox developers and creators to bring their imagination to life.