ProfileStore - Save your player data easy (DataStore Module)

This is most likely because ProfileStore doesn’t yield, and when you call the function addItem it would obviously return nil as there is no index within the module.Profiles table following the Player object. Now as for fixing this, I recommend making a module that would return a signal indicating that the player’s data is loaded and THEN call the function or simply do a repeat until scenario in the module over returning which I don’t think that’s a good method.


Me personally? I have an OOP module called PlayerDataService which pretty much handles the player data loading part — passed the Player object as argument.



However in this case, I’m also using ReplicaService of which I return that instead.


image
Then, I would simply call the Load method and listen for the OnLoad custom signal which returns the Profile object that allows me to work my way through.

image
And alas, I store both Replica and Profile separately within my custom Player object implementation. I did this so I could easily access it anywhere at anytime on server scripts.


If you think that this approach is way too tedious, then it’s fine. Just know that I believe the reason why it returns nil is because it couldn’t find anything within the module.Profiles table of the Player object index. If you tried printing the table then it would return an empty table {} which I can guarantee you. So either you’re calling the addItem function way too early before the player’s data was even able to load in, or I’m just completely off the track. Anyway, hope this helps somehow.

Unfortunately I don’t think this can really work in this contexts. The specific “Additem” I’m firing right now to test… only fires when the player kills an mob in game by dealing enough damage to it (which a script fires additem to add a item to the player), so the data by then has most definitely loaded in.

Would you ever consider doing a similar data store module that isn’t session locked? There’s certain uses cases that I don’t want session locked by a player and instead use a global key that I want any player to access at anytime

Why not just use normal datastores at that point?

That sort of system wouldn’t be scalable, or in other words, you’d be fine with writing to one key when your game is at less than 100 players, but when 1000+ players play your game accessing one DataStore key more and more will make the system halt as Roblox DataStores were not designed for this and have a limit on how many times you can write to a single key until you run into serious issues.

The module you speak of could not exist, at least it would not work like ProfileStore.

I only ask cause I stumbled into this the other day

which caters to both forms of data

Modules can’t change the fact that DataStore keys have a limit on how often you can write to them from different servers at the same time which makes implementations where you’d have something changeable from all servers non-scalable.

Some limitations can be found here:

Data storage is not magic and there’s a limit to everything, so not everything is possible, but there’s usually a workaround for certain features you want to create.

4 Likes

Currently trying to implement a ‘ban wave’ system. Issue is that when a ban wave occurs, all the players caught in the ban wave aren’t necessarily online or may be in another server (their data is session-locked). Is it possible to load a player’s data who happens to be offline and force write to a certain key (in my case, a “banned” key) even though their data may be session-locked?

You would use MessageAsync for this


https://madstudioroblox.github.io/ProfileStore/api/#messageasync

1 Like

How do I migrate from profile service to this? I’ve been using profile service for a minute and needs to transfer all my players data.

I see that it’s backward compatible that means if I use the same keys and things the data structure should still work the same?

Just go through your code and replace all variables and functions to use the new APIs. You might also have to reorder some parts of it. Use the tutorial as a template.

2 Likes

For dummies like me:

  1. Replace your Data script with the example script.
  2. Inside the PROFILE_TEMPLATE, replace the cash & items with the Template variables.
  3. Delete the Template module script, since we now use that in the Data script.
  4. If you have any other scripts that reference the old ProfileService, change it to ProfileStore.

I did this and it seems to be working perfectly

2 Likes

Do we not need :ListenToRelease anymore? I noticed it wasn’t here anymore

Would it be possible for you to make a .Changed signal for profiles whenever the data is changed?

Does this also apply for gamepasses?

Roblox’s Datastores just so happened to go down as I set this up, so I thought I was doing everything wrong… :cry:

Anyways. Could I suggest two global settings for ProfileStore?

SILENCED

This setting would mute all of the prints coming from ProfileStore. Warnings and errors will stay as they are important.

{6939F88A-BEEE-4A57-B217-3A5633FF3260}

It could be implemented like this:

{F7FD462E-8F1B-4747-AB0F-76999B522166}

SAVE_ENABLED

This setting will control whether saving is enabled. When true, data may be loaded, but no changes are saved. I’ve needed to implement this myself in ProfileService, because I don’t want my code to ruin my data when I’m experimenting with something, or if I’m working on a new system.

It could be implemented like this:


Having both of these settings built-in would make migrating to newer versions a lot easier. Thanks!

1 Like

Gamepass purchase state can always be checked, so it is not data that must be saved on the DataStore.

You can attain non-saving behaviour without forking ProfileStore by using ProfileStore:GetAsync(), ProfileStore.Mock and RunService:IsStudio().

2 Likes

Ah, so the way im handling gamepasses with profilestore should work fine? No need :Save()?