Evening, I’m having trouble with this script i’m making:
DSS = game:GetService("DataStoreService")
HTTPS = game:GetService("HttpService")
local CharStats = DSS:GetDataStore("MainCharacterStats")
PlrStats = {
['Currency'] = 0,
['CoreShape'] = "None",
['CoreType'] = "None"
}
game.Players.PlayerAdded:Connect(function(Joinedplr)
--local success, errorMessage = pcall(function()
local ObtainedData = CharStats:GetAsync(Joinedplr.UserId)
if ObtainedData then
local ObtainedData = HTTPS:JSONDecode(ObtainedData)
print(tostring(ObtainedData['Currency']))
else print("No Data.")
end
end)
--[[if errorMessage then
print("Error occured whilst Saving")
warn(errorMessage)
end
end)]]
game.Players.PlayerRemoving:Connect(function(Leftplr)
local success, errorMessage = pcall(function()
CharStats:SetAsync(Leftplr.UserId.."BasicStats",HTTPS:JSONEncode(PlrStats))
print("Data saved Successfully.")
end)
if errorMessage then
print("Error occured whilst Saving")
warn(errorMessage)
end
end)
I’m trying to turn a dictionary into a JSON format so it can be stored into a Datastore but i’m getting the title error whenever asking the script to Decode the data.
Any help is appreciated, i’m very new to datastores so i’m not 100% sure of what im doing is efficent or if there is a better way of going around it.
the three questions above, you should probably pick a different category.
Apparently Datastores can’t store Dictionaries or Tables, so people usually encode it into JSON which datastores can keep. and then decode it back when the data is called back.
You may have heard that you’d need to run HttpService:JSONEncode() on it to turn the table into a string but IIRC it is completely unnecessary as Roblox turns the table into a string with or without the JSONEncode function. Summed up it’s just repeating a function that Roblox is already running and a general waste of time.
tl;dr yes you can use :SetAsync() without doing anything to the table
Quoting someone else but yes datastores can save tables.
You wouldn’t put local infront of it anymore either as it’s been declared already, I think yo ucan fix your entire issue by removing local infront of ObtainedData (the second one)
game.Players.PlayerAdded:Connect(function(Joinedplr)
--local success, errorMessage = pcall(function()
local ObtainedData = CharStats:GetAsync(Joinedplr.UserId) -- FIRST LOCAL
if ObtainedData then
local ObtainedData = HTTPS:JSONDecode(ObtainedData) -- ALREADY SET AS LOCAL ABOVE
print(tostring(ObtainedData['Currency']))
else print("No Data.")
end
end)
if errorMessage then
print("Error occured whilst Saving")
warn(errorMessage)
end
end
So just remove the local or rename it:
game.Players.PlayerAdded:Connect(function(Joinedplr)
--local success, errorMessage = pcall(function()
local ObtainedData = CharStats:GetAsync(Joinedplr.UserId)
if ObtainedData then
ObtainedData = HTTPS:JSONDecode(ObtainedData) -- LOCAL GONE/RENAMED (local decoded = HTTPS:JSONDecode(ObtainedData)
print(tostring(ObtainedData['Currency']))
else print("No Data.")
end
end)
--[[if errorMessage then
print("Error occured whilst Saving")
warn(errorMessage)
end
end
yeah I removed the JSON encode thingy, I thought you had to do that since multiple articles said so, must’ve been updated at some point i suppose but i don’t really know, nice to hear i dont need to do that though, thanks!
doing as you’ve said, i’m not getting the error anymore but data still isn’t being retrieved (“no data”) is still being printed only
removing the else statement doesn’t show an error either
wrap it in a pcall and print the error, I use modules usually so I don’t run into data issues much, try the pcall thing and send the output and FULL code please.
I see, I haven’t actually used return before so I didn’t know, thanks!
I’ve noticed that print statements don’t work when being placed after a return, so I can’t check if saving was successful
So, I quickly made a small clickdetector that gives me 500 on the currency value every time its clicked. I did confirm that this was working as it prints teh added values in the output:
Despite this however, re-entering the game sets the currency value back to 0, so it was never saved.
return always end a function, so you want to put it at the end, alternatively it can be used to exit out of a function early:
local isCool = false
local function areYouCool()
if not isCool then return end
print("He's cool")
end
In this case it will never get printed because the condition wasn’t met
Back to your data stores though
“I’ve noticed that print statements don’t work when being placed after a return, so I can’t check if saving was successful”
You can, just print success.
Despite this however, re-entering the game sets the currency value back to 0, so it was never saved.
You’re setting data even before checking if said player has any data, you wanna do GetAsync and THEN if the player has no data (it will return nil), will you want to set the players data.
In other words when a players join you’ll first do getasync, if it returns data boom you have your data, if it doesn’t, then give the player base data by doing setasync (Like setting their coins to 0 etc.)
Data is complicated and a lot can go wrong, I recommend using a module if you’re no proficient enough to make your own, people can easily lose data if the server crashes and so on.