Best way of manipulating Player Data

The way I’ve been handling Player Data is with Tables and Modules, something like this

local DataModule = {}
local Data = {}

function DataModule.GetData(Player)
      local PlayerData = Data[Player]
      if PlayerData then return PlayerData end

      PlayerData = {}
      PlayerData.Stats = {Level = 1, Exp = 0}

      Data[Player] = PlayerData
      return PlayerData

end

return DataModule

I believe the module and table route is the best way to do this (if there is a better way please let me know)

but I’m unsure if I’m manipulating Player Data properly

I’ve recently been doing this

function PlayerData:AddExp(Amount)
self.Exp = self.Exp + Amount
end

function PlayerData:Spawn()
Player:LoadCharacter()
-- pretend extra stuff is here
end

function PlayerData:LoopExp()
spawn(function()

      local Character = Player.Character
      if Character then

            while Character.Parent do
            self:AddExp(50)
             wait()
            end

      end

end)
end

is this a proper way of manipulating data?

and if so is there a limit to what type of functions I should use?

Does anyone know a better way?

Thanks

4 Likes

you forgot to set the metatable at the .GetData. what you’re doing is basically attempting to use OOP (Object Orientated Programming)
this thread might be useful for you:

self can’t be used properly when not assinging the meta table so read the thread carefully

1 Like

I have some conceptual isses with it.

I would not have the PlayerData module be responsible for spawning the player, or controlling when or how data changes. I would only have it be responsible for loading the players’ data when requested, and saving it when requested (and perhaps a periodic auto save feature).

Stuff like updating stats when the player spawns, or giving them experience points every once in a while, should be the responsibility of a different script. Those things are gameplay related, while the PlayerData module seems to be more an extension of the engine, or a tool that you can use to make saving data simpler in other scripts.

And then of course what VoidedBlade said, what you have so far isn’t going to work properly. Let us know if you want help getting it to work.

2 Likes

@ThanksRoBama

I didn’t use a metatable because I wasn’t using any metamethods

local DataModule = {}
local Data = {}

function DataModule.GetData(Player)
	local PlayerData = Data[Player]
	if PlayerData then return PlayerData end

	PlayerData = {}
	PlayerData.Stats = {Level = 1, Exp = 0}
	
function PlayerData:AddExp(Amount)
	self.Stats.Exp = self.Stats.Exp + Amount
	-- I did have a error because I did self.Exp instead of self.Stats.Exp
end

function PlayerData:Spawn()
Player:LoadCharacter()
-- pretend extra stuff is here
end

function PlayerData:LoopExp()
spawn(function()

      local Character = Player.Character
      if Character then

            while Character.Parent do
            self:AddExp(50)
             wait()
            end

      end

end)
end
	  
	Data[Player] = PlayerData
	return PlayerData

end

return DataModule
local Players = game:GetService("Players")
local Data = require(script.Parent.Data)

Players.PlayerAdded:Connect(function(Player)
	local PlayerData = Data.GetData(Player)
	
	PlayerData:AddExp(50)
	print(PlayerData.Stats.Exp)
end)

is there an issue with doing this, I know how to use metatables but I stopped using them for it as it wasn’t needed

It’s up to preference, the hard thing about manipulating player data would be saving/loading and updating it for client’s cache.

usually for the cache I use RemoteEvents whenever a specific stat changes

like

function PlayerData:AddExp(Amount)
	self.Stats.Exp = self.Stats.Exp + Amount
	RemoteEvent:FireClient(Player, self.Stats.Exp)
end

and just do any changes with that new data on the client

though if lots of data was changing this would probably cause some issues