For a while now, I have been having data store issues, i'm trying to fix the two problems below.
Problem 1: Data does not always save and usually prints ("Data Has Not Been Saved.")
Problem 2: When the data is saved (“Data Has Been Saved!”) When I rejoin, the values are “nil” or “0”
I'm sorta new to data stores. So if anybody can tell me how to use more effectively, it would be greatly appreciated.
You are loading the data on line 59, but you don't actually read from it. You should rename the variable dataExists
to data
; after lines 70, 76, and 82, you should then have if data[v] then value.Value = data[v] end
Further, you can't save Color3 values in the datastore directly. You will need serialize/deserialize functions (put these before you use them):
local function serializeColor3(c) return {R=c.R, G=c.G, B=c.B} end local function deserializeColor3(data) return Color3.new(data.R, data.G, data.B) end
Call serializeColor3
whenever you want to save a Color3 and deserializeColor3 whenever you want to load one. Line 172 can become: storage[v.Name] = typeof(v.Value) == "Color3" and serializeColor3(v.Value) or v.Value
and after line 82 becomes if data[v] then value.Value = deserializeColor3(data[v]) end
Another mild concern is updating data. What happens if you later change what you want stored in the profile? I would assume you would want to use the data loaded where possible and use default values for the rest. You can do this by checking to see if 'data' has the desired key for each value (and ensuring that 'data' is at least an empty table so you don't need to check that each time). ex, instead of line 63 onward, you have:
-- init the profile variables just like you do on lines 65-87 -- if you wanted to do something only if this is a brand new player, you could check to see if data is nil here data = data or {} local random = Random.new(tick()) if not data.Age then playerFolder.Age.Value = agesTable[random:NextInteger(1, #agesTable)] end if not data.Clan or data.Clan == "" then playerFolder.Clan.Value = possibleClans[random:NextInteger(1, #possibleClans)] else playerFolder.Clan.Value = data.Clan end --etc
Also, if there is no "data" (you check if there is data on line 170), you probably shouldn't save anything - you'd be overwriting anything they had previously. (This is not responsible for your problems, but is a good idea to fix in case something goes wrong.)
Other notes:
wait()
line 186fetch
is false, something has gone wrong - you should consider waiting a few seconds and trying again before telling the user you couldn't load their data. If this happens, you probably shouldn't save their data later, either - you would overwrite their earlier save (if they had any) - you could ask the user what they want to do.FindFirstChild
when you're loading in default data (and there's no point in using FindFirstChild if you aren't going to check to see if a child was found anyway). ex, instead of playerFolder:FindFirstChild("Age").Value
, just say playerFolder.Age.Value