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 data stores são consistentes por jogo, então qualquer lugar em um jogo pode acessar e alterar os mesmos dados, incluindo lugares em diferentes servidores.
Se você quiser adicionar controle de permissão granular aos seus data stores e acessá-los fora do Studio ou dos servidores Roblox, você pode usar APIs de Nuvem Abertas para data stores.
Para visualizar e monitorar todos os data stores em um jogo através do Creator Hub, use o Gerenciador de Data Stores.
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 data stores, então você deve habilitá-los primeiro. Acessar data stores no Studio pode ser perigoso para jogos ao vivo porque o Studio acessa os mesmos data stores que a aplicação 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.
- Habilite a opção Habilitar Acesso do Studio aos Serviços de API.
- Clique em Salvar.
Acessar data stores
Para acessar um data store dentro de um jogo:
- Adicione DataStoreService a um Script do lado do servidor.
- Use a função GetDataStore() e especifique o nome do data store que você deseja usar. Se o data store 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 data store é essencialmente um dicionário, semelhante a uma tabela Luau. Uma chave única indexa cada valor no data store, como o Player.UserId único 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)
endAtualizar dados
Para alterar qualquer valor armazenado em um data store, chame UpdateAsync() com o nome da chave da entrada e uma função de callback que define como você deseja atualizar a entrada. Este callback recebe o valor atual e retorna um novo valor com base na lógica que você define. Se o callback 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)
endDefinir vs atualizar
Use set 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 update para lidar com tentativas de múltiplos servidores. A função UpdateAsync():
- Lê o valor atual da chave do servidor que a atualizou por último antes de fazer quaisquer alterações
- É mais lenta porque lê antes de escrever
- Conta contra os limites de leitura e gravação
Ler dados
Para ler o valor de uma entrada de data store, 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)
endIncrementar dados
Para incrementar um inteiro em um data store, chame IncrementAsync() com o nome da chave da entrada e um número para quanto mudar o valor. IncrementAsync() é uma função de conveniência 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)
endRemover dados
Para remover uma entrada e retornar o valor associado à 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)
endMetadados
Existem dois tipos de metadados associados às chaves:
- Definido pelo serviço: Metadados padrão somente leitura, como o horário da atualização mais recente e o horário de criação. Cada objeto tem 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, expanda as funções SetAsync(), UpdateAsync(), GetAsync(), IncrementAsync(), e RemoveAsync().
SetAsync() aceita os terceiros e quartos argumentos opcionais:
Uma tabela de UserIds. Isso pode ajudar com 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, formatado como o número de milissegundos desde a época.
- A propriedade UpdatedTime busca a última vez que a chave foi atualizada, formatada como o número de milissegundos desde a época.
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 callback de UpdateAsync() recebe 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, veja os limites de metadados.
Data stores ordenados
Por padrão, os data stores não ordenam seu conteúdo. Se você precisar obter dados de uma maneira ordenada, como em estatísticas de leaderboard persistentes, chame GetOrderedDataStore() em vez de GetDataStore().
local DataStoreService = game:GetService("DataStoreService")
local characterAgeStore = DataStoreService:GetOrderedDataStore("CharacterAges")Data stores ordenados suportam as mesmas funções básicas que os data stores padrão, além da única função GetSortedAsync(). Isso recupera múltiplas 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 data store ordenado
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
endLer várias entradas
Para ler várias entradas de data store ordenado em uma única solicitação, chame BatchGetAsync() com um array de chaves. Este é o equivalente em lote para ler entradas uma a uma com GetAsync().
BatchGetAsync() retorna um dicionário que mapeia cada chave solicitada para uma tabela com um campo value. Chaves que não existem são omitidas do dicionário, então confirme que uma chave está presente antes de ler seu valor.
Cada chave que você solicitar conta como uma solicitação de leitura, então uma única chamada para N chaves conta como N solicitações contra o limite de leitura do data store ordenado.
O exemplo a seguir lê três pontuações de jogadores em uma única solicitação, e depois percorre as chaves e exibe cada pontuação que existe.
local DataStoreService = game:GetService("DataStoreService")
local playerScores = DataStoreService:GetOrderedDataStore("PlayerScores")
local keys = {"Player_123", "Player_456", "Player_789"}
local success, results = pcall(function()
return playerScores:BatchGetAsync(keys)
end)
if success then
for _, key in keys do
local entry = results[key]
if entry then
print(key .. " : " .. tostring(entry.value))
else
print(key .. " não tem entrada salva")
end
end
end