I’ve been in a dilemma for about a year over trying to figure out some datastore information. I have the basic datastore script scripted (player added ‘player removing -save Etc.) Now where my question comes in is… Can a value be created on the fly (player does something) and saved once the player leaves.
So to recap. I’m looking to see if there is a way for a script to make a value (when the player does something and allow that value to be saved to the datastore and be used once the player does re join.
Here is an example: In this game I’m not limiting a player to a certain amount of items. So suppose this player collects 1,000 pickaxes and each one has a different amount of Health which also needs to be saved as well.
Would I have to create 1,000 IntValues just in case a player would decide to get 1,000 pickaxes , which is essentially limiting the player still as I was trying to avoid, or is there an easier way?
Thank you and I look forward to your thoughts, TonyRayFray.
Don’t use instance values. Instead, create a module to hold the data. Create a function in that module to retrieve the data and save it as a dictionary to the store. Then, when loading, you can clone a template module essentially identical to the other one in terms of structure, and then you can use that.
Yes, you can create and save player data dynamically, including a potentially unlimited number of unique items like pickaxes with individual health values. Instead of creating a separate IntValue for each item, you can store each item’s data in a Lua table. When a player collects an item or changes its attributes, just update this table. Before the player leaves, serialize this table to a JSON string and save it to a DataStore. Upon the player’s return, deserialize the JSON back into a Lua table to restore their inventory. This approach allows for flexible, scalable, and efficient management of player data without pre-defining a fixed number of items or attributes.
-- Services
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
-- DataStore
local playerDataStore = DataStoreService:GetDataStore("PlayerData")
-- Functions
local function serializeTable(table)
return game:GetService("HttpService"):JSONEncode(table)
end
local function deserializeTable(jsonString)
return game:GetService("HttpService"):JSONDecode(jsonString)
end
local function savePlayerData(player)
local playerData = {}
-- Example of player data, imagine we store their inventory
playerData.inventory = {
pickaxe = { health = 100 },
sword = { health = 100 }
}
-- Serialize player data to JSON string
local dataString = serializeTable(playerData)
-- Save to DataStore
local success, errorMessage = pcall(function()
playerDataStore:SetAsync(player.UserId, dataString)
end)
if not success then
warn("Failed to save data for player " .. player.Name .. ": " .. errorMessage)
end
end
local function loadPlayerData(player)
-- Load data from DataStore
local success, result = pcall(function()
return playerDataStore:GetAsync(player.UserId)
end)
if success then
-- Deserialize the JSON string back into a Lua table
local playerData = deserializeTable(result)
-- Process player data, for example, restoring their inventory
print(playerData.inventory.pickaxe.health) -- Just an example of accessing loaded data
else
warn("Failed to load data for player " .. player.Name .. ": " .. result)
end
end
-- Events
Players.PlayerAdded:Connect(function(player)
loadPlayerData(player)
end)
Players.PlayerRemoving:Connect(function(player)
savePlayerData(player)
end)
Just a couple of bits I would like to add to this.
You don’t need to serialise the table in to a JSON string. As long as it only contains numbers, strings, and Booleans, it will save fine.
Use UpdateAsync() instead of SetAsync(), and use multiple attempts in case it fails at first. UpdateAsync() allows you to compare data (allows you to use data versioning as well), and even then, if you don’t add extra code, it has certain safety features that SetAsync() doesn’t. Just helps to prevent data loss.
Yeah, I’ve never done this before. I’m going to have to look at the documentation on it. I’ve always assumed the saving the instances was the only way.
How would you go about adding to the “inventory” table from another script.?