How would I simplify this DataStore Attribute code?

Hi,

So I’m Updating my DataStore System to use Attributes instead of Value Instances,

Overall, It seems to be going alright, no Issues with anything, I wrote this Chunk of code that seems to work, It Updates the Players Session Data, Saves when the Player Leaves, But when trying Updating it and modify it, It get’s confusing for me to traverse.

For some parts of the code, I’m not sure if typeof or the Connection Below the for loop is necessary.

Attribute Setup Code
function profs.SetScore(p: Player)
	for item, val in profs.SD[p.UserId] do -- Looks through Session Data
		if typeof(val) ~= "table" then -- Checks Value Type
			p:SetAttribute(item, val) -- Creates Attributes
			p:GetAttributeChangedSignal(item):Connect(function() -- Changed Event
				profs.SD[p.UserId][item] = p:GetAttribute(item) -- Updates Session Data
			end)
		end
	end
	-- Extra Data
	p:SetAttribute("REXP", p:GetAttribute("Level")*1000)
	p:SetAttribute("Aiming", false)
	p:SetAttribute("Running", false)
	-- EXP Changed Connection
	p:GetAttributeChangedSignal("EXP"):Connect(function()
		local EXP = p:GetAttribute("EXP")
		local REXP = p:GetAttribute("REXP")
		local Level = p:GetAttribute("Level")
		
		if EXP >= REXP then -- if EXp is greated than REXP (Level Up System)
			p:SetAttribute("EXP", EXP - REXP)
			p:SetAttribute("Level", Level + 1)
			p:SetAttribute("REXP",p:GetAttribute("Level") * 1000)
		end
		-- Updates Session Data (again)
		profs.SD[p.UserId]["Level"] = p:GetAttribute("Level")
		profs.SD[p.UserId]["EXP"] = p:GetAttribute("EXP")
	end)
end
Attributes (During Testing)

Screenshot (160)

Data Script
profs.SD = {} -- Session Data
profs.ND = { -- New Data
	["Level"] = 1;
	["Cash"] = 500;
	["EXP"] = 0;
	
	["Items"] = {
		["Weapons"] = {};
		["Tools"] = {};
	};
	["Banned"] = {
		["Status"] = false;
		["Reason"] = "N/A"
	};
}



profs.Prefix = "profile/data/"
profs.Retries = 3




function profs.Load(p: Player)
	local Success, Data = pcall(function() -- Gets data
		return profs.DS:GetAsync(profs.Prefix..p.UserId)
	end)
	-- pcall and Data Checking
	if Success then
		if Data then
			profs.SD[p.UserId] = Data
			print("Fetched Data for", p.Name)
		else
			warn(string.format("No Data for %s, Creating new Data", p.Name))
			profs.SD[p.UserId] = profs.ND
		end
		
	else
		p:Kick("Failed to Access Data")
	end
	
	profs.SetScore(p) -- Function Call here
end
{...}
["Text"] = "Its a Table, what did did you expect???"

I’m pretty sure there can be a Better system with this that I’m overlooking.
If not, How would I make the code look cleaner?

not sure about cleaner, but this is an issue in the loading
tables as passed by reference in Lua, so you’re making all players in the same game with no save data have the same session data

e.g. this would make both table a and table b be {“a”, “b”}

local a = {}
local b = a

a[1] = "a"
b[2] = "b"
print(a)
print(b)

and looking at your variable naming now, you could make it clearer by using verbose names rather than acronyms

No?

The Value of the Key is set as the New Table, I made sure to test, and it works as if it were normal

Thats not what I’m referring ti, Im refering to the Attribute script

you could also handle this inside a separate function instead of making the setScore function really long and hard to follow

e.g.:

local function getOnCharacterAdded(player)
   local function onCharacterAdded(character)
      print(player, "respawned")
   end
   return onCharacterAdded
end

local function onPlayerAdded(player)
   player.CharacterAdded:Connect( getOnCharacterAdded(player) )
end

game.Players.PlayerAdded:Connect(onPlayerAdded)

I setup onCharacterAdded to keep it outside onPlayerAdded, but Roblox’s setup with Connect(…) doesnt let you input custom params, so I setup getOnCharacterAdded to add the player variable into onCharacterAdded

it doesnt
I just gave an example of why it doesnt work

Nothing you are saying is relevant to the Topic, not even the scripts provided are helpful either.
I’m asking on how to Simplify the Attribute Setup Code, that’s all.

the attribute script is included in that
you wrote SD as one of your keys

Anyway, I simplified the Code:

function profs.SetScore(p: Player)
	for item, val in profs.SD[p.UserId] do
		if typeof(val) ~= "table" then
			p:SetAttribute(item, val)
			
			if item == "EXP" then
				print("EXP Connection Set", item, val)
				p:GetAttributeChangedSignal(item):Connect(function()
					GetEXPData(p)
				end)
				
			elseif item ~= "Level" then
				print(item, val)
				p:GetAttributeChangedSignal(item):Connect(function()
					profs.SD[p.UserId][item] = p:GetAttribute(item)
				end)
			end

		end
	end
	profs.spawnExtraData(p)
end

function profs.spawnExtraData(p: Player)
	p:SetAttribute("REXP", p:GetAttribute("Level") * profs.REXP_Multiplier)
	for item, val in profs.ExtraData do
		if typeof(val) ~= "table" then
			p:SetAttribute(item, val)
		end
	end
end

And since you wanted me to, I did this:

profs.SD[p.UserId] = table.clone(profs.ND)

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