Datastores saving issues

completley works for me
image

dont mind all the comented stuff just did that so i didnt have to make a screengui with all the values

1 Like

the values are named correctly, the issue occurs when the players leaves the game. I dont know how bindtoclose() works so i dont know how to fix it

1 Like

if you keep it like this it should work completley
image

2 Likes

I dont understand how the data is being saved. There is nothing that asks for the values. How does it know what values to save? It is saving nil

The only time that the values are being referenced is at the beginning of the playeradded where it sets the values of the saved information but it never saves the data when the player leaves.

1 Like

its not saving nil, its looping through the playerdata table and saving that data to the correct place because if not done then the playerdata will be destroyed before it can be saved

image
image

1 Like

The values of the objects are the int values not “player data”

image

1 Like

i suggest you do a little more reading on bind to close, datastores, tables and dictionaries

let me reitterate, those values in the screen gui are just being set when player is added they are not updated and do not interact with the main script at all, the playerdata dictionary is in the main script which hold the playersuserid joined with the dataname as a key to strore a table of values that you then use later

2 Likes

there is no table/dictionary using this information that i can visually see. I only see a table entitled PlayerData with 0 values located inside of it. You appear to try to be finding values inside this table with 0 values.

Maybe Data in your script was supposed to be PlayerData?

Even then it never changes the value of those 0’s to the int value’s values.

1 Like

thats because you never set it up to do that

1 Like

You’re gaslighting me at this point because you don’t want to realize the mistake bruh.

Look, thank you for helping me. You’re introducing new methods that are very helpful. I’m sorry for coming off as aggressive in this message but I had became angry because I felt confused earlier. This is not necessarily your fault it’s just me being stupid. I got mad because you told me to re-read datastores, tables, and dictionaries which made me feel bad about my own abilities.

1 Like

im not about to go round and round with you but ive told you the problem… multiple times but you keep trying to prove me wrong. i will tell you 1 more time,if you want the values in screengui to match the ones in the mainscript then you have to set it up to do that ie putting some code into the setdata function, look at all my other messages to get the wrest of the infromation or just use roblox doccumentation to get the wrest but again ive told you multiple times how to fix it
Hope you fix it cya

2 Likes

and i didnt mean it like that i just meant that maybe you should take a quick look at them again, no one is perfect it took me years to get the knoledge i have no one should ever feel ashamed to go back and look at API heck i do it alot lol

2 Likes

okay so i think this should be good:

local Datastores = game:GetService("DataStoreService")
local ExperienceStorage = Datastores:GetDataStore("PlayerExperience")
local ServerActive = true
local PlayerData = {}

local function setdata(Player, DataName, Val)
	PlayerData[Player.UserId..DataName] = Val
	ExperienceStorage:SetAsync(Player.UserId..DataName, Val)
end

local function getdata(Player, DataName)
	local HI = ExperienceStorage:GetAsync(Player.UserId..DataName)
	if HI == nil then 
		print("not found data")
		HI = {0,0,0,0,0,0,0,0,0,0,0,1,0,0} 
	end
	return HI
end

game.Players.PlayerAdded:Connect(function(Player)

	repeat wait() until Player.PlayerGui:FindFirstChild("ScreenGui")
	local ScreenGui = Player.PlayerGui:FindFirstChild("ScreenGui")
	

	local PlayerData = getdata(Player, 'Data')

	ScreenGui.Small.Value = PlayerData[1]
	ScreenGui.Mid.Value = PlayerData[2]
	ScreenGui.Long.Value = PlayerData[3]
	ScreenGui.SmallMoving.Value = PlayerData[4]
	ScreenGui.MidMoving.Value = PlayerData[5]
	ScreenGui.LongMoving.Value = PlayerData[6]
	ScreenGui.Wallpaper.Value = PlayerData[7]
	ScreenGui.Crosshair.Value = PlayerData[8]
	ScreenGui.Coins.Value = PlayerData[9]
	ScreenGui.Gems.Value = PlayerData[10]
	ScreenGui.Progress.Value = PlayerData[11]
	ScreenGui.Lv.Value = PlayerData[12]
	ScreenGui.Lv_Boost.Value = PlayerData[13]
	ScreenGui.Coin_Boost.Value = PlayerData[14]

end)

game.Players.PlayerRemoving:Connect(function(Player)
	wait(0.1)
	local screen = Player.PlayerGui.ScreenGui
	PlayerData = {screen.Small.Value,screen.Mid.Value,screen.Long.Value,screen.SmallMoving.Value,screen.MidMoving.Value,screen.LongMoving.Value,screen.Wallpaper.Value,screen.Crosshair.Value,screen.Coins.Value,screen.Gems.Value,screen.Progress.Value,screen.Lv.Value,screen.Lv_Boost.Value,screen.Coin_Boost.Value} 
	if ServerActive then setdata(Player, 'Data', PlayerData[Player.UserId]) end
end)

game:BindToClose(function()
	ServerActive = false
	for Key, PlayerData in pairs(PlayerData) do
		ExperienceStorage:SetAsync(Key, PlayerData)
	end
end)

I reference the screengui values when the player is leaving which I’m not sure if I’m supposed to do because I think the entire point of this is to not do that

yep that should be good the only thing i would suggest is moving the playerdata setting from player removing to setdata or get data but other than that it should be good

ok so i just thought of this, all ur values will not set by checking them because the client cannot speak to the server unless through a function or event if you want to make that you have to make an event that is fired to set playerdata to be saved so that the server can see the new values but i would also be careful in how you implement this because an exploiter can very easily take advantage of that event or function

One optimization, if your data is being lost is to change …:SetAsync(…, …) to

...:UpdateAsync(player.UserId..DataName, function(val)
    return val
end)
2 Likes

I also don’t know why player.UserId…DataName has two periods. Can I get an explanation for that?

1 Like

the client can see the values changed by the server for int values and i use a remote event to change any value from the client already.

1 Like

I don’t think the amount of periods between 2 and 3 matter. If you’re using official lua i think you have to use 2 periods (On lua demo at least)

1 Like

to join the 2 values ie 56456457Data is what it would be
only 2 periods will work

1 Like

Hey the code is still not working. It just says “Not found data” everytime i play the code.

code:

local Datastores = game:GetService("DataStoreService")
local ExperienceStorage = Datastores:GetDataStore("PlayerExperience")
local ServerActive = true
local PlayerData = {}

local function setdata(Player, DataName, Val)
	PlayerData[Player.UserId..DataName] = Val
	ExperienceStorage:UpdateAsync(Player.UserId..DataName, Val)
end

local function getdata(Player, DataName)
	local HI = ExperienceStorage:GetAsync(Player.UserId..DataName)
	if HI == nil then 
		print("not found data")
		HI = {0,0,0,0,0,0,0,0,0,0,0,1,0,0} 
	end
	return HI
end

game.Players.PlayerAdded:Connect(function(Player)

	repeat wait() until Player.PlayerGui:FindFirstChild("ScreenGui")
	local ScreenGui = Player.PlayerGui:FindFirstChild("ScreenGui")
	

	local PlayerData = getdata(Player, 'Data')

	ScreenGui.Small.Value = PlayerData[1]
	ScreenGui.Mid.Value = PlayerData[2]
	ScreenGui.Long.Value = PlayerData[3]
	ScreenGui.SmallMoving.Value = PlayerData[4]
	ScreenGui.MidMoving.Value = PlayerData[5]
	ScreenGui.LongMoving.Value = PlayerData[6]
	ScreenGui.Wallpaper.Value = PlayerData[7]
	ScreenGui.Crosshair.Value = PlayerData[8]
	ScreenGui.Coins.Value = PlayerData[9]
	ScreenGui.Gems.Value = PlayerData[10]
	ScreenGui.Progress.Value = PlayerData[11]
	ScreenGui.Lv.Value = PlayerData[12]
	ScreenGui.Lv_Boost.Value = PlayerData[13]
	ScreenGui.Coin_Boost.Value = PlayerData[14]
	
	 Small = ScreenGui.Small
	 Mid = ScreenGui.Mid
	 Long = ScreenGui.Long
	 Smallmoving = ScreenGui.SmallMoving
	 MidMoving = ScreenGui.MidMoving
	 LongMoving = ScreenGui.LongMoving
	 Wallpaper = ScreenGui.Wallpaper
	 Crosshair = ScreenGui.Crosshair
	 Coins = ScreenGui.Coins
	 Gems = ScreenGui.Gems
	 Progress= ScreenGui.Progress
	 Lv = ScreenGui.Lv
	 Lv_Boost = ScreenGui.Lv_Boost
	 Coin_Boost = ScreenGui.Coin_Boost
end)

game.Players.PlayerRemoving:Connect(function(Player)
	wait(0.1)
	
	PlayerData = {Small.Value,Mid.Value,Long.Value,Smallmoving.Value,MidMoving.Value,LongMoving.Value,Wallpaper.Value,Crosshair.Value,Coins.Value,Gems.Value,Progress.Value,Lv.Value,Lv_Boost.Value,Coin_Boost.Value} 
	if ServerActive then setdata(Player, 'Data', PlayerData[Player.UserId]) end
end)

game:BindToClose(function()
	ServerActive = false
	for Key, PlayerData in pairs(PlayerData) do
		ExperienceStorage:UpdateAsync(Key, PlayerData)
	end
end)

The value of the data is nil which means it’s being saved incorrectly.
I see:

ExperienceStorage:UpdateAsync(Key, PlayerData)

but i dont know if that is suppose to be the same key as:

ExperienceStorage:GetAsync(Player.UserId..DataName)
1 Like