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 Arquivo ⟩ Configurações da Experiência ⟩ Seguranç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.