I am not too experienced with data stores, and i am having trouble saving my player's string value data. And yes, i tried the wiki and stuff but it still doesnt seem to work.
This is what i tried so far:
local ds = game:GetService("DataStoreService"):GetDataStore("Stats") local stats={"Slot1","Slot2","Slot3","Slot4","Slot5","Slot6","Slot7","Slot8","Slot9","Slot10"} game.Players.PlayerAdded:connect(function(plyr) local a=Instance.new("StringValue") a.Parent=plyr a.Name="Characters" for i=1,#stats do local stat=Instance.new("StringValue") stat.Parent=a stat.Value = "None" stat.Name=stats[i] end local child=plyr.Characters:GetChildren() for i=1, #child do child[i].Value=ds:GetAsync(plyr.userId..child[i].Name) end end) game.Players.PlayerRemoving:connect(function(plyr) local child=plyr.Characters:GetChildren() for i=1, #child do child[i].Value=ds:SetAsync(plyr.userId..child[i].Name,child[i].Value) end end)
I get this from Output:
18:19:12.490 - ServerScriptService.DataStore:16: bad argument #3 to 'Value' (string expected, got nil) 18:19:12.491 - Stack Begin 18:19:12.491 - Script 'ServerScriptService.DataStore', Line 16 18:19:12.492 - Stack End
If someone can help then i would be greatly appreciated. Thanks!
The problem here is line fifteen where you put child[i].Name
. Child is a table containing the children of the Characters
instance and does not contain numerical indices.
In order to fix this, iterate through the children using a generic for loop so that you can get the value directly from each pass of the loop. This would be implemented like so:
for i , v in pairs(child) do v.Value = ds:GetAsync(ply.userID..v.Name) end
Because data stores are stored in the Roblox servers, they are prone to error due to problems like connectivity. For this reason, your call to GetAsync should be wrapped in a pcall()
function to handle any possible error correctly. In addition, a player joining for the first time will have a nil value for the player's corresponding data store. You should check if the value from the data store exists or not before using it. If it doesn't, set the value to some sort of default. Your final listener function to the PlayerAdded
event should be this:
game.Players.PlayerAdded:Connect(function(plyr) local a=Instance.new("StringValue") a.Parent=plyr a.Name="Characters" for i=1,#stats do local stat=Instance.new("StringValue") stat.Parent=a stat.Value = "None" stat.Name=stats[i] end for i , v in pairs(plyr.Characters:GetChildren()) do local success , value = pcall(function () return ds:GetAsync(plyr.userId..v.Name) end) if success then if value then v.Value = value else --Player is joining for the first time --and datastore is empty end else --handle error here end end end)