Tutoriais intermediários

Salve os dados do jogador com armazéns de dados padrão

*Este conteúdo é traduzido por IA (Beta) e pode conter erros. Para ver a página em inglês, clique aqui.

Os armazéns de dados são um serviço que você pode usar para salvar e carregar dados persistentes dos jogadores em diferentes sessões de jogo. Eles armazenam informações importantes, como o progresso ou inventário de um jogador, e permitem que você as recupere para o jogador na próxima vez que ele entrar no seu jogo. Sem os armazéns de dados, um jogador perderia todo o seu progresso sempre que saísse do jogo.

Existem dois tipos de armazéns de dados: padrão e ordenados. Este tutorial usa armazéns de dados padrão, que armazenam dados como números, strings e tabelas que não precisam ser classificados ou ordenados.

Usando o tutorial de armazém de dados Gold Rush - Início no arquivo .rbxl como ponto de partida e o tutorial de armazém de dados Gold Rush - Completo como referência, este tutorial fornece a base necessária para salvar o progresso do jogador e criar jogos mais consistentes, incluindo orientações sobre:

  • Salvar e carregar a quantidade de ouro que um jogador coletou.
  • Atualizar a interface do usuário para exibir o inventário de ouro do jogador.
  • Salvar automaticamente o inventário de ouro do jogador a cada 30 segundos.
  • Salvar a posição do jogador quando ele sai do jogo.
  • Restaurar a posição do jogador quando ele voltar ao jogo.

Ao final deste tutorial, você deve ter dois scripts com armazéns de dados dentro de ServerScriptService:

  1. Um script atualizado GoldManager que rastreia, carrega e salva automaticamente o ouro do jogador.
  2. Um script atualizado PositionManager que salva a posição do jogador quando ele sai do jogo e restaura sua posição quando ele volta ao jogo.

Habilitar o acesso do Studio aos serviços de API

Os armazéns de dados não são armazenados localmente no seu dispositivo, então seu jogo depende da comunicação servidor-a-servidor com o backend da Roblox para usá-los. Por padrão, o Studio restringe essa comunicação para evitar abusos ou usos acidentais. O acesso aos serviços de API no Studio está desativado até que você o habilite explicitamente para garantir que apenas jogos confiáveis possam ler e gravar nos servidores de backend da Roblox.

Para habilitar o acesso do Studio aos serviços de API para que você possa usar armazéns de dados:

  1. Abra o arquivo do tutorial de armazém de dados Gold Rush - Início no Studio e crie uma cópia local.
  2. De volta ao Studio, vá em ArquivoConfigurações da ExperiênciaSegurança.
  3. Ative Habilitar Acesso do Studio aos Serviços de API.
  4. Salve suas alterações.

Criar um armazém de dados padrão

Ao criar um armazém de dados, você deve sempre chamar o DataStoreService a partir de um Script do lado do servidor. Isso é importante porque:

  • A Roblox bloqueia todo o acesso ao armazém de dados do cliente, de modo que apenas o servidor tem permissão para acessar e modificar dados persistentes de jogadores.
  • Scripts do lado do servidor são executados em um ambiente centralizado, garantindo que os dados lidos e gravados no seu armazém de dados sejam precisos e válidos.
  • Como os scripts do lado do cliente são executados no dispositivo do jogador, qualquer jogador poderia potencialmente explorar o jogo e roubar ou sobrescrever os dados de outros jogadores se o cliente tivesse acesso aos seus armazéns de dados.

Você também deve dar um nome exclusivo ao seu armazém de dados para manter seus dados organizados e prevenir sobreposições ou conflitos entre diferentes armazéns de dados. Neste tutorial, o armazém de dados que salva e armazena o inventário de ouro do jogador é chamado de PlayerGold.

Para criar o armazém de dados PlayerGold:

  1. Abra o script GoldManager existente em ServerScriptService.

  2. Sob os outros serviços na parte superior do script, inicialize o DataStoreService e chame GetDataStore com a string "PlayerGold".


    local DataStoreService = game:GetService("DataStoreService")
    local goldStore = DataStoreService:GetDataStore("PlayerGold")

Salvar e carregar dados do jogador

Os armazéns de dados são compostos por chaves, que identificam dados, e valores, que armazenam dados.

ChaveValor
DescriçãoUma chave é um identificador único que você pode usar para acessar um pedaço específico de dados.

As chaves permitem que você organize seus dados para que possa gerenciá-los e depurá-los facilmente.
Um valor é o dado real que você deseja salvar ou carregar, como o inventário de um jogador ou suas configurações.

Os valores permitem que você armazene o progresso entre as sessões, bem como recupere os dados do jogador na próxima vez que ele entrar no seu jogo.
Formatos permitidosSomente strings.Podem ser números, strings, booleanos ou tabelas.
Exemplos"Player_A", "TopScore", "GameSetting"100, "Level_5", true, {gold = 100, level = 5}

Neste tutorial, a chave é o userId do jogador e o valor é a quantidade de ouro que ele coletou. Para usar essa chave e valor para salvar e carregar os dados do jogador:

  1. No script GoldManager, adicione uma função auxiliar chamada saveGold para salvar o ouro do jogador no armazém de dados PlayerGold.


    local function saveGold(userId, value)
    local success, err = pcall(function()
    -- `userId` é o ID único do jogador
    -- `value` é a quantidade de ouro a ser salva para aquele jogador
    goldStore:SetAsync(userId, value)
    end)
    end
  2. OPCIONAL
    Adicione um aviso à função saveGold que imprime a ID do jogador e uma mensagem de erro. Embora não seja obrigatório, esse passo é uma boa prática para facilitar a depuração caso sua função falhe.


    local function saveGold(userId, value)
    local success, err = pcall(function()
    -- `userId` é o ID único do jogador
    -- `value` é a quantidade de ouro a ser salva para aquele jogador
    goldStore:SetAsync(userId, value)
    end)
    if not success then
    warn("[ERRO DE SALVAMENTO] Não foi possível salvar o ouro de", userId, ":", err)
    end
    end
  3. Modifique o evento onPlayerAdded para carregar o ouro do jogador quando ele entrar no jogo pela primeira vez. A função onPlayerAdded atualizada:

    • Tenta carregar o conteúdo dentro do armazém de dados PlayerGold. Ele retorna ou o ouro salvo do jogador ou um valor de 0 se o jogador não tiver ouro ou não tiver jogado o jogo antes.
    • Fornece um registro de depuração para ajudá-lo a depurar seu código mais facilmente. Esse registro de depuração inclui o ouro salvo do jogador que está entrando, ou uma mensagem de erro se onPlayerAdded não estiver conseguindo acessar o armazém de dados.
    • Atualiza a interface do usuário para exibir o ouro salvo do jogador na tela.

    local function onPlayerAdded(player)
    local userId = player.UserId
    local success, storedGold = pcall(function()
    return goldStore:GetAsync(userId)
    end)
    if success then
    local currentGold = storedGold or 0
    playerGold[userId] = currentGold
    uiEvent:FireClient(player, {
    gold = currentGold,
    doTween = false,
    showAlert = not success
    })
    else
    uiEvent:FireClient(player, { showAlert = true })
    warn("Não foi possível carregar ouro para", player.Name)
    end
    end
  4. Modifique o evento onPlayerRemoving para chamar a função saveGold que você criou anteriormente e salvar o ouro do jogador quando ele deixar o jogo.


    local function onPlayerRemoving(player)
    local userId = player.UserId
    if playerGold[userId] then
    saveGold(userId, playerGold[userId])
    end
    end

Salvar dados do jogador automaticamente

Salvar automaticamente os dados de um jogador é uma boa prática porque protege o jogador de perder seus dados. Se você salvar os dados do jogador apenas quando ele deixar o jogo com onPlayerRemoving, pode perder seu progresso mais recente se ele se desconectar inesperadamente do servidor.

Para salvar automaticamente os dados do jogador:

  1. Crie uma nova constante para determinar com que frequência você deseja que seu jogo salve automaticamente os dados do jogador. Uma constante é uma variável cujo valor não muda enquanto o jogo está em execução. Você pode usar essa constante para se referir ao intervalo de salvamento automático ao longo do seu script e ajustar facilmente a frequência de salvamento automático.


    -- Este número está em segundos
    local AUTOSAVE_INTERVAL = 30
  2. Adicione uma coroutine de salvamento automático à função onPlayerAdded existente para criar um loop em segundo plano que roda enquanto o jogador estiver dentro do jogo. Uma coroutine é uma função que roda de forma assíncrona; ela pode pausar em determinados pontos, retomar de onde parou e rodar em paralelo com outras partes do seu script sem bloqueá-las.

    Neste script, o loop em segundo plano de salvamento automático espera pelo número de segundos em sua constante AUTOSAVE_INTERVAL, e então chama a função saveGold que você criou anteriormente.


    coroutine.wrap(function()
    while player.Parent do
    task.wait(AUTOSAVE_INTERVAL)
    if playerGold[userId] then
    print("[SALVAMENTO AUTOMÁTICO] Salvando", playerGold[userId], "ouro para", player.Name)
    saveGold(userId, playerGold[userId])
    end
    end
    end)()

Salvar e carregar a posição do jogador

Para salvar a posição de um jogador, trabalhe com o Character em vez do objeto Player em si. O Character de um jogador representa seu modelo físico no mundo 3D e possui as coordenadas de sua posição e orientação atuais, enquanto o objeto Player representa apenas a conta do usuário.

Como os armazéns de dados só podem salvar tipos de dados básicos como números, strings e tabelas, você não pode armazenar diretamente objetos complexos como valores Vector3 ou CFrame. Para salvar a posição de um jogador, você precisa dividi-la em três números separados (as coordenadas X, Y e Z) e salvá-los individualmente. Ao carregar a posição mais tarde, você pode reconstruir o Vector3 usando as coordenadas salvas.

Para salvar e carregar a posição do personagem:

  1. Abra o script PositionManager existente em ServerScriptService.

  2. Na parte superior do script, inicialize o DataStoreService e chame GetDataStore com a string "PlayerPosition".


    local DataStoreService = game:GetService("DataStoreService")
    local positionStore = DataStoreService:GetDataStore("PlayerPosition")
  3. Adicione uma função auxiliar chamada savePosition que recebe o userId de um jogador e uma posição Vector3. Como você não pode salvar valores Vector3 diretamente, converta a posição em uma tabela de números X, Y, Z.


    local function savePosition(player, position)
    local userId = player.UserId
    local success, err = pcall(function()
    positionStore:SetAsync(userId, {position.X, position.Y, position.Z})
    end)
    end
  4. OPCIONAL
    Adicione um aviso à função savePosition que imprime uma mensagem de erro e o nome do jogador para quem você falhou em salvar a posição. Embora não seja obrigatório, esse passo é uma boa prática para facilitar a depuração caso sua função falhe.


    local function savePosition(player, position)
    local userId = player.UserId
    local success, err = pcall(function()
    positionStore:SetAsync(userId, {position.X, position.Y, position.Z})
    end)
    if not success then
    warn("Não foi possível salvar a posição de", player.Name, ":", err)
    end
    end
  5. Adicione outra função auxiliar chamada loadPosition para carregar as coordenadas salvas de um jogador no armazém de dados PlayerPosition. Use PivotTo para restaurar a posição do personagem no mundo. Como a posição salva do jogador é retornada como uma tabela, você tem que reconstruir um Vector3 e então convertê-lo em um CFrame para mover o personagem.


    local function loadPosition(userId, character)
    local userId = player.UserId
    local success, savedCoords = pcall(function()
    return positionStore:GetAsync(userId)
    end)
    if success and savedCoords then
    local pos = Vector3.new(savedCoords[1], savedCoords[2], savedCoords[3])
    print("Posição restaurada para", player.Name)
    character:PivotTo(CFrame.new(pos))
    elseif not success then
    warn("Não foi possível carregar a posição de", player.Name)
    end
    end
  6. Modifique o evento onPlayerAdded para configurar a lógica de posição para cada jogador que entra no seu jogo. Dentro da função onPlayerAdded atualizada:

    • CharacterAdded chama loadPosition para restaurar a última localização conhecida do personagem quando o personagem de um jogador nasce.
    • CharacterRemoving chama savePosition para salvar a posição atual do personagem do jogador se ele for removido do jogo.
    • GetPivot obtém a localização exata do personagem no mundo no momento em que ele é removido.

    local function onPlayerAdded(player)
    local userId = player.UserId
    player.CharacterAdded:Connect(function(character)
    loadPosition(player, character)
    end)
    player.CharacterRemoving:Connect(function(character)
    local pos = character:GetPivot().Position
    savePosition(player, pos)
    end)
    end
    Player.PlayerAdded:Connect(onPlayerAdded)

Código final

Veja os seguintes snippets de código para os scripts completos GoldManager e PositionManager. Você pode colá-los e executá-los diretamente no arquivo Gold Rush - tutorial de salvamento de dados - Início no Studio.

GoldManager


-- Obter serviços
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CollectionService = game:GetService("CollectionService")
local DataStoreService = game:GetService("DataStoreService")
-- Evento remoto para atualizar a interface do usuário
local uiEvent = ReplicatedStorage:WaitForChild("UIEvent")
-- Armazém de dados para salvar os pedaços de ouro do jogador
local goldStore = DataStoreService:GetDataStore("PlayerGold")
-- Tabela para armazenar os pedaços de ouro do jogador para uma única sessão
local playerGold = {}
-- Constantes
local GOLD_VALUE = 10 -- Quanto vale cada pedaço de ouro
local GOLD_REGEN_DELAY = 2 -- O atraso antes que um pedaço reapareça (em segundos)
local AUTOSAVE_INTERVAL = 30 -- Com que frequência os pedaços do jogador são salvos (em segundos)
-- Função para lidar com o jogador coletando um pedaço de ouro
local function processGoldTouch(chunk, player)
-- Esconder o pedaço quando o jogador o coleta
chunk.Parent = nil
-- Adicionar o pedaço à pontuação de ouro da sessão do jogador
local userId = player.UserId
playerGold[userId] = (playerGold[userId] or 0) + GOLD_VALUE
print(player.Name, "agora tem", playerGold[userId], "ouro")
-- Atualizar a interface do usuário para refletir a nova pontuação de ouro para esta sessão
uiEvent:FireClient(player, {
gold = playerGold[userId],
doTween = true,
showAlert = false
})
-- Esperar um pouco e depois reaparecer o pedaço de ouro que foi coletado
task.delay(GOLD_REGEN_DELAY, function()
chunk.Parent = workspace.GoldChunks
end)
end
-- Loop através de todas as partes etiquetadas como "Gold" e conectá-las à detecção de toque
for _, chunk in ipairs(CollectionService:GetTagged("Gold")) do
chunk.Touched:Connect(function(otherPart)
local player = Players:GetPlayerFromCharacter(otherPart.Parent)
if player then
processGoldTouch(chunk, player)
end
end)
end
-- Função para salvar o ouro do jogador no armazém de dados
local function saveGold(player, value)
local userId = player.UserId
local success, err = pcall(function()
goldStore:SetAsync(userId, value)
end)
if not success then
warn("Não foi possível salvar o ouro de", player.Name, ":", err)
end
end
-- Função para lidar com o jogador entrando no jogo
local function onPlayerAdded(player)
local userId = player.UserId
print(player.Name, "entrou no jogo")
-- Tentar carregar o ouro do jogador do armazém de dados
local success, storedGold = pcall(function()
return goldStore:GetAsync(userId)
end)
if success then
-- Definir a pontuação de ouro da sessão atual usando o valor do armazém de dados para o jogador
local currentGold = storedGold or 0
playerGold[userId] = currentGold
-- Atualizar a interface do usuário com o valor do armazém de dados para o jogador
uiEvent:FireClient(player, {
gold = currentGold,
doTween = false,
showAlert = false
})
print("Carregado", currentGold, "de ouro para", player.Name)
else
-- Notificar o jogador que seu ouro não pôde ser carregado
uiEvent:FireClient(player, { showAlert = true })
warn("Não foi possível carregar ouro para", player.Name)
end
-- Iniciar a coroutine de salvamento automático para salvar o ouro do jogador a cada 30 segundos
coroutine.wrap(function()
while player.Parent do
task.wait(AUTOSAVE_INTERVAL)
if playerGold[userId] then
saveGold(player, playerGold[userId])
print("Salvando automaticamente", playerGold[userId], "de ouro para", player.Name)
end
end
end)()
end
-- Função para lidar com o jogador saindo do jogo
local function onPlayerRemoving(player)
local userId = player.UserId
print(player.Name, "saiu do jogo")
-- Verificar se o ouro do jogador foi rastreado
if playerGold[userId] then
-- Salvar o ouro do jogador no armazém de dados antes de sair
saveGold(player, playerGold[userId])
end
end
-- Conectar os eventos de entrada e saída dos jogadores
Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoving:Connect(onPlayerRemoving)

PositionManager


-- Obter serviços
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
-- Armazém de dados para salvar a posição do jogador
local positionStore = DataStoreService:GetDataStore("PlayerPosition")
-- Função para salvar a posição do jogador como uma tabela de {X, Y, Z}
local function savePosition(player, position)
local userId = player.UserId
local success, err = pcall(function()
positionStore:SetAsync(userId, {position.X, position.Y, position.Z})
end)
if not success then
warn("Não foi possível salvar a posição de", player.Name, ":", err)
end
end
-- Função para carregar a última posição salva do jogador e mover seu personagem
local function loadPosition(player, character)
local userId = player.UserId
local success, savedCoords = pcall(function()
return positionStore:GetAsync(userId)
end)
if success and savedCoords then
local pos = Vector3.new(savedCoords[1], savedCoords[2], savedCoords[3])
print("Posição restaurada para", player.Name)
character:PivotTo(CFrame.new(pos))
elseif not success then
warn("Não foi possível carregar a posição de", player.Name)
end
end
-- Função para lidar com o jogador entrando no jogo
local function onPlayerAdded(player)
local userId = player.UserId
-- Tentar carregar a posição do jogador quando seu personagem nascer
player.CharacterAdded:Connect(function(character)
loadPosition(player, character)
end)
-- Salvar a posição do jogador quando seu personagem for removido
player.CharacterRemoving:Connect(function(character)
local pos = character:GetPivot().Position
savePosition(player, pos)
end)
end
Players.PlayerAdded:Connect(onPlayerAdded)
©2026 Roblox Corporation, Roblox, o logotipo Roblox e Powering Imagination estão entre nossas marcas registradas e não registradas nos EUA e em outros países.