How can i safe attributes in datastores?

i now have just started learning datastores and i cant safe any attribute, i have an attribute that indicates the player’s energy and it wont safe, the data is nil when i print it, and even if it wasnt nil my local script that does the energy stuff sees that the attribute nil even tho it shouldnt be, anyways heres the script

also correct my script if im wrong considering i just started learning datastores:

local player = game.Players
local datastores = game:GetService("DataStoreService")

local EnergyData = datastores:GetDataStore("EnergyData")

player.PlayerAdded:Connect(function(plr)
	
	local EnergyValue = plr.PlayerGui:WaitForChild("ScreenUi").Bars.Energy.EnergyValue
	
	local PlayerUserId = "Player_".. plr.UserId
	
	print(PlayerUserId)
	local Data
	local success, errormessage = pcall(function()
		
		Data = EnergyData:GetAsync(PlayerUserId)

	end)
	
	if success then
		
		EnergyValue:SetAttribute("EnergyValue", Data)
		
		print("Data Loaded Successfully")
		
	else
		
		EnergyValue:SetAttribute("EnergyValue", 100)
		print("Encountered An Error While Loading Data")
		warn(errormessage)
		
	end
	
	
end)

player.PlayerRemoving:Connect(function(plr)
	
	local PlayerUserId = "Player_".. plr.UserId
	
	local EnergyValue = plr.PlayerGui:WaitForChild("ScreenUi").Bars.Energy.EnergyValue
	
	local Data
	local success, errormessage = pcall(function()
		
	EnergyData:SetAsync(PlayerUserId, EnergyValue:GetAttribute("EnergyValue"))
		
	end)
	
	if success then
		
		print("Data Have Been Successfully Saved")
		
	else
		
		warn(errormessage)
		
		print("Encountered An Error While Saving Data")
		
	end	
	
end)
1 Like

If you’re setting the attribute via a LocalScript, that won’t replicate between the client/server boundary. You would need to fire a RemoteEvent to update the value on the server

Client-Server Boundary
RemoteEvents

1 Like

No i am not setting any attribute i have created this attribute without any scripts, what i meant is that the local script dosent see the attribute value

What type value is “EnergyValue”? Is it an Integer and is the attribute ever actually set?

sorry for the late response the value is a number value

Well, I noticed you’re trying to grab from a Player’s PlayerGui from the server – it doesn’t quite work like that, you need to use a RemoteEvent to pass what the EnergyValue is supposed to be set to from the Server to the Client. I’d suggest adding a print line after “GetAsync()” to make sure the value is actually being set as well.

1 Like

Something like this should help;

LocalScript

local plr = game.Players.LocalPlayer
local ScreenGui = script.Parent
local MainRE = game.ReplicatedStorage.MainRE


local function ExampleSetEnergy(value)
	MainRE:FireServer({
		Action = 'SetEnergyValue',
		Value = value,
	})
end

ExampleSetEnergy(math.random(0,100))

MainRE.OnClientEvent:Connect(function(args)
	if args.Action == 'SetEnergyValue' then
		ScreenGui.Bars.Energy.EnergyValue:SetAttribute('EnergyValue',args.Value)
	end
end)

Server Script

local datastores = game:GetService("DataStoreService")
local EnergyData = datastores:GetDataStore("EnergyData")
local MainRE = game.ReplicatedStorage.MainRE

local PlayerDatas = {}

game.Players.PlayerAdded:Connect(function(plr)
	PlayerDatas[plr.Name] = {}
	local PlayerUserId = "Player_".. plr.UserId

	print(PlayerUserId)
	local Data
	local success, errormessage = pcall(function()

		Data = EnergyData:GetAsync(PlayerUserId)

	end)

	if success then
		PlayerDatas[plr.Name].Energy = Data
		local success = pcall(function() 
			MainRE:FireClient(plr,{
				Action = 'SetEnergyValue',
				Value = Data,
			})
		end)
		
		if success then
			print('set value')
		end
		print("Data Loaded Successfully")

	else
		PlayerDatas[plr.Name].Energy = 100
		local success = pcall(function() 
			MainRE:FireClient(plr,{
				Action = 'SetEnergyValue',
				Value = 100,
			})
		end)

		if success then
			print('set value')
		end
		print("Encountered An Error While Loading Data")
		warn(errormessage)

	end


end)

game.Players.PlayerRemoving:Connect(function(plr)
	if not PlayerDatas[plr.Name] then return end
	local PlayerUserId = "Player_".. plr.UserId

	local EnergyValue = PlayerDatas[plr.Name].Energy

	local Data
	local success, errormessage = pcall(function()
		EnergyData:SetAsync(PlayerUserId, EnergyValue)
	end)

	if success then
		print("Data Have Been Successfully Saved")
	else
		warn(errormessage)
		print("Encountered An Error While Saving Data")
	end	
	PlayerDatas[plr.Name] = nil
end)

MainRE.OnServerEvent:Connect(function(plr,args)
	if args.Action == 'SetEnergyValue' then
		if PlayerDatas[plr.Name] then
			PlayerDatas[plr.Name].Energy = args.Energy		
		end
	end
end)