Need help with non-leaderstats datastore

So I’ve never done a datastore for values not in leaderstats. I tried to do one so that the IntValue holding the wood resources was saved and when a player joined it would update the Gui. When I join the game the value in the GUI does not change. Very suspiciously, it works in studio (After I go in game and mine the log).

Datastore:

local resourcesDataStore = game:GetService("DataStoreService"):GetDataStore("resourcesDataStore")
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(plr)
	local resourcesStored = Instance.new("Folder")
	resourcesStored.Name = "resourcesStored"
	resourcesStored.Parent = plr
	local woodResources = Instance.new("IntValue")
	woodResources.Name = "woodResources"
	woodResources.Parent = resourcesStored
	woodResources.Value = 0
	
	plr.PlayerGui:WaitForChild("ScreenGui")
	plr.PlayerGui.ScreenGui.Frame.WoodValue.Text = woodResources.Value
	
	local playerKey = "Player_"..plr.UserId
	local data
	local success, errormessage = pcall(function()
		data = resourcesDataStore:GetAsync(playerKey)
	end)
	if success then
		if data then
			plr:WaitForChild("resourcesStored").woodResources.Value = data
		else
			plr:WaitForChild("resourcesStored").woodResources.Value = 0
		end
	else
		print(errormessage)
	end
end)

Players.PlayerRemoving:Connect(function(plr)
	local playerKey = "Player_"..plr.UserId
	local success, errormessage = pcall(function()
		resourcesDataStore:SetAsync(playerKey, plr.resourcesStored.woodResources.Value)
	end)
	if not success then
		print(errormessage)
	end
end)

PlayerAdded Script that Updates Gui:


local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(plr)
	plr.PlayerGui:WaitForChild("ScreenGui")
	plr.PlayerGui.ScreenGui.Frame.WoodValue.Text = plr.resourcesStored.woodResources.Value
end)

Tool that sets data when wood is chopped:


local event = script.Parent:WaitForChild('RemoteEvent')
local canhit = false
local toolhandle = script.Parent:FindFirstChild('Handle')
local hitwoodsound = script.Parent:WaitForChild('Handle').WoodSound
local toolswingsound = script.Parent:WaitForChild('Handle').ToolSwing

event.OnServerEvent:Connect(function(plr)
	toolswingsound:Play()
	canhit = true
	toolhandle.Touched:Connect(function(hit)
		if hit.Parent.Name ~= plr.Name then
			if hit.Name == 'Log' and canhit then
				print(plr.Name..' hit a log.')
				hitwoodsound:Play()
				canhit = false
				hit.Durability.Value -= 1
				if hit.Durability.Value <= 0 then
					wait(0.5)
					hit:Destroy()
					plr.PlayerGui:WaitForChild("ScreenGui")
					plr.PlayerGui.ScreenGui.Frame.WoodValue.Text += 1
					plr.resourcesStored.woodResources.Value += 1
				end
			end
		end 
	end)
	wait(1)
	canhit = false
end)

It appears that the value is saving in output because it tells me the value is 5, but the GUI is not updating in studio anymore either. So the issue may actually not be my datastore, but with how I’m updating the GUI

Yes, because you can’t do plr.PlayerGui.ScreenGui.Frame.WoodValue.Text += 1. You can’t add a value to a text, as it’s a string. Instead, you should do this:

plr.PlayerGui.ScreenGui.Frame.WoodValue.Text = plr.resourcesStored.woodResources.Value
1 Like

Let me explain. If you do:

TextLabel.Text = "Hello!"
TextLabel.Text += 1

It is like trying to do this:

"Hello" + 1

That doesn’t make sense right? While if you do:

local Value = 5
TextLabel.Text = Value

The value will automatically be converted to a string, so the text will display 5 correctly.

1 Like

Thank you, it works now except it only updates once I actually chop a block of wood, is there an issue with how I’m updating the GUI on player join? Actually it only works half the time (very weird). I would imagine I need to add some kind of extra wait step?

I think you did:

plr.PlayerGui.ScreenGui.Frame.WoodValue.Text = plr.resourcesStored.woodResources.Value
plr.resourcesStored.woodResources.Value += 1

^^^ This first sets the text to the current value, then it sets the new value, so the text is actually the old value.
You have to do:

plr.resourcesStored.woodResources.Value += 1
plr.PlayerGui.ScreenGui.Frame.WoodValue.Text = plr.resourcesStored.woodResources.Value

^^^ This one instead, first sets the value and then sets the text to the updated value.

Actually I did the second one, but it only works half the time on join (the GUI, the data saves correctly).

Then why don’t you try using a .Changed event instead?

plr.resourcesStored.woodResources.Changed:Connect(function(NewValue)
   plr.PlayerGui.ScreenGui.Frame.WoodValue.Text = NewValue
end)
1 Like

Just to clarify, you mean in place of the PlayerAdded event, correct? So like the value is received once they join the game, then I change the GUI once that value has been changed? Nevermind, I see what you meant.

Yep, you can add it under the PlayerAdded, or maybe it’s better under CharacterAdded as everytime the player dies the GUI is re-created so the event might error and stop working.

1 Like