After reading trough it I noticed that they didnt’t even get the saving to work in this post.
For using data stores I would recommend reading the tutorial:
https://developer.roblox.com/en-us/articles/Saving-Player-Data
Another useful thread I found:
https://devforum.roblox.com/t/stop-using-setasync-to-save-player-data/276457
You will also need a method of converting a table with your saved data back into your folder structure once it is retrieved. Something like:
function restore(folder, userData)
for key, amount in pairs(userData) do
local s = Instance.new("StringValue")
s.Name = key
s.Parent = folder
local a = Instance.new("IntValue")
a.Name = "Amount"
a.Value = amount
a.Parent = s
end
end
Is there any way first to check if I saved the data?
Could I maybe print out the #Table? Because I am not very sure if it saves in the first place.
To add on and help you with this, you could use this as for saving models and this is something you could do:
local Models = game:GetService("ServerStorage"):WaitForChild("Models") -- Replace with correct path
local datastore = game:GetService("DataStoreService"):GetDataStore("ModelSave")
game.Players.PlayerAdded:Connect(function(plr)
local good, info = pcall(function()
return datastore:GetAsync(plr.UserId)
end)
if good then
for i,v in pairs(info) do
local model = Models[v]
--Load Model
end
end
end)
game.Players.PlayerRemoving:Connect(function(plr)
local Model = --Path to their Model
local InfoToSave = {}
for i,v in pairs(Model:GetChildren()) do
table.insert(InfoToSave, v.Name)
end
datastore:SetAsync(plr.UserId, InfoToSave)
end)
This may have bugs, but I believe it should be ok.
And yes you can check to see if the table has saved something by printing it in the load section of your data store. I am not too sure on checking the whole table b/c you can’t print a table in the output, you probably could put in a for loop to see what has saved in it though and print each thing individually.
Alright, I believe I am very close to get it working. I’ve got an error on this part of the code
local good, info = pcall(function()
return datastore:GetAsync(player.UserId)
end)
if good then
for i,v in pairs(info) do
restore(folder,player.UserId)
end
end
ERROR:
[ServerScriptService.MainLeaderboard:57: bad argument #1 (table expected, got nil)]
Ive tried to implement the restore function aswell , here is my full code:
local datastore = game:GetService("DataStoreService"):GetDataStore("InventorySave")
game.Players.PlayerAdded:Connect(function(player)
local folder = Instance.new("Folder",game.ServerStorage.Inventory)
folder.Name = player.Name
local characterfolder = Instance.new("Folder",folder)
characterfolder.Name = "Character"
local shirtfolder = Instance.new("Folder",characterfolder)
shirtfolder.Name = "Shirts"
local pantsfolder = Instance.new("Folder",characterfolder)
pantsfolder.Name = "Pants"
local hatfolder = Instance.new("Folder",characterfolder)
hatfolder.Name = "Hats"
local weight = Instance.new("NumberValue",folder)
weight.Name = "Weight"
weight.Value = 0
local function NewDataTable()
local inv = {}
for i, v in pairs(game.ServerStorage.Inventory:FindFirstChild(player.Name):GetChildren()) do
if v:IsA("StringValue") then
local vprop = {i,v.Name,v.Amount.Value}
table.insert(inv,vprop)
end
end
return inv
end
--Load Data in
local function restore(folder, userData)
print("Trying to load it in")
for key, amount in pairs(userData) do
print("Zack")
local s = Instance.new("StringValue")
s.Name = key
s.Parent = folder
local a = Instance.new("IntValue")
a.Name = "Amount"
a.Value = amount
a.Parent = s
end
end
local good, info = pcall(function()
return datastore:GetAsync(player.UserId)
end)
if good then
for i,v in pairs(info) do
restore(folder,player.UserId)
end
end
game.Players.PlayerRemoving:Connect(function(player)
local InfoToSave = NewDataTable()
print(#InfoToSave)
datastore:SetAsync(player.UserId, InfoToSave)
end)
end)
Are you saving a StringValue
? You can’t save a string value to a data store, but you can save a string to one as I have discovered in my topic here (How would you save a string value? - #2 by Ravenshield)
I am not saving a stringvalue, I am creating a table with from the strinvalues. Somewhere at the start of this post I showed my hierarchy for storing the items. Im just creating a table and storing the stringvalue Names aswell as the Amount value.
Oh sorry about that misunderstanding, I need to get on studio for this to help see what exactly is going on. Something with your table is catching it as a nil value though. I will have more info on this later for you.
edit: or if someone else comes in with an answer
Would it help alot if I share this place with your sir? Do you think you could solve it maybe then?
I tried saving Table before, You can try json to encode the Table and then Decode the table that way will make you be able to make Save/Load file like one of those RPG where you have save slot and stuff but mainly You can save table if you json them if you don’t json them they will error out about UTF limit
It’s only necessary if you’re working with large tables who can maybe go over the maxlimit. This is not going to happen in my game.
Mine is not even that big, it’s just one table for it and it’s still calling me out on UTF
Even if I encode it with json I still don’t properly know how to save/load it ^^
You know the basic of Datastore right? or just knew it
I am super ■■■■■■■■ when it comes to datastore. Not gonna lie. I know how to save simple strings and int’s etc. but not tables. I really don’t know why it would make such a diffrence
I was able to find a video to help you on this:
He has a script in the description as well, so you can look at it for more help. It seems as if your table wasn’t declared yet though. See if this video helps you with any of your problems.
This helped me out in some way but I can’t get it working with my table somehow. I don’t know my problem and it’s frustrating me for the past 2 days…
Hello!
First of all, you should read through
as Blokav already mentioned.
Then you would create the structure inside ServerStorage when game.Players.PlayerAdded
You should also think of an structure of the array as well, I would choose something like this :
local Inventory = {
Apple = 0;
Banana = 0;
Log = 0;
}
When the player leaves with game.Players.PlayerRemoving
you will want to loop through inventory in ServerStorage and create an array which you will save:
local HttpService = game:GetService("HttpService")
local DataStore = game:GetService("DataStoreService"):GetDataStore("Data")
game.Players.PlayerRemoving:connect(function(Player)
local dataToSave = {}
for i, v in pairs(game.ServerStorage.Inventory:FindFirstChild(Player.Name):GetChildren()) do
if v:FindFirstChild("Amount") then
dataToSave[v.Name] = v.Amount.Value
end
end
pcall(function()
DataStore:SetAsync(Player.UserId,HttpService:JSONEncode(dataToSave))
end)
end)
And then simply load it everytime player joins as I mentioned already :
local HttpService = game:GetService("HttpService")
local DataStore = game:GetService("DataStoreService"):GetDataStore("Data")
game.Players.PlayerAdded:connect(function(Player)
local newData = DataStore:GetAsync(Player.UserId)
if newData then
newData = HttpService:JSONDecode(newData)
-- load data here, newData.Apple, newData.Banana, newData.Log, they return the amount of each.
else
-- create new data (player joined for the first time
end
end)
Hope I helped.
Problem is that I cannot create a strucute like you did, it won’t work with my system rn. hmm
You’ll want to use the HttpService - it has two functions, :JSONEncode()
and :JSONDecode()
, which allow you to encode and decode tables and strings respectively.
To use this simply pass the table as an argument into JSONEncode and save the returned string. When loading the data, you simply load the string and pass it into JSONDecode to get a table again.
This works for tables with non-numerical keys, but if a table contains more tables (common in object-orientated paradigm) you will need to recursively encode and decode the tables, otherwise data will be lost.