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)
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)
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
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.
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