Ive written a datastore and something is going wrong…
Basically I created a datastore script (Shown below) and its not working right, all the values are made their defaults and I dont know why or how to fix it (values are basically 0, 0, 0, blank, blank, blank, blank)
CODE:
local Data = game:GetService('DataStoreService'):GetDataStore('SCPFStatsDatastore600')
local prefix = 'scpfstats_'
game.Players.PlayerAdded:Connect(function(player)
local Folder = Instance.new('Folder')
Folder.Name = 'status'
Folder.Parent = player
local Hunger = Instance.new('IntValue',Folder)
Hunger.Name = 'Hunger'
local Wellness = Instance.new('IntValue',Folder)
Wellness.Name = 'Wellness'
local Temperature = Instance.new('NumberValue',Folder)
Temperature.Name = 'Temperature'
local Happiness = Instance.new('IntValue',Folder)
Happiness.Name = 'Happiness'
local Physical = Instance.new('StringValue',Folder)
Physical.Name = 'Physical'
local Mental = Instance.new('StringValue',Folder)
Mental.Name = 'Mental'
local Injuries = Instance.new('StringValue',Folder)
Injuries.Name = 'Injuries'
local plrData = Data:GetAsync(prefix .. tostring(player.UserId))
if plrData then
Hunger.Value = plrData[1] or 100
Wellness.Value = plrData[2] or 100
Temperature.Value = plrData[3] or 98.6
Happiness.Value = plrData[4] or 100
Physical.Value = plrData[5] or ("Healthy")
Mental.Value = plrData[6] or ("Healthy")
Injuries.Value = plrData[7] or ("None")
else
Data:SetAsync(prefix .. tostring(player.UserId), {
Hunger.Value,
Wellness.Value,
Temperature.Value,
Happiness.Value,
Physical.Value,
Mental.Value,
Injuries.Value
})
end
while true do
wait(math.random(3*60,8*60))
if player.status.Hunger.Value > 0 then
player.status.Hunger.Value = player.status.Hunger.Value-5
end
if player.Status.Happiness.Value > 0 then
player.status.Happiness.Value = player.status.Happiness.Value-5
end
end
end)
game.Players.PlayerRemoving:Connect(function(player)
Data:SetAsync(prefix .. tostring(player.UserId), {
player.status.Hunger.Value,
player.status.Wellness.Value,
player.status.Temperature.Value,
player.status.Happiness.Value,
player.status.Physical.Value,
player.status.Mental.Value,
player.status.Injuries.Value
})
end)
Yeah my bad, I fixed it. Im trying to make it so the values are set the first time the player joins (or if they have no data in this datastore) but its not doing that its just setting it all to the default value of that ValueObject when you instance it.
I made a tutorial which explained an issue like that. I believe what is going on is the PlayerRemoving listener is not called, or it doesn’t finish because the server shut down when you left. The tutorial has more information on this. Also I recommend you wrap your data store requests in pcalls to properly handle any exceptions, i.e the data store request failed, so retry
Its not even just that, in the first place the data isnt being created. I copied this same code but added different values and such from another datastore ive made and it works fine.
I found your issue. In the if plrData then block, you set the values to the datas. But, if they don’t, you just set some data without actually setting the ValueBases values to that data. By the way don’t save player data when they join, you only load, only save when they leave and when the server shuts down and there are players left. Also save if you need to save tool purchases just to make sure it saves. Finally, Stop using SetAsync() to save player data
Also a tiny nitpick in your code, your strings dont need to be wrapped in parentheses
Okay so I know its been over 15 hours but I looked it over and im not entirely sure what you meant by your solution, would you mind explaining a little more?
local plrData = Data:GetAsync(prefix .. tostring(player.UserId))
if plrData then
Hunger.Value = plrData[1] or 100
Wellness.Value = plrData[2] or 100
Temperature.Value = plrData[3] or 98.6
Happiness.Value = plrData[4] or 100
Physical.Value = plrData[5] or ("Healthy")
Mental.Value = plrData[6] or ("Healthy")
Injuries.Value = plrData[7] or ("None")
else
Data:SetAsync(prefix .. tostring(player.UserId), {
Hunger.Value,
Wellness.Value,
Temperature.Value,
Happiness.Value,
Physical.Value,
Mental.Value,
Injuries.Value
})
end
@incapaxx is talking about that you don’t set the default values if the data isn’t found, it just sets the data store for the default values when the values are created and doesn’t change the values before it saves.
local plrData = Data:GetAsync(prefix .. tostring(player.UserId))
if plrData then
Hunger.Value = plrData[1] or 100
Wellness.Value = plrData[2] or 100
Temperature.Value = plrData[3] or 98.6
Happiness.Value = plrData[4] or 100
Physical.Value = plrData[5] or ("Healthy")
Mental.Value = plrData[6] or ("Healthy")
Injuries.Value = plrData[7] or ("None")
else
Hunger.Value = 100
Wellness.Value = 100
Temperature.Value = 98.6
Happiness.Value = 100
Physical.Value = "Healthy"
Mental.Value = "Healthy"
Injuries.Value = "None"
Data:SetAsync(prefix .. tostring(player.UserId), {
Hunger.Value,
Wellness.Value,
Temperature.Value,
Happiness.Value,
Physical.Value,
Mental.Value,
Injuries.Value
})
end
The above sets the values and saves after the values are set, and should fix your issue listed.
Meant to remove the or statements if the playerData is found (shown above), but really that’s the only problem I see.
It also could be that your testing in studio and not the game, since in studio you have to go to the game’s Configure Game and under that enable Studio Access to API Services before you can “test” data stores in studio.
The same thing happened to me, what I did was use update async too.
for example;
game.Players.PlayerRemoving:Connect(function()
if datastore:GetAsync(key) == nil then
dataStore:setAsync(key, yourvalue)
else
function blah()
return yourValue
end
DataStore:UpdateAsync(key, blah)
end
end)