Datastores saving issues

ExperienceStorage:UpdateAsync(Player.UserId..DataName, function(PlayerData)
    return PlayerData
end)

… I believe is the correct code for the updateasync function.

1 Like

it errors because its in the gameToclose function and the player doesnt exist (I presume)

source of this line of code:
(Player does not exist)
I have never used BindToClose() before i dont know how this works

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

BindToClose() just fires when the server needs to close. For instance, when you close the playtest on studio. The function can yield the server from closing for up to 30 seconds iirc. I recommend you store the player data into a module script, so it’s easy to access from anywhere, and just retrieve said data from the module script and save it when the player leaves/server closes.

1 Like

Do this inside of the bindtoclose function.

for i, plr in ipairs(players:GetPlayers()) do
    *code here*
end
1 Like

this will not work because when bindtoclose is fired no players are present in the game
That is the reason i suggested to do it in a dictionary bc that can be accessed anytime

1 Like

i did the suggestion however when i use getdata its still nil. this is the current 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, function(PlayerData)
		return PlayerData
	end)
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()
	for i,plr in ipairs(game.Players:GetPlayers()) do
		ServerActive = false
		for Key, PlayerData in pairs(PlayerData) do
			ExperienceStorage:UpdateAsync(plr.UserId..'Data', function(PlayerData)
				return PlayerData
			end)
		end
	end
end)
1 Like

by the way the server is one player which means i could save the players name in a variable.

1 Like

huh? the server and client are 2 seperate things by saving the players name as the key you risk them changing their name and them loosing all their data

1 Like

I can also save a variable with the UserID. anyways, with that aside, how come the script isnt working? Why does it keep saying the value is nil?? whats wrong with the code i dont see it

1 Like

I dont see what’s wrong with the code. I have been staring at it for the past 20 minutes and i cant see anything wrong. i feel like im losing my mind bruh

1 Like

use the code i origionally sent, whenever i try it it works

1 Like

I did 1 hour ago it didnt work because i needed to add the int values but that didnt work either so i tried more suggestions and now it still doesnt work even though it should work.

1 Like

I highly recommend that you rework the whole thing. Don’t use values, use a dictionary. It’s easier to manage, add/remove values and will persist after a player leaves, just make sure you set the player’s ID as the key (so you can save after they leave). I recommend you look at module scripts as well, because they can store data that multiple scripts can access.

1 Like

This is just a suggestion, but could easily be a good solution:

Use ProfileService.
It’s a public resource, it’s VERY easy to understand, and it has very reliable saving.

“The only thing better than perfect is standardized.” - Someone, sometime, somewhere

No need to reinvent the wheel unless you can make it rounder. :smiley:

1 Like

I need to change the values from other scripts

1 Like

Let me just interject here:

Attributes, use them.

Edit to clarify:

Attributes!

They’re:

  • Faster than Values
  • Integrated into ALL instances
  • Compatible with Events
  • Less resource intensive
  • Can be accessed and modified by multiple scripts.
  • Simply Better
1 Like

Yes, you can use bindable events to update the dictionary or just use a module script and have the data be accessible by multiple scripts at once.

1 Like

What about getting the data from the script to use for things like setting the text of textlabels to display the value?

1 Like

You can use remote events to send specific data to each player.

1 Like

how would i securely update values from the client? like if they clicked a button

i guess i could use remote events and sanity checks but i think the system could be vulnerable to exploits

1 Like