What is the issue with storing player data in tables, data is shared when it should not be

Resolved the issues for trying to use modulescript on multipe players by using just a single modulescript :slight_smile:

1 Like

Let me see if I understand this correctly.
You have a module script in ServerStorage.
Upon a player join you Clone() that module from server, require it from server, edit the module and place the module inside Player. (At this point module has been required by first and once time)
Then a second player join, you clone again the module from SS, require it and parent it, edit it and place it inside new player.

But when a player fires the remote to server asking for a change you require the script that is inside the player on a different script? or the same one that already required it?
Its not possible to repeat the require process, that happens once and the module is cached by the server require it again will do nothing.

In order to interact with the module inside the player you would need a table that reference the module per player, so, client fires remote, you use that player instance to find which module belongs to that player and you go from there without requiring it everytime the player fires the remote.


Could you elaborate this?
I’ve been saving the player’s data in only one module without any issues on many projects I designed for a couple of years. I’m not sure what you mean about “potential causes for shared data”

2 Likes

The modulescript is something every player will get that will perform functions related to that player. And I’m sorry for confusion when I mentioned it was originally in server storage, I meant that I didn’t parent it to the player, and instead I created a folder inside server storage with the players userid as the folder name, the cloned modulescript is then parented to the players folder. So that way each player had their own folder and own modulescript of the original that resides in server storage. I thought that was the issue so instead of creating a folder for the player inside ServerStorage which seemed more protected, I went the route of parenting the modulescript to the player instead.

Shared data as in multiple players have the same table data when it should not be the case. If i clone a modulescript to the player, require it and perform a function that adds data to a table inside the modulescript it should be just for that players modulescript data not every other player. But even If i don’t call a remote function, whenever I add the item to the admin player, every other player will have that item in there data table as well when it shouldn’t be. It’s almost like the modulescript is working in a shared way as if im calling it from one location for all players to use but it’s really each player has their own modulescript so I’m perplexed as to how players are able to have the same data once set for another player.

If you can see the code, it pretty much outlines the steps. And I have tried so many methods. Even storing the data on the server script such as PlayerData[player.Name] = data or PlayerData[player.Name] = {modulescript = require(path_to_module)}.

I will attempt to reference the modules in a main table from the server. As I don’t want restart the framework I was building. I have a lot of lines of code that work but discovering this just ruins my progress.

3 Likes

I really think the explanation is this:


If you prefer to continue with your approach yup, you would need to only require each module once after being Cloned, and keep them in a Table of Player = Module. So whenever you need to access a module you get the module using the Player as the key of the Table.

I see the issues you’ve been facing, and any approach that fits better to you is the right one. For future projects maybe you would like to try the one I did mention.
Have only one Module that will contain all functions, inside that module you can store all player data in tables, there is no way of mixing data if you are doing things correctly

3 Likes

I’m going to attempt your idea instead. I will post back with my results :slight_smile: thanks again for taking the time to read and reply. And you are absolutely correct about doing things properly. I have major OCD about bugs and doing things in good practice. I will sharpen my tool :slight_smile:

2 Likes

You’re lucky that someone dedicates so much time to you, they don’t even say to me: “good topic”

3 Likes

Don’t let that discourage you from continuing to seek advice or help :smiley: I hope you find resolutions just as swiftly!

1 Like

Update: Your suggestion worked and is the correct way of doing it!

That solved my data inconsistency issues as well as the conflict of attempting to require something more than once. By having a single modulescript and requiring it once on the server, I was able to store player data inside the module in a table referenced to that players name (for example modulescript.Playerdata[player.Name] = {–data here}. So, when I run a function inside of the modulescript, such as getting data from the players tables… it shows the correct data. Lesson quickly learned and applied. Glad you gave me that insight, it’s all about how you view things and that never crossed my mind! Thank you again.

1 Like

That’s great! And your way to be opened to try ideas it’s perfect, as you said you are pointing to improve anything that can be better.

One last suggestion, you did mention this:

Thats good, but you can improve that too. Player’s names are not reliable, you can use the Player instance instead or the Player.UserId.

I prefer to use the Player instance itself. Once player join server only one and unique Player instance is created and never changes (different to character models or names)
Same for UserId.

It’s just about improving it, its way easier to find in a dictionary a Player instance than the UserId or the name, (the name could change during game session)

Example:

local YourModule = require(game.ServerScriptService:WaitForChild("Xmodule"))

Players.PlayerAdded:Connect(function(PLY) -- you got a Player instance
	YourModule.PlayersData[PLY] = {theData} -- you use that player instance as the key
end)

local function SomeXfunc(ply) -- that received a player instance
	warn(YourModule.PlayersData[ply]) -- direct access to the players data
end
1 Like

Funny enough, I originally used UserId but when I noticed the data inconsistency, I was changing any and everything to combat that issue, but I never thought of the way you showed me :smiley: One question about using the Player instance, is there any risk of memory leaks by doing that? Or just when that player leaves or disconnects, to set that to nil? I’ve been wanting to try something other than UserId and Name myself.

Of course. But its not only about using Player instance or a string made by the name or the UserId. Mandatory you should flush the table you created when player leaves, probably you already know that, keeping that record on the module after player leaves will create a huge memory leak no matter if you are using the player instance, name or whatever string/number you like.

The real issue about player instances, is that are not garbage collected when player leaves, those and characters are just parented to nil and preserved on server… causing memory leaks.
That issue is already being addressed on recent updates of roblox.
If you flush the table you created and setting it to nil thats enough for your module. (the idea is not keeping a hard reference of that player instance anywhere, and flushing the data ofc)

If you can enroll into the player/character real Destroy of the roblox update the better.
Real destroy of player instance

1 Like

That’s true, I’m always trying to keep my mind on what i may be leaving around! I will have to look into the update. Thanks again you were much help!

1 Like

One thing i thought you may need to know: If you intend to use player instances as keys in tables that you will also be sending to players via remotes, the player instance keys of those tables received through the remotes will not behave as expected, as described in this post

2 Likes

Totally agree, good point.
But, in any scenario where you want to send a whole dictionary with all players data that exist in server to client, there are many more proper approaches that are not sending the entire dictionary that is using Player instances as keys. Perhaps sending only the data that is needed, or keeping a bridge of communication between client/server so you are not sending big amount of data thru the remote

If the goal is to constantly share the server table with the client, yes, the UserId is the best option

1 Like

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