O DataStoreService permite que você armazene dados que precisam persistir entre sessões, como itens no inventário de um jogador ou pontos de habilidade. Os armazenamentos de dados são consistentes por jogo, portanto, qualquer lugar em um jogo pode acessar e alterar os mesmos dados, incluindo lugares em diferentes servidores.
Se você deseja adicionar controle de permissão granular aos seus armazenamentos de dados e acessá-los fora do Studio ou dos servidores Roblox, pode usar as APIs de Nuvem Abertas para armazenamentos de dados.
Para visualizar e monitorar todos os armazenamentos de dados em um jogo através do Creator Hub, use o Gerenciador de Armazenamentos de Dados.
Para dados temporários que você precisa atualizar ou acessar com frequência, use armazenamentos em memória.
Habilitar acesso ao Studio
Por padrão, jogos testados no Studio não podem acessar armazenamentos de dados, portanto, você deve habilitá-los primeiro. Acessar armazenamentos de dados no Studio pode ser perigoso para jogos em produção, pois o Studio acessa os mesmos armazenamentos de dados que o aplicativo cliente. Para evitar sobrescrever dados de produção, não habilite esta configuração para jogos ao vivo. Em vez disso, habilite-a para uma versão de teste separada do jogo.
Para habilitar o acesso ao Studio em um jogo publicado:
- Abra a janela Arquivo ⟩ Configurações da Experiência do Studio.
- Navegue até Segurança.
- Ative a alternância Habilitar Acesso do Studio aos Serviços de API.
- Clique em Salvar.
Acessar armazenamentos de dados
Para acessar um armazenamento de dados dentro de um jogo:
- Adicione DataStoreService a um Script do lado do servidor.
- Use a função GetDataStore() e especifique o nome do armazenamento de dados que você deseja usar. Se o armazenamento de dados não existir, o Studio cria um quando você salva os dados do seu jogo pela primeira vez.
local DataStoreService = game:GetService("DataStoreService")local gameStore = DataStoreService:GetDataStore("PlayerGame")
Criar dados
Um armazenamento de dados é essencialmente um dicionário, semelhante a uma tabela Luau. Uma chave única indexa cada valor no armazenamento de dados, como o Player.UserId exclusivo de um usuário ou uma string nomeada para uma promoção de jogo.
| Chave de dados do usuário | Valor |
|---|---|
| 31250608 | 50 |
| 351675979 | 20 |
| 505306092 | 78000 |
| Chave de dados de promoção | Valor |
| ActiveSpecialEvent | SummerParty2 |
| ActivePromoCode | BONUS123 |
| CanAccessPartyPlace | true |
Para criar uma nova entrada, chame SetAsync() com o nome da chave e um valor.
local DataStoreService = game:GetService("DataStoreService")
local gameStore = DataStoreService:GetDataStore("PlayerGame")
local success, errorMessage = pcall(function()
gameStore:SetAsync("User_1234", 50)
end)
if not success then
print(errorMessage)
end
Atualizar dados
Para alterar qualquer valor armazenado em um armazenamento de dados, chame UpdateAsync() com o nome da chave da entrada e uma função de retorno que define como você deseja atualizar a entrada. Essa função de retorno recebe o valor atual e retorna um novo valor com base na lógica que você define. Se a função de retorno retornar nil, a operação de gravação é cancelada e o valor não é atualizado.
local DataStoreService = game:GetService("DataStoreService")
local nicknameStore = DataStoreService:GetDataStore("Nicknames")
local function makeNameUpper(currentName)
local nameUpper = string.upper(currentName)
return nameUpper
end
local success, updatedName = pcall(function()
return nicknameStore:UpdateAsync("User_1234", makeNameUpper)
end)
if success then
print("Nome em Maiúsculas:", updatedName)
end
Definir vs. atualizar
Use definir para atualizar rapidamente uma chave específica. A função SetAsync():
- Pode causar inconsistência de dados se dois servidores tentarem definir a mesma chave ao mesmo tempo.
- Conta apenas contra o limite de gravação.
Use atualizar para lidar com tentativas de múltiplos servidores. A função UpdateAsync():
- Lê o valor atual da chave do servidor que a atualizou pela última vez antes de fazer quaisquer alterações.
- É mais lenta porque lê antes de gravar.
- Conta contra os limites de leitura e gravação.
Ler dados
Para ler o valor de uma entrada de armazenamento de dados, chame GetAsync() com o nome da chave da entrada.
local DataStoreService = game:GetService("DataStoreService")
local gameStore = DataStoreService:GetDataStore("PlayerGame")
local success, currentGame = pcall(function()
return gameStore:GetAsync("User_1234")
end)
if success then
print(currentGame)
end
Incrementar dados
Para incrementar um inteiro em um armazenamento de dados, chame IncrementAsync() com o nome da chave da entrada e um número para quanto deve mudar o valor. IncrementAsync() é uma função conveniente que permite que você evite chamar UpdateAsync() e incrementar manualmente o inteiro.
local DataStoreService = game:GetService("DataStoreService")
local gameStore = DataStoreService:GetDataStore("PlayerGame")
local success, newGame = pcall(function()
return gameStore:IncrementAsync("Player_1234", 1)
end)
if success then
print(newGame)
end
Remover dados
Para remover uma entrada e retornar o valor associado com a chave, chame RemoveAsync().
local DataStoreService = game:GetService("DataStoreService")
local nicknameStore = DataStoreService:GetDataStore("Nicknames")
local success, removedValue = pcall(function()
return nicknameStore:RemoveAsync("User_1234")
end)
if success then
print(removedValue)
end
Metadados
Existem dois tipos de metadados associados às chaves:
- Definido pelo serviço: Metadados de leitura padrão, como o tempo da última atualização e o tempo de criação. Cada objeto possui metadados definidos pelo serviço.
- Definido pelo usuário: Metadados personalizados para marcação e categorização. Definido usando o objeto DataStoreSetOptions e a função SetMetadata().
Para gerenciar metadados, amplie as funções SetAsync(), UpdateAsync(), GetAsync(), IncrementAsync(), e RemoveAsync().
SetAsync() aceita os terceiros e quartos argumentos opcionais:
Uma tabela de UserIds. Isso pode ajudar no rastreamento e remoção de direitos autorais de conteúdo e propriedade intelectual.
Um objeto DataStoreSetOptions, onde você pode definir metadados personalizados usando a função SetMetadata().
local DataStoreService = game:GetService("DataStoreService")local gameStore = DataStoreService:GetDataStore("PlayerGame")local setOptions = Instance.new("DataStoreSetOptions")setOptions:SetMetadata({["GameElement"] = "Fire"})local success, errorMessage = pcall(function()gameStore:SetAsync("User_1234", 50, {1234}, setOptions)end)if not success thenprint(errorMessage)end
GetAsync(), IncrementAsync(), e RemoveAsync() retornam um segundo valor no objeto DataStoreKeyInfo. Este segundo valor contém tanto propriedades definidas pelo serviço quanto funções para buscar metadados definidos pelo usuário.
- A função GetMetadata() busca metadados definidos pelo usuário que você passou para SetAsync() através de SetMetadata().
- A propriedade Version busca a versão da chave.
- A propriedade CreatedTime busca o horário em que a chave foi criada, formatada como o número de milissegundos desde a epoch.
- A propriedade UpdatedTime busca a última vez que a chave foi atualizada, formatada como o número de milissegundos desde a epoch.
local DataStoreService = game:GetService("DataStoreService")local gameStore = DataStoreService:GetDataStore("PlayerGame")local success, currentGame, keyInfo = pcall(function()return gameStore:GetAsync("User_1234")end)if success thenprint(currentGame)print(keyInfo.Version)print(keyInfo.CreatedTime)print(keyInfo.UpdatedTime)print(keyInfo:GetUserIds())print(keyInfo:GetMetadata())endA função de retorno de UpdateAsync() aceita um parâmetro adicional no objeto DataStoreKeyInfo que descreve o estado atual da chave. Ela retorna o valor modificado, as chaves associadas a UserIds, e os metadados da chave.
local DataStoreService = game:GetService("DataStoreService")local nicknameStore = DataStoreService:GetDataStore("Nicknames")local function makeNameUpper(currentName, keyInfo)local nameUpper = string.upper(currentName)local userIDs = keyInfo:GetUserIds()local metadata = keyInfo:GetMetadata()return nameUpper, userIDs, metadataendlocal success, updatedName, keyInfo = pcall(function()return nicknameStore:UpdateAsync("User_1234", makeNameUpper)end)if success thenprint(updatedName)print(keyInfo.Version)print(keyInfo.CreatedTime)print(keyInfo.UpdatedTime)print(keyInfo:GetUserIds())print(keyInfo:GetMetadata())end
Para limites ao definir metadados, consulte os limites de metadados.
Armazenamentos de dados ordenados
Por padrão, os armazenamentos de dados não organizam seu conteúdo. Se você precisa obter dados de forma ordenada, como em classificações persistentes, chame GetOrderedDataStore() em vez de GetDataStore().
local DataStoreService = game:GetService("DataStoreService")local characterAgeStore = DataStoreService:GetOrderedDataStore("CharacterAges")
Os armazenamentos de dados ordenados suportam as mesmas funções básicas que os armazenamentos de dados padrão, além da função única GetSortedAsync(). Esta função recupera várias chaves ordenadas com base em uma ordem de classificação específica, tamanho da página e valores mínimos/máximos.
O exemplo a seguir ordena dados de personagens em páginas com três entradas, cada uma em ordem decrescente, e depois percorre as páginas e exibe o nome e a idade de cada personagem.
local DataStoreService = game:GetService("DataStoreService")
local characterAgeStore = DataStoreService:GetOrderedDataStore("CharacterAges")
-- Popula o armazenamento de dados ordenados
local characters = {
Mars = 19,
Janus = 20,
Diana = 18,
Venus = 25,
Neptune = 62
}
for char, age in characters do
local success, errorMessage = pcall(function()
characterAgeStore:SetAsync(char, age)
end)
if not success then
print(errorMessage)
end
end
-- Ordena os dados em ordem decrescente em páginas de três entradas cada
local success, pages = pcall(function()
return characterAgeStore:GetSortedAsync(false, 3)
end)
if success then
while true do
-- Obtém a página atual (primeira)
local entries = pages:GetCurrentPage()
-- Itera por todos os pares chave-valor na página
for _, entry in entries do
print(entry.key .. " : " .. tostring(entry.value))
end
-- Verifica se a última página foi alcançada
if pages.IsFinished then
break
else
print("----------")
-- Avança para a próxima página
pages:AdvanceToNextPageAsync()
end
end
end