Is it possible to create a Table and save/Load it?

After reading trough it I noticed that they didnt’t even get the saving to work in this post.

2 Likes

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
1 Like

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.

2 Likes

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.

3 Likes

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.