Messy data script

Hi, I was working on a data module and I wanted to add folders and values into the player but it turned out to be very messy

Is there any way to clean the function PlayerDataLoaded

local Players = game:GetService("Players")
local Profiles = {}

-- Modules
local ProfileService = require(script.ProfileService)

local saveStructure = {
	-- Currency stuff
	Currency = {
		FP = 0; -- starting currency
		Storage = 16; -- starting storage
		GrowthTime = 4; -- starting flower growth time
		ValueMultiplier = 1; -- starting value for each flower multiplier
		WalkSpeedMultiplier = 1; -- starting walkspeed multiplier
	};
	-- Upgrade stuff
	Upgrades = {
		GrowthAmount = 0;
		GrowthCost = 10; -- starting growth cost is 10 fp
		StorageAmount = 0;
		StorageCost = 10;
		ValueAmount = 0;
		ValueCost = 30;
		WalkspeedAmount = 0;
		WalkspeedCost = 100;
	};
	
}

local PlayerProfileStore = ProfileService.GetProfileStore("Test_102", saveStructure)

local function PlayerDataLoaded(player)
	local profile = Profiles[player]
	
	local Data = Instance.new("Folder")
	Data.Name = "Data"
	Data.Parent = player
	
	local Currency = Instance.new("Folder",Data)
	Currency.Name = "Currency"
	
	local Upgrades = Instance.new("Folder",Data)
	Upgrades.Name = "Upgrades"
	
	-- Currency Stuff
	local FP = Instance.new("NumberValue",Currency)
	FP.Name = "FP"
	FP.Value = profile.Data.FP
	
	local Storage = Instance.new("NumberValue",Currency)
	Storage.Name = "Storage"
	Storage.Value = profile.Data.Storage
	
	local GrowthTime = Instance.new("NumberValue",Currency)
	GrowthTime.Name = "GrowthTime"
	GrowthTime.Value = profile.Data.GrowthTime
	
	local ValueMultiplier = Instance.new("NumberValue",Currency)
	ValueMultiplier.Name = "ValueMultiplier"
	ValueMultiplier.Value = profile.Data.ValueMultiplier
	
	local WalkSpeedMultiplier = Instance.new("NumberValue",Currency)
	WalkSpeedMultiplier.Name = "WalkSpeedMultiplier"
	WalkSpeedMultiplier.Value = profile.Data.WalkSpeedMultiplier
	
	--] Upgrades
	
	local StorageAmount = Instance.new("NumberValue",Upgrades)
	StorageAmount.Name = "StorageAmount"
	StorageAmount.Value = profile.Data.StorageAmount
	
	local StorageCost = Instance.new("NumberValue",Upgrades)
	StorageCost.Name = "StorageCost"
	StorageCost.Value = profile.Data.StorageCost
	
	local GrowthAmount = Instance.new("NumberValue",Upgrades)
	GrowthAmount.Name = "GrowthAmount"
	GrowthAmount.Value = profile.Data.GrowthAmount
	
	local GrowthCost = Instance.new("NumberValue",Upgrades)
	GrowthCost.Name = "GrowthCost"
	GrowthCost.Value = profile.Data.GrowthCost
	
	local ValueAmount = Instance.new("NumberValue",Upgrades)
	ValueAmount.Name = "ValueAmount"
	ValueAmount.Value = profile.Data.ValueAmount
	
	local ValueCost = Instance.new("NumberValue",Upgrades)
	ValueCost.Name = "ValueCost"
	ValueCost.Value = profile.Data.ValueCost
	
	local WalkspeedAmount = Instance.new("NumberValue",Upgrades)
	WalkspeedAmount.Name = "WalkspeedAmount"
	WalkspeedAmount.Value = profile.Data.WalkspeedAmount
	
	local WalkspeedCost = Instance.new("NumberValue",Upgrades)
	WalkspeedCost.Name = "WalkspeedCost"
	WalkspeedCost.Value = profile.Data.WalkspeedCost
end

local function PlayerAdded(player)
	local profile = PlayerProfileStore:LoadProfileAsync("Player_" .. player.UserId, "ForceLoad")
	
	if profile ~= nil then
		profile:ListenToRelease(function()
			Profiles[player] = nil
			player:Kick("Your profile has been loaded remotely. Please rejoin.")
		end)

		if player:IsDescendantOf(Players) then
			local player_profile = {
				Profile = profile,
				_player = player,
			}
			
			setmetatable(player_profile, profile)

			Profiles[player] = profile
			PlayerDataLoaded(player)
		else
			profile:Release()
		end
	else
		player:Kick("Unable to load saved data. Please rejoin.")
	end
end

for _, player in ipairs(Players:GetPlayers()) do
	spawn(function()
		PlayerAdded(player)
	end)
end

Players.PlayerAdded:Connect(PlayerAdded)
Players.PlayerRemoving:Connect(function(player)
	local profile = Profiles[player]
	if profile ~= nil then
		profile:Release()
	end
end)

return Profiles

maybe make a function for creating new values.
usually makes scripts like that look better in my experience.
adds more functionality too i think.

example:

local function newValue(name, value, parent, class)
  local v = Instance.new(class)
  v.Name = name
  v.Value = value
  v.Parent = parent
  return v
end

local someValue = newValue("something", 999, workspace, "NumberValue")

Also never use the parent setting thing part of instance.new.
It takes longer and causes more lag.
You should always set the parent AFTER setting its properties
The set parent part of the instance.new function is deprecated

First of all, you don’t need all those semicolons, this isn’t Python or Java (I know there are other programming languages that use them but those are the best examples I could think of). Also I think you could probably use a ModuleScript (I think that’s what it’s called anyway. It’s the one with the brick on the icon) for the different values.

I think that’s even more work but lua supports semi colons so I don’t mind using them

try not to use spawn() and instead use task.spawn() It’s just better and more optimised.

1 Like

Not related to your query of cleaning the PlayerDataLoaded function but,
image
Just do, task.spawn(PlayerAdded, player)

The best solution would be to not create any folders nor number value instances. (this would also allow profile service to make automatic saves).

But here’s how I would make it make folders and such:

local function PlayerDataLoaded(player)
	local profile = Profiles[player]

	local Data = Instance.new("Folder")
	Data.Name = "Data"
	Data.Parent = player

	local Currency = Instance.new("Folder")
	Currency.Name = "Currency"
	Currency.Parent = Data

	local Upgrades = Instance.new("Folder")
	Upgrades.Name = "Upgrades"
	Upgrades.Parent = Data
	
	local currencyKeys = {
		"FP",
		"Storage",
		"GrowthTime",
		"ValueMultiplier",
		"WalkSpeedMultiplier"
	}
	
	local upgradeKeys = {
		"StorageAmount",
		"StorageCost",
		"GrowthAmount",
		"GrowthCost",
		"ValueAmount",
		"ValueCost",
		"WalkspeedAmount",
		"WalkspeedCost"
	}
	
	for _,key in currencyKeys do
		local value = Instance.new("NumberValue")
		value.Name = key
		value.Value = profile.Data[key]
		value.Parent = Currency
	end
	
	for _,key in upgradeKeys do
		local value = Instance.new("NumberValue")
		value.Name = key
		value.Value = profile.Data[key]
		value.Parent = Upgrades
	end
	
	return Data
end

Though I am a bit confused because your PlayerDataLoaded() doesn’t seem compatible with saveStructure. Since it assumes that all keys are directly under a single table, while saveStructure says that they are grouped together in Currency and Upgrades. Which would make this function even simpler.