Scripting Lua

Dá para aprender scripting inteiro em um ano? A resposta honesta

Você assiste tutorial há meses, abre o Studio em branco e não sabe digitar a primeira linha sozinho. O conserto é trocar a playlist infinita por um mapa de 12 semanas com entregável em cada bloco.

por Gustavo Cantino12 min de leituraIniciante

Rascunho assistido por IA, revisado, testado e editado por um humano antes de publicar. Ver Política Editorial. · Revisado por Gustavo Cantino, 07/09/2026 Política Editorial

Placa tipográfica com a categoria Scripting Lua em destaque, o nível iniciante abaixo, e um campo de barras verticais verde-limão sobre fundo escuro.

Dá para aprender scripting "completo" em alguns meses ou em um ano? Não — e o problema está na palavra "completo", não no prazo. Ninguém termina scripting: quem programa há dez anos ainda abre a documentação da Roblox para conferir a ordem dos argumentos de TweenInfo.new. A pergunta útil, a que provavelmente te trouxe aqui, é outra: em quanto tempo eu paro de copiar código de tutorial e consigo fazer o meu jogo funcionar sozinho? Essa tem resposta com número: com 1 hora por dia, 5 dias por semana, você fica autônomo em 3 a 6 meses e fica bom em 12.

O buraco real: oito meses de vídeo e nenhum jogo publicado

O cenário que se repete é este. Você assistiu uns 60 vídeos, sabe o que é uma variável, entende o que o cara está fazendo enquanto ele digita — e quando abre o Roblox Studio com um lugar vazio, a tela em branco vence. Faça a conta do prejuízo: 1 hora por dia, 5 dias por semana, 8 meses dá cerca de 170 horas. Se 80% disso foi vídeo assistido sem você digitar nada, são 136 horas que não viraram habilidade nenhuma. É meio ano de trabalho jogado fora, e o pior é que a sensação de "eu entendi" é real — entender e conseguir escrever são coisas diferentes.

Antes de seguir, o vocabulário mínimo dos painéis, porque o resto do texto usa esses nomes. O Explorer é o painel da direita que lista todos os objetos do seu jogo em forma de árvore; se ele não estiver aberto, você liga em View > Explorer, na barra de cima. O Properties fica logo abaixo do Explorer e mostra as propriedades do objeto que você clicou (cor, tamanho, se está travado no lugar). O Output é o painel de baixo onde aparecem os erros em vermelho e o que os seus print escrevem — abre em View > Output, e você vai passar mais tempo olhando pra ele do que pro jogo. E o ServerScriptService é uma pasta que já existe dentro do Explorer: é lá que mora o código que roda no servidor, ou seja, o código que vale pra todo mundo na partida.

O segundo motivo do buraco é que "scripting" não é uma coisa só. São seis blocos empilhados, e cada um tem um custo de horas mais ou menos previsível: sintaxe do Luau (10 a 15 horas), a API da Roblox — Instâncias, propriedades, serviços (20 a 30 horas), eventos (10 horas), loops e tabelas (15 horas), cliente e servidor com RemoteEvent (20 horas) e salvar dados com DataStore (15 horas). Some: em torno de 100 horas para atravessar os seis. Uma hora por dia em 5 dias por semana são 20 horas por mês. Cinco meses, se você digitar. Vinte anos, se você só assistir.

12 semanas, 1 hora por dia: o mapa que substitui a playlist

O plano abaixo tem uma regra que não se quebra: cada bloco de duas semanas termina com uma coisa que roda e que você consegue mostrar pra alguém. Sem entregável, o bloco não acabou.

Semanas 1 e 2 — sintaxe. Variáveis, if, for, funções e print. Crie um Script clicando com o botão direito em ServerScriptService, escolhendo Insert Object > Script. Escreva coisas bobas e olhe o resultado no Output: somar dois números, decidir se um valor é maior que outro. Entregável: um script que imprime a tabuada do 7 no Output.

Semanas 3 e 4 — Instâncias. Aqui você descobre que tudo no Roblox é um objeto com propriedades: uma Part tem Size, Color, Anchored. Clique numa peça no Explorer, olhe o Properties, e depois faça a mesma mudança por código. Aprenda Instance.new, :FindFirstChild e :WaitForChild. Entregável: um script que cria 10 peças coloridas em posições diferentes quando o jogo começa.

Semanas 5 e 6 — eventos. Evento é "quando isso acontecer, faça aquilo": Touched quando alguém encosta numa peça, PlayerAdded quando alguém entra no jogo. Aqui entra o conceito de debounce, que é impedir que o evento dispare 40 vezes no mesmo segundo enquanto o pé do personagem raspa na peça. Entregável: uma moeda que dá pontos e volta depois de alguns segundos — é exatamente o artefato deste post.

Semanas 7 e 8 — loops e tabelas. É onde a maioria trava e onde nasce o erro mais comum de iniciante. Isto aqui congela o servidor inteiro no segundo em que você aperta Play:

Script em ServerScriptService
while true do
	print("rodando")
end

Falta uma pausa. while true do roda milhões de vezes por segundo e não devolve o controle pro motor do jogo. A versão que funciona tem task.wait(1) antes do end. Entregável: um contador regressivo que aparece no Output e um sistema de rodadas de 60 segundos.

Semanas 9 e 10 — cliente e servidor. Esse é o divisor de águas. Script roda no servidor; LocalScript roda no computador do jogador e vai dentro de StarterPlayerScripts (dentro de StarterPlayer, no Explorer) ou dentro da interface em StarterGui. O que o LocalScript muda, só o dono da tela vê. Um RemoteEvent, criado dentro de ReplicatedStorage, é o telefone entre os dois lados. Entregável: um botão na tela que, ao ser clicado, faz o servidor teleportar o jogador.

Semanas 11 e 12 — dados e publicação. DataStoreService para salvar moedas entre sessões, sempre dentro de pcall — que é o jeito de dizer "tente isto; se der erro, não derrube o jogo". Entregável: um jogo publicado, mesmo feio, com moedas que continuam lá quando você sai e volta.

Dentro da hora diária, a divisão que funciona é 45 minutos digitando e 15 minutos lendo a documentação oficial (create.roblox.com/docs). Vídeo entra como consulta, não como aula: você assiste o trecho de 2 minutos que resolve o seu problema e volta pro Studio.

O script da semana 5 e o checklist em JSON

São dois artefatos. O primeiro é um Script completo que você coloca em ServerScriptService: ele cria cinco moedas no ar, monta o placar do canto superior direito da tela (o tal leaderstats) e dá 5 pontos por moeda encostada, com a moeda sumindo por 3 segundos antes de voltar. Ele roda como está — dá Play e as moedas aparecem, sem você precisar montar nada no Explorer.

O segredo do uso é este: não cole. Abra o script ao lado e digite linha por linha. Digitando, você erra, o Output reclama, e é nesse erro que a habilidade gruda. Depois de rodar, mexa nos números: mude PONTOS_POR_MOEDA para 25, TEMPO_DE_RESPAWN para 0.5, troque o for i = 1, 5 por 1, 30. Cada mudança que você entende é uma hora do plano que você adiantou.

O segundo artefato é o plano de 12 semanas em JSON, com o tema, o entregável e as horas de cada bloco. Salve como um arquivo no seu computador e marque "feito": true conforme fecha cada bloco. Serve como controle: sem isso, três meses passam e você não sabe dizer onde parou.

O erro mais caro: colecionar tutorial em vez de terminar jogo ruim

O erro que come meses não é técnico. É passar 40 horas assistindo e zero horas travado. Você se sente produtivo porque o vídeo é claro e o cara nunca erra — só que o trabalho real de programar é justamente o que o vídeo corta: ler o erro em vermelho no Output, não entender, tentar, tentar de novo. Quem pula essa parte não está aprendendo scripting, está assistindo alguém fazer scripting.

O primo desse erro é o Free Model. Você arrasta um sistema pronto da Toolbox, ele funciona, e você não faz ideia de qual das 300 linhas faz o quê. Quando quebrar — e vai quebrar, porque metade dos modelos gratuitos foi escrita em 2017 com API que hoje está descontinuada — você não tem por onde começar a consertar.

A saída tem três passos e cabe numa semana. Primeiro, a regra dos 20 minutos: quando um erro travar você, tenta sozinho por 20 minutos antes de procurar resposta, e leia a mensagem do Output inteira, incluindo o número da linha que ela cita. Segundo, o teste do comentário: pegue um script que você "entendeu" e escreva com suas palavras, em português, o que cada linha faz. Onde você não conseguir escrever, você não entendeu — volte ali. Terceiro, apague e reescreva de memória. Reescrever o script das moedas sem olhar, no terceiro dia, vale mais que cinco tutoriais novos.

E uma calibragem de expectativa: em 2021 o Corridor of Hell bateu 33.000 jogadores simultâneos. Jogo que segura número assim não nasce de um dev que sabe tudo de Luau; nasce de um sistema simples testado até não quebrar. Você não precisa de scripting "completo" para começar. Precisa de um loop que não trava.

O que medir nas próximas quatro semanas

Pare de medir horas de conteúdo e comece a medir três coisas, uma vez por semana, num bloco de notas.

Um: minutos com o teclado, não com o vídeo. Meta de 45 minutos por dia digitando código, mesmo que seja código errado. Se a semana fechou abaixo de 150 minutos, o plano de 12 semanas vira plano de 30 — o que ainda funciona, desde que você saiba disso.

Dois: erros resolvidos sem ajuda. Anote a mensagem do Output e se você saiu sozinho ou não. Na semana 1 a taxa vai ser 1 em 10; quando virar 6 em 10, você é autônomo, e normalmente isso acontece entre a semana 8 e a 14 — bem antes de você "saber tudo".

Três: jogos publicados. A meta é um a cada quatro semanas, feios e pequenos: um obby de 10 partes, um simulador de clicar num botão. Publicar ensina o que nenhum tutorial ensina — que o código que funciona no seu Studio pode quebrar quando entram cinco pessoas ao mesmo tempo.

Se no fim de quatro semanas os três números existirem no papel, você já está na frente da maioria de quem começou junto com você. Agora sim vale abrir o próximo bloco: cliente e servidor, que é onde o seu jogo deixa de ser um teste e vira algo que outras pessoas conseguem jogar.

Artefato pronto pra usar

Script em ServerScriptService
lua
--!strict
-- COMO USAR: no Explorer (painel da direita), clique com o botao direito em
-- ServerScriptService > Insert Object > Script. Apague o conteudo padrao e
-- DIGITE este codigo (nao cole). Aperte Play. Cinco moedas aparecem no ar.

local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")

-- Mexa nestes dois numeros depois que funcionar. E o exercicio.
local PONTOS_POR_MOEDA: number = 5
local TEMPO_DE_RESPAWN: number = 3

-- Cria o placar do canto superior direito da tela para cada jogador.
-- A pasta PRECISA se chamar "leaderstats", com esse nome exato.
local function criarLeaderstats(player: Player)
	local pasta = Instance.new("Folder")
	pasta.Name = "leaderstats"

	local moedas = Instance.new("IntValue")
	moedas.Name = "Moedas"
	moedas.Value = 0
	moedas.Parent = pasta

	pasta.Parent = player
end

-- PlayerAdded dispara toda vez que alguem entra no servidor.
Players.PlayerAdded:Connect(criarLeaderstats)

-- Monta uma moeda amarela e devolve ela para quem chamou a funcao.
local function criarMoeda(posicao: Vector3): Part
	local moeda = Instance.new("Part")
	moeda.Name = "Moeda"
	moeda.Shape = Enum.PartType.Cylinder
	moeda.Size = Vector3.new(0.4, 3, 3)
	moeda.Color = Color3.fromRGB(255, 200, 40)
	moeda.Material = Enum.Material.Neon
	moeda.Anchored = true -- sem isso ela cai no chao
	moeda.CanCollide = false -- o jogador atravessa em vez de bater
	-- CFrame.Angles gira o cilindro para ele ficar em pe, como uma moeda
	moeda.CFrame = CFrame.new(posicao) * CFrame.Angles(0, 0, math.rad(90))
	moeda.Parent = Workspace
	return moeda
end

-- Liga o evento Touched: "quando alguem encostar, faca isto".
local function conectarMoeda(moeda: Part)
	-- "disponivel" e o debounce: impede que o evento dispare varias vezes
	-- enquanto o pe do personagem raspa na peca.
	local disponivel = true

	moeda.Touched:Connect(function(outraParte: BasePart)
		if not disponivel then
			return
		end

		-- Quem encostou e mesmo um jogador? Cada linha abaixo derruba um caso.
		local personagem = outraParte.Parent
		if not personagem or not personagem:IsA("Model") then
			return
		end

		local player = Players:GetPlayerFromCharacter(personagem)
		if not player then
			return
		end

		local stats = player:FindFirstChild("leaderstats")
		if not stats then
			return
		end

		local moedas = stats:FindFirstChild("Moedas")
		if not moedas or not moedas:IsA("IntValue") then
			return
		end

		disponivel = false
		moedas.Value += PONTOS_POR_MOEDA

		-- Some com a moeda em vez de destruir: assim ela volta depois.
		moeda.Transparency = 1
		moeda.CanTouch = false

		task.wait(TEMPO_DE_RESPAWN) -- pausa sem congelar o servidor

		moeda.Transparency = 0
		moeda.CanTouch = true
		disponivel = true
	end)
end

-- Cria 5 moedas em linha, espacadas de 6 em 6 studs, 5 studs acima do chao.
for i = 1, 5 do
	local moeda = criarMoeda(Vector3.new(i * 6, 5, 0))
	conectarMoeda(moeda)
end

print("Moedas criadas. Encoste em uma e olhe o placar no canto da tela.")
Arquivo plano-12-semanas.json salvo na pasta do seu projeto
json
{
  "plano": "Scripting Roblox do zero",
  "ritmo": "1 hora por dia, 5 dias por semana",
  "horas_totais": 60,
  "regra": "45 min digitando + 15 min lendo create.roblox.com/docs",
  "blocos": [
    {
      "semanas": "1-2",
      "tema": "Sintaxe Luau: variaveis, if, funcoes, print",
      "onde": "Script em ServerScriptService",
      "entregavel": "Tabuada do 7 impressa no Output",
      "horas": 10,
      "feito": false
    },
    {
      "semanas": "3-4",
      "tema": "Instancias e API: Instance.new, FindFirstChild, propriedades",
      "onde": "Script em ServerScriptService",
      "entregavel": "10 pecas coloridas criadas por codigo",
      "horas": 10,
      "feito": false
    },
    {
      "semanas": "5-6",
      "tema": "Eventos: Touched, PlayerAdded, debounce",
      "onde": "Script em ServerScriptService",
      "entregavel": "Moeda que da pontos e volta depois de 3 segundos",
      "horas": 10,
      "feito": false
    },
    {
      "semanas": "7-8",
      "tema": "Loops e tabelas: for, while com task.wait, listas",
      "onde": "Script em ServerScriptService",
      "entregavel": "Sistema de rodadas de 60 segundos",
      "horas": 10,
      "feito": false
    },
    {
      "semanas": "9-10",
      "tema": "Cliente x servidor: LocalScript e RemoteEvent",
      "onde": "LocalScript em StarterPlayerScripts + RemoteEvent em ReplicatedStorage",
      "entregavel": "Botao na tela que teleporta o jogador pelo servidor",
      "horas": 10,
      "feito": false
    },
    {
      "semanas": "11-12",
      "tema": "DataStore com pcall e publicacao",
      "onde": "Script em ServerScriptService",
      "entregavel": "Jogo publicado com moedas que persistem entre sessoes",
      "horas": 10,
      "feito": false
    }
  ],
  "metricas_semanais": {
    "minutos_digitando": 0,
    "erros_resolvidos_sozinho": 0,
    "jogos_publicados": 0
  }
}
Neste artigo

Continue por aqui