Codes rewarding system not working correctly

Hello, I am currently working on a codes reward system but I’m having some slight issues with the saving of the full list of codes the player has ever had: plrCodeList

The way I was thinking about doing it was by having one StringValue which stores the available codes which have yet to be used and one StringValue which stores every code which has been used and not been used. This one is used to check if the codes list is up to date and if not it’ll update that list as well as adding the newly added code to the list of the available codes.

Now back to the problem, when the player is loaded in there is a check if that player’s codes are up to date. However, for some reason, it will always go back to the server version of the list aka the one with all the codes even if I remove one to test if it’ll work or not.

Ex:

  1. plrCodeList = {"Alpha", "Beta"} and plrCodes = {"Alpha", "Beta"}
  2. Then I remove beta from the StringValue: plrCodeList = {"Alpha"} and redeem it to remove it: plrCodes = {"Alpha"}
  3. Now I leave the game to save the current data
  4. I rejoin to check if it will add “Beta” to the the plrCodes and plrCodeList but I just loads the plrCodeList as if it was never saved.

The reason why I know this is because of the print statement within the updateCodes function which prints the serverList and plrCodeList prints “Alpha,Beta : Alpha,Beta” when it shouldn’t have been updated yet.

I am unsure as to what is causing the problem but I think it might be the saving script(Which does save, I know this because of a warning that is printed in the output window)

local Players = game:GetService("Players")

local DataStoreService = game:GetService("DataStoreService")
local playerInfo = DataStoreService:GetDataStore("playerInfo")

local System = require(game:GetService("ServerScriptService")["General System"].System)

local DataTable = require(script.dataTable)

local serverValues = require(game.ServerScriptService.DataManagment.leaderstats.serverValues)
local version = serverValues.dataVersion

local function loadProfile(plr)
	playerInfo:SetAsync(plr.userId..version, DataTable)
	print("New profile has been loaded")
end


local function saveData(plr)
	playerInfo:SetAsync(plr.userId..version, {
		["Codes"] = {
			["NotUsed"] = System.General.SplitString(plr.plrInfo.plrCodes.Value),
			["List"] = System.General.SplitString(plr.plrInfo.plrCodeList.Value)
		};
	})
end

local function getData(plr)
	return playerInfo:GetAsync(plr.userId..version)
end

local function updateCodes(plr)
	
	local codeUpdateList = System.General.SplitString(plr.plrInfo.plrCodes.Value)
	local list = System.General.SplitString(plr.plrInfo.plrCodeList.Value)
	
	print(table.concat(serverValues.codeList, ",").." : "..table.concat(list, ","))
	
	if table.concat(list, ",") == table.concat(serverValues.codeList, ",") then -- Check if the player has been given every code the game has in store
		print(1)
		return
	end
	print(2)
	for i,v in pairs(serverValues.codeList) do
		for a, b in pairs(list) do
			if v == b then
				continue
			else
				table.insert(codeUpdateList, v)
			end
		end
	end
	plr.plrInfo.plrCodes.Value = table.concat(codeUpdateList, ",")
	plr.plrInfo.plrCodeList.Value = table.concat(serverValues.codeList, ",")
end

Players.PlayerAdded:Connect(function(plr)
	local plrData = getData(plr)
	
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = plr
	
	if getData(plr) == nil then
		loadProfile(plr)
		plrData = getData(plr)
		print(plrData)
	end

	local plrInfo = Instance.new("Folder")
	plrInfo.Name = "plrInfo"
	plrInfo.Parent = plr
	
	local plrCodes = Instance.new("StringValue")
	plrCodes.Name = "plrCodes"
	plrCodes.Parent = plrInfo
	plrCodes.Value = table.concat(plrData.Codes.NotUsed, ",")
	
	local plrCodeList = Instance.new("StringValue")
	plrCodeList.Name = "plrCodeList"
	plrCodeList.Parent = plrInfo
	plrCodeList.Value = table.concat(plrData.Codes.List, ",")
	
	updateCodes(plr)
end)

game:BindToClose(function()
	for i,v in pairs(Players:GetChildren()) do
		if getData(v) ~= nil then
			coroutine.wrap(saveData(v))
		end
	end
end)

Players.PlayerRemoving:Connect(function(plr)
	local s, e = pcall(function()
		if getData(plr) ~= nil then
			saveData(plr)
		end
	end)
	if not s then
		warn(plr.Name.."'s data was not saved correctly on leaving! Error: "..e)
	end
end)

while true do
	wait(120)
	for i,plr in pairs(Players:GetChildren()) do
		local s, e = pcall(function()
			coroutine.wrap(saveData(plr))
		end)
		if not s then
			warn(plr.Name.."'s data was not saved correctly! Error: "..e)
		end
	end
end

If there is anything you’re wondering about, please tell me and I’ll do my best to answer.

1 Like

I have now found the issue, the reason behind this issue was not the code itself. It was the way I went about changing a player’s data. I realized this when I was thinking about why it wouldn’t get the actual data of the player. The problem was that I was on the client side when I changed the StringValue. I have now fixed the “issue”. The other issue was that the game was not saving correctly due to the courtine for some reason so I chose to just remove it.