How do I save Values in a DataStore that have been modified in a LocalScript?

I want to save Values in a DataStore that are stored in a Folder that is a Child of a player, these values are changed in a Local Script and whenever the player leaves it doesn’t save.

The saving works perfectly fine if you tried to change the values in the script.

I have tried using RemoteEvents to fire the the values to the server, didn’t work.

PS. I started DataStore like a day ago so I’m very sorry if I’ve missed something obvious!

local Players = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")
local DSS = game:GetService("DataStoreService")
local DS = DSS:GetDataStore("Test5")

Players.PlayerAdded:Connect(function(plr)
	
	local key = plr.UserId
	
	-- Value Holders
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = plr
	
	local playerstats = Instance.new("Folder")
	playerstats.Name = "playerstats"
	playerstats.Parent = plr
	
	-- Values
	local Value1 = Instance.new("IntValue")
	Value1.Name = "Value1"
	Value1.Parent = leaderstats
	
	local Value2= Instance.new("IntValue")
	Value2.Name = "Value2"
	Value2.Parent = playerstats
	
	local Value3= Instance.new("NumberValue")
	Value3.Name = "PixelSize"
	Value.Parent = playerstats
	
	local data = DS:GetAsync(key)

	
	if data then
		Value1.Value = data.Value1
		Value2.Value = data.Value2
		Value3.Value = data.Value3
	else
		Value1.Value = 1
		Value2.Value = 1
		Value3.Value = 1
	end	
end)

Players.PlayerRemoving:Connect(function(plr)
	local key = plr.UserId
	
	local data = {
		Value1 = plr.leaderstats.Value1.Value,
		Value2 = plr.playerstats.Value2.Value,
		Value3 = plr.playerstats.Value3.Value
	}
	
	DS:SetAsync(key, data)
	
	print("player has left")	
end)

In cases like these, you should be using RemoteEvents.
Let’s say we didn’t care about security or spamming. We could fire an event every time you want to update a value on the client to save it on the server. Then the server receives the new value and updates the leaderstat value accordingly.

-- LocalScript
local remote = ... -- lets say this updated Value1
remote:FireServer(123)
-- Script
local remote = ...
remote.OnServerEvent:Connect(function(player, value)
    player.leaderstats.Value1.Value = value
end

You can’t exactly send over data from the client to the server last minute since when you leave, your client would already have been disconnected, which means you data won’t be saved properly. I would go with the method I mentioned above if you don’t care about security and just need to send over client data, but make sure to add sanity checks and make it not so exploitable yourself.

2 Likes

I really don’t know how I forgot to do this, but tysm!
Do you have any ideas on how I could make it more secure?

validate user input.
for example, numbers;

floor and clamp them;

math.clamp(math.floor(number), 0, 100)

1 Like

Not really since I don’t know what you are planning on doing with those values. But if you were to send over numbers, you could double check those and see if they’re allowed.

For example, if I don’t want to save negative numbers and an exploiter tries to fire the remote with a negative number. You could use math.abs on the server to turn the negative number into a positive, or you could cancel it and not set the value if it’s negative.

If it’s a NaN value, then just cancel it.

if number ~= number then -- NaN
    return
end

If you want the number to be within range of 2 other numbers, then use math.clamp

There are many ways to secure your values but you could do these for starters.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.