How would I make a data system where it doesn't overwrite

This is my local script contacting a remote function to the data handler where it saves data.

local Data = {
	["Kills"] = 0,
	["Nickname"] = "",
	["Deaths"] = 0,
	["Banned"] = 0,
	["Warnings"] = 0
}
local playa = script.Parent.Parent.Parent
local rem = game.ReplicatedStorage.DataHandler
wait(3)
local pvo = nil
local z = rem:InvokeServer('Load',nil,true)
killc = z.Kills
local deathc = z.Deaths
print(deathc,z.Kills,z.Banned,z.Warnings,z.Nickname[1])
local savehand = game.ReplicatedStorage.SaveHandlerToClient
savehand.OnClientInvoke = print
if workspace:FindFirstChild(playa.Name) then
	pvo = workspace:FindFirstChild(playa.Name)
end
	local hum = pvo.Humanoid
	local banana = pvo.Data
	local Kills = script.Parent.k
	local Deaths = script.Parent.d
	local Warnings = script.Parent.w
	local Nickname = script.Parent.nick
	local Banned = script.Parent.ban
	if pvo.Data ~= nil or pvo ~= nil then
	local thefold = pvo.Data
	while wait(6) do
	local tabln = rem:InvokeServer('Load',nil,true)
	for i,z in pairs(tabln) do
		for i,b in pairs(Data) do
			if tabln.i ~= Data.i then
				
			elseif tabln.i == Data.i then
				Data.Kills = thefold.Kills.Value
	            Data.Deaths = thefold.Deaths.Value
	            Data.Banned = thefold.Banned.Value
	            Data.Warnings = thefold.Warnings.Value
	            Data.Nickname = thefold.Nickname.Value
			end
		end
	end
	rem:InvokeServer('Save',Data,true)
	Kills.Text = 'Kills: '..thefold.Kills.Value
	Deaths.Text = 'Deaths: '..thefold.Deaths.Value
	Warnings.Text = 'Warnings: '..thefold.Warnings.Value
	Banned.Text = 'Banned: '..thefold.Banned.Value
	Nickname.Text = 'Nickname: '..thefold.Nickname.Value
	tabln.Kills = Data.Kills
	tabln.Deaths = Data.Deaths
	tabln.Banned = Data.Banned
	tabln.Warnings = Data.Warnings
	tabln.Nickname = Data.Nickname
	thefold.Kills.Value = Data.Kills
	thefold.Deaths.Value = Data.Deaths
	thefold.Banned.Value = Data.Banned
	thefold.Warnings.Value = Data.Warnings
	thefold.Nickname.Value = Data.Nickname
	end
	hum.Died:connect(function()
		print('died')
	end)
end

The issue is that it is overrwriting, I have changed it up a few times so that it saves FIRST before loading. But that did not go so well when I rejoined. It’s overwriting data, I don’t have an idea on how to fix that.
Any tips or suggestions would be nice.

Well I was going to take a look at why its overwriting but then I quickly noticed a lot of things you are doing that could cause issues in your game so I will address those instead.

  1. Get the Player’s Character and Humanoid from the Players service, not the workspace.
    Server-side Example: game.Players.PlayerName.Character.Humanoid
    Client-side Example: game.Players.LocalPlayer.Character.Humanoid

  2. Do NOT manage data that is being saved, on the client side. You are basically letting the server trust the client and that is not good. Exploiters can use this to get the server to save anything they want, such as infinite stats.

You’re also reusing/overwriting i in your for loops…

Maybe use longer variable names? :smiley:

1 Like

If you see why there is a “true” when invoking server, that is the value if it is coming from a script, if it is false then that exploiter is banned.

I just noticed that. thanks! :smile:

while that is a clever move, it wont stop exploiters from reading the incoming data, and then just simply sending it back but with modified values. assuming they can do such things, as I do not know the full extent to what exploiters can see.

Also what Chicken said, using “for i” inside a “for i” will cause issues. you have to change the second i to a different letter that isn’t being used.

That may be true, but I do not have any other ways to stop that from happening.

Thats why this sort of thing is handled server side, so the server can do what most devs call “sanity checks”. basically checking if they are allowed to make such calls. like say you have a feature where they can retrieve info about something but you limit the retrieval to once per minute. you can then put a debounce in place that makes it so if it hasn’t been 60 seconds since the last remote call, the call is dropped.

I am not familiar whatsoever with a debounce.
But I think I know what you mean, a value that is set whenever 60 seconds has passed since last remote call?

Basically like a true or false value in the script, and then after another attempt to call the function whilst 60 seconds haven’t passed since the last remote call then they are banned?

Pretty much yea. Like an on/off switch and only the server has the ability to flip the switch. This is usually done with a boolean but can also be done with a timer and checking if it reached 0.

Then I can do a while wait(1) loop for the timer.