Guia Completo da API do Roblox 🚀
Do Zero ao Herói - Linguagem Descomplicada
📋 Índice
1. Introdução - Por Onde Começar
2. Conceitos Fundamentais
3. Workspace - Onde Tudo Acontece
4. Scripts e Programação
5. Partes e Objetos 3D
6. Eventos e Conexões
7. Interface Gráfica (GUI)
8. Jogadores e Personagens
9. Serviços Essenciais
10. DataStores - Salvando Dados
11. Tweening e Animações
12. Audio e Efeitos Visuais
13. Física e Constraints
14. Networking - Cliente vs Servidor
15. Exemplos Práticos Completos
🎯 Introdução
Opa, dev! Bem-vindo ao mundo maluco do desenvolvimento no Roblox!
O que é a API do Roblox?
A API (Application Programming Interface) do Roblox é basicamente um manual de instruções
gigante que te ensina como fazer as coisas funcionarem no jogo. É tipo um dicionário, mas ao invés
de palavras, tem comandos, propriedades e métodos que fazem a mágica acontecer.
Por que Lua?
O Roblox usa Lua, uma linguagem de programação que é:
Fácil de aprender (mais fácil que Python, sério!)
Rápida para executar
Perfeita para jogos
Como Funciona?
No Roblox, tudo funciona numa hierarquia tipo árvore genealógica:
game (raiz de tudo)
├── Workspace (onde ficam os objetos 3D)
├── Players (jogadores conectados)
├── ReplicatedStorage (coisas compartilhadas)
├── ServerStorage (coisas só do servidor)
└── StarterGui (interface do usuário)
🧠 Conceitos Fundamentais
Instance - O Pai de Todos
Instance é a classe mãe de TUDO no Roblox. É tipo o DNA básico que todos os objetos compartilham.
lua
-- Toda coisa no Roblox é uma Instance
local parte = [Link]("Part") -- Cria uma parte nova
-- [Link]() = "Ei Roblox, me dá um objeto novo do tipo X"
local gui = [Link]("ScreenGui") -- Cria uma interface
-- Mesmo comando, tipo diferente
Propriedades vs Métodos vs Eventos
Propriedades: características do objeto (cor, tamanho, nome)
Métodos: ações que o objeto pode fazer (mover, deletar, criar)
Eventos: coisas que acontecem com o objeto (clicado, tocado, destruído)
lua
local parte = [Link]("Part")
-- PROPRIEDADE (característica)
[Link] = "MinhaParteIncrivel" -- Muda o nome
[Link] = [Link]("Really red") -- Muda a cor
-- MÉTODO (ação)
parte:SetPrimaryPartCFrame([Link](0, 10, 0)) -- Move a parte
-- Os dois pontos (:) significam "faça isso com você mesmo"
-- EVENTO (reação)
[Link]:Connect(function(hit) -- Quando algo tocar na parte
print("Alguém encostou em mim!") -- Faz alguma coisa
end)
-- .Touched é o evento, :Connect liga uma função a ele
CFrame - O Sistema de Coordenadas Ninja
CFrame = Coordinate Frame = posição + rotação em uma tacada só
lua
-- CFrame básico
local posicao = [Link](10, 5, 20) -- x=10, y=5, z=20
-- new() cria um novo CFrame na posição especificada
-- CFrame com rotação
local posicaoComRotacao = [Link](0, 0, 0) * [Link](0, [Link](45), 0)
-- [Link]() cria rotação em radianos
-- [Link]() converte graus para radianos (45° vira radianos)
-- O * multiplica posição com rotação
-- Exemplo prático: teleportar jogador
[Link] = [Link](0, 50, 0)
-- Pega o jogador local -> seu personagem -> a parte principal -> muda a posição
Vector3 - Coordenadas Simples
Vector3 é só posição, sem rotação
lua
local tamanho = [Link](4, 2, 1) -- largura=4, altura=2, profundidade=1
[Link] = tamanho -- Aplica o tamanho na parte
-- Matemática com Vector3
local posicaoA = [Link](0, 0, 0)
local posicaoB = [Link](10, 0, 0)
local distancia = (posicaoB - posicaoA).Magnitude -- Calcula distância
-- .Magnitude pega o "comprimento" do vetor (distância do ponto 0,0,0)
🌍 Workspace - Onde Tudo Acontece
O Workspace é tipo o palco do teatro - é onde todos os objetos 3D ficam e onde a ação rola.
Acessando o Workspace
lua
-- Várias formas de acessar
local workspace1 = [Link] -- Forma direta
local workspace2 = game:GetService("Workspace") -- Forma segura
local workspace3 = workspace -- Variável global (mais usada)
-- :GetService() é mais seguro porque garante que o serviço existe
Criando e Manipulando Objetos
lua
-- Criando uma parte
local minhaParte = [Link]("Part") -- Cria a parte na memória
[Link] = workspace -- Coloca ela no mundo visível
-- .Parent define onde o objeto vai "morar" na hierarquia
-- Configurando propriedades
[Link] = "ParteMagica" -- Nome do objeto
[Link] = [Link](4, 2, 8) -- Tamanho (x, y, z)
[Link] = [Link](0, 5, 0) -- Posição inicial
[Link] = [Link]("Bright blue") -- Cor
[Link] = [Link] -- Material brilhante
-- [Link] é uma lista de materiais disponíveis
-- Adicionando física
[Link] = false -- false = pode se mover com física
-- true = fica fixo no lugar, não é afetado por gravidade
Encontrando Objetos
lua
-- Por nome (cuidado: pode não existir!)
local parte = workspace:FindFirstChild("ParteMagica") -- Procura filho direto
if parte then -- Sempre verifica se encontrou
print("Achei a parte!")
else
print("Parte não encontrada :(")
end
-- Procura recursiva (em toda a árvore)
local parteDistante = workspace:FindFirstChild("ParteMagica", true) -- true = busca recursiva
-- Procura não só nos filhos diretos, mas nos filhos dos filhos também
-- Por classe
local todasAsPartes = workspace:GetChildren() -- Pega TODOS os filhos
for i, objeto in pairs(todasAsPartes) do -- Loop por todos
if objeto:IsA("Part") then -- Se for uma Part
print("Encontrei uma parte:", [Link])
end
end
-- :IsA() verifica se o objeto é de uma classe específica
💻 Scripts e Programação
Tipos de Scripts
ServerScript (Script normal):
Roda no servidor
Todos os jogadores veem o resultado
Pode modificar qualquer coisa no jogo
Não pode acessar coisas específicas do jogador (como mouse, câmera)
LocalScript:
Roda no cliente (computador do jogador)
Só aquele jogador vê o resultado
Pode acessar coisas locais (mouse, câmera, GUI)
Mudanças não são replicadas para outros jogadores
lua
-- Em um ServerScript
local parte = [Link]("Part")
[Link] = workspace -- TODOS os jogadores veem esta parte
-- Em um LocalScript
[Link] = 50
-- Só ESSE jogador fica mais rápido
ModuleScript - Código Reutilizável
ModuleScript é tipo uma biblioteca de funções que outros scripts podem usar.
lua
-- ModuleScript chamado "MathUtils"
local MathUtils = {} -- Cria uma tabela vazia
-- Função para calcular distância entre duas posições
function [Link](pos1, pos2)
return (pos2 - pos1).Magnitude -- Retorna a distância
end
-- Função para gerar número aleatório em um range
function [Link](min, max)
return [Link]() * (max - min) + min
-- [Link]() gera 0-1, multiplicamos pelo range e somamos o mínimo
end
return MathUtils -- SEMPRE retorna a tabela no final
lua
-- Em outro script, usando o ModuleScript
local MathUtils = require([Link]) -- Importa o módulo
-- require() carrega e executa o ModuleScript, retornando o que ele retornou
local distancia = [Link](
[Link](0, 0, 0),
[Link](10, 0, 0)
)
print("Distância:", distancia) -- Resultado: 10
RunService - O Coração do Jogo
RunService controla os loops de atualização do jogo.
lua
local RunService = game:GetService("RunService")
-- Loop que roda todo frame (60 fps = 60 vezes por segundo)
[Link]:Connect(function(deltaTime)
-- deltaTime = tempo desde o último frame
print("Frame! Tempo desde último:", deltaTime)
end)
-- Só no cliente
if RunService:IsClient() then
[Link]:Connect(function()
-- Roda antes de cada frame ser desenhado
-- Perfeito para updates de câmera e GUI
end)
end
-- Só no servidor
if RunService:IsServer() then
[Link]:Connect(function()
-- Roda a cada step da física
-- Bom para lógica de jogo
end)
end
🧱 Partes e Objetos 3D
Part - O Bloco Básico
Part é o objeto 3D mais básico. É tipo um Lego digital.
lua
local parte = [Link]("Part")
-- Propriedades visuais
[Link] = [Link](4, 2, 1) -- Largura, altura, profundidade
[Link] = [Link](1, 0, 0) -- RGB de 0 a 1 (vermelho puro)
-- [Link](r, g, b) onde cada valor vai de 0 a 1
-- Ou usar BrickColor (cores pré-definidas)
[Link] = [Link]("Really red")
-- BrickColor tem nomes específicos como "Really red", "Bright blue"
-- Material afeta como a luz interage
[Link] = [Link] -- Vidro
-- Outros: Wood, Metal, Concrete, Fabric, etc.
-- Transparência (0 = opaco, 1 = invisível)
[Link] = 0.5 -- 50% transparente
-- Propriedades físicas
[Link] = true -- Não se move com física
[Link] = false -- Jogadores passam através
[Link] = true -- Não tem peso (não afeta outras partes)
Formas Especiais
lua
-- Sphere (esfera)
local esfera = [Link]("Part")
[Link] = [Link] -- Transforma em esfera
[Link] = [Link] -- Remove texturas das faces
[Link] = [Link]
-- Cylinder (cilindro)
local cilindro = [Link]("Part")
[Link] = [Link]
-- WedgePart (rampa triangular)
local rampa = [Link]("WedgePart")
[Link] = [Link](4, 2, 8)
MeshPart - Modelos Customizados
MeshPart permite usar modelos 3D complexos.
lua
local meshPart = [Link]("MeshPart")
[Link] = "rbxassetid://12345678" -- ID do modelo no catálogo
[Link] = "rbxassetid://87654321" -- ID da textura
-- IDs são números que identificam assets no Roblox
-- Escalar o mesh
[Link] = [Link](2, 2, 2) -- 2x maior que o original
SpecialMesh - Modificando Partes Normais
lua
local parte = [Link]("Part")
local mesh = [Link]("SpecialMesh")
[Link] = parte -- O mesh modifica a parte pai
[Link] = [Link] -- Tipo da mesh
[Link] = [Link](2, 1, 2) -- Escala diferente em cada eixo
-- Scale multiplica o tamanho: 2 = dobro, 0.5 = metade
⚡ Eventos e Conexões
Eventos são como notificações - quando algo específico acontece, seu código é executado.
Evento Touched - O Mais Usado
lua
local parte = [Link]
-- Conecta uma função ao evento Touched
local conexao = [Link]:Connect(function(hit)
-- hit = a parte que tocou na nossa parte
print("Algo tocou em mim:", [Link])
-- Verifica se foi um jogador que tocou
local humanoid = [Link]:FindFirstChildOfClass("Humanoid")
if humanoid then
-- [Link] seria o Character do jogador
local jogador = [Link]:GetPlayerFromCharacter([Link])
if jogador then
print("Jogador", [Link], "me tocou!")
end
end
end)
-- Desconectar o evento (importante para economia de memória)
-- conexao:Disconnect() -- Para de escutar o evento
Eventos de Clique
lua
local clickDetector = [Link]("ClickDetector")
[Link] = parte -- Precisa estar dentro de uma Part
[Link]:Connect(function(jogador)
print("Jogador", [Link], "clicou na parte!")
-- Exemplo: dar item ao jogador
local leaderstats = jogador:FindFirstChild("leaderstats")
if leaderstats then
local moedas = leaderstats:FindFirstChild("Coins")
if moedas then
[Link] = [Link] + 10 -- Adiciona 10 moedas
end
end
end)
-- Configurações do ClickDetector
[Link] = 50 -- Distância máxima para clicar
[Link] = "rbxasset://textures/[Link]" -- Cursor personalizado
ProximityPrompt - Interações Modernas
ProximityPrompt é a evolução do ClickDetector - mais bonito e funcional.
lua
local proximityPrompt = [Link]("ProximityPrompt")
[Link] = parte
-- Configurações
[Link] = "Pegar Item" -- Texto mostrado
[Link] = [Link].E -- Tecla para ativar
[Link] = 2 -- Tempo que precisa segurar (segundos)
-- Eventos do ProximityPrompt
[Link]:Connect(function(jogador)
print("Jogador", [Link], "usou o prompt!")
end)
[Link]:Connect(function(jogador)
print("Jogador começou a segurar...")
end)
[Link]:Connect(function(jogador)
print("Jogador parou de segurar...")
end)
Eventos Personalizados com RemoteEvents
Para comunicação entre servidor e cliente:
lua
-- No ReplicatedStorage, criar um RemoteEvent chamado "PlayerDamage"
-- SERVER SCRIPT
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PlayerDamage = ReplicatedStorage:WaitForChild("PlayerDamage")
-- Escuta pedidos dos clientes
[Link]:Connect(function(jogador, dano, posicao)
-- jogador = quem enviou o evento
-- dano, posicao = dados enviados
print("Jogador", [Link], "recebeu", dano, "de dano em", posicao)
-- Aplica dano
local character = [Link]
if character then
local humanoid = character:FindFirstChildOfClass("Humanoid")
if humanoid then
[Link] = [Link] - dano
end
end
end)
lua
-- LOCAL SCRIPT (cliente)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PlayerDamage = ReplicatedStorage:WaitForChild("PlayerDamage")
-- Envia evento para o servidor
PlayerDamage:FireServer(20, [Link](0, 5, 0))
-- Argumentos: dano=20, posição=(0,5,0)
🖼️ Interface Gráfica (GUI)
ScreenGui - A Tela do Jogador
ScreenGui é tipo uma tela transparente na frente do jogador onde você coloca elementos visuais.
lua
local screenGui = [Link]("ScreenGui")
[Link] = [Link]:WaitForChild("PlayerGui")
-- PlayerGui é onde ficam todas as interfaces do jogador
-- Propriedades importantes
[Link] = false -- Não desaparece quando jogador renasce
[Link] = [Link] -- Controle de camadas moderno
Frame - Container Básico
Frame é tipo uma caixa retangular onde você coloca outros elementos.
lua
local frame = [Link]("Frame")
[Link] = screenGui
-- Posição e tamanho com UDim2
[Link] = [Link](0, 300, 0, 200) -- Largura=300px, altura=200px
-- [Link](escalaX, offsetX, escalaY, offsetY)
-- escala = porcentagem da tela pai (0-1)
-- offset = pixels absolutos
[Link] = [Link](0.5, -150, 0.5, -100) -- Centro da tela
-- 0.5 = centro, -150 = metade da largura para centralizar perfeitamente
-- Aparência
frame.BackgroundColor3 = [Link](0, 0.5, 1) -- Azul
[Link] = 0 -- Remove borda
[Link] = 0.2 -- Levemente transparente
-- Cantos arredondados
local corner = [Link]("UICorner")
[Link] = frame
[Link] = [Link](0, 12) -- 12 pixels de raio
TextLabel - Mostrando Texto
lua
local textLabel = [Link]("TextLabel")
[Link] = frame
[Link] = [Link](1, 0, 0.3, 0) -- 100% da largura, 30% da altura do pai
[Link] = [Link](0, 0, 0, 0) -- Topo do frame
[Link] = "Bem-vindo ao jogo!"
textLabel.TextColor3 = [Link](1, 1, 1) -- Branco
[Link] = true -- Ajusta tamanho da fonte automaticamente
[Link] = [Link] -- Fonte moderna
[Link] = 1 -- Fundo invisível
TextButton - Botão Clicável
lua
local button = [Link]("TextButton")
[Link] = frame
[Link] = [Link](0.8, 0, 0.2, 0) -- 80% largura, 20% altura
[Link] = [Link](0.1, 0, 0.7, 0) -- 10% da esquerda, 70% de cima
[Link] = "Clique Aqui!"
button.TextColor3 = [Link](1, 1, 1)
button.BackgroundColor3 = [Link](0.2, 0.8, 0.2) -- Verde
-- Evento de clique
button.MouseButton1Click:Connect(function()
print("Botão foi clicado!")
-- Animação simples
button:TweenSize(
[Link](0.85, 0, 0.25, 0), -- Tamanho final
"Out", -- Direção da animação
"Quad", -- Estilo da animação
0.1, -- Duração em segundos
true -- Volta ao tamanho original
)
end)
-- Efeitos visuais
[Link]:Connect(function()
-- Quando mouse passa por cima
button.BackgroundColor3 = [Link](0.3, 0.9, 0.3) -- Verde mais claro
end)
[Link]:Connect(function()
-- Quando mouse sai de cima
button.BackgroundColor3 = [Link](0.2, 0.8, 0.2) -- Verde original
end)
ImageLabel e ImageButton - Usando Imagens
lua
local imageLabel = [Link]("ImageLabel")
[Link] = frame
[Link] = [Link](0.2, 0, 0.4, 0) -- Tamanho da imagem
[Link] = "rbxassetid://12345678" -- ID da imagem no Roblox
[Link] = 1 -- Remove fundo
-- ImageButton funciona igual, mas pode ser clicado
local imageButton = [Link]("ImageButton")
[Link] = frame
[Link] = "rbxassetid://87654321"
imageButton.MouseButton1Click:Connect(function()
print("Imagem clicada!")
end)
Layouts Automáticos
lua
-- UIListLayout - Organiza elementos em lista
local listLayout = [Link]("UIListLayout")
[Link] = frame
[Link] = [Link] -- Vertical ou Horizontal
[Link] = [Link] -- Centraliza
[Link] = [Link](0, 10) -- 10 pixels entre cada elemento
-- UIGridLayout - Organiza em grid
local gridLayout = [Link]("UIGridLayout")
[Link] = frame
[Link] = [Link](0, 100, 0, 100) -- Cada célula = 100x100px
[Link] = [Link](0, 5, 0, 5) -- 5px entre células
👥 Jogadores e Personagens
Players Service - Gerenciando Jogadores
lua
local Players = game:GetService("Players")
-- Eventos importantes
[Link]:Connect(function(jogador)
print("Jogador entrou:", [Link])
-- Configurações iniciais
[Link]:Connect(function(character)
print("Personagem de", [Link], "spawnou!")
-- Espera o Humanoid carregar
local humanoid = character:WaitForChild("Humanoid")
-- Personalizar o personagem
[Link] = 20 -- Velocidade de caminhada (padrão: 16)
[Link] = 60 -- Força do pulo (padrão: 50)
[Link] = 150 -- Vida máxima
[Link] = 150 -- Vida atual
-- Evento quando jogador morre
[Link]:Connect(function()
print([Link], "morreu!")
-- Código para quando jogador morre
end)
end)
-- Configurar leaderstats (placar)
local leaderstats = [Link]("Folder")
[Link] = "leaderstats"
[Link] = jogador
local coins = [Link]("IntValue")
[Link] = "Coins"
[Link] = 0
[Link] = leaderstats
local level = [Link]("IntValue")
[Link] = "Level"
[Link] = 1
[Link] = leaderstats
end)
[Link]:Connect(function(jogador)
print("Jogador saiu:", [Link])
-- Salvar dados do jogador aqui
end)
Manipulando Personagens
lua
-- Pegar jogador específico
local jogador = Players:FindFirstChild("NomeDoJogador")
if jogador and [Link] then
local character = [Link]
local humanoid = character:FindFirstChildOfClass("Humanoid")
local rootPart = character:FindFirstChild("HumanoidRootPart")
-- Teleportar jogador
if rootPart then
[Link] = [Link](0, 50, 0) -- Teleporta para (0, 50, 0)
end
-- Aplicar dano
if humanoid then
humanoid:TakeDamage(20) -- Remove 20 de vida
end
-- Curar jogador
[Link] = [Link] -- Cura completamente
-- Fazer jogador pular
[Link] = true
-- Mudanças visuais
local bodyColors = character:FindFirstChildOfClass("BodyColors")
if bodyColors then
[Link] = [Link]("Really red")
end
end
UserInputService - Controles do Jogador
lua
-- APENAS EM LOCAL SCRIPTS!
local UserInputService = game:GetService("UserInputService")
-- Detectar teclas pressionadas
[Link]:Connect(function(input, gameProcessed)
if gameProcessed then return end -- Ignora se estava digitando no chat
if [Link] == [Link].E then
print("Jogador pressionou E!")
-- Código para ação especial
elseif [Link] == [Link] then
print("Jogador pressionou espaço!")
-- Ação personalizada de pulo
end
end)
-- Detectar mouse
[Link]:Connect(function(input, gameProcessed)
if [Link] == [Link].MouseButton1 then
print("Clique esquerdo!")
elseif [Link] == [Link].MouseButton2 then
print("Clique direito!")
end
end)
-- Pegar posição do mouse
local mouse = [Link]:GetMouse()
print("Mouse está em:", mouse.X, mouse.Y) -- Posição na tela
print("Mouse está apontando para:", [Link]) -- Posição no mundo 3D
🔧 Serviços Essenciais
ReplicatedStorage - Compartilhando Assets
ReplicatedStorage é onde você coloca coisas que tanto servidor quanto cliente precisam acessar.
lua
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Criar RemoteEvents para comunicação
local remoteEvent = [Link]("RemoteEvent")
[Link] = "PlayerAction"
[Link] = ReplicatedStorage
-- ModuleScripts compartilhados
local configModule = [Link]("ModuleScript")
[Link] = "GameConfig"
[Link] = ReplicatedStorage
-- Conteúdo do GameConfig
local GameConfig = {
PlayerSpeed = 20,
JumpPower = 60,
StartingCoins = 100,
MaxHealth = 150
}
return GameConfig
ServerStorage vs ServerScriptService
lua
-- ServerStorage: assets que só o servidor precisa
-- - Mapas secretos
-- - Configurações sensíveis
-- - Tools especiais
-- ServerScriptService: onde ficam os scripts do servidor
-- Estrutura típica:
-- ServerScriptService
-- ├── PlayerManager (gerencia entrada/saída de jogadores)
-- ├── GameLogic (lógica principal do jogo)
-- ├── DataManager (salvar/carregar dados)
-- └── AntiCheat (proteção contra hackers)
local ServerStorage = game:GetService("ServerStorage")
local ServerScriptService = game:GetService("ServerScriptService")
-- Exemplo: sistema de spawn de itens
local itemSpawner = ServerStorage:WaitForChild("ItemSpawner")
function spawnRandomItem()
local items = itemSpawner:GetChildren() -- Pega todos os itens possíveis
local randomItem = items[[Link](1, #items)] -- Escolhe um aleatório
local clone = randomItem:Clone() -- Clona o item
[Link] = workspace -- Coloca no mundo
[Link] = [Link](
[Link](-50, 50), -- X aleatório
10, -- Y fixo (acima do chão)
[Link](-50, 50) -- Z aleatório
)
end
MarketplaceService - Robux e Game Passes
lua
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
-- IDs dos seus produtos (você define no site do Roblox)
local SPEED_GAMEPASS_ID = 123456789
local VIP_GAMEPASS_ID = 987654321
-- Verificar se jogador tem gamepass
function playerHasGamepass(jogador, gamepassId)
local success, hasPass = pcall(function()
return MarketplaceService:UserOwnsGamePassAsync([Link], gamepassId)
end)
if success then
return hasPass
else
warn("Erro ao verificar gamepass para", [Link])
return false
end
end
-- Usar quando jogador entra
[Link]:Connect(function(jogador)
-- Espera character carregar
[Link]:Connect(function(character)
local humanoid = character:WaitForChild("Humanoid")
-- Verifica gamepasses e aplica benefícios
if playerHasGamepass(jogador, SPEED_GAMEPASS_ID) then
[Link] = 32 -- Dobra a velocidade
print([Link], "tem speed gamepass!")
end
if playerHasGamepass(jogador, VIP_GAMEPASS_ID) then
-- Dar acesso a área VIP, skin especial, etc.
print([Link], "é VIP!")
end
end)
end)
-- Processar compras de produtos (Developer Products)
[Link] = function(receiptInfo)
-- receiptInfo contém informações da compra
local jogador = Players:GetPlayerByUserId([Link])
if [Link] == 111111111 then -- ID do produto "100 Moedas"
-- Adicionar moedas ao jogador
local leaderstats = jogador:FindFirstChild("leaderstats")
if leaderstats then
local coins = leaderstats:FindFirstChild("Coins")
if coins and [Link] >= preco then
-- Jogador pode comprar
[Link] = [Link] - preco
-- Dar item ao jogador (exemplo: tool)
local tool = [Link]:FindFirstChild(itemId):Clone()
[Link] = [Link]
-- Confirmar compra para o cliente
PlayerAction:FireClient(jogador, "compra_sucesso", {item = itemId})
else
-- Não tem dinheiro suficiente
PlayerAction:FireClient(jogador, "compra_falhou", {motivo = "Dinheiro insuficiente"})
end
end
elseif acao == "teleport_request" then
local destino = [Link]
if destino == "spawn" then
local character = [Link]
if character then
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if humanoidRootPart then
[Link] = [Link](0, 5, 0) -- Teleporta para spawn
end
end
end
end
end)
-- Enviar dados para TODOS os jogadores
PlayerAction:FireAllClients("server_message", {
texto = "Servidor reiniciará em 5 minutos!",
cor = [Link](1, 0, 0)
})
lua
-- LOCAL SCRIPT - Cliente envia pedidos e recebe respostas
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local PlayerAction = ReplicatedStorage:WaitForChild("PlayerAction")
local player = [Link]
-- Enviar pedido ao servidor
function comprarItem(itemId, preco)
PlayerAction:FireServer("comprar_item", {
itemId = itemId,
preco = preco
})
end
-- Escutar respostas do servidor
[Link]:Connect(function(acao, dados)
if acao == "compra_sucesso" then
print("Compra realizada! Item:", [Link])
-- Mostrar GUI de sucesso
elseif acao == "compra_falhou" then
print("Compra falhou:", [Link])
-- Mostrar mensagem de erro
elseif acao == "server_message" then
print("Servidor:", [Link])
-- Mostrar notificação na tela
end
end)
-- Exemplo de uso
local gui = [Link]
local buyButton = [Link]
buyButton.MouseButton1Click:Connect(function()
comprarItem("Sword", 100) -- Comprar espada por 100 moedas
end)
RemoteFunction - Comunicação com Retorno
RemoteFunction é como RemoteEvent, mas retorna uma resposta imediata.
lua
-- CRIAR NO REPLICATEDSTORAGE
local remoteFunction = [Link]("RemoteFunction")
[Link] = "GetPlayerInfo"
[Link] = [Link]
lua
-- SERVER SCRIPT
local GetPlayerInfo = ReplicatedStorage:WaitForChild("GetPlayerInfo")
-- Função que responde aos pedidos
[Link] = function(jogador, tipoInfo)
if tipoInfo == "stats" then
local leaderstats = jogador:FindFirstChild("leaderstats")
if leaderstats then
return {
coins = [Link],
level = [Link],
playtime = tick() - [Link]
}
end
elseif tipoInfo == "inventory" then
local backpack = [Link]
local items = {}
for _, tool in pairs(backpack:GetChildren()) do
if tool:IsA("Tool") then
[Link](items, [Link])
end
end
return {items = items}
end
return nil -- Retorna nil se não encontrar nada
end
lua
-- LOCAL SCRIPT
local GetPlayerInfo = ReplicatedStorage:WaitForChild("GetPlayerInfo")
-- Pedir informações (bloqueia até receber resposta)
local stats = GetPlayerInfo:InvokeServer("stats")
if stats then
print("Moedas:", [Link])
print("Level:", [Link])
print("Tempo jogado:", [Link], "segundos")
end
local inventory = GetPlayerInfo:InvokeServer("inventory")
if inventory then
print("Itens no inventário:")
for _, item in pairs([Link]) do
print("-", item)
end
end
BindableEvent e BindableFunction - Comunicação Local
Para comunicação entre scripts no mesmo contexto (servidor-servidor ou cliente-cliente).
lua
-- Script A (cria o BindableEvent)
local bindableEvent = [Link]("BindableEvent")
[Link] = "CustomEvent"
[Link] = [Link]
-- Disparar evento
bindableEvent:Fire("Hello", "World", 123)
lua
-- Script B (escuta o evento)
local bindableEvent = [Link]:WaitForChild("CustomEvent")
[Link]:Connect(function(arg1, arg2, arg3)
print("Recebi:", arg1, arg2, arg3) -- Saída: "Recebi: Hello World 123"
end)
Filtering Enabled e Segurança
IMPORTANTE: No Roblox, Filtering Enabled está sempre ativado. Isso significa:
Cliente não pode modificar o servidor diretamente
Todas as mudanças no servidor devem ser aprovadas pelo servidor
LocalScripts só rodam no cliente
ServerScripts só rodam no servidor
lua
-- ❌ ISSO NÃO FUNCIONA (LocalScript tentando mudar servidor)
[Link] = [Link]("Really red") -- Só o cliente vê
-- ✅ FORMA CORRETA
-- LocalScript envia pedido
local RemoteEvent = [Link]
RemoteEvent:FireServer("Really red")
-- ServerScript processa o pedido
[Link]:Connect(function(player, newColor)
-- Validar se jogador pode fazer isso
if playerCanChangeColors(player) then
[Link] = [Link](newColor) -- Todos veem
end
end)
📖 Exemplos Práticos Completos
Sistema de Loja Completo
lua
-- === SERVER SCRIPT ===
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Criar RemoteEvents
local buyItemEvent = [Link]("RemoteEvent")
[Link] = "BuyItem"
[Link] = ReplicatedStorage
local getShopDataFunction = [Link]("RemoteFunction")
[Link] = "GetShopData"
[Link] = ReplicatedStorage
-- Dados da loja
local SHOP_ITEMS = {
{id = "speed_boost", name = "Speed Boost", price = 50, duration = 30},
{id = "jump_boost", name = "Jump Boost", price = 30, duration = 20},
{id = "sword", name = "Epic Sword", price = 200, permanent = true},
{id = "heal", name = "Full Heal", price = 25, instant = true}
}
-- Função para dar item ao jogador
function giveItemToPlayer(player, itemData)
local character = [Link]
if not character then return false end
local humanoid = character:FindFirstChildOfClass("Humanoid")
if not humanoid then return false end
if [Link] == "speed_boost" then
[Link] = 32
-- Reverter depois do tempo
game:GetService("Debris"):AddItem([Link](function()
wait([Link])
if humanoid and [Link] then
[Link] = 16 -- Velocidade normal
end
end), 0)
return true
elseif [Link] == "jump_boost" then
[Link] = 100
game:GetService("Debris"):AddItem([Link](function()
wait([Link])
if humanoid and [Link] then
[Link] = 50 -- Pulo normal
end
end), 0)
return true
elseif [Link] == "sword" then
-- Verificar se já tem espada
if [Link]:FindFirstChild("Epic Sword") then
return false -- Já tem
end
local sword = [Link]:FindFirstChild("Epic Sword")
if sword then
local swordClone = sword:Clone()
[Link] = [Link]
return true
end
elseif [Link] == "heal" then
[Link] = [Link]
return true
end
return false
end
-- Processar compras
[Link]:Connect(function(player, itemId)
-- Encontrar item na loja
local itemData = nil
for _, item in pairs(SHOP_ITEMS) do
if [Link] == itemId then
itemData = item
break
end
end
if not itemData then
print("Item inválido:", itemId)
return
end
-- Verificar dinheiro do jogador
local leaderstats = player:FindFirstChild("leaderstats")
if not leaderstats then return end
local coins = leaderstats:FindFirstChild("Coins")
if not coins then return end
if [Link] < [Link] then
-- Enviar mensagem de erro para cliente
[Link]:FireClient(player, "Dinheiro insuficiente!", "Error")
return
end
-- Tentar dar o item
if giveItemToPlayer(player, itemData) then
-- Sucesso: cobrar o dinheiro
[Link] = [Link] - [Link]
[Link]:FireClient(player, "Compra realizada: " .. [Link], "Success")
print("Jogador", [Link], "comprou", [Link], "por", [Link], "moedas")
else
[Link]:FireClient(player, "Não foi possível dar o item", "Error")
end
end)
-- Enviar dados da loja para cliente
[Link] = function(player)
return SHOP_ITEMS
end
-- Sistema de mensagens
local showMessageEvent = [Link]("RemoteEvent")
[Link] = "ShowMessage"
[Link] = ReplicatedStorage
lua
-- === LOCAL SCRIPT ===
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local player = [Link]
local playerGui = player:WaitForChild("PlayerGui")
-- Aguardar RemoteEvents
local buyItemEvent = ReplicatedStorage:WaitForChild("BuyItem")
local getShopDataFunction = ReplicatedStorage:WaitForChild("GetShopData")
local showMessageEvent = ReplicatedStorage:WaitForChild("ShowMessage")
-- Criar GUI da loja
local screenGui = [Link]("ScreenGui")
[Link] = "ShopGui"
[Link] = playerGui
-- Frame principal da loja
local shopFrame = [Link]("Frame")
[Link] = "ShopFrame"
[Link] = [Link](0.6, 0, 0.8, 0)
[Link] = [Link](0.2, 0, 0.1, 0)
shopFrame.BackgroundColor3 = [Link](0.1, 0.1, 0.15)
[Link] = 0
[Link] = false
[Link] = screenGui
-- Cantos arredondados
local corner = [Link]("UICorner")
[Link] = [Link](0, 15)
[Link] = shopFrame
-- Título da loja
local titleLabel = [Link]("TextLabel")
[Link] = "Title"
[Link] = [Link](1, 0, 0.1, 0)
[Link] = [Link](0, 0, 0, 0)
[Link] = "🛍️ LOJA DO JOGO"
titleLabel.TextColor3 = [Link](1, 1, 1)
[Link] = true
[Link] = [Link]
[Link] = 1
[Link] = shopFrame
-- Container dos itens
local itemsFrame = [Link]("ScrollingFrame")
[Link] = "ItemsFrame"
[Link] = [Link](1, -20, 0.8, 0)
[Link] = [Link](0, 10, 0.1, 10)
[Link] = 1
[Link] = 0
[Link] = 8
[Link] = shopFrame
-- Layout dos itens
local listLayout = [Link]("UIListLayout")
[Link] = [Link](0, 10)
[Link] = itemsFrame
-- Botão fechar
local closeButton = [Link]("TextButton")
[Link] = "CloseButton"
[Link] = [Link](0.1, 0, 0.08, 0)
[Link] = [Link](0.9, 0, 0.02, 0)
[Link] = "✕"
closeButton.TextColor3 = [Link](1, 0.3, 0.3)
[Link] = true
[Link] = [Link]
[Link] = 1
[Link] = shopFrame
-- Função para criar item na loja
function createShopItem(itemData)
local itemFrame = [Link]("Frame")
[Link] = [Link](1, 0, 0, 80)
itemFrame.BackgroundColor3 = [Link](0.15, 0.15, 0.2)
[Link] = 0
[Link] = itemsFrame
local itemCorner = [Link]("UICorner")
[Link] = [Link](0, 8)
[Link] = itemFrame
-- Nome do item
local nameLabel = [Link]("TextLabel")
[Link] = [Link](0.5, 0, 0.5, 0)
[Link] = [Link](0.02, 0, 0, 0)
[Link] = [Link]
nameLabel.TextColor3 = [Link](1, 1, 1)
[Link] = true
[Link] = [Link]
[Link] = 1
[Link] = [Link]
[Link] = itemFrame
-- Preço
local priceLabel = [Link]("TextLabel")
[Link] = [Link](0.5, 0, 0.5, 0)
[Link] = [Link](0.02, 0, 0.5, 0)
[Link] = "💰 " .. [Link] .. " moedas"
priceLabel.TextColor3 = [Link](1, 0.8, 0)
[Link] = true
[Link] = [Link]
[Link] = 1
[Link] = [Link]
[Link] = itemFrame
-- Botão comprar
local buyButton = [Link]("TextButton")
[Link] = [Link](0.25, 0, 0.6, 0)
[Link] = [Link](0.7, 0, 0.2, 0)
[Link] = "COMPRAR"
buyButton.TextColor3 = [Link](1, 1, 1)
[Link] = true
[Link] = [Link]
buyButton.BackgroundColor3 = [Link](0.2, 0.7, 0.2)
[Link] = 0
[Link] = itemFrame
local buyCorner = [Link]("UICorner")
[Link] = [Link](0, 5)
[Link] = buyButton
-- Evento do botão
buyButton.MouseButton1Click:Connect(function()
-- Animação do botão
local tween = TweenService:Create(buyButton,
[Link](0.1, [Link]),
{Size = [Link](0.23, 0, 0.55, 0)}
)
tween:Play()
[Link]:Connect(function()
local tween2 = TweenService:Create(buyButton,
[Link](0.1, [Link]),
{Size = [Link](0.25, 0, 0.6, 0)}
)
tween2:Play()
end)
-- Enviar pedido de compra
buyItemEvent:FireServer([Link])
end)
-- Efeitos hover
[Link]:Connect(function()
TweenService:Create(buyButton,
[Link](0.2, [Link]),
{BackgroundColor3 = [Link](0.3, 0.8, 0.3)}
):Play()
end)
[Link]:Connect(function()
TweenService:Create(buyButton,
[Link](0.2, [Link]),
{BackgroundColor3 = [Link](0.2, 0.7, 0.2)}
):Play()
end)
end
-- Carregar itens da loja
function loadShopItems()
local shopData = getShopDataFunction:InvokeServer()
-- Limpar itens existentes
for _, child in pairs(itemsFrame:GetChildren()) do
if child:IsA("Frame") then
child:Destroy()
end
end
-- Criar novos itens
for _, itemData in pairs(shopData) do
createShopItem(itemData)
end
-- Ajustar tamanho do ScrollingFrame
[Link] = [Link](0, 0, 0, [Link].Y + 20)
end
-- Sistema de mensagens
local messageFrame = [Link]("Frame")
[Link] = "MessageFrame"
[Link] = [Link](0.4, 0, 0.1, 0)
[Link] = [Link](0.3, 0, -0.15, 0) -- Começa fora da tela
messageFrame.BackgroundColor3 = [Link](0.2, 0.2, 0.2)
[Link] = 0
[Link] = screenGui
local messageCorner = [Link]("UICorner")
[Link] = [Link](0, 10)
[Link] = messageFrame
local messageLabel = [Link]("TextLabel")
[Link] = [Link](1, -20, 1, -20)
[Link] = [Link](0, 10, 0, 10)
[Link] = ""
messageLabel.TextColor3 = [Link](1, 1, 1)
[Link] = true
[Link] = [Link]
[Link] = 1
[Link] = messageFrame
-- Função para mostrar mensagem
function showMessage(text, type)
[Link] = text
if type == "Success" then
messageFrame.BackgroundColor3 = [Link](0.2, 0.7, 0.2)
elseif type == "Error" then
messageFrame.BackgroundColor3 = [Link](0.7, 0.2, 0.2)
else
messageFrame.BackgroundColor3 = [Link](0.2, 0.2, 0.7)
end
-- Animação de entrada
local tweenIn = TweenService:Create(messageFrame,
[Link](0.3, [Link], [Link]),
{Position = [Link](0.3, 0, 0.05, 0)}
)
tweenIn:Play()
-- Animação de saída após 3 segundos
[Link]:Connect(function()
wait(3)
local tweenOut = TweenService:Create(messageFrame,
[Link](0.3, [Link], [Link]),
{Position = [Link](0.3, 0, -0.15, 0)}
)
tweenOut:Play()
end)
end
-- Eventos
closeButton.MouseButton1Click:Connect(function()
[Link] = false
end)
-- Escutar mensagens do servidor
[Link]:Connect(function(message, type)
showMessage(message, type)
end)
-- Tecla para abrir loja (exemplo: P)
local UserInputService = game:GetService("UserInputService")
[Link]:Connect(function(input, gameProcessed)
if gameProcessed then return end
if [Link] == [Link].P then
if [Link] then
[Link] = false
else
loadShopItems()
[Link] = true
end
end
end)
Sistema de Ranking/Leaderboard
lua
-- === SERVER SCRIPT ===
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- DataStores
local playerDataStore = DataStoreService:GetDataStore("PlayerData")
local leaderboardStore = DataStoreService:GetOrderedDataStore("Leaderboard")
-- RemoteFunction para leaderboard
local getLeaderboardFunction = [Link]("RemoteFunction")
[Link] = "GetLeaderboard"
[Link] = ReplicatedStorage
-- Função para atualizar score no leaderboard
function updateLeaderboard(player, newScore)
pcall(function()
leaderboardStore:SetAsync([Link], newScore)
end)
end
-- Função para obter top jogadores
function getTopPlayers(count)
local success, pages = pcall(function()
return leaderboardStore:GetSortedAsync(false, count or 10)
end)
if success then
local leaderboard = {}
local data = pages:GetCurrentPage()
for rank, entry in pairs(data) do
local userName = "Jogador Desconhecido"
pcall(function()
userName = Players:GetNameFromUserIdAsync([Link])
end)
[Link](leaderboard, {
rank = rank,
name = userName,
score = [Link],
userId = [Link]
})
end
return leaderboard
end
return {}
end
-- Carregar dados do jogador
function loadPlayerData(player)
local success, data = pcall(function()
return playerDataStore:GetAsync([Link])
end)
if success and data then
return data
else
return {
coins = 0,
level = 1,
totalScore = 0,
gamesPlayed = 0,
wins = 0
}
end
end
-- Salvar dados do jogador
function savePlayerData(player, data)
pcall(function()
playerDataStore:SetAsync([Link], data)
-- Também atualizar leaderboard
updateLeaderboard(player, [Link])
end)
end
-- Quando jogador entra
[Link]:Connect(function(player)
local data = loadPlayerData(player)
-- Criar leaderstats
local leaderstats = [Link]("Folder")
[Link] = "leaderstats"
[Link] = player
local coins = [Link]("IntValue")
[Link] = "Coins"
[Link] = [Link]
[Link] = leaderstats
local level = [Link]("IntValue")
[Link] = "Level"
[Link] = [Link]
[Link] = leaderstats
local totalScore = [Link]("IntValue")
[Link] = "Score"
[Link] = [Link]
[Link] = leaderstats
-- Salvar referência dos dados
player:SetAttribute("GamesPlayed", [Link])
player:SetAttribute("Wins", [Link])
print("Jogador", [Link], "entrou com", [Link], "pontos")
end)
-- Quando jogador sai
[Link]:Connect(function(player)
local leaderstats = player:FindFirstChild("leaderstats")
if leaderstats then
local data = {
coins = [Link],
level = [Link],
totalScore = [Link],
gamesPlayed = player:GetAttribute("GamesPlayed") or 0,
wins = player:GetAttribute("Wins") or 0
}
savePlayerData(player, data)
print("Dados salvos para", [Link])
end
end)
-- Função para adicionar pontos ao jogador
function addScore(player, points, reason)
local leaderstats = player:FindFirstChild("leaderstats")
if leaderstats then
local score = leaderstats:FindFirstChild("Score")
if score then
[Link] = [Link] + points
print("Jogador", [Link], "ganhou", points, "pontos por", reason)
-- Atualizar leaderboard imediatamente
updateLeaderboard(player, [Link])
end
end
end
-- Responder pedidos de leaderboard
[Link] = function(player)
return getTopPlayers(10) -- Top 10 jogadores
end)
-- Exemplo: sistema de pontuação por tocar em partes
local pontosPart = workspace:WaitForChild("PontosPart")
[Link]:Connect(function(hit)
local humanoid = [Link]:FindFirstChildOfClass("Humanoid")
if humanoid then
local player = Players:GetPlayerFromCharacter([Link])
if player then
addScore(player, 10, "tocar na parte especial")
end
end
end)
lua
-- === LOCAL SCRIPT (GUI do Leaderboard) ===
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local player = [Link]
local playerGui = player:WaitForChild("PlayerGui")
-- Aguardar RemoteFunction
local getLeaderboardFunction = ReplicatedStorage:WaitForChild("GetLeaderboard")
-- Criar GUI do leaderboard
local screenGui = [Link]("ScreenGui")
[Link] = "LeaderboardGui"
[Link] = playerGui
-- Frame do leaderboard
local leaderboardFrame = [Link]("Frame")
[Link] = "LeaderboardFrame"
[Link] = [Link](0.35, 0, 0.7, 0)
[Link] = [Link](0.02, 0, 0.15, 0)
leaderboardFrame.BackgroundColor3 = [Link](0.1, 0.1, 0.15)
[Link] = 0
[Link] = screenGui
-- Cantos arredondados
local corner = [Link]("UICorner")
[Link] = [Link](0, 12)
[Link] = leaderboardFrame
-- Título
local titleLabel = [Link]("TextLabel")
[Link] = "Title"
[Link] = [Link](1, 0, 0.1, 0)
[Link] = [Link](0, 0, 0, 0)
[Link] = "🏆 TOP JOGADORES"
titleLabel.TextColor3 = [Link](1, 0.8, 0)
[Link] = true
[Link] = [Link]
[Link] = 1
[Link] = leaderboardFrame
-- Container dos rankings
local rankingsFrame = [Link]("ScrollingFrame")
[Link] = "RankingsFrame"
[Link] = [Link](1, -10, 0.85, 0)
[Link] = [Link](0, 5, 0.1, 5)
[Link] = 1
[Link] = 0
[Link] = 6
[Link] = leaderboardFrame
-- Layout dos rankings
local listLayout = [Link]("UIListLayout")
[Link] = [Link](0, 5)
[Link] = rankingsFrame
-- Função para criar entrada no ranking
function createRankEntry(rankData, playerUserId)
local isCurrentPlayer = ([Link] == playerUserId)
local entryFrame = [Link]("Frame")
[Link] = [Link](1, -10, 0, 40)
entryFrame.BackgroundColor3 = isCurrentPlayer and [Link](0.3, 0.5, 0.8) or [Link](0.15, 0.15, 0.2)
[Link] = 0
[Link] = rankingsFrame
local entryCorner = [Link]("UICorner")
[Link] = [Link](0, 6)
[Link] = entryFrame
-- Posição no ranking
local rankLabel = [Link]("TextLabel")
[Link] = [Link](0.15, 0, 1, 0)
[Link] = [Link](0, 0, 0, 0)
[Link] = "#" .. [Link]
rankLabel.TextColor3 = getRankColor([Link])
[Link] = true
[Link] = [Link]
[Link] = 1
[Link] = entryFrame
-- Nome do jogador
local nameLabel = [Link]("TextLabel")
[Link] = [Link](0.5, 0, 1, 0)
[Link] = [Link](0.15, 0, 0, 0)
[Link] = [Link]
nameLabel.TextColor3 = isCurrentPlayer and [Link](1, 1, 0) or [Link](1, 1, 1)
[Link] = true
[Link] = isCurrentPlayer and [Link] or [Link]
[Link] = 1
[Link] = [Link]
[Link] = entryFrame
-- Pontuação
local scoreLabel = [Link]("TextLabel")
[Link] = [Link](0.35, 0, 1, 0)
[Link] = [Link](0.65, 0, 0, 0)
[Link] = formatNumber([Link]) .. " pts"
scoreLabel.TextColor3 = [Link](0.8, 1, 0.8)
[Link] = true
[Link] = [Link]
[Link] = 1
[Link] = [Link]
[Link] = entryFrame
return entryFrame
end
-- Função para obter cor baseada na posição
function getRankColor(rank)
if rank == 1 then
return [Link](1, 0.8, 0) -- Ouro
elseif rank == 2 then
return [Link](0.8, 0.8, 0.8) -- Prata
elseif rank == 3 then
return [Link](0.8, 0.5, 0.2) -- Bronze
else
return [Link](0.6, 0.6, 0.6) -- Cinza
end
end
-- Função para formatar números grandes
function formatNumber(num)
if num >= 1000000 then
return [Link]("%.1fM", num / 1000000)
elseif num >= 1000 then
return [Link]("%.1fK", num / 1000)
else
return tostring(num)
end
end
-- Função para atualizar leaderboard
function updateLeaderboard()
-- Limpar entradas existentes
for _, child in pairs(rankingsFrame:GetChildren()) do
if child:IsA("Frame") then
child:Destroy()
end
end
-- Obter dados do servidor
local leaderboardData = getLeaderboardFunction:InvokeServer()
-- Criar novas entradas
for _, rankData in pairs(leaderboardData) do
createRankEntry(rankData, [Link])
end
-- Ajustar tamanho do ScrollingFrame
[Link] = [Link](0, 0, 0, [Link].Y + 10)
end
-- Atualizar leaderboard periodicamente
spawn(function()
while true do
updateLeaderboard()
wait(10) -- Atualiza a cada 10 segundos
end
end)
-- Atualização inicial
updateLeaderboard()
Sistema de Spawner de Inimigos
lua
-- === SERVER SCRIPT ===
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local PathfindingService = game:GetService("PathfindingService")
local Players = game:GetService("Players")
-- Configurações dos inimigos
local ENEMY_CONFIGS = {
basic = {
name = "Zumbi Básico",
health = 100,
speed = 12,
damage = 20,
reward = 50,
model = "Zombie",
color = [Link](0.3, 0.8, 0.3)
},
fast = {
name = "Corredor Rápido",
health = 50,
speed = 20,
damage = 15,
reward = 75,
model = "FastZombie",
color = [Link](0.8, 0.8, 0.3)
},
tank = {
name = "Tanque Pesado",
health = 300,
speed = 8,
damage = 40,
reward = 150,
model = "TankZombie",
color = [Link](0.8, 0.3, 0.3)
}
}
-- Pontos de spawn
local spawnPoints = {
[Link](-50, 5, -50),
[Link](50, 5, -50),
[Link](-50, 5, 50),
[Link](50, 5, 50)
}
-- Lista de inimigos ativos
local activeEnemies = {}
local enemyCount = 0
local maxEnemies = 20
-- RemoteEvent para sincronizar mortes
local enemyDefeatedEvent = [Link]("RemoteEvent")
[Link] = "EnemyDefeated"
[Link] = ReplicatedStorage
-- Função para criar inimigo
function createEnemy(enemyType, spawnPosition)
local config = ENEMY_CONFIGS[enemyType]
if not config then return nil end
-- Criar modelo do inimigo
local enemy = [Link]("Model")
[Link] = [Link]
[Link] = workspace
-- Parte principal (corpo)
local body = [Link]("Part")
[Link] = "Body"
[Link] = [Link](2, 4, 1)
[Link] = spawnPosition
[Link] = [Link]("Medium stone grey")
[Link] = [Link]
[Link] = false
[Link] = enemy
-- Humanoid para movimento
local humanoid = [Link]("Humanoid")
[Link] = [Link]
[Link] = [Link]
[Link] = [Link]
[Link] = 0 -- Inimigos não pulam
[Link] = enemy
-- HumanoidRootPart para pathfinding
local rootPart = [Link]("Part")
[Link] = "HumanoidRootPart"
[Link] = [Link](2, 2, 1)
[Link] = spawnPosition
[Link] = 1
[Link] = false
[Link] = false
[Link] = enemy
-- Conectar partes
local weld = [Link]("WeldConstraint")
weld.Part0 = rootPart
weld.Part1 = body
[Link] = body
-- Cabeça para visual
local head = [Link]("Part")
[Link] = "Head"
[Link] = [Link](1.5, 1.5, 1.5)
[Link] = [Link]
[Link] = [Link]("Bright green")
[Link] = [Link]
[Link] = false
[Link] = enemy
-- Conectar cabeça ao corpo
local headWeld = [Link]("WeldConstraint")
headWeld.Part0 = body
headWeld.Part1 = head
[Link] = head
-- Posicionar cabeça
local headAttachment = [Link]("Attachment")
[Link] = [Link](0, 2.75, 0) -- Em cima do corpo
[Link] = body
local headAttachment2 = [Link]("Attachment")
[Link] = head
local alignPos = [Link]("AlignPosition")
alignPos.Attachment0 = headAttachment2
alignPos.Attachment1 = headAttachment
[Link] = 4000
[Link] = 200
[Link] = head
-- Sistema de dano
local damageBox = [Link]("Part")
[Link] = "DamageBox"
[Link] = [Link](3, 4, 3) -- Área de dano
[Link] = spawnPosition
[Link] = 1
[Link] = false
[Link] = enemy
local damageWeld = [Link]("WeldConstraint")
damageWeld.Part0 = rootPart
damageWeld.Part1 = damageBox
[Link] = damageBox
-- Detectar jogadores próximos
local lastDamageTime = {}
[Link]:Connect(function(hit)
local character = [Link]
local humanoidHit = character:FindFirstChildOfClass("Humanoid")
if humanoidHit and character ~= enemy then
local player = Players:GetPlayerFromCharacter(character)
if player then
local currentTime = tick()
local lastTime = lastDamageTime[[Link]] or 0
if currentTime - lastTime >= 1 then -- Dano a cada 1 segundo
lastDamageTime[[Link]] = currentTime
humanoidHit:TakeDamage([Link])
print("Inimigo causou", [Link], "de dano em", [Link])
end
end
end
end)
-- Configurar atributos personalizados
enemy:SetAttribute("EnemyType", enemyType)
enemy:SetAttribute("Reward", [Link])
enemy:SetAttribute("MaxHealth", [Link])
-- Adicionar à lista de inimigos ativos
[Link](activeEnemies, enemy)
enemyCount = enemyCount + 1
-- Configurar morte do inimigo
[Link]:Connect(function()
-- Remover da lista de inimigos
for i, activeEnemy in pairs(activeEnemies) do
if activeEnemy == enemy then
[Link](activeEnemies, i)
break
end
end
enemyCount = enemyCount - 1
-- Efeito de morte (explosão simples)
local explosion = [Link]("Explosion")
[Link] = [Link]
[Link] = 5
[Link] = 0 -- Não empurra outros objetos
[Link] = workspace
-- Dar recompensa ao jogador que matou (se houver)
-- (Implementação simplificada - normalmente você rastrearia quem causou o dano)
local nearestPlayer = findNearestPlayer([Link])
if nearestPlayer then
giveReward(nearestPlayer, [Link])
end
-- Remover inimigo após pequeno delay
game:GetService("Debris"):AddItem(enemy, 2)
end)
return enemy
end
-- Função para encontrar jogador mais próximo
function findNearestPlayer(position)
local nearestPlayer = nil
local nearestDistance = [Link]
for _, player in pairs(Players:GetPlayers()) do
if [Link] and [Link]:FindFirstChild("HumanoidRootPart") then
local distance = ([Link] - position).Magnitude
if distance < nearestDistance and distance < 50 then -- Dentro de 50 studs
nearestDistance = distance
nearestPlayer = player
end
end
end
return nearestPlayer
end
-- Função para dar recompensa
function giveReward(player, amount)
local leaderstats = player:FindFirstChild("leaderstats")
if leaderstats then
local coins = leaderstats:FindFirstChild("Coins")
if coins then
[Link] = [Link] + amount
print("Jogador", [Link], "ganhou", amount, "moedas!")
-- Notificar cliente
enemyDefeatedEvent:FireClient(player, amount)
end
end
end
-- AI simples para perseguir jogadores
function updateEnemyAI(enemy)
local humanoid = enemy:FindFirstChildOfClass("Humanoid")
local rootPart = enemy:FindFirstChild("HumanoidRootPart")
if not humanoid or not rootPart or [Link] <= 0 then
return
end
-- Encontrar jogador mais próximo
local targetPlayer = nil
local nearestDistance = [Link]
for _, player in pairs(Players:GetPlayers()) do
if [Link] and [Link]:FindFirstChild("HumanoidRootPart") then
local distance = ([Link] - [Link]).Magnitude
if distance < nearestDistance then
nearestDistance = distance
targetPlayer = player
end
end
end
-- Se encontrou um alvo e está próximo o suficiente
if targetPlayer and nearestDistance < 100 then
local targetPosition = [Link]
-- Usar pathfinding para navegar
local path = PathfindingService:CreatePath({
AgentRadius = 2,
AgentHeight = 5,
AgentCanJump = false
})
local success, errorMessage = pcall(function()
path:ComputeAsync([Link], targetPosition)
end)
if success then
local waypoints = path:GetWaypoints()
if #waypoints > 1 then
-- Mover para o próximo waypoint
humanoid:MoveTo(waypoints[2].Position)
else
-- Path muito curto, mover diretamente
humanoid:MoveTo(targetPosition)
end
else
-- Fallback: mover diretamente
humanoid:MoveTo(targetPosition)
end
else
-- Nenhum alvo próximo, ficar parado ou patrulhar
if [Link]() < 0.1 then -- 10% de chance por update
local randomDirection = [Link](
[Link](-20, 20),
0,
[Link](-20, 20)
)
humanoid:MoveTo([Link] + randomDirection)
end
end
end
-- Loop principal de spawn
spawn(function()
while true do
-- Spawnar novos inimigos se necessário
if enemyCount < maxEnemies then
local spawnChance = [Link]()
if spawnChance < 0.6 then -- 60% chance
createEnemy("basic", spawnPoints[[Link](1, #spawnPoints)])
elseif spawnChance < 0.85 then -- 25% chance
createEnemy("fast", spawnPoints[[Link](1, #spawnPoints)])
else -- 15% chance
createEnemy("tank", spawnPoints[[Link](1, #spawnPoints)])
end
end
wait(3) -- Spawn a cada 3 segundos
end
end)
-- Loop de AI
spawn(function()
while true do
for _, enemy in pairs(activeEnemies) do
if [Link] then -- Verificar se ainda existe
updateEnemyAI(enemy)
end
end
wait(0.5) -- Update AI a cada 0.5 segundos
end
end)
print("Sistema de spawner de inimigos iniciado!")
📚 Dicas Avançadas e Melhores Práticas
Otimização de Performance
lua
-- ✅ BOM: Usar :WaitForChild() para aguardar objetos
local part = workspace:WaitForChild("ImportantPart")
-- ❌ RUIM: Loop infinito desperdiça recursos
while not workspace:FindFirstChild("ImportantPart") do
wait()
end
-- ✅ BOM: Desconectar eventos não utilizados
local connection = [Link]:Connect(function() end)
connection:Disconnect() -- Libera memória
-- ❌ RUIM: Deixar eventos conectados sem necessidade
[Link]:Connect(function() end) -- Conexão nunca é removida
-- ✅ BOM: Usar pcall() para operações que podem falhar
local success, result = pcall(function()
return DataStore:GetAsync(key)
end)
if success then
print("Dados carregados:", result)
else
warn("Erro ao carregar dados:", result)
end
-- ✅ BOM: Agrupar mudanças de propriedades
local part = [Link]("Part")
[Link] = [Link](4, 2, 1)
[Link] = [Link](0, 5, 0)
[Link] = [Link]("Really red")
[Link] = workspace -- Só adiciona ao mundo no final
-- ❌ RUIM: Adicionar ao mundo muito cedo
local part = [Link]("Part")
[Link] = workspace -- Já está sendo renderizado
[Link] = [Link](4, 2, 1) -- Cada mudança força re-render
[Link] = [Link](0, 5, 0)
Padrões Úteis
Singleton Pattern (Uma Instância Só)
lua
-- ModuleScript: GameManager
local GameManager = {}
local instance = nil
function [Link]()
if not instance then
instance = {
players = {},
gameState = "waiting",
roundTime = 0
}
end
return instance
end
function [Link]()
local manager = [Link]()
[Link] = "playing"
print("Jogo iniciado!")
end
return GameManager
-- Usar em outros scripts:
local GameManager = require([Link])
local manager = [Link]()
print("Estado do jogo:", [Link])
Observer Pattern (Sistema de Notificações)
lua
-- ModuleScript: EventSystem
local EventSystem = {}
local events = {}
function [Link](eventName, callback)
if not events[eventName] then
events[eventName] = {}
end
[Link](events[eventName], callback)
end
function [Link](eventName, ...)
local eventCallbacks = events[eventName]
if eventCallbacks then
for _, callback in pairs(eventCallbacks) do
callback(...)
end
end
end
return EventSystem
-- Uso:
local EventSystem = require([Link])
-- Registrar observador
[Link]("PlayerDied", function(player, cause)
print("Jogador", [Link], "morreu por", cause)
end)
-- Disparar evento
[Link]("PlayerDied", somePlayer, "queda")
Depuração (Debugging)
lua
-- Sistema de logs com níveis
local LogLevel = {
DEBUG = 1,
INFO = 2,
WARN = 3,
ERROR = 4
}
local currentLogLevel = [Link]
function log(level, message, ...)
if level >= currentLogLevel then
local prefix = {"[DEBUG]", "[INFO]", "[WARN]", "[ERROR]"}
print(prefix[level], message, ...)
end
end
-- Uso:
log([Link], "Jogador entrou na zona:", [Link])
log([Link], "Falha ao salvar dados para:", [Link])
-- Profiling simples
local startTime = tick()
-- ... código a ser medido ...
local endTime = tick()
log([Link], "Operação levou:", endTime - startTime, "segundos")
Estrutura de Projeto Recomendada
ServerScriptService/
├── Core/
│ ├── [Link]
│ ├── [Link]
│ └── [Link]
├── Systems/
│ ├── [Link]
│ ├── [Link]
│ └── [Link]
└── Utils/
├── [Link]
└── [Link]
StarterPlayer/StarterPlayerScripts/
├── UI/
│ ├── [Link]
│ ├── [Link]
│ └── [Link]
├── Systems/
│ ├── [Link]
│ ├── [Link]
│ └── [Link]
└── Utils/
└── [Link]
ReplicatedStorage/
├── Modules/
│ ├── [Link]
│ ├── [Link]
│ └── [Link]
└── Events/
├── [Link]
├── [Link]
└── [Link]
🎯 Conclusão
Parabéns! 🎉 Você chegou ao final deste guia completo da API do Roblox!
O que você aprendeu:
1. Fundamentos: Instance, CFrame, Vector3, e como tudo se conecta
2. Scripting: Diferenças entre ServerScript, LocalScript e ModuleScript
3. Objetos 3D: Parts, MeshParts, e como manipulá-los
4. Eventos: Como fazer objetos reagirem a interações
5. Interface: Criar GUIs bonitas e funcionais
6. Jogadores: Gerenciar personagens e dados
7. Serviços: MarketplaceService, DataStores, TweenService
8. Física: Constraints e movimento realista
9. Networking: Comunicação cliente-servidor segura
10. Projetos Completos: Exemplos do mundo real
Próximos Passos:
Pratique muito! A programação se aprende fazendo
Entre na comunidade do Roblox Developer Forum
Estude jogos famosos para ver como foram feitos
Experimente com diferentes tipos de jogos
Não tenha medo de errar - todo dev já quebrou um projeto mil vezes!
Recursos Importantes:
Developer Hub: [Link]
API Reference: [Link]
DevForum: [Link]
Roblox Studio: Sua principal ferramenta de desenvolvimento
Lembre-se:
"O melhor código não é o mais complexo, é o mais fácil de entender e manter!"
Agora vai lá e cria jogos incríveis! 🚀
Este PDF foi criado com ❤️ para a comunidade de desenvolvedores Roblox
Versão 1.0 - 2025Coins") if coins then [Link] = [Link] + 100 return
[Link] end end end
return [Link]
end
---
## 💾 DataStores - Salvando Dados
**DataStores** salvam dados dos jogadores entre sessões (tipo um banco de dados).
### DataStore Básico
```lua
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
-- Criar/acessar um DataStore
local playerDataStore = DataStoreService:GetDataStore("PlayerData")
-- "PlayerData" é o nome do banco - você escolhe
-- Função para carregar dados do jogador
function loadPlayerData(jogador)
local success, data = pcall(function()
return playerDataStore:GetAsync([Link]) -- UserId como chave única
end)
if success then
return data or { -- Se data é nil, usa valores padrão
Coins = 0,
Level = 1,
Experience = 0,
Inventory = {}
}
else
warn("Erro ao carregar dados de", [Link])
return { -- Retorna dados padrão se falhou
Coins = 0,
Level = 1,
Experience = 0,
Inventory = {}
}
end
end
-- Função para salvar dados
function savePlayerData(jogador, data)
local success = pcall(function()
playerDataStore:SetAsync([Link], data)
end)
if success then
print("Dados salvos para", [Link])
else
warn("ERRO: Falha ao salvar dados de", [Link])
end
end
-- Carregar dados quando jogador entra
[Link]:Connect(function(jogador)
local data = loadPlayerData(jogador)
-- Criar leaderstats com dados carregados
local leaderstats = [Link]("Folder")
[Link] = "leaderstats"
[Link] = jogador
local coins = [Link]("IntValue")
[Link] = "Coins"
[Link] = [Link]
[Link] = leaderstats
local level = [Link]("IntValue")
[Link] = "Level"
[Link] = [Link]
[Link] = leaderstats
-- Salvar referência dos dados no jogador (para fácil acesso)
local dataValue = [Link]("Folder")
[Link] = "Data"
[Link] = jogador
-- Salvar periodicamente (a cada 5 minutos)
spawn(function()
while [Link] do -- Enquanto jogador estiver no jogo
wait(300) -- 5 minutos
local currentData = {
Coins = [Link],
Level = [Link],
Experience = [Link], -- Assumindo que não muda
Inventory = [Link]
}
savePlayerData(jogador, currentData)
end
end)
end)
-- Salvar quando jogador sai
[Link]:Connect(function(jogador)
local leaderstats = jogador:FindFirstChild("leaderstats")
if leaderstats then
local data = {
Coins = [Link],
Level = [Link],
Experience = 0, -- Você adicionaria lógica para isso
Inventory = {} -- E para isso também
}
savePlayerData(jogador, data)
end
end)
OrderedDataStore - Rankings
lua
-- Para criar leaderboards/rankings
local orderedStore = DataStoreService:GetOrderedDataStore("Leaderboard")
-- Salvar pontuação (maior = melhor)
function saveScore(jogador, pontuacao)
pcall(function()
orderedStore:SetAsync([Link], pontuacao)
end)
end
-- Pegar top 10 jogadores
function getTopPlayers()
local success, pages = pcall(function()
return orderedStore:GetSortedAsync(false, 10) -- false = maior primeiro
end)
if success then
local topPlayers = {}
local data = pages:GetCurrentPage()
for rank, entry in pairs(data) do
-- [Link] = UserId do jogador
-- [Link] = pontuação
local userName = "Jogador Desconhecido"
pcall(function()
userName = Players:GetNameFromUserIdAsync([Link])
end)
[Link](topPlayers, {
rank = rank,
name = userName,
score = [Link]
})
end
return topPlayers
end
return {}
end
🎬 Tweening e Animações
TweenService cria animações suaves para propriedades dos objetos.
TweenService Básico
lua
local TweenService = game:GetService("TweenService")
local parte = [Link]
-- Informações da animação
local tweenInfo = [Link](
2, -- Duração (segundos)
[Link], -- Estilo da animação
[Link], -- Direção (In, Out, InOut)
0, -- Repetições (0 = não repete, -1 = infinito)
false, -- Vai e volta (reverses)
0 -- Delay antes de começar
)
-- Propriedades finais (onde queremos chegar)
local goal = {
Position = [Link](0, 50, 0), -- Posição final
Color = [Link](1, 0, 0), -- Cor final (vermelho)
Transparency = 0.5, -- Transparência final
Size = [Link](8, 4, 2) -- Tamanho final
}
-- Criar e tocar a animação
local tween = TweenService:Create(parte, tweenInfo, goal)
tween:Play()
-- Eventos da animação
[Link]:Connect(function()
print("Animação terminou!")
-- Fazer algo quando acabar
end)
Estilos de Animação (EasingStyle)
lua
-- Diferentes estilos criam sensações diferentes:
-- Linear: velocidade constante (robótico)
[Link]
-- Quad: aceleração suave (natural)
[Link]
-- Cubic: aceleração mais pronunciada
[Link]
-- Back: ultrapassa o destino e volta (elástico)
[Link]
-- Bounce: quica no final
[Link]
-- Elastic: efeito mola
[Link]
Animações de GUI
lua
local screenGui = [Link]:WaitForChild("PlayerGui"):WaitForChild("ScreenGui")
local frame = screenGui:WaitForChild("Frame")
-- Animação de entrada (slide from left)
[Link] = [Link](-1, 0, 0.5, -100) -- Começa fora da tela
local slideInInfo = [Link](0.5, [Link], [Link])
local slideInTween = TweenService:Create(frame, slideInInfo, {
Position = [Link](0.5, -150, 0.5, -100) -- Posição final (centro)
})
slideInTween:Play()
-- Animação de hover em botão
local button = frame:WaitForChild("Button")
[Link]:Connect(function()
local hoverTween = TweenService:Create(button,
[Link](0.2, [Link], [Link]),
{
Size = [Link](0.85, 0, 0.25, 0), -- Cresce 5%
BackgroundColor3 = [Link](0.3, 0.9, 0.3) -- Cor mais clara
}
)
hoverTween:Play()
end)
[Link]:Connect(function()
local unhoverTween = TweenService:Create(button,
[Link](0.2, [Link], [Link]),
{
Size = [Link](0.8, 0, 0.2, 0), -- Tamanho original
BackgroundColor3 = [Link](0.2, 0.8, 0.2) -- Cor original
}
)
unhoverTween:Play()
end)
Animações em Cadeia
lua
-- Criar sequência de animações
local parte = [Link]
-- Primeira animação: mover para cima
local moveUpTween = TweenService:Create(parte,
[Link](1, [Link], [Link]),
{ Position = [Link](0, 20, 0) }
)
-- Segunda animação: mudar cor
local colorTween = TweenService:Create(parte,
[Link](0.5, [Link]),
{ Color = [Link](1, 0, 0) }
)
-- Terceira animação: mover para baixo
local moveDownTween = TweenService:Create(parte,
[Link](1, [Link], [Link]),
{ Position = [Link](0, 5, 0) }
)
-- Executar em sequência
moveUpTween:Play()
[Link]:Connect(function()
colorTween:Play()
end)
[Link]:Connect(function()
moveDownTween:Play()
end)
[Link]:Connect(function()
print("Sequência completa!")
end)
🔊 Audio e Efeitos Visuais
Sound - Reproduzindo Áudio
lua
-- Criar um som
local sound = [Link]("Sound")
[Link] = workspace -- Ou em qualquer parte para som 3D
-- Configurar propriedades
[Link] = "rbxassetid://12345678" -- ID do áudio no Roblox
[Link] = 0.5 -- Volume (0-1)
[Link] = 1 -- Tom (0.5 = mais grave, 2 = mais agudo)
[Link] = false -- Se deve repetir
[Link] = 10 -- Tamanho da área de som (para som 3D)
-- Controlar reprodução
sound:Play() -- Toca o som
sound:Pause() -- Pausa
sound:Resume() -- Continua de onde parou
sound:Stop() -- Para e volta ao início
-- Eventos
[Link]:Connect(function()
print("Som terminou!")
sound:Destroy() -- Remove da memória
end)
-- Som ambiente (música de fundo)
local musicSound = [Link]("Sound")
[Link] = workspace
[Link] = "rbxassetid://87654321"
[Link] = 0.3
[Link] = true
musicSound:Play()
SoundService - Configurações Globais
lua
local SoundService = game:GetService("SoundService")
-- Volume geral do jogo
[Link] = 0.8 -- 80% do volume
-- Configurações de ambiente
[Link] = [Link] -- Eco de caverna
[Link] = 3.33 -- Como som diminui com distância
[Link] = 1 -- Taxa de diminuição do som
ParticleEmitter - Efeitos de Partículas
lua
local parte = [Link]
-- Criar emissor de partículas
local particles = [Link]("ParticleEmitter")
[Link] = parte
-- Configurações básicas
[Link] = true -- Liga/desliga o emissor
-- Textura das partículas
[Link] = "rbxassetid://241650934" -- ID da imagem
-- Quantidade e velocidade
[Link] = 50 -- Partículas por segundo
[Link] = [Link](1, 3) -- Vida útil (1-3 segundos)
-- Movimento
[Link] = [Link](5, 10) -- Velocidade inicial
[Link] = [Link](45, 45) -- Ângulo de dispersão
[Link] = [Link](0, -10, 0) -- Gravidade personalizada
-- Aparência
[Link] = [Link]{
[Link](0, 0), -- Começa pequeno (0% da vida)
[Link](0.5, 1), -- Cresce no meio (50% da vida)
[Link](1, 0) -- Diminui no final (100% da vida)
}
[Link] = [Link]{
[Link](0, 0), -- Começa opaco
[Link](1, 1) -- Termina transparente
}
-- Cor ao longo da vida
[Link] = [Link]{
[Link](0, [Link](1, 1, 0)), -- Amarelo no início
[Link](0.5, [Link](1, 0.5, 0)), -- Laranja no meio
[Link](1, [Link](1, 0, 0)) -- Vermelho no final
}
-- Controlar o emissor
[Link] = false -- Desliga
particles:Clear() -- Remove partículas existentes
particles:Emit(10) -- Emite 10 partículas de uma vez
Fire, Smoke e Sparkles - Efeitos Clássicos
lua
local parte = [Link]
-- Fogo
local fire = [Link]("Fire")
[Link] = parte
[Link] = 5 -- Tamanho das chamas
[Link] = 10 -- Altura das chamas
[Link] = [Link](0, 1, 0) -- Fogo verde
[Link] = [Link](0, 0.5, 0) -- Cor secundária
-- Fumaça
local smoke = [Link]("Smoke")
[Link] = parte
[Link] = 3 -- Densidade da fumaça
[Link] = 1 -- Velocidade de subida
[Link] = [Link](0.2, 0.2, 0.2) -- Cor da fumaça
-- Brilhos
local sparkles = [Link]("Sparkles")
[Link] = parte
[Link] = [Link](1, 1, 0) -- Cor dos brilhos
Beam - Raios Laser
lua
-- Beam conecta duas partes com um raio visual
local parteA = [Link]
local parteB = [Link]
-- Criar Attachments (pontos de conexão)
local attachA = [Link]("Attachment")
[Link] = parteA
local attachB = [Link]("Attachment")
[Link] = parteB
-- Criar o Beam
local beam = [Link]("Beam")
[Link] = workspace
beam.Attachment0 = attachA -- Ponto inicial
beam.Attachment1 = attachB -- Ponto final
-- Configurar aparência
beam.Width0 = 1 -- Largura no início
beam.Width1 = 1 -- Largura no final
[Link] = [Link]([Link](0, 0.5, 1)) -- Azul
[Link] = [Link](0.3) -- 30% transparente
[Link] = "rbxassetid://1084991215" -- Textura do raio
-- Animação do raio
[Link] = 2 -- Velocidade da animação da textura
[Link] = 4 -- Quantas vezes a textura se repete
⚙️ Física e Constraints
Constraints - Conectando Objetos
Constraints são como "cordas invisíveis" que conectam partes e controlam como elas se movem.
WeldConstraint - Soldando Partes
lua
local parteA = [Link]
local parteB = [Link]
-- Criar weld constraint
local weld = [Link]("WeldConstraint")
[Link] = parteA -- Pode estar em qualquer uma das partes
weld.Part0 = parteA -- Primeira parte
weld.Part1 = parteB -- Segunda parte
-- Agora as partes estão "soldadas" - se movem juntas
-- parteA e parteB agora agem como um objeto único
HingeConstraint - Dobradiças
lua
local porta = [Link]
local batente = [Link]
-- Criar pontos de conexão
local attachmentPorta = [Link]("Attachment")
[Link] = porta
[Link] = [Link](-2, 0, 0) -- Lado esquerdo da porta
local attachmentBatente = [Link]("Attachment")
[Link] = batente
[Link] = [Link](0, 0, 0) -- Centro do batente
-- Criar dobradiça
local hinge = [Link]("HingeConstraint")
[Link] = porta
hinge.Attachment0 = attachmentPorta
hinge.Attachment1 = attachmentBatente
-- Configurações
[Link] = [Link] -- Tipo motor (pode ser controlado)
[Link] = 10000 -- Força máxima
[Link] = 2 -- Velocidade de rotação (rad/s)
-- Limites de rotação
[Link] = true
[Link] = -90 -- Limite inferior (-90 graus)
[Link] = 0 -- Limite superior (0 graus)
-- Controlar a dobradiça
[Link] = 2 -- Abre a porta
wait(2) -- Espera 2 segundos
[Link] = -2 -- Fecha a porta
BallSocketConstraint - Articulações
lua
-- Como um ombro ou quadril - rota em todas as direções
local braco = [Link]
local torso = [Link]
local attachmentBraco = [Link]("Attachment")
[Link] = braco
[Link] = [Link](0, 1, 0) -- Topo do braço
local attachmentTorso = [Link]("Attachment")
[Link] = torso
[Link] = [Link](1.5, 0.5, 0) -- Lado do torso
local ballSocket = [Link]("BallSocketConstraint")
[Link] = braco
ballSocket.Attachment0 = attachmentBraco
ballSocket.Attachment1 = attachmentTorso
-- Limites (opcional)
[Link] = true
[Link] = 90 -- Máximo 90 graus de rotação
AlignPosition e AlignOrientation - Controle Suave
lua
local objetoControlado = [Link]
local alvo = [Link]
-- Attachment no objeto controlado
local attachment = [Link]("Attachment")
[Link] = objetoControlado
-- AlignPosition - faz o objeto seguir uma posição
local alignPos = [Link]("AlignPosition")
[Link] = objetoControlado
alignPos.Attachment0 = attachment
-- Configurações de movimento
[Link] = 4000 -- Força máxima para mover
[Link] = 16 -- Velocidade máxima
[Link] = 10 -- Quão rápido responde (1-200)
-- Definir posição alvo
[Link] = [Link] -- Vai para a posição do alvo
-- AlignOrientation - controla rotação
local alignOri = [Link]("AlignOrientation")
[Link] = objetoControlado
alignOri.Attachment0 = attachment
[Link] = 4000
[Link] = 20
[Link] = 10
-- Definir rotação alvo
[Link] = [Link] -- Copia rotação do alvo
VectorForce e Torque - Forças Customizadas
lua
local parte = [Link]
-- Attachment para aplicar forças
local attachment = [Link]("Attachment")
[Link] = parte
-- VectorForce - empurra em uma direção
local force = [Link]("VectorForce")
[Link] = parte
force.Attachment0 = attachment
[Link] = [Link](0, 500, 0) -- Força para cima (anti-gravidade)
[Link] = [Link] -- Relativo ao mundo
-- Torque - aplica rotação
local torque = [Link]("Torque")
[Link] = parte
torque.Attachment0 = attachment
[Link] = [Link](0, 100, 0) -- Gira em torno do eixo Y
[Link] = [Link]
Exemplo Prático: Carro Simples
lua
-- Criar chassi do carro
local chassi = [Link]("Part")
[Link] = "Chassi"
[Link] = [Link](6, 1, 12)
[Link] = [Link](0, 3, 0)
[Link] = [Link]("Really red")
[Link] = workspace
-- Função para criar roda
function criarRoda(nome, posicao)
local roda = [Link]("Part")
[Link] = nome
[Link] = [Link]
[Link] = [Link](1, 3, 3)
[Link] = posicao
[Link] = [Link]("Really black")
[Link] = workspace
-- Conectar roda ao chassi com HingeConstraint
local attachmentRoda = [Link]("Attachment")
[Link] = roda
local attachmentChassi = [Link]("Attachment")
[Link] = chassi
[Link] = posicao
local hinge = [Link]("HingeConstraint")
[Link] = roda
hinge.Attachment0 = attachmentRoda
hinge.Attachment1 = attachmentChassi
-- Configurar como motor (para movimento)
[Link] = [Link]
[Link] = 10000
return hinge
end
-- Criar 4 rodas
local rodaFE = criarRoda("RodaFrenteEsquerda", [Link](-2, 1.5, 4))
local rodaFD = criarRoda("RodaFrenteDireita", [Link](2, 1.5, 4))
local rodaTE = criarRoda("RodaTrasEsquerda", [Link](-2, 1.5, -4))
local rodaTD = criarRoda("RodaTrasDireita", [Link](2, 1.5, -4))
-- Sistema de controle simples
local UserInputService = game:GetService("UserInputService")
[Link]:Connect(function(input)
if [Link] == [Link].W then -- Acelerar
[Link] = 10
[Link] = 10
[Link] = 10
[Link] = 10
elseif [Link] == [Link].S then -- Ré
[Link] = -10
[Link] = -10
[Link] = -10
[Link] = -10
end
end)
[Link]:Connect(function(input)
if [Link] == [Link].W or [Link] == [Link].S then
-- Parar todas as rodas
[Link] = 0
[Link] = 0
[Link] = 0
[Link] = 0
end
end)
🌐 Networking - Cliente vs Servidor
Networking é como cliente (jogador) e servidor se comunicam.
RemoteEvent - Comunicação Básica
lua
-- CRIAR NO REPLICATEDSTORAGE
local remoteEvent = [Link]("RemoteEvent")
[Link] = "PlayerAction"
[Link] = [Link]
lua
-- SERVER SCRIPT - Escuta pedidos dos clientes
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local PlayerAction = ReplicatedStorage:WaitForChild("PlayerAction")
[Link]:Connect(function(jogador, acao, dados)
-- jogador = quem enviou o evento
-- acao = tipo de ação
-- dados = informações extras
print("Jogador", [Link], "quer fazer:", acao)
if acao == "comprar_item" then
local itemId = [Link]
local preco = [Link]
-- Verificar se jogador tem dinheiro
local leaderstats = jogador:FindFirstChild("leaderstats")
if leaderstats then
local coins = leaderstats:FindFirstChild("