Tutorial de Luau scripting no Roblox mostrando editor de código no Roblox Studio

Por Que Aprender Luau Scripting

Você já sabe como posicionar parts e construir coisas no Roblox Studio. Isso te dá um mundo estático – paredes, pisos, decorações. Mas no momento em que você quer uma porta que abre, um leaderboard que rastreia pontos, ou inimigos que perseguem jogadores, você precisa de scripts. E scripts no Roblox são escritos em Luau.

Luau é a linguagem de programação do Roblox. É baseada em Lua 5.1, mas o Roblox adicionou verificação de tipos, otimizações de performance e uma tonelada de APIs integradas que se comunicam diretamente com o game engine. Se você já passou pelo nosso tutorial de Roblox Studio para iniciantes, este é o seu próximo passo. Vamos sair da construção para a programação.

A melhor parte? Luau foi literalmente projetado para pessoas que nunca programaram antes. A sintaxe é limpa, as mensagens de erro são legíveis, e você pode ver os resultados do seu código em tempo real pressionando F5. Sem compilação, sem terminal, sem configuração complicada. Apenas escreva código e veja seu jogo reagir.

Vamos começar.

Configurando Seu Primeiro Script no Roblox Studio

Antes de escrever qualquer código, você precisa entender onde os scripts ficam no Roblox Studio. Isso importa mais do que você imagina – colocar um script no lugar errado é a razão número um pela qual iniciantes ficam confusos quando seu código não faz nada.

Tipos de Script e Onde Eles Ficam

Tipo de ScriptLocalizaçãoPropósito
ScriptServerScriptServiceLógica de jogo que roda no servidor (dano, pontuação, salvar dados)
LocalScriptStarterPlayerScripts ou StarterGuiCódigo do lado do jogador (câmera, UI, input)
ModuleScriptReplicatedStorage ou ServerStorageCódigo reutilizável que outros scripts podem usar com require

Para este tutorial, vamos começar com Scripts regulares no ServerScriptService. Eles rodam no servidor e afetam todos os jogadores igualmente.

Criando Seu Primeiro Script

  1. Abra o Roblox Studio e carregue qualquer projeto (um Baseplate funciona)
  2. No painel Explorer, encontre o ServerScriptService
  3. Clique com o botão direito e selecione Insert Object > Script
  4. O editor de script abre com uma única linha: print("Hello world!")
  5. Pressione F5 para testar
  6. Verifique a janela Output (View > Output se você não a vê)

Você deve ver “Hello world!” impresso no Output. Essa única linha rodou no servidor do Roblox. Tudo a partir daqui é construído sobre esse mesmo fluxo de trabalho: escreva código, pressione F5, verifique o Output.

Se você não vê a janela Output, vá em View no menu superior e clique em Output. Você vai usar essa janela constantemente, então mantenha-a aberta.

Variáveis e Tipos de Dados em Luau

Variáveis armazenam informações que seus scripts usam. Pense nelas como caixas rotuladas – você coloca um valor dentro e referencia o rótulo sempre que precisa daquele valor.

Declarando Variáveis

Em Luau, você cria variáveis com a palavra-chave local:

local playerName = "RobloxDrop"
local maxHealth = 100
local isGameOver = false
local speedMultiplier = 1.5

Sempre use local. Tecnicamente Luau permite que você pule isso, mas isso cria variáveis globais que causam bugs em projetos maiores e rodam mais lento. Faça do local um hábito desde o primeiro dia.

Tipos de Dados Que Você Vai Usar

TipoExemploCaso de Uso
string"Hello"Nomes de jogadores, mensagens, texto de UI
number42, 3.14Vida, velocidade, pontuações, posições
booleantrue, falseToggles, condições, estado do jogo
nilnilNada, vazio, ainda não definido
table{1, 2, 3}Listas, inventários, dados de leaderboard

Operações com Strings

Strings são valores de texto e você vai usá-las em todo lugar:

local firstName = "Roblox"
local lastName = "Drop"

-- Concatenação (juntando strings)
local fullName = firstName.. lastName -- "RobloxDrop"
local spaced = firstName.. " ".. lastName -- "Roblox Drop"

-- Tamanho da string
local nameLength = #fullName -- 10

-- Funções úteis de string
local upper = string.upper(fullName) -- "ROBLOXDROP"
local lower = string.lower(fullName) -- "robloxdrop"
local sub = string.sub(fullName, 1, 6) -- "Roblox"

Tables (Arrays e Dicionários)

Tables são a estrutura de dados multiuso do Luau. Funcionam tanto como listas ordenadas quanto como pares chave-valor:

-- Array (lista ordenada)
local fruits = {"Apple", "Banana", "Cherry"}
print(fruits[1]) -- "Apple" (arrays em Luau começam no 1, não no 0)

-- Dicionário (pares chave-valor)
local playerStats = {
 health = 100,
 speed = 16,
 level = 1
}
print(playerStats.health) -- 100

-- Adicionando a uma table
table.insert(fruits, "Mango")
playerStats.coins = 50

Tables vão se tornar essenciais quando você construir inventários, salvar dados de jogadores ou armazenar configurações do jogo.

Funções: Blocos Reutilizáveis de Lógica

Funções permitem que você empacote código em blocos reutilizáveis. Em vez de escrever a mesma lógica repetidamente, você define uma vez e chama sempre que precisar.

Definindo e Chamando Funções

local function healPlayer(humanoid, amount)
 local newHealth = humanoid.Health + amount
 if newHealth > humanoid.MaxHealth then
 newHealth = humanoid.MaxHealth
 end
 humanoid.Health = newHealth
 print("Healed to ".. newHealth)
end

Essa função recebe um objeto Humanoid e uma quantidade de cura, limita a vida no máximo e aplica a cura. Você a chama assim:

-- Em outro lugar do seu código
healPlayer(someHumanoid, 25)

Funções Que Retornam Valores

Funções também podem calcular algo e enviar o resultado de volta:

local function calculateDamage(baseDamage, level)
 local multiplier = 1 + (level * 0.1)
 return baseDamage * multiplier
end

local damage = calculateDamage(50, 10)
print(damage) -- 100

Funções Anônimas

Você vai ver funções sem nome o tempo todo em Roblox scripting, especialmente com eventos:

part.Touched:Connect(function(hit)
 print(hit.Name.. " touched the part")
end)

Esse bloco function(hit) ... end é uma função anônima – não tem nome, apenas roda quando o evento dispara. Esse padrão está em todo lugar no Luau.

Eventos e Conexões: Fazendo as Coisas Acontecerem

Eventos são o coração de qualquer jogo no Roblox. Eles disparam quando algo acontece – um jogador toca uma part, um personagem spawna, um valor muda. Seus scripts escutam eventos e respondem a eles.

Como Eventos Funcionam

Todo objeto do Roblox tem eventos aos quais você pode se conectar. O padrão é sempre o mesmo:

object.EventName:Connect(function(parameters)
 -- Seu código roda aqui quando o evento dispara
end)

Eventos Comuns Que Você Vai Usar

EventoDispara QuandoEncontrado Em
TouchedAlgo toca fisicamente a partBasePart
TouchEndedAlgo para de tocar a partBasePart
PlayerAddedUm novo jogador entra no servidorPlayers service
PlayerRemovingUm jogador sai do servidorPlayers service
CharacterAddedO personagem de um jogador spawna ou respawnaPlayer object
ChangedO valor de uma propriedade mudaQualquer instance
ChildAddedUm novo child é adicionado a um objetoQualquer instance

Conectando ao PlayerAdded

Um dos eventos mais importantes. Ele dispara toda vez que um jogador entra no seu jogo:

local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(player)
 print(player.Name.. " joined the game!")
end)

A linha game:GetService("Players") é como você acessa os services do Roblox. Services são objetos de nível superior que gerenciam diferentes sistemas – Players lida com conexões de jogadores, Lighting lida com o ambiente, DataStoreService lida com salvamento de dados, e assim por diante.

Desconectando Eventos

Às vezes você precisa que um evento dispare apenas uma vez ou pare de escutar:

local connection

connection = part.Touched:Connect(function(hit)
 print("Touched once!")
 connection:Disconnect -- Para de escutar após o primeiro toque
end)

Isso é útil para gatilhos únicos como pegar um colecionável ou abrir um baú.

Fazendo um Script de Porta Funcional

Vamos construir algo prático. Uma porta que abre quando um jogador a toca e fecha depois de alguns segundos. Isso combina variáveis, funções, eventos e temporização – tudo o que cobrimos até agora.

Passo 1: Configure a Porta

  1. Crie uma Part no seu workspace
  2. Redimensione para parecer uma porta (tente Size 1, 7, 5)
  3. Pinte de marrom e defina Material como Wood
  4. Ancore-a (isso é crítico)
  5. Nomeie como “Door” no painel Properties

Passo 2: Escreva o Script

Clique com o botão direito na part Door no Explorer, insira um Script e substitua o código padrão:

local door = script.Parent
local debounce = false
local openTime = 3

local closedPosition = door.Position
local openOffset = Vector3.new(0, door.Size.Y, 0)

local function openDoor
 if debounce then return end
 debounce = true

 -- Move a porta para cima (abre)
 door.Position = closedPosition + openOffset
 door.Transparency = 0.5
 door.CanCollide = false

 print("Door opened")

 task.wait(openTime)

 -- Move a porta de volta para baixo (fecha)
 door.Position = closedPosition
 door.Transparency = 0
 door.CanCollide = true

 print("Door closed")

 debounce = false
end

door.Touched:Connect(function(hit)
 local humanoid = hit.Parent:FindFirstChild("Humanoid")
 if humanoid then
 openDoor
 end
end)

Como Funciona

  • debounce impede que a porta seja acionada repetidamente enquanto já está aberta. Esse é um padrão que você vai usar em quase todo script interativo.
  • task.wait(3) pausa o script por 3 segundos antes de fechar a porta. A biblioteca task é a forma moderna de lidar com temporização em Luau.
  • Verificamos se há um Humanoid no objeto que tocou para garantir que apenas jogadores (não parts aleatórias) acionem a porta.
  • A porta se move para cima pela sua própria altura, fica semi-transparente e desabilita colisão para que jogadores possam passar.

Pressione F5 e ande até a porta. Ela deve deslizar para cima, ficar aberta por 3 segundos e voltar para baixo. Se você está construindo estágios de obby, dungeons de RPG ou portões de tycoon, esse padrão de porta é sua base.

Construindo um Leaderboard de Pontos

Leaderboards permitem que jogadores vejam suas estatísticas no lado direito da tela. O Roblox tem um sistema de leaderboard integrado ligado a uma folder chamada “leaderstats.” Uma vez que você configura, o leaderboard aparece automaticamente – não precisa de scripting de UI.

O Script do Leaderboard

Crie um novo Script no ServerScriptService e adicione este código:

local Players = game:GetService("Players")

local function onPlayerAdded(player)
 -- Cria a folder leaderstats
 local leaderstats = Instance.new("Folder")
 leaderstats.Name = "leaderstats"
 leaderstats.Parent = player

 -- Cria um valor de Points
 local points = Instance.new("IntValue")
 points.Name = "Points"
 points.Value = 0
 points.Parent = leaderstats

 -- Cria um valor de Level
 local level = Instance.new("IntValue")
 level.Name = "Level"
 level.Value = 1
 level.Parent = leaderstats

 print(player.Name.. " leaderstats created")
end

Players.PlayerAdded:Connect(onPlayerAdded)

Pressione F5 e você verá um leaderboard aparecer no canto superior direito com seu nome de usuário, 0 Points e Level 1.

Adicionando um Pickup de Pontos

Agora vamos criar parts que dão pontos quando um jogador as toca. Adicione isso a um novo Script dentro do ServerScriptService:

local function setupCoin(coin)
 coin.Touched:Connect(function(hit)
 local humanoid = hit.Parent:FindFirstChild("Humanoid")
 if not humanoid then return end

 local player = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
 if not player then return end

 local points = player:FindFirstChild("leaderstats")
 and player.leaderstats:FindFirstChild("Points")
 if not points then return end

 points.Value = points.Value + 10
 coin:Destroy
 print(player.Name.. " collected a coin! Total: " .. points.Value)
 end)
end

-- Configura todas as parts em uma folder chamada "Coins"
local coinsFolder = workspace:FindFirstChild("Coins")
if coinsFolder then
 for _, coin in coinsFolder:GetChildren do
 setupCoin(coin)
 end
end

Para fazer isso funcionar, crie uma Folder no Workspace chamada “Coins” e adicione algumas Parts pequenas e amarelas dentro dela. Cada uma se torna um colecionável que adiciona 10 pontos ao leaderboard. Esse é o mesmo conceito por trás da coleta de moedas em tycoons, obbies e jogos de aventura.

Se você quer aprender como transformar mecânicas simples de jogo como essa em uma experiência publicada completa, nosso guia sobre como fazer um jogo popular no Roblox cobre o processo de design e lançamento.

Dicas de Debugging Que Vão Economizar Horas

Todo programador gasta tempo com debugging. A diferença entre um iniciante frustrado e um scripter produtivo é saber como encontrar e corrigir erros rapidamente.

Lendo Mensagens de Erro

Quando um script quebra, o Roblox te diz exatamente o que deu errado na janela Output. Um erro típico se parece com isso:

ServerScriptService.Script:15: attempt to index nil with 'Health'

Isso te diz:

  • ServerScriptService.Script – Qual script tem o erro
  • :15 – O número da linha (linha 15)
  • attempt to index nil with ‘Health’ – Você tentou acessar .Health em algo que não existe (nil)

Usando Print para Debugging

Quando você não tem certeza do que seu código está fazendo, adicione comandos print para rastrear o fluxo:

local function onTouched(hit)
 print("1. Something touched the part:", hit.Name)

 local humanoid = hit.Parent:FindFirstChild("Humanoid")
 print("2. Found humanoid:", humanoid)

 if humanoid then
 print("3. Player health:", humanoid.Health)
 humanoid.Health = humanoid.Health - 25
 print("4. New health:", humanoid.Health)
 end
end

Rode o jogo e verifique o Output. Se você vê o passo 1 imprimir mas não o passo 2, você sabe que o problema está entre essas linhas. Essa técnica de “print debugging” funciona em todo nível de habilidade.

Tipos Comuns de Erro

ErroO Que SignificaCorreção
attempt to index nilVocê está acessando uma propriedade em algo que não existeVerifique se o objeto existe antes de usá-lo com FindFirstChild
Expected 'end'Você esqueceu de fechar uma function, bloco if ou loopConte suas aberturas de function/if/for e certifique-se de que cada uma tem um end
Expected identifierErro de digitação em uma keyword ou nome de variávelVerifique a ortografia cuidadosamente, Luau diferencia maiúsculas de minúsculas
Infinite yield possibleWaitForChild está esperando por algo que pode nunca aparecerCertifique-se de que o objeto que você está esperando realmente existe ou é criado

A Janela Output É Sua Melhor Amiga

Mantenha a janela Output aberta o tempo todo. Vá em View > Output se ela não estiver visível. Todo erro, todo print, todo aviso aparece aqui. Ignorá-la é como dirigir de olhos fechados.

Você também pode filtrar mensagens – clique com o botão direito na janela Output para mostrar apenas erros, avisos ou mensagens. Quando seu jogo fica complexo e o Output está barulhento, filtrar ajuda você a manter o foco.

Erros Comuns de Iniciantes em Luau

Depois de ajudar centenas de novos scripters, esses são os erros que aparecem repetidamente. Conhecê-los antecipadamente vai te poupar frustração real.

1. Esquecer a Palavra-chave local

-- Errado: cria uma variável global
playerScore = 100

-- Correto: cria uma variável local
local playerScore = 100

Variáveis globais vazam entre scripts e causam bugs imprevisíveis. Sempre use local.

2. Colocar Scripts no Service Errado

Um Script em StarterPlayerScripts não vai funcionar. Um LocalScript em ServerScriptService não vai funcionar. Combine o tipo de script com a localização correta toda vez.

3. Não Verificar Nil

-- Isso crasha se não houver Humanoid
hit.Parent.Humanoid.Health = 0

-- Isso é seguro
local humanoid = hit.Parent:FindFirstChild("Humanoid")
if humanoid then
 humanoid.Health = 0
end

Sempre use FindFirstChild antes de acessar objetos filhos. Nem tudo que toca uma part é um personagem de jogador.

4. Esquecer Que Touched Dispara Para Cada Parte do Corpo

Quando um jogador entra em uma part, o evento Touched dispara para a cabeça, torso e cada membro. Sem debounce, seu código roda 5+ vezes:

local debounce = false

part.Touched:Connect(function(hit)
 if debounce then return end
 debounce = true

 -- Seu código aqui (roda uma vez)

 task.wait(1)
 debounce = false
end)

5. Usar wait em Vez de task.wait

A antiga função wait está depreciada. Sempre use task.wait no lugar:

-- Antigo (depreciado, menos preciso)
wait(2)

-- Novo (recomendado, mais confiável)
task.wait(2)

A biblioteca task também te dá task.spawn, task.delay e task.defer para mais controle sobre temporização.

6. Loops Infinitos Sem Yields

Se você escrever um while loop que nunca pausa, ele congela o jogo inteiro:

-- Isso congela o jogo
while true do
 -- fazendo coisas para sempre sem pausa
end

-- Isso funciona bem
while true do
 -- fazendo coisas
 task.wait(1) -- Pausa 1 segundo a cada loop
end

Todo loop precisa de um task.wait ou algum outro ponto de yield. Sem exceções.

Se você encontrar problemas de performance ao testar seus scripts, confira nosso guia de correção de lag e performance no Roblox para técnicas de otimização.

Verificação de Tipos em Luau (Recurso)

Uma das maiores vantagens do Luau sobre o Lua padrão é seu sistema de tipos. Type annotations ajudam a detectar bugs antes mesmo de você rodar seu jogo.

Type Annotations Básicas

local playerName: string = "RobloxDrop"
local health: number = 100
local isAlive: boolean = true

local function calculateDamage(base: number, multiplier: number): number
 return base * multiplier
end

Você não precisa usar tipos – eles são opcionais. Mas adicioná-los aos parâmetros de funções e valores de retorno ajuda o Studio a detectar erros no editor antes de você pressionar F5. Conforme seus scripts ficam mais longos, a verificação de tipos se torna incrivelmente valiosa.

Habilitando o Modo Strict

Adicione este comentário no topo do seu script para habilitar a verificação de tipos estrita:

--!strict

local function greet(name: string): string
 return "Hello, " .. name
end

greet(42) -- Studio te avisa: number não é string

O modo strict detecta incompatibilidades de tipo, valores de retorno faltantes e outros problemas que caso contrário só apareceriam em runtime. Não é obrigatório para iniciantes, mas vale a pena aprender cedo.

Próximos Passos Após Este Tutorial

Você agora tem os fundamentos de Luau scripting – variáveis, funções, eventos, exemplos práticos e habilidades de debugging. Veja para onde ir a seguir para continuar evoluindo seu desenvolvimento de jogos:

Tópicos Intermediários:

  • RemoteEvents e RemoteFunctions – Comunicação entre scripts de servidor e cliente. Necessário para qualquer recurso multiplayer como trading, sistemas de chat ou mecânicas de equipe.
  • DataStoreService – Salvar dados de jogadores (moedas, níveis, inventário) para que persistam entre sessões. Sem isso, jogadores perdem tudo quando saem.
  • ModuleScripts – Organize seu código em módulos reutilizáveis em vez de jogar tudo em um script enorme.
  • TweenService – Animações suaves para mover parts, fazer fade em UI e criar efeitos visuais polidos sem scripting frame-by-frame.

Tópicos Avançados:

  • Metatables e OOP – Padrões orientados a objetos em Luau para construir sistemas complexos como classes de armas ou IA de inimigos.
  • Raycasting – Detectar para onde um jogador está olhando ou atirando. Essencial para jogos FPS e sistemas de interação.
  • CollectionService – Marcar objetos com tags e gerenciar grupos de itens similares de forma eficiente.

A documentação oficial Roblox Creator Documentation cobre cada API em detalhes e inclui exemplos interativos. O DevForum em devforum.roblox.com é onde desenvolvedores experientes compartilham tutoriais e respondem perguntas.

Para inspiração sobre o que você pode construir, navegue pelo nosso compilado dos melhores jogos do Roblox e faça engenharia reversa do que torna jogos populares funcionarem. Confira as experiências 4D generation do Roblox para ver para onde a plataforma está indo e que tipos de jogos estão recebendo atenção do próprio Roblox.

Explore todo o nosso conteúdo de desenvolvimento e estratégia no nosso hub de guias – de monetização a criação de UGC, tem um guia para cada etapa da sua jornada como criador no Roblox.

Você tem as ferramentas. Você tem o conhecimento. Agora vá construir algo e faça ser seu.

FAQ

Luau é a mesma coisa que Lua?

Luau é baseado em Lua 5.1, mas inclui adições específicas do Roblox como tipagem estrita, type annotations e melhorias de performance. A maioria do código Lua padrão funciona em Luau, mas Luau tem recursos extras que o Lua padrão não tem.

Preciso de experiência com programação antes de aprender Luau?

Não. Luau foi projetado para ser amigável para iniciantes e funciona como uma primeira linguagem de programação. Se você consegue seguir instruções passo a passo e está disposto a experimentar, você consegue aprender Luau.

Onde eu coloco meus scripts no Roblox Studio?

Scripts de servidor vão no ServerScriptService. LocalScripts vão em StarterPlayerScripts ou StarterGui. ModuleScripts vão no ReplicatedStorage ou ServerStorage dependendo de quem precisa acessá-los.

Qual é a diferença entre Script e LocalScript?

Um Script roda no servidor e controla a lógica compartilhada do jogo. Um LocalScript roda no dispositivo de um único jogador e lida com coisas como movimento de câmera, UI e detecção de input.

Como faço debug de scripts Luau?

Abra a janela Output pelo menu View. Ela mostra comandos print e mensagens de erro com números de linha. Adicione chamadas print ao longo do seu código para rastrear o fluxo de execução e identificar onde as coisas quebram.

Posso construir um jogo multiplayer completo com Luau?

Sim. Jogos do Roblox são multiplayer por padrão. Scripts no servidor gerenciam o estado compartilhado enquanto LocalScripts lidam com a experiência de cada jogador. RemoteEvents conectam servidor e cliente.

Quanto tempo leva para ficar bom em Luau?

Scripts básicos como portas e kill bricks levam um dia para aprender. Eventos e game loops levam cerca de uma semana. Salvar dados, remote events e sistemas de jogo polidos levam de 2 a 4 semanas de prática consistente.

Quais são os erros mais comuns de iniciantes?

Esquecer a palavra-chave local, colocar scripts no service errado, não verificar nil antes de acessar propriedades e pular a janela Output quando erros acontecem.

Luau é rápido o suficiente para jogos complexos?

Sim. Luau foi especificamente otimizado pelo Roblox para performance em jogos. Ele lida com física, IA, grandes quantidades de jogadores e sistemas complexos sem problemas quando você segue boas práticas de programação.

Que recursos devo usar para continuar aprendendo?

Comece com a documentação oficial Roblox Creator Docs em create.roblox.com/docs. Entre no DevForum para ajuda da comunidade. Siga criadores do YouTube que se especializam em tutoriais de desenvolvimento para Roblox.