Storing Player Data in a Module Script, okay or not okay?

Hey!
I’m currently working on redo-ing my game’s way of storing and checking player data.

The way I’d like to do this is storing it inside of a ModuleScript inside of replicatedstorage.

The client only ever needs data for visuals and is told by the server what to do and when to do it, so I don’t see any issue with this.

A serverscript placed under SSS would handle player joining, leaving, data changing, and data saving.

I am not very experienced with handling data;
Is this okay to do?
Could anyone second this before I actually start making this?
To my understanding this should be fine, but I’d like to know any pointers or flaws this could have

1 Like

Store the UserIDs not the player objects themselves.

local PlayerData = {}
PlayerData.Players = {} -- Will contain our User IDs

-- Add a new player when they join
game:GetService('Players').PlayerAdded:Connect(function(player)
  table.insert(PlayerData.Players, {
    id = player.UserId,
    coins = 0 -- Just an example of data
  })
end)

-- Remove the player when they leave
-- You could also implement DataStore data saving here
game:GetService('Players').PlayerRemoving:Connect(function(player)
  for index, data in pairs(PlayerData.Players) do
    if data.id == player.UserId then
      table.remove(PlayerData.Players, index)
      break
    end
  end
end)

-- An example utility functions for manipulating data
-- Here we can safely accept a player
function PlayerData:SetCoins(player: Player, coins: number)
  -- Same concept as when the player is remvoing just find their data and update their coins
end

return PlayerData

When you require this script by the server its shared across the entire server. All data is persistent across the server. If you were to require this by the client the data would not match since that’s a breach of the server client boundary. In order to query the data from the client you need to setup a RemoteFunction and return the data the client wants from the server.

Yes, it is fine to do it and you can use a normal module or with metatables, here is an example of both

Normal module
local Storage = {}
return {
	Set = function(Player, Table)
		if not Storage[Player] then		Storage[Player] = {}		end
		for Key, Value in pairs(Table or {}) do
			Storage[Player][Key] = Value
		end
		return Storage[Player]
	end,
	Get = function(Player, Key)
		local Info = Storage[Player]
		return Info and Info[Key]
	end,
}

-- In another script
local Module = require() -- Module location
Module.Set(Player, {Sword = 1})
print(Module.Get(Player, "Sword")) -- 1
Module.Set(Player, {Sword = 0})
print(Module.Get(Player, "Sword")) -- 0
metatable
local M, Storage = {}, {}
M.__index = M

--// Module base
function M.SetUp(Player, Table)
    local NewEntry = setmetatable({}, M)
    NewEntry.Storage = Table or {}
    Storage[Player] = NewEntry
    return NewEntry
end
function M.GetData(Player)
    return Storage[Player]
end

--// Methodos
function M:Get(Key)
    local Table = self.Storage
    return Table[Key] or Table
end
function M:Set(Table)
    for Key, Value in pairs(Table or {}) do
        self.Storage[Key] = Value
    end
end
return M

-- In another script.
local Module = require() -- Module location
local Storage = Module.SetUp(Player, {Sword = 1})
print(M:Get("Sword")) -- 1
M:Set({Sword = 0})
print(M:Get("Sword")) -- 0

Both must have functions that allow you to edit and retrieve the data.
PS: for security, it should be only for the server, since I think that the players can see the information of another.

4 Likes

Just to clarify, I’m not confused with saving data, I’m confused with making data visible to the server and to the client.

A client cannot see the table without using events or having an actual object, so I’m trying to use a module script

You’ll have to use events no matter what you can’t use ModuleScripts to circumvent this.

1 Like

So I’ve been learning how to use metatables lately and I think I’m going to go with that

Question, if a hacker requires the module and sets data (on the client ofcourse), will the server be able to see this? The module would be inside of replicatedstorage.

No, because the client has no access to data persistence features (for a good reason).

The hackers can view and edit the information, but only for them, the server will not see those changes.