Pular para o conteúdo
PTEntrar

Como fazer um sistema de chocar ovos no Roblox?

Um ovo é três coisas: um preço, uma tabela de pets com peso e uma animação. O servidor cobra as moedas, sorteia na tabela, grava o pet no inventário do jogador e responde qual pet saiu. O cliente toca a rachadura e revela aquele pet. Nada é decidido no cliente.

Em resumo

  • Cobre, sorteie e salve nesta ordem, tudo no servidor.
  • Uma tabela com peso por ovo, para um ovo novo ser dado e não código.
  • A animação de revelação lê o resultado; ela nunca o produz.

Chocar é uma compra com uma surpresa em cima. A surpresa é a parte divertida e a compra é a parte que precisa estar certa: as moedas saem da conta uma vez, o pet chega uma vez, e quem fecha o jogo no meio da animação continua com o pet quando voltar.

Passo a passo

1. Descreva o ovo como dado

Uma tabela por ovo, com preço e pets. Acrescentar o Ovo de Vulcão tem de ser oito linhas de dado, não um script novo.

local OVOS = {
	basico = {
		preco = 250,
		pets = {
			{ id = "dog",    peso = 500 },
			{ id = "cat",    peso = 300 },
			{ id = "bunny",  peso = 150 },
			{ id = "dragon", peso = 49 },
			{ id = "void",   peso = 1 },
		},
	},
	vulcao = {
		preco = 5000,
		pets = {
			{ id = "magma",    peso = 600 },
			{ id = "obsidian", peso = 300 },
			{ id = "phoenix",  peso = 95 },
			{ id = "void",     peso = 5 },
		},
	},
}

2. Sorteie na tabela

O mesmo sorteio com peso que a roleta usa. Deixe num lugar só: um ovo e uma roleta discordando sobre as chances é um bug que ninguém encontra.

local rng = Random.new()

local function sortearPet(pets): string
	local total = 0
	for _, p in pets do
		total += p.peso
	end
	local bilhete = rng:NextInteger(1, total)
	local soma = 0
	for _, p in pets do
		soma += p.peso
		if bilhete <= soma then
			return p.id
		end
	end
	return pets[#pets].id
end

3. Cobre, salve e só então responda

A ordem é o projeto inteiro. Tire as moedas antes de sortear, para ninguém chocar de graça disparando o remote duas vezes; salve antes de responder, para o pet existir antes de o jogador ver.

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DataStoreService = game:GetService("DataStoreService")

local pets = DataStoreService:GetDataStore("Pets_v1")
local chocar = Instance.new("RemoteEvent")
chocar.Name = "HatchEgg"
chocar.Parent = ReplicatedStorage

local ocupado: { [number]: boolean } = {}

chocar.OnServerEvent:Connect(function(player: Player, ovoId: unknown)
	-- Nunca confie no id do ovo: ele veio do cliente.
	local ovo = type(ovoId) == "string" and OVOS[ovoId] or nil
	if not ovo then return end
	-- Um choque por vez por jogador: dois remotes no mesmo tick leriam o mesmo
	-- saldo de moedas e os dois passariam.
	if ocupado[player.UserId] then return end
	ocupado[player.UserId] = true

	local ok = pcall(function()
		local stats = player:FindFirstChild("leaderstats")
		local moedas = stats and stats:FindFirstChild("Coins")
		if not moedas or moedas.Value < ovo.preco then
			error("sem moedas")
		end
		moedas.Value = moedas.Value - ovo.preco

		local petId = sortearPet(ovo.pets)
		pets:UpdateAsync("u_" .. player.UserId, function(antigo)
			local tem = type(antigo) == "table" and antigo or {}
			tem[petId] = (tem[petId] or 0) + 1
			return tem
		end)
		chocar:FireClient(player, ovoId, petId)
	end)
	ocupado[player.UserId] = nil
	if not ok then
		chocar:FireClient(player, ovoId, nil)
	end
end)

Players.PlayerRemoving:Connect(function(player)
	ocupado[player.UserId] = nil
end)

4. Abra o ovo no cliente

A animação é só show. Ela recebe o id do pet e revela aquele modelo — se o jogador sair no meio, o pet já é dele.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")

local chocar = ReplicatedStorage:WaitForChild("HatchEgg")
local modelos = ReplicatedStorage:WaitForChild("PetModels")

chocar.OnClientEvent:Connect(function(_ovoId: string, petId: string?)
	if not petId then return end -- recusado: faltavam moedas
	local modelo = modelos:FindFirstChild(petId)
	if not modelo then return end

	local mostrado = modelo:Clone()
	mostrado.Parent = workspace
	mostrado:PivotTo(workspace.CurrentCamera.CFrame * CFrame.new(0, 0, -6))
	for _, parte in mostrado:GetDescendants() do
		if parte:IsA("BasePart") then
			parte.Anchored = true
			parte.CanCollide = false
			parte.Transparency = 1
			TweenService:Create(parte, TweenInfo.new(0.6), { Transparency = 0 }):Play()
		end
	end
	task.delay(3, function()
		mostrado:Destroy()
	end)
end)

Onde guardar o pet que o jogador tem

OndeSobrevive a reentrarA salvo do clienteUse quando
DataStore, contado por id de petsimsimO padrão: uma tabela { petId = quantos }
Uma pasta de valores sob o jogadornãosimSó como espelho ao vivo da tabela salva
Uma tabela no clientenãonãoNunca
Um DataStore ordenadosimsimSó para um ranking de quantos foram chocados

Perguntas

O pet é sorteado ao chocar ou ao comprar o ovo?

Ao chocar, que neste desenho é o mesmo instante. O que não pode é sortear quando o ovo aparece na loja: um resultado que existe antes de o jogador apertar o botão é um resultado que algo no cliente consegue ler.

Por que às vezes o jogador é cobrado e não recebe o pet?

Porque a cobrança e o save são duas gravações separadas e uma delas falhou. O pcall acima põe as duas num bloco e recusa o choque inteiro, então um save que falha devolve as moedas por nunca ter confirmado o sorteio. Se você separar, o bug é seu.

Como mostrar as chances?

Imprima a partir da mesma tabela que o sorteio usa — peso / total em porcentagem, com uma casa. Digitar as porcentagens na interface na mão é como um pet de 1% vira silenciosamente um pet de 0,2% depois de alguém acrescentar um sexto pet.

Dá para usar um script de ovo para dez ovos?

É exatamente o motivo do passo 1. O script recebe um id de ovo, procura na tabela e sorteia. Dez ovos são dez entradas em OVOS, e um ovo novo não consegue trazer um bug novo porque não há código novo.

Atualizado: Testado no Studio: Roblox Studio, outubro de 2026Autor: GustavoLicença: O código deste guia pode ser usado em qualquer experiência do Roblox, inclusive paga

Pack relacionado

Brainrot Pet Pack

Brainrot Pet Pack

US$ 150Ver o pack

Quero ser avisado

Em breve

Deixe seu e-mail e a gente te avisa na hora em que este pack sair.