Resumo
Para programar no Roblox Studio, passe o mouse sobre ServerScriptService no Explorer, clique em + e insira um Script. O Studio o abre no Script Editor. Escreva Luau, como print("Hello"), aperte Play (F5) e leia o resultado na janela Output (menu Window ou aba Script). Um Script roda no servidor e muda as coisas para todo mundo; um LocalScript em StarterPlayerScripts roda no dispositivo de um jogador.
- Aprenda quatro ideias primeiro: variáveis (
local coins = 3), funções (local function name() ... end), if e eventos (part.Touched:Connect(...)). Os quatro scripts deste guia são feitos disso, mais loops e tabelas. - Use
task.wait(), nãowait(). A referência da Roblox marca owait()global como obsoleto e substituído portask.wait(). - Nas opções de exibição da janela Output, ative Show Context para cada linha dizer se veio do Server ou de um Client.
Nesta página
Antes de começar: o Studio, uma Baseplate e a janela Output
Você precisa do Roblox Studio e de uma conta do Roblox, e mais nada: nem editor de código nem plugin. Todo script deste guia é digitado no próprio Script Editor do Studio.
- Instale o Roblox Studio, o app grátis da Roblox para Windows e Mac, e entre com a sua conta do Roblox.
- Abra o Studio. A página inicial lista templates: escolha Baseplate. Você ganha um chão com textura de grade 4x4 e uma SpawnLocation, o lugar onde o seu avatar aparece quando você joga.
- Se as janelas Explorer e Properties não estiverem aparecendo, abra pelo menu Window ou pela aba Home. O Explorer lista todos os objetos do seu jogo; o Properties mostra as configurações do que estiver selecionado.
- Abra o Output pelo menu Window ou pela aba Script. É aqui que aparecem as mensagens e os erros dos seus scripts.
- Nas opções de exibição da janela Output, ative Show Context, que marca cada mensagem como Client ou Server, e Show Source, que mostra o script e o número da linha que a gerou.
| Script | Tipo | Onde fica | O que ensina |
|---|---|---|---|
FirstScript | Script | ServerScriptService | Variáveis, uma função, um if, loops e uma tabela |
ColourChanger | Script | Dentro de uma Part no Workspace | Mudar propriedades, script.Parent e um loop que espera |
TouchPad | Script | Dentro de uma Part chamada Pad | Eventos, achar o jogador que tocou uma parte, e um debounce |
MyFirstLocalScript | LocalScript | StarterPlayerScripts, dentro de StarterPlayer | Código que roda no dispositivo de um jogador, teclas e o que fica naquele dispositivo |
Workspace
Baseplate Part
SpawnLocation SpawnLocation
Part Part new
ColourChanger Script new
Pad Part new
TouchPad Script new
ServerScriptService
FirstScript Script new
StarterPlayer
StarterPlayerScripts
MyFirstLocalScript LocalScript new
Passo 1: Escreva o seu primeiro script
- No Explorer, passe o mouse sobre ServerScriptService, clique no botão + e escolha Script (o atalho é Ctrl+I, ou ⌘I no Mac). O Studio cria o script e o abre no Script Editor.
- Clique com o botão direito no script novo, escolha Rename e chame de
FirstScript. O nome não muda o que o script faz, mas diz qual script imprimiu o quê. - Scripts novos começam com uma linha,
print("Hello world!"). Apague e cole o código abaixo. - Aperte Play (F5), com Test escolhido no menu à esquerda dele. O Studio inicia um teste e coloca o seu avatar na SpawnLocation.
- Leia as linhas no Output e aperte Stop (Shift+F5). O Stop também devolve cada objeto ao estado de antes do Play, então tudo o que você moveu ou pintou enquanto jogava volta ao normal.
-- Script no ServerScriptService chamado FirstScript.
-- Seu primeiro Luau: variáveis, uma função, um if, um loop e uma tabela.
-- Aperte Play (F5) e leia os resultados na janela Output.
-- Uma variável é um nome que guarda um valor
local gameName = "Coin Run"
local coinsToWin = 3
-- Uma função é um bloco de código com nome que você roda quantas vezes quiser.
-- name e goal são os parâmetros; return devolve um valor para quem chamou.
local function describe(name: string, goal: number): string
return `{name}: collect {goal} coins to win`
end
print(describe(gameName, coinsToWin)) --> Coin Run: collect 3 coins to win
-- Um if só roda o código quando a condição é verdadeira
if coinsToWin > 5 then
print("That is a long game")
elseif coinsToWin > 1 then
print("That is a short game")
else
print("One coin and you win")
end
-- Um loop for repete o código um número definido de vezes
for count = 1, coinsToWin do
print("Coin number", count)
end
-- Uma tabela guarda uma lista de valores; este loop visita cada um em ordem
local colours = { "Red", "Green", "Blue" }
for position, colour in colours do
print(position, colour) --> 1 Red, depois 2 Green, depois 3 Blue
end
Tudo depois de -- em uma linha é um comentário: o Luau ignora, então você pode deixar anotações para você mesmo. Os comentários --> mostram o que aquela linha imprime.
O Output deve mostrar estas oito linhas, misturadas com mensagens do próprio Studio. Quando o print recebe mais de um valor, ele coloca um espaço entre eles. Com Show Context e Show Source ligados, cada linha também vem marcada como Server e FirstScript com o número da linha. Os textos estão em inglês porque são as strings do código.
Coin Run: collect 3 coins to win
That is a short game
Coin number 1
Coin number 2
Coin number 3
1 Red
2 Green
3 Blue
Ligue cada linha ao código que a imprimiu. Você vai fazer o mesmo com mensagens de erro depois, então vale criar o hábito agora.
O FirstScript usa só Luau puro, sem objetos do Roblox, então também roda no Luau playground grátis no seu navegador. Mude um valor lá e rode de novo para ver o que muda.
| Código | Ideia | O que significa |
|---|---|---|
local gameName = "Coin Run" | Variável | Um nome que guarda um valor. local quer dizer que só este script, ou o bloco em que ela está, pode usá-la. Texto entre aspas é uma string; 3 é um number. Nomes diferenciam maiúsculas, então coinsToWin e CoinsToWin são duas variáveis diferentes. |
local function describe(name: string, goal: number): string | Função | Um bloco de código com nome que você roda quantas vezes quiser. name e goal são os parâmetros: valores passados cada vez que ela é chamada. : string e : number são anotações de tipo opcionais. O Luau as usa para avisar sobre erros no Script Editor; o código roda igual sem elas. |
return | Valor de retorno | Devolve um valor ao código que chamou a função. print(describe(gameName, coinsToWin)) imprime o que describe devolver. |
`{name}: collect {goal} coins to win` | Interpolação de strings | Texto entre crases pode conter valores: o Luau troca {name} e {goal} pelos valores atuais. |
if, elseif, else, end | If | O Luau testa as condições de cima para baixo e roda só a primeira que for verdadeira. coinsToWin é 3, que não é maior que 5 mas é maior que 1, então só "That is a short game" é impresso. |
for count = 1, coinsToWin do | Loop for numérico | Roda o código de dentro uma vez para cada número de 1 até coinsToWin, com count valendo 1, depois 2, depois 3. |
{ "Red", "Green", "Blue" } e for position, colour in colours do | Tabela e loop | Uma tabela usada como lista, que o Luau chama de array. As posições começam em 1, não em 0. O loop visita cada item e dá a posição e o valor. |
Todo bloco que abre com function, if, for ou while fecha com end. Um end faltando impede o script inteiro de rodar; ler os erros mostra a mensagem que aparece.
Passo 2: Mude uma parte com um script
Scripts ficam úteis quando mudam coisas no mundo. As configurações que você vê na janela Properties, como Color, Transparency ou Anchored de uma parte, são propriedades, e um script também pode defini-las.
- Na aba Home, clique em Part. O Studio adiciona um bloco ao Workspace. O nome dele não importa.
- No Explorer, passe o mouse sobre a parte nova, clique em + e insira um Script. Renomeie para
ColourChangere troque o conteúdo pelo código abaixo. - Aperte Play. A parte fica vermelha, depois azul, depois verde, mudando uma vez por segundo, e recomeça.
-- Script dentro de uma Part no Workspace, chamado ColourChanger.
-- Scripts mudam as mesmas propriedades que você vê na janela Properties.
-- Este dá uma cor nova à sua parte a cada segundo, para todos os jogadores.
local part = script.Parent :: BasePart -- a parte em que este script está
local colours = {
Color3.fromRGB(255, 85, 85), -- vermelho
Color3.fromRGB(85, 170, 255), -- azul
Color3.fromRGB(85, 255, 127), -- verde
}
part.Anchored = true -- uma parte ancorada fica onde você a colocou
local index = 1
while true do
part.Color = colours[index]
index = index % #colours + 1 -- 1, 2, 3, depois volta para 1
task.wait(1) -- pausa de um segundo (o antigo wait() está obsoleto)
end
script.Parenté o objeto em que o script está, aqui a parte. Arraste o script para outra parte e ele passa a mudar aquela parte.:: BaseParté um cast de tipo. Ele diz ao Script Editor que o pai é uma parte, para conferir as propriedades que você usa nele. O Luau só usa tipos para avisos e sugestões, então o cast não muda o que a linha faz.part.Colorepart.Anchoredsão as mesmas propriedades da janela Properties, com os mesmos nomes. A Roblox usa a grafia americana, então a propriedade éColormesmo o script se chamando ColourChanger.Anchored = truemantém a parte parada: a referência da Roblox diz que uma parte ancorada nunca se move por gravidade, colisões ou qualquer outra física.colours[index]lê um item da lista.#coloursé o tamanho da lista, 3, e%dá o resto da divisão, entãoindex % #colours + 1conta 1, 2, 3, 1, 2, 3.while true dorepete para sempre, e por isso otask.wait(1)de dentro importa. A documentação da Roblox diz para sempre colocar uma pausa comotask.wait()em um loop infinito: sem ela, o jogo trava e o Studio fecha.
O ColourChanger é um Script, então roda no servidor, e todos os jogadores no jogo veem a mesma cor ao mesmo tempo. O Passo 4 mostra o outro tipo de script.
Passo 3: Reaja a um jogador com um evento
A maior parte do código de jogo espera algo acontecer: um jogador entra, uma parte é tocada, um botão é clicado. A Roblox chama isso de eventos. Para rodar código quando um deles dispara, você conecta uma função a ele.
- Insira outra Part e renomeie para exatamente
Pad, com P maiúsculo. Deixe direto no Workspace, não dentro de uma pasta ou de um modelo, porque o LocalScript do Passo 4 procura por ela lá. - Faça dela uma plataforma plana em que dá para pisar, por exemplo definindo o
Sizecomo6, 1, 6na janela Properties. Coloque no chão perto da SpawnLocation e marque Anchored para ela ficar parada. - Passe o mouse sobre Pad, clique em +, insira um Script, renomeie para
TouchPade cole o código abaixo. - Aperte Play e pise na plataforma. Ela fica amarela por 2 segundos, e o Output diz o seu nome.
-- Script dentro de uma Part no Workspace chamada Pad, script chamado TouchPad.
-- Eventos: quando um jogador pisa na plataforma, ela brilha amarela e o Output diz quem foi.
-- Um debounce impede que rode várias vezes por segundo enquanto ele fica em cima.
local Players = game:GetService("Players")
local pad = script.Parent :: BasePart
local COOLDOWN_SECONDS = 2
local normalColour = pad.Color
local busy = false
local function onTouched(otherPart: BasePart)
if busy then
return -- ainda esperando o tempo de recarga do último toque
end
-- O personagem é o Model que contém a parte do corpo (ou o chapéu) que tocou a plataforma
local character = otherPart:FindFirstAncestorOfClass("Model")
local player = character and Players:GetPlayerFromCharacter(character)
if not player then
return -- uma parte solta ou um NPC tocou, não um jogador
end
busy = true
print(`{player.Name} stepped on the pad`)
pad.Color = Color3.fromRGB(255, 220, 0)
task.wait(COOLDOWN_SECONDS)
pad.Color = normalColour
busy = false
end
pad.Touched:Connect(onTouched)
| Código | O que faz |
|---|---|
pad.Touched:Connect(onTouched) | Conecta a função ao evento Touched da plataforma, então a Roblox roda onTouched toda vez que algo toca a plataforma, e passa a parte que tocou. |
otherPart | A parte que tocou a plataforma: um pé, uma perna, o cabo de um chapéu ou uma ferramenta que o jogador segura. Nunca é o jogador, então as duas linhas seguintes descobrem a quem ela pertence. |
otherPart:FindFirstAncestorOfClass("Model") | Sobe a partir daquela parte até o primeiro ancestral cuja classe é exatamente Model, que é o personagem. Como o nome da classe precisa ser exato, ele passa por cima de um chapéu (classe Accessory) e de uma ferramenta na mão (classe Tool). |
Players:GetPlayerFromCharacter(character) | Devolve o Player de quem aquele modelo é o personagem, ou nil se não for o personagem de ninguém, como um NPC. O character and na frente pula a chamada quando nenhum modelo foi achado, o que deixa player como nil. |
if not player then return end | Para aqui para tudo o que não for um jogador. return sai da função mais cedo. |
Por que a plataforma precisa de um debounce
A página de debounce da Roblox avisa que o Touched dispara várias vezes em sequência rápida conforme as partes fazem contato, e um personagem andando tem várias partes do corpo. Sem uma checagem, um passo na plataforma poderia imprimir muitas linhas e reiniciar o brilho amarelo de novo e de novo.
A variável busy é o debounce. O primeiro toque a define como true, e todo toque nos 2 segundos seguintes chega em if busy then return end e para. Depois de task.wait(COOLDOWN_SECONDS), a plataforma volta ao normal e busy volta a false. COOLDOWN_SECONDS está em maiúsculas porque é uma configuração que não muda enquanto o jogo roda, o padrão de nomes que a Roblox sugere para constantes.
Esta plataforma tem um debounce para todo mundo, então um segundo jogador que pisar dentro desses 2 segundos é ignorado. Isso serve para uma plataforma que brilha. Uma plataforma que dá recompensas deve ter um tempo de recarga para cada jogador, como faz a plataforma de moedas do guia de leaderboard (em inglês).
Passo 4: Seu primeiro LocalScript, e por que ele é diferente
Um jogo rodando é um servidor mais um cliente para cada jogador. Tudo até aqui foi um Script, que roda no servidor, então as alterações chegam a todos os jogadores. Um LocalScript roda no dispositivo de um jogador. Teclas, câmera e menus na tela são tratados ali, porque só aquele dispositivo sabe deles.
- No Explorer, abra StarterPlayer, passe o mouse sobre StarterPlayerScripts, clique em + e insira um LocalScript. Renomeie para
MyFirstLocalScripte cole o código abaixo. - Aperte Play. O Output mostra
Hello,e o seu nome, marcado como Client. - Clique na visão do jogo e aperte E. A plataforma fica transparente. Aperte E de novo para voltar.
- Com o teste ainda rodando, clique no botão Client/Server nos controles de teste do Studio para trocar para a cópia do jogo do servidor. Lá a plataforma está sólida: o servidor nunca soube da mudança.
-- LocalScript em StarterPlayer > StarterPlayerScripts chamado MyFirstLocalScript.
-- Um LocalScript roda no próprio dispositivo de um jogador. Aperte E: a Pad fica transparente
-- só na sua tela, porque uma mudança em uma parte feita aqui não chega ao servidor nem a mais ninguém.
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local player = Players.LocalPlayer
print(`Hello, {player.Name}`) -- aparece no Output, marcado como Client
UserInputService.InputBegan:Connect(function(input: InputObject, gameProcessed: boolean)
if gameProcessed then
return -- a tecla foi usada para outra coisa, como digitar no chat
end
if input.KeyCode == Enum.KeyCode.E then
local pad = workspace:FindFirstChild("Pad")
if pad and pad:IsA("BasePart") then
pad.Transparency = if pad.Transparency == 0 then 0.6 else 0
end
end
end)
Players.LocalPlayeré o jogador cujo dispositivo está rodando o script. A Roblox o define só para LocalScripts e os ModuleScripts que eles usam com require, então o código do servidor não pode usá-lo.UserInputService.InputBegandispara quando o jogador começa a apertar uma tecla, clicar ou tocar.gameProcessedétruequando o motor já usou essa entrada, por exemplo um clique em um botão ou uma tecla digitada na barra do chat, então o script ignora.workspace:FindFirstChild("Pad")devolve o filho chamado Pad, ounilse não houver.pad:IsA("BasePart")confere se é mesmo uma parte antes de o script mudar aTransparency.if pad.Transparency == 0 then 0.6 else 0é uma expressão if: ela escolhe um de dois valores. Transparency 0 é totalmente visível e 1 é invisível.- Um script de correr com Shift (em inglês) é um bom segundo LocalScript: ele escuta uma tecla e muda a WalkSpeed do seu personagem.
| Tipo | Roda em | As mudanças chegam a | Use para | Costuma ficar em |
|---|---|---|---|---|
| Script | O servidor | Todos os jogadores | Regras do jogo: moedas, dano, portas, rodadas, salvamento | ServerScriptService, ou dentro de uma parte enquanto você aprende |
| LocalScript | O dispositivo de um jogador | Só aquele dispositivo, fora o movimento do próprio personagem | Entrada, câmera, menus na tela, efeitos para um jogador | StarterPlayerScripts ou StarterGui |
| ModuleScript | O lado que chamar require() nele | O mesmo que o script que fez o require | Código que vários scripts compartilham | ReplicatedStorage para os dois lados, ServerScriptService só para o servidor |
O que um trapaceiro consegue mudar
Considere que um trapaceiro controla tudo no próprio dispositivo. Ele pode rodar os próprios LocalScripts e mudar os seus, então pode deixar a plataforma transparente, ou qualquer outra coisa, na tela dele. Aqui isso é inofensivo: a transparência é só visual e fica no dispositivo dele. É também o motivo de tudo o que importa ser decidido por um Script no servidor.
Um Script de servidor também não é seguro automaticamente. O TouchPad roda no servidor, mas o dispositivo de cada jogador controla a física do próprio personagem, e a documentação de segurança da Roblox lista manipular quando o Touched dispara, ou impedir que ele dispare, entre as coisas que um cliente pode fazer com as partes que controla. Para uma plataforma que brilha, isso não importa. Para uma plataforma que paga, confira também algo que o próprio servidor controla, como a regra do guia de obby (em inglês) de que os checkpoints só contam em ordem.
Passo 5: Teste os quatro scripts juntos
- Limpe o Output com Ctrl+K (⌘K no Mac) e aperte Play (F5). O Output mostra as oito linhas do FirstScript marcadas como Server, e a sua linha Hello marcada como Client. A parte do ColourChanger muda de cor a cada segundo.
- Pise na plataforma. Ela fica amarela por 2 segundos e o Output mostra o seu nome e "stepped on the pad" uma vez. Continue andando em cima dela: uma linha nova aparece no máximo uma vez a cada 2 segundos, não toda vez que o Touched dispara.
- Aperte E. A plataforma vai para Transparency 0,6. Aperte E de novo e ela fica sólida.
- Aperte Stop. No menu de teste, escolha Server & Clients, defina 2 clientes e aperte Play (ou F7). O Studio abre uma janela de servidor e duas de cliente. Em um cliente, aperte E: a plataforma fica transparente ali, enquanto o outro cliente e o servidor ainda a mostram sólida. Aperte End Session quando terminar.
- Quebre algo de propósito. Renomeie Pad para
Pad2e jogue. Pisar nela ainda a deixa amarela, porque o TouchPad acha a parte comscript.Parent, não pelo nome. Apertar E agora não faz nada, e não há erro:FindFirstChild("Pad")devolveunil, e a checagemif pad and ...pulou o resto em silêncio. Adicioneprint(pad)na linha depois doFindFirstChild, jogue e aperte E: o Output mostranil. Um print assim é o jeito mais rápido de descobrir por que um script não faz nada. Pare, apague a linha do print e renomeie a parte de volta para Pad.
Onde ficam os scripts
O lugar onde um script fica decide se ele roda ou não, e o Studio não avisa quando ele nunca vai rodar. Para os scripts que você vai escrever a seguir:
| Contêiner | Coloque aqui | Por quê |
|---|---|---|
| ServerScriptService | Scripts com a maior parte das regras do jogo: recompensas, rodadas, salvamento | Eles rodam no servidor, e nada no ServerScriptService é enviado aos jogadores. |
| Dentro de uma parte no Workspace | Um Script que pertence àquela parte, como ColourChanger e TouchPad | Serve enquanto você aprende: a parte é script.Parent. Em projetos de verdade, a Roblox recomenda marcar as partes com tags (veja abaixo). |
| StarterPlayerScripts, dentro de StarterPlayer | A maioria dos LocalScripts: entrada, câmera, efeitos para um jogador | Cada jogador recebe a própria cópia ao entrar. |
| StarterGui | LocalScripts dentro de uma ScreenGui que controlam um menu na tela | Cada jogador recebe a própria cópia da interface. |
| ReplicatedStorage | ModuleScripts que o código do servidor e do cliente usam com require | Os dois lados enxergam. Um LocalScript, ou um Script com as configurações padrão, colocado aqui nunca roda. |
A página de locais de scripts da Roblox recomenda não colocar scripts direto dentro de partes no Workspace: marque as partes com tags e trabalhe com elas a partir de um único ModuleScript usando CollectionService. Um script dentro de uma parte ainda é o jeito mais fácil de começar, e serve para um ou dois objetos enquanto você aprende. O guia de portas mostra o padrão com tags, com um script para todas as portas, e o guia de cliente e servidor tem a tabela completa de quais contêineres rodam quais scripts (em inglês).
Quando algo dá errado: leia o Output
Os erros aparecem no Output em vermelho. Cada um começa dizendo onde aconteceu, o nome completo do script e o número da linha, e depois diz o que deu errado. Clique no erro e o Studio abre aquele script naquela linha. Por exemplo, se você apagasse a checagem if not player do TouchPad e uma parte solta caísse na plataforma, o Output mostraria:
Workspace.Pad.TouchPad:22: attempt to index nil with 'Name'
Erros na forma como o código está escrito, como um end faltando, aparecem antes de você apertar Play: o Script Editor sublinha em vermelho, e a janela Script Analysis (o botão Analysis na aba Script) lista todos. Um script com um erro desses não roda nada, nem as linhas acima dele.
| Mensagem | O que significa | Como corrigir |
|---|---|---|
Colour is not a valid member of Part "Workspace.Part" | Não existe nada com esse nome exato naquele objeto. Aqui, a propriedade se escreve Color. | Use a mesma grafia e as mesmas maiúsculas da janela Properties ou do Explorer. Mais sobre este erro (em inglês). |
attempt to index nil with 'Name' | O código leu algo, aqui .Name, de um valor que era nil. No exemplo acima, player era nil porque uma parte solta tocou a plataforma. | Descubra por que o valor é nil e confira com if antes de usar. Mais sobre este erro (em inglês). |
Expected 'end' (to close 'then' at line 2), got <eof> | O if da linha 2 não tem um end correspondente. Para uma função, a mensagem diz to close 'function', e <eof> quer dizer fim do arquivo. | Adicione o end que falta, olhando a linha citada entre parênteses e não a última linha. Às vezes a mensagem termina com "did you forget to close ... at line N?". Essa parte é um palpite do Luau pela sua indentação e pode apontar o bloco errado, então confira primeiro a linha entre parênteses. Mais sobre erros de sintaxe (em inglês). |
Quando um script não faz nada e o Output também não mostra nada, normalmente ele está em um lugar onde nunca roda, ou esperando um evento que nunca dispara. O guia de erros de script tem uma lista para scripts silenciosos e se aprofunda em como ler o Output (em inglês).
O que os tutoriais de scripting antigos fazem diferente
Se você também aprende com vídeos e posts em fóruns, vai encontrar padrões antigos. Estes são os que importam, com o motivo de cada um ser um problema.
| O tutorial | O problema | Este guia |
|---|---|---|
Pausa com wait(1) | A referência da Roblox marca o wait() global como obsoleto e diz que o task.wait() o substituiu. | task.wait(1) |
Acha o personagem com otherPart.Parent, como faz a própria aula de lava da Roblox | Quando um chapéu ou uma ferramenta na mão toca a parte, otherPart.Parent é o Accessory ou a Tool, não o personagem, então nenhum Humanoid é achado e aquele toque é perdido. | FindFirstAncestorOfClass("Model"), depois GetPlayerFromCharacter |
Usa Touched sem debounce | O Touched dispara várias vezes em sequência rápida para um passo, então o código roda de novo e de novo. | Uma flag busy e um tempo de recarga |
| Coloca um LocalScript dentro de uma parte no Workspace | Um LocalScript nunca roda ali. Ele só roda em lugares que pertencem a um jogador. | LocalScripts em StarterPlayerScripts (por quê, em inglês) |
Escreve part.Touched:connect(...) ou table.getn(list) | O guia de nomes da Roblox diz que APIs em camelCase estão em grande parte obsoletas, e a referência lista só Connect. table.getn está obsoleto em favor de #list. | :Connect(...) e #list |
| Muda moedas ou causa dano em um LocalScript | A mudança fica no dispositivo daquele jogador, então ninguém mais vê e o servidor nunca conta. | Regras do jogo em Scripts no servidor |
Prática: três mudanças para tentar
Mudar código ensina mais do que ler. Tente estas no seu próprio jogo, uma de cada vez, e aperte Play depois de cada uma.
- Faça a plataforma dar um ponto. Adicione o script Leaderstats do Passo 1 do guia de leaderboard (em inglês). Depois, no TouchPad, depois de
busy = true, ache a pastaleaderstatsdo jogador e some 1 ao valorCoins. Dica:player:FindFirstChild("leaderstats"), depoisleaderstats:FindFirstChild("Coins"), depoiscoins.Value += 1. A plataforma de moedas do guia de leaderboard é uma versão pronta, com tempo de recarga para cada jogador. - Faça o ColourChanger mudar a transparência também. Faça o ColourChanger mudar a
Transparencyda parte a cada segundo também. Dica: adicione uma segunda tabela de números entre 0 e 1, como{ 0, 0.3, 0.6 }, e definapart.Transparencya partir dela na linha depois depart.Color, usando o mesmoindex. - Imprima a cor da plataforma. Faça o MyFirstLocalScript imprimir a
Colorda plataforma quando você apertar E. Dica:print(pad.Color)dentro do blocoif pad and pad:IsA("BasePart"). Aperte E enquanto a plataforma está amarela: o cliente vê a cor que o servidor definiu, porque mudanças feitas no servidor chegam a todos os clientes.
O que aprender a seguir
Agora você já usou as peças de que a maioria dos scripts de jogo é feita. Uma boa ordem para o que vem a seguir (guias em inglês, exceto o do primeiro jogo):
- LocalScript vs Script vs ModuleScript: onde cada tipo de script roda e o que ele pode mudar, com mais detalhes que o Passo 4.
- RemoteEvents: como um LocalScript pede ao servidor para fazer algo, e como o servidor confere o pedido.
- Um leaderboard: suas primeiras estatísticas, criadas e mudadas no servidor.
- Seu primeiro jogo: um percurso curto de moedas com lava, moedas e uma plataforma de chegada, controlado por dois scripts de servidor, e depois publicado.
- Depois escolha um sistema para adicionar: uma loja com GUI, um sistema de rodadas, checkpoints de obby, uma tela de carregamento ou uma animação ao apertar uma tecla. Quando algo quebrar, o guia de erros de script ajuda a ler a mensagem.
Os tutoriais Coding fundamentals da própria Roblox (em inglês) são um bom complemento: seis séries que vão de variáveis e funções a condicionais, loops, arrays e dicionários até organizar código com ModuleScripts, com pequenos projetos para construir no Studio.
Problemas comuns e soluções
A maioria dos problemas com os primeiros scripts é um nome que não bate, um script no lugar errado ou um loop sem espera. Mantenha o Output aberto enquanto testa.
O Studio trava ou para de responder quando aperto Play
Um loop while true do não tem espera dentro, então nada mais consegue rodar. A documentação da Roblox diz que um loop infinito sem uma pausa como task.wait() trava o jogo e fecha o Studio. Coloque um task.wait() dentro de todo loop que roda para sempre, como o ColourChanger faz.
Nada acontece quando piso na plataforma
Confira se o TouchPad é um Script, não um LocalScript, direto dentro da parte Pad, se ele não está desativado e se a propriedade CanTouch da plataforma está marcada. Depois faça de print("touched", otherPart.Name) a primeira linha dentro de onTouched. Se nunca imprimir, o evento não está disparando; se imprimir, o problema está mais abaixo.
Apertar E não faz nada
O MyFirstLocalScript precisa ser um LocalScript dentro de StarterPlayerScripts: um LocalScript no Workspace ou no ServerScriptService nunca roda. A parte precisa se chamar exatamente Pad e ficar direto no Workspace. Clique na visão do jogo antes, e confira se você não está digitando no chat, porque o script ignora teclas que o jogo já usou.
A parte muda na minha tela, mas não para os outros jogadores
A mudança foi feita em um LocalScript, então ficou no seu dispositivo. Faça em um Script de servidor, ou faça o LocalScript pedir ao servidor com um RemoteEvent (em inglês).
O ColourChanger funciona dentro de uma parte mas quebra no ServerScriptService
Ele usa script.Parent como a parte. No ServerScriptService, o pai é o ServerScriptService, que não tem Anchored nem Color, então o Output mostra um erro "not a valid member". Mantenha dentro da parte, ou dê um nome à parte e ache pelo nome, por exemplo local part = workspace:WaitForChild("ColourPart") :: BasePart.
O Output não mostra nada
Confira se a janela Output está aberta (menu Window ou aba Script) e se não há filtro: o Output pode ser filtrado por tipo de mensagem, por Client ou Server e por texto. Se está aberta e ainda vazia, o script provavelmente nunca rodou. Veja a lista para scripts que não fazem nada (em inglês).
Destravando com o RoCode
Se você empacar em um script no seu próprio jogo, o RoCode pode lê-lo com você. O RoCode é um agente de IA independente para Roblox Studio, não feito pela Roblox: você escreve em um chat na web, e o plugin dele para o Studio cria e edita os scripts no seu Explorer.
Enquanto você aprende, o modo Ask é o útil: você continua escrevendo os scripts, e o RoCode lê o que já existe e responde suas perguntas sobre isso.
Explique linha por linha o que o script TouchPad dentro da parte Pad faz, e me diga por que ele usa um debounce.
- No modo Ask, usa só ferramentas de leitura como Search Scripts e Read Script, e não muda nada no jogo
- Se algo precisar de correção, diz o que mudaria e onde, e sugere trocar para o modo Build
- No modo Build, ele edita os scripts no lugar e compila cada um com Check Script. É uma verificação de compilação, não de tipos nem um teste
- Lê o Output do Studio com a ferramenta Check Output, incluindo as linhas Server e Client do seu último teste, mesmo depois que você aperta Stop
No modo Build, com o plugin 3.9 ou mais recente, o RoCode pode rodar um teste curto e ler os erros, e com o 3.9.11 ou mais recente controlar um personagem de teste para conferir se o jogo funciona, mas ele não tira capturas de tela enquanto o jogo roda, então você ainda pisa na plataforma. Como o RoCode se conecta ao Studio.
Perguntas frequentes
Onde eu escrevo scripts no Roblox Studio?
No Explorer, passe o mouse sobre um contêiner como o ServerScriptService, clique no botão + e escolha Script. O Studio o abre no Script Editor, onde você escreve Luau. Scripts de servidor costumam ficar no ServerScriptService; LocalScripts ficam em StarterPlayerScripts ou StarterGui.
Como eu rodo um script no Roblox Studio?
Aperte Play (F5). O Studio inicia um teste, e cada Script ativado no ServerScriptService ou no Workspace roda assim que o jogo começa; LocalScripts em StarterPlayerScripts rodam quando você entra no teste. O Run (escolha no menu ao lado do Play, ou aperte F8) inicia o jogo sem o seu avatar, então use o Play neste guia. Aperte Stop (Shift+F5) para encerrar o teste. Para abrir um script que já existe, clique duas vezes nele no Explorer.
Que linguagem de programação o Roblox usa?
Luau. A Roblox a descreve como uma linguagem de script rápida, pequena, segura e com tipagem gradual, derivada do Lua 5.1, então a maioria dos tutoriais de Lua ainda ajuda. O Luau adiciona recursos como interpolação de strings com crases e anotações de tipo opcionais, e a Roblox adiciona as próprias bibliotecas e objetos, como task.wait.
Qual a diferença entre um Script e um LocalScript?
Um Script roda no servidor, e as mudanças dele chegam a todos os jogadores. Um LocalScript roda no dispositivo de um jogador, para coisas como entrada, câmera e menus na tela, e as mudanças dele em partes, valores e interface ficam naquele dispositivo. O guia de cliente e servidor (em inglês) cobre os dois, mais ModuleScripts.
Dá para programar no Roblox Studio pelo celular ou iPad?
A página de configuração da Roblox descreve o Studio como um app grátis para Windows e Mac e não lista versão para celular ou tablet, então você precisa de um computador para escrever scripts.
Por que meu script não faz nada e não mostra erro?
Normalmente ele está em um lugar onde aquele tipo de script não roda (um LocalScript no Workspace, ou um Script em StarterPlayerScripts), está desativado, ou o evento que ele espera nunca dispara. O guia de erros de script tem uma lista de verificação (em inglês).
Quanto tempo leva para aprender a programar no Roblox?
Ninguém consegue dar um número honesto: depende de quanto você constrói. O que mais ajuda é escrever scripts pequenos no seu próprio jogo com frequência. Mude os quatro scripts daqui, tente as tarefas de prática, depois siga o guia do primeiro jogo e adicione um sistema de cada vez.
Fontes e leitura extra
- Roblox Creator Docs: Luau (em inglês). o que é o Luau e de onde ele vem
- Roblox Creator Docs: Roblox Studio setup (em inglês). Windows e Mac, e os requisitos do sistema
- Roblox Creator Docs: Output (em inglês). abrir o Output, filtros, Show Context e Show Source
- Roblox Creator Docs: Studio testing modes (em inglês). Play, Run, Stop, o botão Client/Server e Server & Clients
- Roblox Creator Docs: Script Editor (em inglês). onde os scripts novos abrem, e o Script Analysis
- Roblox Creator Docs: Script types and locations (em inglês). onde cada tipo de script roda, e usar tags em vez de colocar scripts nas partes
- Roblox Creator Docs: Script (em inglês). quando um Script começa a rodar
- Roblox Creator Docs: Control structures (em inglês). if, loops, e por que um loop infinito precisa de uma espera
- Roblox Creator Docs: Events (em inglês). Connect, e o que o Touched passa para a sua função
- Roblox Creator Docs: Debounce patterns (em inglês). por que o Touched dispara várias vezes em um contato
- Roblox Creator Docs: wait (em inglês). o wait() global e o task.wait()
- Roblox Creator Docs: Network ownership, movement validation and physics exploits (em inglês). o que um cliente pode fazer com o próprio personagem
- Roblox Creator Docs: Coding fundamentals (em inglês). a série para iniciantes da própria Roblox
Como o código foi verificado: todo script desta página passa no verificador de tipos estrito do Luau com as definições da API do Roblox (luau-lsp, 26 de outubro de 2026). A verificação de tipos pega APIs com nome errado e tipos incorretos, não a lógica do jogo, então teste no Studio antes de publicar.