I’ve edited my script so that it would save player’s hats that hey have bought. But it isn’t working and no errors are turning up in the output which means an if statement is probably returning false somewhere.
--} Reference services:
local RS = game:GetService("ReplicatedStorage");
local DSS = game:GetService("DataStoreService");
local P = game:GetService("Players");
--} Reference variables:
local bytes = {
{97, 122}; --! a-z:
{65, 90}; --! A-Z:
{48, 57}; --! 0-9:
};
local overwrite = true;
local vault = DSS:GetDataStore("Test");
--} Reference functions:
function GetRandomCharacter()
local charset = bytes[math.random(1, 3)];
return string.char(math.random(charset[1], charset[2]));
end;
function GenerateID(len)
local id;
for i = 1, len do
local char = GetRandomCharacter();
if not id then
id = char;
else
id = id .. char;
end;
end;
return id;
end;
function SaveData(plr, uid)
local pack = plr:WaitForChild("Backpack");
local gear = plr:WaitForChild("StarterGear");
local hats = plr:WaitForChild("Hats")
local keys = {};
if #gear:GetChildren() > 0 then
for i, v in next, gear:GetChildren() do
keys[GenerateID(20)] = v.Name;
end;
end;
if #hats:GetChildren() > 0 then
for x, y in next, hats:GetChildren() do
keys[GenerateID(25)] = y.Name;
print("Got hat keys")
end
end
vault:SetAsync(uid, keys);
end;
function LoadData(plr, uid)
local pack = plr:WaitForChild("Backpack");
local gear = plr:WaitForChild("StarterGear");
local hats = plr:WaitForChild("Hats");
for i, v in next, vault:GetAsync(uid) do
for x, y in next, RS:GetChildren() do
if v == y.Name then
y:Clone().Parent = pack;
y:Clone().Parent = gear;
for g, l in next, RS.HatShop.ShopItem:GetChildren() do
if v == l.Name then
l:Clone().Parent = hats;
print("Loaded hats")
end;
end;
end;
end;
end;
end;
P.PlayerAdded:connect(function(plr)
local uid = plr.userId;
if vault:GetAsync(uid) then
LoadData(plr, uid);
print("Worked - game.Workspace.Data Store")
else
return;
end;
end);
P.PlayerRemoving:connect(function(plr)
local uid = plr.userId;
if overwrite then
SaveData(plr, uid);
else
return;
end;
end);
What I have done is removed loadHats() and saveHats(). I put the hat saving part in to both load and save functions however I think there may be a problem in the saving function where it says:
if #hats:GetChildren() > 0 then
for x, y in next, hats:GetChildren() do
keys[GenerateID(25)] = y.Name;
because when loading the hats it doesn’t seem to recognise anything stored in the datastore in replicatedstorage. Which results in “Loaded Hats” not being printed and hats not being cloned.
I only have a short observation as I am on phone
there is no “local hats = plr:WaitForChild(“Hats”)”
I suppose that’s what you edited?
hats are placed in a character, unlike inactive gear (StarterGear/Backpack)
function SaveData(plr, uid)
local pack = plr:WaitForChild("Backpack");
local gear = plr:WaitForChild("StarterGear");
local hats = plr:WaitForChild("Hats")
local keys = {};
if #gear:GetChildren() > 0 then
for i, v in next, gear:GetChildren() do
keys[GenerateID(20)] = v.Name;
end;
end;
if #hats:GetChildren() > 0 then
for x, y in next, hats:GetChildren() do
keys[GenerateID(25)] = y.Name;
print("Got hat keys")
end
end
vault:SetAsync(uid, keys);
end;
you placed the check for hats inside the check for gears, instead of before or after it
this makes it check for hats only when an element in the datastore matches the name of a gear
a clearer explanation is that a hat will only be loaded if it has the same name as a gear, because it’s inside the hat check is inside the gear check and a condition of that is the name to match one of a gear
that’s what I’ve seen in the load function, and I think it should look more like this
function LoadData(plr, uid)
local pack = plr:WaitForChild("Backpack");
local gear = plr:WaitForChild("StarterGear");
local hats = plr:WaitForChild("Hats");
for i, v in next, vault:GetAsync(uid) do
for x, y in next, RS:GetChildren() do
if v == y.Name then
y:Clone().Parent = pack;
y:Clone().Parent = gear;
end;
end;
for g, l in next, RS.HatShop.ShopItem:GetChildren() do
if v == l.Name then
l:Clone().Parent = hats;
print("Loaded hats")
end;
end;
end;
end;
ofcourse, that won’t work either if the hats are not saved in the first place
are you sure the hats are not saved? does “got hat keys” not print?
we could then look at what is inside of “keys” before doing setasync in datastore
since you said it does print “Got hat keys”, it does try to put something in there
instead of
keys[GenerateID(25)] = y.Name;
you could try doing
local generatedID = GenerateId(25);
keys[generatedID] = y.Name;
print("saved",y.Name,"as",keys[generatedID])
this way you could check what saves and if it does get put into “keys” after the attribution
if it doesn’t get put into “keys”, it will show up as “saved (hat as”, with nothing after “as”
although I suspect it would be the datastore that doesn’t agree with a 25 characters long index, rather than the “keys” dictionary
The first thing you should do to debug this is print out all the data you are trying to load.
In LoadData do:
for i, v in next, vault:GetAsync(uid) do
print(i, " = ", v)
---Rest of your code.
See if the names of your hats get printed correctly. If they do not, then you have a problem in your saving code not the loading code.
Another key problem with this datastore code is that you will save a players data even if you did not sucessfully load their data (This causes their data to be overwritten). You should keep a table of players whose data has been successfully loaded so you know whether or not to save.
Your LoadData function could also be much improved using :FindFirstChild instead of looping through everything. Also the inner for loop does not make sense to be there, it should be separate from the code for gears. Something like this would be much better:
function LoadData(plr, uid)
local pack = plr:WaitForChild("Backpack");
local gear = plr:WaitForChild("StarterGear");
local hats = plr:WaitForChild("Hats");
for i, v in next, vault:GetAsync(uid) do
print("Loading: ", i, " = ", v)
local tool = RS:FindFirstChild(v)
if tool then
tool:Clone().Parent = pack
tool:Clone().Parent = gear
end
local hat = RS.HatShop.ShopItem:FindFirstChild(v)
if hat then
hat:Clone().Parent = hats
end
end
considering the results of above prints, I’d assume that there’s no hat name stored in the datastore, so that’s why I went on and suggested checking of the savedata function
Sounds like the problem might be that the hats are never placed in the Hats folder, since that code works the exact same way as the gear saving code that does work. Where and how is it done @WhatZitTooyya ?